[coreboot-gerrit] New patch to review for coreboot: drivers/spi/acpi: Add additional generic ACPI support

Duncan Laurie (dlaurie@chromium.org) gerrit at coreboot.org
Sat Feb 18 03:18:36 CET 2017


Duncan Laurie (dlaurie at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18393

-gerrit

commit 1dc4d17cd2dcbbe762dc32dba959b6a7b43c785f
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Fri Feb 17 17:14:35 2017 -0800

    drivers/spi/acpi: Add additional generic ACPI support
    
    Add support for more ACPI features in the generic SPI ACPI
    driver so it can be flexible enough to support more devices,
    or devices in different configurations.
    
    - add a wake pin
    - add support for using IRQ GPIO instead of PIRQ
    - add power resource support with enable and reset gpios
    
    BUG=chrome-os-partner:61233
    TEST=ensure existing SSDT generation is unchanged,
    and test that new features generate expected code
    
    Change-Id: Ibe37cc87e488004baa2c08a369f73c86e6cd6dce
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/drivers/spi/acpi/acpi.c | 85 +++++++++++++++++++++++++++++++++++++++++++--
 src/drivers/spi/acpi/chip.h | 22 +++++++++++-
 2 files changed, 103 insertions(+), 4 deletions(-)

diff --git a/src/drivers/spi/acpi/acpi.c b/src/drivers/spi/acpi/acpi.c
index 0d7d2aa..028a37c 100644
--- a/src/drivers/spi/acpi/acpi.c
+++ b/src/drivers/spi/acpi/acpi.c
@@ -42,10 +42,40 @@ static int spi_acpi_get_bus(struct device *dev)
 	return -1;
 }
 
+static bool spi_acpi_add_gpios_to_crs(struct drivers_spi_acpi_config *config)
+{
+	/*
+	 * Return false if:
+	 * 1. Request to explicitly disable export of GPIOs in CRS, or
+	 * 2. Both reset and enable GPIOs are not provided.
+	 */
+	if (config->disable_gpio_export_in_crs ||
+	    ((config->reset_gpio.pin_count == 0) &&
+	     (config->enable_gpio.pin_count == 0)))
+		return false;
+
+	return true;
+}
+
+static int spi_acpi_write_gpio(struct acpi_gpio *gpio, int *curr_index)
+{
+	int ret = -1;
+
+	if (gpio->pin_count == 0)
+		return ret;
+
+	acpi_device_write_gpio(gpio);
+	ret = *curr_index;
+	(*curr_index)++;
+
+	return ret;
+}
+
 static void spi_acpi_fill_ssdt_generator(struct device *dev)
 {
 	struct drivers_spi_acpi_config *config = dev->chip_info;
 	const char *scope = acpi_device_scope(dev);
+	const char *path = acpi_device_path(dev);
 	struct spi_cfg spi_cfg;
 	struct spi_slave slave;
 	int bus = -1, cs = dev->path.spi.cs;
@@ -54,6 +84,10 @@ static void spi_acpi_fill_ssdt_generator(struct device *dev)
 		.speed = config->speed ? : 1 * MHz,
 		.resource = scope,
 	};
+	int curr_index = 0;
+	int irq_gpio_index = -1;
+	int reset_gpio_index = -1;
+	int enable_gpio_index = -1;
 
 	if (!dev->enabled || !scope)
 		return;
@@ -101,17 +135,62 @@ static void spi_acpi_fill_ssdt_generator(struct device *dev)
 	acpigen_write_name("_CRS");
 	acpigen_write_resourcetemplate_header();
 	acpi_device_write_spi(&spi);
