diff options
author | Aaron Durbin <adurbin@chromium.org> | 2013-12-10 16:05:30 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2013-12-11 19:50:39 +0000 |
commit | 1aa59b0ea545d571f24a64af71f412fb214e4f82 (patch) | |
tree | 85420040088667c4bb25ee7cb41ca18447b6f0fb /host/arch/x86/lib/crossystem_arch.c | |
parent | 31912b61a7c19515f5f5decae8ccad7b8e42f4cf (diff) | |
download | vboot-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>
Diffstat (limited to 'host/arch/x86/lib/crossystem_arch.c')
-rw-r--r-- | host/arch/x86/lib/crossystem_arch.c | 54 |
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 }, }; |