diff options
Diffstat (limited to 'drivers/gpio/gpiolib-acpi.c')
-rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 54 |
1 files changed, 25 insertions, 29 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 985e8589c58b..c0f6a25c3279 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -219,14 +219,13 @@ EXPORT_SYMBOL_GPL(acpi_gpio_get_io_resource); static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio, struct acpi_gpio_event *event) { + struct device *parent = acpi_gpio->chip->parent; int ret, value; ret = request_threaded_irq(event->irq, NULL, event->handler, event->irqflags | IRQF_ONESHOT, "ACPI:Event", event); if (ret) { - dev_err(acpi_gpio->chip->parent, - "Failed to setup interrupt handler for %d\n", - event->irq); + dev_err(parent, "Failed to setup interrupt handler for %d\n", event->irq); return; } @@ -347,8 +346,7 @@ static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in) return false; err: - pr_err_once("Error invalid value for gpiolib_acpi.ignore_wake: %s\n", - ignore_wake); + pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_wake: %s\n", ignore_wake); return false; } @@ -579,36 +577,24 @@ void acpi_dev_remove_driver_gpios(struct acpi_device *adev) } EXPORT_SYMBOL_GPL(acpi_dev_remove_driver_gpios); -static void devm_acpi_dev_release_driver_gpios(struct device *dev, void *res) +static void acpi_dev_release_driver_gpios(void *adev) { - acpi_dev_remove_driver_gpios(ACPI_COMPANION(dev)); + acpi_dev_remove_driver_gpios(adev); } int devm_acpi_dev_add_driver_gpios(struct device *dev, const struct acpi_gpio_mapping *gpios) { - void *res; + struct acpi_device *adev = ACPI_COMPANION(dev); int ret; - res = devres_alloc(devm_acpi_dev_release_driver_gpios, 0, GFP_KERNEL); - if (!res) - return -ENOMEM; - - ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), gpios); - if (ret) { - devres_free(res); + ret = acpi_dev_add_driver_gpios(adev, gpios); + if (ret) return ret; - } - devres_add(dev, res); - return 0; -} -EXPORT_SYMBOL_GPL(devm_acpi_dev_add_driver_gpios); -void devm_acpi_dev_remove_driver_gpios(struct device *dev) -{ - WARN_ON(devres_release(dev, devm_acpi_dev_release_driver_gpios, NULL, NULL)); + return devm_add_action_or_reset(dev, acpi_dev_release_driver_gpios, adev); } -EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios); +EXPORT_SYMBOL_GPL(devm_acpi_dev_add_driver_gpios); static bool acpi_get_driver_gpio_data(struct acpi_device *adev, const char *name, int index, @@ -941,7 +927,7 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, if (info.gpioint && (*dflags == GPIOD_OUT_LOW || *dflags == GPIOD_OUT_HIGH)) { - dev_dbg(dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n"); + dev_dbg(&adev->dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n"); return ERR_PTR(-ENOENT); } @@ -1056,10 +1042,17 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind irq_flags = acpi_dev_get_irq_type(info.triggering, info.polarity); - /* Set type if specified and different than the current one */ - if (irq_flags != IRQ_TYPE_NONE && - irq_flags != irq_get_trigger_type(irq)) - irq_set_irq_type(irq, irq_flags); + /* + * If the IRQ is not already in use then set type + * if specified and different than the current one. + */ + if (can_request_irq(irq, irq_flags)) { + if (irq_flags != IRQ_TYPE_NONE && + irq_flags != irq_get_trigger_type(irq)) + irq_set_irq_type(irq, irq_flags); + } else { + dev_dbg(&adev->dev, "IRQ %d already in use\n", irq); + } return irq; } @@ -1346,6 +1339,9 @@ void acpi_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev) /* Set default fwnode to parent's one if present */ if (gc->parent) ACPI_COMPANION_SET(&gdev->dev, ACPI_COMPANION(gc->parent)); + + if (gc->fwnode) + device_set_node(&gdev->dev, gc->fwnode); } static int acpi_gpio_package_count(const union acpi_object *obj) |