aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2012-11-06 10:03:35 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-11-11 13:06:07 -0500
commit1e63d7b9363f0c57d00991f9f2e0af374dfc591a (patch)
tree6bea7bfdd9dbfbe21433629b3f2a9758c92447be
parent9ef0d6f7628bdcb5cc3c11623930f2527a3881a0 (diff)
gpiolib: separation of pin concerns
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>
-rw-r--r--drivers/gpio/gpiolib-of.c23
-rw-r--r--drivers/gpio/gpiolib.c8
-rw-r--r--drivers/pinctrl/devicetree.c4
-rw-r--r--include/asm-generic/gpio.h4
-rw-r--r--include/linux/gpio.h2
-rw-r--r--include/linux/pinctrl/pinctrl.h7
6 files changed, 20 insertions, 28 deletions
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 67403e47e4dc..a40cd84c5c10 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -221,8 +221,8 @@ EXPORT_SYMBOL(of_mm_gpiochip_add);
221static void of_gpiochip_add_pin_range(struct gpio_chip *chip) 221static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
222{ 222{
223 struct device_node *np = chip->of_node; 223 struct device_node *np = chip->of_node;
224 struct gpio_pin_range *pin_range;
225 struct of_phandle_args pinspec; 224 struct of_phandle_args pinspec;
225 struct pinctrl_dev *pctldev;
226 int index = 0, ret; 226 int index = 0, ret;
227 227
228 if (!np) 228 if (!np)
@@ -234,22 +234,17 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
234 if (ret) 234 if (ret)
235 break; 235 break;
236 236
237 pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), 237 pctldev = of_pinctrl_get(pinspec.np);
238 GFP_KERNEL); 238 if (!pctldev)
239 if (!pin_range) {
240 pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
241 chip->label);
242 break; 239 break;
243 }
244 240
245 pin_range->range.name = chip->label; 241 ret = gpiochip_add_pin_range(chip,
246 pin_range->range.base = chip->base; 242 pinctrl_dev_get_name(pctldev),
247 pin_range->range.pin_base = pinspec.args[0]; 243 pinspec.args[0],
248 pin_range->range.npins = pinspec.args[1]; 244 pinspec.args[1]);
249 pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np,
250 &pin_range->range);
251 245
252 list_add_tail(&pin_range->node, &chip->pin_ranges); 246 if (ret)
247 break;
253 248
254 } while (index++); 249 } while (index++);
255} 250}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index bcf9b9914fb7..c5f650095faa 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1187,8 +1187,8 @@ EXPORT_SYMBOL_GPL(gpiochip_find);
1187 1187
1188#ifdef CONFIG_PINCTRL 1188#ifdef CONFIG_PINCTRL
1189 1189
1190void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, 1190int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
1191 unsigned int pin_base, unsigned int npins) 1191 unsigned int pin_base, unsigned int npins)
1192{ 1192{
1193 struct gpio_pin_range *pin_range; 1193 struct gpio_pin_range *pin_range;
1194 1194
@@ -1196,7 +1196,7 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
1196 if (!pin_range) { 1196 if (!pin_range) {
1197 pr_err("%s: GPIO chip: failed to allocate pin ranges\n", 1197 pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
1198 chip->label); 1198 chip->label);
1199 return; 1199 return -ENOMEM;
1200 } 1200 }
1201 1201
1202 pin_range->range.name = chip->label; 1202 pin_range->range.name = chip->label;
@@ -1207,6 +1207,8 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
1207 &pin_range->range); 1207 &pin_range->range);
1208 1208
1209 list_add_tail(&pin_range->node, &chip->pin_ranges); 1209 list_add_tail(&pin_range->node, &chip->pin_ranges);
1210
1211 return 0;
1210} 1212}
1211EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); 1213EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
1212 1214
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index 6728ec71cb65..fe2d1af7cfa0 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)
106 return NULL; 106 return NULL;
107} 107}
108 108
109struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, 109struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
110 struct pinctrl_gpio_range *range)
111{ 110{
112 struct pinctrl_dev *pctldev; 111 struct pinctrl_dev *pctldev;
113 112
@@ -115,7 +114,6 @@ struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
115 if (!pctldev) 114 if (!pctldev)
116 return NULL; 115 return NULL;
117 116
118 pinctrl_add_gpio_range(pctldev, range);
119 return pctldev; 117 return pctldev;
120} 118}
121 119
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 2e60de4265ac..50d995e7e44a 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -63,8 +63,8 @@ struct gpio_pin_range {
63 struct pinctrl_gpio_range range; 63 struct pinctrl_gpio_range range;
64}; 64};
65 65
66void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, 66int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
67 unsigned int pin_base, unsigned int npins); 67 unsigned int pin_base, unsigned int npins);
68void gpiochip_remove_pin_ranges(struct gpio_chip *chip); 68void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
69 69
70#endif 70#endif
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 21d28b930dc7..81bbfe5b5de6 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -233,7 +233,7 @@ static inline int irq_to_gpio(unsigned irq)
233 233
234#ifdef CONFIG_PINCTRL 234#ifdef CONFIG_PINCTRL
235 235
236static inline void 236static inline int
237gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, 237gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
238 unsigned int pin_base, unsigned int npins) 238 unsigned int pin_base, unsigned int npins)
239{ 239{
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index 434e5a94e131..4a58428bc793 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -141,16 +141,13 @@ extern struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname,
141 struct pinctrl_gpio_range *range); 141 struct pinctrl_gpio_range *range);
142 142
143#ifdef CONFIG_OF 143#ifdef CONFIG_OF
144extern struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, 144extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np);
145 struct pinctrl_gpio_range *range);
146#else 145#else
147static inline 146static inline
148struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, 147struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
149 struct pinctrl_gpio_range *range)
150{ 148{
151 return NULL; 149 return NULL;
152} 150}
153
154#endif /* CONFIG_OF */ 151#endif /* CONFIG_OF */
155 152
156extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); 153extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);