summaryrefslogtreecommitdiff
path: root/target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch')
-rw-r--r--target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch115
1 files changed, 115 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch b/target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch
new file mode 100644
index 0000000..ab2fb07
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch
@@ -0,0 +1,115 @@
+From 0cf3292cde22f8843ae5d1eeb8466d8121243c1a Mon Sep 17 00:00:00 2001
+From: Laxman Dewangan <ldewangan@nvidia.com>
+Date: Mon, 15 Feb 2016 16:32:09 +0530
+Subject: [PATCH] gpio: Add devm_ apis for gpiochip_add_data and
+ gpiochip_remove
+
+Add device managed APIs devm_gpiochip_add_data() and
+devm_gpiochip_remove() for the APIs gpiochip_add_data()
+and gpiochip_remove().
+
+This helps in reducing code in error path and sometimes
+removal of .remove callback for driver unbind.
+
+Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
+---
+ drivers/gpio/gpiolib.c | 74 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/gpio/driver.h | 4 +++
+ 2 files changed, 78 insertions(+)
+
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -433,6 +433,80 @@ void gpiochip_remove(struct gpio_chip *c
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_remove);
+
++static void devm_gpio_chip_release(struct device *dev, void *res)
++{
++ struct gpio_chip *chip = *(struct gpio_chip **)res;
++
++ gpiochip_remove(chip);
++}
++
++static int devm_gpio_chip_match(struct device *dev, void *res, void *data)
++
++{
++ struct gpio_chip **r = res;
++
++ if (!r || !*r) {
++ WARN_ON(!r || !*r);
++ return 0;
++ }
++
++ return *r == data;
++}
++
++/**
++ * devm_gpiochip_add_data() - Resource manager piochip_add_data()
++ * @dev: the device pointer on which irq_chip belongs to.
++ * @chip: the chip to register, with chip->base initialized
++ * Context: potentially before irqs will work
++ *
++ * Returns a negative errno if the chip can't be registered, such as
++ * because the chip->base is invalid or already associated with a
++ * different chip. Otherwise it returns zero as a success code.
++ *
++ * The gpio chip automatically be released when the device is unbound.
++ */
++int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip,
++ void *data)
++{
++ struct gpio_chip **ptr;
++ int ret;
++
++ ptr = devres_alloc(devm_gpio_chip_release, sizeof(*ptr),
++ GFP_KERNEL);
++ if (!ptr)
++ return -ENOMEM;
++
++ ret = gpiochip_add_data(chip, data);
++ if (ret < 0) {
++ devres_free(ptr);
++ return ret;
++ }
++
++ *ptr = chip;
++ devres_add(dev, ptr);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(devm_gpiochip_add_data);
++
++/**
++ * devm_gpiochip_remove() - Resource manager of gpiochip_remove()
++ * @dev: device for which which resource was allocated
++ * @chip: the chip to remove
++ *
++ * A gpio_chip with any GPIOs still requested may not be removed.
++ */
++void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip)
++{
++ int ret;
++
++ ret = devres_release(dev, devm_gpio_chip_release,
++ devm_gpio_chip_match, chip);
++ if (!ret)
++ WARN_ON(ret);
++}
++EXPORT_SYMBOL_GPL(devm_gpiochip_remove);
++
+ /**
+ * gpiochip_find() - iterator for locating a specific gpio_chip
+ * @data: data to pass to match function
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -206,6 +206,10 @@ static inline int gpiochip_add(struct gp
+ return gpiochip_add_data(chip, NULL);
+ }
+ extern void gpiochip_remove(struct gpio_chip *chip);
++extern int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip,
++ void *data);
++extern void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip);
++
+ extern struct gpio_chip *gpiochip_find(void *data,
+ int (*match)(struct gpio_chip *chip, void *data));
+