From patchwork Mon Jan 27 05:05:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 240181 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Jan 2020 22:05:38 -0700 Subject: [PATCH 031/108] gpio: Add a method to convert a GPIO to ACPI In-Reply-To: <20200127050655.170614-1-sjg@chromium.org> References: <20200127050655.170614-1-sjg@chromium.org> Message-ID: <20200126220508.31.I29adaf758a9ea81f51ffbecf89b53983968a0d2a@changeid> 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 --- 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 +#include #include #include #include @@ -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 +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)