diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2012-11-06 10:03:35 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-11-11 13:06:07 -0500 |
commit | 1e63d7b9363f0c57d00991f9f2e0af374dfc591a (patch) | |
tree | 6bea7bfdd9dbfbe21433629b3f2a9758c92447be | |
parent | 9ef0d6f7628bdcb5cc3c11623930f2527a3881a0 (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.c | 23 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 8 | ||||
-rw-r--r-- | drivers/pinctrl/devicetree.c | 4 | ||||
-rw-r--r-- | include/asm-generic/gpio.h | 4 | ||||
-rw-r--r-- | include/linux/gpio.h | 2 | ||||
-rw-r--r-- | include/linux/pinctrl/pinctrl.h | 7 |
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); | |||
221 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) | 221 | static 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 | ||
1190 | void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | 1190 | int 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 | } |
1211 | EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); | 1213 | EXPORT_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 | ||
109 | struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, | 109 | struct 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 | ||
66 | void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | 66 | int 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); |
68 | void gpiochip_remove_pin_ranges(struct gpio_chip *chip); | 68 | void 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 | ||
236 | static inline void | 236 | static inline int |
237 | gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | 237 | gpiochip_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 |
144 | extern struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, | 144 | extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np); |
145 | struct pinctrl_gpio_range *range); | ||
146 | #else | 145 | #else |
147 | static inline | 146 | static inline |
148 | struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, | 147 | struct 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 | ||
156 | extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); | 153 | extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); |