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 58c21f0db095172cf5f76323a4140d3e9a2b7a90 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 | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 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..a8b5dfa 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; @@ -36,6 +51,8 @@ static void i2c_generic_fill_ssdt(struct device *dev) .resource = scope, }; struct acpi_dp *dsd = NULL; + int reset_index; + const char *path = acpi_device_path(dev);
if (!dev->enabled || !scope) return; @@ -58,6 +75,7 @@ static void i2c_generic_fill_ssdt(struct device *dev) 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,16 +84,24 @@ static void i2c_generic_fill_ssdt(struct device *dev) acpigen_write_PRW(config->wake, 3); }
- if (config->probed) { + /* Device-specific data */ + /* Decide if _DSD is required. */ + if (config->probed || (reset_index != -1)) dsd = acpi_dp_new_table("_DSD"); - acpi_dp_add_integer(dsd, "linux,probed", 1); + + acpi_dp_add_integer(dsd, "linux,probed", config->probed); + + if (reset_index != -1) + acpi_dp_add_gpio(dsd, "reset-gpio", path, reset_index, 0, + config->reset_gpio.polarity); + + if (dsd) acpi_dp_write(dsd); - }
acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */
- printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), + printk(BIOS_INFO, "%s: %s at %s\n", path, config->desc ? : dev->chip_ops->name, dev_path(dev)); }