diff options
Diffstat (limited to 'drivers/gpio/gpiolib-acpi.c')
-rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index cd3e9657cc..c1e190d3ea 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -126,9 +126,26 @@ static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock); static LIST_HEAD(acpi_gpio_deferred_req_irqs_list); static bool acpi_gpio_deferred_req_irqs_done; -static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) +static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data) { - return device_match_acpi_handle(&gc->gpiodev->dev, data); + /* First check the actual GPIO device */ + if (device_match_acpi_handle(&gc->gpiodev->dev, data)) + return true; + + /* + * When the ACPI device is artificially split to the banks of GPIOs, + * where each of them is represented by a separate GPIO device, + * the firmware node of the physical device may not be shared among + * the banks as they may require different values for the same property, + * e.g., number of GPIOs in a certain bank. In such case the ACPI handle + * of a GPIO device is NULL and can not be used. Hence we have to check + * the parent device to be sure that there is no match before bailing + * out. + */ + if (gc->parent) + return device_match_acpi_handle(gc->parent, data); + + return false; } /** @@ -1402,17 +1419,17 @@ static int acpi_find_gpio_count(struct acpi_resource *ares, void *data) } /** - * acpi_gpio_count - count the GPIOs associated with a device / function - * @dev: GPIO consumer, can be %NULL for system-global GPIOs + * acpi_gpio_count - count the GPIOs associated with a firmware node / function + * @fwnode: firmware node of the GPIO consumer * @con_id: function within the GPIO consumer * * Return: - * The number of GPIOs associated with a device / function or %-ENOENT, + * The number of GPIOs associated with a firmware node / function or %-ENOENT, * if no GPIO has been assigned to the requested function. */ -int acpi_gpio_count(struct device *dev, const char *con_id) +int acpi_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) { - struct acpi_device *adev = ACPI_COMPANION(dev); + struct acpi_device *adev = to_acpi_device_node(fwnode); const union acpi_object *obj; const struct acpi_gpio_mapping *gm; int count = -ENOENT; @@ -1429,8 +1446,7 @@ int acpi_gpio_count(struct device *dev, const char *con_id) snprintf(propname, sizeof(propname), "%s", gpio_suffixes[i]); - ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, - &obj); + ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, &obj); if (ret == 0) { if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) count = 1; |