aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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");