gpio: acpi: Add managed variant of acpi_dev_add_driver_gpios()
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Thu, 2 Mar 2017 13:48:05 +0000 (15:48 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 15 Mar 2017 10:16:29 +0000 (11:16 +0100)
Introduce device managed variant of acpi_dev_add_driver_gpios() and its
counterpart acpi_dev_remove_driver_gpios().

The functions in most cases are used in driver's ->probe() and
->remove() callbacks, that's why it's useful to have managed variant of
them.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Rafael J. Wysocki <rjw@rjwysocki.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpiolib-acpi.c
include/linux/acpi.h

index 9b37a3692b3feed18578c39f4acc22ba03182e8c..108331de440bafd813eca42f0a73f50ad279869c 100644 (file)
@@ -362,6 +362,37 @@ int acpi_dev_add_driver_gpios(struct acpi_device *adev,
 }
 EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios);
 
+static void devm_acpi_dev_release_driver_gpios(struct device *dev, void *res)
+{
+       acpi_dev_remove_driver_gpios(ACPI_COMPANION(dev));
+}
+
+int devm_acpi_dev_add_driver_gpios(struct device *dev,
+                                  const struct acpi_gpio_mapping *gpios)
+{
+       void *res;
+       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);
+               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));
+}
+EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios);
+
 static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
                                      const char *name, int index,
                                      struct acpi_reference_args *args)
index 673acda012af44efe4fb5a7fc5279d08e416cc86..c8eaaad4a9ed316b839af027c388ff97da56cf49 100644 (file)
@@ -952,6 +952,10 @@ static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev)
                adev->driver_gpios = NULL;
 }
 
+int devm_acpi_dev_add_driver_gpios(struct device *dev,
+                                  const struct acpi_gpio_mapping *gpios);
+void devm_acpi_dev_remove_driver_gpios(struct device *dev);
+
 int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index);
 #else
 static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
@@ -961,6 +965,13 @@ static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
 }
 static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {}
 
+static inline int devm_acpi_dev_add_driver_gpios(struct device *dev,
+                             const struct acpi_gpio_mapping *gpios)
+{
+       return -ENXIO;
+}
+static inline void devm_acpi_dev_remove_driver_gpios(struct device *dev) {}
+
 static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
 {
        return -ENXIO;