Furquan Shaikh (furquan@google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16872
-gerrit
commit 3d502453f17410be94989c632121774c8587d81d Author: Furquan Shaikh furquan@chromium.org Date: Mon Oct 3 23:43:06 2016 -0700
i2c/generic: Add support for passing reset-gpio in ACPI
There are two things required to pass reset-gpio via ACPI: 1. Add GPIO to _CRS 2. Add reset-gpio property in _DSD with index in _CRS to the corresponding gpio.
Implement function to add gpio to _CRS and return appropriate index. This can be useful if later we need to add more gpio properties with appropriate indices.
BUG=chrome-os-partner:55988 BRANCH=None TEST=Verified that reset-gpio property appears in SSDT on reef.
Change-Id: Ibbf7d6f3916fb43bd722de21391e635c07dd81f7 Signed-off-by: Furquan Shaikh furquan@chromium.org --- src/drivers/i2c/generic/chip.h | 3 +++ src/drivers/i2c/generic/generic.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/src/drivers/i2c/generic/chip.h b/src/drivers/i2c/generic/chip.h index d84097f..7e319b4 100644 --- a/src/drivers/i2c/generic/chip.h +++ b/src/drivers/i2c/generic/chip.h @@ -22,4 +22,7 @@ struct drivers_i2c_generic_config { /* GPIO used to indicate if this device is present */ unsigned device_present_gpio; unsigned device_present_gpio_invert; + + /* GPIO used to reset the device. */ + struct acpi_gpio reset_gpio; }; diff --git a/src/drivers/i2c/generic/generic.c b/src/drivers/i2c/generic/generic.c index 30a280b..8a2cc23 100644 --- a/src/drivers/i2c/generic/generic.c +++ b/src/drivers/i2c/generic/generic.c @@ -25,6 +25,21 @@ #include "chip.h"
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + +static int i2c_generic_device_write_gpio(struct acpi_gpio *gpio) +{ + static int gpio_index = 0; + int ret = -1; + + if (gpio->pin_count) { + acpi_device_write_gpio(gpio); + ret = gpio_index; + gpio_index++; + } + + return ret; +} + static void i2c_generic_fill_ssdt(struct device *dev) { struct drivers_i2c_generic_config *config = dev->chip_info; @@ -54,10 +69,13 @@ static void i2c_generic_fill_ssdt(struct device *dev) acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
/* Resources */ + int reset_index; + acpigen_write_name("_CRS"); acpigen_write_resourcetemplate_header(); acpi_device_write_i2c(&i2c); acpi_device_write_interrupt(&config->irq); + reset_index = i2c_generic_device_write_gpio(&config->reset_gpio); acpigen_write_resourcetemplate_footer();
/* Wake capabilities */ @@ -66,11 +84,21 @@ static void i2c_generic_fill_ssdt(struct device *dev) acpigen_write_PRW(config->wake, 3); }
- if (config->probed) { + /* Device-specific data */ + const char *path = acpi_device_path(dev); + + /* Decide if _DSD is required. */ + if (config->probed || (reset_index != -1)) dsd = acpi_dp_new_table("_DSD"); + + if (config->probed) acpi_dp_add_integer(dsd, "linux,probed", 1); + + if (reset_index != -1) + acpi_dp_add_gpio(dsd, "reset-gpio", path, reset_index, 0, 0); + + if (dsd) acpi_dp_write(dsd); - }
acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */