summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2013-12-10 16:05:30 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-12-11 19:50:39 +0000
commit1aa59b0ea545d571f24a64af71f412fb214e4f82 (patch)
tree85420040088667c4bb25ee7cb41ca18447b6f0fb
parent31912b61a7c19515f5f5decae8ccad7b8e42f4cf (diff)
downloadvboot-1aa59b0ea545d571f24a64af71f412fb214e4f82.tar.gz
crossystem: handle BayTrail gpios
BayTrail systems have 3 banks of gpios. Therefore, the Linux kernel exposes these 3 banks as 3 gpiochip entries. The kernel driver expects the 3 banks to be exposed with specific UIDs associated with a specific banks. ChromeOS firmware maps gpios within a given bank using the bank's MMIO offset. In summary: Bank Type | UID | Offset ----------+-----+------- SCORE | 1 | 0x0000 NCORE | 2 | 0x1000 SUS | 3 | 0x2000 BUG=chrome-os-partner:24408 BUG=chrome-os-partner:24324 BRANCH=None TEST=Built. 'crossystem wpsw_cur' works correctly. Change-Id: I251f86285ce9733f7ca90ed1ebef536f4fe5c07c Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/179513 Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r--host/arch/x86/lib/crossystem_arch.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c
index 922dc649..4f2b6117 100644
--- a/host/arch/x86/lib/crossystem_arch.c
+++ b/host/arch/x86/lib/crossystem_arch.c
@@ -519,6 +519,59 @@ static int FindGpioChipOffset(int *gpio_num, int *offset) {
return (1 == match);
}
+/* BayTrail has 3 sets of GPIO banks. It is expected the firmware exposes
+ * each bank of gpios using a UID in ACPI. Furthermore the gpio number exposed
+ * is relative to the bank. e.g. gpio 6 in the bank specified by UID 3 would
+ * be encoded as 0x2006.
+ * UID | Bank Offset
+ * ----+------------
+ * 1 | 0x0000
+ * 2 | 0x1000
+ * 3 | 0x2000
+ */
+static int BayTrailFindGpioChipOffset(int *gpio_num, int *offset) {
+ DIR *dir;
+ struct dirent *ent;
+ int expected_uid;
+ int match = 0;
+
+ /* Obtain relative GPIO number. */
+ if (*gpio_num >= 0x2000) {
+ *gpio_num -= 0x2000;
+ expected_uid = 3;
+ } else if (*gpio_num >= 0x1000) {
+ *gpio_num -= 0x1000;
+ expected_uid = 2;
+ } else if (*gpio_num >= 0x0000) {
+ *gpio_num -= 0x0000;
+ expected_uid = 1;
+ } else {
+ return 0;
+ }
+
+ dir = opendir(GPIO_BASE_PATH);
+ if (!dir) {
+ return 0;
+ }
+
+ while(0 != (ent = readdir(dir))) {
+ /* For every gpiochip entry determine uid. */
+ if (1 == sscanf(ent->d_name, "gpiochip%d", offset)) {
+ char uid_file[128];
+ snprintf(uid_file, sizeof(uid_file),
+ "%s/gpiochip%d/device/firmware_node/uid", GPIO_BASE_PATH,
+ *offset);
+ if (expected_uid == ReadFileInt(uid_file)) {
+ match++;
+ break;
+ }
+ }
+ }
+
+ closedir(dir);
+ return (1 == match);
+}
+
struct GpioChipset {
const char *name;
@@ -530,6 +583,7 @@ static const struct GpioChipset chipsets_supported[] = {
{ "CougarPoint", FindGpioChipOffset },
{ "PantherPoint", FindGpioChipOffset },
{ "LynxPoint", FindGpioChipOffset },
+ { "BayTrail", BayTrailFindGpioChipOffset },
{ NULL },
};