Exporting GPIO if the sysfs node does not exist

This change exports gpio number if it can not be accessed. Ignore
the active_low checking for compatibility.

Signed-off-by: Rong Chang <rongchang@chromium.org>
BUG=chrome-os-partner:11029
TEST=manual
  Run crossystem and check WP pin status

Change-Id: I0885ab21c6c6d614945e4fda49a373e8619772a9
Reviewed-on: https://gerrit.chromium.org/gerrit/26563
Commit-Ready: Tom Wai-Hong Tam <waihong@chromium.org>
Reviewed-by: Tom Wai-Hong Tam <waihong@chromium.org>
Tested-by: Tom Wai-Hong Tam <waihong@chromium.org>
diff --git a/host/arch/arm/lib/crossystem_arch.c b/host/arch/arm/lib/crossystem_arch.c
index c3afccf..1cb51c2 100644
--- a/host/arch/arm/lib/crossystem_arch.c
+++ b/host/arch/arm/lib/crossystem_arch.c
@@ -25,6 +25,9 @@
 #define FDT_COMPATIBLE_PATH "/proc/device-tree/compatible"
 /* Device for NVCTX write */
 #define NVCTX_PATH "/dev/mmcblk%d"
+/* Base name for GPIO files */
+#define GPIO_BASE_PATH "/sys/class/gpio"
+#define GPIO_EXPORT_PATH GPIO_BASE_PATH "/export"
 /* Errors */
 #define E_FAIL      -1
 #define E_FILEOP    -2
@@ -191,11 +194,26 @@
 }
 
 static int VbGetGpioStatus(unsigned gpio_number) {
-  char const *gpio_name_format = "/sys/class/gpio/gpio%d/value";
   char gpio_name[FNAME_SIZE];
+  int value;
 
-  snprintf(gpio_name, sizeof(gpio_name), gpio_name_format, gpio_number);
-  return ReadFileInt(gpio_name);
+  snprintf(gpio_name, sizeof(gpio_name), "%s/gpio%d/value",
+           GPIO_BASE_PATH, gpio_number);
+  value = ReadFileInt(gpio_name);
+
+  if (value == -1) {
+    /* Try exporting the GPIO */
+    FILE* f = fopen(GPIO_EXPORT_PATH, "wt");
+    if (!f)
+      return -1;
+    fprintf(f, "%d", gpio_number);
+    fclose(f);
+
+    /* Try re-reading the GPIO value */
+    value = ReadFileInt(gpio_name);
+  }
+
+  return value;
 }
 
 static int VbGetVarGpio(const char* name) {