summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2014-10-17 14:35:33 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-21 03:03:20 +0000
commit5e646355cb11c8e31c781f6d83cea4aa1690095c (patch)
tree954d983d53322c614079c7e1c526a27cac575d0b
parent298fbe59aebecf6eaf2a1ad9c7fe0144b49a90b3 (diff)
downloadvboot-5e646355cb11c8e31c781f6d83cea4aa1690095c.tar.gz
crossystem: Add support for multiple gpiochip entries
The current logic for finding a GPIO expects only one gpiochip entry to exist in /sys/class/gpio. With Samus there is a second entry because the codec also exports a set of GPIOs. To solve this we can use the gpiochip#/label file and compare against the GPIO controller name described in ACPI. This adds support for that detection method, as well as a new GPIO controller entry for INT3437:00 which is used in Broadwell systems. BUG=chrome-os-partner:33098 BRANCH=samus TEST=crossytem wpsw_cur works on samus (TOT with enabled codec) Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/224156 Reviewed-by: Bill Richardson <wfrichar@chromium.org> (cherry picked from commit 8bb3689d42089241b209ccea2860f03aeaddd8f8) Change-Id: I5763abdf1c9479d82826516f1c36d6374a0df288 Reviewed-on: https://chromium-review.googlesource.com/224572 Commit-Queue: Ricky Liang <jcliang@chromium.org> Tested-by: Ricky Liang <jcliang@chromium.org> Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r--host/arch/x86/lib/crossystem_arch.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c
index eb87f84d..15a6433e 100644
--- a/host/arch/x86/lib/crossystem_arch.c
+++ b/host/arch/x86/lib/crossystem_arch.c
@@ -505,7 +505,8 @@ static char* ReadPlatformFamilyString(char* dest, int size) {
* 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(unsigned *gpio_num, unsigned *offset) {
+static int FindGpioChipOffset(unsigned *gpio_num, unsigned *offset,
+ const char *name) {
DIR *dir;
struct dirent *ent;
int match = 0;
@@ -525,6 +526,43 @@ static int FindGpioChipOffset(unsigned *gpio_num, unsigned *offset) {
return (1 == match);
}
+/* 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>/ and check for
+ * a 'label' file inside of it to find the expected the controller name.
+ */
+static int FindGpioChipOffsetByLabel(unsigned *gpio_num, unsigned *offset,
+ const char *name) {
+ DIR *dir;
+ struct dirent *ent;
+ char filename[128];
+ char chiplabel[128];
+ int match = 0;
+
+ dir = opendir(GPIO_BASE_PATH);
+ if (!dir) {
+ return 0;
+ }
+
+ while(0 != (ent = readdir(dir))) {
+ if (1 == sscanf(ent->d_name, "gpiochip%u", offset)) {
+ /*
+ * Read the file at gpiochip<O>/label to get the identifier
+ * for this bank of GPIOs.
+ */
+ snprintf(filename, sizeof(filename), "%s/gpiochip%u/label",
+ GPIO_BASE_PATH, *offset);
+ if (ReadFileString(chiplabel, sizeof(chiplabel), filename)) {
+ if (!strncasecmp(chiplabel, name, strlen(name)))
+ match++;
+ }
+ }
+ }
+
+ closedir(dir);
+ 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
@@ -535,7 +573,8 @@ static int FindGpioChipOffset(unsigned *gpio_num, unsigned *offset) {
* 2 | 0x1000
* 3 | 0x2000
*/
-static int BayTrailFindGpioChipOffset(unsigned *gpio_num, unsigned *offset) {
+static int BayTrailFindGpioChipOffset(unsigned *gpio_num, unsigned *offset,
+ const char *name) {
DIR *dir;
struct dirent *ent;
unsigned expected_uid;
@@ -584,7 +623,8 @@ static int BayTrailFindGpioChipOffset(unsigned *gpio_num, unsigned *offset) {
struct GpioChipset {
const char *name;
- int (*ChipOffsetAndGpioNumber)(unsigned *gpio_num, unsigned *chip_offset);
+ int (*ChipOffsetAndGpioNumber)(unsigned *gpio_num, unsigned *chip_offset,
+ const char *name);
};
static const struct GpioChipset chipsets_supported[] = {
@@ -593,6 +633,7 @@ static const struct GpioChipset chipsets_supported[] = {
{ "PantherPoint", FindGpioChipOffset },
{ "LynxPoint", FindGpioChipOffset },
{ "PCH-LP", FindGpioChipOffset },
+ { "INT3437:00", FindGpioChipOffsetByLabel },
{ "BayTrail", BayTrailFindGpioChipOffset },
{ NULL },
};
@@ -651,7 +692,8 @@ static int ReadGpio(unsigned signal_type) {
return -1;
/* Modify GPIO number by driver's offset */
- if (!chipset->ChipOffsetAndGpioNumber(&controller_num, &controller_offset))
+ if (!chipset->ChipOffsetAndGpioNumber(&controller_num, &controller_offset,
+ chipset->name))
return -1;
controller_offset += controller_num;