-	acpi_device_write_interrupt(&config->irq);
+
+	/* Use either Interrupt() or GpioInt() */
+	if (config->irq_gpio.pin_count)
+		irq_gpio_index = spi_acpi_write_gpio(&config->irq_gpio,
+						     &curr_index);
+	else
+		acpi_device_write_interrupt(&config->irq);
+
+	/* Add enable/reset GPIOs if needed */
+	if (spi_acpi_add_gpios_to_crs(config)) {
+		reset_gpio_index = spi_acpi_write_gpio(&config->reset_gpio,
+						       &curr_index);
+		enable_gpio_index = spi_acpi_write_gpio(&config->enable_gpio,
+							&curr_index);
+	}
 	acpigen_write_resourcetemplate_footer();
 
-	if (config->compat_string) {
+	/* Wake capabilities */
+	if (config->wake) {
+		acpigen_write_name_integer("_S0W", 4);
+		acpigen_write_PRW(config->wake, 3);
+	};
+
+	/* Write device properties if needed */
+	if (config->compat_string || irq_gpio_index >= 0 ||
+	    reset_gpio_index >= 0 || enable_gpio_index >= 0) {
 		struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
-		acpi_dp_add_string(dsd, "compatible", config->compat_string);
+		if (config->compat_string)
+			acpi_dp_add_string(dsd, "compatible",
+					   config->compat_string);
+		if (irq_gpio_index >= 0)
+			acpi_dp_add_gpio(dsd, "irq-gpios", path,
+					 irq_gpio_index, 0,
+					 config->irq_gpio.polarity);
+		if (reset_gpio_index >= 0)
+			acpi_dp_add_gpio(dsd, "reset-gpios", path,
+					 reset_gpio_index, 0,
+					 config->reset_gpio.polarity);
+		if (enable_gpio_index >= 0)
+			acpi_dp_add_gpio(dsd, "enable-gpios", path,
+					 enable_gpio_index, 0,
+					 config->enable_gpio.polarity);
 		acpi_dp_write(dsd);
 	}
 
+	/* Power Resource */
+	if (config->has_power_resource)
+		acpi_device_add_power_res(
+			&config->reset_gpio, config->reset_delay_ms,
+			&config->enable_gpio, config->enable_delay_ms);
+
 	acpigen_pop_len(); /* Device */
 	acpigen_pop_len(); /* Scope */
+
+	printk(BIOS_INFO, "%s: %s at %s\n", path,
+	       config->desc ? : dev->chip_ops->name, dev_path(dev));
 }
 
 static const char *spi_acpi_name(struct device *dev)
diff --git a/src/drivers/spi/acpi/chip.h b/src/drivers/spi/acpi/chip.h
index f0cc941..6b54100 100644
--- a/src/drivers/spi/acpi/chip.h
+++ b/src/drivers/spi/acpi/chip.h
@@ -24,9 +24,29 @@ struct drivers_spi_acpi_config {
 	const char *name;		/* ACPI Device Name */
 	const char *desc;		/* Device Description */
 	unsigned uid;			/* ACPI _UID */
-	unsigned speed;		/* Bus speed in Hz (default 1MHz) */
+	unsigned speed;			/* Bus speed in Hz (default 1MHz) */
 	const char *compat_string;	/* Compatible string for _HID=PRP0001 */
 	struct acpi_irq irq;		/* Interrupt */
+	unsigned wake;			/* Wake GPE */
+
+	/* Use GPIO based interrupt instead of PIRQ */
+	struct acpi_gpio irq_gpio;
+
+	/* Disable reset and enable GPIO export in _CRS */
+	bool disable_gpio_export_in_crs;
+
+	/* Does the device have a power resource? */
+	bool has_power_resource;
+
+	/* GPIO used to take device out of reset or to put it into reset. */
+	struct acpi_gpio reset_gpio;
+	/* Delay to be inserted after device is taken out of reset. */
+	unsigned reset_delay_ms;
+
+	/* GPIO used to enable device. */
+	struct acpi_gpio enable_gpio;
+	/* Delay to be inserted after device is enabled. */
+	unsigned enable_delay_ms;
 };
 
 #endif /* __SPI_ACPI_CHIP_H__ */



More information about the coreboot-gerrit mailing list