Commit 2eca25af authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Linus Walleij

gpio: acpi: Factor out acpi_gpio_to_gpiod_flags() helper

The helper function acpi_gpio_to_gpiod_flags() will be used later to configure
pin properly whenever it's requested.

While here, introduce a checking error code returned by gpiod_configure_flags()
and bail out if it's not okay.
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: default avatarJarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent ed7fcf1e
...@@ -423,6 +423,31 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev, ...@@ -423,6 +423,31 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
return false; return false;
} }
static enum gpiod_flags
acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio)
{
bool pull_up = agpio->pin_config == ACPI_PIN_CONFIG_PULLUP;
switch (agpio->io_restriction) {
case ACPI_IO_RESTRICT_INPUT:
return GPIOD_IN;
case ACPI_IO_RESTRICT_OUTPUT:
/*
* 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.
*/
return pull_up ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
default:
/*
* Assume that the BIOS has configured the direction and pull
* accordingly.
*/
return GPIOD_ASIS;
}
}
struct acpi_gpio_lookup { struct acpi_gpio_lookup {
struct acpi_gpio_info info; struct acpi_gpio_info info;
int index; int index;
...@@ -740,7 +765,6 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, ...@@ -740,7 +765,6 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
struct acpi_resource *ares; struct acpi_resource *ares;
int pin_index = (int)address; int pin_index = (int)address;
acpi_status status; acpi_status status;
bool pull_up;
int length; int length;
int i; int i;
...@@ -755,7 +779,6 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, ...@@ -755,7 +779,6 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
} }
agpio = &ares->data.gpio; agpio = &ares->data.gpio;
pull_up = agpio->pin_config == ACPI_PIN_CONFIG_PULLUP;
if (WARN_ON(agpio->io_restriction == ACPI_IO_RESTRICT_INPUT && if (WARN_ON(agpio->io_restriction == ACPI_IO_RESTRICT_INPUT &&
function == ACPI_WRITE)) { function == ACPI_WRITE)) {
...@@ -806,35 +829,23 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, ...@@ -806,35 +829,23 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
} }
if (!found) { if (!found) {
desc = gpiochip_request_own_desc(chip, pin, enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio);
"ACPI:OpRegion"); const char *label = "ACPI:OpRegion";
int err;
desc = gpiochip_request_own_desc(chip, pin, label);
if (IS_ERR(desc)) { if (IS_ERR(desc)) {
status = AE_ERROR; status = AE_ERROR;
mutex_unlock(&achip->conn_lock); mutex_unlock(&achip->conn_lock);
goto out; goto out;
} }
switch (agpio->io_restriction) { err = gpiod_configure_flags(desc, label, 0, flags);
case ACPI_IO_RESTRICT_INPUT: if (err < 0) {
gpiod_direction_input(desc); status = AE_NOT_CONFIGURED;
break; gpiochip_free_own_desc(desc);
case ACPI_IO_RESTRICT_OUTPUT: mutex_unlock(&achip->conn_lock);
/* goto out;
* 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.
*/
gpiod_direction_output(desc, pull_up);
break;
default:
/*
* Assume that the BIOS has configured the
* direction and pull accordingly.
*/
break;
} }
conn = kzalloc(sizeof(*conn), GFP_KERNEL); conn = kzalloc(sizeof(*conn), GFP_KERNEL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment