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