aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2012-12-15 17:50:46 -0500
committerSimon Horman <horms+renesas@verge.net.au>2013-01-24 19:24:21 -0500
commit6f6a4a683be97837f3baae443aacd2b0e6162b10 (patch)
treef1a3970e00dfd46df21769c11c7d795ebd192c25 /drivers/sh
parentf9492fda70c87b410e61675095212dc806bdf615 (diff)
sh-pfc: Merge PFC core and gpio
The PFC core calls the gpio module gpiochip registration in its register_sh_pfc() function, itself called at arch initialization time. If the gpio module isn't present then the gpiochip will never be registered. As the gpio module can only be present at arch initialization time if it's builtin, there's no point in allowing to build it as a module. Make it a boolean option, and initialize it synchronously with the core if selected. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'drivers/sh')
-rw-r--r--drivers/sh/pfc/Kconfig2
-rw-r--r--drivers/sh/pfc/Makefile4
-rw-r--r--drivers/sh/pfc/core.c23
-rw-r--r--drivers/sh/pfc/core.h4
-rw-r--r--drivers/sh/pfc/gpio.c79
5 files changed, 25 insertions, 87 deletions
diff --git a/drivers/sh/pfc/Kconfig b/drivers/sh/pfc/Kconfig
index f33d82a38b4b..eaeabc58bb06 100644
--- a/drivers/sh/pfc/Kconfig
+++ b/drivers/sh/pfc/Kconfig
@@ -11,7 +11,7 @@ config SH_PFC
11 def_bool y 11 def_bool y
12 12
13config GPIO_SH_PFC 13config GPIO_SH_PFC
14 tristate "SuperH PFC GPIO support" 14 bool "SuperH PFC GPIO support"
15 depends on SH_PFC && GPIOLIB 15 depends on SH_PFC && GPIOLIB
16 help 16 help
17 This enables support for GPIOs within the SoC's pin function 17 This enables support for GPIOs within the SoC's pin function
diff --git a/drivers/sh/pfc/Makefile b/drivers/sh/pfc/Makefile
index ce6fae353844..6315cf35b34d 100644
--- a/drivers/sh/pfc/Makefile
+++ b/drivers/sh/pfc/Makefile
@@ -1,3 +1,5 @@
1sh-pfc-objs = core.o pinctrl.o 1sh-pfc-objs = core.o pinctrl.o
2ifeq ($(CONFIG_GPIO_SH_PFC),y)
3sh-pfc-objs += gpio.o
4endif
2obj-y += sh-pfc.o 5obj-y += sh-pfc.o
3obj-$(CONFIG_GPIO_SH_PFC) += gpio.o
diff --git a/drivers/sh/pfc/core.c b/drivers/sh/pfc/core.c
index 30e33db7a2dc..541099613a21 100644
--- a/drivers/sh/pfc/core.c
+++ b/drivers/sh/pfc/core.c
@@ -149,7 +149,6 @@ int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos)
149 149
150 return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1; 150 return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1;
151} 151}
152EXPORT_SYMBOL_GPL(sh_pfc_read_bit);
153 152
154void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, 153void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos,
155 unsigned long value) 154 unsigned long value)
@@ -169,7 +168,6 @@ void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos,
169 168
170 gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow); 169 gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
171} 170}
172EXPORT_SYMBOL_GPL(sh_pfc_write_bit);
173 171
174static void config_reg_helper(struct sh_pfc *pfc, 172static void config_reg_helper(struct sh_pfc *pfc,
175 struct pinmux_cfg_reg *crp, 173 struct pinmux_cfg_reg *crp,
@@ -307,7 +305,6 @@ int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio,
307 *bitp = n; 305 *bitp = n;
308 return 0; 306 return 0;
309} 307}
310EXPORT_SYMBOL_GPL(sh_pfc_get_data_reg);
311 308
312static int get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, 309static int get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id,
313 struct pinmux_cfg_reg **crp, 310 struct pinmux_cfg_reg **crp,
@@ -384,7 +381,6 @@ int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos,
384 pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio); 381 pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
385 return -1; 382 return -1;
386} 383}
387EXPORT_SYMBOL_GPL(sh_pfc_gpio_to_enum);
388 384
389int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, 385int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type,
390 int cfg_mode) 386 int cfg_mode)
@@ -500,7 +496,6 @@ int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type,
500 496
501int register_sh_pfc(struct sh_pfc_platform_data *pdata) 497int register_sh_pfc(struct sh_pfc_platform_data *pdata)
502{ 498{
503 int (*initroutine)(struct sh_pfc *) = NULL;
504 int ret; 499 int ret;
505 500
506 /* 501 /*
@@ -531,24 +526,20 @@ int register_sh_pfc(struct sh_pfc_platform_data *pdata)
531 if (unlikely(ret != 0)) 526 if (unlikely(ret != 0))
532 goto err; 527 goto err;
533 528
529#ifdef CONFIG_GPIO_SH_PFC
534 /* 530 /*
535 * Then the GPIO chip 531 * Then the GPIO chip
536 */ 532 */
537 initroutine = symbol_request(sh_pfc_register_gpiochip); 533 ret = sh_pfc_register_gpiochip(&sh_pfc);
538 if (initroutine) { 534 if (unlikely(ret != 0)) {
539 ret = (*initroutine)(&sh_pfc);
540 symbol_put_addr(initroutine);
541
542 /* 535 /*
543 * If the GPIO chip fails to come up we still leave the 536 * If the GPIO chip fails to come up we still leave the
544 * PFC state as it is, given that there are already 537 * PFC state as it is, given that there are already
545 * extant users of it that have succeeded by this point. 538 * extant users of it that have succeeded by this point.
546 */ 539 */
547 if (unlikely(ret != 0)) { 540 pr_notice("failed to init GPIO chip, ignoring...\n");
548 pr_notice("failed to init GPIO chip, ignoring...\n");
549 ret = 0;
550 }
551 } 541 }
542#endif
552 543
553 pr_info("%s support registered\n", sh_pfc.pdata->name); 544 pr_info("%s support registered\n", sh_pfc.pdata->name);
554 545
@@ -560,3 +551,7 @@ err:
560 551
561 return ret; 552 return ret;
562} 553}
554
555MODULE_AUTHOR("Magnus Damm, Paul Mundt, Laurent Pinchart");
556MODULE_DESCRIPTION("Pin Control and GPIO driver for SuperH pin function controller");
557MODULE_LICENSE("GPL v2");
diff --git a/drivers/sh/pfc/core.h b/drivers/sh/pfc/core.h
index b07ae259c0eb..f3032b232fb0 100644
--- a/drivers/sh/pfc/core.h
+++ b/drivers/sh/pfc/core.h
@@ -20,14 +20,18 @@ struct pfc_window {
20 unsigned long size; 20 unsigned long size;
21}; 21};
22 22
23struct sh_pfc_chip;
24
23struct sh_pfc { 25struct sh_pfc {
24 struct sh_pfc_platform_data *pdata; 26 struct sh_pfc_platform_data *pdata;
25 spinlock_t lock; 27 spinlock_t lock;
26 28
27 struct pfc_window *window; 29 struct pfc_window *window;
30 struct sh_pfc_chip *gpio;
28}; 31};
29 32
30int sh_pfc_register_gpiochip(struct sh_pfc *pfc); 33int sh_pfc_register_gpiochip(struct sh_pfc *pfc);
34int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc);
31 35
32int sh_pfc_register_pinctrl(struct sh_pfc *pfc); 36int sh_pfc_register_pinctrl(struct sh_pfc *pfc);
33 37
diff --git a/drivers/sh/pfc/gpio.c b/drivers/sh/pfc/gpio.c
index 565b366c909f..d8b0c74a950d 100644
--- a/drivers/sh/pfc/gpio.c
+++ b/drivers/sh/pfc/gpio.c
@@ -15,7 +15,6 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/pinctrl/consumer.h> 18#include <linux/pinctrl/consumer.h>
20#include <linux/sh_pfc.h> 19#include <linux/sh_pfc.h>
21 20
@@ -152,44 +151,23 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
152 sh_pfc_gpio_setup(chip); 151 sh_pfc_gpio_setup(chip);
153 152
154 ret = gpiochip_add(&chip->gpio_chip); 153 ret = gpiochip_add(&chip->gpio_chip);
155 if (unlikely(ret < 0)) 154 if (unlikely(ret < 0)) {
156 kfree(chip); 155 kfree(chip);
156 return ret;
157 }
158
159 pfc->gpio = chip;
157 160
158 pr_info("%s handling gpio %d -> %d\n", 161 pr_info("%s handling gpio %d -> %d\n",
159 pfc->pdata->name, pfc->pdata->first_gpio, 162 pfc->pdata->name, pfc->pdata->first_gpio,
160 pfc->pdata->last_gpio); 163 pfc->pdata->last_gpio);
161 164
162 return ret;
163}
164EXPORT_SYMBOL_GPL(sh_pfc_register_gpiochip);
165
166static int sh_pfc_gpio_match(struct gpio_chip *gc, void *data)
167{
168 return !!strstr(gc->label, data);
169}
170
171static int sh_pfc_gpio_probe(struct platform_device *pdev)
172{
173 struct sh_pfc_chip *chip;
174 struct gpio_chip *gc;
175
176 gc = gpiochip_find("_pfc", sh_pfc_gpio_match);
177 if (unlikely(!gc)) {
178 pr_err("Cant find gpio chip\n");
179 return -ENODEV;
180 }
181
182 chip = gpio_to_pfc_chip(gc);
183 platform_set_drvdata(pdev, chip);
184
185 pr_info("attaching to GPIO chip %s\n", chip->pfc->pdata->name);
186
187 return 0; 165 return 0;
188} 166}
189 167
190static int sh_pfc_gpio_remove(struct platform_device *pdev) 168int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
191{ 169{
192 struct sh_pfc_chip *chip = platform_get_drvdata(pdev); 170 struct sh_pfc_chip *chip = pfc->gpio;
193 int ret; 171 int ret;
194 172
195 ret = gpiochip_remove(&chip->gpio_chip); 173 ret = gpiochip_remove(&chip->gpio_chip);
@@ -197,47 +175,6 @@ static int sh_pfc_gpio_remove(struct platform_device *pdev)
197 return ret; 175 return ret;
198 176
199 kfree(chip); 177 kfree(chip);
178 pfc->gpio = NULL;
200 return 0; 179 return 0;
201} 180}
202
203static struct platform_driver sh_pfc_gpio_driver = {
204 .probe = sh_pfc_gpio_probe,
205 .remove = sh_pfc_gpio_remove,
206 .driver = {
207 .name = KBUILD_MODNAME,
208 .owner = THIS_MODULE,
209 },
210};
211
212static struct platform_device sh_pfc_gpio_device = {
213 .name = KBUILD_MODNAME,
214 .id = -1,
215};
216
217static int __init sh_pfc_gpio_init(void)
218{
219 int rc;
220
221 rc = platform_driver_register(&sh_pfc_gpio_driver);
222 if (likely(!rc)) {
223 rc = platform_device_register(&sh_pfc_gpio_device);
224 if (unlikely(rc))
225 platform_driver_unregister(&sh_pfc_gpio_driver);
226 }
227
228 return rc;
229}
230
231static void __exit sh_pfc_gpio_exit(void)
232{
233 platform_device_unregister(&sh_pfc_gpio_device);
234 platform_driver_unregister(&sh_pfc_gpio_driver);
235}
236
237module_init(sh_pfc_gpio_init);
238module_exit(sh_pfc_gpio_exit);
239
240MODULE_AUTHOR("Magnus Damm, Paul Mundt");
241MODULE_DESCRIPTION("GPIO driver for SuperH pin function controller");
242MODULE_LICENSE("GPL v2");
243MODULE_ALIAS("platform:pfc-gpio");