diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-04 13:22:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-04 13:22:09 -0400 |
commit | 88a99886c26fec8bf662e7b6bc080431a8660326 (patch) | |
tree | 615b9a9a959ab093f6d8d0dd94d3bbc5299fc4c6 /drivers/pinctrl/sh-pfc | |
parent | 8d2faea672606827c2018143ec7d88c760f2d6de (diff) | |
parent | 1ab36387ea4face01aac3560b396b1e2ce07c4ff (diff) |
Merge tag 'pinctrl-v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij:
"This is the bulk of pin control changes for the v4.3 development
cycle.
Like with GPIO it's a lot of stuff. If my subsystems are any sign of
the overall tempo of the kernel v4.3 will be a gigantic diff.
[ It looks like 4.3 is calmer than 4.2 in most other subsystems, but
we'll see - Linus ]
Core changes:
- It is possible configure groups in debugfs.
- Consolidation of chained IRQ handler install/remove replacing all
call sites where irq_set_handler_data() and
irq_set_chained_handler() were done in succession with a combined
call to irq_set_chained_handler_and_data(). This series was
created by Thomas Gleixner after the problem was observed by
Russell King.
- Tglx also made another series of patches switching
__irq_set_handler_locked() for irq_set_handler_locked() which is
way cleaner.
- Tglx also wrote a good bunch of patches to make use of
irq_desc_get_xxx() accessors and avoid looking up irq_descs from
IRQ numbers. The goal is to get rid of the irq number from the
handlers in the IRQ flow which is nice.
Driver feature enhancements:
- Power management support for the SiRF SoC Atlas 7.
- Power down support for the Qualcomm driver.
- Intel Cherryview and Baytrail: switch drivers to use raw spinlocks
in IRQ handlers to play nice with the realtime patch set.
- Rework and new modes handling for Qualcomm SPMI-MPP.
- Pinconf power source config for SH PFC.
New drivers and subdrivers:
- A new driver for Conexant Digicolor CX92755.
- A new driver for UniPhier PH1-LD4, PH1-Pro4, PH1-sLD8, PH1-Pro5,
ProXtream2 and PH1-LD6b SoC pin control support.
- Reverse-egineered the S/PDIF settings for the Allwinner sun4i
driver.
- Support for Qualcomm Technologies QDF2xxx ARM64 SoCs
- A new Freescale i.mx6ul subdriver.
Cleanup:
- Remove platform data support in a number of SH PFC subdrivers"
* tag 'pinctrl-v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (95 commits)
pinctrl: at91: fix null pointer dereference
pinctrl: mediatek: Implement wake handler and suspend resume
pinctrl: mediatek: Fix multiple registration issue.
pinctrl: sh-pfc: r8a7794: add USB pin groups
pinctrl: at91: Use generic irq_{request,release}_resources()
pinctrl: cherryview: Use raw_spinlock for locking
pinctrl: baytrail: Use raw_spinlock for locking
pinctrl: imx6ul: Remove .owner field
pinctrl: zynq: Fix typos in smc0_nand_grp and smc0_nor_grp
pinctrl: sh-pfc: Implement pinconf power-source param for voltage switching
clk: rockchip: add pclk_pd_pmu to the list of rk3288 critical clocks
pinctrl: sun4i: add spdif to pin description.
pinctrl: atlas7: clear ugly branch statements for pull and drivestrength
pinctrl: baytrail: Serialize all register access
pinctrl: baytrail: Drop FSF mailing address
pinctrl: rockchip: only enable gpio clock when it setting
pinctrl/mediatek: fix spelling mistake in dev_err error message
pinctrl: cherryview: Serialize all register access
pinctrl: UniPhier: PH1-Pro5: add I2C ch6 pin-mux setting
pinctrl: nomadik: reflect current input value
...
Diffstat (limited to 'drivers/pinctrl/sh-pfc')
-rw-r--r-- | drivers/pinctrl/sh-pfc/core.c | 52 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 4 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 21 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pfc-r8a7791.c | 19 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pfc-r8a7794.c | 30 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 4 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 86 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/sh_pfc.h | 5 |
8 files changed, 168 insertions, 53 deletions
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 865d235612c5..fb9c44805234 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c | |||
@@ -29,24 +29,25 @@ | |||
29 | static int sh_pfc_map_resources(struct sh_pfc *pfc, | 29 | static int sh_pfc_map_resources(struct sh_pfc *pfc, |
30 | struct platform_device *pdev) | 30 | struct platform_device *pdev) |
31 | { | 31 | { |
32 | unsigned int num_windows = 0; | 32 | unsigned int num_windows, num_irqs; |
33 | unsigned int num_irqs = 0; | ||
34 | struct sh_pfc_window *windows; | 33 | struct sh_pfc_window *windows; |
35 | unsigned int *irqs = NULL; | 34 | unsigned int *irqs = NULL; |
36 | struct resource *res; | 35 | struct resource *res; |
37 | unsigned int i; | 36 | unsigned int i; |
37 | int irq; | ||
38 | 38 | ||
39 | /* Count the MEM and IRQ resources. */ | 39 | /* Count the MEM and IRQ resources. */ |
40 | for (i = 0; i < pdev->num_resources; ++i) { | 40 | for (num_windows = 0;; num_windows++) { |
41 | switch (resource_type(&pdev->resource[i])) { | 41 | res = platform_get_resource(pdev, IORESOURCE_MEM, num_windows); |
42 | case IORESOURCE_MEM: | 42 | if (!res) |
43 | num_windows++; | ||
44 | break; | 43 | break; |
45 | 44 | } | |
46 | case IORESOURCE_IRQ: | 45 | for (num_irqs = 0;; num_irqs++) { |
47 | num_irqs++; | 46 | irq = platform_get_irq(pdev, num_irqs); |
47 | if (irq == -EPROBE_DEFER) | ||
48 | return irq; | ||
49 | if (irq < 0) | ||
48 | break; | 50 | break; |
49 | } | ||
50 | } | 51 | } |
51 | 52 | ||
52 | if (num_windows == 0) | 53 | if (num_windows == 0) |
@@ -72,22 +73,17 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc, | |||
72 | } | 73 | } |
73 | 74 | ||
74 | /* Fill them. */ | 75 | /* Fill them. */ |
75 | for (i = 0, res = pdev->resource; i < pdev->num_resources; i++, res++) { | 76 | for (i = 0; i < num_windows; i++) { |
76 | switch (resource_type(res)) { | 77 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); |
77 | case IORESOURCE_MEM: | 78 | windows->phys = res->start; |
78 | windows->phys = res->start; | 79 | windows->size = resource_size(res); |
79 | windows->size = resource_size(res); | 80 | windows->virt = devm_ioremap_resource(pfc->dev, res); |
80 | windows->virt = devm_ioremap_resource(pfc->dev, res); | 81 | if (IS_ERR(windows->virt)) |
81 | if (IS_ERR(windows->virt)) | 82 | return -ENOMEM; |
82 | return -ENOMEM; | 83 | windows++; |
83 | windows++; | ||
84 | break; | ||
85 | |||
86 | case IORESOURCE_IRQ: | ||
87 | *irqs++ = res->start; | ||
88 | break; | ||
89 | } | ||
90 | } | 84 | } |
85 | for (i = 0; i < num_irqs; i++) | ||
86 | *irqs++ = platform_get_irq(pdev, i); | ||
91 | 87 | ||
92 | return 0; | 88 | return 0; |
93 | } | 89 | } |
@@ -591,9 +587,6 @@ static int sh_pfc_remove(struct platform_device *pdev) | |||
591 | } | 587 | } |
592 | 588 | ||
593 | static const struct platform_device_id sh_pfc_id_table[] = { | 589 | static const struct platform_device_id sh_pfc_id_table[] = { |
594 | #ifdef CONFIG_PINCTRL_PFC_R8A7740 | ||
595 | { "pfc-r8a7740", (kernel_ulong_t)&r8a7740_pinmux_info }, | ||
596 | #endif | ||
597 | #ifdef CONFIG_PINCTRL_PFC_R8A7778 | 590 | #ifdef CONFIG_PINCTRL_PFC_R8A7778 |
598 | { "pfc-r8a7778", (kernel_ulong_t)&r8a7778_pinmux_info }, | 591 | { "pfc-r8a7778", (kernel_ulong_t)&r8a7778_pinmux_info }, |
599 | #endif | 592 | #endif |
@@ -609,9 +602,6 @@ static const struct platform_device_id sh_pfc_id_table[] = { | |||
609 | #ifdef CONFIG_PINCTRL_PFC_SH7269 | 602 | #ifdef CONFIG_PINCTRL_PFC_SH7269 |
610 | { "pfc-sh7269", (kernel_ulong_t)&sh7269_pinmux_info }, | 603 | { "pfc-sh7269", (kernel_ulong_t)&sh7269_pinmux_info }, |
611 | #endif | 604 | #endif |
612 | #ifdef CONFIG_PINCTRL_PFC_SH73A0 | ||
613 | { "pfc-sh73a0", (kernel_ulong_t)&sh73a0_pinmux_info }, | ||
614 | #endif | ||
615 | #ifdef CONFIG_PINCTRL_PFC_SH7720 | 605 | #ifdef CONFIG_PINCTRL_PFC_SH7720 |
616 | { "pfc-sh7720", (kernel_ulong_t)&sh7720_pinmux_info }, | 606 | { "pfc-sh7720", (kernel_ulong_t)&sh7720_pinmux_info }, |
617 | #endif | 607 | #endif |
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index d0bb1459783a..82ef1862dd1b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c | |||
@@ -22,10 +22,6 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/pinctrl/pinconf-generic.h> | 23 | #include <linux/pinctrl/pinconf-generic.h> |
24 | 24 | ||
25 | #ifndef CONFIG_ARCH_MULTIPLATFORM | ||
26 | #include <mach/irqs.h> | ||
27 | #endif | ||
28 | |||
29 | #include "core.h" | 25 | #include "core.h" |
30 | #include "sh_pfc.h" | 26 | #include "sh_pfc.h" |
31 | 27 | ||
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c index baab81ead9ff..fc344a7c2b53 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c | |||
@@ -27,10 +27,27 @@ | |||
27 | #include "core.h" | 27 | #include "core.h" |
28 | #include "sh_pfc.h" | 28 | #include "sh_pfc.h" |
29 | 29 | ||
30 | #define PORT_GP_30(bank, fn, sfx) \ | ||
31 | PORT_GP_1(bank, 0, fn, sfx), PORT_GP_1(bank, 1, fn, sfx), \ | ||
32 | PORT_GP_1(bank, 2, fn, sfx), PORT_GP_1(bank, 3, fn, sfx), \ | ||
33 | PORT_GP_1(bank, 4, fn, sfx), PORT_GP_1(bank, 5, fn, sfx), \ | ||
34 | PORT_GP_1(bank, 6, fn, sfx), PORT_GP_1(bank, 7, fn, sfx), \ | ||
35 | PORT_GP_1(bank, 8, fn, sfx), PORT_GP_1(bank, 9, fn, sfx), \ | ||
36 | PORT_GP_1(bank, 10, fn, sfx), PORT_GP_1(bank, 11, fn, sfx), \ | ||
37 | PORT_GP_1(bank, 12, fn, sfx), PORT_GP_1(bank, 13, fn, sfx), \ | ||
38 | PORT_GP_1(bank, 14, fn, sfx), PORT_GP_1(bank, 15, fn, sfx), \ | ||
39 | PORT_GP_1(bank, 16, fn, sfx), PORT_GP_1(bank, 17, fn, sfx), \ | ||
40 | PORT_GP_1(bank, 18, fn, sfx), PORT_GP_1(bank, 19, fn, sfx), \ | ||
41 | PORT_GP_1(bank, 20, fn, sfx), PORT_GP_1(bank, 21, fn, sfx), \ | ||
42 | PORT_GP_1(bank, 22, fn, sfx), PORT_GP_1(bank, 23, fn, sfx), \ | ||
43 | PORT_GP_1(bank, 24, fn, sfx), PORT_GP_1(bank, 25, fn, sfx), \ | ||
44 | PORT_GP_1(bank, 26, fn, sfx), PORT_GP_1(bank, 27, fn, sfx), \ | ||
45 | PORT_GP_1(bank, 28, fn, sfx), PORT_GP_1(bank, 29, fn, sfx) | ||
46 | |||
30 | #define CPU_ALL_PORT(fn, sfx) \ | 47 | #define CPU_ALL_PORT(fn, sfx) \ |
31 | PORT_GP_32(0, fn, sfx), \ | 48 | PORT_GP_32(0, fn, sfx), \ |
32 | PORT_GP_32(1, fn, sfx), \ | 49 | PORT_GP_30(1, fn, sfx), \ |
33 | PORT_GP_32(2, fn, sfx), \ | 50 | PORT_GP_30(2, fn, sfx), \ |
34 | PORT_GP_32(3, fn, sfx), \ | 51 | PORT_GP_32(3, fn, sfx), \ |
35 | PORT_GP_32(4, fn, sfx), \ | 52 | PORT_GP_32(4, fn, sfx), \ |
36 | PORT_GP_32(5, fn, sfx) | 53 | PORT_GP_32(5, fn, sfx) |
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c index 3ddf23ec9f0b..25e8117f5a1a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c | |||
@@ -14,15 +14,30 @@ | |||
14 | #include "core.h" | 14 | #include "core.h" |
15 | #include "sh_pfc.h" | 15 | #include "sh_pfc.h" |
16 | 16 | ||
17 | #define PORT_GP_26(bank, fn, sfx) \ | ||
18 | PORT_GP_1(bank, 0, fn, sfx), PORT_GP_1(bank, 1, fn, sfx), \ | ||
19 | PORT_GP_1(bank, 2, fn, sfx), PORT_GP_1(bank, 3, fn, sfx), \ | ||
20 | PORT_GP_1(bank, 4, fn, sfx), PORT_GP_1(bank, 5, fn, sfx), \ | ||
21 | PORT_GP_1(bank, 6, fn, sfx), PORT_GP_1(bank, 7, fn, sfx), \ | ||
22 | PORT_GP_1(bank, 8, fn, sfx), PORT_GP_1(bank, 9, fn, sfx), \ | ||
23 | PORT_GP_1(bank, 10, fn, sfx), PORT_GP_1(bank, 11, fn, sfx), \ | ||
24 | PORT_GP_1(bank, 12, fn, sfx), PORT_GP_1(bank, 13, fn, sfx), \ | ||
25 | PORT_GP_1(bank, 14, fn, sfx), PORT_GP_1(bank, 15, fn, sfx), \ | ||
26 | PORT_GP_1(bank, 16, fn, sfx), PORT_GP_1(bank, 17, fn, sfx), \ | ||
27 | PORT_GP_1(bank, 18, fn, sfx), PORT_GP_1(bank, 19, fn, sfx), \ | ||
28 | PORT_GP_1(bank, 20, fn, sfx), PORT_GP_1(bank, 21, fn, sfx), \ | ||
29 | PORT_GP_1(bank, 22, fn, sfx), PORT_GP_1(bank, 23, fn, sfx), \ | ||
30 | PORT_GP_1(bank, 24, fn, sfx), PORT_GP_1(bank, 25, fn, sfx) | ||
31 | |||
17 | #define CPU_ALL_PORT(fn, sfx) \ | 32 | #define CPU_ALL_PORT(fn, sfx) \ |
18 | PORT_GP_32(0, fn, sfx), \ | 33 | PORT_GP_32(0, fn, sfx), \ |
19 | PORT_GP_32(1, fn, sfx), \ | 34 | PORT_GP_26(1, fn, sfx), \ |
20 | PORT_GP_32(2, fn, sfx), \ | 35 | PORT_GP_32(2, fn, sfx), \ |
21 | PORT_GP_32(3, fn, sfx), \ | 36 | PORT_GP_32(3, fn, sfx), \ |
22 | PORT_GP_32(4, fn, sfx), \ | 37 | PORT_GP_32(4, fn, sfx), \ |
23 | PORT_GP_32(5, fn, sfx), \ | 38 | PORT_GP_32(5, fn, sfx), \ |
24 | PORT_GP_32(6, fn, sfx), \ | 39 | PORT_GP_32(6, fn, sfx), \ |
25 | PORT_GP_32(7, fn, sfx) | 40 | PORT_GP_26(7, fn, sfx) |
26 | 41 | ||
27 | enum { | 42 | enum { |
28 | PINMUX_RESERVED = 0, | 43 | PINMUX_RESERVED = 0, |
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7794.c b/drivers/pinctrl/sh-pfc/pfc-r8a7794.c index bfdcac4b3bc4..5248685dbb4e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7794.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7794.c | |||
@@ -2770,6 +2770,24 @@ static const unsigned int sdhi2_wp_pins[] = { | |||
2770 | static const unsigned int sdhi2_wp_mux[] = { | 2770 | static const unsigned int sdhi2_wp_mux[] = { |
2771 | SD2_WP_MARK, | 2771 | SD2_WP_MARK, |
2772 | }; | 2772 | }; |
2773 | /* - USB0 ------------------------------------------------------------------- */ | ||
2774 | static const unsigned int usb0_pins[] = { | ||
2775 | RCAR_GP_PIN(5, 24), /* PWEN */ | ||
2776 | RCAR_GP_PIN(5, 25), /* OVC */ | ||
2777 | }; | ||
2778 | static const unsigned int usb0_mux[] = { | ||
2779 | USB0_PWEN_MARK, | ||
2780 | USB0_OVC_MARK, | ||
2781 | }; | ||
2782 | /* - USB1 ------------------------------------------------------------------- */ | ||
2783 | static const unsigned int usb1_pins[] = { | ||
2784 | RCAR_GP_PIN(5, 26), /* PWEN */ | ||
2785 | RCAR_GP_PIN(5, 27), /* OVC */ | ||
2786 | }; | ||
2787 | static const unsigned int usb1_mux[] = { | ||
2788 | USB1_PWEN_MARK, | ||
2789 | USB1_OVC_MARK, | ||
2790 | }; | ||
2773 | 2791 | ||
2774 | static const struct sh_pfc_pin_group pinmux_groups[] = { | 2792 | static const struct sh_pfc_pin_group pinmux_groups[] = { |
2775 | SH_PFC_PIN_GROUP(eth_link), | 2793 | SH_PFC_PIN_GROUP(eth_link), |
@@ -2945,6 +2963,8 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { | |||
2945 | SH_PFC_PIN_GROUP(sdhi2_ctrl), | 2963 | SH_PFC_PIN_GROUP(sdhi2_ctrl), |
2946 | SH_PFC_PIN_GROUP(sdhi2_cd), | 2964 | SH_PFC_PIN_GROUP(sdhi2_cd), |
2947 | SH_PFC_PIN_GROUP(sdhi2_wp), | 2965 | SH_PFC_PIN_GROUP(sdhi2_wp), |
2966 | SH_PFC_PIN_GROUP(usb0), | ||
2967 | SH_PFC_PIN_GROUP(usb1), | ||
2948 | }; | 2968 | }; |
2949 | 2969 | ||
2950 | static const char * const eth_groups[] = { | 2970 | static const char * const eth_groups[] = { |
@@ -3219,6 +3239,14 @@ static const char * const sdhi2_groups[] = { | |||
3219 | "sdhi2_wp", | 3239 | "sdhi2_wp", |
3220 | }; | 3240 | }; |
3221 | 3241 | ||
3242 | static const char * const usb0_groups[] = { | ||
3243 | "usb0", | ||
3244 | }; | ||
3245 | |||
3246 | static const char * const usb1_groups[] = { | ||
3247 | "usb1", | ||
3248 | }; | ||
3249 | |||
3222 | static const struct sh_pfc_function pinmux_functions[] = { | 3250 | static const struct sh_pfc_function pinmux_functions[] = { |
3223 | SH_PFC_FUNCTION(eth), | 3251 | SH_PFC_FUNCTION(eth), |
3224 | SH_PFC_FUNCTION(hscif0), | 3252 | SH_PFC_FUNCTION(hscif0), |
@@ -3253,6 +3281,8 @@ static const struct sh_pfc_function pinmux_functions[] = { | |||
3253 | SH_PFC_FUNCTION(sdhi0), | 3281 | SH_PFC_FUNCTION(sdhi0), |
3254 | SH_PFC_FUNCTION(sdhi1), | 3282 | SH_PFC_FUNCTION(sdhi1), |
3255 | SH_PFC_FUNCTION(sdhi2), | 3283 | SH_PFC_FUNCTION(sdhi2), |
3284 | SH_PFC_FUNCTION(usb0), | ||
3285 | SH_PFC_FUNCTION(usb1), | ||
3256 | }; | 3286 | }; |
3257 | 3287 | ||
3258 | static const struct pinmux_cfg_reg pinmux_config_regs[] = { | 3288 | static const struct pinmux_cfg_reg pinmux_config_regs[] = { |
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index d2efbfb776ac..097526576f88 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c | |||
@@ -26,10 +26,6 @@ | |||
26 | #include <linux/regulator/machine.h> | 26 | #include <linux/regulator/machine.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | #ifndef CONFIG_ARCH_MULTIPLATFORM | ||
30 | #include <mach/irqs.h> | ||
31 | #endif | ||
32 | |||
33 | #include "core.h" | 29 | #include "core.h" |
34 | #include "sh_pfc.h" | 30 | #include "sh_pfc.h" |
35 | 31 | ||
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index ff678966008b..863c3e30ce05 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c | |||
@@ -40,6 +40,10 @@ struct sh_pfc_pinctrl { | |||
40 | 40 | ||
41 | struct pinctrl_pin_desc *pins; | 41 | struct pinctrl_pin_desc *pins; |
42 | struct sh_pfc_pin_config *configs; | 42 | struct sh_pfc_pin_config *configs; |
43 | |||
44 | const char *func_prop_name; | ||
45 | const char *groups_prop_name; | ||
46 | const char *pins_prop_name; | ||
43 | }; | 47 | }; |
44 | 48 | ||
45 | static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) | 49 | static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) |
@@ -96,10 +100,13 @@ static int sh_pfc_map_add_config(struct pinctrl_map *map, | |||
96 | return 0; | 100 | return 0; |
97 | } | 101 | } |
98 | 102 | ||
99 | static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, | 103 | static int sh_pfc_dt_subnode_to_map(struct pinctrl_dev *pctldev, |
104 | struct device_node *np, | ||
100 | struct pinctrl_map **map, | 105 | struct pinctrl_map **map, |
101 | unsigned int *num_maps, unsigned int *index) | 106 | unsigned int *num_maps, unsigned int *index) |
102 | { | 107 | { |
108 | struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); | ||
109 | struct device *dev = pmx->pfc->dev; | ||
103 | struct pinctrl_map *maps = *map; | 110 | struct pinctrl_map *maps = *map; |
104 | unsigned int nmaps = *num_maps; | 111 | unsigned int nmaps = *num_maps; |
105 | unsigned int idx = *index; | 112 | unsigned int idx = *index; |
@@ -113,10 +120,27 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, | |||
113 | const char *pin; | 120 | const char *pin; |
114 | int ret; | 121 | int ret; |
115 | 122 | ||
123 | /* Support both the old Renesas-specific properties and the new standard | ||
124 | * properties. Mixing old and new properties isn't allowed, neither | ||
125 | * inside a subnode nor across subnodes. | ||
126 | */ | ||
127 | if (!pmx->func_prop_name) { | ||
128 | if (of_find_property(np, "groups", NULL) || | ||
129 | of_find_property(np, "pins", NULL)) { | ||
130 | pmx->func_prop_name = "function"; | ||
131 | pmx->groups_prop_name = "groups"; | ||
132 | pmx->pins_prop_name = "pins"; | ||
133 | } else { | ||
134 | pmx->func_prop_name = "renesas,function"; | ||
135 | pmx->groups_prop_name = "renesas,groups"; | ||
136 | pmx->pins_prop_name = "renesas,pins"; | ||
137 | } | ||
138 | } | ||
139 | |||
116 | /* Parse the function and configuration properties. At least a function | 140 | /* Parse the function and configuration properties. At least a function |
117 | * or one configuration must be specified. | 141 | * or one configuration must be specified. |
118 | */ | 142 | */ |
119 | ret = of_property_read_string(np, "renesas,function", &function); | 143 | ret = of_property_read_string(np, pmx->func_prop_name, &function); |
120 | if (ret < 0 && ret != -EINVAL) { | 144 | if (ret < 0 && ret != -EINVAL) { |
121 | dev_err(dev, "Invalid function in DT\n"); | 145 | dev_err(dev, "Invalid function in DT\n"); |
122 | return ret; | 146 | return ret; |
@@ -129,11 +153,12 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, | |||
129 | if (!function && num_configs == 0) { | 153 | if (!function && num_configs == 0) { |
130 | dev_err(dev, | 154 | dev_err(dev, |
131 | "DT node must contain at least a function or config\n"); | 155 | "DT node must contain at least a function or config\n"); |
156 | ret = -ENODEV; | ||
132 | goto done; | 157 | goto done; |
133 | } | 158 | } |
134 | 159 | ||
135 | /* Count the number of pins and groups and reallocate mappings. */ | 160 | /* Count the number of pins and groups and reallocate mappings. */ |
136 | ret = of_property_count_strings(np, "renesas,pins"); | 161 | ret = of_property_count_strings(np, pmx->pins_prop_name); |
137 | if (ret == -EINVAL) { | 162 | if (ret == -EINVAL) { |
138 | num_pins = 0; | 163 | num_pins = 0; |
139 | } else if (ret < 0) { | 164 | } else if (ret < 0) { |
@@ -143,7 +168,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, | |||
143 | num_pins = ret; | 168 | num_pins = ret; |
144 | } | 169 | } |
145 | 170 | ||
146 | ret = of_property_count_strings(np, "renesas,groups"); | 171 | ret = of_property_count_strings(np, pmx->groups_prop_name); |
147 | if (ret == -EINVAL) { | 172 | if (ret == -EINVAL) { |
148 | num_groups = 0; | 173 | num_groups = 0; |
149 | } else if (ret < 0) { | 174 | } else if (ret < 0) { |
@@ -174,7 +199,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, | |||
174 | *num_maps = nmaps; | 199 | *num_maps = nmaps; |
175 | 200 | ||
176 | /* Iterate over pins and groups and create the mappings. */ | 201 | /* Iterate over pins and groups and create the mappings. */ |
177 | of_property_for_each_string(np, "renesas,groups", prop, group) { | 202 | of_property_for_each_string(np, pmx->groups_prop_name, prop, group) { |
178 | if (function) { | 203 | if (function) { |
179 | maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; | 204 | maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; |
180 | maps[idx].data.mux.group = group; | 205 | maps[idx].data.mux.group = group; |
@@ -198,7 +223,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, | |||
198 | goto done; | 223 | goto done; |
199 | } | 224 | } |
200 | 225 | ||
201 | of_property_for_each_string(np, "renesas,pins", prop, pin) { | 226 | of_property_for_each_string(np, pmx->pins_prop_name, prop, pin) { |
202 | ret = sh_pfc_map_add_config(&maps[idx], pin, | 227 | ret = sh_pfc_map_add_config(&maps[idx], pin, |
203 | PIN_MAP_TYPE_CONFIGS_PIN, | 228 | PIN_MAP_TYPE_CONFIGS_PIN, |
204 | configs, num_configs); | 229 | configs, num_configs); |
@@ -246,7 +271,7 @@ static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
246 | index = 0; | 271 | index = 0; |
247 | 272 | ||
248 | for_each_child_of_node(np, child) { | 273 | for_each_child_of_node(np, child) { |
249 | ret = sh_pfc_dt_subnode_to_map(dev, child, map, num_maps, | 274 | ret = sh_pfc_dt_subnode_to_map(pctldev, child, map, num_maps, |
250 | &index); | 275 | &index); |
251 | if (ret < 0) | 276 | if (ret < 0) |
252 | goto done; | 277 | goto done; |
@@ -254,7 +279,8 @@ static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
254 | 279 | ||
255 | /* If no mapping has been found in child nodes try the config node. */ | 280 | /* If no mapping has been found in child nodes try the config node. */ |
256 | if (*num_maps == 0) { | 281 | if (*num_maps == 0) { |
257 | ret = sh_pfc_dt_subnode_to_map(dev, np, map, num_maps, &index); | 282 | ret = sh_pfc_dt_subnode_to_map(pctldev, np, map, num_maps, |
283 | &index); | ||
258 | if (ret < 0) | 284 | if (ret < 0) |
259 | goto done; | 285 | goto done; |
260 | } | 286 | } |
@@ -465,6 +491,9 @@ static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin, | |||
465 | case PIN_CONFIG_BIAS_PULL_DOWN: | 491 | case PIN_CONFIG_BIAS_PULL_DOWN: |
466 | return pin->configs & SH_PFC_PIN_CFG_PULL_DOWN; | 492 | return pin->configs & SH_PFC_PIN_CFG_PULL_DOWN; |
467 | 493 | ||
494 | case PIN_CONFIG_POWER_SOURCE: | ||
495 | return pin->configs & SH_PFC_PIN_CFG_IO_VOLTAGE; | ||
496 | |||
468 | default: | 497 | default: |
469 | return false; | 498 | return false; |
470 | } | 499 | } |
@@ -477,7 +506,6 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, | |||
477 | struct sh_pfc *pfc = pmx->pfc; | 506 | struct sh_pfc *pfc = pmx->pfc; |
478 | enum pin_config_param param = pinconf_to_config_param(*config); | 507 | enum pin_config_param param = pinconf_to_config_param(*config); |
479 | unsigned long flags; | 508 | unsigned long flags; |
480 | unsigned int bias; | ||
481 | 509 | ||
482 | if (!sh_pfc_pinconf_validate(pfc, _pin, param)) | 510 | if (!sh_pfc_pinconf_validate(pfc, _pin, param)) |
483 | return -ENOTSUPP; | 511 | return -ENOTSUPP; |
@@ -485,7 +513,9 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, | |||
485 | switch (param) { | 513 | switch (param) { |
486 | case PIN_CONFIG_BIAS_DISABLE: | 514 | case PIN_CONFIG_BIAS_DISABLE: |
487 | case PIN_CONFIG_BIAS_PULL_UP: | 515 | case PIN_CONFIG_BIAS_PULL_UP: |
488 | case PIN_CONFIG_BIAS_PULL_DOWN: | 516 | case PIN_CONFIG_BIAS_PULL_DOWN: { |
517 | unsigned int bias; | ||
518 | |||
489 | if (!pfc->info->ops || !pfc->info->ops->get_bias) | 519 | if (!pfc->info->ops || !pfc->info->ops->get_bias) |
490 | return -ENOTSUPP; | 520 | return -ENOTSUPP; |
491 | 521 | ||
@@ -498,6 +528,24 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, | |||
498 | 528 | ||
499 | *config = 0; | 529 | *config = 0; |
500 | break; | 530 | break; |
531 | } | ||
532 | |||
533 | case PIN_CONFIG_POWER_SOURCE: { | ||
534 | int ret; | ||
535 | |||
536 | if (!pfc->info->ops || !pfc->info->ops->get_io_voltage) | ||
537 | return -ENOTSUPP; | ||
538 | |||
539 | spin_lock_irqsave(&pfc->lock, flags); | ||
540 | ret = pfc->info->ops->get_io_voltage(pfc, _pin); | ||
541 | spin_unlock_irqrestore(&pfc->lock, flags); | ||
542 | |||
543 | if (ret < 0) | ||
544 | return ret; | ||
545 | |||
546 | *config = ret; | ||
547 | break; | ||
548 | } | ||
501 | 549 | ||
502 | default: | 550 | default: |
503 | return -ENOTSUPP; | 551 | return -ENOTSUPP; |
@@ -534,6 +582,24 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, | |||
534 | 582 | ||
535 | break; | 583 | break; |
536 | 584 | ||
585 | case PIN_CONFIG_POWER_SOURCE: { | ||
586 | unsigned int arg = | ||
587 | pinconf_to_config_argument(configs[i]); | ||
588 | int ret; | ||
589 | |||
590 | if (!pfc->info->ops || !pfc->info->ops->set_io_voltage) | ||
591 | return -ENOTSUPP; | ||
592 | |||
593 | spin_lock_irqsave(&pfc->lock, flags); | ||
594 | ret = pfc->info->ops->set_io_voltage(pfc, _pin, arg); | ||
595 | spin_unlock_irqrestore(&pfc->lock, flags); | ||
596 | |||
597 | if (ret) | ||
598 | return ret; | ||
599 | |||
600 | break; | ||
601 | } | ||
602 | |||
537 | default: | 603 | default: |
538 | return -ENOTSUPP; | 604 | return -ENOTSUPP; |
539 | } | 605 | } |
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 0874cfee6889..15afd49fd4e3 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define __SH_PFC_H | 12 | #define __SH_PFC_H |
13 | 13 | ||
14 | #include <linux/bug.h> | 14 | #include <linux/bug.h> |
15 | #include <linux/pinctrl/pinconf-generic.h> | ||
15 | #include <linux/stringify.h> | 16 | #include <linux/stringify.h> |
16 | 17 | ||
17 | enum { | 18 | enum { |
@@ -26,6 +27,7 @@ enum { | |||
26 | #define SH_PFC_PIN_CFG_OUTPUT (1 << 1) | 27 | #define SH_PFC_PIN_CFG_OUTPUT (1 << 1) |
27 | #define SH_PFC_PIN_CFG_PULL_UP (1 << 2) | 28 | #define SH_PFC_PIN_CFG_PULL_UP (1 << 2) |
28 | #define SH_PFC_PIN_CFG_PULL_DOWN (1 << 3) | 29 | #define SH_PFC_PIN_CFG_PULL_DOWN (1 << 3) |
30 | #define SH_PFC_PIN_CFG_IO_VOLTAGE (1 << 4) | ||
29 | #define SH_PFC_PIN_CFG_NO_GPIO (1 << 31) | 31 | #define SH_PFC_PIN_CFG_NO_GPIO (1 << 31) |
30 | 32 | ||
31 | struct sh_pfc_pin { | 33 | struct sh_pfc_pin { |
@@ -121,6 +123,9 @@ struct sh_pfc_soc_operations { | |||
121 | unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin); | 123 | unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin); |
122 | void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, | 124 | void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, |
123 | unsigned int bias); | 125 | unsigned int bias); |
126 | int (*get_io_voltage)(struct sh_pfc *pfc, unsigned int pin); | ||
127 | int (*set_io_voltage)(struct sh_pfc *pfc, unsigned int pin, | ||
128 | u16 voltage_mV); | ||
124 | }; | 129 | }; |
125 | 130 | ||
126 | struct sh_pfc_soc_info { | 131 | struct sh_pfc_soc_info { |