diff mbox

[PATCH/RFC,153/390] gpiolib: separation of pin concerns

Message ID 1364525119-31791-154-git-send-email-horms+renesas@verge.net.au (mailing list archive)
State New, archived
Headers show

Commit Message

Simon Horman March 29, 2013, 2:41 a.m. UTC
From: Linus Walleij <linus.walleij@linaro.org>

The fact that of_gpiochip_add_pin_range() and
gpiochip_add_pin_range() share too much code is fragile and
will invariably mean that bugs need to be fixed in two places
instead of one.

So separate the concerns of gpiolib.c and gpiolib-of.c and
have the latter call the former as back-end. This is necessary
also when going forward with other device descriptions such
as ACPI.

This is done by:

- Adding a return code to gpiochip_add_pin_range() so we can
  reliably check whether this succeeds.

- Get rid of the custom of_pinctrl_add_gpio_range() from
  pinctrl. Instead create of_pinctrl_get() to just retrive the
  pin controller per se from an OF node. This composite
  function was just begging to be deleted, it was way to
  purpose-specific.

- Use pinctrl_dev_get_name() to get the name of the retrieved
  pin controller and use that to call back into the generic
  gpiochip_add_pin_range().

Now the pin range is only allocated and tied to a pin
controller from the core implementation in gpiolib.c.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
(cherry picked from commit 1e63d7b9363f0c57d00991f9f2e0af374dfc591a)

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 drivers/gpio/gpiolib-of.c       |   23 +++++++++--------------
 drivers/gpio/gpiolib.c          |    8 +++++---
 drivers/pinctrl/devicetree.c    |    4 +---
 include/asm-generic/gpio.h      |    4 ++--
 include/linux/gpio.h            |    2 +-
 include/linux/pinctrl/pinctrl.h |    7 ++-----
 6 files changed, 20 insertions(+), 28 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 67403e4..a40cd84 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -221,8 +221,8 @@  EXPORT_SYMBOL(of_mm_gpiochip_add);
 static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
 {
 	struct device_node *np = chip->of_node;
-	struct gpio_pin_range *pin_range;
 	struct of_phandle_args pinspec;
+	struct pinctrl_dev *pctldev;
 	int index = 0, ret;
 
 	if (!np)
@@ -234,22 +234,17 @@  static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
 		if (ret)
 			break;
 
-		pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range),
-				GFP_KERNEL);
-		if (!pin_range) {
-			pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
-					chip->label);
+		pctldev = of_pinctrl_get(pinspec.np);
+		if (!pctldev)
 			break;
-		}
 
-		pin_range->range.name = chip->label;
-		pin_range->range.base = chip->base;
-		pin_range->range.pin_base = pinspec.args[0];
-		pin_range->range.npins = pinspec.args[1];
-		pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np,
-				&pin_range->range);
+		ret = gpiochip_add_pin_range(chip,
+					     pinctrl_dev_get_name(pctldev),
+					     pinspec.args[0],
+					     pinspec.args[1]);
 
-		list_add_tail(&pin_range->node, &chip->pin_ranges);
+		if (ret)
+			break;
 
 	} while (index++);
 }
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 064d2af..b667f76 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1224,8 +1224,8 @@  EXPORT_SYMBOL_GPL(gpiochip_find);
 
 #ifdef CONFIG_PINCTRL
 
-void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
-		unsigned int pin_base, unsigned int npins)
+int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
+			   unsigned int pin_base, unsigned int npins)
 {
 	struct gpio_pin_range *pin_range;
 
@@ -1233,7 +1233,7 @@  void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
 	if (!pin_range) {
 		pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
 				chip->label);
-		return;
+		return -ENOMEM;
 	}
 
 	pin_range->range.name = chip->label;
@@ -1244,6 +1244,8 @@  void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
 			&pin_range->range);
 
 	list_add_tail(&pin_range->node, &chip->pin_ranges);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
 
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index 6728ec7..fe2d1af 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -106,8 +106,7 @@  static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np)
 	return NULL;
 }
 
-struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
-		struct pinctrl_gpio_range *range)
+struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
 {
 	struct pinctrl_dev *pctldev;
 
@@ -115,7 +114,6 @@  struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
 	if (!pctldev)
 		return NULL;
 
-	pinctrl_add_gpio_range(pctldev, range);
 	return pctldev;
 }
 
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 5c1dee8f..b433c63 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -63,8 +63,8 @@  struct gpio_pin_range {
 	struct pinctrl_gpio_range range;
 };
 
-void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
-			    unsigned int pin_base, unsigned int npins);
+int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
+			   unsigned int pin_base, unsigned int npins);
 void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
 
 #endif
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index ad32f87..b5bf774 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -185,7 +185,7 @@  static inline int irq_to_gpio(unsigned irq)
 
 #ifdef CONFIG_PINCTRL
 
-static inline void
+static inline int
 gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
 		       unsigned int pin_base, unsigned int npins)
 {
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index 3b23e80..559ba85 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -130,16 +130,13 @@  extern struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname,
 		struct pinctrl_gpio_range *range);
 
 #ifdef CONFIG_OF
-extern struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
-		struct pinctrl_gpio_range *range);
+extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np);
 #else
 static inline
-struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
-		struct pinctrl_gpio_range *range)
+struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
 {
 	return NULL;
 }
-
 #endif /* CONFIG_OF */
 
 extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);