[PATCH] gpiolib-acpi: Set gpiod flags for ACPI GPIO resources based on pullup and polarity

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>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



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux