mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
gpiolib-acpi: introduce acpi_get_gpio_by_index() helper
Instead of open-coding ACPI GPIO resource lookup in each driver, we provide a helper function analogous to Device Tree version that allows drivers to specify which GPIO resource they are interested (using an index to the GPIO resources). The function then finds out the correct resource, translates the ACPI GPIO number to the corresponding Linux GPIO number and returns that. Signed-off-by: Mika Westerberg <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
This commit is contained in:
parent
2ce7c62d1b
commit
12028d2d21
3 changed files with 125 additions and 1 deletions
|
|
@ -201,6 +201,83 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
|
|||
}
|
||||
EXPORT_SYMBOL(acpi_gpiochip_request_interrupts);
|
||||
|
||||
struct acpi_gpio_lookup {
|
||||
struct acpi_gpio_info info;
|
||||
int index;
|
||||
int gpio;
|
||||
int n;
|
||||
};
|
||||
|
||||
static int acpi_find_gpio(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct acpi_gpio_lookup *lookup = data;
|
||||
|
||||
if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
|
||||
return 1;
|
||||
|
||||
if (lookup->n++ == lookup->index && lookup->gpio < 0) {
|
||||
const struct acpi_resource_gpio *agpio = &ares->data.gpio;
|
||||
|
||||
lookup->gpio = acpi_get_gpio(agpio->resource_source.string_ptr,
|
||||
agpio->pin_table[0]);
|
||||
lookup->info.gpioint =
|
||||
agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_get_gpio_by_index() - get a GPIO number from device resources
|
||||
* @dev: pointer to a device to get GPIO from
|
||||
* @index: index of GpioIo/GpioInt resource (starting from %0)
|
||||
* @info: info pointer to fill in (optional)
|
||||
*
|
||||
* Function goes through ACPI resources for @dev and based on @index looks
|
||||
* up a GpioIo/GpioInt resource, translates it to the Linux GPIO number,
|
||||
* and returns it. @index matches GpioIo/GpioInt resources only so if there
|
||||
* are total %3 GPIO resources, the index goes from %0 to %2.
|
||||
*
|
||||
* If the GPIO cannot be translated or there is an error, negative errno is
|
||||
* returned.
|
||||
*
|
||||
* Note: if the GPIO resource has multiple entries in the pin list, this
|
||||
* function only returns the first.
|
||||
*/
|
||||
int acpi_get_gpio_by_index(struct device *dev, int index,
|
||||
struct acpi_gpio_info *info)
|
||||
{
|
||||
struct acpi_gpio_lookup lookup;
|
||||
struct list_head resource_list;
|
||||
struct acpi_device *adev;
|
||||
acpi_handle handle;
|
||||
int ret;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
handle = ACPI_HANDLE(dev);
|
||||
if (!handle || acpi_bus_get_device(handle, &adev))
|
||||
return -ENODEV;
|
||||
|
||||
memset(&lookup, 0, sizeof(lookup));
|
||||
lookup.index = index;
|
||||
lookup.gpio = -ENODEV;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
|
||||
&lookup);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
if (lookup.gpio >= 0 && info)
|
||||
*info = lookup.info;
|
||||
|
||||
return lookup.gpio;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_get_gpio_by_index);
|
||||
|
||||
/**
|
||||
* acpi_gpiochip_free_interrupts() - Free GPIO _EVT ACPI event interrupts.
|
||||
|
|
|
|||
Loading…
Reference in a new issue