aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2012-12-15 17:50:47 -0500
committerSimon Horman <horms+renesas@verge.net.au>2013-01-24 19:24:21 -0500
commitc6193eacda6d50c405b0d484f5f2577ff9068a13 (patch)
treed736dd1e72bd85664698e7dcecc461fd1d991bef
parent6f6a4a683be97837f3baae443aacd2b0e6162b10 (diff)
sh-pfc: Move platform device and driver to the core
The pinctrl module registers both a platform device and a platform driver. The only purpose of this awkward construction is to have a device to pass to the pinctrl registration function. As a first step to get rid of this hack, move the platform device and driver from the pinctrl module to the core. The platform device will then be moved to arch code. 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>
-rw-r--r--drivers/sh/pfc/core.c101
-rw-r--r--drivers/sh/pfc/core.h4
-rw-r--r--drivers/sh/pfc/gpio.c3
-rw-r--r--drivers/sh/pfc/pinctrl.c100
4 files changed, 114 insertions, 94 deletions
diff --git a/drivers/sh/pfc/core.c b/drivers/sh/pfc/core.c
index 541099613a21..6d162e694e68 100644
--- a/drivers/sh/pfc/core.c
+++ b/drivers/sh/pfc/core.c
@@ -8,6 +8,8 @@
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 */ 10 */
11
12#define DRV_NAME "sh-pfc"
11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 14
13#include <linux/errno.h> 15#include <linux/errno.h>
@@ -20,11 +22,10 @@
20#include <linux/slab.h> 22#include <linux/slab.h>
21#include <linux/ioport.h> 23#include <linux/ioport.h>
22#include <linux/pinctrl/machine.h> 24#include <linux/pinctrl/machine.h>
25#include <linux/platform_device.h>
23 26
24#include "core.h" 27#include "core.h"
25 28
26static struct sh_pfc sh_pfc __read_mostly;
27
28static void pfc_iounmap(struct sh_pfc *pfc) 29static void pfc_iounmap(struct sh_pfc *pfc)
29{ 30{
30 int k; 31 int k;
@@ -494,8 +495,10 @@ int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type,
494 return -1; 495 return -1;
495} 496}
496 497
497int register_sh_pfc(struct sh_pfc_platform_data *pdata) 498static int sh_pfc_probe(struct platform_device *pdev)
498{ 499{
500 struct sh_pfc_platform_data *pdata = pdev->dev.platform_data;
501 struct sh_pfc *pfc;
499 int ret; 502 int ret;
500 503
501 /* 504 /*
@@ -503,26 +506,29 @@ int register_sh_pfc(struct sh_pfc_platform_data *pdata)
503 */ 506 */
504 BUILD_BUG_ON(PINMUX_FLAG_TYPE > ((1 << PINMUX_FLAG_DBIT_SHIFT) - 1)); 507 BUILD_BUG_ON(PINMUX_FLAG_TYPE > ((1 << PINMUX_FLAG_DBIT_SHIFT) - 1));
505 508
506 if (sh_pfc.pdata) 509 if (pdata == NULL)
507 return -EBUSY; 510 return -ENODEV;
508 511
509 sh_pfc.pdata = pdata; 512 pfc = devm_kzalloc(&pdev->dev, sizeof(pfc), GFP_KERNEL);
513 if (pfc == NULL)
514 return -ENOMEM;
510 515
511 ret = pfc_ioremap(&sh_pfc); 516 pfc->pdata = pdata;
512 if (unlikely(ret < 0)) { 517 pfc->dev = &pdev->dev;
513 sh_pfc.pdata = NULL; 518
519 ret = pfc_ioremap(pfc);
520 if (unlikely(ret < 0))
514 return ret; 521 return ret;
515 }
516 522
517 spin_lock_init(&sh_pfc.lock); 523 spin_lock_init(&pfc->lock);
518 524
519 pinctrl_provide_dummies(); 525 pinctrl_provide_dummies();
520 setup_data_regs(&sh_pfc); 526 setup_data_regs(pfc);
521 527
522 /* 528 /*
523 * Initialize pinctrl bindings first 529 * Initialize pinctrl bindings first
524 */ 530 */
525 ret = sh_pfc_register_pinctrl(&sh_pfc); 531 ret = sh_pfc_register_pinctrl(pfc);
526 if (unlikely(ret != 0)) 532 if (unlikely(ret != 0))
527 goto err; 533 goto err;
528 534
@@ -530,7 +536,7 @@ int register_sh_pfc(struct sh_pfc_platform_data *pdata)
530 /* 536 /*
531 * Then the GPIO chip 537 * Then the GPIO chip
532 */ 538 */
533 ret = sh_pfc_register_gpiochip(&sh_pfc); 539 ret = sh_pfc_register_gpiochip(pfc);
534 if (unlikely(ret != 0)) { 540 if (unlikely(ret != 0)) {
535 /* 541 /*
536 * If the GPIO chip fails to come up we still leave the 542 * If the GPIO chip fails to come up we still leave the
@@ -541,17 +547,76 @@ int register_sh_pfc(struct sh_pfc_platform_data *pdata)
541 } 547 }
542#endif 548#endif
543 549
544 pr_info("%s support registered\n", sh_pfc.pdata->name); 550 platform_set_drvdata(pdev, pfc);
551
552 pr_info("%s support registered\n", pdata->name);
545 553
546 return 0; 554 return 0;
547 555
548err: 556err:
549 pfc_iounmap(&sh_pfc); 557 pfc_iounmap(pfc);
550 sh_pfc.pdata = NULL;
551
552 return ret; 558 return ret;
553} 559}
554 560
561static int sh_pfc_remove(struct platform_device *pdev)
562{
563 struct sh_pfc *pfc = platform_get_drvdata(pdev);
564
565#ifdef CONFIG_GPIO_SH_PFC
566 sh_pfc_unregister_gpiochip(pfc);
567#endif
568 sh_pfc_unregister_pinctrl(pfc);
569
570 pfc_iounmap(pfc);
571
572 platform_set_drvdata(pdev, NULL);
573
574 return 0;
575}
576
577static const struct platform_device_id sh_pfc_id_table[] = {
578 { "sh-pfc", 0 },
579 { },
580};
581MODULE_DEVICE_TABLE(platform, sh_pfc_id_table);
582
583static struct platform_driver sh_pfc_driver = {
584 .probe = sh_pfc_probe,
585 .remove = sh_pfc_remove,
586 .id_table = sh_pfc_id_table,
587 .driver = {
588 .name = DRV_NAME,
589 .owner = THIS_MODULE,
590 },
591};
592
593static struct platform_device sh_pfc_device = {
594 .name = DRV_NAME,
595 .id = -1,
596};
597
598int __init register_sh_pfc(struct sh_pfc_platform_data *pdata)
599{
600 int rc;
601
602 sh_pfc_device.dev.platform_data = pdata;
603
604 rc = platform_driver_register(&sh_pfc_driver);
605 if (likely(!rc)) {
606 rc = platform_device_register(&sh_pfc_device);
607 if (unlikely(rc))
608 platform_driver_unregister(&sh_pfc_driver);
609 }
610
611 return rc;
612}
613
614static void __exit sh_pfc_exit(void)
615{
616 platform_driver_unregister(&sh_pfc_driver);
617}
618module_exit(sh_pfc_exit);
619
555MODULE_AUTHOR("Magnus Damm, Paul Mundt, Laurent Pinchart"); 620MODULE_AUTHOR("Magnus Damm, Paul Mundt, Laurent Pinchart");
556MODULE_DESCRIPTION("Pin Control and GPIO driver for SuperH pin function controller"); 621MODULE_DESCRIPTION("Pin Control and GPIO driver for SuperH pin function controller");
557MODULE_LICENSE("GPL v2"); 622MODULE_LICENSE("GPL v2");
diff --git a/drivers/sh/pfc/core.h b/drivers/sh/pfc/core.h
index f3032b232fb0..1287b3e6222c 100644
--- a/drivers/sh/pfc/core.h
+++ b/drivers/sh/pfc/core.h
@@ -21,19 +21,23 @@ struct pfc_window {
21}; 21};
22 22
23struct sh_pfc_chip; 23struct sh_pfc_chip;
24struct sh_pfc_pinctrl;
24 25
25struct sh_pfc { 26struct sh_pfc {
27 struct device *dev;
26 struct sh_pfc_platform_data *pdata; 28 struct sh_pfc_platform_data *pdata;
27 spinlock_t lock; 29 spinlock_t lock;
28 30
29 struct pfc_window *window; 31 struct pfc_window *window;
30 struct sh_pfc_chip *gpio; 32 struct sh_pfc_chip *gpio;
33 struct sh_pfc_pinctrl *pinctrl;
31}; 34};
32 35
33int sh_pfc_register_gpiochip(struct sh_pfc *pfc); 36int sh_pfc_register_gpiochip(struct sh_pfc *pfc);
34int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc); 37int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc);
35 38
36int sh_pfc_register_pinctrl(struct sh_pfc *pfc); 39int sh_pfc_register_pinctrl(struct sh_pfc *pfc);
40int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc);
37 41
38int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos); 42int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos);
39void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, 43void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos,
diff --git a/drivers/sh/pfc/gpio.c b/drivers/sh/pfc/gpio.c
index d8b0c74a950d..a32ea8083b91 100644
--- a/drivers/sh/pfc/gpio.c
+++ b/drivers/sh/pfc/gpio.c
@@ -8,7 +8,8 @@
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 */ 10 */
11#define pr_fmt(fmt) "sh_pfc " KBUILD_MODNAME ": " fmt 11
12#define pr_fmt(fmt) KBUILD_MODNAME " gpio: " fmt
12 13
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/gpio.h> 15#include <linux/gpio.h>
diff --git a/drivers/sh/pfc/pinctrl.c b/drivers/sh/pfc/pinctrl.c
index 6f0f58bd3f87..2fc873137ce8 100644
--- a/drivers/sh/pfc/pinctrl.c
+++ b/drivers/sh/pfc/pinctrl.c
@@ -7,8 +7,8 @@
7 * License. See the file "COPYING" in the main directory of this archive 7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details. 8 * for more details.
9 */ 9 */
10#define DRV_NAME "pinctrl-sh_pfc"
11 10
11#define DRV_NAME "sh-pfc"
12#define pr_fmt(fmt) KBUILD_MODNAME " pinctrl: " fmt 12#define pr_fmt(fmt) KBUILD_MODNAME " pinctrl: " fmt
13 13
14#include <linux/init.h> 14#include <linux/init.h>
@@ -17,7 +17,6 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/platform_device.h>
21#include <linux/pinctrl/consumer.h> 20#include <linux/pinctrl/consumer.h>
22#include <linux/pinctrl/pinctrl.h> 21#include <linux/pinctrl/pinctrl.h>
23#include <linux/pinctrl/pinconf.h> 22#include <linux/pinctrl/pinconf.h>
@@ -39,8 +38,6 @@ struct sh_pfc_pinctrl {
39 spinlock_t lock; 38 spinlock_t lock;
40}; 39};
41 40
42static struct sh_pfc_pinctrl *sh_pfc_pmx;
43
44static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) 41static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev)
45{ 42{
46 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); 43 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
@@ -421,28 +418,31 @@ static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
421 return 0; 418 return 0;
422} 419}
423 420
424static int sh_pfc_pinctrl_probe(struct platform_device *pdev) 421int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
425{ 422{
426 struct sh_pfc *pfc; 423 struct sh_pfc_pinctrl *pmx;
427 int ret; 424 int ret;
428 425
429 if (unlikely(!sh_pfc_pmx)) 426 pmx = kzalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL);
430 return -ENODEV; 427 if (unlikely(!pmx))
428 return -ENOMEM;
429
430 spin_lock_init(&pmx->lock);
431 431
432 pfc = sh_pfc_pmx->pfc; 432 pmx->pfc = pfc;
433 pfc->pinctrl = pmx;
433 434
434 ret = sh_pfc_map_gpios(pfc, sh_pfc_pmx); 435 ret = sh_pfc_map_gpios(pfc, pmx);
435 if (unlikely(ret != 0)) 436 if (unlikely(ret != 0))
436 return ret; 437 return ret;
437 438
438 ret = sh_pfc_map_functions(pfc, sh_pfc_pmx); 439 ret = sh_pfc_map_functions(pfc, pmx);
439 if (unlikely(ret != 0)) 440 if (unlikely(ret != 0))
440 goto free_pads; 441 goto free_pads;
441 442
442 sh_pfc_pmx->pctl = pinctrl_register(&sh_pfc_pinctrl_desc, &pdev->dev, 443 pmx->pctl = pinctrl_register(&sh_pfc_pinctrl_desc, pfc->dev, pmx);
443 sh_pfc_pmx); 444 if (IS_ERR(pmx->pctl)) {
444 if (IS_ERR(sh_pfc_pmx->pctl)) { 445 ret = PTR_ERR(pmx->pctl);
445 ret = PTR_ERR(sh_pfc_pmx->pctl);
446 goto free_functions; 446 goto free_functions;
447 } 447 }
448 448
@@ -451,79 +451,29 @@ static int sh_pfc_pinctrl_probe(struct platform_device *pdev)
451 sh_pfc_gpio_range.base = pfc->pdata->first_gpio; 451 sh_pfc_gpio_range.base = pfc->pdata->first_gpio;
452 sh_pfc_gpio_range.pin_base = pfc->pdata->first_gpio; 452 sh_pfc_gpio_range.pin_base = pfc->pdata->first_gpio;
453 453
454 pinctrl_add_gpio_range(sh_pfc_pmx->pctl, &sh_pfc_gpio_range); 454 pinctrl_add_gpio_range(pmx->pctl, &sh_pfc_gpio_range);
455
456 platform_set_drvdata(pdev, sh_pfc_pmx);
457 455
458 return 0; 456 return 0;
459 457
460free_functions: 458free_functions:
461 kfree(sh_pfc_pmx->functions); 459 kfree(pmx->functions);
462free_pads: 460free_pads:
463 kfree(sh_pfc_pmx->pads); 461 kfree(pmx->pads);
464 kfree(sh_pfc_pmx); 462 kfree(pmx);
465 463
466 return ret; 464 return ret;
467} 465}
468 466
469static int sh_pfc_pinctrl_remove(struct platform_device *pdev) 467int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc)
470{ 468{
471 struct sh_pfc_pinctrl *pmx = platform_get_drvdata(pdev); 469 struct sh_pfc_pinctrl *pmx = pfc->pinctrl;
472 470
473 pinctrl_unregister(pmx->pctl); 471 pinctrl_unregister(pmx->pctl);
474 472
475 platform_set_drvdata(pdev, NULL); 473 kfree(pmx->functions);
476 474 kfree(pmx->pads);
477 kfree(sh_pfc_pmx->functions); 475 kfree(pmx);
478 kfree(sh_pfc_pmx->pads);
479 kfree(sh_pfc_pmx);
480 476
477 pfc->pinctrl = NULL;
481 return 0; 478 return 0;
482} 479}
483
484static struct platform_driver sh_pfc_pinctrl_driver = {
485 .probe = sh_pfc_pinctrl_probe,
486 .remove = sh_pfc_pinctrl_remove,
487 .driver = {
488 .name = DRV_NAME,
489 .owner = THIS_MODULE,
490 },
491};
492
493static struct platform_device sh_pfc_pinctrl_device = {
494 .name = DRV_NAME,
495 .id = -1,
496};
497
498static int sh_pfc_pinctrl_init(void)
499{
500 int rc;
501
502 rc = platform_driver_register(&sh_pfc_pinctrl_driver);
503 if (likely(!rc)) {
504 rc = platform_device_register(&sh_pfc_pinctrl_device);
505 if (unlikely(rc))
506 platform_driver_unregister(&sh_pfc_pinctrl_driver);
507 }
508
509 return rc;
510}
511
512int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
513{
514 sh_pfc_pmx = kzalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL);
515 if (unlikely(!sh_pfc_pmx))
516 return -ENOMEM;
517
518 spin_lock_init(&sh_pfc_pmx->lock);
519
520 sh_pfc_pmx->pfc = pfc;
521
522 return sh_pfc_pinctrl_init();
523}
524
525static void __exit sh_pfc_pinctrl_exit(void)
526{
527 platform_driver_unregister(&sh_pfc_pinctrl_driver);
528}
529module_exit(sh_pfc_pinctrl_exit);