mmc-init: Enable factory reset from gpio change

The factory-reset-toggle GPIO can have its state changed by physically
toggling SWITCH_RESET_N. If this GPIO is in a different state than it
was during the last boot, it triggers a BMC factory reset.

Tested: Added extra files to /var. Verified that a reset from a
physical toggle caused these files to be removed. Verified that resets
from the REST API and from setting rwreset to true still function
properly. Verified that repeated rebooting without calling for a reset
does not inadvertently trigger a reset.

Signed-off-by: Isaac Kurth <isaac.kurth@ibm.com>
Change-Id: I3cf3f9519033db240c0db2eec35a5b09b8fefdf2
diff --git a/meta-phosphor/recipes-phosphor/initrdscripts/phosphor-mmc-init.bb b/meta-phosphor/recipes-phosphor/initrdscripts/phosphor-mmc-init.bb
index 88807c0..96c27da 100644
--- a/meta-phosphor/recipes-phosphor/initrdscripts/phosphor-mmc-init.bb
+++ b/meta-phosphor/recipes-phosphor/initrdscripts/phosphor-mmc-init.bb
@@ -13,6 +13,7 @@
     e2fsprogs-e2fsck \
     e2fsprogs-mke2fs \
     gptfdisk \
+    libgpiod-tools \
     parted \
     udev \
 "
diff --git a/meta-phosphor/recipes-phosphor/initrdscripts/phosphor-mmc-init/mmc-init.sh b/meta-phosphor/recipes-phosphor/initrdscripts/phosphor-mmc-init/mmc-init.sh
index 575b760..ad9748e 100644
--- a/meta-phosphor/recipes-phosphor/initrdscripts/phosphor-mmc-init/mmc-init.sh
+++ b/meta-phosphor/recipes-phosphor/initrdscripts/phosphor-mmc-init/mmc-init.sh
@@ -10,6 +10,9 @@
 
 fslist="proc sys dev run"
 rodir=/mnt/rofs
+mmcdev="/dev/mmcblk0"
+rwfsdev="/dev/disk/by-partlabel/rwfs"
+
 cd /
 mkdir -p $fslist
 mount dev dev -tdevtmpfs
@@ -19,7 +22,6 @@
 
 # Wait up to 5s for the mmc device to appear. Continue even if the count is
 # exceeded. A failure will be caught later like in the mount command.
-mmcdev="/dev/mmcblk0"
 count=0
 while [ $count -lt 5 ]; do
     if [ -e "${mmcdev}" ]; then
@@ -48,16 +50,29 @@
     /bin/sh
 fi
 
-rwfsdev="/dev/disk/by-partlabel/rwfs"
+# Determine if a factory reset has been requested
 mkdir -p /var/lock
-if test $(fw_printenv -n rwreset) = "true"; then
+resetval=$(fw_printenv -n rwreset 2>/dev/null)
+gpiopresent=$(gpiofind factory-reset-toggle)
+if [ $? -eq 0 ]; then
+    gpioval=$(gpioget $gpiopresent)
+else
+    gpioval=""
+fi
+# Prevent unnecessary resets on first boot
+if [ -n "$gpioval" -a -z "$resetval" ]; then
+    fw_setenv rwreset $gpioval
+    resetval=$gpioval
+fi
+if [ "$resetval" = "true" -o -n "$gpioval" -a "$resetval" != "$gpioval" ]; then
     echo "Factory reset requested."
     if ! mkfs.ext4 -F "${rwfsdev}"; then
         echo "Reformat for factory reset failed."
         /bin/sh
     else
-        fw_setenv rwreset
-        echo "Formatting of rwfs is complete."
+        # gpioval will be an empty string if factory-reset-toggle was not found
+        fw_setenv rwreset $gpioval
+        echo "rwfs has been formatted."
     fi
 fi