>From f8093f2c73c636b75fcf4dee4178af0e24c2f878 Mon Sep 17 00:00:00 2001 From: Vasile-Laurentiu Stanimir <vasile-laurentiu.stanimir@xxxxxxxxxxxxx> Date: Mon, 2 Dec 2019 14:20:11 +0200 Subject: [PATCH] gpiolib-acpi: Set gpiod flags for ACPI GPIO resources based on pullup and polarity ACPI GPIO resources don't contain an initial value for the GPIO. Therefore instead of deducting its value based on pullup field we should deduce that value from the polarity and the pull field. Typical scenario is when ACPI is defined in acpi-table and its polarity is defined as ACTIVE-LOW in the following call: acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio) it will return GPIOD_OUT_HIGH if pull_up is set no matter if polarity is GPIO_ACTIVE_LOW, so it will return the current level instead of the logical level. Signed-off-by: Vasile-Laurentiu Stanimir <vasile-laurentiu.stanimir@xxxxxxxxxxxxx> --- drivers/gpio/gpiolib-acpi.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index a3e43cacd78e..a3e327d05e26 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -420,7 +420,7 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev, } static enum gpiod_flags -acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio) +acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio, int polarity) { bool pull_up = agpio->pin_config == ACPI_PIN_CONFIG_PULLUP; @@ -431,9 +431,16 @@ acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio) /* * ACPI GPIO resources don't contain an initial value for the * GPIO. Therefore we deduce that value from the pull field - * instead. If the pin is pulled up we assume default to be - * high, otherwise low. + * and the polarity instead. + * By default if the pin is pulled up we assume default to be + * high, otherwise low. For ACTIVE LOW polarity values will be + * switched. */ + if (agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_IO && + polarity == GPIO_ACTIVE_LOW) { + return pull_up ? GPIOD_OUT_LOW : GPIOD_OUT_HIGH; + } + return pull_up ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; default: /* @@ -532,8 +539,9 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) lookup->info.polarity = agpio->polarity; lookup->info.triggering = agpio->triggering; } else { - lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio); lookup->info.polarity = lookup->active_low; + lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio, + lookup->info.polarity); } } @@ -881,7 +889,8 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, } if (!found) { - enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio); + enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio, + agpio->polarity); const char *label = "ACPI:OpRegion"; int err; -- 2.17.1