summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2011-08-31 12:01:13 -0700
committerBill Richardson <wfrichar@chromium.org>2011-08-31 12:51:05 -0700
commit1a4d03dc902b03c236df01791c0db1f4489ae411 (patch)
tree053aec2167cd04aa58b15a9718dc8c97ac7ec0ad
parentfec47595ce655c580749f9a3f47e1fd6bd4d8ee3 (diff)
downloadvboot-1a4d03dc902b03c236df01791c0db1f4489ae411.tar.gz
Determine GPIO base from /sys/class/gpio/gpiochip<N>
... instead of using hard-coded 192 constant. BUG=chromium-os:19876 TEST=manual If crossystem still reports correct values for devsw_cur recoverysw_cur (and maybe wpsw_cur, although that's a separate bug), then it works. Change-Id: Id8d4fb389bfd78f40da9ef08aa372071d77cbec1 Reviewed-on: http://gerrit.chromium.org/gerrit/7014 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Tested-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--host/arch/x86/lib/crossystem_arch.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c
index 1db81fd9..9feb6c37 100644
--- a/host/arch/x86/lib/crossystem_arch.c
+++ b/host/arch/x86/lib/crossystem_arch.c
@@ -3,12 +3,13 @@
* found in the LICENSE file.
*/
+#include <ctype.h>
+#include <dirent.h>
#include <stdio.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <ctype.h>
#include "host_common.h"
@@ -422,6 +423,32 @@ static int VbGetRecoveryReason(void) {
}
+/* Physical GPIO number <N> may be accessed through /sys/class/gpio/gpio<M>/,
+ * but <N> and <M> may differ by some offset <O>. To determine that constant,
+ * we look for a directory named /sys/class/gpio/gpiochip<O>/. If there's not
+ * exactly one match for that, we're SOL.
+ */
+static int FindGpioChipOffset(int *offset) {
+ DIR *dir;
+ struct dirent *ent;
+ int match = 0;
+
+ dir = opendir(GPIO_BASE_PATH);
+ if (!dir) {
+ return 0;
+ }
+
+ while(0 != (ent = readdir(dir))) {
+ if (1 == sscanf(ent->d_name, "gpiochip%d", offset)) {
+ match++;
+ }
+ }
+
+ closedir(dir);
+ return (1 == match);
+}
+
+
/* Read a GPIO of the specified signal type (see ACPI GPIO SignalType).
*
* Returns 1 if the signal is asserted, 0 if not asserted, or -1 if error. */
@@ -430,7 +457,8 @@ static int ReadGpio(int signal_type) {
int index = 0;
int gpio_type;
int active_high;
- int controller_offset;
+ int controller_num;
+ int controller_offset = 0;
char controller_name[128];
int value;
@@ -441,16 +469,16 @@ static int ReadGpio(int signal_type) {
if (gpio_type == signal_type)
break;
else if (gpio_type == -1)
- return -1; /* Ran out of GPIOs before finding a match */
+ return -1; /* Ran out of GPIOs before finding a match */
}
/* Read attributes and controller info for the GPIO */
snprintf(name, sizeof(name), "%s.%d/GPIO.1", ACPI_GPIO_PATH, index);
active_high = ReadFileBit(name, 0x00000001);
snprintf(name, sizeof(name), "%s.%d/GPIO.2", ACPI_GPIO_PATH, index);
- controller_offset = ReadFileInt(name);
- if (active_high == -1 || controller_offset == -1)
- return -1; /* Missing needed info */
+ controller_num = ReadFileInt(name);
+ if (active_high == -1 || controller_num == -1)
+ return -1; /* Missing needed info */
/* Check for chipsets we recognize. */
snprintf(name, sizeof(name), "%s.%d/GPIO.3", ACPI_GPIO_PATH, index);
@@ -460,12 +488,10 @@ static int ReadGpio(int signal_type) {
(0 != strcmp(controller_name, "CougarPoint")))
return -1;
- /* We blindly assume the controller has offset 192.
- * There is some information under /sys/class/gpio/gpiochip192/,
- * but there's nothing there to correlate that with anything we already
- * discovered, so if it's not the right thing we have no way of knowing.
- */
- controller_offset += 192;
+ /* Modify GPIO number by driver's offset */
+ if (!FindGpioChipOffset(&controller_offset))
+ return -1;
+ controller_offset += controller_num;
/* Try reading the GPIO value */
snprintf(name, sizeof(name), "%s/gpio%d/value",