[PATCH 031/108] gpio: Add a method to convert a GPIO to ACPI
Simon Glass
sjg at chromium.org
Mon Jan 27 06:05:38 CET 2020
When generating ACPI tables we need to convert GPIOs in U-Boot to the ACPI
structures required by ACPI. This is a SoC-specific conversion and cannot
be handled by generic code, so add a new GPIO method to do the conversion.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
drivers/gpio/gpio-uclass.c | 21 +++++++++++++++++++++
include/acpi_device.h | 12 ++++++++++++
include/asm-generic/gpio.h | 27 +++++++++++++++++++++++++++
lib/acpi/acpi_device.c | 16 ++++++++++++++++
4 files changed, 76 insertions(+)
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index c3c60a73eb..b49f64d90d 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -4,6 +4,7 @@
*/
#include <common.h>
+#include <acpi_device.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
@@ -697,6 +698,26 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
return 0;
}
+#if CONFIG_IS_ENABLED(ACPIGEN)
+int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
+{
+ struct dm_gpio_ops *ops;
+
+ if (!dm_gpio_is_valid(desc)) {
+ /* Indicate that the GPIO is not valid */
+ gpio->pin_count = 0;
+ gpio->pins[0] = 0;
+ return -EINVAL;
+ }
+
+ ops = gpio_get_ops(desc->dev);
+ if (!ops->get_acpi)
+ return -ENOSYS;
+
+ return ops->get_acpi(desc, gpio);
+}
+#endif
+
int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
{
int i, ret;
diff --git a/include/acpi_device.h b/include/acpi_device.h
index 919e6bcdaa..fd047f3944 100644
--- a/include/acpi_device.h
+++ b/include/acpi_device.h
@@ -533,6 +533,18 @@ size_t acpi_dp_add_property_list(struct acpi_dp *dp,
*/
int acpi_dp_write(struct acpi_ctx *ctx, struct acpi_dp *table);
+/**
+ * acpi_device_write_gpio_desc() - Write a GPIO to ACPI
+ *
+ * This creates a GPIO descriptor for a GPIO, including information ACPI needs
+ * to use it. The type is always ACPI_GPIO_TYPE_IO.
+ *
+ * @desc: GPIO to write
+ * @return 0 if OK, -ve on error
+ */
+int acpi_device_write_gpio_desc(struct acpi_ctx *ctx,
+ const struct gpio_desc *desc);
+
/**
* acpi_device_write_i2c_dev() - Write an I2C device to ACPI, including
* information ACPI needs to use it.
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index d6cf18744f..42e112ee66 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -9,6 +9,7 @@
#include <dm/ofnode.h>
+struct acpi_gpio;
struct ofnode_phandle_args;
/*
@@ -290,6 +291,20 @@ struct dm_gpio_ops {
*/
int (*xlate)(struct udevice *dev, struct gpio_desc *desc,
struct ofnode_phandle_args *args);
+
+#if CONFIG_IS_ENABLED(ACPIGEN)
+ /**
+ * get_acpi() - Get the ACPI info for a GPIO
+ *
+ * This converts a GPIO to an ACPI structure for adding to the ACPI
+ * tables.
+ *
+ * @desc: GPIO description to convert
+ * @gpio: Output ACPI GPIO information
+ * @return ACPI pin number or -ve on error
+ */
+ int (*get_acpi)(const struct gpio_desc *desc, struct acpi_gpio *gpio);
+#endif
};
/**
@@ -657,4 +672,16 @@ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
*/
int gpio_get_number(const struct gpio_desc *desc);
+/**
+ * gpio_get_acpi() - Get the ACPI pin for a GPIO
+ *
+ * This converts a GPIO to an ACPI pin number for adding to the ACPI
+ * tables. If the GPIO is invalid, the pin_count and pins[0] are set to 0
+ *
+ * @desc: GPIO description to convert
+ * @gpio: Output ACPI GPIO information
+ * @return ACPI pin number or -ve on error
+ */
+int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio);
+
#endif /* _ASM_GENERIC_GPIO_H_ */
diff --git a/lib/acpi/acpi_device.c b/lib/acpi/acpi_device.c
index 2d03639714..d94a403aa1 100644
--- a/lib/acpi/acpi_device.c
+++ b/lib/acpi/acpi_device.c
@@ -287,6 +287,22 @@ int acpi_device_write_gpio(struct acpi_ctx *ctx, const struct acpi_gpio *gpio)
return 0;
}
+int acpi_device_write_gpio_desc(struct acpi_ctx *ctx,
+ const struct gpio_desc *desc)
+{
+ struct acpi_gpio gpio;
+ int ret;
+
+ ret = gpio_get_acpi(desc, &gpio);
+ if (ret)
+ return log_msg_ret("desc", ret);
+ ret = acpi_device_write_gpio(ctx, &gpio);
+ if (ret)
+ return log_msg_ret("gpio", ret);
+
+ return 0;
+}
+
/* ACPI 6.1 section 6.4.3.8.2.1 - I2cSerialBus() */
static void acpi_device_write_i2c(struct acpi_ctx *ctx,
const struct acpi_i2c *i2c)
--
2.25.0.341.g760bfbb309-goog
More information about the U-Boot
mailing list