diff options
Diffstat (limited to 'drivers/sh')
-rw-r--r-- | drivers/sh/pfc/core.c | 101 | ||||
-rw-r--r-- | drivers/sh/pfc/core.h | 4 | ||||
-rw-r--r-- | drivers/sh/pfc/gpio.c | 3 | ||||
-rw-r--r-- | drivers/sh/pfc/pinctrl.c | 100 |
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 | ||
26 | static struct sh_pfc sh_pfc __read_mostly; | ||
27 | |||
28 | static void pfc_iounmap(struct sh_pfc *pfc) | 29 | static 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 | ||
497 | int register_sh_pfc(struct sh_pfc_platform_data *pdata) | 498 | static 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 | ||
548 | err: | 556 | err: |
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 | ||
561 | static 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 | |||
577 | static const struct platform_device_id sh_pfc_id_table[] = { | ||
578 | { "sh-pfc", 0 }, | ||
579 | { }, | ||
580 | }; | ||
581 | MODULE_DEVICE_TABLE(platform, sh_pfc_id_table); | ||
582 | |||
583 | static 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 | |||
593 | static struct platform_device sh_pfc_device = { | ||
594 | .name = DRV_NAME, | ||
595 | .id = -1, | ||
596 | }; | ||
597 | |||
598 | int __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 | |||
614 | static void __exit sh_pfc_exit(void) | ||
615 | { | ||
616 | platform_driver_unregister(&sh_pfc_driver); | ||
617 | } | ||
618 | module_exit(sh_pfc_exit); | ||
619 | |||
555 | MODULE_AUTHOR("Magnus Damm, Paul Mundt, Laurent Pinchart"); | 620 | MODULE_AUTHOR("Magnus Damm, Paul Mundt, Laurent Pinchart"); |
556 | MODULE_DESCRIPTION("Pin Control and GPIO driver for SuperH pin function controller"); | 621 | MODULE_DESCRIPTION("Pin Control and GPIO driver for SuperH pin function controller"); |
557 | MODULE_LICENSE("GPL v2"); | 622 | MODULE_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 | ||
23 | struct sh_pfc_chip; | 23 | struct sh_pfc_chip; |
24 | struct sh_pfc_pinctrl; | ||
24 | 25 | ||
25 | struct sh_pfc { | 26 | struct 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 | ||
33 | int sh_pfc_register_gpiochip(struct sh_pfc *pfc); | 36 | int sh_pfc_register_gpiochip(struct sh_pfc *pfc); |
34 | int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc); | 37 | int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc); |
35 | 38 | ||
36 | int sh_pfc_register_pinctrl(struct sh_pfc *pfc); | 39 | int sh_pfc_register_pinctrl(struct sh_pfc *pfc); |
40 | int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc); | ||
37 | 41 | ||
38 | int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos); | 42 | int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos); |
39 | void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, | 43 | void 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 | ||
42 | static struct sh_pfc_pinctrl *sh_pfc_pmx; | ||
43 | |||
44 | static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) | 41 | static 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 | ||
424 | static int sh_pfc_pinctrl_probe(struct platform_device *pdev) | 421 | int 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 | ||
460 | free_functions: | 458 | free_functions: |
461 | kfree(sh_pfc_pmx->functions); | 459 | kfree(pmx->functions); |
462 | free_pads: | 460 | free_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 | ||
469 | static int sh_pfc_pinctrl_remove(struct platform_device *pdev) | 467 | int 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 | |||
484 | static 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 | |||
493 | static struct platform_device sh_pfc_pinctrl_device = { | ||
494 | .name = DRV_NAME, | ||
495 | .id = -1, | ||
496 | }; | ||
497 | |||
498 | static 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 | |||
512 | int 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 | |||
525 | static void __exit sh_pfc_pinctrl_exit(void) | ||
526 | { | ||
527 | platform_driver_unregister(&sh_pfc_pinctrl_driver); | ||
528 | } | ||
529 | module_exit(sh_pfc_pinctrl_exit); | ||