diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-19 15:50:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-19 15:50:56 -0400 |
commit | a37571a29eca963562ff5a9233db4a5c73c72cf9 (patch) | |
tree | ec78d4b5b905f32bc541b2faa5b89f88967cf990 /drivers/pinctrl/stm32 | |
parent | a0d3c7c5c07cfbe00ab89438ddf82482f5a99422 (diff) | |
parent | 0d5358330c20d50e52e3e65ff07a5db8007041fc (diff) |
Merge tag 'pinctrl-v4.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij:
"This kernel cycle was quite calm when it comes to pin control and
there is really just one major change, and that is the introduction of
devm_pinctrl_register() managed resources.
Apart from that linear development, details below.
Core changes:
- Add the devm_pinctrl_register() API and switch all applicable
drivers to use it, saving lots of lines of code all over the place.
New drivers:
- driver for the Broadcom NS2 SoC
- subdriver for the PXA25x SoCs
- subdriver for the AMLogic Meson GXBB SoC
Driver improvements:
- the Intel Baytrail driver now properly supports pin control
- Nomadik, Rockchip, Broadcom BCM2835 support the .get_direction()
callback in the GPIO portions
- continued development and stabilization of several SH-PFC SoC
subdrivers: r8a7795, r8a7790, r8a7794 etc"
* tag 'pinctrl-v4.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (85 commits)
Revert "pinctrl: tegra: avoid parked_reg and parked_bank"
pinctrl: meson: Fix eth_tx_en bit index
pinctrl: tegra: avoid parked_reg and parked_bank
pinctrl: tegra: Correctly check the supported configuration
pinctrl: amlogic: Add support for Amlogic Meson GXBB SoC
pinctrl: rockchip: fix pull setting error for rk3399
pinctrl: stm32: Implement .pin_config_dbg_show()
pinctrl: nomadik: hide nmk_gpio_get_mode when unused
pinctrl: ns2: rename pinctrl_utils_dt_free_map
pinctrl: at91: Merge clk_prepare and clk_enable into clk_prepare_enable
pinctrl: at91: Make at91_gpio_template const
pinctrl: baytrail: fix some error handling in debugfs
pinctrl: ns2: add pinmux driver support for Broadcom NS2 SoC
pinctrl: sirf/atlas7: trivial fix of spelling mistake on flagged
pinctrl: sh-pfc: Kill unused variable in sh_pfc_remove()
pinctrl: nomadik: implement .get_direction()
pinctrl: nomadik: use BIT() with offsets consequently
pinctrl: exynos5440: Use off-stack memory for pinctrl_gpio_range
pinctrl: zynq: Use devm_pinctrl_register() for pinctrl registration
pinctrl: u300: Use devm_pinctrl_register() for pinctrl registration
...
Diffstat (limited to 'drivers/pinctrl/stm32')
-rw-r--r-- | drivers/pinctrl/stm32/pinctrl-stm32.c | 185 |
1 files changed, 180 insertions, 5 deletions
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 8deb566ed4cd..ae9fab82a1b9 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c | |||
@@ -358,7 +358,7 @@ static int stm32_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
358 | ret = stm32_pctrl_dt_subnode_to_map(pctldev, np, map, | 358 | ret = stm32_pctrl_dt_subnode_to_map(pctldev, np, map, |
359 | &reserved_maps, num_maps); | 359 | &reserved_maps, num_maps); |
360 | if (ret < 0) { | 360 | if (ret < 0) { |
361 | pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); | 361 | pinctrl_utils_free_map(pctldev, *map, *num_maps); |
362 | return ret; | 362 | return ret; |
363 | } | 363 | } |
364 | } | 364 | } |
@@ -396,7 +396,7 @@ static int stm32_pctrl_get_group_pins(struct pinctrl_dev *pctldev, | |||
396 | 396 | ||
397 | static const struct pinctrl_ops stm32_pctrl_ops = { | 397 | static const struct pinctrl_ops stm32_pctrl_ops = { |
398 | .dt_node_to_map = stm32_pctrl_dt_node_to_map, | 398 | .dt_node_to_map = stm32_pctrl_dt_node_to_map, |
399 | .dt_free_map = pinctrl_utils_dt_free_map, | 399 | .dt_free_map = pinctrl_utils_free_map, |
400 | .get_groups_count = stm32_pctrl_get_groups_count, | 400 | .get_groups_count = stm32_pctrl_get_groups_count, |
401 | .get_group_name = stm32_pctrl_get_group_name, | 401 | .get_group_name = stm32_pctrl_get_group_name, |
402 | .get_group_pins = stm32_pctrl_get_group_pins, | 402 | .get_group_pins = stm32_pctrl_get_group_pins, |
@@ -454,6 +454,29 @@ static void stm32_pmx_set_mode(struct stm32_gpio_bank *bank, | |||
454 | clk_disable(bank->clk); | 454 | clk_disable(bank->clk); |
455 | } | 455 | } |
456 | 456 | ||
457 | static void stm32_pmx_get_mode(struct stm32_gpio_bank *bank, | ||
458 | int pin, u32 *mode, u32 *alt) | ||
459 | { | ||
460 | u32 val; | ||
461 | int alt_shift = (pin % 8) * 4; | ||
462 | int alt_offset = STM32_GPIO_AFRL + (pin / 8) * 4; | ||
463 | unsigned long flags; | ||
464 | |||
465 | clk_enable(bank->clk); | ||
466 | spin_lock_irqsave(&bank->lock, flags); | ||
467 | |||
468 | val = readl_relaxed(bank->base + alt_offset); | ||
469 | val &= GENMASK(alt_shift + 3, alt_shift); | ||
470 | *alt = val >> alt_shift; | ||
471 | |||
472 | val = readl_relaxed(bank->base + STM32_GPIO_MODER); | ||
473 | val &= GENMASK(pin * 2 + 1, pin * 2); | ||
474 | *mode = val >> (pin * 2); | ||
475 | |||
476 | spin_unlock_irqrestore(&bank->lock, flags); | ||
477 | clk_disable(bank->clk); | ||
478 | } | ||
479 | |||
457 | static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev, | 480 | static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev, |
458 | unsigned function, | 481 | unsigned function, |
459 | unsigned group) | 482 | unsigned group) |
@@ -525,6 +548,24 @@ static void stm32_pconf_set_driving(struct stm32_gpio_bank *bank, | |||
525 | clk_disable(bank->clk); | 548 | clk_disable(bank->clk); |
526 | } | 549 | } |
527 | 550 | ||
551 | static u32 stm32_pconf_get_driving(struct stm32_gpio_bank *bank, | ||
552 | unsigned int offset) | ||
553 | { | ||
554 | unsigned long flags; | ||
555 | u32 val; | ||
556 | |||
557 | clk_enable(bank->clk); | ||
558 | spin_lock_irqsave(&bank->lock, flags); | ||
559 | |||
560 | val = readl_relaxed(bank->base + STM32_GPIO_TYPER); | ||
561 | val &= BIT(offset); | ||
562 | |||
563 | spin_unlock_irqrestore(&bank->lock, flags); | ||
564 | clk_disable(bank->clk); | ||
565 | |||
566 | return (val >> offset); | ||
567 | } | ||
568 | |||
528 | static void stm32_pconf_set_speed(struct stm32_gpio_bank *bank, | 569 | static void stm32_pconf_set_speed(struct stm32_gpio_bank *bank, |
529 | unsigned offset, u32 speed) | 570 | unsigned offset, u32 speed) |
530 | { | 571 | { |
@@ -543,6 +584,24 @@ static void stm32_pconf_set_speed(struct stm32_gpio_bank *bank, | |||
543 | clk_disable(bank->clk); | 584 | clk_disable(bank->clk); |
544 | } | 585 | } |
545 | 586 | ||
587 | static u32 stm32_pconf_get_speed(struct stm32_gpio_bank *bank, | ||
588 | unsigned int offset) | ||
589 | { | ||
590 | unsigned long flags; | ||
591 | u32 val; | ||
592 | |||
593 | clk_enable(bank->clk); | ||
594 | spin_lock_irqsave(&bank->lock, flags); | ||
595 | |||
596 | val = readl_relaxed(bank->base + STM32_GPIO_SPEEDR); | ||
597 | val &= GENMASK(offset * 2 + 1, offset * 2); | ||
598 | |||
599 | spin_unlock_irqrestore(&bank->lock, flags); | ||
600 | clk_disable(bank->clk); | ||
601 | |||
602 | return (val >> (offset * 2)); | ||
603 | } | ||
604 | |||
546 | static void stm32_pconf_set_bias(struct stm32_gpio_bank *bank, | 605 | static void stm32_pconf_set_bias(struct stm32_gpio_bank *bank, |
547 | unsigned offset, u32 bias) | 606 | unsigned offset, u32 bias) |
548 | { | 607 | { |
@@ -561,6 +620,57 @@ static void stm32_pconf_set_bias(struct stm32_gpio_bank *bank, | |||
561 | clk_disable(bank->clk); | 620 | clk_disable(bank->clk); |
562 | } | 621 | } |
563 | 622 | ||
623 | static u32 stm32_pconf_get_bias(struct stm32_gpio_bank *bank, | ||
624 | unsigned int offset) | ||
625 | { | ||
626 | unsigned long flags; | ||
627 | u32 val; | ||
628 | |||
629 | clk_enable(bank->clk); | ||
630 | spin_lock_irqsave(&bank->lock, flags); | ||
631 | |||
632 | val = readl_relaxed(bank->base + STM32_GPIO_PUPDR); | ||
633 | val &= GENMASK(offset * 2 + 1, offset * 2); | ||
634 | |||
635 | spin_unlock_irqrestore(&bank->lock, flags); | ||
636 | clk_disable(bank->clk); | ||
637 | |||
638 | return (val >> (offset * 2)); | ||
639 | } | ||
640 | |||
641 | static bool stm32_pconf_input_get(struct stm32_gpio_bank *bank, | ||
642 | unsigned int offset) | ||
643 | { | ||
644 | unsigned long flags; | ||
645 | u32 val; | ||
646 | |||
647 | clk_enable(bank->clk); | ||
648 | spin_lock_irqsave(&bank->lock, flags); | ||
649 | |||
650 | val = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset)); | ||
651 | |||
652 | spin_unlock_irqrestore(&bank->lock, flags); | ||
653 | clk_disable(bank->clk); | ||
654 | |||
655 | return val; | ||
656 | } | ||
657 | |||
658 | static bool stm32_pconf_output_get(struct stm32_gpio_bank *bank, | ||
659 | unsigned int offset) | ||
660 | { | ||
661 | unsigned long flags; | ||
662 | u32 val; | ||
663 | |||
664 | clk_enable(bank->clk); | ||
665 | spin_lock_irqsave(&bank->lock, flags); | ||
666 | val = !!(readl_relaxed(bank->base + STM32_GPIO_ODR) & BIT(offset)); | ||
667 | |||
668 | spin_unlock_irqrestore(&bank->lock, flags); | ||
669 | clk_disable(bank->clk); | ||
670 | |||
671 | return val; | ||
672 | } | ||
673 | |||
564 | static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, | 674 | static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, |
565 | unsigned int pin, enum pin_config_param param, | 675 | unsigned int pin, enum pin_config_param param, |
566 | enum pin_config_param arg) | 676 | enum pin_config_param arg) |
@@ -634,9 +744,73 @@ static int stm32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, | |||
634 | return 0; | 744 | return 0; |
635 | } | 745 | } |
636 | 746 | ||
747 | static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev, | ||
748 | struct seq_file *s, | ||
749 | unsigned int pin) | ||
750 | { | ||
751 | struct pinctrl_gpio_range *range; | ||
752 | struct stm32_gpio_bank *bank; | ||
753 | int offset; | ||
754 | u32 mode, alt, drive, speed, bias; | ||
755 | static const char * const modes[] = { | ||
756 | "input", "output", "alternate", "analog" }; | ||
757 | static const char * const speeds[] = { | ||
758 | "low", "medium", "high", "very high" }; | ||
759 | static const char * const biasing[] = { | ||
760 | "floating", "pull up", "pull down", "" }; | ||
761 | bool val; | ||
762 | |||
763 | range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin); | ||
764 | bank = gpio_range_to_bank(range); | ||
765 | offset = stm32_gpio_pin(pin); | ||
766 | |||
767 | stm32_pmx_get_mode(bank, offset, &mode, &alt); | ||
768 | bias = stm32_pconf_get_bias(bank, offset); | ||
769 | |||
770 | seq_printf(s, "%s ", modes[mode]); | ||
771 | |||
772 | switch (mode) { | ||
773 | /* input */ | ||
774 | case 0: | ||
775 | val = stm32_pconf_input_get(bank, offset); | ||
776 | seq_printf(s, "- %s - %s", | ||
777 | val ? "high" : "low", | ||
778 | biasing[bias]); | ||
779 | break; | ||
780 | |||
781 | /* output */ | ||
782 | case 1: | ||
783 | drive = stm32_pconf_get_driving(bank, offset); | ||
784 | speed = stm32_pconf_get_speed(bank, offset); | ||
785 | val = stm32_pconf_output_get(bank, offset); | ||
786 | seq_printf(s, "- %s - %s - %s - %s %s", | ||
787 | val ? "high" : "low", | ||
788 | drive ? "open drain" : "push pull", | ||
789 | biasing[bias], | ||
790 | speeds[speed], "speed"); | ||
791 | break; | ||
792 | |||
793 | /* alternate */ | ||
794 | case 2: | ||
795 | drive = stm32_pconf_get_driving(bank, offset); | ||
796 | speed = stm32_pconf_get_speed(bank, offset); | ||
797 | seq_printf(s, "%d - %s - %s - %s %s", alt, | ||
798 | drive ? "open drain" : "push pull", | ||
799 | biasing[bias], | ||
800 | speeds[speed], "speed"); | ||
801 | break; | ||
802 | |||
803 | /* analog */ | ||
804 | case 3: | ||
805 | break; | ||
806 | } | ||
807 | } | ||
808 | |||
809 | |||
637 | static const struct pinconf_ops stm32_pconf_ops = { | 810 | static const struct pinconf_ops stm32_pconf_ops = { |
638 | .pin_config_group_get = stm32_pconf_group_get, | 811 | .pin_config_group_get = stm32_pconf_group_get, |
639 | .pin_config_group_set = stm32_pconf_group_set, | 812 | .pin_config_group_set = stm32_pconf_group_set, |
813 | .pin_config_dbg_show = stm32_pconf_dbg_show, | ||
640 | }; | 814 | }; |
641 | 815 | ||
642 | static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, | 816 | static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, |
@@ -813,10 +987,11 @@ int stm32_pctl_probe(struct platform_device *pdev) | |||
813 | pctl->pctl_desc.pmxops = &stm32_pmx_ops; | 987 | pctl->pctl_desc.pmxops = &stm32_pmx_ops; |
814 | pctl->dev = &pdev->dev; | 988 | pctl->dev = &pdev->dev; |
815 | 989 | ||
816 | pctl->pctl_dev = pinctrl_register(&pctl->pctl_desc, &pdev->dev, pctl); | 990 | pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, &pctl->pctl_desc, |
817 | if (!pctl->pctl_dev) { | 991 | pctl); |
992 | if (IS_ERR(pctl->pctl_dev)) { | ||
818 | dev_err(&pdev->dev, "Failed pinctrl registration\n"); | 993 | dev_err(&pdev->dev, "Failed pinctrl registration\n"); |
819 | return -EINVAL; | 994 | return PTR_ERR(pctl->pctl_dev); |
820 | } | 995 | } |
821 | 996 | ||
822 | for (i = 0; i < pctl->nbanks; i++) | 997 | for (i = 0; i < pctl->nbanks; i++) |