diff options
Diffstat (limited to 'drivers/sh/pfc/core.c')
-rw-r--r-- | drivers/sh/pfc/core.c | 81 |
1 files changed, 36 insertions, 45 deletions
diff --git a/drivers/sh/pfc/core.c b/drivers/sh/pfc/core.c index ce4579ebd602..02e9f62e2b28 100644 --- a/drivers/sh/pfc/core.c +++ b/drivers/sh/pfc/core.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
22 | #include <linux/pinctrl/machine.h> | ||
22 | 23 | ||
23 | static struct sh_pfc *sh_pfc __read_mostly; | 24 | static struct sh_pfc *sh_pfc __read_mostly; |
24 | 25 | ||
@@ -501,49 +502,6 @@ int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, | |||
501 | } | 502 | } |
502 | EXPORT_SYMBOL_GPL(sh_pfc_config_gpio); | 503 | EXPORT_SYMBOL_GPL(sh_pfc_config_gpio); |
503 | 504 | ||
504 | int sh_pfc_set_direction(struct sh_pfc *pfc, unsigned gpio, | ||
505 | int new_pinmux_type) | ||
506 | { | ||
507 | int pinmux_type; | ||
508 | int ret = -EINVAL; | ||
509 | |||
510 | if (!pfc) | ||
511 | goto err_out; | ||
512 | |||
513 | pinmux_type = pfc->gpios[gpio].flags & PINMUX_FLAG_TYPE; | ||
514 | |||
515 | switch (pinmux_type) { | ||
516 | case PINMUX_TYPE_GPIO: | ||
517 | break; | ||
518 | case PINMUX_TYPE_OUTPUT: | ||
519 | case PINMUX_TYPE_INPUT: | ||
520 | case PINMUX_TYPE_INPUT_PULLUP: | ||
521 | case PINMUX_TYPE_INPUT_PULLDOWN: | ||
522 | sh_pfc_config_gpio(pfc, gpio, pinmux_type, GPIO_CFG_FREE); | ||
523 | break; | ||
524 | default: | ||
525 | goto err_out; | ||
526 | } | ||
527 | |||
528 | if (sh_pfc_config_gpio(pfc, gpio, | ||
529 | new_pinmux_type, | ||
530 | GPIO_CFG_DRYRUN) != 0) | ||
531 | goto err_out; | ||
532 | |||
533 | if (sh_pfc_config_gpio(pfc, gpio, | ||
534 | new_pinmux_type, | ||
535 | GPIO_CFG_REQ) != 0) | ||
536 | BUG(); | ||
537 | |||
538 | pfc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE; | ||
539 | pfc->gpios[gpio].flags |= new_pinmux_type; | ||
540 | |||
541 | ret = 0; | ||
542 | err_out: | ||
543 | return ret; | ||
544 | } | ||
545 | EXPORT_SYMBOL_GPL(sh_pfc_set_direction); | ||
546 | |||
547 | int register_sh_pfc(struct sh_pfc *pfc) | 505 | int register_sh_pfc(struct sh_pfc *pfc) |
548 | { | 506 | { |
549 | int (*initroutine)(struct sh_pfc *) = NULL; | 507 | int (*initroutine)(struct sh_pfc *) = NULL; |
@@ -563,16 +521,49 @@ int register_sh_pfc(struct sh_pfc *pfc) | |||
563 | 521 | ||
564 | spin_lock_init(&pfc->lock); | 522 | spin_lock_init(&pfc->lock); |
565 | 523 | ||
524 | pinctrl_provide_dummies(); | ||
566 | setup_data_regs(pfc); | 525 | setup_data_regs(pfc); |
567 | 526 | ||
568 | sh_pfc = pfc; | 527 | sh_pfc = pfc; |
569 | pr_info("%s support registered\n", pfc->name); | ||
570 | 528 | ||
529 | /* | ||
530 | * Initialize pinctrl bindings first | ||
531 | */ | ||
532 | initroutine = symbol_request(sh_pfc_register_pinctrl); | ||
533 | if (initroutine) { | ||
534 | ret = (*initroutine)(pfc); | ||
535 | symbol_put_addr(initroutine); | ||
536 | |||
537 | if (unlikely(ret != 0)) | ||
538 | goto err; | ||
539 | } | ||
540 | |||
541 | /* | ||
542 | * Then the GPIO chip | ||
543 | */ | ||
571 | initroutine = symbol_request(sh_pfc_register_gpiochip); | 544 | initroutine = symbol_request(sh_pfc_register_gpiochip); |
572 | if (initroutine) { | 545 | if (initroutine) { |
573 | (*initroutine)(pfc); | 546 | ret = (*initroutine)(pfc); |
574 | symbol_put_addr(initroutine); | 547 | symbol_put_addr(initroutine); |
548 | |||
549 | /* | ||
550 | * If the GPIO chip fails to come up we still leave the | ||
551 | * PFC state as it is, given that there are already | ||
552 | * extant users of it that have succeeded by this point. | ||
553 | */ | ||
554 | if (unlikely(ret != 0)) { | ||
555 | pr_notice("failed to init GPIO chip, ignoring...\n"); | ||
556 | ret = 0; | ||
557 | } | ||
575 | } | 558 | } |
576 | 559 | ||
560 | pr_info("%s support registered\n", pfc->name); | ||
561 | |||
577 | return 0; | 562 | return 0; |
563 | |||
564 | err: | ||
565 | pfc_iounmap(pfc); | ||
566 | sh_pfc = NULL; | ||
567 | |||
568 | return ret; | ||
578 | } | 569 | } |