diff options
Diffstat (limited to 'drivers/pinctrl')
61 files changed, 5515 insertions, 1329 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index aeecf0f72cad..c31aeb01bb00 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -26,6 +26,15 @@ config DEBUG_PINCTRL | |||
26 | help | 26 | help |
27 | Say Y here to add some extra checks and diagnostics to PINCTRL calls. | 27 | Say Y here to add some extra checks and diagnostics to PINCTRL calls. |
28 | 28 | ||
29 | config PINCTRL_AT91 | ||
30 | bool "AT91 pinctrl driver" | ||
31 | depends on OF | ||
32 | depends on ARCH_AT91 | ||
33 | select PINMUX | ||
34 | select PINCONF | ||
35 | help | ||
36 | Say Y here to enable the at91 pinctrl driver | ||
37 | |||
29 | config PINCTRL_BCM2835 | 38 | config PINCTRL_BCM2835 |
30 | bool | 39 | bool |
31 | select PINMUX | 40 | select PINMUX |
@@ -87,21 +96,18 @@ config PINCTRL_MMP2 | |||
87 | bool "MMP2 pin controller driver" | 96 | bool "MMP2 pin controller driver" |
88 | depends on ARCH_MMP | 97 | depends on ARCH_MMP |
89 | select PINCTRL_PXA3xx | 98 | select PINCTRL_PXA3xx |
90 | select PINCONF | ||
91 | 99 | ||
92 | config PINCTRL_MXS | 100 | config PINCTRL_MXS |
93 | bool | 101 | bool |
102 | select PINMUX | ||
103 | select PINCONF | ||
94 | 104 | ||
95 | config PINCTRL_IMX23 | 105 | config PINCTRL_IMX23 |
96 | bool | 106 | bool |
97 | select PINMUX | ||
98 | select PINCONF | ||
99 | select PINCTRL_MXS | 107 | select PINCTRL_MXS |
100 | 108 | ||
101 | config PINCTRL_IMX28 | 109 | config PINCTRL_IMX28 |
102 | bool | 110 | bool |
103 | select PINMUX | ||
104 | select PINCONF | ||
105 | select PINCTRL_MXS | 111 | select PINCTRL_MXS |
106 | 112 | ||
107 | config PINCTRL_NOMADIK | 113 | config PINCTRL_NOMADIK |
@@ -126,13 +132,11 @@ config PINCTRL_PXA168 | |||
126 | bool "PXA168 pin controller driver" | 132 | bool "PXA168 pin controller driver" |
127 | depends on ARCH_MMP | 133 | depends on ARCH_MMP |
128 | select PINCTRL_PXA3xx | 134 | select PINCTRL_PXA3xx |
129 | select PINCONF | ||
130 | 135 | ||
131 | config PINCTRL_PXA910 | 136 | config PINCTRL_PXA910 |
132 | bool "PXA910 pin controller driver" | 137 | bool "PXA910 pin controller driver" |
133 | depends on ARCH_MMP | 138 | depends on ARCH_MMP |
134 | select PINCTRL_PXA3xx | 139 | select PINCTRL_PXA3xx |
135 | select PINCONF | ||
136 | 140 | ||
137 | config PINCTRL_SINGLE | 141 | config PINCTRL_SINGLE |
138 | tristate "One-register-per-pin type device tree based pinctrl driver" | 142 | tristate "One-register-per-pin type device tree based pinctrl driver" |
@@ -143,23 +147,21 @@ config PINCTRL_SINGLE | |||
143 | This selects the device tree based generic pinctrl driver. | 147 | This selects the device tree based generic pinctrl driver. |
144 | 148 | ||
145 | config PINCTRL_SIRF | 149 | config PINCTRL_SIRF |
146 | bool "CSR SiRFprimaII pin controller driver" | 150 | bool "CSR SiRFprimaII/SiRFmarco pin controller driver" |
147 | depends on ARCH_PRIMA2 | 151 | depends on ARCH_SIRF |
148 | select PINMUX | 152 | select PINMUX |
149 | 153 | ||
150 | config PINCTRL_TEGRA | 154 | config PINCTRL_TEGRA |
151 | bool | 155 | bool |
156 | select PINMUX | ||
157 | select PINCONF | ||
152 | 158 | ||
153 | config PINCTRL_TEGRA20 | 159 | config PINCTRL_TEGRA20 |
154 | bool | 160 | bool |
155 | select PINMUX | ||
156 | select PINCONF | ||
157 | select PINCTRL_TEGRA | 161 | select PINCTRL_TEGRA |
158 | 162 | ||
159 | config PINCTRL_TEGRA30 | 163 | config PINCTRL_TEGRA30 |
160 | bool | 164 | bool |
161 | select PINMUX | ||
162 | select PINCONF | ||
163 | select PINCTRL_TEGRA | 165 | select PINCTRL_TEGRA |
164 | 166 | ||
165 | config PINCTRL_U300 | 167 | config PINCTRL_U300 |
@@ -188,27 +190,12 @@ config PINCTRL_EXYNOS4 | |||
188 | depends on OF && GPIOLIB | 190 | depends on OF && GPIOLIB |
189 | select PINCTRL_SAMSUNG | 191 | select PINCTRL_SAMSUNG |
190 | 192 | ||
191 | config PINCTRL_MVEBU | 193 | config PINCTRL_EXYNOS5440 |
192 | bool | 194 | bool "Samsung EXYNOS5440 SoC pinctrl driver" |
193 | depends on ARCH_MVEBU | ||
194 | select PINMUX | 195 | select PINMUX |
195 | select PINCONF | 196 | select PINCONF |
196 | 197 | ||
197 | config PINCTRL_DOVE | 198 | source "drivers/pinctrl/mvebu/Kconfig" |
198 | bool | ||
199 | select PINCTRL_MVEBU | ||
200 | |||
201 | config PINCTRL_KIRKWOOD | ||
202 | bool | ||
203 | select PINCTRL_MVEBU | ||
204 | |||
205 | config PINCTRL_ARMADA_370 | ||
206 | bool | ||
207 | select PINCTRL_MVEBU | ||
208 | |||
209 | config PINCTRL_ARMADA_XP | ||
210 | bool | ||
211 | select PINCTRL_MVEBU | ||
212 | 199 | ||
213 | source "drivers/pinctrl/spear/Kconfig" | 200 | source "drivers/pinctrl/spear/Kconfig" |
214 | 201 | ||
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f395ba5cec25..fc4606f27dc7 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
@@ -9,6 +9,7 @@ ifeq ($(CONFIG_OF),y) | |||
9 | obj-$(CONFIG_PINCTRL) += devicetree.o | 9 | obj-$(CONFIG_PINCTRL) += devicetree.o |
10 | endif | 10 | endif |
11 | obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o | 11 | obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o |
12 | obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o | ||
12 | obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o | 13 | obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o |
13 | obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o | 14 | obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o |
14 | obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o | 15 | obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o |
@@ -36,12 +37,9 @@ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o | |||
36 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o | 37 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o |
37 | obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o | 38 | obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o |
38 | obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o | 39 | obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o |
39 | obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o | 40 | obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o |
40 | obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o | ||
41 | obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o | ||
42 | obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o | ||
43 | obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o | ||
44 | obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o | 41 | obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o |
45 | obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o | 42 | obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o |
46 | 43 | ||
44 | obj-$(CONFIG_PLAT_ORION) += mvebu/ | ||
47 | obj-$(CONFIG_PLAT_SPEAR) += spear/ | 45 | obj-$(CONFIG_PLAT_SPEAR) += spear/ |
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 2e39c04fc16b..5cdee8669ea3 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -345,6 +345,62 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, | |||
345 | } | 345 | } |
346 | EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); | 346 | EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); |
347 | 347 | ||
348 | struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, | ||
349 | struct pinctrl_gpio_range *range) | ||
350 | { | ||
351 | struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname); | ||
352 | |||
353 | /* | ||
354 | * If we can't find this device, let's assume that is because | ||
355 | * it has not probed yet, so the driver trying to register this | ||
356 | * range need to defer probing. | ||
357 | */ | ||
358 | if (!pctldev) | ||
359 | return ERR_PTR(-EPROBE_DEFER); | ||
360 | |||
361 | pinctrl_add_gpio_range(pctldev, range); | ||
362 | return pctldev; | ||
363 | } | ||
364 | EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); | ||
365 | |||
366 | /** | ||
367 | * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin | ||
368 | * @pctldev: the pin controller device to look in | ||
369 | * @pin: a controller-local number to find the range for | ||
370 | */ | ||
371 | struct pinctrl_gpio_range * | ||
372 | pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, | ||
373 | unsigned int pin) | ||
374 | { | ||
375 | struct pinctrl_gpio_range *range = NULL; | ||
376 | |||
377 | /* Loop over the ranges */ | ||
378 | list_for_each_entry(range, &pctldev->gpio_ranges, node) { | ||
379 | /* Check if we're in the valid range */ | ||
380 | if (pin >= range->pin_base && | ||
381 | pin < range->pin_base + range->npins) { | ||
382 | return range; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | return NULL; | ||
387 | } | ||
388 | EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin); | ||
389 | |||
390 | /** | ||
391 | * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller | ||
392 | * @pctldev: pin controller device to remove the range from | ||
393 | * @range: the GPIO range to remove | ||
394 | */ | ||
395 | void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, | ||
396 | struct pinctrl_gpio_range *range) | ||
397 | { | ||
398 | mutex_lock(&pinctrl_mutex); | ||
399 | list_del(&range->node); | ||
400 | mutex_unlock(&pinctrl_mutex); | ||
401 | } | ||
402 | EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); | ||
403 | |||
348 | /** | 404 | /** |
349 | * pinctrl_get_group_selector() - returns the group selector for a group | 405 | * pinctrl_get_group_selector() - returns the group selector for a group |
350 | * @pctldev: the pin controller handling the group | 406 | * @pctldev: the pin controller handling the group |
@@ -563,6 +619,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) | |||
563 | return -EPROBE_DEFER; | 619 | return -EPROBE_DEFER; |
564 | } | 620 | } |
565 | 621 | ||
622 | setting->dev_name = map->dev_name; | ||
623 | |||
566 | switch (map->type) { | 624 | switch (map->type) { |
567 | case PIN_MAP_TYPE_MUX_GROUP: | 625 | case PIN_MAP_TYPE_MUX_GROUP: |
568 | ret = pinmux_map_to_setting(map, setting); | 626 | ret = pinmux_map_to_setting(map, setting); |
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 1f40ff68a8c4..12f5694f3d5d 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
@@ -105,12 +105,14 @@ struct pinctrl_setting_configs { | |||
105 | * @type: the type of setting | 105 | * @type: the type of setting |
106 | * @pctldev: pin control device handling to be programmed. Not used for | 106 | * @pctldev: pin control device handling to be programmed. Not used for |
107 | * PIN_MAP_TYPE_DUMMY_STATE. | 107 | * PIN_MAP_TYPE_DUMMY_STATE. |
108 | * @dev_name: the name of the device using this state | ||
108 | * @data: Data specific to the setting type | 109 | * @data: Data specific to the setting type |
109 | */ | 110 | */ |
110 | struct pinctrl_setting { | 111 | struct pinctrl_setting { |
111 | struct list_head node; | 112 | struct list_head node; |
112 | enum pinctrl_map_type type; | 113 | enum pinctrl_map_type type; |
113 | struct pinctrl_dev *pctldev; | 114 | struct pinctrl_dev *pctldev; |
115 | const char *dev_name; | ||
114 | union { | 116 | union { |
115 | struct pinctrl_setting_mux mux; | 117 | struct pinctrl_setting_mux mux; |
116 | struct pinctrl_setting_configs configs; | 118 | struct pinctrl_setting_configs configs; |
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index fcb1de45473c..fe2d1af7cfa0 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c | |||
@@ -106,6 +106,17 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) | |||
106 | return NULL; | 106 | return NULL; |
107 | } | 107 | } |
108 | 108 | ||
109 | struct pinctrl_dev *of_pinctrl_get(struct device_node *np) | ||
110 | { | ||
111 | struct pinctrl_dev *pctldev; | ||
112 | |||
113 | pctldev = find_pinctrl_by_of_node(np); | ||
114 | if (!pctldev) | ||
115 | return NULL; | ||
116 | |||
117 | return pctldev; | ||
118 | } | ||
119 | |||
109 | static int dt_to_map_one_config(struct pinctrl *p, const char *statename, | 120 | static int dt_to_map_one_config(struct pinctrl *p, const char *statename, |
110 | struct device_node *np_config) | 121 | struct device_node *np_config) |
111 | { | 122 | { |
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig new file mode 100644 index 000000000000..366fa541ee91 --- /dev/null +++ b/drivers/pinctrl/mvebu/Kconfig | |||
@@ -0,0 +1,24 @@ | |||
1 | if PLAT_ORION | ||
2 | |||
3 | config PINCTRL_MVEBU | ||
4 | bool | ||
5 | select PINMUX | ||
6 | select PINCONF | ||
7 | |||
8 | config PINCTRL_DOVE | ||
9 | bool | ||
10 | select PINCTRL_MVEBU | ||
11 | |||
12 | config PINCTRL_KIRKWOOD | ||
13 | bool | ||
14 | select PINCTRL_MVEBU | ||
15 | |||
16 | config PINCTRL_ARMADA_370 | ||
17 | bool | ||
18 | select PINCTRL_MVEBU | ||
19 | |||
20 | config PINCTRL_ARMADA_XP | ||
21 | bool | ||
22 | select PINCTRL_MVEBU | ||
23 | |||
24 | endif | ||
diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile new file mode 100644 index 000000000000..37c253297af0 --- /dev/null +++ b/drivers/pinctrl/mvebu/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o | ||
2 | obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o | ||
3 | obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o | ||
4 | obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o | ||
5 | obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o | ||
diff --git a/drivers/pinctrl/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c index c907647de6ad..c907647de6ad 100644 --- a/drivers/pinctrl/pinctrl-armada-370.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c | |||
diff --git a/drivers/pinctrl/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c index 40bd52a46b4e..40bd52a46b4e 100644 --- a/drivers/pinctrl/pinctrl-armada-xp.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c | |||
diff --git a/drivers/pinctrl/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c index ffe74b27d66d..40c9c3eecd94 100644 --- a/drivers/pinctrl/pinctrl-dove.c +++ b/drivers/pinctrl/mvebu/pinctrl-dove.c | |||
@@ -22,22 +22,22 @@ | |||
22 | 22 | ||
23 | #include "pinctrl-mvebu.h" | 23 | #include "pinctrl-mvebu.h" |
24 | 24 | ||
25 | #define DOVE_SB_REGS_VIRT_BASE 0xfde00000 | 25 | #define DOVE_SB_REGS_VIRT_BASE IOMEM(0xfde00000) |
26 | #define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200) | 26 | #define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0200) |
27 | #define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10) | 27 | #define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10) |
28 | #define DOVE_AU0_AC97_SEL BIT(16) | 28 | #define DOVE_AU0_AC97_SEL BIT(16) |
29 | #define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C) | 29 | #define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C) |
30 | #define DOVE_TWSI_ENABLE_OPTION1 BIT(7) | 30 | #define DOVE_TWSI_ENABLE_OPTION1 BIT(7) |
31 | #define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030) | 31 | #define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE + 0xe8030) |
32 | #define DOVE_TWSI_ENABLE_OPTION2 BIT(20) | 32 | #define DOVE_TWSI_ENABLE_OPTION2 BIT(20) |
33 | #define DOVE_TWSI_ENABLE_OPTION3 BIT(21) | 33 | #define DOVE_TWSI_ENABLE_OPTION3 BIT(21) |
34 | #define DOVE_TWSI_OPTION3_GPIO BIT(22) | 34 | #define DOVE_TWSI_OPTION3_GPIO BIT(22) |
35 | #define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034) | 35 | #define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE + 0xe8034) |
36 | #define DOVE_SSP_ON_AU1 BIT(0) | 36 | #define DOVE_SSP_ON_AU1 BIT(0) |
37 | #define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c) | 37 | #define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe803c) |
38 | #define DOVE_AU1_SPDIFO_GPIO_EN BIT(1) | 38 | #define DOVE_AU1_SPDIFO_GPIO_EN BIT(1) |
39 | #define DOVE_NAND_GPIO_EN BIT(0) | 39 | #define DOVE_NAND_GPIO_EN BIT(0) |
40 | #define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400) | 40 | #define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0400) |
41 | #define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40) | 41 | #define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40) |
42 | #define DOVE_SPI_GPIO_SEL BIT(5) | 42 | #define DOVE_SPI_GPIO_SEL BIT(5) |
43 | #define DOVE_UART1_GPIO_SEL BIT(4) | 43 | #define DOVE_UART1_GPIO_SEL BIT(4) |
@@ -234,6 +234,14 @@ static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl, | |||
234 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | 234 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); |
235 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | 235 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); |
236 | 236 | ||
237 | /* | ||
238 | * clear all audio1 related bits before configure | ||
239 | */ | ||
240 | gcfg2 &= ~DOVE_TWSI_OPTION3_GPIO; | ||
241 | gmpp &= ~DOVE_AU1_SPDIFO_GPIO_EN; | ||
242 | sspc1 &= ~DOVE_SSP_ON_AU1; | ||
243 | mpp4 &= ~DOVE_AU1_GPIO_SEL; | ||
244 | |||
237 | if (config & BIT(0)) | 245 | if (config & BIT(0)) |
238 | gcfg2 |= DOVE_TWSI_OPTION3_GPIO; | 246 | gcfg2 |= DOVE_TWSI_OPTION3_GPIO; |
239 | if (config & BIT(1)) | 247 | if (config & BIT(1)) |
diff --git a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c new file mode 100644 index 000000000000..fa6ce31c94d9 --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c | |||
@@ -0,0 +1,484 @@ | |||
1 | /* | ||
2 | * Marvell Kirkwood pinctrl driver based on mvebu pinctrl core | ||
3 | * | ||
4 | * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/err.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_device.h> | ||
20 | #include <linux/pinctrl/pinctrl.h> | ||
21 | |||
22 | #include "pinctrl-mvebu.h" | ||
23 | |||
24 | #define V(f6180, f6190, f6192, f6281, f6282, dx4122) \ | ||
25 | ((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \ | ||
26 | (f6281 << 3) | (f6282 << 4) | (dx4122 << 5)) | ||
27 | |||
28 | enum kirkwood_variant { | ||
29 | VARIANT_MV88F6180 = V(1, 0, 0, 0, 0, 0), | ||
30 | VARIANT_MV88F6190 = V(0, 1, 0, 0, 0, 0), | ||
31 | VARIANT_MV88F6192 = V(0, 0, 1, 0, 0, 0), | ||
32 | VARIANT_MV88F6281 = V(0, 0, 0, 1, 0, 0), | ||
33 | VARIANT_MV88F6282 = V(0, 0, 0, 0, 1, 0), | ||
34 | VARIANT_MV98DX4122 = V(0, 0, 0, 0, 0, 1), | ||
35 | }; | ||
36 | |||
37 | static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = { | ||
38 | MPP_MODE(0, | ||
39 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
40 | MPP_VAR_FUNCTION(0x1, "nand", "io2", V(1, 1, 1, 1, 1, 1)), | ||
41 | MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1, 1))), | ||
42 | MPP_MODE(1, | ||
43 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), | ||
44 | MPP_VAR_FUNCTION(0x1, "nand", "io3", V(1, 1, 1, 1, 1, 1)), | ||
45 | MPP_VAR_FUNCTION(0x2, "spi", "mosi", V(1, 1, 1, 1, 1, 1))), | ||
46 | MPP_MODE(2, | ||
47 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), | ||
48 | MPP_VAR_FUNCTION(0x1, "nand", "io4", V(1, 1, 1, 1, 1, 1)), | ||
49 | MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1, 1))), | ||
50 | MPP_MODE(3, | ||
51 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), | ||
52 | MPP_VAR_FUNCTION(0x1, "nand", "io5", V(1, 1, 1, 1, 1, 1)), | ||
53 | MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1, 1))), | ||
54 | MPP_MODE(4, | ||
55 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
56 | MPP_VAR_FUNCTION(0x1, "nand", "io6", V(1, 1, 1, 1, 1, 1)), | ||
57 | MPP_VAR_FUNCTION(0x2, "uart0", "rxd", V(1, 1, 1, 1, 1, 1)), | ||
58 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1, 0)), | ||
59 | MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1, 0)), | ||
60 | MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0, 0))), | ||
61 | MPP_MODE(5, | ||
62 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), | ||
63 | MPP_VAR_FUNCTION(0x1, "nand", "io7", V(1, 1, 1, 1, 1, 1)), | ||
64 | MPP_VAR_FUNCTION(0x2, "uart0", "txd", V(1, 1, 1, 1, 1, 1)), | ||
65 | MPP_VAR_FUNCTION(0x4, "ptp", "trig", V(1, 1, 1, 1, 0, 0)), | ||
66 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)), | ||
67 | MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1, 0))), | ||
68 | MPP_MODE(6, | ||
69 | MPP_VAR_FUNCTION(0x0, "sysrst", "out", V(1, 1, 1, 1, 1, 1)), | ||
70 | MPP_VAR_FUNCTION(0x1, "spi", "mosi", V(1, 1, 1, 1, 1, 1)), | ||
71 | MPP_VAR_FUNCTION(0x2, "ptp", "trig", V(1, 1, 1, 1, 0, 0))), | ||
72 | MPP_MODE(7, | ||
73 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), | ||
74 | MPP_VAR_FUNCTION(0x1, "pex", "rsto", V(1, 1, 1, 1, 0, 1)), | ||
75 | MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1, 1)), | ||
76 | MPP_VAR_FUNCTION(0x3, "ptp", "trig", V(1, 1, 1, 1, 0, 0)), | ||
77 | MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1, 0))), | ||
78 | MPP_MODE(8, | ||
79 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
80 | MPP_VAR_FUNCTION(0x1, "twsi0", "sda", V(1, 1, 1, 1, 1, 1)), | ||
81 | MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1, 1)), | ||
82 | MPP_VAR_FUNCTION(0x3, "uart1", "rts", V(1, 1, 1, 1, 1, 1)), | ||
83 | MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr", V(0, 1, 1, 1, 1, 0)), | ||
84 | MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1, 0)), | ||
85 | MPP_VAR_FUNCTION(0xc, "ptp", "clk", V(1, 1, 1, 1, 0, 0)), | ||
86 | MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1, 0))), | ||
87 | MPP_MODE(9, | ||
88 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
89 | MPP_VAR_FUNCTION(0x1, "twsi0", "sck", V(1, 1, 1, 1, 1, 1)), | ||
90 | MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1, 1)), | ||
91 | MPP_VAR_FUNCTION(0x3, "uart1", "cts", V(1, 1, 1, 1, 1, 1)), | ||
92 | MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1, 0)), | ||
93 | MPP_VAR_FUNCTION(0xc, "ptp", "evreq", V(1, 1, 1, 1, 0, 0)), | ||
94 | MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1, 0))), | ||
95 | MPP_MODE(10, | ||
96 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), | ||
97 | MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1, 1)), | ||
98 | MPP_VAR_FUNCTION(0X3, "uart0", "txd", V(1, 1, 1, 1, 1, 1)), | ||
99 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1, 0)), | ||
100 | MPP_VAR_FUNCTION(0xc, "ptp", "trig", V(1, 1, 1, 1, 0, 0))), | ||
101 | MPP_MODE(11, | ||
102 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
103 | MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1, 1)), | ||
104 | MPP_VAR_FUNCTION(0x3, "uart0", "rxd", V(1, 1, 1, 1, 1, 1)), | ||
105 | MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq", V(1, 1, 1, 1, 0, 0)), | ||
106 | MPP_VAR_FUNCTION(0xc, "ptp-2", "trig", V(1, 1, 1, 1, 0, 0)), | ||
107 | MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0, 0)), | ||
108 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0))), | ||
109 | MPP_MODE(12, | ||
110 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 0, 1, 0)), | ||
111 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0, 0)), | ||
112 | MPP_VAR_FUNCTION(0x1, "sdio", "clk", V(1, 1, 1, 1, 1, 0)), | ||
113 | MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1, 0)), | ||
114 | MPP_VAR_FUNCTION(0xb, "spi", "mosi", V(0, 0, 0, 0, 1, 0)), | ||
115 | MPP_VAR_FUNCTION(0xd, "twsi1", "sda", V(0, 0, 0, 0, 1, 0))), | ||
116 | MPP_MODE(13, | ||
117 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
118 | MPP_VAR_FUNCTION(0x1, "sdio", "cmd", V(1, 1, 1, 1, 1, 0)), | ||
119 | MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1, 1)), | ||
120 | MPP_VAR_FUNCTION(0xa, "audio", "rmclk", V(0, 0, 0, 0, 1, 0)), | ||
121 | MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1, 0))), | ||
122 | MPP_MODE(14, | ||
123 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
124 | MPP_VAR_FUNCTION(0x1, "sdio", "d0", V(1, 1, 1, 1, 1, 0)), | ||
125 | MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1, 1)), | ||
126 | MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V(0, 0, 1, 1, 1, 0)), | ||
127 | MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1, 0)), | ||
128 | MPP_VAR_FUNCTION(0xb, "audio-1", "sdi", V(0, 0, 0, 0, 1, 0)), | ||
129 | MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1, 0))), | ||
130 | MPP_MODE(15, | ||
131 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
132 | MPP_VAR_FUNCTION(0x1, "sdio", "d1", V(1, 1, 1, 1, 1, 0)), | ||
133 | MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1, 1)), | ||
134 | MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1, 0)), | ||
135 | MPP_VAR_FUNCTION(0x4, "sata0", "act", V(0, 1, 1, 1, 1, 0)), | ||
136 | MPP_VAR_FUNCTION(0xb, "spi", "cs", V(0, 0, 0, 0, 1, 0))), | ||
137 | MPP_MODE(16, | ||
138 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), | ||
139 | MPP_VAR_FUNCTION(0x1, "sdio", "d2", V(1, 1, 1, 1, 1, 0)), | ||
140 | MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1, 1)), | ||
141 | MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1, 0)), | ||
142 | MPP_VAR_FUNCTION(0x4, "sata1", "act", V(0, 0, 1, 1, 1, 0)), | ||
143 | MPP_VAR_FUNCTION(0xb, "lcd", "extclk", V(0, 0, 0, 0, 1, 0)), | ||
144 | MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1, 0))), | ||
145 | MPP_MODE(17, | ||
146 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
147 | MPP_VAR_FUNCTION(0x1, "sdio", "d3", V(1, 1, 1, 1, 1, 0)), | ||
148 | MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V(0, 1, 1, 1, 1, 0)), | ||
149 | MPP_VAR_FUNCTION(0xa, "sata1", "act", V(0, 0, 0, 0, 1, 0)), | ||
150 | MPP_VAR_FUNCTION(0xd, "twsi1", "sck", V(0, 0, 0, 0, 1, 0))), | ||
151 | MPP_MODE(18, | ||
152 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), | ||
153 | MPP_VAR_FUNCTION(0x1, "nand", "io0", V(1, 1, 1, 1, 1, 1)), | ||
154 | MPP_VAR_FUNCTION(0x2, "pex", "clkreq", V(0, 0, 0, 0, 1, 0))), | ||
155 | MPP_MODE(19, | ||
156 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), | ||
157 | MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1, 1))), | ||
158 | MPP_MODE(20, | ||
159 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
160 | MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1, 0)), | ||
161 | MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)), | ||
162 | MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1, 0)), | ||
163 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1, 0)), | ||
164 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1, 0)), | ||
165 | MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1, 0)), | ||
166 | MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0, 0))), | ||
167 | MPP_MODE(21, | ||
168 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
169 | MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1, 0)), | ||
170 | MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1, 0)), | ||
171 | MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1, 0)), | ||
172 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0, 0)), | ||
173 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1, 0)), | ||
174 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)), | ||
175 | MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1, 0))), | ||
176 | MPP_MODE(22, | ||
177 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
178 | MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1, 0)), | ||
179 | MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1, 0)), | ||
180 | MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1, 0)), | ||
181 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0, 0)), | ||
182 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1, 0)), | ||
183 | MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1, 0)), | ||
184 | MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1, 0))), | ||
185 | MPP_MODE(23, | ||
186 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
187 | MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1, 0)), | ||
188 | MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1, 0)), | ||
189 | MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1, 0)), | ||
190 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0, 0)), | ||
191 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1, 0)), | ||
192 | MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1, 0)), | ||
193 | MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1, 0))), | ||
194 | MPP_MODE(24, | ||
195 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
196 | MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1, 0)), | ||
197 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1, 0)), | ||
198 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1, 0)), | ||
199 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0, 0)), | ||
200 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1, 0)), | ||
201 | MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1, 0))), | ||
202 | MPP_MODE(25, | ||
203 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
204 | MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1, 0)), | ||
205 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1, 0)), | ||
206 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1, 0)), | ||
207 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0, 0)), | ||
208 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1, 0)), | ||
209 | MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1, 0))), | ||
210 | MPP_MODE(26, | ||
211 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
212 | MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1, 0)), | ||
213 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1, 0)), | ||
214 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1, 0)), | ||
215 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0, 0)), | ||
216 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1, 0)), | ||
217 | MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1, 0))), | ||
218 | MPP_MODE(27, | ||
219 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
220 | MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1, 0)), | ||
221 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1, 0)), | ||
222 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1, 0)), | ||
223 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0, 0)), | ||
224 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1, 0)), | ||
225 | MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1, 0))), | ||
226 | MPP_MODE(28, | ||
227 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
228 | MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1, 0)), | ||
229 | MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1, 0)), | ||
230 | MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1, 0)), | ||
231 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0, 0)), | ||
232 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1, 0)), | ||
233 | MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1, 0))), | ||
234 | MPP_MODE(29, | ||
235 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), | ||
236 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1, 0)), | ||
237 | MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1, 0)), | ||
238 | MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1, 0)), | ||
239 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0, 0)), | ||
240 | MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1, 0))), | ||
241 | MPP_MODE(30, | ||
242 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), | ||
243 | MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 1, 1, 1, 0)), | ||
244 | MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 1, 1, 1, 0)), | ||
245 | MPP_VAR_FUNCTION(0x3, "ge1", "rxctl", V(0, 1, 1, 1, 1, 0)), | ||
246 | MPP_VAR_FUNCTION(0xb, "lcd", "d10", V(0, 0, 0, 0, 1, 0))), | ||
247 | MPP_MODE(31, | ||
248 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), | ||
249 | MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 1, 1, 1, 0)), | ||
250 | MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 1, 1, 1, 0)), | ||
251 | MPP_VAR_FUNCTION(0x3, "ge1", "rxclk", V(0, 1, 1, 1, 1, 0)), | ||
252 | MPP_VAR_FUNCTION(0xb, "lcd", "d11", V(0, 0, 0, 0, 1, 0))), | ||
253 | MPP_MODE(32, | ||
254 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), | ||
255 | MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 1, 1, 1, 0)), | ||
256 | MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 1, 1, 1, 0)), | ||
257 | MPP_VAR_FUNCTION(0x3, "ge1", "txclko", V(0, 1, 1, 1, 1, 0)), | ||
258 | MPP_VAR_FUNCTION(0xb, "lcd", "d12", V(0, 0, 0, 0, 1, 0))), | ||
259 | MPP_MODE(33, | ||
260 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 1, 1, 1, 1, 0)), | ||
261 | MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 1, 1, 1, 0)), | ||
262 | MPP_VAR_FUNCTION(0x3, "ge1", "txctl", V(0, 1, 1, 1, 1, 0)), | ||
263 | MPP_VAR_FUNCTION(0xb, "lcd", "d13", V(0, 0, 0, 0, 1, 0))), | ||
264 | MPP_MODE(34, | ||
265 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 1)), | ||
266 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 1, 1, 1, 0)), | ||
267 | MPP_VAR_FUNCTION(0x3, "ge1", "txen", V(0, 1, 1, 1, 1, 0)), | ||
268 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1, 0)), | ||
269 | MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1, 0))), | ||
270 | MPP_MODE(35, | ||
271 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 1)), | ||
272 | MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)), | ||
273 | MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1, 0)), | ||
274 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)), | ||
275 | MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1, 0)), | ||
276 | MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1, 0))), | ||
277 | MPP_MODE(36, | ||
278 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
279 | MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1, 0)), | ||
280 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1, 0)), | ||
281 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1, 0)), | ||
282 | MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1, 0))), | ||
283 | MPP_MODE(37, | ||
284 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
285 | MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1, 0)), | ||
286 | MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1, 0)), | ||
287 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1, 0)), | ||
288 | MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1, 0))), | ||
289 | MPP_MODE(38, | ||
290 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
291 | MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1, 0)), | ||
292 | MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1, 0)), | ||
293 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1, 0)), | ||
294 | MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1, 0))), | ||
295 | MPP_MODE(39, | ||
296 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
297 | MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1, 0)), | ||
298 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1, 0)), | ||
299 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1, 0)), | ||
300 | MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1, 0))), | ||
301 | MPP_MODE(40, | ||
302 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
303 | MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1, 0)), | ||
304 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1, 0)), | ||
305 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1, 0)), | ||
306 | MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1, 0))), | ||
307 | MPP_MODE(41, | ||
308 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
309 | MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1, 0)), | ||
310 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1, 0)), | ||
311 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1, 0)), | ||
312 | MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1, 0))), | ||
313 | MPP_MODE(42, | ||
314 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
315 | MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1, 0)), | ||
316 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1, 0)), | ||
317 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1, 0)), | ||
318 | MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1, 0))), | ||
319 | MPP_MODE(43, | ||
320 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
321 | MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1, 0)), | ||
322 | MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1, 0)), | ||
323 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1, 0)), | ||
324 | MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1, 0))), | ||
325 | MPP_MODE(44, | ||
326 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
327 | MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1, 0)), | ||
328 | MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1, 0)), | ||
329 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1, 0)), | ||
330 | MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1, 0))), | ||
331 | MPP_MODE(45, | ||
332 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), | ||
333 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 1, 0)), | ||
334 | MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 0, 1, 1, 0)), | ||
335 | MPP_VAR_FUNCTION(0xb, "lcd", "e", V(0, 0, 0, 0, 1, 0))), | ||
336 | MPP_MODE(46, | ||
337 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 0)), | ||
338 | MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 0, 1, 1, 0)), | ||
339 | MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 0, 1, 1, 0)), | ||
340 | MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1, 0))), | ||
341 | MPP_MODE(47, | ||
342 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 0)), | ||
343 | MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 0, 1, 1, 0)), | ||
344 | MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 0, 1, 1, 0)), | ||
345 | MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1, 0))), | ||
346 | MPP_MODE(48, | ||
347 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 0)), | ||
348 | MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 0, 1, 1, 0)), | ||
349 | MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 0, 1, 1, 0)), | ||
350 | MPP_VAR_FUNCTION(0xb, "lcd", "d16", V(0, 0, 0, 0, 1, 0))), | ||
351 | MPP_MODE(49, | ||
352 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0, 1)), | ||
353 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 0, 0, 0, 1, 0)), | ||
354 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 0, 0)), | ||
355 | MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 0, 1, 1, 0)), | ||
356 | MPP_VAR_FUNCTION(0x5, "ptp", "clk", V(0, 0, 0, 1, 0, 0)), | ||
357 | MPP_VAR_FUNCTION(0xa, "pex", "clkreq", V(0, 0, 0, 0, 1, 0)), | ||
358 | MPP_VAR_FUNCTION(0xb, "lcd", "d17", V(0, 0, 0, 0, 1, 0))), | ||
359 | }; | ||
360 | |||
361 | static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = { | ||
362 | MPP_REG_CTRL(0, 29), | ||
363 | }; | ||
364 | |||
365 | static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = { | ||
366 | MPP_GPIO_RANGE(0, 0, 0, 30), | ||
367 | }; | ||
368 | |||
369 | static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = { | ||
370 | MPP_REG_CTRL(0, 35), | ||
371 | }; | ||
372 | |||
373 | static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = { | ||
374 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
375 | MPP_GPIO_RANGE(1, 32, 32, 4), | ||
376 | }; | ||
377 | |||
378 | static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = { | ||
379 | MPP_REG_CTRL(0, 49), | ||
380 | }; | ||
381 | |||
382 | static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = { | ||
383 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
384 | MPP_GPIO_RANGE(1, 32, 32, 18), | ||
385 | }; | ||
386 | |||
387 | static struct mvebu_pinctrl_soc_info mv88f6180_info = { | ||
388 | .variant = VARIANT_MV88F6180, | ||
389 | .controls = mv88f6180_mpp_controls, | ||
390 | .ncontrols = ARRAY_SIZE(mv88f6180_mpp_controls), | ||
391 | .modes = mv88f6xxx_mpp_modes, | ||
392 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
393 | .gpioranges = mv88f6180_gpio_ranges, | ||
394 | .ngpioranges = ARRAY_SIZE(mv88f6180_gpio_ranges), | ||
395 | }; | ||
396 | |||
397 | static struct mvebu_pinctrl_soc_info mv88f6190_info = { | ||
398 | .variant = VARIANT_MV88F6190, | ||
399 | .controls = mv88f619x_mpp_controls, | ||
400 | .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), | ||
401 | .modes = mv88f6xxx_mpp_modes, | ||
402 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
403 | .gpioranges = mv88f619x_gpio_ranges, | ||
404 | .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), | ||
405 | }; | ||
406 | |||
407 | static struct mvebu_pinctrl_soc_info mv88f6192_info = { | ||
408 | .variant = VARIANT_MV88F6192, | ||
409 | .controls = mv88f619x_mpp_controls, | ||
410 | .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), | ||
411 | .modes = mv88f6xxx_mpp_modes, | ||
412 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
413 | .gpioranges = mv88f619x_gpio_ranges, | ||
414 | .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), | ||
415 | }; | ||
416 | |||
417 | static struct mvebu_pinctrl_soc_info mv88f6281_info = { | ||
418 | .variant = VARIANT_MV88F6281, | ||
419 | .controls = mv88f628x_mpp_controls, | ||
420 | .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), | ||
421 | .modes = mv88f6xxx_mpp_modes, | ||
422 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
423 | .gpioranges = mv88f628x_gpio_ranges, | ||
424 | .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), | ||
425 | }; | ||
426 | |||
427 | static struct mvebu_pinctrl_soc_info mv88f6282_info = { | ||
428 | .variant = VARIANT_MV88F6282, | ||
429 | .controls = mv88f628x_mpp_controls, | ||
430 | .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), | ||
431 | .modes = mv88f6xxx_mpp_modes, | ||
432 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
433 | .gpioranges = mv88f628x_gpio_ranges, | ||
434 | .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), | ||
435 | }; | ||
436 | |||
437 | static struct mvebu_pinctrl_soc_info mv98dx4122_info = { | ||
438 | .variant = VARIANT_MV98DX4122, | ||
439 | .controls = mv88f628x_mpp_controls, | ||
440 | .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), | ||
441 | .modes = mv88f6xxx_mpp_modes, | ||
442 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
443 | .gpioranges = mv88f628x_gpio_ranges, | ||
444 | .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), | ||
445 | }; | ||
446 | |||
447 | static struct of_device_id kirkwood_pinctrl_of_match[] __devinitdata = { | ||
448 | { .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info }, | ||
449 | { .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info }, | ||
450 | { .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info }, | ||
451 | { .compatible = "marvell,88f6281-pinctrl", .data = &mv88f6281_info }, | ||
452 | { .compatible = "marvell,88f6282-pinctrl", .data = &mv88f6282_info }, | ||
453 | { .compatible = "marvell,98dx4122-pinctrl", .data = &mv98dx4122_info }, | ||
454 | { } | ||
455 | }; | ||
456 | |||
457 | static int __devinit kirkwood_pinctrl_probe(struct platform_device *pdev) | ||
458 | { | ||
459 | const struct of_device_id *match = | ||
460 | of_match_device(kirkwood_pinctrl_of_match, &pdev->dev); | ||
461 | pdev->dev.platform_data = match->data; | ||
462 | return mvebu_pinctrl_probe(pdev); | ||
463 | } | ||
464 | |||
465 | static int __devexit kirkwood_pinctrl_remove(struct platform_device *pdev) | ||
466 | { | ||
467 | return mvebu_pinctrl_remove(pdev); | ||
468 | } | ||
469 | |||
470 | static struct platform_driver kirkwood_pinctrl_driver = { | ||
471 | .driver = { | ||
472 | .name = "kirkwood-pinctrl", | ||
473 | .owner = THIS_MODULE, | ||
474 | .of_match_table = of_match_ptr(kirkwood_pinctrl_of_match), | ||
475 | }, | ||
476 | .probe = kirkwood_pinctrl_probe, | ||
477 | .remove = __devexit_p(kirkwood_pinctrl_remove), | ||
478 | }; | ||
479 | |||
480 | module_platform_driver(kirkwood_pinctrl_driver); | ||
481 | |||
482 | MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>"); | ||
483 | MODULE_DESCRIPTION("Marvell Kirkwood pinctrl driver"); | ||
484 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c index 8e6266c6249a..6c44b7e8964c 100644 --- a/drivers/pinctrl/pinctrl-mvebu.c +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/pinctrl/pinctrl.h> | 24 | #include <linux/pinctrl/pinctrl.h> |
25 | #include <linux/pinctrl/pinmux.h> | 25 | #include <linux/pinctrl/pinmux.h> |
26 | 26 | ||
27 | #include "core.h" | ||
28 | #include "pinctrl-mvebu.h" | 27 | #include "pinctrl-mvebu.h" |
29 | 28 | ||
30 | #define MPPS_PER_REG 8 | 29 | #define MPPS_PER_REG 8 |
diff --git a/drivers/pinctrl/pinctrl-mvebu.h b/drivers/pinctrl/mvebu/pinctrl-mvebu.h index 90bd3beee860..90bd3beee860 100644 --- a/drivers/pinctrl/pinctrl-mvebu.h +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.h | |||
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 33fbaeaa65dd..833a36458157 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c | |||
@@ -41,6 +41,7 @@ struct pin_config_item conf_items[] = { | |||
41 | PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL), | 41 | PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL), |
42 | PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL), | 42 | PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL), |
43 | PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL), | 43 | PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL), |
44 | PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_DISABLE, "input schmitt disabled", NULL), | ||
44 | PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL), | 45 | PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL), |
45 | PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"), | 46 | PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"), |
46 | PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"), | 47 | PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"), |
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c new file mode 100644 index 000000000000..c5e757157183 --- /dev/null +++ b/drivers/pinctrl/pinctrl-at91.c | |||
@@ -0,0 +1,1634 @@ | |||
1 | /* | ||
2 | * at91 pinctrl driver based on at91 pinmux core | ||
3 | * | ||
4 | * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | ||
5 | * | ||
6 | * Under GPLv2 only | ||
7 | */ | ||
8 | |||
9 | #include <linux/clk.h> | ||
10 | #include <linux/err.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/of.h> | ||
14 | #include <linux/of_device.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/irqdomain.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/pinctrl/machine.h> | ||
24 | #include <linux/pinctrl/pinconf.h> | ||
25 | #include <linux/pinctrl/pinctrl.h> | ||
26 | #include <linux/pinctrl/pinmux.h> | ||
27 | /* Since we request GPIOs from ourself */ | ||
28 | #include <linux/pinctrl/consumer.h> | ||
29 | |||
30 | #include <asm/mach/irq.h> | ||
31 | |||
32 | #include <mach/hardware.h> | ||
33 | #include <mach/at91_pio.h> | ||
34 | |||
35 | #include "core.h" | ||
36 | |||
37 | #define MAX_NB_GPIO_PER_BANK 32 | ||
38 | |||
39 | struct at91_pinctrl_mux_ops; | ||
40 | |||
41 | struct at91_gpio_chip { | ||
42 | struct gpio_chip chip; | ||
43 | struct pinctrl_gpio_range range; | ||
44 | struct at91_gpio_chip *next; /* Bank sharing same clock */ | ||
45 | int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ | ||
46 | int pioc_virq; /* PIO bank Linux virtual interrupt */ | ||
47 | int pioc_idx; /* PIO bank index */ | ||
48 | void __iomem *regbase; /* PIO bank virtual address */ | ||
49 | struct clk *clock; /* associated clock */ | ||
50 | struct irq_domain *domain; /* associated irq domain */ | ||
51 | struct at91_pinctrl_mux_ops *ops; /* ops */ | ||
52 | }; | ||
53 | |||
54 | #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) | ||
55 | |||
56 | static struct at91_gpio_chip *gpio_chips[MAX_GPIO_BANKS]; | ||
57 | |||
58 | static int gpio_banks; | ||
59 | |||
60 | #define PULL_UP (1 << 0) | ||
61 | #define MULTI_DRIVE (1 << 1) | ||
62 | #define DEGLITCH (1 << 2) | ||
63 | #define PULL_DOWN (1 << 3) | ||
64 | #define DIS_SCHMIT (1 << 4) | ||
65 | #define DEBOUNCE (1 << 16) | ||
66 | #define DEBOUNCE_VAL_SHIFT 17 | ||
67 | #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) | ||
68 | |||
69 | /** | ||
70 | * struct at91_pmx_func - describes AT91 pinmux functions | ||
71 | * @name: the name of this specific function | ||
72 | * @groups: corresponding pin groups | ||
73 | * @ngroups: the number of groups | ||
74 | */ | ||
75 | struct at91_pmx_func { | ||
76 | const char *name; | ||
77 | const char **groups; | ||
78 | unsigned ngroups; | ||
79 | }; | ||
80 | |||
81 | enum at91_mux { | ||
82 | AT91_MUX_GPIO = 0, | ||
83 | AT91_MUX_PERIPH_A = 1, | ||
84 | AT91_MUX_PERIPH_B = 2, | ||
85 | AT91_MUX_PERIPH_C = 3, | ||
86 | AT91_MUX_PERIPH_D = 4, | ||
87 | }; | ||
88 | |||
89 | /** | ||
90 | * struct at91_pmx_pin - describes an At91 pin mux | ||
91 | * @bank: the bank of the pin | ||
92 | * @pin: the pin number in the @bank | ||
93 | * @mux: the mux mode : gpio or periph_x of the pin i.e. alternate function. | ||
94 | * @conf: the configuration of the pin: PULL_UP, MULTIDRIVE etc... | ||
95 | */ | ||
96 | struct at91_pmx_pin { | ||
97 | uint32_t bank; | ||
98 | uint32_t pin; | ||
99 | enum at91_mux mux; | ||
100 | unsigned long conf; | ||
101 | }; | ||
102 | |||
103 | /** | ||
104 | * struct at91_pin_group - describes an At91 pin group | ||
105 | * @name: the name of this specific pin group | ||
106 | * @pins_conf: the mux mode for each pin in this group. The size of this | ||
107 | * array is the same as pins. | ||
108 | * @pins: an array of discrete physical pins used in this group, taken | ||
109 | * from the driver-local pin enumeration space | ||
110 | * @npins: the number of pins in this group array, i.e. the number of | ||
111 | * elements in .pins so we can iterate over that array | ||
112 | */ | ||
113 | struct at91_pin_group { | ||
114 | const char *name; | ||
115 | struct at91_pmx_pin *pins_conf; | ||
116 | unsigned int *pins; | ||
117 | unsigned npins; | ||
118 | }; | ||
119 | |||
120 | /** | ||
121 | * struct at91_pinctrl_mux_ops - describes an At91 mux ops group | ||
122 | * on new IP with support for periph C and D the way to mux in | ||
123 | * periph A and B has changed | ||
124 | * So provide the right call back | ||
125 | * if not present means the IP does not support it | ||
126 | * @get_periph: return the periph mode configured | ||
127 | * @mux_A_periph: mux as periph A | ||
128 | * @mux_B_periph: mux as periph B | ||
129 | * @mux_C_periph: mux as periph C | ||
130 | * @mux_D_periph: mux as periph D | ||
131 | * @get_deglitch: get deglitch status | ||
132 | * @set_deglitch: enable/disable deglitch | ||
133 | * @get_debounce: get debounce status | ||
134 | * @set_debounce: enable/disable debounce | ||
135 | * @get_pulldown: get pulldown status | ||
136 | * @set_pulldown: enable/disable pulldown | ||
137 | * @get_schmitt_trig: get schmitt trigger status | ||
138 | * @disable_schmitt_trig: disable schmitt trigger | ||
139 | * @irq_type: return irq type | ||
140 | */ | ||
141 | struct at91_pinctrl_mux_ops { | ||
142 | enum at91_mux (*get_periph)(void __iomem *pio, unsigned mask); | ||
143 | void (*mux_A_periph)(void __iomem *pio, unsigned mask); | ||
144 | void (*mux_B_periph)(void __iomem *pio, unsigned mask); | ||
145 | void (*mux_C_periph)(void __iomem *pio, unsigned mask); | ||
146 | void (*mux_D_periph)(void __iomem *pio, unsigned mask); | ||
147 | bool (*get_deglitch)(void __iomem *pio, unsigned pin); | ||
148 | void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on); | ||
149 | bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div); | ||
150 | void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 div); | ||
151 | bool (*get_pulldown)(void __iomem *pio, unsigned pin); | ||
152 | void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on); | ||
153 | bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin); | ||
154 | void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask); | ||
155 | /* irq */ | ||
156 | int (*irq_type)(struct irq_data *d, unsigned type); | ||
157 | }; | ||
158 | |||
159 | static int gpio_irq_type(struct irq_data *d, unsigned type); | ||
160 | static int alt_gpio_irq_type(struct irq_data *d, unsigned type); | ||
161 | |||
162 | struct at91_pinctrl { | ||
163 | struct device *dev; | ||
164 | struct pinctrl_dev *pctl; | ||
165 | |||
166 | int nbanks; | ||
167 | |||
168 | uint32_t *mux_mask; | ||
169 | int nmux; | ||
170 | |||
171 | struct at91_pmx_func *functions; | ||
172 | int nfunctions; | ||
173 | |||
174 | struct at91_pin_group *groups; | ||
175 | int ngroups; | ||
176 | |||
177 | struct at91_pinctrl_mux_ops *ops; | ||
178 | }; | ||
179 | |||
180 | static const inline struct at91_pin_group *at91_pinctrl_find_group_by_name( | ||
181 | const struct at91_pinctrl *info, | ||
182 | const char *name) | ||
183 | { | ||
184 | const struct at91_pin_group *grp = NULL; | ||
185 | int i; | ||
186 | |||
187 | for (i = 0; i < info->ngroups; i++) { | ||
188 | if (strcmp(info->groups[i].name, name)) | ||
189 | continue; | ||
190 | |||
191 | grp = &info->groups[i]; | ||
192 | dev_dbg(info->dev, "%s: %d 0:%d\n", name, grp->npins, grp->pins[0]); | ||
193 | break; | ||
194 | } | ||
195 | |||
196 | return grp; | ||
197 | } | ||
198 | |||
199 | static int at91_get_groups_count(struct pinctrl_dev *pctldev) | ||
200 | { | ||
201 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
202 | |||
203 | return info->ngroups; | ||
204 | } | ||
205 | |||
206 | static const char *at91_get_group_name(struct pinctrl_dev *pctldev, | ||
207 | unsigned selector) | ||
208 | { | ||
209 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
210 | |||
211 | return info->groups[selector].name; | ||
212 | } | ||
213 | |||
214 | static int at91_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, | ||
215 | const unsigned **pins, | ||
216 | unsigned *npins) | ||
217 | { | ||
218 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
219 | |||
220 | if (selector >= info->ngroups) | ||
221 | return -EINVAL; | ||
222 | |||
223 | *pins = info->groups[selector].pins; | ||
224 | *npins = info->groups[selector].npins; | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static void at91_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, | ||
230 | unsigned offset) | ||
231 | { | ||
232 | seq_printf(s, "%s", dev_name(pctldev->dev)); | ||
233 | } | ||
234 | |||
235 | static int at91_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
236 | struct device_node *np, | ||
237 | struct pinctrl_map **map, unsigned *num_maps) | ||
238 | { | ||
239 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
240 | const struct at91_pin_group *grp; | ||
241 | struct pinctrl_map *new_map; | ||
242 | struct device_node *parent; | ||
243 | int map_num = 1; | ||
244 | int i; | ||
245 | |||
246 | /* | ||
247 | * first find the group of this node and check if we need create | ||
248 | * config maps for pins | ||
249 | */ | ||
250 | grp = at91_pinctrl_find_group_by_name(info, np->name); | ||
251 | if (!grp) { | ||
252 | dev_err(info->dev, "unable to find group for node %s\n", | ||
253 | np->name); | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | |||
257 | map_num += grp->npins; | ||
258 | new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, GFP_KERNEL); | ||
259 | if (!new_map) | ||
260 | return -ENOMEM; | ||
261 | |||
262 | *map = new_map; | ||
263 | *num_maps = map_num; | ||
264 | |||
265 | /* create mux map */ | ||
266 | parent = of_get_parent(np); | ||
267 | if (!parent) { | ||
268 | kfree(new_map); | ||
269 | return -EINVAL; | ||
270 | } | ||
271 | new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; | ||
272 | new_map[0].data.mux.function = parent->name; | ||
273 | new_map[0].data.mux.group = np->name; | ||
274 | of_node_put(parent); | ||
275 | |||
276 | /* create config map */ | ||
277 | new_map++; | ||
278 | for (i = 0; i < grp->npins; i++) { | ||
279 | new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; | ||
280 | new_map[i].data.configs.group_or_pin = | ||
281 | pin_get_name(pctldev, grp->pins[i]); | ||
282 | new_map[i].data.configs.configs = &grp->pins_conf[i].conf; | ||
283 | new_map[i].data.configs.num_configs = 1; | ||
284 | } | ||
285 | |||
286 | dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", | ||
287 | (*map)->data.mux.function, (*map)->data.mux.group, map_num); | ||
288 | |||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static void at91_dt_free_map(struct pinctrl_dev *pctldev, | ||
293 | struct pinctrl_map *map, unsigned num_maps) | ||
294 | { | ||
295 | } | ||
296 | |||
297 | static struct pinctrl_ops at91_pctrl_ops = { | ||
298 | .get_groups_count = at91_get_groups_count, | ||
299 | .get_group_name = at91_get_group_name, | ||
300 | .get_group_pins = at91_get_group_pins, | ||
301 | .pin_dbg_show = at91_pin_dbg_show, | ||
302 | .dt_node_to_map = at91_dt_node_to_map, | ||
303 | .dt_free_map = at91_dt_free_map, | ||
304 | }; | ||
305 | |||
306 | static void __iomem * pin_to_controller(struct at91_pinctrl *info, | ||
307 | unsigned int bank) | ||
308 | { | ||
309 | return gpio_chips[bank]->regbase; | ||
310 | } | ||
311 | |||
312 | static inline int pin_to_bank(unsigned pin) | ||
313 | { | ||
314 | return pin /= MAX_NB_GPIO_PER_BANK; | ||
315 | } | ||
316 | |||
317 | static unsigned pin_to_mask(unsigned int pin) | ||
318 | { | ||
319 | return 1 << pin; | ||
320 | } | ||
321 | |||
322 | static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask) | ||
323 | { | ||
324 | writel_relaxed(mask, pio + PIO_IDR); | ||
325 | } | ||
326 | |||
327 | static unsigned at91_mux_get_pullup(void __iomem *pio, unsigned pin) | ||
328 | { | ||
329 | return (readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1; | ||
330 | } | ||
331 | |||
332 | static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on) | ||
333 | { | ||
334 | writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR)); | ||
335 | } | ||
336 | |||
337 | static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin) | ||
338 | { | ||
339 | return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1; | ||
340 | } | ||
341 | |||
342 | static void at91_mux_set_multidrive(void __iomem *pio, unsigned mask, bool on) | ||
343 | { | ||
344 | writel_relaxed(mask, pio + (on ? PIO_MDER : PIO_MDDR)); | ||
345 | } | ||
346 | |||
347 | static void at91_mux_set_A_periph(void __iomem *pio, unsigned mask) | ||
348 | { | ||
349 | writel_relaxed(mask, pio + PIO_ASR); | ||
350 | } | ||
351 | |||
352 | static void at91_mux_set_B_periph(void __iomem *pio, unsigned mask) | ||
353 | { | ||
354 | writel_relaxed(mask, pio + PIO_BSR); | ||
355 | } | ||
356 | |||
357 | static void at91_mux_pio3_set_A_periph(void __iomem *pio, unsigned mask) | ||
358 | { | ||
359 | |||
360 | writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) & ~mask, | ||
361 | pio + PIO_ABCDSR1); | ||
362 | writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) & ~mask, | ||
363 | pio + PIO_ABCDSR2); | ||
364 | } | ||
365 | |||
366 | static void at91_mux_pio3_set_B_periph(void __iomem *pio, unsigned mask) | ||
367 | { | ||
368 | writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) | mask, | ||
369 | pio + PIO_ABCDSR1); | ||
370 | writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) & ~mask, | ||
371 | pio + PIO_ABCDSR2); | ||
372 | } | ||
373 | |||
374 | static void at91_mux_pio3_set_C_periph(void __iomem *pio, unsigned mask) | ||
375 | { | ||
376 | writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); | ||
377 | writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); | ||
378 | } | ||
379 | |||
380 | static void at91_mux_pio3_set_D_periph(void __iomem *pio, unsigned mask) | ||
381 | { | ||
382 | writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); | ||
383 | writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); | ||
384 | } | ||
385 | |||
386 | static enum at91_mux at91_mux_pio3_get_periph(void __iomem *pio, unsigned mask) | ||
387 | { | ||
388 | unsigned select; | ||
389 | |||
390 | if (readl_relaxed(pio + PIO_PSR) & mask) | ||
391 | return AT91_MUX_GPIO; | ||
392 | |||
393 | select = !!(readl_relaxed(pio + PIO_ABCDSR1) & mask); | ||
394 | select |= (!!(readl_relaxed(pio + PIO_ABCDSR2) & mask) << 1); | ||
395 | |||
396 | return select + 1; | ||
397 | } | ||
398 | |||
399 | static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask) | ||
400 | { | ||
401 | unsigned select; | ||
402 | |||
403 | if (readl_relaxed(pio + PIO_PSR) & mask) | ||
404 | return AT91_MUX_GPIO; | ||
405 | |||
406 | select = readl_relaxed(pio + PIO_ABSR) & mask; | ||
407 | |||
408 | return select + 1; | ||
409 | } | ||
410 | |||
411 | static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin) | ||
412 | { | ||
413 | return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1; | ||
414 | } | ||
415 | |||
416 | static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) | ||
417 | { | ||
418 | __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); | ||
419 | } | ||
420 | |||
421 | static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) | ||
422 | { | ||
423 | if (is_on) | ||
424 | __raw_writel(mask, pio + PIO_IFSCDR); | ||
425 | at91_mux_set_deglitch(pio, mask, is_on); | ||
426 | } | ||
427 | |||
428 | static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div) | ||
429 | { | ||
430 | *div = __raw_readl(pio + PIO_SCDR); | ||
431 | |||
432 | return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1; | ||
433 | } | ||
434 | |||
435 | static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask, | ||
436 | bool is_on, u32 div) | ||
437 | { | ||
438 | if (is_on) { | ||
439 | __raw_writel(mask, pio + PIO_IFSCER); | ||
440 | __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); | ||
441 | __raw_writel(mask, pio + PIO_IFER); | ||
442 | } else { | ||
443 | __raw_writel(mask, pio + PIO_IFDR); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin) | ||
448 | { | ||
449 | return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1; | ||
450 | } | ||
451 | |||
452 | static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) | ||
453 | { | ||
454 | __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); | ||
455 | } | ||
456 | |||
457 | static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask) | ||
458 | { | ||
459 | __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); | ||
460 | } | ||
461 | |||
462 | static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin) | ||
463 | { | ||
464 | return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1; | ||
465 | } | ||
466 | |||
467 | static struct at91_pinctrl_mux_ops at91rm9200_ops = { | ||
468 | .get_periph = at91_mux_get_periph, | ||
469 | .mux_A_periph = at91_mux_set_A_periph, | ||
470 | .mux_B_periph = at91_mux_set_B_periph, | ||
471 | .get_deglitch = at91_mux_get_deglitch, | ||
472 | .set_deglitch = at91_mux_set_deglitch, | ||
473 | .irq_type = gpio_irq_type, | ||
474 | }; | ||
475 | |||
476 | static struct at91_pinctrl_mux_ops at91sam9x5_ops = { | ||
477 | .get_periph = at91_mux_pio3_get_periph, | ||
478 | .mux_A_periph = at91_mux_pio3_set_A_periph, | ||
479 | .mux_B_periph = at91_mux_pio3_set_B_periph, | ||
480 | .mux_C_periph = at91_mux_pio3_set_C_periph, | ||
481 | .mux_D_periph = at91_mux_pio3_set_D_periph, | ||
482 | .get_deglitch = at91_mux_get_deglitch, | ||
483 | .set_deglitch = at91_mux_pio3_set_deglitch, | ||
484 | .get_debounce = at91_mux_pio3_get_debounce, | ||
485 | .set_debounce = at91_mux_pio3_set_debounce, | ||
486 | .get_pulldown = at91_mux_pio3_get_pulldown, | ||
487 | .set_pulldown = at91_mux_pio3_set_pulldown, | ||
488 | .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, | ||
489 | .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, | ||
490 | .irq_type = alt_gpio_irq_type, | ||
491 | }; | ||
492 | |||
493 | static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin) | ||
494 | { | ||
495 | if (pin->mux) { | ||
496 | dev_dbg(dev, "pio%c%d configured as periph%c with conf = 0x%lu\n", | ||
497 | pin->bank + 'A', pin->pin, pin->mux - 1 + 'A', pin->conf); | ||
498 | } else { | ||
499 | dev_dbg(dev, "pio%c%d configured as gpio with conf = 0x%lu\n", | ||
500 | pin->bank + 'A', pin->pin, pin->conf); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | static int pin_check_config(struct at91_pinctrl *info, const char* name, | ||
505 | int index, const struct at91_pmx_pin *pin) | ||
506 | { | ||
507 | int mux; | ||
508 | |||
509 | /* check if it's a valid config */ | ||
510 | if (pin->bank >= info->nbanks) { | ||
511 | dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n", | ||
512 | name, index, pin->bank, info->nbanks); | ||
513 | return -EINVAL; | ||
514 | } | ||
515 | |||
516 | if (pin->pin >= MAX_NB_GPIO_PER_BANK) { | ||
517 | dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n", | ||
518 | name, index, pin->pin, MAX_NB_GPIO_PER_BANK); | ||
519 | return -EINVAL; | ||
520 | } | ||
521 | |||
522 | if (!pin->mux) | ||
523 | return 0; | ||
524 | |||
525 | mux = pin->mux - 1; | ||
526 | |||
527 | if (mux >= info->nmux) { | ||
528 | dev_err(info->dev, "%s: pin conf %d mux_id %d >= nmux %d\n", | ||
529 | name, index, mux, info->nmux); | ||
530 | return -EINVAL; | ||
531 | } | ||
532 | |||
533 | if (!(info->mux_mask[pin->bank * info->nmux + mux] & 1 << pin->pin)) { | ||
534 | dev_err(info->dev, "%s: pin conf %d mux_id %d not supported for pio%c%d\n", | ||
535 | name, index, mux, pin->bank + 'A', pin->pin); | ||
536 | return -EINVAL; | ||
537 | } | ||
538 | |||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | static void at91_mux_gpio_disable(void __iomem *pio, unsigned mask) | ||
543 | { | ||
544 | writel_relaxed(mask, pio + PIO_PDR); | ||
545 | } | ||
546 | |||
547 | static void at91_mux_gpio_enable(void __iomem *pio, unsigned mask, bool input) | ||
548 | { | ||
549 | writel_relaxed(mask, pio + PIO_PER); | ||
550 | writel_relaxed(mask, pio + (input ? PIO_ODR : PIO_OER)); | ||
551 | } | ||
552 | |||
553 | static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, | ||
554 | unsigned group) | ||
555 | { | ||
556 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
557 | const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf; | ||
558 | const struct at91_pmx_pin *pin; | ||
559 | uint32_t npins = info->groups[group].npins; | ||
560 | int i, ret; | ||
561 | unsigned mask; | ||
562 | void __iomem *pio; | ||
563 | |||
564 | dev_dbg(info->dev, "enable function %s group %s\n", | ||
565 | info->functions[selector].name, info->groups[group].name); | ||
566 | |||
567 | /* first check that all the pins of the group are valid with a valid | ||
568 | * paramter */ | ||
569 | for (i = 0; i < npins; i++) { | ||
570 | pin = &pins_conf[i]; | ||
571 | ret = pin_check_config(info, info->groups[group].name, i, pin); | ||
572 | if (ret) | ||
573 | return ret; | ||
574 | } | ||
575 | |||
576 | for (i = 0; i < npins; i++) { | ||
577 | pin = &pins_conf[i]; | ||
578 | at91_pin_dbg(info->dev, pin); | ||
579 | pio = pin_to_controller(info, pin->bank); | ||
580 | mask = pin_to_mask(pin->pin); | ||
581 | at91_mux_disable_interrupt(pio, mask); | ||
582 | switch(pin->mux) { | ||
583 | case AT91_MUX_GPIO: | ||
584 | at91_mux_gpio_enable(pio, mask, 1); | ||
585 | break; | ||
586 | case AT91_MUX_PERIPH_A: | ||
587 | info->ops->mux_A_periph(pio, mask); | ||
588 | break; | ||
589 | case AT91_MUX_PERIPH_B: | ||
590 | info->ops->mux_B_periph(pio, mask); | ||
591 | break; | ||
592 | case AT91_MUX_PERIPH_C: | ||
593 | if (!info->ops->mux_C_periph) | ||
594 | return -EINVAL; | ||
595 | info->ops->mux_C_periph(pio, mask); | ||
596 | break; | ||
597 | case AT91_MUX_PERIPH_D: | ||
598 | if (!info->ops->mux_D_periph) | ||
599 | return -EINVAL; | ||
600 | info->ops->mux_D_periph(pio, mask); | ||
601 | break; | ||
602 | } | ||
603 | if (pin->mux) | ||
604 | at91_mux_gpio_disable(pio, mask); | ||
605 | } | ||
606 | |||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, | ||
611 | unsigned group) | ||
612 | { | ||
613 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
614 | const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf; | ||
615 | const struct at91_pmx_pin *pin; | ||
616 | uint32_t npins = info->groups[group].npins; | ||
617 | int i; | ||
618 | unsigned mask; | ||
619 | void __iomem *pio; | ||
620 | |||
621 | for (i = 0; i < npins; i++) { | ||
622 | pin = &pins_conf[i]; | ||
623 | at91_pin_dbg(info->dev, pin); | ||
624 | pio = pin_to_controller(info, pin->bank); | ||
625 | mask = pin_to_mask(pin->pin); | ||
626 | at91_mux_gpio_enable(pio, mask, 1); | ||
627 | } | ||
628 | } | ||
629 | |||
630 | static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev) | ||
631 | { | ||
632 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
633 | |||
634 | return info->nfunctions; | ||
635 | } | ||
636 | |||
637 | static const char *at91_pmx_get_func_name(struct pinctrl_dev *pctldev, | ||
638 | unsigned selector) | ||
639 | { | ||
640 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
641 | |||
642 | return info->functions[selector].name; | ||
643 | } | ||
644 | |||
645 | static int at91_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, | ||
646 | const char * const **groups, | ||
647 | unsigned * const num_groups) | ||
648 | { | ||
649 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
650 | |||
651 | *groups = info->functions[selector].groups; | ||
652 | *num_groups = info->functions[selector].ngroups; | ||
653 | |||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | static int at91_gpio_request_enable(struct pinctrl_dev *pctldev, | ||
658 | struct pinctrl_gpio_range *range, | ||
659 | unsigned offset) | ||
660 | { | ||
661 | struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); | ||
662 | struct at91_gpio_chip *at91_chip; | ||
663 | struct gpio_chip *chip; | ||
664 | unsigned mask; | ||
665 | |||
666 | if (!range) { | ||
667 | dev_err(npct->dev, "invalid range\n"); | ||
668 | return -EINVAL; | ||
669 | } | ||
670 | if (!range->gc) { | ||
671 | dev_err(npct->dev, "missing GPIO chip in range\n"); | ||
672 | return -EINVAL; | ||
673 | } | ||
674 | chip = range->gc; | ||
675 | at91_chip = container_of(chip, struct at91_gpio_chip, chip); | ||
676 | |||
677 | dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset); | ||
678 | |||
679 | mask = 1 << (offset - chip->base); | ||
680 | |||
681 | dev_dbg(npct->dev, "enable pin %u as PIO%c%d 0x%x\n", | ||
682 | offset, 'A' + range->id, offset - chip->base, mask); | ||
683 | |||
684 | writel_relaxed(mask, at91_chip->regbase + PIO_PER); | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static void at91_gpio_disable_free(struct pinctrl_dev *pctldev, | ||
690 | struct pinctrl_gpio_range *range, | ||
691 | unsigned offset) | ||
692 | { | ||
693 | struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); | ||
694 | |||
695 | dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset); | ||
696 | /* Set the pin to some default state, GPIO is usually default */ | ||
697 | } | ||
698 | |||
699 | static struct pinmux_ops at91_pmx_ops = { | ||
700 | .get_functions_count = at91_pmx_get_funcs_count, | ||
701 | .get_function_name = at91_pmx_get_func_name, | ||
702 | .get_function_groups = at91_pmx_get_groups, | ||
703 | .enable = at91_pmx_enable, | ||
704 | .disable = at91_pmx_disable, | ||
705 | .gpio_request_enable = at91_gpio_request_enable, | ||
706 | .gpio_disable_free = at91_gpio_disable_free, | ||
707 | }; | ||
708 | |||
709 | static int at91_pinconf_get(struct pinctrl_dev *pctldev, | ||
710 | unsigned pin_id, unsigned long *config) | ||
711 | { | ||
712 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
713 | void __iomem *pio; | ||
714 | unsigned pin; | ||
715 | int div; | ||
716 | |||
717 | dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config); | ||
718 | pio = pin_to_controller(info, pin_to_bank(pin_id)); | ||
719 | pin = pin_id % MAX_NB_GPIO_PER_BANK; | ||
720 | |||
721 | if (at91_mux_get_multidrive(pio, pin)) | ||
722 | *config |= MULTI_DRIVE; | ||
723 | |||
724 | if (at91_mux_get_pullup(pio, pin)) | ||
725 | *config |= PULL_UP; | ||
726 | |||
727 | if (info->ops->get_deglitch && info->ops->get_deglitch(pio, pin)) | ||
728 | *config |= DEGLITCH; | ||
729 | if (info->ops->get_debounce && info->ops->get_debounce(pio, pin, &div)) | ||
730 | *config |= DEBOUNCE | (div << DEBOUNCE_VAL_SHIFT); | ||
731 | if (info->ops->get_pulldown && info->ops->get_pulldown(pio, pin)) | ||
732 | *config |= PULL_DOWN; | ||
733 | if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin)) | ||
734 | *config |= DIS_SCHMIT; | ||
735 | |||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | static int at91_pinconf_set(struct pinctrl_dev *pctldev, | ||
740 | unsigned pin_id, unsigned long config) | ||
741 | { | ||
742 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
743 | unsigned mask; | ||
744 | void __iomem *pio; | ||
745 | |||
746 | dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, config); | ||
747 | pio = pin_to_controller(info, pin_to_bank(pin_id)); | ||
748 | mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); | ||
749 | |||
750 | if (config & PULL_UP && config & PULL_DOWN) | ||
751 | return -EINVAL; | ||
752 | |||
753 | at91_mux_set_pullup(pio, mask, config & PULL_UP); | ||
754 | at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); | ||
755 | if (info->ops->set_deglitch) | ||
756 | info->ops->set_deglitch(pio, mask, config & DEGLITCH); | ||
757 | if (info->ops->set_debounce) | ||
758 | info->ops->set_debounce(pio, mask, config & DEBOUNCE, | ||
759 | (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT); | ||
760 | if (info->ops->set_pulldown) | ||
761 | info->ops->set_pulldown(pio, mask, config & PULL_DOWN); | ||
762 | if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT) | ||
763 | info->ops->disable_schmitt_trig(pio, mask); | ||
764 | |||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev, | ||
769 | struct seq_file *s, unsigned pin_id) | ||
770 | { | ||
771 | |||
772 | } | ||
773 | |||
774 | static void at91_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, | ||
775 | struct seq_file *s, unsigned group) | ||
776 | { | ||
777 | } | ||
778 | |||
779 | static struct pinconf_ops at91_pinconf_ops = { | ||
780 | .pin_config_get = at91_pinconf_get, | ||
781 | .pin_config_set = at91_pinconf_set, | ||
782 | .pin_config_dbg_show = at91_pinconf_dbg_show, | ||
783 | .pin_config_group_dbg_show = at91_pinconf_group_dbg_show, | ||
784 | }; | ||
785 | |||
786 | static struct pinctrl_desc at91_pinctrl_desc = { | ||
787 | .pctlops = &at91_pctrl_ops, | ||
788 | .pmxops = &at91_pmx_ops, | ||
789 | .confops = &at91_pinconf_ops, | ||
790 | .owner = THIS_MODULE, | ||
791 | }; | ||
792 | |||
793 | static const char *gpio_compat = "atmel,at91rm9200-gpio"; | ||
794 | |||
795 | static void __devinit at91_pinctrl_child_count(struct at91_pinctrl *info, | ||
796 | struct device_node *np) | ||
797 | { | ||
798 | struct device_node *child; | ||
799 | |||
800 | for_each_child_of_node(np, child) { | ||
801 | if (of_device_is_compatible(child, gpio_compat)) { | ||
802 | info->nbanks++; | ||
803 | } else { | ||
804 | info->nfunctions++; | ||
805 | info->ngroups += of_get_child_count(child); | ||
806 | } | ||
807 | } | ||
808 | } | ||
809 | |||
810 | static int __devinit at91_pinctrl_mux_mask(struct at91_pinctrl *info, | ||
811 | struct device_node *np) | ||
812 | { | ||
813 | int ret = 0; | ||
814 | int size; | ||
815 | const const __be32 *list; | ||
816 | |||
817 | list = of_get_property(np, "atmel,mux-mask", &size); | ||
818 | if (!list) { | ||
819 | dev_err(info->dev, "can not read the mux-mask of %d\n", size); | ||
820 | return -EINVAL; | ||
821 | } | ||
822 | |||
823 | size /= sizeof(*list); | ||
824 | if (!size || size % info->nbanks) { | ||
825 | dev_err(info->dev, "wrong mux mask array should be by %d\n", info->nbanks); | ||
826 | return -EINVAL; | ||
827 | } | ||
828 | info->nmux = size / info->nbanks; | ||
829 | |||
830 | info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL); | ||
831 | if (!info->mux_mask) { | ||
832 | dev_err(info->dev, "could not alloc mux_mask\n"); | ||
833 | return -ENOMEM; | ||
834 | } | ||
835 | |||
836 | ret = of_property_read_u32_array(np, "atmel,mux-mask", | ||
837 | info->mux_mask, size); | ||
838 | if (ret) | ||
839 | dev_err(info->dev, "can not read the mux-mask of %d\n", size); | ||
840 | return ret; | ||
841 | } | ||
842 | |||
843 | static int __devinit at91_pinctrl_parse_groups(struct device_node *np, | ||
844 | struct at91_pin_group *grp, | ||
845 | struct at91_pinctrl *info, | ||
846 | u32 index) | ||
847 | { | ||
848 | struct at91_pmx_pin *pin; | ||
849 | int size; | ||
850 | const const __be32 *list; | ||
851 | int i, j; | ||
852 | |||
853 | dev_dbg(info->dev, "group(%d): %s\n", index, np->name); | ||
854 | |||
855 | /* Initialise group */ | ||
856 | grp->name = np->name; | ||
857 | |||
858 | /* | ||
859 | * the binding format is atmel,pins = <bank pin mux CONFIG ...>, | ||
860 | * do sanity check and calculate pins number | ||
861 | */ | ||
862 | list = of_get_property(np, "atmel,pins", &size); | ||
863 | /* we do not check return since it's safe node passed down */ | ||
864 | size /= sizeof(*list); | ||
865 | if (!size || size % 4) { | ||
866 | dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n"); | ||
867 | return -EINVAL; | ||
868 | } | ||
869 | |||
870 | grp->npins = size / 4; | ||
871 | pin = grp->pins_conf = devm_kzalloc(info->dev, grp->npins * sizeof(struct at91_pmx_pin), | ||
872 | GFP_KERNEL); | ||
873 | grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), | ||
874 | GFP_KERNEL); | ||
875 | if (!grp->pins_conf || !grp->pins) | ||
876 | return -ENOMEM; | ||
877 | |||
878 | for (i = 0, j = 0; i < size; i += 4, j++) { | ||
879 | pin->bank = be32_to_cpu(*list++); | ||
880 | pin->pin = be32_to_cpu(*list++); | ||
881 | grp->pins[j] = pin->bank * MAX_NB_GPIO_PER_BANK + pin->pin; | ||
882 | pin->mux = be32_to_cpu(*list++); | ||
883 | pin->conf = be32_to_cpu(*list++); | ||
884 | |||
885 | at91_pin_dbg(info->dev, pin); | ||
886 | pin++; | ||
887 | } | ||
888 | |||
889 | return 0; | ||
890 | } | ||
891 | |||
892 | static int __devinit at91_pinctrl_parse_functions(struct device_node *np, | ||
893 | struct at91_pinctrl *info, u32 index) | ||
894 | { | ||
895 | struct device_node *child; | ||
896 | struct at91_pmx_func *func; | ||
897 | struct at91_pin_group *grp; | ||
898 | int ret; | ||
899 | static u32 grp_index; | ||
900 | u32 i = 0; | ||
901 | |||
902 | dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); | ||
903 | |||
904 | func = &info->functions[index]; | ||
905 | |||
906 | /* Initialise function */ | ||
907 | func->name = np->name; | ||
908 | func->ngroups = of_get_child_count(np); | ||
909 | if (func->ngroups <= 0) { | ||
910 | dev_err(info->dev, "no groups defined\n"); | ||
911 | return -EINVAL; | ||
912 | } | ||
913 | func->groups = devm_kzalloc(info->dev, | ||
914 | func->ngroups * sizeof(char *), GFP_KERNEL); | ||
915 | if (!func->groups) | ||
916 | return -ENOMEM; | ||
917 | |||
918 | for_each_child_of_node(np, child) { | ||
919 | func->groups[i] = child->name; | ||
920 | grp = &info->groups[grp_index++]; | ||
921 | ret = at91_pinctrl_parse_groups(child, grp, info, i++); | ||
922 | if (ret) | ||
923 | return ret; | ||
924 | } | ||
925 | |||
926 | return 0; | ||
927 | } | ||
928 | |||
929 | static struct of_device_id at91_pinctrl_of_match[] __devinitdata = { | ||
930 | { .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops }, | ||
931 | { .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops }, | ||
932 | { /* sentinel */ } | ||
933 | }; | ||
934 | |||
935 | static int __devinit at91_pinctrl_probe_dt(struct platform_device *pdev, | ||
936 | struct at91_pinctrl *info) | ||
937 | { | ||
938 | int ret = 0; | ||
939 | int i, j; | ||
940 | uint32_t *tmp; | ||
941 | struct device_node *np = pdev->dev.of_node; | ||
942 | struct device_node *child; | ||
943 | |||
944 | if (!np) | ||
945 | return -ENODEV; | ||
946 | |||
947 | info->dev = &pdev->dev; | ||
948 | info->ops = (struct at91_pinctrl_mux_ops*) | ||
949 | of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; | ||
950 | at91_pinctrl_child_count(info, np); | ||
951 | |||
952 | if (info->nbanks < 1) { | ||
953 | dev_err(&pdev->dev, "you need to specify atleast one gpio-controller\n"); | ||
954 | return -EINVAL; | ||
955 | } | ||
956 | |||
957 | ret = at91_pinctrl_mux_mask(info, np); | ||
958 | if (ret) | ||
959 | return ret; | ||
960 | |||
961 | dev_dbg(&pdev->dev, "nmux = %d\n", info->nmux); | ||
962 | |||
963 | dev_dbg(&pdev->dev, "mux-mask\n"); | ||
964 | tmp = info->mux_mask; | ||
965 | for (i = 0; i < info->nbanks; i++) { | ||
966 | for (j = 0; j < info->nmux; j++, tmp++) { | ||
967 | dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]); | ||
968 | } | ||
969 | } | ||
970 | |||
971 | dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); | ||
972 | dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); | ||
973 | info->functions = devm_kzalloc(&pdev->dev, info->nfunctions * sizeof(struct at91_pmx_func), | ||
974 | GFP_KERNEL); | ||
975 | if (!info->functions) | ||
976 | return -ENOMEM; | ||
977 | |||
978 | info->groups = devm_kzalloc(&pdev->dev, info->ngroups * sizeof(struct at91_pin_group), | ||
979 | GFP_KERNEL); | ||
980 | if (!info->groups) | ||
981 | return -ENOMEM; | ||
982 | |||
983 | dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks); | ||
984 | dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); | ||
985 | dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); | ||
986 | |||
987 | i = 0; | ||
988 | |||
989 | for_each_child_of_node(np, child) { | ||
990 | if (of_device_is_compatible(child, gpio_compat)) | ||
991 | continue; | ||
992 | ret = at91_pinctrl_parse_functions(child, info, i++); | ||
993 | if (ret) { | ||
994 | dev_err(&pdev->dev, "failed to parse function\n"); | ||
995 | return ret; | ||
996 | } | ||
997 | } | ||
998 | |||
999 | return 0; | ||
1000 | } | ||
1001 | |||
1002 | static int __devinit at91_pinctrl_probe(struct platform_device *pdev) | ||
1003 | { | ||
1004 | struct at91_pinctrl *info; | ||
1005 | struct pinctrl_pin_desc *pdesc; | ||
1006 | int ret, i, j ,k; | ||
1007 | |||
1008 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
1009 | if (!info) | ||
1010 | return -ENOMEM; | ||
1011 | |||
1012 | ret = at91_pinctrl_probe_dt(pdev, info); | ||
1013 | if (ret) | ||
1014 | return ret; | ||
1015 | |||
1016 | /* | ||
1017 | * We need all the GPIO drivers to probe FIRST, or we will not be able | ||
1018 | * to obtain references to the struct gpio_chip * for them, and we | ||
1019 | * need this to proceed. | ||
1020 | */ | ||
1021 | for (i = 0; i < info->nbanks; i++) { | ||
1022 | if (!gpio_chips[i]) { | ||
1023 | dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); | ||
1024 | devm_kfree(&pdev->dev, info); | ||
1025 | return -EPROBE_DEFER; | ||
1026 | } | ||
1027 | } | ||
1028 | |||
1029 | at91_pinctrl_desc.name = dev_name(&pdev->dev); | ||
1030 | at91_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK; | ||
1031 | at91_pinctrl_desc.pins = pdesc = | ||
1032 | devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL); | ||
1033 | |||
1034 | if (!at91_pinctrl_desc.pins) | ||
1035 | return -ENOMEM; | ||
1036 | |||
1037 | for (i = 0 , k = 0; i < info->nbanks; i++) { | ||
1038 | for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) { | ||
1039 | pdesc->number = k; | ||
1040 | pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j); | ||
1041 | pdesc++; | ||
1042 | } | ||
1043 | } | ||
1044 | |||
1045 | platform_set_drvdata(pdev, info); | ||
1046 | info->pctl = pinctrl_register(&at91_pinctrl_desc, &pdev->dev, info); | ||
1047 | |||
1048 | if (!info->pctl) { | ||
1049 | dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n"); | ||
1050 | ret = -EINVAL; | ||
1051 | goto err; | ||
1052 | } | ||
1053 | |||
1054 | /* We will handle a range of GPIO pins */ | ||
1055 | for (i = 0; i < info->nbanks; i++) | ||
1056 | pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); | ||
1057 | |||
1058 | dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); | ||
1059 | |||
1060 | return 0; | ||
1061 | |||
1062 | err: | ||
1063 | return ret; | ||
1064 | } | ||
1065 | |||
1066 | static int __devexit at91_pinctrl_remove(struct platform_device *pdev) | ||
1067 | { | ||
1068 | struct at91_pinctrl *info = platform_get_drvdata(pdev); | ||
1069 | |||
1070 | pinctrl_unregister(info->pctl); | ||
1071 | |||
1072 | return 0; | ||
1073 | } | ||
1074 | |||
1075 | static int at91_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
1076 | { | ||
1077 | /* | ||
1078 | * Map back to global GPIO space and request muxing, the direction | ||
1079 | * parameter does not matter for this controller. | ||
1080 | */ | ||
1081 | int gpio = chip->base + offset; | ||
1082 | int bank = chip->base / chip->ngpio; | ||
1083 | |||
1084 | dev_dbg(chip->dev, "%s:%d pio%c%d(%d)\n", __func__, __LINE__, | ||
1085 | 'A' + bank, offset, gpio); | ||
1086 | |||
1087 | return pinctrl_request_gpio(gpio); | ||
1088 | } | ||
1089 | |||
1090 | static void at91_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
1091 | { | ||
1092 | int gpio = chip->base + offset; | ||
1093 | |||
1094 | pinctrl_free_gpio(gpio); | ||
1095 | } | ||
1096 | |||
1097 | static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
1098 | { | ||
1099 | struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); | ||
1100 | void __iomem *pio = at91_gpio->regbase; | ||
1101 | unsigned mask = 1 << offset; | ||
1102 | |||
1103 | writel_relaxed(mask, pio + PIO_ODR); | ||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
1107 | static int at91_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
1108 | { | ||
1109 | struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); | ||
1110 | void __iomem *pio = at91_gpio->regbase; | ||
1111 | unsigned mask = 1 << offset; | ||
1112 | u32 pdsr; | ||
1113 | |||
1114 | pdsr = readl_relaxed(pio + PIO_PDSR); | ||
1115 | return (pdsr & mask) != 0; | ||
1116 | } | ||
1117 | |||
1118 | static void at91_gpio_set(struct gpio_chip *chip, unsigned offset, | ||
1119 | int val) | ||
1120 | { | ||
1121 | struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); | ||
1122 | void __iomem *pio = at91_gpio->regbase; | ||
1123 | unsigned mask = 1 << offset; | ||
1124 | |||
1125 | writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR)); | ||
1126 | } | ||
1127 | |||
1128 | static int at91_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
1129 | int val) | ||
1130 | { | ||
1131 | struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); | ||
1132 | void __iomem *pio = at91_gpio->regbase; | ||
1133 | unsigned mask = 1 << offset; | ||
1134 | |||
1135 | writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR)); | ||
1136 | writel_relaxed(mask, pio + PIO_OER); | ||
1137 | |||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1141 | static int at91_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
1142 | { | ||
1143 | struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); | ||
1144 | int virq; | ||
1145 | |||
1146 | if (offset < chip->ngpio) | ||
1147 | virq = irq_create_mapping(at91_gpio->domain, offset); | ||
1148 | else | ||
1149 | virq = -ENXIO; | ||
1150 | |||
1151 | dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", | ||
1152 | chip->label, offset + chip->base, virq); | ||
1153 | return virq; | ||
1154 | } | ||
1155 | |||
1156 | #ifdef CONFIG_DEBUG_FS | ||
1157 | static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | ||
1158 | { | ||
1159 | enum at91_mux mode; | ||
1160 | int i; | ||
1161 | struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); | ||
1162 | void __iomem *pio = at91_gpio->regbase; | ||
1163 | |||
1164 | for (i = 0; i < chip->ngpio; i++) { | ||
1165 | unsigned pin = chip->base + i; | ||
1166 | unsigned mask = pin_to_mask(pin); | ||
1167 | const char *gpio_label; | ||
1168 | u32 pdsr; | ||
1169 | |||
1170 | gpio_label = gpiochip_is_requested(chip, i); | ||
1171 | if (!gpio_label) | ||
1172 | continue; | ||
1173 | mode = at91_gpio->ops->get_periph(pio, mask); | ||
1174 | seq_printf(s, "[%s] GPIO%s%d: ", | ||
1175 | gpio_label, chip->label, i); | ||
1176 | if (mode == AT91_MUX_GPIO) { | ||
1177 | pdsr = readl_relaxed(pio + PIO_PDSR); | ||
1178 | |||
1179 | seq_printf(s, "[gpio] %s\n", | ||
1180 | pdsr & mask ? | ||
1181 | "set" : "clear"); | ||
1182 | } else { | ||
1183 | seq_printf(s, "[periph %c]\n", | ||
1184 | mode + 'A' - 1); | ||
1185 | } | ||
1186 | } | ||
1187 | } | ||
1188 | #else | ||
1189 | #define at91_gpio_dbg_show NULL | ||
1190 | #endif | ||
1191 | |||
1192 | /* Several AIC controller irqs are dispatched through this GPIO handler. | ||
1193 | * To use any AT91_PIN_* as an externally triggered IRQ, first call | ||
1194 | * at91_set_gpio_input() then maybe enable its glitch filter. | ||
1195 | * Then just request_irq() with the pin ID; it works like any ARM IRQ | ||
1196 | * handler. | ||
1197 | * First implementation always triggers on rising and falling edges | ||
1198 | * whereas the newer PIO3 can be additionally configured to trigger on | ||
1199 | * level, edge with any polarity. | ||
1200 | * | ||
1201 | * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after | ||
1202 | * configuring them with at91_set_a_periph() or at91_set_b_periph(). | ||
1203 | * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering. | ||
1204 | */ | ||
1205 | |||
1206 | static void gpio_irq_mask(struct irq_data *d) | ||
1207 | { | ||
1208 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); | ||
1209 | void __iomem *pio = at91_gpio->regbase; | ||
1210 | unsigned mask = 1 << d->hwirq; | ||
1211 | |||
1212 | if (pio) | ||
1213 | writel_relaxed(mask, pio + PIO_IDR); | ||
1214 | } | ||
1215 | |||
1216 | static void gpio_irq_unmask(struct irq_data *d) | ||
1217 | { | ||
1218 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); | ||
1219 | void __iomem *pio = at91_gpio->regbase; | ||
1220 | unsigned mask = 1 << d->hwirq; | ||
1221 | |||
1222 | if (pio) | ||
1223 | writel_relaxed(mask, pio + PIO_IER); | ||
1224 | } | ||
1225 | |||
1226 | static int gpio_irq_type(struct irq_data *d, unsigned type) | ||
1227 | { | ||
1228 | switch (type) { | ||
1229 | case IRQ_TYPE_NONE: | ||
1230 | case IRQ_TYPE_EDGE_BOTH: | ||
1231 | return 0; | ||
1232 | default: | ||
1233 | return -EINVAL; | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | /* Alternate irq type for PIO3 support */ | ||
1238 | static int alt_gpio_irq_type(struct irq_data *d, unsigned type) | ||
1239 | { | ||
1240 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); | ||
1241 | void __iomem *pio = at91_gpio->regbase; | ||
1242 | unsigned mask = 1 << d->hwirq; | ||
1243 | |||
1244 | switch (type) { | ||
1245 | case IRQ_TYPE_EDGE_RISING: | ||
1246 | writel_relaxed(mask, pio + PIO_ESR); | ||
1247 | writel_relaxed(mask, pio + PIO_REHLSR); | ||
1248 | break; | ||
1249 | case IRQ_TYPE_EDGE_FALLING: | ||
1250 | writel_relaxed(mask, pio + PIO_ESR); | ||
1251 | writel_relaxed(mask, pio + PIO_FELLSR); | ||
1252 | break; | ||
1253 | case IRQ_TYPE_LEVEL_LOW: | ||
1254 | writel_relaxed(mask, pio + PIO_LSR); | ||
1255 | writel_relaxed(mask, pio + PIO_FELLSR); | ||
1256 | break; | ||
1257 | case IRQ_TYPE_LEVEL_HIGH: | ||
1258 | writel_relaxed(mask, pio + PIO_LSR); | ||
1259 | writel_relaxed(mask, pio + PIO_REHLSR); | ||
1260 | break; | ||
1261 | case IRQ_TYPE_EDGE_BOTH: | ||
1262 | /* | ||
1263 | * disable additional interrupt modes: | ||
1264 | * fall back to default behavior | ||
1265 | */ | ||
1266 | writel_relaxed(mask, pio + PIO_AIMDR); | ||
1267 | return 0; | ||
1268 | case IRQ_TYPE_NONE: | ||
1269 | default: | ||
1270 | pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq)); | ||
1271 | return -EINVAL; | ||
1272 | } | ||
1273 | |||
1274 | /* enable additional interrupt modes */ | ||
1275 | writel_relaxed(mask, pio + PIO_AIMER); | ||
1276 | |||
1277 | return 0; | ||
1278 | } | ||
1279 | |||
1280 | #ifdef CONFIG_PM | ||
1281 | static int gpio_irq_set_wake(struct irq_data *d, unsigned state) | ||
1282 | { | ||
1283 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); | ||
1284 | unsigned bank = at91_gpio->pioc_idx; | ||
1285 | |||
1286 | if (unlikely(bank >= MAX_GPIO_BANKS)) | ||
1287 | return -EINVAL; | ||
1288 | |||
1289 | irq_set_irq_wake(at91_gpio->pioc_virq, state); | ||
1290 | |||
1291 | return 0; | ||
1292 | } | ||
1293 | #else | ||
1294 | #define gpio_irq_set_wake NULL | ||
1295 | #endif | ||
1296 | |||
1297 | static struct irq_chip gpio_irqchip = { | ||
1298 | .name = "GPIO", | ||
1299 | .irq_disable = gpio_irq_mask, | ||
1300 | .irq_mask = gpio_irq_mask, | ||
1301 | .irq_unmask = gpio_irq_unmask, | ||
1302 | /* .irq_set_type is set dynamically */ | ||
1303 | .irq_set_wake = gpio_irq_set_wake, | ||
1304 | }; | ||
1305 | |||
1306 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
1307 | { | ||
1308 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
1309 | struct irq_data *idata = irq_desc_get_irq_data(desc); | ||
1310 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); | ||
1311 | void __iomem *pio = at91_gpio->regbase; | ||
1312 | unsigned long isr; | ||
1313 | int n; | ||
1314 | |||
1315 | chained_irq_enter(chip, desc); | ||
1316 | for (;;) { | ||
1317 | /* Reading ISR acks pending (edge triggered) GPIO interrupts. | ||
1318 | * When there none are pending, we're finished unless we need | ||
1319 | * to process multiple banks (like ID_PIOCDE on sam9263). | ||
1320 | */ | ||
1321 | isr = readl_relaxed(pio + PIO_ISR) & readl_relaxed(pio + PIO_IMR); | ||
1322 | if (!isr) { | ||
1323 | if (!at91_gpio->next) | ||
1324 | break; | ||
1325 | at91_gpio = at91_gpio->next; | ||
1326 | pio = at91_gpio->regbase; | ||
1327 | continue; | ||
1328 | } | ||
1329 | |||
1330 | for_each_set_bit(n, &isr, BITS_PER_LONG) { | ||
1331 | generic_handle_irq(irq_find_mapping(at91_gpio->domain, n)); | ||
1332 | } | ||
1333 | } | ||
1334 | chained_irq_exit(chip, desc); | ||
1335 | /* now it may re-trigger */ | ||
1336 | } | ||
1337 | |||
1338 | /* | ||
1339 | * This lock class tells lockdep that GPIO irqs are in a different | ||
1340 | * category than their parents, so it won't report false recursion. | ||
1341 | */ | ||
1342 | static struct lock_class_key gpio_lock_class; | ||
1343 | |||
1344 | static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, | ||
1345 | irq_hw_number_t hw) | ||
1346 | { | ||
1347 | struct at91_gpio_chip *at91_gpio = h->host_data; | ||
1348 | |||
1349 | irq_set_lockdep_class(virq, &gpio_lock_class); | ||
1350 | |||
1351 | /* | ||
1352 | * Can use the "simple" and not "edge" handler since it's | ||
1353 | * shorter, and the AIC handles interrupts sanely. | ||
1354 | */ | ||
1355 | irq_set_chip_and_handler(virq, &gpio_irqchip, | ||
1356 | handle_simple_irq); | ||
1357 | set_irq_flags(virq, IRQF_VALID); | ||
1358 | irq_set_chip_data(virq, at91_gpio); | ||
1359 | |||
1360 | return 0; | ||
1361 | } | ||
1362 | |||
1363 | static int at91_gpio_irq_domain_xlate(struct irq_domain *d, | ||
1364 | struct device_node *ctrlr, | ||
1365 | const u32 *intspec, unsigned int intsize, | ||
1366 | irq_hw_number_t *out_hwirq, | ||
1367 | unsigned int *out_type) | ||
1368 | { | ||
1369 | struct at91_gpio_chip *at91_gpio = d->host_data; | ||
1370 | int ret; | ||
1371 | int pin = at91_gpio->chip.base + intspec[0]; | ||
1372 | |||
1373 | if (WARN_ON(intsize < 2)) | ||
1374 | return -EINVAL; | ||
1375 | *out_hwirq = intspec[0]; | ||
1376 | *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; | ||
1377 | |||
1378 | ret = gpio_request(pin, ctrlr->full_name); | ||
1379 | if (ret) | ||
1380 | return ret; | ||
1381 | |||
1382 | ret = gpio_direction_input(pin); | ||
1383 | if (ret) | ||
1384 | return ret; | ||
1385 | |||
1386 | return 0; | ||
1387 | } | ||
1388 | |||
1389 | static struct irq_domain_ops at91_gpio_ops = { | ||
1390 | .map = at91_gpio_irq_map, | ||
1391 | .xlate = at91_gpio_irq_domain_xlate, | ||
1392 | }; | ||
1393 | |||
1394 | static int at91_gpio_of_irq_setup(struct device_node *node, | ||
1395 | struct at91_gpio_chip *at91_gpio) | ||
1396 | { | ||
1397 | struct at91_gpio_chip *prev = NULL; | ||
1398 | struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq); | ||
1399 | |||
1400 | at91_gpio->pioc_hwirq = irqd_to_hwirq(d); | ||
1401 | |||
1402 | /* Setup proper .irq_set_type function */ | ||
1403 | gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type; | ||
1404 | |||
1405 | /* Disable irqs of this PIO controller */ | ||
1406 | writel_relaxed(~0, at91_gpio->regbase + PIO_IDR); | ||
1407 | |||
1408 | /* Setup irq domain */ | ||
1409 | at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio, | ||
1410 | &at91_gpio_ops, at91_gpio); | ||
1411 | if (!at91_gpio->domain) | ||
1412 | panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n", | ||
1413 | at91_gpio->pioc_idx); | ||
1414 | |||
1415 | /* Setup chained handler */ | ||
1416 | if (at91_gpio->pioc_idx) | ||
1417 | prev = gpio_chips[at91_gpio->pioc_idx - 1]; | ||
1418 | |||
1419 | /* The toplevel handler handles one bank of GPIOs, except | ||
1420 | * on some SoC it can handles up to three... | ||
1421 | * We only set up the handler for the first of the list. | ||
1422 | */ | ||
1423 | if (prev && prev->next == at91_gpio) | ||
1424 | return 0; | ||
1425 | |||
1426 | irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio); | ||
1427 | irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler); | ||
1428 | |||
1429 | return 0; | ||
1430 | } | ||
1431 | |||
1432 | /* This structure is replicated for each GPIO block allocated at probe time */ | ||
1433 | static struct gpio_chip at91_gpio_template = { | ||
1434 | .request = at91_gpio_request, | ||
1435 | .free = at91_gpio_free, | ||
1436 | .direction_input = at91_gpio_direction_input, | ||
1437 | .get = at91_gpio_get, | ||
1438 | .direction_output = at91_gpio_direction_output, | ||
1439 | .set = at91_gpio_set, | ||
1440 | .to_irq = at91_gpio_to_irq, | ||
1441 | .dbg_show = at91_gpio_dbg_show, | ||
1442 | .can_sleep = 0, | ||
1443 | .ngpio = MAX_NB_GPIO_PER_BANK, | ||
1444 | }; | ||
1445 | |||
1446 | static void __devinit at91_gpio_probe_fixup(void) | ||
1447 | { | ||
1448 | unsigned i; | ||
1449 | struct at91_gpio_chip *at91_gpio, *last = NULL; | ||
1450 | |||
1451 | for (i = 0; i < gpio_banks; i++) { | ||
1452 | at91_gpio = gpio_chips[i]; | ||
1453 | |||
1454 | /* | ||
1455 | * GPIO controller are grouped on some SoC: | ||
1456 | * PIOC, PIOD and PIOE can share the same IRQ line | ||
1457 | */ | ||
1458 | if (last && last->pioc_virq == at91_gpio->pioc_virq) | ||
1459 | last->next = at91_gpio; | ||
1460 | last = at91_gpio; | ||
1461 | } | ||
1462 | } | ||
1463 | |||
1464 | static struct of_device_id at91_gpio_of_match[] __devinitdata = { | ||
1465 | { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, | ||
1466 | { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, | ||
1467 | { /* sentinel */ } | ||
1468 | }; | ||
1469 | |||
1470 | static int __devinit at91_gpio_probe(struct platform_device *pdev) | ||
1471 | { | ||
1472 | struct device_node *np = pdev->dev.of_node; | ||
1473 | struct resource *res; | ||
1474 | struct at91_gpio_chip *at91_chip = NULL; | ||
1475 | struct gpio_chip *chip; | ||
1476 | struct pinctrl_gpio_range *range; | ||
1477 | int ret = 0; | ||
1478 | int irq, i; | ||
1479 | int alias_idx = of_alias_get_id(np, "gpio"); | ||
1480 | uint32_t ngpio; | ||
1481 | char **names; | ||
1482 | |||
1483 | BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); | ||
1484 | if (gpio_chips[alias_idx]) { | ||
1485 | ret = -EBUSY; | ||
1486 | goto err; | ||
1487 | } | ||
1488 | |||
1489 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1490 | if (!res) { | ||
1491 | ret = -ENOENT; | ||
1492 | goto err; | ||
1493 | } | ||
1494 | |||
1495 | irq = platform_get_irq(pdev, 0); | ||
1496 | if (irq < 0) { | ||
1497 | ret = irq; | ||
1498 | goto err; | ||
1499 | } | ||
1500 | |||
1501 | at91_chip = devm_kzalloc(&pdev->dev, sizeof(*at91_chip), GFP_KERNEL); | ||
1502 | if (!at91_chip) { | ||
1503 | ret = -ENOMEM; | ||
1504 | goto err; | ||
1505 | } | ||
1506 | |||
1507 | at91_chip->regbase = devm_request_and_ioremap(&pdev->dev, res); | ||
1508 | if (!at91_chip->regbase) { | ||
1509 | dev_err(&pdev->dev, "failed to map registers, ignoring.\n"); | ||
1510 | ret = -EBUSY; | ||
1511 | goto err; | ||
1512 | } | ||
1513 | |||
1514 | at91_chip->ops = (struct at91_pinctrl_mux_ops*) | ||
1515 | of_match_device(at91_gpio_of_match, &pdev->dev)->data; | ||
1516 | at91_chip->pioc_virq = irq; | ||
1517 | at91_chip->pioc_idx = alias_idx; | ||
1518 | |||
1519 | at91_chip->clock = clk_get(&pdev->dev, NULL); | ||
1520 | if (IS_ERR(at91_chip->clock)) { | ||
1521 | dev_err(&pdev->dev, "failed to get clock, ignoring.\n"); | ||
1522 | goto err; | ||
1523 | } | ||
1524 | |||
1525 | if (clk_prepare(at91_chip->clock)) | ||
1526 | goto clk_prep_err; | ||
1527 | |||
1528 | /* enable PIO controller's clock */ | ||
1529 | if (clk_enable(at91_chip->clock)) { | ||
1530 | dev_err(&pdev->dev, "failed to enable clock, ignoring.\n"); | ||
1531 | goto clk_err; | ||
1532 | } | ||
1533 | |||
1534 | at91_chip->chip = at91_gpio_template; | ||
1535 | |||
1536 | chip = &at91_chip->chip; | ||
1537 | chip->of_node = np; | ||
1538 | chip->label = dev_name(&pdev->dev); | ||
1539 | chip->dev = &pdev->dev; | ||
1540 | chip->owner = THIS_MODULE; | ||
1541 | chip->base = alias_idx * MAX_NB_GPIO_PER_BANK; | ||
1542 | |||
1543 | if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) { | ||
1544 | if (ngpio >= MAX_NB_GPIO_PER_BANK) | ||
1545 | pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n", | ||
1546 | alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); | ||
1547 | else | ||
1548 | chip->ngpio = ngpio; | ||
1549 | } | ||
1550 | |||
1551 | names = devm_kzalloc(&pdev->dev, sizeof(char*) * chip->ngpio, GFP_KERNEL); | ||
1552 | |||
1553 | if (!names) { | ||
1554 | ret = -ENOMEM; | ||
1555 | goto clk_err; | ||
1556 | } | ||
1557 | |||
1558 | for (i = 0; i < chip->ngpio; i++) | ||
1559 | names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); | ||
1560 | |||
1561 | chip->names = (const char*const*)names; | ||
1562 | |||
1563 | range = &at91_chip->range; | ||
1564 | range->name = chip->label; | ||
1565 | range->id = alias_idx; | ||
1566 | range->pin_base = range->base = range->id * MAX_NB_GPIO_PER_BANK; | ||
1567 | |||
1568 | range->npins = chip->ngpio; | ||
1569 | range->gc = chip; | ||
1570 | |||
1571 | ret = gpiochip_add(chip); | ||
1572 | if (ret) | ||
1573 | goto clk_err; | ||
1574 | |||
1575 | gpio_chips[alias_idx] = at91_chip; | ||
1576 | gpio_banks = max(gpio_banks, alias_idx + 1); | ||
1577 | |||
1578 | at91_gpio_probe_fixup(); | ||
1579 | |||
1580 | at91_gpio_of_irq_setup(np, at91_chip); | ||
1581 | |||
1582 | dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase); | ||
1583 | |||
1584 | return 0; | ||
1585 | |||
1586 | clk_err: | ||
1587 | clk_unprepare(at91_chip->clock); | ||
1588 | clk_prep_err: | ||
1589 | clk_put(at91_chip->clock); | ||
1590 | err: | ||
1591 | dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx); | ||
1592 | |||
1593 | return ret; | ||
1594 | } | ||
1595 | |||
1596 | static struct platform_driver at91_gpio_driver = { | ||
1597 | .driver = { | ||
1598 | .name = "gpio-at91", | ||
1599 | .owner = THIS_MODULE, | ||
1600 | .of_match_table = of_match_ptr(at91_gpio_of_match), | ||
1601 | }, | ||
1602 | .probe = at91_gpio_probe, | ||
1603 | }; | ||
1604 | |||
1605 | static struct platform_driver at91_pinctrl_driver = { | ||
1606 | .driver = { | ||
1607 | .name = "pinctrl-at91", | ||
1608 | .owner = THIS_MODULE, | ||
1609 | .of_match_table = of_match_ptr(at91_pinctrl_of_match), | ||
1610 | }, | ||
1611 | .probe = at91_pinctrl_probe, | ||
1612 | .remove = __devexit_p(at91_pinctrl_remove), | ||
1613 | }; | ||
1614 | |||
1615 | static int __init at91_pinctrl_init(void) | ||
1616 | { | ||
1617 | int ret; | ||
1618 | |||
1619 | ret = platform_driver_register(&at91_gpio_driver); | ||
1620 | if (ret) | ||
1621 | return ret; | ||
1622 | return platform_driver_register(&at91_pinctrl_driver); | ||
1623 | } | ||
1624 | arch_initcall(at91_pinctrl_init); | ||
1625 | |||
1626 | static void __exit at91_pinctrl_exit(void) | ||
1627 | { | ||
1628 | platform_driver_unregister(&at91_pinctrl_driver); | ||
1629 | } | ||
1630 | |||
1631 | module_exit(at91_pinctrl_exit); | ||
1632 | MODULE_AUTHOR("Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>"); | ||
1633 | MODULE_DESCRIPTION("Atmel AT91 pinctrl driver"); | ||
1634 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c index 7e9be18ec2d2..0b0e9b49a1b5 100644 --- a/drivers/pinctrl/pinctrl-bcm2835.c +++ b/drivers/pinctrl/pinctrl-bcm2835.c | |||
@@ -372,7 +372,7 @@ static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
372 | return irq_linear_revmap(pc->irq_domain, offset); | 372 | return irq_linear_revmap(pc->irq_domain, offset); |
373 | } | 373 | } |
374 | 374 | ||
375 | static struct gpio_chip bcm2835_gpio_chip __devinitconst = { | 375 | static struct gpio_chip bcm2835_gpio_chip = { |
376 | .label = MODULE_NAME, | 376 | .label = MODULE_NAME, |
377 | .owner = THIS_MODULE, | 377 | .owner = THIS_MODULE, |
378 | .request = bcm2835_gpio_request, | 378 | .request = bcm2835_gpio_request, |
@@ -916,7 +916,7 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, | |||
916 | return 0; | 916 | return 0; |
917 | } | 917 | } |
918 | 918 | ||
919 | struct pinconf_ops bcm2835_pinconf_ops = { | 919 | static struct pinconf_ops bcm2835_pinconf_ops = { |
920 | .pin_config_get = bcm2835_pinconf_get, | 920 | .pin_config_get = bcm2835_pinconf_get, |
921 | .pin_config_set = bcm2835_pinconf_set, | 921 | .pin_config_set = bcm2835_pinconf_set, |
922 | }; | 922 | }; |
@@ -931,7 +931,7 @@ static struct pinctrl_desc bcm2835_pinctrl_desc = { | |||
931 | .owner = THIS_MODULE, | 931 | .owner = THIS_MODULE, |
932 | }; | 932 | }; |
933 | 933 | ||
934 | static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range __devinitconst = { | 934 | static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = { |
935 | .name = MODULE_NAME, | 935 | .name = MODULE_NAME, |
936 | .npins = BCM2835_NUM_GPIOS, | 936 | .npins = BCM2835_NUM_GPIOS, |
937 | }; | 937 | }; |
@@ -1042,7 +1042,7 @@ static int __devinit bcm2835_pinctrl_probe(struct platform_device *pdev) | |||
1042 | return 0; | 1042 | return 0; |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | static int __devexit bcm2835_pinctrl_remove(struct platform_device *pdev) | 1045 | static int bcm2835_pinctrl_remove(struct platform_device *pdev) |
1046 | { | 1046 | { |
1047 | struct bcm2835_pinctrl *pc = platform_get_drvdata(pdev); | 1047 | struct bcm2835_pinctrl *pc = platform_get_drvdata(pdev); |
1048 | 1048 | ||
@@ -1052,7 +1052,7 @@ static int __devexit bcm2835_pinctrl_remove(struct platform_device *pdev) | |||
1052 | return 0; | 1052 | return 0; |
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | static struct of_device_id bcm2835_pinctrl_match[] __devinitconst = { | 1055 | static struct of_device_id bcm2835_pinctrl_match[] = { |
1056 | { .compatible = "brcm,bcm2835-gpio" }, | 1056 | { .compatible = "brcm,bcm2835-gpio" }, |
1057 | {} | 1057 | {} |
1058 | }; | 1058 | }; |
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index b446c9641212..fbb37154471c 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/irqdomain.h> | ||
16 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
17 | #include <linux/err.h> | 18 | #include <linux/err.h> |
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
@@ -64,10 +65,8 @@ struct u300_gpio { | |||
64 | struct gpio_chip chip; | 65 | struct gpio_chip chip; |
65 | struct list_head port_list; | 66 | struct list_head port_list; |
66 | struct clk *clk; | 67 | struct clk *clk; |
67 | struct resource *memres; | ||
68 | void __iomem *base; | 68 | void __iomem *base; |
69 | struct device *dev; | 69 | struct device *dev; |
70 | int irq_base; | ||
71 | u32 stride; | 70 | u32 stride; |
72 | /* Register offsets */ | 71 | /* Register offsets */ |
73 | u32 pcr; | 72 | u32 pcr; |
@@ -83,6 +82,7 @@ struct u300_gpio_port { | |||
83 | struct list_head node; | 82 | struct list_head node; |
84 | struct u300_gpio *gpio; | 83 | struct u300_gpio *gpio; |
85 | char name[8]; | 84 | char name[8]; |
85 | struct irq_domain *domain; | ||
86 | int irq; | 86 | int irq; |
87 | int number; | 87 | int number; |
88 | u8 toggle_edge_mode; | 88 | u8 toggle_edge_mode; |
@@ -314,10 +314,30 @@ static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | |||
314 | static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | 314 | static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
315 | { | 315 | { |
316 | struct u300_gpio *gpio = to_u300_gpio(chip); | 316 | struct u300_gpio *gpio = to_u300_gpio(chip); |
317 | int retirq = gpio->irq_base + offset; | 317 | int portno = offset >> 3; |
318 | struct u300_gpio_port *port = NULL; | ||
319 | struct list_head *p; | ||
320 | int retirq; | ||
318 | 321 | ||
319 | dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset, | 322 | list_for_each(p, &gpio->port_list) { |
320 | retirq); | 323 | port = list_entry(p, struct u300_gpio_port, node); |
324 | if (port->number == portno) | ||
325 | break; | ||
326 | } | ||
327 | if (port == NULL) { | ||
328 | dev_err(gpio->dev, "could not locate port for GPIO %d IRQ\n", | ||
329 | offset); | ||
330 | return -EINVAL; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * The local hwirqs on the port are the lower three bits, there | ||
335 | * are exactly 8 IRQs per port since they are 8-bit | ||
336 | */ | ||
337 | retirq = irq_find_mapping(port->domain, (offset & 0x7)); | ||
338 | |||
339 | dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d from port %d\n", | ||
340 | offset, retirq, port->number); | ||
321 | return retirq; | 341 | return retirq; |
322 | } | 342 | } |
323 | 343 | ||
@@ -467,7 +487,7 @@ static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) | |||
467 | { | 487 | { |
468 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | 488 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); |
469 | struct u300_gpio *gpio = port->gpio; | 489 | struct u300_gpio *gpio = port->gpio; |
470 | int offset = d->irq - gpio->irq_base; | 490 | int offset = (port->number << 3) + d->hwirq; |
471 | u32 val; | 491 | u32 val; |
472 | 492 | ||
473 | if ((trigger & IRQF_TRIGGER_RISING) && | 493 | if ((trigger & IRQF_TRIGGER_RISING) && |
@@ -503,10 +523,12 @@ static void u300_gpio_irq_enable(struct irq_data *d) | |||
503 | { | 523 | { |
504 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | 524 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); |
505 | struct u300_gpio *gpio = port->gpio; | 525 | struct u300_gpio *gpio = port->gpio; |
506 | int offset = d->irq - gpio->irq_base; | 526 | int offset = (port->number << 3) + d->hwirq; |
507 | u32 val; | 527 | u32 val; |
508 | unsigned long flags; | 528 | unsigned long flags; |
509 | 529 | ||
530 | dev_dbg(gpio->dev, "enable IRQ for hwirq %lu on port %s, offset %d\n", | ||
531 | d->hwirq, port->name, offset); | ||
510 | local_irq_save(flags); | 532 | local_irq_save(flags); |
511 | val = readl(U300_PIN_REG(offset, ien)); | 533 | val = readl(U300_PIN_REG(offset, ien)); |
512 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); | 534 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); |
@@ -517,7 +539,7 @@ static void u300_gpio_irq_disable(struct irq_data *d) | |||
517 | { | 539 | { |
518 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | 540 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); |
519 | struct u300_gpio *gpio = port->gpio; | 541 | struct u300_gpio *gpio = port->gpio; |
520 | int offset = d->irq - gpio->irq_base; | 542 | int offset = (port->number << 3) + d->hwirq; |
521 | u32 val; | 543 | u32 val; |
522 | unsigned long flags; | 544 | unsigned long flags; |
523 | 545 | ||
@@ -555,8 +577,7 @@ static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
555 | int irqoffset; | 577 | int irqoffset; |
556 | 578 | ||
557 | for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { | 579 | for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { |
558 | int pin_irq = gpio->irq_base + (port->number << 3) | 580 | int pin_irq = irq_find_mapping(port->domain, irqoffset); |
559 | + irqoffset; | ||
560 | int offset = pinoffset + irqoffset; | 581 | int offset = pinoffset + irqoffset; |
561 | 582 | ||
562 | dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", | 583 | dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", |
@@ -631,64 +652,86 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) | |||
631 | list_for_each_safe(p, n, &gpio->port_list) { | 652 | list_for_each_safe(p, n, &gpio->port_list) { |
632 | port = list_entry(p, struct u300_gpio_port, node); | 653 | port = list_entry(p, struct u300_gpio_port, node); |
633 | list_del(&port->node); | 654 | list_del(&port->node); |
655 | if (port->domain) | ||
656 | irq_domain_remove(port->domain); | ||
634 | kfree(port); | 657 | kfree(port); |
635 | } | 658 | } |
636 | } | 659 | } |
637 | 660 | ||
661 | /* | ||
662 | * Here we map a GPIO in the local gpio_chip pin space to a pin in | ||
663 | * the local pinctrl pin space. The pin controller used is | ||
664 | * pinctrl-u300. | ||
665 | */ | ||
666 | struct coh901_pinpair { | ||
667 | unsigned int offset; | ||
668 | unsigned int pin_base; | ||
669 | }; | ||
670 | |||
671 | #define COH901_PINRANGE(a, b) { .offset = a, .pin_base = b } | ||
672 | |||
673 | static struct coh901_pinpair coh901_pintable[] = { | ||
674 | COH901_PINRANGE(10, 426), | ||
675 | COH901_PINRANGE(11, 180), | ||
676 | COH901_PINRANGE(12, 165), /* MS/MMC card insertion */ | ||
677 | COH901_PINRANGE(13, 179), | ||
678 | COH901_PINRANGE(14, 178), | ||
679 | COH901_PINRANGE(16, 194), | ||
680 | COH901_PINRANGE(17, 193), | ||
681 | COH901_PINRANGE(18, 192), | ||
682 | COH901_PINRANGE(19, 191), | ||
683 | COH901_PINRANGE(20, 186), | ||
684 | COH901_PINRANGE(21, 185), | ||
685 | COH901_PINRANGE(22, 184), | ||
686 | COH901_PINRANGE(23, 183), | ||
687 | COH901_PINRANGE(24, 182), | ||
688 | COH901_PINRANGE(25, 181), | ||
689 | }; | ||
690 | |||
638 | static int __init u300_gpio_probe(struct platform_device *pdev) | 691 | static int __init u300_gpio_probe(struct platform_device *pdev) |
639 | { | 692 | { |
640 | struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); | 693 | struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); |
641 | struct u300_gpio *gpio; | 694 | struct u300_gpio *gpio; |
695 | struct resource *memres; | ||
642 | int err = 0; | 696 | int err = 0; |
643 | int portno; | 697 | int portno; |
644 | u32 val; | 698 | u32 val; |
645 | u32 ifr; | 699 | u32 ifr; |
646 | int i; | 700 | int i; |
647 | 701 | ||
648 | gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL); | 702 | gpio = devm_kzalloc(&pdev->dev, sizeof(struct u300_gpio), GFP_KERNEL); |
649 | if (gpio == NULL) { | 703 | if (gpio == NULL) |
650 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
651 | return -ENOMEM; | 704 | return -ENOMEM; |
652 | } | ||
653 | 705 | ||
654 | gpio->chip = u300_gpio_chip; | 706 | gpio->chip = u300_gpio_chip; |
655 | gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; | 707 | gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; |
656 | gpio->irq_base = plat->gpio_irq_base; | ||
657 | gpio->chip.dev = &pdev->dev; | 708 | gpio->chip.dev = &pdev->dev; |
658 | gpio->chip.base = plat->gpio_base; | 709 | gpio->chip.base = plat->gpio_base; |
659 | gpio->dev = &pdev->dev; | 710 | gpio->dev = &pdev->dev; |
660 | 711 | ||
661 | /* Get GPIO clock */ | 712 | memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
662 | gpio->clk = clk_get(gpio->dev, NULL); | 713 | if (!memres) { |
714 | dev_err(gpio->dev, "could not get GPIO memory resource\n"); | ||
715 | return -ENODEV; | ||
716 | } | ||
717 | |||
718 | gpio->base = devm_request_and_ioremap(&pdev->dev, memres); | ||
719 | if (!gpio->base) { | ||
720 | dev_err(gpio->dev, "could not get remap memory\n"); | ||
721 | return -ENOMEM; | ||
722 | } | ||
723 | |||
724 | gpio->clk = devm_clk_get(gpio->dev, NULL); | ||
663 | if (IS_ERR(gpio->clk)) { | 725 | if (IS_ERR(gpio->clk)) { |
664 | err = PTR_ERR(gpio->clk); | 726 | err = PTR_ERR(gpio->clk); |
665 | dev_err(gpio->dev, "could not get GPIO clock\n"); | 727 | dev_err(gpio->dev, "could not get GPIO clock\n"); |
666 | goto err_no_clk; | 728 | return err; |
667 | } | 729 | } |
730 | |||
668 | err = clk_prepare_enable(gpio->clk); | 731 | err = clk_prepare_enable(gpio->clk); |
669 | if (err) { | 732 | if (err) { |
670 | dev_err(gpio->dev, "could not enable GPIO clock\n"); | 733 | dev_err(gpio->dev, "could not enable GPIO clock\n"); |
671 | goto err_no_clk_enable; | 734 | return err; |
672 | } | ||
673 | |||
674 | gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
675 | if (!gpio->memres) { | ||
676 | dev_err(gpio->dev, "could not get GPIO memory resource\n"); | ||
677 | err = -ENODEV; | ||
678 | goto err_no_resource; | ||
679 | } | ||
680 | |||
681 | if (!request_mem_region(gpio->memres->start, | ||
682 | resource_size(gpio->memres), | ||
683 | "GPIO Controller")) { | ||
684 | err = -ENODEV; | ||
685 | goto err_no_ioregion; | ||
686 | } | ||
687 | |||
688 | gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres)); | ||
689 | if (!gpio->base) { | ||
690 | err = -ENOMEM; | ||
691 | goto err_no_ioremap; | ||
692 | } | 735 | } |
693 | 736 | ||
694 | dev_info(gpio->dev, | 737 | dev_info(gpio->dev, |
@@ -732,18 +775,28 @@ static int __init u300_gpio_probe(struct platform_device *pdev) | |||
732 | port->irq = platform_get_irq_byname(pdev, | 775 | port->irq = platform_get_irq_byname(pdev, |
733 | port->name); | 776 | port->name); |
734 | 777 | ||
735 | dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq, | 778 | dev_dbg(gpio->dev, "register IRQ %d for port %s\n", port->irq, |
736 | port->name); | 779 | port->name); |
737 | 780 | ||
781 | port->domain = irq_domain_add_linear(pdev->dev.of_node, | ||
782 | U300_GPIO_PINS_PER_PORT, | ||
783 | &irq_domain_simple_ops, | ||
784 | port); | ||
785 | if (!port->domain) { | ||
786 | err = -ENOMEM; | ||
787 | goto err_no_domain; | ||
788 | } | ||
789 | |||
738 | irq_set_chained_handler(port->irq, u300_gpio_irq_handler); | 790 | irq_set_chained_handler(port->irq, u300_gpio_irq_handler); |
739 | irq_set_handler_data(port->irq, port); | 791 | irq_set_handler_data(port->irq, port); |
740 | 792 | ||
741 | /* For each GPIO pin set the unique IRQ handler */ | 793 | /* For each GPIO pin set the unique IRQ handler */ |
742 | for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { | 794 | for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { |
743 | int irqno = gpio->irq_base + (portno << 3) + i; | 795 | int irqno = irq_create_mapping(port->domain, i); |
744 | 796 | ||
745 | dev_dbg(gpio->dev, "handler for IRQ %d on %s\n", | 797 | dev_dbg(gpio->dev, "GPIO%d on port %s gets IRQ %d\n", |
746 | irqno, port->name); | 798 | gpio->chip.base + (port->number << 3) + i, |
799 | port->name, irqno); | ||
747 | irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, | 800 | irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, |
748 | handle_simple_irq); | 801 | handle_simple_irq); |
749 | set_irq_flags(irqno, IRQF_VALID); | 802 | set_irq_flags(irqno, IRQF_VALID); |
@@ -763,32 +816,31 @@ static int __init u300_gpio_probe(struct platform_device *pdev) | |||
763 | goto err_no_chip; | 816 | goto err_no_chip; |
764 | } | 817 | } |
765 | 818 | ||
766 | /* Spawn pin controller device as child of the GPIO, pass gpio chip */ | 819 | /* |
767 | plat->pinctrl_device->dev.platform_data = &gpio->chip; | 820 | * Add pinctrl pin ranges, the pin controller must be registered |
768 | err = platform_device_register(plat->pinctrl_device); | 821 | * at this point |
769 | if (err) | 822 | */ |
770 | goto err_no_pinctrl; | 823 | for (i = 0; i < ARRAY_SIZE(coh901_pintable); i++) { |
824 | struct coh901_pinpair *p = &coh901_pintable[i]; | ||
825 | |||
826 | err = gpiochip_add_pin_range(&gpio->chip, "pinctrl-u300", | ||
827 | p->offset, p->pin_base, 1); | ||
828 | if (err) | ||
829 | goto err_no_range; | ||
830 | } | ||
771 | 831 | ||
772 | platform_set_drvdata(pdev, gpio); | 832 | platform_set_drvdata(pdev, gpio); |
773 | 833 | ||
774 | return 0; | 834 | return 0; |
775 | 835 | ||
776 | err_no_pinctrl: | 836 | err_no_range: |
777 | err = gpiochip_remove(&gpio->chip); | 837 | err = gpiochip_remove(&gpio->chip); |
778 | err_no_chip: | 838 | err_no_chip: |
839 | err_no_domain: | ||
779 | err_no_port: | 840 | err_no_port: |
780 | u300_gpio_free_ports(gpio); | 841 | u300_gpio_free_ports(gpio); |
781 | iounmap(gpio->base); | ||
782 | err_no_ioremap: | ||
783 | release_mem_region(gpio->memres->start, resource_size(gpio->memres)); | ||
784 | err_no_ioregion: | ||
785 | err_no_resource: | ||
786 | clk_disable_unprepare(gpio->clk); | 842 | clk_disable_unprepare(gpio->clk); |
787 | err_no_clk_enable: | 843 | dev_err(&pdev->dev, "module ERROR:%d\n", err); |
788 | clk_put(gpio->clk); | ||
789 | err_no_clk: | ||
790 | kfree(gpio); | ||
791 | dev_info(&pdev->dev, "module ERROR:%d\n", err); | ||
792 | return err; | 844 | return err; |
793 | } | 845 | } |
794 | 846 | ||
@@ -806,13 +858,8 @@ static int __exit u300_gpio_remove(struct platform_device *pdev) | |||
806 | return err; | 858 | return err; |
807 | } | 859 | } |
808 | u300_gpio_free_ports(gpio); | 860 | u300_gpio_free_ports(gpio); |
809 | iounmap(gpio->base); | ||
810 | release_mem_region(gpio->memres->start, | ||
811 | resource_size(gpio->memres)); | ||
812 | clk_disable_unprepare(gpio->clk); | 861 | clk_disable_unprepare(gpio->clk); |
813 | clk_put(gpio->clk); | ||
814 | platform_set_drvdata(pdev, NULL); | 862 | platform_set_drvdata(pdev, NULL); |
815 | kfree(gpio); | ||
816 | return 0; | 863 | return 0; |
817 | } | 864 | } |
818 | 865 | ||
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 21362f48d370..538b9ddaadf7 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c | |||
@@ -36,50 +36,51 @@ | |||
36 | /* list of external wakeup controllers supported */ | 36 | /* list of external wakeup controllers supported */ |
37 | static const struct of_device_id exynos_wkup_irq_ids[] = { | 37 | static const struct of_device_id exynos_wkup_irq_ids[] = { |
38 | { .compatible = "samsung,exynos4210-wakeup-eint", }, | 38 | { .compatible = "samsung,exynos4210-wakeup-eint", }, |
39 | { } | ||
39 | }; | 40 | }; |
40 | 41 | ||
41 | static void exynos_gpio_irq_unmask(struct irq_data *irqd) | 42 | static void exynos_gpio_irq_unmask(struct irq_data *irqd) |
42 | { | 43 | { |
43 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 44 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
44 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 45 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
45 | unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset; | 46 | unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; |
46 | unsigned long mask; | 47 | unsigned long mask; |
47 | 48 | ||
48 | mask = readl(d->virt_base + reg_mask); | 49 | mask = readl(d->virt_base + reg_mask); |
49 | mask &= ~(1 << edata->pin); | 50 | mask &= ~(1 << irqd->hwirq); |
50 | writel(mask, d->virt_base + reg_mask); | 51 | writel(mask, d->virt_base + reg_mask); |
51 | } | 52 | } |
52 | 53 | ||
53 | static void exynos_gpio_irq_mask(struct irq_data *irqd) | 54 | static void exynos_gpio_irq_mask(struct irq_data *irqd) |
54 | { | 55 | { |
55 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 56 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
56 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 57 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
57 | unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset; | 58 | unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; |
58 | unsigned long mask; | 59 | unsigned long mask; |
59 | 60 | ||
60 | mask = readl(d->virt_base + reg_mask); | 61 | mask = readl(d->virt_base + reg_mask); |
61 | mask |= 1 << edata->pin; | 62 | mask |= 1 << irqd->hwirq; |
62 | writel(mask, d->virt_base + reg_mask); | 63 | writel(mask, d->virt_base + reg_mask); |
63 | } | 64 | } |
64 | 65 | ||
65 | static void exynos_gpio_irq_ack(struct irq_data *irqd) | 66 | static void exynos_gpio_irq_ack(struct irq_data *irqd) |
66 | { | 67 | { |
67 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 68 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
68 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 69 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
69 | unsigned long reg_pend = d->ctrl->geint_pend + edata->eint_offset; | 70 | unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset; |
70 | 71 | ||
71 | writel(1 << edata->pin, d->virt_base + reg_pend); | 72 | writel(1 << irqd->hwirq, d->virt_base + reg_pend); |
72 | } | 73 | } |
73 | 74 | ||
74 | static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) | 75 | static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) |
75 | { | 76 | { |
76 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 77 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
78 | struct samsung_pinctrl_drv_data *d = bank->drvdata; | ||
77 | struct samsung_pin_ctrl *ctrl = d->ctrl; | 79 | struct samsung_pin_ctrl *ctrl = d->ctrl; |
78 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 80 | unsigned int pin = irqd->hwirq; |
79 | struct samsung_pin_bank *bank = edata->bank; | 81 | unsigned int shift = EXYNOS_EINT_CON_LEN * pin; |
80 | unsigned int shift = EXYNOS_EINT_CON_LEN * edata->pin; | ||
81 | unsigned int con, trig_type; | 82 | unsigned int con, trig_type; |
82 | unsigned long reg_con = ctrl->geint_con + edata->eint_offset; | 83 | unsigned long reg_con = ctrl->geint_con + bank->eint_offset; |
83 | unsigned int mask; | 84 | unsigned int mask; |
84 | 85 | ||
85 | switch (type) { | 86 | switch (type) { |
@@ -114,7 +115,7 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
114 | writel(con, d->virt_base + reg_con); | 115 | writel(con, d->virt_base + reg_con); |
115 | 116 | ||
116 | reg_con = bank->pctl_offset; | 117 | reg_con = bank->pctl_offset; |
117 | shift = edata->pin * bank->func_width; | 118 | shift = pin * bank->func_width; |
118 | mask = (1 << bank->func_width) - 1; | 119 | mask = (1 << bank->func_width) - 1; |
119 | 120 | ||
120 | con = readl(d->virt_base + reg_con); | 121 | con = readl(d->virt_base + reg_con); |
@@ -136,82 +137,23 @@ static struct irq_chip exynos_gpio_irq_chip = { | |||
136 | .irq_set_type = exynos_gpio_irq_set_type, | 137 | .irq_set_type = exynos_gpio_irq_set_type, |
137 | }; | 138 | }; |
138 | 139 | ||
139 | /* | ||
140 | * given a controller-local external gpio interrupt number, prepare the handler | ||
141 | * data for it. | ||
142 | */ | ||
143 | static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw, | ||
144 | struct samsung_pinctrl_drv_data *d) | ||
145 | { | ||
146 | struct samsung_pin_bank *bank = d->ctrl->pin_banks; | ||
147 | struct exynos_geint_data *eint_data; | ||
148 | unsigned int nr_banks = d->ctrl->nr_banks, idx; | ||
149 | unsigned int irq_base = 0, eint_offset = 0; | ||
150 | |||
151 | if (hw >= d->ctrl->nr_gint) { | ||
152 | dev_err(d->dev, "unsupported ext-gpio interrupt\n"); | ||
153 | return NULL; | ||
154 | } | ||
155 | |||
156 | for (idx = 0; idx < nr_banks; idx++, bank++) { | ||
157 | if (bank->eint_type != EINT_TYPE_GPIO) | ||
158 | continue; | ||
159 | if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins))) | ||
160 | break; | ||
161 | irq_base += bank->nr_pins; | ||
162 | eint_offset += 4; | ||
163 | } | ||
164 | |||
165 | if (idx == nr_banks) { | ||
166 | dev_err(d->dev, "pin bank not found for ext-gpio interrupt\n"); | ||
167 | return NULL; | ||
168 | } | ||
169 | |||
170 | eint_data = devm_kzalloc(d->dev, sizeof(*eint_data), GFP_KERNEL); | ||
171 | if (!eint_data) { | ||
172 | dev_err(d->dev, "no memory for eint-gpio data\n"); | ||
173 | return NULL; | ||
174 | } | ||
175 | |||
176 | eint_data->bank = bank; | ||
177 | eint_data->pin = hw - irq_base; | ||
178 | eint_data->eint_offset = eint_offset; | ||
179 | return eint_data; | ||
180 | } | ||
181 | |||
182 | static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, | 140 | static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, |
183 | irq_hw_number_t hw) | 141 | irq_hw_number_t hw) |
184 | { | 142 | { |
185 | struct samsung_pinctrl_drv_data *d = h->host_data; | 143 | struct samsung_pin_bank *b = h->host_data; |
186 | struct exynos_geint_data *eint_data; | ||
187 | |||
188 | eint_data = exynos_get_eint_data(hw, d); | ||
189 | if (!eint_data) | ||
190 | return -EINVAL; | ||
191 | 144 | ||
192 | irq_set_handler_data(virq, eint_data); | 145 | irq_set_chip_data(virq, b); |
193 | irq_set_chip_data(virq, h->host_data); | ||
194 | irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip, | 146 | irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip, |
195 | handle_level_irq); | 147 | handle_level_irq); |
196 | set_irq_flags(virq, IRQF_VALID); | 148 | set_irq_flags(virq, IRQF_VALID); |
197 | return 0; | 149 | return 0; |
198 | } | 150 | } |
199 | 151 | ||
200 | static void exynos_gpio_irq_unmap(struct irq_domain *h, unsigned int virq) | ||
201 | { | ||
202 | struct samsung_pinctrl_drv_data *d = h->host_data; | ||
203 | struct exynos_geint_data *eint_data; | ||
204 | |||
205 | eint_data = irq_get_handler_data(virq); | ||
206 | devm_kfree(d->dev, eint_data); | ||
207 | } | ||
208 | |||
209 | /* | 152 | /* |
210 | * irq domain callbacks for external gpio interrupt controller. | 153 | * irq domain callbacks for external gpio interrupt controller. |
211 | */ | 154 | */ |
212 | static const struct irq_domain_ops exynos_gpio_irqd_ops = { | 155 | static const struct irq_domain_ops exynos_gpio_irqd_ops = { |
213 | .map = exynos_gpio_irq_map, | 156 | .map = exynos_gpio_irq_map, |
214 | .unmap = exynos_gpio_irq_unmap, | ||
215 | .xlate = irq_domain_xlate_twocell, | 157 | .xlate = irq_domain_xlate_twocell, |
216 | }; | 158 | }; |
217 | 159 | ||
@@ -230,7 +172,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) | |||
230 | return IRQ_HANDLED; | 172 | return IRQ_HANDLED; |
231 | bank += (group - 1); | 173 | bank += (group - 1); |
232 | 174 | ||
233 | virq = irq_linear_revmap(d->gpio_irqd, bank->irq_base + pin); | 175 | virq = irq_linear_revmap(bank->irq_domain, pin); |
234 | if (!virq) | 176 | if (!virq) |
235 | return IRQ_NONE; | 177 | return IRQ_NONE; |
236 | generic_handle_irq(virq); | 178 | generic_handle_irq(virq); |
@@ -243,8 +185,10 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) | |||
243 | */ | 185 | */ |
244 | static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | 186 | static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) |
245 | { | 187 | { |
188 | struct samsung_pin_bank *bank; | ||
246 | struct device *dev = d->dev; | 189 | struct device *dev = d->dev; |
247 | unsigned int ret; | 190 | unsigned int ret; |
191 | unsigned int i; | ||
248 | 192 | ||
249 | if (!d->irq) { | 193 | if (!d->irq) { |
250 | dev_err(dev, "irq number not available\n"); | 194 | dev_err(dev, "irq number not available\n"); |
@@ -258,11 +202,16 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
258 | return -ENXIO; | 202 | return -ENXIO; |
259 | } | 203 | } |
260 | 204 | ||
261 | d->gpio_irqd = irq_domain_add_linear(dev->of_node, d->ctrl->nr_gint, | 205 | bank = d->ctrl->pin_banks; |
262 | &exynos_gpio_irqd_ops, d); | 206 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { |
263 | if (!d->gpio_irqd) { | 207 | if (bank->eint_type != EINT_TYPE_GPIO) |
264 | dev_err(dev, "gpio irq domain allocation failed\n"); | 208 | continue; |
265 | return -ENXIO; | 209 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
210 | bank->nr_pins, &exynos_gpio_irqd_ops, bank); | ||
211 | if (!bank->irq_domain) { | ||
212 | dev_err(dev, "gpio irq domain add failed\n"); | ||
213 | return -ENXIO; | ||
214 | } | ||
266 | } | 215 | } |
267 | 216 | ||
268 | return 0; | 217 | return 0; |
@@ -270,48 +219,46 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
270 | 219 | ||
271 | static void exynos_wkup_irq_unmask(struct irq_data *irqd) | 220 | static void exynos_wkup_irq_unmask(struct irq_data *irqd) |
272 | { | 221 | { |
273 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 222 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
274 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 223 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
275 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 224 | unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; |
276 | unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2); | ||
277 | unsigned long mask; | 225 | unsigned long mask; |
278 | 226 | ||
279 | mask = readl(d->virt_base + reg_mask); | 227 | mask = readl(d->virt_base + reg_mask); |
280 | mask &= ~(1 << pin); | 228 | mask &= ~(1 << irqd->hwirq); |
281 | writel(mask, d->virt_base + reg_mask); | 229 | writel(mask, d->virt_base + reg_mask); |
282 | } | 230 | } |
283 | 231 | ||
284 | static void exynos_wkup_irq_mask(struct irq_data *irqd) | 232 | static void exynos_wkup_irq_mask(struct irq_data *irqd) |
285 | { | 233 | { |
286 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 234 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
287 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 235 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
288 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 236 | unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; |
289 | unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2); | ||
290 | unsigned long mask; | 237 | unsigned long mask; |
291 | 238 | ||
292 | mask = readl(d->virt_base + reg_mask); | 239 | mask = readl(d->virt_base + reg_mask); |
293 | mask |= 1 << pin; | 240 | mask |= 1 << irqd->hwirq; |
294 | writel(mask, d->virt_base + reg_mask); | 241 | writel(mask, d->virt_base + reg_mask); |
295 | } | 242 | } |
296 | 243 | ||
297 | static void exynos_wkup_irq_ack(struct irq_data *irqd) | 244 | static void exynos_wkup_irq_ack(struct irq_data *irqd) |
298 | { | 245 | { |
299 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 246 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
300 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 247 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
301 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 248 | unsigned long pend = d->ctrl->weint_pend + b->eint_offset; |
302 | unsigned long pend = d->ctrl->weint_pend + (bank << 2); | ||
303 | 249 | ||
304 | writel(1 << pin, d->virt_base + pend); | 250 | writel(1 << irqd->hwirq, d->virt_base + pend); |
305 | } | 251 | } |
306 | 252 | ||
307 | static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) | 253 | static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) |
308 | { | 254 | { |
309 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 255 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
310 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 256 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
311 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 257 | unsigned int pin = irqd->hwirq; |
312 | unsigned long reg_con = d->ctrl->weint_con + (bank << 2); | 258 | unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset; |
313 | unsigned long shift = EXYNOS_EINT_CON_LEN * pin; | 259 | unsigned long shift = EXYNOS_EINT_CON_LEN * pin; |
314 | unsigned long con, trig_type; | 260 | unsigned long con, trig_type; |
261 | unsigned int mask; | ||
315 | 262 | ||
316 | switch (type) { | 263 | switch (type) { |
317 | case IRQ_TYPE_EDGE_RISING: | 264 | case IRQ_TYPE_EDGE_RISING: |
@@ -343,6 +290,16 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
343 | con &= ~(EXYNOS_EINT_CON_MASK << shift); | 290 | con &= ~(EXYNOS_EINT_CON_MASK << shift); |
344 | con |= trig_type << shift; | 291 | con |= trig_type << shift; |
345 | writel(con, d->virt_base + reg_con); | 292 | writel(con, d->virt_base + reg_con); |
293 | |||
294 | reg_con = bank->pctl_offset; | ||
295 | shift = pin * bank->func_width; | ||
296 | mask = (1 << bank->func_width) - 1; | ||
297 | |||
298 | con = readl(d->virt_base + reg_con); | ||
299 | con &= ~(mask << shift); | ||
300 | con |= EXYNOS_EINT_FUNC << shift; | ||
301 | writel(con, d->virt_base + reg_con); | ||
302 | |||
346 | return 0; | 303 | return 0; |
347 | } | 304 | } |
348 | 305 | ||
@@ -361,6 +318,7 @@ static struct irq_chip exynos_wkup_irq_chip = { | |||
361 | static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | 318 | static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) |
362 | { | 319 | { |
363 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); | 320 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); |
321 | struct samsung_pin_bank *bank = eintd->bank; | ||
364 | struct irq_chip *chip = irq_get_chip(irq); | 322 | struct irq_chip *chip = irq_get_chip(irq); |
365 | int eint_irq; | 323 | int eint_irq; |
366 | 324 | ||
@@ -370,20 +328,20 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | |||
370 | if (chip->irq_ack) | 328 | if (chip->irq_ack) |
371 | chip->irq_ack(&desc->irq_data); | 329 | chip->irq_ack(&desc->irq_data); |
372 | 330 | ||
373 | eint_irq = irq_linear_revmap(eintd->domain, eintd->irq); | 331 | eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq); |
374 | generic_handle_irq(eint_irq); | 332 | generic_handle_irq(eint_irq); |
375 | chip->irq_unmask(&desc->irq_data); | 333 | chip->irq_unmask(&desc->irq_data); |
376 | chained_irq_exit(chip, desc); | 334 | chained_irq_exit(chip, desc); |
377 | } | 335 | } |
378 | 336 | ||
379 | static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend, | 337 | static inline void exynos_irq_demux_eint(unsigned long pend, |
380 | struct irq_domain *domain) | 338 | struct irq_domain *domain) |
381 | { | 339 | { |
382 | unsigned int irq; | 340 | unsigned int irq; |
383 | 341 | ||
384 | while (pend) { | 342 | while (pend) { |
385 | irq = fls(pend) - 1; | 343 | irq = fls(pend) - 1; |
386 | generic_handle_irq(irq_find_mapping(domain, irq_base + irq)); | 344 | generic_handle_irq(irq_find_mapping(domain, irq)); |
387 | pend &= ~(1 << irq); | 345 | pend &= ~(1 << irq); |
388 | } | 346 | } |
389 | } | 347 | } |
@@ -392,18 +350,22 @@ static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend, | |||
392 | static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | 350 | static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) |
393 | { | 351 | { |
394 | struct irq_chip *chip = irq_get_chip(irq); | 352 | struct irq_chip *chip = irq_get_chip(irq); |
395 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); | 353 | struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq); |
396 | struct samsung_pinctrl_drv_data *d = eintd->domain->host_data; | 354 | struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata; |
355 | struct samsung_pin_ctrl *ctrl = d->ctrl; | ||
397 | unsigned long pend; | 356 | unsigned long pend; |
398 | unsigned long mask; | 357 | unsigned long mask; |
358 | int i; | ||
399 | 359 | ||
400 | chained_irq_enter(chip, desc); | 360 | chained_irq_enter(chip, desc); |
401 | pend = readl(d->virt_base + d->ctrl->weint_pend + 0x8); | 361 | |
402 | mask = readl(d->virt_base + d->ctrl->weint_mask + 0x8); | 362 | for (i = 0; i < eintd->nr_banks; ++i) { |
403 | exynos_irq_demux_eint(16, pend & ~mask, eintd->domain); | 363 | struct samsung_pin_bank *b = eintd->banks[i]; |
404 | pend = readl(d->virt_base + d->ctrl->weint_pend + 0xC); | 364 | pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset); |
405 | mask = readl(d->virt_base + d->ctrl->weint_mask + 0xC); | 365 | mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset); |
406 | exynos_irq_demux_eint(24, pend & ~mask, eintd->domain); | 366 | exynos_irq_demux_eint(pend & ~mask, b->irq_domain); |
367 | } | ||
368 | |||
407 | chained_irq_exit(chip, desc); | 369 | chained_irq_exit(chip, desc); |
408 | } | 370 | } |
409 | 371 | ||
@@ -433,7 +395,11 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
433 | struct device *dev = d->dev; | 395 | struct device *dev = d->dev; |
434 | struct device_node *wkup_np = NULL; | 396 | struct device_node *wkup_np = NULL; |
435 | struct device_node *np; | 397 | struct device_node *np; |
398 | struct samsung_pin_bank *bank; | ||
436 | struct exynos_weint_data *weint_data; | 399 | struct exynos_weint_data *weint_data; |
400 | struct exynos_muxed_weint_data *muxed_data; | ||
401 | unsigned int muxed_banks = 0; | ||
402 | unsigned int i; | ||
437 | int idx, irq; | 403 | int idx, irq; |
438 | 404 | ||
439 | for_each_child_of_node(dev->of_node, np) { | 405 | for_each_child_of_node(dev->of_node, np) { |
@@ -445,90 +411,124 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
445 | if (!wkup_np) | 411 | if (!wkup_np) |
446 | return -ENODEV; | 412 | return -ENODEV; |
447 | 413 | ||
448 | d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint, | 414 | bank = d->ctrl->pin_banks; |
449 | &exynos_wkup_irqd_ops, d); | 415 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { |
450 | if (!d->wkup_irqd) { | 416 | if (bank->eint_type != EINT_TYPE_WKUP) |
451 | dev_err(dev, "wakeup irq domain allocation failed\n"); | 417 | continue; |
452 | return -ENXIO; | ||
453 | } | ||
454 | 418 | ||
455 | weint_data = devm_kzalloc(dev, sizeof(*weint_data) * 17, GFP_KERNEL); | 419 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
456 | if (!weint_data) { | 420 | bank->nr_pins, &exynos_wkup_irqd_ops, bank); |
457 | dev_err(dev, "could not allocate memory for weint_data\n"); | 421 | if (!bank->irq_domain) { |
458 | return -ENOMEM; | 422 | dev_err(dev, "wkup irq domain add failed\n"); |
459 | } | 423 | return -ENXIO; |
424 | } | ||
460 | 425 | ||
461 | irq = irq_of_parse_and_map(wkup_np, 16); | 426 | if (!of_find_property(bank->of_node, "interrupts", NULL)) { |
462 | if (irq) { | 427 | bank->eint_type = EINT_TYPE_WKUP_MUX; |
463 | weint_data[16].domain = d->wkup_irqd; | 428 | ++muxed_banks; |
464 | irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); | 429 | continue; |
465 | irq_set_handler_data(irq, &weint_data[16]); | 430 | } |
466 | } else { | ||
467 | dev_err(dev, "irq number for EINT16-32 not found\n"); | ||
468 | } | ||
469 | 431 | ||
470 | for (idx = 0; idx < 16; idx++) { | 432 | weint_data = devm_kzalloc(dev, bank->nr_pins |
471 | weint_data[idx].domain = d->wkup_irqd; | 433 | * sizeof(*weint_data), GFP_KERNEL); |
472 | weint_data[idx].irq = idx; | 434 | if (!weint_data) { |
435 | dev_err(dev, "could not allocate memory for weint_data\n"); | ||
436 | return -ENOMEM; | ||
437 | } | ||
473 | 438 | ||
474 | irq = irq_of_parse_and_map(wkup_np, idx); | 439 | for (idx = 0; idx < bank->nr_pins; ++idx) { |
475 | if (irq) { | 440 | irq = irq_of_parse_and_map(bank->of_node, idx); |
441 | if (!irq) { | ||
442 | dev_err(dev, "irq number for eint-%s-%d not found\n", | ||
443 | bank->name, idx); | ||
444 | continue; | ||
445 | } | ||
446 | weint_data[idx].irq = idx; | ||
447 | weint_data[idx].bank = bank; | ||
476 | irq_set_handler_data(irq, &weint_data[idx]); | 448 | irq_set_handler_data(irq, &weint_data[idx]); |
477 | irq_set_chained_handler(irq, exynos_irq_eint0_15); | 449 | irq_set_chained_handler(irq, exynos_irq_eint0_15); |
478 | } else { | ||
479 | dev_err(dev, "irq number for eint-%x not found\n", idx); | ||
480 | } | 450 | } |
481 | } | 451 | } |
452 | |||
453 | if (!muxed_banks) | ||
454 | return 0; | ||
455 | |||
456 | irq = irq_of_parse_and_map(wkup_np, 0); | ||
457 | if (!irq) { | ||
458 | dev_err(dev, "irq number for muxed EINTs not found\n"); | ||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | muxed_data = devm_kzalloc(dev, sizeof(*muxed_data) | ||
463 | + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL); | ||
464 | if (!muxed_data) { | ||
465 | dev_err(dev, "could not allocate memory for muxed_data\n"); | ||
466 | return -ENOMEM; | ||
467 | } | ||
468 | |||
469 | irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); | ||
470 | irq_set_handler_data(irq, muxed_data); | ||
471 | |||
472 | bank = d->ctrl->pin_banks; | ||
473 | idx = 0; | ||
474 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | ||
475 | if (bank->eint_type != EINT_TYPE_WKUP_MUX) | ||
476 | continue; | ||
477 | |||
478 | muxed_data->banks[idx++] = bank; | ||
479 | } | ||
480 | muxed_data->nr_banks = muxed_banks; | ||
481 | |||
482 | return 0; | 482 | return 0; |
483 | } | 483 | } |
484 | 484 | ||
485 | /* pin banks of exynos4210 pin-controller 0 */ | 485 | /* pin banks of exynos4210 pin-controller 0 */ |
486 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { | 486 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { |
487 | EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_A0, "gpa0"), | 487 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
488 | EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_A1, "gpa1"), | 488 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), |
489 | EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_B, "gpb"), | 489 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), |
490 | EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_C0, "gpc0"), | 490 | EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c), |
491 | EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_C1, "gpc1"), | 491 | EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10), |
492 | EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_D0, "gpd0"), | 492 | EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14), |
493 | EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_D1, "gpd1"), | 493 | EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18), |
494 | EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_E0, "gpe0"), | 494 | EXYNOS_PIN_BANK_EINTG(5, 0x0E0, "gpe0", 0x1c), |
495 | EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_E1, "gpe1"), | 495 | EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpe1", 0x20), |
496 | EXYNOS_PIN_BANK_EINTG(0x120, EXYNOS4210_GPIO_E2, "gpe2"), | 496 | EXYNOS_PIN_BANK_EINTG(6, 0x120, "gpe2", 0x24), |
497 | EXYNOS_PIN_BANK_EINTG(0x140, EXYNOS4210_GPIO_E3, "gpe3"), | 497 | EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpe3", 0x28), |
498 | EXYNOS_PIN_BANK_EINTG(0x160, EXYNOS4210_GPIO_E4, "gpe4"), | 498 | EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpe4", 0x2c), |
499 | EXYNOS_PIN_BANK_EINTG(0x180, EXYNOS4210_GPIO_F0, "gpf0"), | 499 | EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30), |
500 | EXYNOS_PIN_BANK_EINTG(0x1A0, EXYNOS4210_GPIO_F1, "gpf1"), | 500 | EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34), |
501 | EXYNOS_PIN_BANK_EINTG(0x1C0, EXYNOS4210_GPIO_F2, "gpf2"), | 501 | EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38), |
502 | EXYNOS_PIN_BANK_EINTG(0x1E0, EXYNOS4210_GPIO_F3, "gpf3"), | 502 | EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c), |
503 | }; | 503 | }; |
504 | 504 | ||
505 | /* pin banks of exynos4210 pin-controller 1 */ | 505 | /* pin banks of exynos4210 pin-controller 1 */ |
506 | static struct samsung_pin_bank exynos4210_pin_banks1[] = { | 506 | static struct samsung_pin_bank exynos4210_pin_banks1[] = { |
507 | EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_J0, "gpj0"), | 507 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00), |
508 | EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_J1, "gpj1"), | 508 | EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04), |
509 | EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_K0, "gpk0"), | 509 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), |
510 | EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_K1, "gpk1"), | 510 | EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), |
511 | EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_K2, "gpk2"), | 511 | EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), |
512 | EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_K3, "gpk3"), | 512 | EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14), |
513 | EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_L0, "gpl0"), | 513 | EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpl0", 0x18), |
514 | EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_L1, "gpl1"), | 514 | EXYNOS_PIN_BANK_EINTG(3, 0x0E0, "gpl1", 0x1c), |
515 | EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_L2, "gpl2"), | 515 | EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20), |
516 | EXYNOS_PIN_BANK_EINTN(0x120, EXYNOS4210_GPIO_Y0, "gpy0"), | 516 | EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"), |
517 | EXYNOS_PIN_BANK_EINTN(0x140, EXYNOS4210_GPIO_Y1, "gpy1"), | 517 | EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"), |
518 | EXYNOS_PIN_BANK_EINTN(0x160, EXYNOS4210_GPIO_Y2, "gpy2"), | 518 | EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"), |
519 | EXYNOS_PIN_BANK_EINTN(0x180, EXYNOS4210_GPIO_Y3, "gpy3"), | 519 | EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"), |
520 | EXYNOS_PIN_BANK_EINTN(0x1A0, EXYNOS4210_GPIO_Y4, "gpy4"), | 520 | EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"), |
521 | EXYNOS_PIN_BANK_EINTN(0x1C0, EXYNOS4210_GPIO_Y5, "gpy5"), | 521 | EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"), |
522 | EXYNOS_PIN_BANK_EINTN(0x1E0, EXYNOS4210_GPIO_Y6, "gpy6"), | 522 | EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"), |
523 | EXYNOS_PIN_BANK_EINTN(0xC00, EXYNOS4210_GPIO_X0, "gpx0"), | 523 | EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), |
524 | EXYNOS_PIN_BANK_EINTN(0xC20, EXYNOS4210_GPIO_X1, "gpx1"), | 524 | EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), |
525 | EXYNOS_PIN_BANK_EINTN(0xC40, EXYNOS4210_GPIO_X2, "gpx2"), | 525 | EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), |
526 | EXYNOS_PIN_BANK_EINTN(0xC60, EXYNOS4210_GPIO_X3, "gpx3"), | 526 | EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), |
527 | }; | 527 | }; |
528 | 528 | ||
529 | /* pin banks of exynos4210 pin-controller 2 */ | 529 | /* pin banks of exynos4210 pin-controller 2 */ |
530 | static struct samsung_pin_bank exynos4210_pin_banks2[] = { | 530 | static struct samsung_pin_bank exynos4210_pin_banks2[] = { |
531 | EXYNOS_PIN_BANK_EINTN(0x000, EXYNOS4210_GPIO_Z, "gpz"), | 531 | EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"), |
532 | }; | 532 | }; |
533 | 533 | ||
534 | /* | 534 | /* |
@@ -540,9 +540,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
540 | /* pin-controller instance 0 data */ | 540 | /* pin-controller instance 0 data */ |
541 | .pin_banks = exynos4210_pin_banks0, | 541 | .pin_banks = exynos4210_pin_banks0, |
542 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0), | 542 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0), |
543 | .base = EXYNOS4210_GPIO_A0_START, | ||
544 | .nr_pins = EXYNOS4210_GPIOA_NR_PINS, | ||
545 | .nr_gint = EXYNOS4210_GPIOA_NR_GINT, | ||
546 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | 543 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, |
547 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | 544 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, |
548 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 545 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
@@ -553,10 +550,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
553 | /* pin-controller instance 1 data */ | 550 | /* pin-controller instance 1 data */ |
554 | .pin_banks = exynos4210_pin_banks1, | 551 | .pin_banks = exynos4210_pin_banks1, |
555 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1), | 552 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1), |
556 | .base = EXYNOS4210_GPIOA_NR_PINS, | ||
557 | .nr_pins = EXYNOS4210_GPIOB_NR_PINS, | ||
558 | .nr_gint = EXYNOS4210_GPIOB_NR_GINT, | ||
559 | .nr_wint = 32, | ||
560 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | 553 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, |
561 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | 554 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, |
562 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 555 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
@@ -571,9 +564,116 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
571 | /* pin-controller instance 2 data */ | 564 | /* pin-controller instance 2 data */ |
572 | .pin_banks = exynos4210_pin_banks2, | 565 | .pin_banks = exynos4210_pin_banks2, |
573 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), | 566 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), |
574 | .base = EXYNOS4210_GPIOA_NR_PINS + | ||
575 | EXYNOS4210_GPIOB_NR_PINS, | ||
576 | .nr_pins = EXYNOS4210_GPIOC_NR_PINS, | ||
577 | .label = "exynos4210-gpio-ctrl2", | 567 | .label = "exynos4210-gpio-ctrl2", |
578 | }, | 568 | }, |
579 | }; | 569 | }; |
570 | |||
571 | /* pin banks of exynos4x12 pin-controller 0 */ | ||
572 | static struct samsung_pin_bank exynos4x12_pin_banks0[] = { | ||
573 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | ||
574 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), | ||
575 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), | ||
576 | EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c), | ||
577 | EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10), | ||
578 | EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14), | ||
579 | EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18), | ||
580 | EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30), | ||
581 | EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34), | ||
582 | EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38), | ||
583 | EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c), | ||
584 | EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x40), | ||
585 | EXYNOS_PIN_BANK_EINTG(5, 0x260, "gpj1", 0x44), | ||
586 | }; | ||
587 | |||
588 | /* pin banks of exynos4x12 pin-controller 1 */ | ||
589 | static struct samsung_pin_bank exynos4x12_pin_banks1[] = { | ||
590 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), | ||
591 | EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), | ||
592 | EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), | ||
593 | EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14), | ||
594 | EXYNOS_PIN_BANK_EINTG(7, 0x0C0, "gpl0", 0x18), | ||
595 | EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpl1", 0x1c), | ||
596 | EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20), | ||
597 | EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24), | ||
598 | EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28), | ||
599 | EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c), | ||
600 | EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30), | ||
601 | EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34), | ||
602 | EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"), | ||
603 | EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"), | ||
604 | EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"), | ||
605 | EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"), | ||
606 | EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"), | ||
607 | EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"), | ||
608 | EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"), | ||
609 | EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), | ||
610 | EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), | ||
611 | EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), | ||
612 | EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), | ||
613 | }; | ||
614 | |||
615 | /* pin banks of exynos4x12 pin-controller 2 */ | ||
616 | static struct samsung_pin_bank exynos4x12_pin_banks2[] = { | ||
617 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), | ||
618 | }; | ||
619 | |||
620 | /* pin banks of exynos4x12 pin-controller 3 */ | ||
621 | static struct samsung_pin_bank exynos4x12_pin_banks3[] = { | ||
622 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), | ||
623 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), | ||
624 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08), | ||
625 | EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv3", 0x0c), | ||
626 | EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpv4", 0x10), | ||
627 | }; | ||
628 | |||
629 | /* | ||
630 | * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes | ||
631 | * four gpio/pin-mux/pinconfig controllers. | ||
632 | */ | ||
633 | struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | ||
634 | { | ||
635 | /* pin-controller instance 0 data */ | ||
636 | .pin_banks = exynos4x12_pin_banks0, | ||
637 | .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks0), | ||
638 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | ||
639 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | ||
640 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | ||
641 | .svc = EXYNOS_SVC_OFFSET, | ||
642 | .eint_gpio_init = exynos_eint_gpio_init, | ||
643 | .label = "exynos4x12-gpio-ctrl0", | ||
644 | }, { | ||
645 | /* pin-controller instance 1 data */ | ||
646 | .pin_banks = exynos4x12_pin_banks1, | ||
647 | .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks1), | ||
648 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | ||
649 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | ||
650 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | ||
651 | .weint_con = EXYNOS_WKUP_ECON_OFFSET, | ||
652 | .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, | ||
653 | .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, | ||
654 | .svc = EXYNOS_SVC_OFFSET, | ||
655 | .eint_gpio_init = exynos_eint_gpio_init, | ||
656 | .eint_wkup_init = exynos_eint_wkup_init, | ||
657 | .label = "exynos4x12-gpio-ctrl1", | ||
658 | }, { | ||
659 | /* pin-controller instance 2 data */ | ||
660 | .pin_banks = exynos4x12_pin_banks2, | ||
661 | .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks2), | ||
662 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | ||
663 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | ||
664 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | ||
665 | .svc = EXYNOS_SVC_OFFSET, | ||
666 | .eint_gpio_init = exynos_eint_gpio_init, | ||
667 | .label = "exynos4x12-gpio-ctrl2", | ||
668 | }, { | ||
669 | /* pin-controller instance 3 data */ | ||
670 | .pin_banks = exynos4x12_pin_banks3, | ||
671 | .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks3), | ||
672 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | ||
673 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | ||
674 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | ||
675 | .svc = EXYNOS_SVC_OFFSET, | ||
676 | .eint_gpio_init = exynos_eint_gpio_init, | ||
677 | .label = "exynos4x12-gpio-ctrl3", | ||
678 | }, | ||
679 | }; | ||
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h index 31d0a06174e4..0a708890d8b4 100644 --- a/drivers/pinctrl/pinctrl-exynos.h +++ b/drivers/pinctrl/pinctrl-exynos.h | |||
@@ -17,125 +17,6 @@ | |||
17 | * (at your option) any later version. | 17 | * (at your option) any later version. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define EXYNOS_GPIO_START(__gpio) ((__gpio##_START) + (__gpio##_NR)) | ||
21 | |||
22 | #define EXYNOS4210_GPIO_A0_NR (8) | ||
23 | #define EXYNOS4210_GPIO_A1_NR (6) | ||
24 | #define EXYNOS4210_GPIO_B_NR (8) | ||
25 | #define EXYNOS4210_GPIO_C0_NR (5) | ||
26 | #define EXYNOS4210_GPIO_C1_NR (5) | ||
27 | #define EXYNOS4210_GPIO_D0_NR (4) | ||
28 | #define EXYNOS4210_GPIO_D1_NR (4) | ||
29 | #define EXYNOS4210_GPIO_E0_NR (5) | ||
30 | #define EXYNOS4210_GPIO_E1_NR (8) | ||
31 | #define EXYNOS4210_GPIO_E2_NR (6) | ||
32 | #define EXYNOS4210_GPIO_E3_NR (8) | ||
33 | #define EXYNOS4210_GPIO_E4_NR (8) | ||
34 | #define EXYNOS4210_GPIO_F0_NR (8) | ||
35 | #define EXYNOS4210_GPIO_F1_NR (8) | ||
36 | #define EXYNOS4210_GPIO_F2_NR (8) | ||
37 | #define EXYNOS4210_GPIO_F3_NR (6) | ||
38 | #define EXYNOS4210_GPIO_J0_NR (8) | ||
39 | #define EXYNOS4210_GPIO_J1_NR (5) | ||
40 | #define EXYNOS4210_GPIO_K0_NR (7) | ||
41 | #define EXYNOS4210_GPIO_K1_NR (7) | ||
42 | #define EXYNOS4210_GPIO_K2_NR (7) | ||
43 | #define EXYNOS4210_GPIO_K3_NR (7) | ||
44 | #define EXYNOS4210_GPIO_L0_NR (8) | ||
45 | #define EXYNOS4210_GPIO_L1_NR (3) | ||
46 | #define EXYNOS4210_GPIO_L2_NR (8) | ||
47 | #define EXYNOS4210_GPIO_Y0_NR (6) | ||
48 | #define EXYNOS4210_GPIO_Y1_NR (4) | ||
49 | #define EXYNOS4210_GPIO_Y2_NR (6) | ||
50 | #define EXYNOS4210_GPIO_Y3_NR (8) | ||
51 | #define EXYNOS4210_GPIO_Y4_NR (8) | ||
52 | #define EXYNOS4210_GPIO_Y5_NR (8) | ||
53 | #define EXYNOS4210_GPIO_Y6_NR (8) | ||
54 | #define EXYNOS4210_GPIO_X0_NR (8) | ||
55 | #define EXYNOS4210_GPIO_X1_NR (8) | ||
56 | #define EXYNOS4210_GPIO_X2_NR (8) | ||
57 | #define EXYNOS4210_GPIO_X3_NR (8) | ||
58 | #define EXYNOS4210_GPIO_Z_NR (7) | ||
59 | |||
60 | enum exynos4210_gpio_xa_start { | ||
61 | EXYNOS4210_GPIO_A0_START = 0, | ||
62 | EXYNOS4210_GPIO_A1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_A0), | ||
63 | EXYNOS4210_GPIO_B_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_A1), | ||
64 | EXYNOS4210_GPIO_C0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_B), | ||
65 | EXYNOS4210_GPIO_C1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_C0), | ||
66 | EXYNOS4210_GPIO_D0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_C1), | ||
67 | EXYNOS4210_GPIO_D1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_D0), | ||
68 | EXYNOS4210_GPIO_E0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_D1), | ||
69 | EXYNOS4210_GPIO_E1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E0), | ||
70 | EXYNOS4210_GPIO_E2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E1), | ||
71 | EXYNOS4210_GPIO_E3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E2), | ||
72 | EXYNOS4210_GPIO_E4_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E3), | ||
73 | EXYNOS4210_GPIO_F0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E4), | ||
74 | EXYNOS4210_GPIO_F1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F0), | ||
75 | EXYNOS4210_GPIO_F2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F1), | ||
76 | EXYNOS4210_GPIO_F3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F2), | ||
77 | }; | ||
78 | |||
79 | enum exynos4210_gpio_xb_start { | ||
80 | EXYNOS4210_GPIO_J0_START = 0, | ||
81 | EXYNOS4210_GPIO_J1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_J0), | ||
82 | EXYNOS4210_GPIO_K0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_J1), | ||
83 | EXYNOS4210_GPIO_K1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K0), | ||
84 | EXYNOS4210_GPIO_K2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K1), | ||
85 | EXYNOS4210_GPIO_K3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K2), | ||
86 | EXYNOS4210_GPIO_L0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K3), | ||
87 | EXYNOS4210_GPIO_L1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L0), | ||
88 | EXYNOS4210_GPIO_L2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L1), | ||
89 | EXYNOS4210_GPIO_Y0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2), | ||
90 | EXYNOS4210_GPIO_Y1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y0), | ||
91 | EXYNOS4210_GPIO_Y2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y1), | ||
92 | EXYNOS4210_GPIO_Y3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y2), | ||
93 | EXYNOS4210_GPIO_Y4_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y3), | ||
94 | EXYNOS4210_GPIO_Y5_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y4), | ||
95 | EXYNOS4210_GPIO_Y6_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y5), | ||
96 | EXYNOS4210_GPIO_X0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y6), | ||
97 | EXYNOS4210_GPIO_X1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X0), | ||
98 | EXYNOS4210_GPIO_X2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X1), | ||
99 | EXYNOS4210_GPIO_X3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X2), | ||
100 | }; | ||
101 | |||
102 | enum exynos4210_gpio_xc_start { | ||
103 | EXYNOS4210_GPIO_Z_START = 0, | ||
104 | }; | ||
105 | |||
106 | #define EXYNOS4210_GPIO_A0_IRQ EXYNOS4210_GPIO_A0_START | ||
107 | #define EXYNOS4210_GPIO_A1_IRQ EXYNOS4210_GPIO_A1_START | ||
108 | #define EXYNOS4210_GPIO_B_IRQ EXYNOS4210_GPIO_B_START | ||
109 | #define EXYNOS4210_GPIO_C0_IRQ EXYNOS4210_GPIO_C0_START | ||
110 | #define EXYNOS4210_GPIO_C1_IRQ EXYNOS4210_GPIO_C1_START | ||
111 | #define EXYNOS4210_GPIO_D0_IRQ EXYNOS4210_GPIO_D0_START | ||
112 | #define EXYNOS4210_GPIO_D1_IRQ EXYNOS4210_GPIO_D1_START | ||
113 | #define EXYNOS4210_GPIO_E0_IRQ EXYNOS4210_GPIO_E0_START | ||
114 | #define EXYNOS4210_GPIO_E1_IRQ EXYNOS4210_GPIO_E1_START | ||
115 | #define EXYNOS4210_GPIO_E2_IRQ EXYNOS4210_GPIO_E2_START | ||
116 | #define EXYNOS4210_GPIO_E3_IRQ EXYNOS4210_GPIO_E3_START | ||
117 | #define EXYNOS4210_GPIO_E4_IRQ EXYNOS4210_GPIO_E4_START | ||
118 | #define EXYNOS4210_GPIO_F0_IRQ EXYNOS4210_GPIO_F0_START | ||
119 | #define EXYNOS4210_GPIO_F1_IRQ EXYNOS4210_GPIO_F1_START | ||
120 | #define EXYNOS4210_GPIO_F2_IRQ EXYNOS4210_GPIO_F2_START | ||
121 | #define EXYNOS4210_GPIO_F3_IRQ EXYNOS4210_GPIO_F3_START | ||
122 | #define EXYNOS4210_GPIO_J0_IRQ EXYNOS4210_GPIO_J0_START | ||
123 | #define EXYNOS4210_GPIO_J1_IRQ EXYNOS4210_GPIO_J1_START | ||
124 | #define EXYNOS4210_GPIO_K0_IRQ EXYNOS4210_GPIO_K0_START | ||
125 | #define EXYNOS4210_GPIO_K1_IRQ EXYNOS4210_GPIO_K1_START | ||
126 | #define EXYNOS4210_GPIO_K2_IRQ EXYNOS4210_GPIO_K2_START | ||
127 | #define EXYNOS4210_GPIO_K3_IRQ EXYNOS4210_GPIO_K3_START | ||
128 | #define EXYNOS4210_GPIO_L0_IRQ EXYNOS4210_GPIO_L0_START | ||
129 | #define EXYNOS4210_GPIO_L1_IRQ EXYNOS4210_GPIO_L1_START | ||
130 | #define EXYNOS4210_GPIO_L2_IRQ EXYNOS4210_GPIO_L2_START | ||
131 | #define EXYNOS4210_GPIO_Z_IRQ EXYNOS4210_GPIO_Z_START | ||
132 | |||
133 | #define EXYNOS4210_GPIOA_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3) | ||
134 | #define EXYNOS4210_GPIOA_NR_GINT EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3) | ||
135 | #define EXYNOS4210_GPIOB_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_X3) | ||
136 | #define EXYNOS4210_GPIOB_NR_GINT EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2) | ||
137 | #define EXYNOS4210_GPIOC_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_Z) | ||
138 | |||
139 | /* External GPIO and wakeup interrupt related definitions */ | 20 | /* External GPIO and wakeup interrupt related definitions */ |
140 | #define EXYNOS_GPIO_ECON_OFFSET 0x700 | 21 | #define EXYNOS_GPIO_ECON_OFFSET 0x700 |
141 | #define EXYNOS_GPIO_EMASK_OFFSET 0x900 | 22 | #define EXYNOS_GPIO_EMASK_OFFSET 0x900 |
@@ -165,11 +46,10 @@ enum exynos4210_gpio_xc_start { | |||
165 | #define EXYNOS_EINT_MAX_PER_BANK 8 | 46 | #define EXYNOS_EINT_MAX_PER_BANK 8 |
166 | #define EXYNOS_EINT_NR_WKUP_EINT | 47 | #define EXYNOS_EINT_NR_WKUP_EINT |
167 | 48 | ||
168 | #define EXYNOS_PIN_BANK_EINTN(reg, __gpio, id) \ | 49 | #define EXYNOS_PIN_BANK_EINTN(pins, reg, id) \ |
169 | { \ | 50 | { \ |
170 | .pctl_offset = reg, \ | 51 | .pctl_offset = reg, \ |
171 | .pin_base = (__gpio##_START), \ | 52 | .nr_pins = pins, \ |
172 | .nr_pins = (__gpio##_NR), \ | ||
173 | .func_width = 4, \ | 53 | .func_width = 4, \ |
174 | .pud_width = 2, \ | 54 | .pud_width = 2, \ |
175 | .drv_width = 2, \ | 55 | .drv_width = 2, \ |
@@ -179,40 +59,50 @@ enum exynos4210_gpio_xc_start { | |||
179 | .name = id \ | 59 | .name = id \ |
180 | } | 60 | } |
181 | 61 | ||
182 | #define EXYNOS_PIN_BANK_EINTG(reg, __gpio, id) \ | 62 | #define EXYNOS_PIN_BANK_EINTG(pins, reg, id, offs) \ |
183 | { \ | 63 | { \ |
184 | .pctl_offset = reg, \ | 64 | .pctl_offset = reg, \ |
185 | .pin_base = (__gpio##_START), \ | 65 | .nr_pins = pins, \ |
186 | .nr_pins = (__gpio##_NR), \ | ||
187 | .func_width = 4, \ | 66 | .func_width = 4, \ |
188 | .pud_width = 2, \ | 67 | .pud_width = 2, \ |
189 | .drv_width = 2, \ | 68 | .drv_width = 2, \ |
190 | .conpdn_width = 2, \ | 69 | .conpdn_width = 2, \ |
191 | .pudpdn_width = 2, \ | 70 | .pudpdn_width = 2, \ |
192 | .eint_type = EINT_TYPE_GPIO, \ | 71 | .eint_type = EINT_TYPE_GPIO, \ |
193 | .irq_base = (__gpio##_IRQ), \ | 72 | .eint_offset = offs, \ |
194 | .name = id \ | 73 | .name = id \ |
195 | } | 74 | } |
196 | 75 | ||
197 | /** | 76 | #define EXYNOS_PIN_BANK_EINTW(pins, reg, id, offs) \ |
198 | * struct exynos_geint_data: gpio eint specific data for irq_chip callbacks. | 77 | { \ |
199 | * @bank: pin bank from which this gpio interrupt originates. | 78 | .pctl_offset = reg, \ |
200 | * @pin: pin number within the bank. | 79 | .nr_pins = pins, \ |
201 | * @eint_offset: offset to be added to the con/pend/mask register bank base. | 80 | .func_width = 4, \ |
202 | */ | 81 | .pud_width = 2, \ |
203 | struct exynos_geint_data { | 82 | .drv_width = 2, \ |
204 | struct samsung_pin_bank *bank; | 83 | .eint_type = EINT_TYPE_WKUP, \ |
205 | u32 pin; | 84 | .eint_offset = offs, \ |
206 | u32 eint_offset; | 85 | .name = id \ |
207 | }; | 86 | } |
208 | 87 | ||
209 | /** | 88 | /** |
210 | * struct exynos_weint_data: irq specific data for all the wakeup interrupts | 89 | * struct exynos_weint_data: irq specific data for all the wakeup interrupts |
211 | * generated by the external wakeup interrupt controller. | 90 | * generated by the external wakeup interrupt controller. |
212 | * @domain: irq domain representing the external wakeup interrupts | ||
213 | * @irq: interrupt number within the domain. | 91 | * @irq: interrupt number within the domain. |
92 | * @bank: bank responsible for this interrupt | ||
214 | */ | 93 | */ |
215 | struct exynos_weint_data { | 94 | struct exynos_weint_data { |
216 | struct irq_domain *domain; | 95 | unsigned int irq; |
217 | u32 irq; | 96 | struct samsung_pin_bank *bank; |
97 | }; | ||
98 | |||
99 | /** | ||
100 | * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts | ||
101 | * generated by the external wakeup interrupt controller. | ||
102 | * @nr_banks: count of banks being part of the mux | ||
103 | * @banks: array of banks being part of the mux | ||
104 | */ | ||
105 | struct exynos_muxed_weint_data { | ||
106 | unsigned int nr_banks; | ||
107 | struct samsung_pin_bank *banks[]; | ||
218 | }; | 108 | }; |
diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/pinctrl-exynos5440.c new file mode 100644 index 000000000000..b8635f634e91 --- /dev/null +++ b/drivers/pinctrl/pinctrl-exynos5440.c | |||
@@ -0,0 +1,919 @@ | |||
1 | /* | ||
2 | * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's EXYNOS5440 SoC. | ||
3 | * | ||
4 | * Copyright (c) 2012 Samsung Electronics Co., Ltd. | ||
5 | * http://www.samsung.com | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/pinctrl/pinctrl.h> | ||
21 | #include <linux/pinctrl/pinmux.h> | ||
22 | #include <linux/pinctrl/pinconf.h> | ||
23 | #include "core.h" | ||
24 | |||
25 | /* EXYNOS5440 GPIO and Pinctrl register offsets */ | ||
26 | #define GPIO_MUX 0x00 | ||
27 | #define GPIO_IE 0x04 | ||
28 | #define GPIO_INT 0x08 | ||
29 | #define GPIO_TYPE 0x0C | ||
30 | #define GPIO_VAL 0x10 | ||
31 | #define GPIO_OE 0x14 | ||
32 | #define GPIO_IN 0x18 | ||
33 | #define GPIO_PE 0x1C | ||
34 | #define GPIO_PS 0x20 | ||
35 | #define GPIO_SR 0x24 | ||
36 | #define GPIO_DS0 0x28 | ||
37 | #define GPIO_DS1 0x2C | ||
38 | |||
39 | #define EXYNOS5440_MAX_PINS 23 | ||
40 | #define PIN_NAME_LENGTH 10 | ||
41 | |||
42 | #define GROUP_SUFFIX "-grp" | ||
43 | #define GSUFFIX_LEN sizeof(GROUP_SUFFIX) | ||
44 | #define FUNCTION_SUFFIX "-mux" | ||
45 | #define FSUFFIX_LEN sizeof(FUNCTION_SUFFIX) | ||
46 | |||
47 | /* | ||
48 | * pin configuration type and its value are packed together into a 16-bits. | ||
49 | * The upper 8-bits represent the configuration type and the lower 8-bits | ||
50 | * hold the value of the configuration type. | ||
51 | */ | ||
52 | #define PINCFG_TYPE_MASK 0xFF | ||
53 | #define PINCFG_VALUE_SHIFT 8 | ||
54 | #define PINCFG_VALUE_MASK (0xFF << PINCFG_VALUE_SHIFT) | ||
55 | #define PINCFG_PACK(type, value) (((value) << PINCFG_VALUE_SHIFT) | type) | ||
56 | #define PINCFG_UNPACK_TYPE(cfg) ((cfg) & PINCFG_TYPE_MASK) | ||
57 | #define PINCFG_UNPACK_VALUE(cfg) (((cfg) & PINCFG_VALUE_MASK) >> \ | ||
58 | PINCFG_VALUE_SHIFT) | ||
59 | |||
60 | /** | ||
61 | * enum pincfg_type - possible pin configuration types supported. | ||
62 | * @PINCFG_TYPE_PUD: Pull up/down configuration. | ||
63 | * @PINCFG_TYPE_DRV: Drive strength configuration. | ||
64 | * @PINCFG_TYPE_SKEW_RATE: Skew rate configuration. | ||
65 | * @PINCFG_TYPE_INPUT_TYPE: Pin input type configuration. | ||
66 | */ | ||
67 | enum pincfg_type { | ||
68 | PINCFG_TYPE_PUD, | ||
69 | PINCFG_TYPE_DRV, | ||
70 | PINCFG_TYPE_SKEW_RATE, | ||
71 | PINCFG_TYPE_INPUT_TYPE | ||
72 | }; | ||
73 | |||
74 | /** | ||
75 | * struct exynos5440_pin_group: represent group of pins for pincfg setting. | ||
76 | * @name: name of the pin group, used to lookup the group. | ||
77 | * @pins: the pins included in this group. | ||
78 | * @num_pins: number of pins included in this group. | ||
79 | */ | ||
80 | struct exynos5440_pin_group { | ||
81 | const char *name; | ||
82 | const unsigned int *pins; | ||
83 | u8 num_pins; | ||
84 | }; | ||
85 | |||
86 | /** | ||
87 | * struct exynos5440_pmx_func: represent a pin function. | ||
88 | * @name: name of the pin function, used to lookup the function. | ||
89 | * @groups: one or more names of pin groups that provide this function. | ||
90 | * @num_groups: number of groups included in @groups. | ||
91 | * @function: the function number to be programmed when selected. | ||
92 | */ | ||
93 | struct exynos5440_pmx_func { | ||
94 | const char *name; | ||
95 | const char **groups; | ||
96 | u8 num_groups; | ||
97 | unsigned long function; | ||
98 | }; | ||
99 | |||
100 | /** | ||
101 | * struct exynos5440_pinctrl_priv_data: driver's private runtime data. | ||
102 | * @reg_base: ioremapped based address of the register space. | ||
103 | * @gc: gpio chip registered with gpiolib. | ||
104 | * @pin_groups: list of pin groups parsed from device tree. | ||
105 | * @nr_groups: number of pin groups available. | ||
106 | * @pmx_functions: list of pin functions parsed from device tree. | ||
107 | * @nr_functions: number of pin functions available. | ||
108 | */ | ||
109 | struct exynos5440_pinctrl_priv_data { | ||
110 | void __iomem *reg_base; | ||
111 | struct gpio_chip *gc; | ||
112 | |||
113 | const struct exynos5440_pin_group *pin_groups; | ||
114 | unsigned int nr_groups; | ||
115 | const struct exynos5440_pmx_func *pmx_functions; | ||
116 | unsigned int nr_functions; | ||
117 | }; | ||
118 | |||
119 | /* list of all possible config options supported */ | ||
120 | struct pin_config { | ||
121 | char *prop_cfg; | ||
122 | unsigned int cfg_type; | ||
123 | } pcfgs[] = { | ||
124 | { "samsung,exynos5440-pin-pud", PINCFG_TYPE_PUD }, | ||
125 | { "samsung,exynos5440-pin-drv", PINCFG_TYPE_DRV }, | ||
126 | { "samsung,exynos5440-pin-skew-rate", PINCFG_TYPE_SKEW_RATE }, | ||
127 | { "samsung,exynos5440-pin-input-type", PINCFG_TYPE_INPUT_TYPE }, | ||
128 | }; | ||
129 | |||
130 | /* check if the selector is a valid pin group selector */ | ||
131 | static int exynos5440_get_group_count(struct pinctrl_dev *pctldev) | ||
132 | { | ||
133 | struct exynos5440_pinctrl_priv_data *priv; | ||
134 | |||
135 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
136 | return priv->nr_groups; | ||
137 | } | ||
138 | |||
139 | /* return the name of the group selected by the group selector */ | ||
140 | static const char *exynos5440_get_group_name(struct pinctrl_dev *pctldev, | ||
141 | unsigned selector) | ||
142 | { | ||
143 | struct exynos5440_pinctrl_priv_data *priv; | ||
144 | |||
145 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
146 | return priv->pin_groups[selector].name; | ||
147 | } | ||
148 | |||
149 | /* return the pin numbers associated with the specified group */ | ||
150 | static int exynos5440_get_group_pins(struct pinctrl_dev *pctldev, | ||
151 | unsigned selector, const unsigned **pins, unsigned *num_pins) | ||
152 | { | ||
153 | struct exynos5440_pinctrl_priv_data *priv; | ||
154 | |||
155 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
156 | *pins = priv->pin_groups[selector].pins; | ||
157 | *num_pins = priv->pin_groups[selector].num_pins; | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* create pinctrl_map entries by parsing device tree nodes */ | ||
162 | static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
163 | struct device_node *np, struct pinctrl_map **maps, | ||
164 | unsigned *nmaps) | ||
165 | { | ||
166 | struct device *dev = pctldev->dev; | ||
167 | struct pinctrl_map *map; | ||
168 | unsigned long *cfg = NULL; | ||
169 | char *gname, *fname; | ||
170 | int cfg_cnt = 0, map_cnt = 0, idx = 0; | ||
171 | |||
172 | /* count the number of config options specfied in the node */ | ||
173 | for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++) | ||
174 | if (of_find_property(np, pcfgs[idx].prop_cfg, NULL)) | ||
175 | cfg_cnt++; | ||
176 | |||
177 | /* | ||
178 | * Find out the number of map entries to create. All the config options | ||
179 | * can be accomadated into a single config map entry. | ||
180 | */ | ||
181 | if (cfg_cnt) | ||
182 | map_cnt = 1; | ||
183 | if (of_find_property(np, "samsung,exynos5440-pin-function", NULL)) | ||
184 | map_cnt++; | ||
185 | if (!map_cnt) { | ||
186 | dev_err(dev, "node %s does not have either config or function " | ||
187 | "configurations\n", np->name); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | /* Allocate memory for pin-map entries */ | ||
192 | map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL); | ||
193 | if (!map) { | ||
194 | dev_err(dev, "could not alloc memory for pin-maps\n"); | ||
195 | return -ENOMEM; | ||
196 | } | ||
197 | *nmaps = 0; | ||
198 | |||
199 | /* | ||
200 | * Allocate memory for pin group name. The pin group name is derived | ||
201 | * from the node name from which these map entries are be created. | ||
202 | */ | ||
203 | gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL); | ||
204 | if (!gname) { | ||
205 | dev_err(dev, "failed to alloc memory for group name\n"); | ||
206 | goto free_map; | ||
207 | } | ||
208 | sprintf(gname, "%s%s", np->name, GROUP_SUFFIX); | ||
209 | |||
210 | /* | ||
211 | * don't have config options? then skip over to creating function | ||
212 | * map entries. | ||
213 | */ | ||
214 | if (!cfg_cnt) | ||
215 | goto skip_cfgs; | ||
216 | |||
217 | /* Allocate memory for config entries */ | ||
218 | cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL); | ||
219 | if (!cfg) { | ||
220 | dev_err(dev, "failed to alloc memory for configs\n"); | ||
221 | goto free_gname; | ||
222 | } | ||
223 | |||
224 | /* Prepare a list of config settings */ | ||
225 | for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) { | ||
226 | u32 value; | ||
227 | if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value)) | ||
228 | cfg[cfg_cnt++] = | ||
229 | PINCFG_PACK(pcfgs[idx].cfg_type, value); | ||
230 | } | ||
231 | |||
232 | /* create the config map entry */ | ||
233 | map[*nmaps].data.configs.group_or_pin = gname; | ||
234 | map[*nmaps].data.configs.configs = cfg; | ||
235 | map[*nmaps].data.configs.num_configs = cfg_cnt; | ||
236 | map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP; | ||
237 | *nmaps += 1; | ||
238 | |||
239 | skip_cfgs: | ||
240 | /* create the function map entry */ | ||
241 | if (of_find_property(np, "samsung,exynos5440-pin-function", NULL)) { | ||
242 | fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL); | ||
243 | if (!fname) { | ||
244 | dev_err(dev, "failed to alloc memory for func name\n"); | ||
245 | goto free_cfg; | ||
246 | } | ||
247 | sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX); | ||
248 | |||
249 | map[*nmaps].data.mux.group = gname; | ||
250 | map[*nmaps].data.mux.function = fname; | ||
251 | map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP; | ||
252 | *nmaps += 1; | ||
253 | } | ||
254 | |||
255 | *maps = map; | ||
256 | return 0; | ||
257 | |||
258 | free_cfg: | ||
259 | kfree(cfg); | ||
260 | free_gname: | ||
261 | kfree(gname); | ||
262 | free_map: | ||
263 | kfree(map); | ||
264 | return -ENOMEM; | ||
265 | } | ||
266 | |||
267 | /* free the memory allocated to hold the pin-map table */ | ||
268 | static void exynos5440_dt_free_map(struct pinctrl_dev *pctldev, | ||
269 | struct pinctrl_map *map, unsigned num_maps) | ||
270 | { | ||
271 | int idx; | ||
272 | |||
273 | for (idx = 0; idx < num_maps; idx++) { | ||
274 | if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) { | ||
275 | kfree(map[idx].data.mux.function); | ||
276 | if (!idx) | ||
277 | kfree(map[idx].data.mux.group); | ||
278 | } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) { | ||
279 | kfree(map[idx].data.configs.configs); | ||
280 | if (!idx) | ||
281 | kfree(map[idx].data.configs.group_or_pin); | ||
282 | } | ||
283 | }; | ||
284 | |||
285 | kfree(map); | ||
286 | } | ||
287 | |||
288 | /* list of pinctrl callbacks for the pinctrl core */ | ||
289 | static struct pinctrl_ops exynos5440_pctrl_ops = { | ||
290 | .get_groups_count = exynos5440_get_group_count, | ||
291 | .get_group_name = exynos5440_get_group_name, | ||
292 | .get_group_pins = exynos5440_get_group_pins, | ||
293 | .dt_node_to_map = exynos5440_dt_node_to_map, | ||
294 | .dt_free_map = exynos5440_dt_free_map, | ||
295 | }; | ||
296 | |||
297 | /* check if the selector is a valid pin function selector */ | ||
298 | static int exynos5440_get_functions_count(struct pinctrl_dev *pctldev) | ||
299 | { | ||
300 | struct exynos5440_pinctrl_priv_data *priv; | ||
301 | |||
302 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
303 | return priv->nr_functions; | ||
304 | } | ||
305 | |||
306 | /* return the name of the pin function specified */ | ||
307 | static const char *exynos5440_pinmux_get_fname(struct pinctrl_dev *pctldev, | ||
308 | unsigned selector) | ||
309 | { | ||
310 | struct exynos5440_pinctrl_priv_data *priv; | ||
311 | |||
312 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
313 | return priv->pmx_functions[selector].name; | ||
314 | } | ||
315 | |||
316 | /* return the groups associated for the specified function selector */ | ||
317 | static int exynos5440_pinmux_get_groups(struct pinctrl_dev *pctldev, | ||
318 | unsigned selector, const char * const **groups, | ||
319 | unsigned * const num_groups) | ||
320 | { | ||
321 | struct exynos5440_pinctrl_priv_data *priv; | ||
322 | |||
323 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
324 | *groups = priv->pmx_functions[selector].groups; | ||
325 | *num_groups = priv->pmx_functions[selector].num_groups; | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /* enable or disable a pinmux function */ | ||
330 | static void exynos5440_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, | ||
331 | unsigned group, bool enable) | ||
332 | { | ||
333 | struct exynos5440_pinctrl_priv_data *priv; | ||
334 | void __iomem *base; | ||
335 | u32 function; | ||
336 | u32 data; | ||
337 | |||
338 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
339 | base = priv->reg_base; | ||
340 | function = priv->pmx_functions[selector].function; | ||
341 | |||
342 | data = readl(base + GPIO_MUX); | ||
343 | if (enable) | ||
344 | data |= (1 << function); | ||
345 | else | ||
346 | data &= ~(1 << function); | ||
347 | writel(data, base + GPIO_MUX); | ||
348 | } | ||
349 | |||
350 | /* enable a specified pinmux by writing to registers */ | ||
351 | static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector, | ||
352 | unsigned group) | ||
353 | { | ||
354 | exynos5440_pinmux_setup(pctldev, selector, group, true); | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | /* disable a specified pinmux by writing to registers */ | ||
359 | static void exynos5440_pinmux_disable(struct pinctrl_dev *pctldev, | ||
360 | unsigned selector, unsigned group) | ||
361 | { | ||
362 | exynos5440_pinmux_setup(pctldev, selector, group, false); | ||
363 | } | ||
364 | |||
365 | /* | ||
366 | * The calls to gpio_direction_output() and gpio_direction_input() | ||
367 | * leads to this function call (via the pinctrl_gpio_direction_{input|output}() | ||
368 | * function called from the gpiolib interface). | ||
369 | */ | ||
370 | static int exynos5440_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, | ||
371 | struct pinctrl_gpio_range *range, unsigned offset, bool input) | ||
372 | { | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | /* list of pinmux callbacks for the pinmux vertical in pinctrl core */ | ||
377 | static struct pinmux_ops exynos5440_pinmux_ops = { | ||
378 | .get_functions_count = exynos5440_get_functions_count, | ||
379 | .get_function_name = exynos5440_pinmux_get_fname, | ||
380 | .get_function_groups = exynos5440_pinmux_get_groups, | ||
381 | .enable = exynos5440_pinmux_enable, | ||
382 | .disable = exynos5440_pinmux_disable, | ||
383 | .gpio_set_direction = exynos5440_pinmux_gpio_set_direction, | ||
384 | }; | ||
385 | |||
386 | /* set the pin config settings for a specified pin */ | ||
387 | static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | ||
388 | unsigned long config) | ||
389 | { | ||
390 | struct exynos5440_pinctrl_priv_data *priv; | ||
391 | void __iomem *base; | ||
392 | enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(config); | ||
393 | u32 cfg_value = PINCFG_UNPACK_VALUE(config); | ||
394 | u32 data; | ||
395 | |||
396 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
397 | base = priv->reg_base; | ||
398 | |||
399 | switch (cfg_type) { | ||
400 | case PINCFG_TYPE_PUD: | ||
401 | /* first set pull enable/disable bit */ | ||
402 | data = readl(base + GPIO_PE); | ||
403 | data &= ~(1 << pin); | ||
404 | if (cfg_value) | ||
405 | data |= (1 << pin); | ||
406 | writel(data, base + GPIO_PE); | ||
407 | |||
408 | /* then set pull up/down bit */ | ||
409 | data = readl(base + GPIO_PS); | ||
410 | data &= ~(1 << pin); | ||
411 | if (cfg_value == 2) | ||
412 | data |= (1 << pin); | ||
413 | writel(data, base + GPIO_PS); | ||
414 | break; | ||
415 | |||
416 | case PINCFG_TYPE_DRV: | ||
417 | /* set the first bit of the drive strength */ | ||
418 | data = readl(base + GPIO_DS0); | ||
419 | data &= ~(1 << pin); | ||
420 | data |= ((cfg_value & 1) << pin); | ||
421 | writel(data, base + GPIO_DS0); | ||
422 | cfg_value >>= 1; | ||
423 | |||
424 | /* set the second bit of the driver strength */ | ||
425 | data = readl(base + GPIO_DS1); | ||
426 | data &= ~(1 << pin); | ||
427 | data |= ((cfg_value & 1) << pin); | ||
428 | writel(data, base + GPIO_DS1); | ||
429 | break; | ||
430 | case PINCFG_TYPE_SKEW_RATE: | ||
431 | data = readl(base + GPIO_SR); | ||
432 | data &= ~(1 << pin); | ||
433 | data |= ((cfg_value & 1) << pin); | ||
434 | writel(data, base + GPIO_SR); | ||
435 | break; | ||
436 | case PINCFG_TYPE_INPUT_TYPE: | ||
437 | data = readl(base + GPIO_TYPE); | ||
438 | data &= ~(1 << pin); | ||
439 | data |= ((cfg_value & 1) << pin); | ||
440 | writel(data, base + GPIO_TYPE); | ||
441 | break; | ||
442 | default: | ||
443 | WARN_ON(1); | ||
444 | return -EINVAL; | ||
445 | } | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | /* get the pin config settings for a specified pin */ | ||
451 | static int exynos5440_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, | ||
452 | unsigned long *config) | ||
453 | { | ||
454 | struct exynos5440_pinctrl_priv_data *priv; | ||
455 | void __iomem *base; | ||
456 | enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config); | ||
457 | u32 data; | ||
458 | |||
459 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
460 | base = priv->reg_base; | ||
461 | |||
462 | switch (cfg_type) { | ||
463 | case PINCFG_TYPE_PUD: | ||
464 | data = readl(base + GPIO_PE); | ||
465 | data = (data >> pin) & 1; | ||
466 | if (!data) | ||
467 | *config = 0; | ||
468 | else | ||
469 | *config = ((readl(base + GPIO_PS) >> pin) & 1) + 1; | ||
470 | break; | ||
471 | case PINCFG_TYPE_DRV: | ||
472 | data = readl(base + GPIO_DS0); | ||
473 | data = (data >> pin) & 1; | ||
474 | *config = data; | ||
475 | data = readl(base + GPIO_DS1); | ||
476 | data = (data >> pin) & 1; | ||
477 | *config |= (data << 1); | ||
478 | break; | ||
479 | case PINCFG_TYPE_SKEW_RATE: | ||
480 | data = readl(base + GPIO_SR); | ||
481 | *config = (data >> pin) & 1; | ||
482 | break; | ||
483 | case PINCFG_TYPE_INPUT_TYPE: | ||
484 | data = readl(base + GPIO_TYPE); | ||
485 | *config = (data >> pin) & 1; | ||
486 | break; | ||
487 | default: | ||
488 | WARN_ON(1); | ||
489 | return -EINVAL; | ||
490 | } | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | /* set the pin config settings for a specified pin group */ | ||
496 | static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev, | ||
497 | unsigned group, unsigned long config) | ||
498 | { | ||
499 | struct exynos5440_pinctrl_priv_data *priv; | ||
500 | const unsigned int *pins; | ||
501 | unsigned int cnt; | ||
502 | |||
503 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
504 | pins = priv->pin_groups[group].pins; | ||
505 | |||
506 | for (cnt = 0; cnt < priv->pin_groups[group].num_pins; cnt++) | ||
507 | exynos5440_pinconf_set(pctldev, pins[cnt], config); | ||
508 | |||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | /* get the pin config settings for a specified pin group */ | ||
513 | static int exynos5440_pinconf_group_get(struct pinctrl_dev *pctldev, | ||
514 | unsigned int group, unsigned long *config) | ||
515 | { | ||
516 | struct exynos5440_pinctrl_priv_data *priv; | ||
517 | const unsigned int *pins; | ||
518 | |||
519 | priv = pinctrl_dev_get_drvdata(pctldev); | ||
520 | pins = priv->pin_groups[group].pins; | ||
521 | exynos5440_pinconf_get(pctldev, pins[0], config); | ||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | /* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */ | ||
526 | static struct pinconf_ops exynos5440_pinconf_ops = { | ||
527 | .pin_config_get = exynos5440_pinconf_get, | ||
528 | .pin_config_set = exynos5440_pinconf_set, | ||
529 | .pin_config_group_get = exynos5440_pinconf_group_get, | ||
530 | .pin_config_group_set = exynos5440_pinconf_group_set, | ||
531 | }; | ||
532 | |||
533 | /* gpiolib gpio_set callback function */ | ||
534 | static void exynos5440_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | ||
535 | { | ||
536 | struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev); | ||
537 | void __iomem *base = priv->reg_base; | ||
538 | u32 data; | ||
539 | |||
540 | data = readl(base + GPIO_VAL); | ||
541 | data &= ~(1 << offset); | ||
542 | if (value) | ||
543 | data |= 1 << offset; | ||
544 | writel(data, base + GPIO_VAL); | ||
545 | } | ||
546 | |||
547 | /* gpiolib gpio_get callback function */ | ||
548 | static int exynos5440_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
549 | { | ||
550 | struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev); | ||
551 | void __iomem *base = priv->reg_base; | ||
552 | u32 data; | ||
553 | |||
554 | data = readl(base + GPIO_IN); | ||
555 | data >>= offset; | ||
556 | data &= 1; | ||
557 | return data; | ||
558 | } | ||
559 | |||
560 | /* gpiolib gpio_direction_input callback function */ | ||
561 | static int exynos5440_gpio_direction_input(struct gpio_chip *gc, unsigned offset) | ||
562 | { | ||
563 | struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev); | ||
564 | void __iomem *base = priv->reg_base; | ||
565 | u32 data; | ||
566 | |||
567 | /* first disable the data output enable on this pin */ | ||
568 | data = readl(base + GPIO_OE); | ||
569 | data &= ~(1 << offset); | ||
570 | writel(data, base + GPIO_OE); | ||
571 | |||
572 | /* now enable input on this pin */ | ||
573 | data = readl(base + GPIO_IE); | ||
574 | data |= 1 << offset; | ||
575 | writel(data, base + GPIO_IE); | ||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | /* gpiolib gpio_direction_output callback function */ | ||
580 | static int exynos5440_gpio_direction_output(struct gpio_chip *gc, unsigned offset, | ||
581 | int value) | ||
582 | { | ||
583 | struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev); | ||
584 | void __iomem *base = priv->reg_base; | ||
585 | u32 data; | ||
586 | |||
587 | exynos5440_gpio_set(gc, offset, value); | ||
588 | |||
589 | /* first disable the data input enable on this pin */ | ||
590 | data = readl(base + GPIO_IE); | ||
591 | data &= ~(1 << offset); | ||
592 | writel(data, base + GPIO_IE); | ||
593 | |||
594 | /* now enable output on this pin */ | ||
595 | data = readl(base + GPIO_OE); | ||
596 | data |= 1 << offset; | ||
597 | writel(data, base + GPIO_OE); | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | /* parse the pin numbers listed in the 'samsung,exynos5440-pins' property */ | ||
602 | static int __init exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev, | ||
603 | struct device_node *cfg_np, unsigned int **pin_list, | ||
604 | unsigned int *npins) | ||
605 | { | ||
606 | struct device *dev = &pdev->dev; | ||
607 | struct property *prop; | ||
608 | |||
609 | prop = of_find_property(cfg_np, "samsung,exynos5440-pins", NULL); | ||
610 | if (!prop) | ||
611 | return -ENOENT; | ||
612 | |||
613 | *npins = prop->length / sizeof(unsigned long); | ||
614 | if (!*npins) { | ||
615 | dev_err(dev, "invalid pin list in %s node", cfg_np->name); | ||
616 | return -EINVAL; | ||
617 | } | ||
618 | |||
619 | *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL); | ||
620 | if (!*pin_list) { | ||
621 | dev_err(dev, "failed to allocate memory for pin list\n"); | ||
622 | return -ENOMEM; | ||
623 | } | ||
624 | |||
625 | return of_property_read_u32_array(cfg_np, "samsung,exynos5440-pins", | ||
626 | *pin_list, *npins); | ||
627 | } | ||
628 | |||
629 | /* | ||
630 | * Parse the information about all the available pin groups and pin functions | ||
631 | * from device node of the pin-controller. | ||
632 | */ | ||
633 | static int __init exynos5440_pinctrl_parse_dt(struct platform_device *pdev, | ||
634 | struct exynos5440_pinctrl_priv_data *priv) | ||
635 | { | ||
636 | struct device *dev = &pdev->dev; | ||
637 | struct device_node *dev_np = dev->of_node; | ||
638 | struct device_node *cfg_np; | ||
639 | struct exynos5440_pin_group *groups, *grp; | ||
640 | struct exynos5440_pmx_func *functions, *func; | ||
641 | unsigned *pin_list; | ||
642 | unsigned int npins, grp_cnt, func_idx = 0; | ||
643 | char *gname, *fname; | ||
644 | int ret; | ||
645 | |||
646 | grp_cnt = of_get_child_count(dev_np); | ||
647 | if (!grp_cnt) | ||
648 | return -EINVAL; | ||
649 | |||
650 | groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL); | ||
651 | if (!groups) { | ||
652 | dev_err(dev, "failed allocate memory for ping group list\n"); | ||
653 | return -EINVAL; | ||
654 | } | ||
655 | grp = groups; | ||
656 | |||
657 | functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL); | ||
658 | if (!functions) { | ||
659 | dev_err(dev, "failed to allocate memory for function list\n"); | ||
660 | return -EINVAL; | ||
661 | } | ||
662 | func = functions; | ||
663 | |||
664 | /* | ||
665 | * Iterate over all the child nodes of the pin controller node | ||
666 | * and create pin groups and pin function lists. | ||
667 | */ | ||
668 | for_each_child_of_node(dev_np, cfg_np) { | ||
669 | u32 function; | ||
670 | |||
671 | ret = exynos5440_pinctrl_parse_dt_pins(pdev, cfg_np, | ||
672 | &pin_list, &npins); | ||
673 | if (ret) | ||
674 | return ret; | ||
675 | |||
676 | /* derive pin group name from the node name */ | ||
677 | gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN, | ||
678 | GFP_KERNEL); | ||
679 | if (!gname) { | ||
680 | dev_err(dev, "failed to alloc memory for group name\n"); | ||
681 | return -ENOMEM; | ||
682 | } | ||
683 | sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX); | ||
684 | |||
685 | grp->name = gname; | ||
686 | grp->pins = pin_list; | ||
687 | grp->num_pins = npins; | ||
688 | grp++; | ||
689 | |||
690 | ret = of_property_read_u32(cfg_np, "samsung,exynos5440-pin-function", | ||
691 | &function); | ||
692 | if (ret) | ||
693 | continue; | ||
694 | |||
695 | /* derive function name from the node name */ | ||
696 | fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN, | ||
697 | GFP_KERNEL); | ||
698 | if (!fname) { | ||
699 | dev_err(dev, "failed to alloc memory for func name\n"); | ||
700 | return -ENOMEM; | ||
701 | } | ||
702 | sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX); | ||
703 | |||
704 | func->name = fname; | ||
705 | func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL); | ||
706 | if (!func->groups) { | ||
707 | dev_err(dev, "failed to alloc memory for group list " | ||
708 | "in pin function"); | ||
709 | return -ENOMEM; | ||
710 | } | ||
711 | func->groups[0] = gname; | ||
712 | func->num_groups = 1; | ||
713 | func->function = function; | ||
714 | func++; | ||
715 | func_idx++; | ||
716 | } | ||
717 | |||
718 | priv->pin_groups = groups; | ||
719 | priv->nr_groups = grp_cnt; | ||
720 | priv->pmx_functions = functions; | ||
721 | priv->nr_functions = func_idx; | ||
722 | return 0; | ||
723 | } | ||
724 | |||
725 | /* register the pinctrl interface with the pinctrl subsystem */ | ||
726 | static int __init exynos5440_pinctrl_register(struct platform_device *pdev, | ||
727 | struct exynos5440_pinctrl_priv_data *priv) | ||
728 | { | ||
729 | struct device *dev = &pdev->dev; | ||
730 | struct pinctrl_desc *ctrldesc; | ||
731 | struct pinctrl_dev *pctl_dev; | ||
732 | struct pinctrl_pin_desc *pindesc, *pdesc; | ||
733 | struct pinctrl_gpio_range grange; | ||
734 | char *pin_names; | ||
735 | int pin, ret; | ||
736 | |||
737 | ctrldesc = devm_kzalloc(dev, sizeof(*ctrldesc), GFP_KERNEL); | ||
738 | if (!ctrldesc) { | ||
739 | dev_err(dev, "could not allocate memory for pinctrl desc\n"); | ||
740 | return -ENOMEM; | ||
741 | } | ||
742 | |||
743 | ctrldesc->name = "exynos5440-pinctrl"; | ||
744 | ctrldesc->owner = THIS_MODULE; | ||
745 | ctrldesc->pctlops = &exynos5440_pctrl_ops; | ||
746 | ctrldesc->pmxops = &exynos5440_pinmux_ops; | ||
747 | ctrldesc->confops = &exynos5440_pinconf_ops; | ||
748 | |||
749 | pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * | ||
750 | EXYNOS5440_MAX_PINS, GFP_KERNEL); | ||
751 | if (!pindesc) { | ||
752 | dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); | ||
753 | return -ENOMEM; | ||
754 | } | ||
755 | ctrldesc->pins = pindesc; | ||
756 | ctrldesc->npins = EXYNOS5440_MAX_PINS; | ||
757 | |||
758 | /* dynamically populate the pin number and pin name for pindesc */ | ||
759 | for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++) | ||
760 | pdesc->number = pin; | ||
761 | |||
762 | /* | ||
763 | * allocate space for storing the dynamically generated names for all | ||
764 | * the pins which belong to this pin-controller. | ||
765 | */ | ||
766 | pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH * | ||
767 | ctrldesc->npins, GFP_KERNEL); | ||
768 | if (!pin_names) { | ||
769 | dev_err(&pdev->dev, "mem alloc for pin names failed\n"); | ||
770 | return -ENOMEM; | ||
771 | } | ||
772 | |||
773 | /* for each pin, set the name of the pin */ | ||
774 | for (pin = 0; pin < ctrldesc->npins; pin++) { | ||
775 | sprintf(pin_names, "gpio%02d", pin); | ||
776 | pdesc = pindesc + pin; | ||
777 | pdesc->name = pin_names; | ||
778 | pin_names += PIN_NAME_LENGTH; | ||
779 | } | ||
780 | |||
781 | ret = exynos5440_pinctrl_parse_dt(pdev, priv); | ||
782 | if (ret) | ||
783 | return ret; | ||
784 | |||
785 | pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, priv); | ||
786 | if (!pctl_dev) { | ||
787 | dev_err(&pdev->dev, "could not register pinctrl driver\n"); | ||
788 | return -EINVAL; | ||
789 | } | ||
790 | |||
791 | grange.name = "exynos5440-pctrl-gpio-range"; | ||
792 | grange.id = 0; | ||
793 | grange.base = 0; | ||
794 | grange.npins = EXYNOS5440_MAX_PINS; | ||
795 | grange.gc = priv->gc; | ||
796 | pinctrl_add_gpio_range(pctl_dev, &grange); | ||
797 | return 0; | ||
798 | } | ||
799 | |||
800 | /* register the gpiolib interface with the gpiolib subsystem */ | ||
801 | static int __init exynos5440_gpiolib_register(struct platform_device *pdev, | ||
802 | struct exynos5440_pinctrl_priv_data *priv) | ||
803 | { | ||
804 | struct gpio_chip *gc; | ||
805 | int ret; | ||
806 | |||
807 | gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL); | ||
808 | if (!gc) { | ||
809 | dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n"); | ||
810 | return -ENOMEM; | ||
811 | } | ||
812 | |||
813 | priv->gc = gc; | ||
814 | gc->base = 0; | ||
815 | gc->ngpio = EXYNOS5440_MAX_PINS; | ||
816 | gc->dev = &pdev->dev; | ||
817 | gc->set = exynos5440_gpio_set; | ||
818 | gc->get = exynos5440_gpio_get; | ||
819 | gc->direction_input = exynos5440_gpio_direction_input; | ||
820 | gc->direction_output = exynos5440_gpio_direction_output; | ||
821 | gc->label = "gpiolib-exynos5440"; | ||
822 | gc->owner = THIS_MODULE; | ||
823 | ret = gpiochip_add(gc); | ||
824 | if (ret) { | ||
825 | dev_err(&pdev->dev, "failed to register gpio_chip %s, error " | ||
826 | "code: %d\n", gc->label, ret); | ||
827 | return ret; | ||
828 | } | ||
829 | |||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | /* unregister the gpiolib interface with the gpiolib subsystem */ | ||
834 | static int __init exynos5440_gpiolib_unregister(struct platform_device *pdev, | ||
835 | struct exynos5440_pinctrl_priv_data *priv) | ||
836 | { | ||
837 | int ret = gpiochip_remove(priv->gc); | ||
838 | if (ret) { | ||
839 | dev_err(&pdev->dev, "gpio chip remove failed\n"); | ||
840 | return ret; | ||
841 | } | ||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static int __devinit exynos5440_pinctrl_probe(struct platform_device *pdev) | ||
846 | { | ||
847 | struct device *dev = &pdev->dev; | ||
848 | struct exynos5440_pinctrl_priv_data *priv; | ||
849 | struct resource *res; | ||
850 | int ret; | ||
851 | |||
852 | if (!dev->of_node) { | ||
853 | dev_err(dev, "device tree node not found\n"); | ||
854 | return -ENODEV; | ||
855 | } | ||
856 | |||
857 | priv = devm_kzalloc(dev, sizeof(priv), GFP_KERNEL); | ||
858 | if (!priv) { | ||
859 | dev_err(dev, "could not allocate memory for private data\n"); | ||
860 | return -ENOMEM; | ||
861 | } | ||
862 | |||
863 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
864 | if (!res) { | ||
865 | dev_err(dev, "cannot find IO resource\n"); | ||
866 | return -ENOENT; | ||
867 | } | ||
868 | |||
869 | priv->reg_base = devm_request_and_ioremap(&pdev->dev, res); | ||
870 | if (!priv->reg_base) { | ||
871 | dev_err(dev, "ioremap failed\n"); | ||
872 | return -ENODEV; | ||
873 | } | ||
874 | |||
875 | ret = exynos5440_gpiolib_register(pdev, priv); | ||
876 | if (ret) | ||
877 | return ret; | ||
878 | |||
879 | ret = exynos5440_pinctrl_register(pdev, priv); | ||
880 | if (ret) { | ||
881 | exynos5440_gpiolib_unregister(pdev, priv); | ||
882 | return ret; | ||
883 | } | ||
884 | |||
885 | platform_set_drvdata(pdev, priv); | ||
886 | dev_info(dev, "EXYNOS5440 pinctrl driver registered\n"); | ||
887 | return 0; | ||
888 | } | ||
889 | |||
890 | static const struct of_device_id exynos5440_pinctrl_dt_match[] = { | ||
891 | { .compatible = "samsung,exynos5440-pinctrl" }, | ||
892 | {}, | ||
893 | }; | ||
894 | MODULE_DEVICE_TABLE(of, exynos5440_pinctrl_dt_match); | ||
895 | |||
896 | static struct platform_driver exynos5440_pinctrl_driver = { | ||
897 | .probe = exynos5440_pinctrl_probe, | ||
898 | .driver = { | ||
899 | .name = "exynos5440-pinctrl", | ||
900 | .owner = THIS_MODULE, | ||
901 | .of_match_table = of_match_ptr(exynos5440_pinctrl_dt_match), | ||
902 | }, | ||
903 | }; | ||
904 | |||
905 | static int __init exynos5440_pinctrl_drv_register(void) | ||
906 | { | ||
907 | return platform_driver_register(&exynos5440_pinctrl_driver); | ||
908 | } | ||
909 | postcore_initcall(exynos5440_pinctrl_drv_register); | ||
910 | |||
911 | static void __exit exynos5440_pinctrl_drv_unregister(void) | ||
912 | { | ||
913 | platform_driver_unregister(&exynos5440_pinctrl_driver); | ||
914 | } | ||
915 | module_exit(exynos5440_pinctrl_drv_unregister); | ||
916 | |||
917 | MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>"); | ||
918 | MODULE_DESCRIPTION("Samsung EXYNOS5440 SoC pinctrl driver"); | ||
919 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c index ee7305903470..8ed20e84cb02 100644 --- a/drivers/pinctrl/pinctrl-falcon.c +++ b/drivers/pinctrl/pinctrl-falcon.c | |||
@@ -322,7 +322,7 @@ static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev, | |||
322 | { | 322 | { |
323 | } | 323 | } |
324 | 324 | ||
325 | struct pinconf_ops falcon_pinconf_ops = { | 325 | static struct pinconf_ops falcon_pinconf_ops = { |
326 | .pin_config_get = falcon_pinconf_get, | 326 | .pin_config_get = falcon_pinconf_get, |
327 | .pin_config_set = falcon_pinconf_set, | 327 | .pin_config_set = falcon_pinconf_set, |
328 | .pin_config_group_get = falcon_pinconf_group_get, | 328 | .pin_config_group_get = falcon_pinconf_group_get, |
diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index 63866d95357d..131d86d7c2a5 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c | |||
@@ -71,7 +71,7 @@ static const struct imx_pin_reg *imx_find_pin_reg( | |||
71 | break; | 71 | break; |
72 | } | 72 | } |
73 | 73 | ||
74 | if (!pin_reg) { | 74 | if (i == info->npin_regs) { |
75 | dev_err(info->dev, "Pin(%s): unable to find pin reg map\n", | 75 | dev_err(info->dev, "Pin(%s): unable to find pin reg map\n", |
76 | info->pins[pin].name); | 76 | info->pins[pin].name); |
77 | return NULL; | 77 | return NULL; |
@@ -397,7 +397,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, | |||
397 | } | 397 | } |
398 | } | 398 | } |
399 | 399 | ||
400 | struct pinconf_ops imx_pinconf_ops = { | 400 | static struct pinconf_ops imx_pinconf_ops = { |
401 | .pin_config_get = imx_pinconf_get, | 401 | .pin_config_get = imx_pinconf_get, |
402 | .pin_config_set = imx_pinconf_set, | 402 | .pin_config_set = imx_pinconf_set, |
403 | .pin_config_dbg_show = imx_pinconf_dbg_show, | 403 | .pin_config_dbg_show = imx_pinconf_dbg_show, |
@@ -611,7 +611,7 @@ int __devinit imx_pinctrl_probe(struct platform_device *pdev, | |||
611 | return 0; | 611 | return 0; |
612 | } | 612 | } |
613 | 613 | ||
614 | int __devexit imx_pinctrl_remove(struct platform_device *pdev) | 614 | int imx_pinctrl_remove(struct platform_device *pdev) |
615 | { | 615 | { |
616 | struct imx_pinctrl *ipctl = platform_get_drvdata(pdev); | 616 | struct imx_pinctrl *ipctl = platform_get_drvdata(pdev); |
617 | 617 | ||
diff --git a/drivers/pinctrl/pinctrl-imx23.c b/drivers/pinctrl/pinctrl-imx23.c index 3674d877ed7c..04364f7822b7 100644 --- a/drivers/pinctrl/pinctrl-imx23.c +++ b/drivers/pinctrl/pinctrl-imx23.c | |||
@@ -272,7 +272,7 @@ static int __devinit imx23_pinctrl_probe(struct platform_device *pdev) | |||
272 | return mxs_pinctrl_probe(pdev, &imx23_pinctrl_data); | 272 | return mxs_pinctrl_probe(pdev, &imx23_pinctrl_data); |
273 | } | 273 | } |
274 | 274 | ||
275 | static struct of_device_id imx23_pinctrl_of_match[] __devinitdata = { | 275 | static struct of_device_id imx23_pinctrl_of_match[] = { |
276 | { .compatible = "fsl,imx23-pinctrl", }, | 276 | { .compatible = "fsl,imx23-pinctrl", }, |
277 | { /* sentinel */ } | 277 | { /* sentinel */ } |
278 | }; | 278 | }; |
@@ -285,7 +285,7 @@ static struct platform_driver imx23_pinctrl_driver = { | |||
285 | .of_match_table = imx23_pinctrl_of_match, | 285 | .of_match_table = imx23_pinctrl_of_match, |
286 | }, | 286 | }, |
287 | .probe = imx23_pinctrl_probe, | 287 | .probe = imx23_pinctrl_probe, |
288 | .remove = __devexit_p(mxs_pinctrl_remove), | 288 | .remove = mxs_pinctrl_remove, |
289 | }; | 289 | }; |
290 | 290 | ||
291 | static int __init imx23_pinctrl_init(void) | 291 | static int __init imx23_pinctrl_init(void) |
diff --git a/drivers/pinctrl/pinctrl-imx28.c b/drivers/pinctrl/pinctrl-imx28.c index 0f5b2122b1ba..e1af2ba89004 100644 --- a/drivers/pinctrl/pinctrl-imx28.c +++ b/drivers/pinctrl/pinctrl-imx28.c | |||
@@ -388,7 +388,7 @@ static int __devinit imx28_pinctrl_probe(struct platform_device *pdev) | |||
388 | return mxs_pinctrl_probe(pdev, &imx28_pinctrl_data); | 388 | return mxs_pinctrl_probe(pdev, &imx28_pinctrl_data); |
389 | } | 389 | } |
390 | 390 | ||
391 | static struct of_device_id imx28_pinctrl_of_match[] __devinitdata = { | 391 | static struct of_device_id imx28_pinctrl_of_match[] = { |
392 | { .compatible = "fsl,imx28-pinctrl", }, | 392 | { .compatible = "fsl,imx28-pinctrl", }, |
393 | { /* sentinel */ } | 393 | { /* sentinel */ } |
394 | }; | 394 | }; |
@@ -401,7 +401,7 @@ static struct platform_driver imx28_pinctrl_driver = { | |||
401 | .of_match_table = imx28_pinctrl_of_match, | 401 | .of_match_table = imx28_pinctrl_of_match, |
402 | }, | 402 | }, |
403 | .probe = imx28_pinctrl_probe, | 403 | .probe = imx28_pinctrl_probe, |
404 | .remove = __devexit_p(mxs_pinctrl_remove), | 404 | .remove = mxs_pinctrl_remove, |
405 | }; | 405 | }; |
406 | 406 | ||
407 | static int __init imx28_pinctrl_init(void) | 407 | static int __init imx28_pinctrl_init(void) |
diff --git a/drivers/pinctrl/pinctrl-imx35.c b/drivers/pinctrl/pinctrl-imx35.c index 82f109e26f27..1dbf5278acec 100644 --- a/drivers/pinctrl/pinctrl-imx35.c +++ b/drivers/pinctrl/pinctrl-imx35.c | |||
@@ -1559,7 +1559,7 @@ static struct imx_pinctrl_soc_info imx35_pinctrl_info = { | |||
1559 | .npin_regs = ARRAY_SIZE(imx35_pin_regs), | 1559 | .npin_regs = ARRAY_SIZE(imx35_pin_regs), |
1560 | }; | 1560 | }; |
1561 | 1561 | ||
1562 | static struct of_device_id imx35_pinctrl_of_match[] __devinitdata = { | 1562 | static struct of_device_id imx35_pinctrl_of_match[] = { |
1563 | { .compatible = "fsl,imx35-iomuxc", }, | 1563 | { .compatible = "fsl,imx35-iomuxc", }, |
1564 | { /* sentinel */ } | 1564 | { /* sentinel */ } |
1565 | }; | 1565 | }; |
@@ -1576,7 +1576,7 @@ static struct platform_driver imx35_pinctrl_driver = { | |||
1576 | .of_match_table = of_match_ptr(imx35_pinctrl_of_match), | 1576 | .of_match_table = of_match_ptr(imx35_pinctrl_of_match), |
1577 | }, | 1577 | }, |
1578 | .probe = imx35_pinctrl_probe, | 1578 | .probe = imx35_pinctrl_probe, |
1579 | .remove = __devexit_p(imx_pinctrl_remove), | 1579 | .remove = imx_pinctrl_remove, |
1580 | }; | 1580 | }; |
1581 | 1581 | ||
1582 | static int __init imx35_pinctrl_init(void) | 1582 | static int __init imx35_pinctrl_init(void) |
diff --git a/drivers/pinctrl/pinctrl-imx51.c b/drivers/pinctrl/pinctrl-imx51.c index fb8468966779..131216558a7b 100644 --- a/drivers/pinctrl/pinctrl-imx51.c +++ b/drivers/pinctrl/pinctrl-imx51.c | |||
@@ -1286,7 +1286,7 @@ static struct imx_pinctrl_soc_info imx51_pinctrl_info = { | |||
1286 | .npin_regs = ARRAY_SIZE(imx51_pin_regs), | 1286 | .npin_regs = ARRAY_SIZE(imx51_pin_regs), |
1287 | }; | 1287 | }; |
1288 | 1288 | ||
1289 | static struct of_device_id imx51_pinctrl_of_match[] __devinitdata = { | 1289 | static struct of_device_id imx51_pinctrl_of_match[] = { |
1290 | { .compatible = "fsl,imx51-iomuxc", }, | 1290 | { .compatible = "fsl,imx51-iomuxc", }, |
1291 | { /* sentinel */ } | 1291 | { /* sentinel */ } |
1292 | }; | 1292 | }; |
@@ -1303,7 +1303,7 @@ static struct platform_driver imx51_pinctrl_driver = { | |||
1303 | .of_match_table = of_match_ptr(imx51_pinctrl_of_match), | 1303 | .of_match_table = of_match_ptr(imx51_pinctrl_of_match), |
1304 | }, | 1304 | }, |
1305 | .probe = imx51_pinctrl_probe, | 1305 | .probe = imx51_pinctrl_probe, |
1306 | .remove = __devexit_p(imx_pinctrl_remove), | 1306 | .remove = imx_pinctrl_remove, |
1307 | }; | 1307 | }; |
1308 | 1308 | ||
1309 | static int __init imx51_pinctrl_init(void) | 1309 | static int __init imx51_pinctrl_init(void) |
diff --git a/drivers/pinctrl/pinctrl-imx53.c b/drivers/pinctrl/pinctrl-imx53.c index 783feb1ce064..ec4048691775 100644 --- a/drivers/pinctrl/pinctrl-imx53.c +++ b/drivers/pinctrl/pinctrl-imx53.c | |||
@@ -1613,7 +1613,7 @@ static struct imx_pinctrl_soc_info imx53_pinctrl_info = { | |||
1613 | .npin_regs = ARRAY_SIZE(imx53_pin_regs), | 1613 | .npin_regs = ARRAY_SIZE(imx53_pin_regs), |
1614 | }; | 1614 | }; |
1615 | 1615 | ||
1616 | static struct of_device_id imx53_pinctrl_of_match[] __devinitdata = { | 1616 | static struct of_device_id imx53_pinctrl_of_match[] = { |
1617 | { .compatible = "fsl,imx53-iomuxc", }, | 1617 | { .compatible = "fsl,imx53-iomuxc", }, |
1618 | { /* sentinel */ } | 1618 | { /* sentinel */ } |
1619 | }; | 1619 | }; |
@@ -1630,7 +1630,7 @@ static struct platform_driver imx53_pinctrl_driver = { | |||
1630 | .of_match_table = of_match_ptr(imx53_pinctrl_of_match), | 1630 | .of_match_table = of_match_ptr(imx53_pinctrl_of_match), |
1631 | }, | 1631 | }, |
1632 | .probe = imx53_pinctrl_probe, | 1632 | .probe = imx53_pinctrl_probe, |
1633 | .remove = __devexit_p(imx_pinctrl_remove), | 1633 | .remove = imx_pinctrl_remove, |
1634 | }; | 1634 | }; |
1635 | 1635 | ||
1636 | static int __init imx53_pinctrl_init(void) | 1636 | static int __init imx53_pinctrl_init(void) |
diff --git a/drivers/pinctrl/pinctrl-imx6q.c b/drivers/pinctrl/pinctrl-imx6q.c index e9bf71fbedca..844ab13c93a3 100644 --- a/drivers/pinctrl/pinctrl-imx6q.c +++ b/drivers/pinctrl/pinctrl-imx6q.c | |||
@@ -2297,7 +2297,7 @@ static struct imx_pinctrl_soc_info imx6q_pinctrl_info = { | |||
2297 | .npin_regs = ARRAY_SIZE(imx6q_pin_regs), | 2297 | .npin_regs = ARRAY_SIZE(imx6q_pin_regs), |
2298 | }; | 2298 | }; |
2299 | 2299 | ||
2300 | static struct of_device_id imx6q_pinctrl_of_match[] __devinitdata = { | 2300 | static struct of_device_id imx6q_pinctrl_of_match[] = { |
2301 | { .compatible = "fsl,imx6q-iomuxc", }, | 2301 | { .compatible = "fsl,imx6q-iomuxc", }, |
2302 | { /* sentinel */ } | 2302 | { /* sentinel */ } |
2303 | }; | 2303 | }; |
@@ -2314,7 +2314,7 @@ static struct platform_driver imx6q_pinctrl_driver = { | |||
2314 | .of_match_table = of_match_ptr(imx6q_pinctrl_of_match), | 2314 | .of_match_table = of_match_ptr(imx6q_pinctrl_of_match), |
2315 | }, | 2315 | }, |
2316 | .probe = imx6q_pinctrl_probe, | 2316 | .probe = imx6q_pinctrl_probe, |
2317 | .remove = __devexit_p(imx_pinctrl_remove), | 2317 | .remove = imx_pinctrl_remove, |
2318 | }; | 2318 | }; |
2319 | 2319 | ||
2320 | static int __init imx6q_pinctrl_init(void) | 2320 | static int __init imx6q_pinctrl_init(void) |
diff --git a/drivers/pinctrl/pinctrl-kirkwood.c b/drivers/pinctrl/pinctrl-kirkwood.c deleted file mode 100644 index 9a74ef674a0e..000000000000 --- a/drivers/pinctrl/pinctrl-kirkwood.c +++ /dev/null | |||
@@ -1,472 +0,0 @@ | |||
1 | /* | ||
2 | * Marvell Kirkwood pinctrl driver based on mvebu pinctrl core | ||
3 | * | ||
4 | * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/err.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_device.h> | ||
20 | #include <linux/pinctrl/pinctrl.h> | ||
21 | |||
22 | #include "pinctrl-mvebu.h" | ||
23 | |||
24 | #define V(f6180, f6190, f6192, f6281, f6282) \ | ||
25 | ((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \ | ||
26 | (f6281 << 3) | (f6282 << 4)) | ||
27 | |||
28 | enum kirkwood_variant { | ||
29 | VARIANT_MV88F6180 = V(1, 0, 0, 0, 0), | ||
30 | VARIANT_MV88F6190 = V(0, 1, 0, 0, 0), | ||
31 | VARIANT_MV88F6192 = V(0, 0, 1, 0, 0), | ||
32 | VARIANT_MV88F6281 = V(0, 0, 0, 1, 0), | ||
33 | VARIANT_MV88F6282 = V(0, 0, 0, 0, 1), | ||
34 | }; | ||
35 | |||
36 | static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = { | ||
37 | MPP_MODE(0, | ||
38 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
39 | MPP_VAR_FUNCTION(0x1, "nand", "io2", V(1, 1, 1, 1, 1)), | ||
40 | MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1))), | ||
41 | MPP_MODE(1, | ||
42 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
43 | MPP_VAR_FUNCTION(0x1, "nand", "io3", V(1, 1, 1, 1, 1)), | ||
44 | MPP_VAR_FUNCTION(0x2, "spi", "mosi", V(1, 1, 1, 1, 1))), | ||
45 | MPP_MODE(2, | ||
46 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
47 | MPP_VAR_FUNCTION(0x1, "nand", "io4", V(1, 1, 1, 1, 1)), | ||
48 | MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1))), | ||
49 | MPP_MODE(3, | ||
50 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
51 | MPP_VAR_FUNCTION(0x1, "nand", "io5", V(1, 1, 1, 1, 1)), | ||
52 | MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1))), | ||
53 | MPP_MODE(4, | ||
54 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
55 | MPP_VAR_FUNCTION(0x1, "nand", "io6", V(1, 1, 1, 1, 1)), | ||
56 | MPP_VAR_FUNCTION(0x2, "uart0", "rxd", V(1, 1, 1, 1, 1)), | ||
57 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), | ||
58 | MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1)), | ||
59 | MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0))), | ||
60 | MPP_MODE(5, | ||
61 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
62 | MPP_VAR_FUNCTION(0x1, "nand", "io7", V(1, 1, 1, 1, 1)), | ||
63 | MPP_VAR_FUNCTION(0x2, "uart0", "txd", V(1, 1, 1, 1, 1)), | ||
64 | MPP_VAR_FUNCTION(0x4, "ptp", "trig", V(1, 1, 1, 1, 0)), | ||
65 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), | ||
66 | MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))), | ||
67 | MPP_MODE(6, | ||
68 | MPP_VAR_FUNCTION(0x0, "sysrst", "out", V(1, 1, 1, 1, 1)), | ||
69 | MPP_VAR_FUNCTION(0x1, "spi", "mosi", V(1, 1, 1, 1, 1)), | ||
70 | MPP_VAR_FUNCTION(0x2, "ptp", "trig", V(1, 1, 1, 1, 0))), | ||
71 | MPP_MODE(7, | ||
72 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
73 | MPP_VAR_FUNCTION(0x1, "pex", "rsto", V(1, 1, 1, 1, 0)), | ||
74 | MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1)), | ||
75 | MPP_VAR_FUNCTION(0x3, "ptp", "trig", V(1, 1, 1, 1, 0)), | ||
76 | MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))), | ||
77 | MPP_MODE(8, | ||
78 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
79 | MPP_VAR_FUNCTION(0x1, "twsi0", "sda", V(1, 1, 1, 1, 1)), | ||
80 | MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)), | ||
81 | MPP_VAR_FUNCTION(0x3, "uart1", "rts", V(1, 1, 1, 1, 1)), | ||
82 | MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr", V(0, 1, 1, 1, 1)), | ||
83 | MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)), | ||
84 | MPP_VAR_FUNCTION(0xc, "ptp", "clk", V(1, 1, 1, 1, 0)), | ||
85 | MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))), | ||
86 | MPP_MODE(9, | ||
87 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
88 | MPP_VAR_FUNCTION(0x1, "twsi0", "sck", V(1, 1, 1, 1, 1)), | ||
89 | MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)), | ||
90 | MPP_VAR_FUNCTION(0x3, "uart1", "cts", V(1, 1, 1, 1, 1)), | ||
91 | MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)), | ||
92 | MPP_VAR_FUNCTION(0xc, "ptp", "evreq", V(1, 1, 1, 1, 0)), | ||
93 | MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))), | ||
94 | MPP_MODE(10, | ||
95 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
96 | MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1)), | ||
97 | MPP_VAR_FUNCTION(0X3, "uart0", "txd", V(1, 1, 1, 1, 1)), | ||
98 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), | ||
99 | MPP_VAR_FUNCTION(0xc, "ptp", "trig", V(1, 1, 1, 1, 0))), | ||
100 | MPP_MODE(11, | ||
101 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
102 | MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1)), | ||
103 | MPP_VAR_FUNCTION(0x3, "uart0", "rxd", V(1, 1, 1, 1, 1)), | ||
104 | MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq", V(1, 1, 1, 1, 0)), | ||
105 | MPP_VAR_FUNCTION(0xc, "ptp-2", "trig", V(1, 1, 1, 1, 0)), | ||
106 | MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0)), | ||
107 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1))), | ||
108 | MPP_MODE(12, | ||
109 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 0, 1)), | ||
110 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)), | ||
111 | MPP_VAR_FUNCTION(0x1, "sdio", "clk", V(1, 1, 1, 1, 1)), | ||
112 | MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1)), | ||
113 | MPP_VAR_FUNCTION(0xb, "spi", "mosi", V(0, 0, 0, 0, 1)), | ||
114 | MPP_VAR_FUNCTION(0xd, "twsi1", "sda", V(0, 0, 0, 0, 1))), | ||
115 | MPP_MODE(13, | ||
116 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
117 | MPP_VAR_FUNCTION(0x1, "sdio", "cmd", V(1, 1, 1, 1, 1)), | ||
118 | MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)), | ||
119 | MPP_VAR_FUNCTION(0xa, "audio", "rmclk", V(0, 0, 0, 0, 1)), | ||
120 | MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))), | ||
121 | MPP_MODE(14, | ||
122 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
123 | MPP_VAR_FUNCTION(0x1, "sdio", "d0", V(1, 1, 1, 1, 1)), | ||
124 | MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)), | ||
125 | MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V(0, 0, 1, 1, 1)), | ||
126 | MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1)), | ||
127 | MPP_VAR_FUNCTION(0xb, "audio-1", "sdi", V(0, 0, 0, 0, 1)), | ||
128 | MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))), | ||
129 | MPP_MODE(15, | ||
130 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
131 | MPP_VAR_FUNCTION(0x1, "sdio", "d1", V(1, 1, 1, 1, 1)), | ||
132 | MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)), | ||
133 | MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)), | ||
134 | MPP_VAR_FUNCTION(0x4, "sata0", "act", V(0, 1, 1, 1, 1)), | ||
135 | MPP_VAR_FUNCTION(0xb, "spi", "cs", V(0, 0, 0, 0, 1))), | ||
136 | MPP_MODE(16, | ||
137 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
138 | MPP_VAR_FUNCTION(0x1, "sdio", "d2", V(1, 1, 1, 1, 1)), | ||
139 | MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)), | ||
140 | MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)), | ||
141 | MPP_VAR_FUNCTION(0x4, "sata1", "act", V(0, 0, 1, 1, 1)), | ||
142 | MPP_VAR_FUNCTION(0xb, "lcd", "extclk", V(0, 0, 0, 0, 1)), | ||
143 | MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))), | ||
144 | MPP_MODE(17, | ||
145 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
146 | MPP_VAR_FUNCTION(0x1, "sdio", "d3", V(1, 1, 1, 1, 1)), | ||
147 | MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V(0, 1, 1, 1, 1)), | ||
148 | MPP_VAR_FUNCTION(0xa, "sata1", "act", V(0, 0, 0, 0, 1)), | ||
149 | MPP_VAR_FUNCTION(0xd, "twsi1", "sck", V(0, 0, 0, 0, 1))), | ||
150 | MPP_MODE(18, | ||
151 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
152 | MPP_VAR_FUNCTION(0x1, "nand", "io0", V(1, 1, 1, 1, 1)), | ||
153 | MPP_VAR_FUNCTION(0x2, "pex", "clkreq", V(0, 0, 0, 0, 1))), | ||
154 | MPP_MODE(19, | ||
155 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
156 | MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1))), | ||
157 | MPP_MODE(20, | ||
158 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
159 | MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1)), | ||
160 | MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)), | ||
161 | MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1)), | ||
162 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1)), | ||
163 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), | ||
164 | MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1)), | ||
165 | MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0))), | ||
166 | MPP_MODE(21, | ||
167 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
168 | MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1)), | ||
169 | MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1)), | ||
170 | MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1)), | ||
171 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0)), | ||
172 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1)), | ||
173 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), | ||
174 | MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1))), | ||
175 | MPP_MODE(22, | ||
176 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
177 | MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1)), | ||
178 | MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1)), | ||
179 | MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1)), | ||
180 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0)), | ||
181 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1)), | ||
182 | MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)), | ||
183 | MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1))), | ||
184 | MPP_MODE(23, | ||
185 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
186 | MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1)), | ||
187 | MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1)), | ||
188 | MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1)), | ||
189 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0)), | ||
190 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1)), | ||
191 | MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)), | ||
192 | MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1))), | ||
193 | MPP_MODE(24, | ||
194 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
195 | MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1)), | ||
196 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1)), | ||
197 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1)), | ||
198 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0)), | ||
199 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1)), | ||
200 | MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1))), | ||
201 | MPP_MODE(25, | ||
202 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
203 | MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1)), | ||
204 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1)), | ||
205 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1)), | ||
206 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0)), | ||
207 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1)), | ||
208 | MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1))), | ||
209 | MPP_MODE(26, | ||
210 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
211 | MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1)), | ||
212 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1)), | ||
213 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1)), | ||
214 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0)), | ||
215 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1)), | ||
216 | MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1))), | ||
217 | MPP_MODE(27, | ||
218 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
219 | MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1)), | ||
220 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1)), | ||
221 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1)), | ||
222 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0)), | ||
223 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1)), | ||
224 | MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1))), | ||
225 | MPP_MODE(28, | ||
226 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
227 | MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1)), | ||
228 | MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1)), | ||
229 | MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1)), | ||
230 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0)), | ||
231 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1)), | ||
232 | MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1))), | ||
233 | MPP_MODE(29, | ||
234 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
235 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1)), | ||
236 | MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1)), | ||
237 | MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1)), | ||
238 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0)), | ||
239 | MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1))), | ||
240 | MPP_MODE(30, | ||
241 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
242 | MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 1, 1, 1)), | ||
243 | MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 1, 1, 1)), | ||
244 | MPP_VAR_FUNCTION(0x3, "ge1", "rxctl", V(0, 1, 1, 1, 1)), | ||
245 | MPP_VAR_FUNCTION(0xb, "lcd", "d10", V(0, 0, 0, 0, 1))), | ||
246 | MPP_MODE(31, | ||
247 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
248 | MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 1, 1, 1)), | ||
249 | MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 1, 1, 1)), | ||
250 | MPP_VAR_FUNCTION(0x3, "ge1", "rxclk", V(0, 1, 1, 1, 1)), | ||
251 | MPP_VAR_FUNCTION(0xb, "lcd", "d11", V(0, 0, 0, 0, 1))), | ||
252 | MPP_MODE(32, | ||
253 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
254 | MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 1, 1, 1)), | ||
255 | MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 1, 1, 1)), | ||
256 | MPP_VAR_FUNCTION(0x3, "ge1", "txclko", V(0, 1, 1, 1, 1)), | ||
257 | MPP_VAR_FUNCTION(0xb, "lcd", "d12", V(0, 0, 0, 0, 1))), | ||
258 | MPP_MODE(33, | ||
259 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 1, 1, 1, 1)), | ||
260 | MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 1, 1, 1)), | ||
261 | MPP_VAR_FUNCTION(0x3, "ge1", "txctl", V(0, 1, 1, 1, 1)), | ||
262 | MPP_VAR_FUNCTION(0xb, "lcd", "d13", V(0, 0, 0, 0, 1))), | ||
263 | MPP_MODE(34, | ||
264 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
265 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 1, 1, 1)), | ||
266 | MPP_VAR_FUNCTION(0x3, "ge1", "txen", V(0, 1, 1, 1, 1)), | ||
267 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1)), | ||
268 | MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1))), | ||
269 | MPP_MODE(35, | ||
270 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
271 | MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)), | ||
272 | MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1)), | ||
273 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), | ||
274 | MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1)), | ||
275 | MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1))), | ||
276 | MPP_MODE(36, | ||
277 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
278 | MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1)), | ||
279 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1)), | ||
280 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1)), | ||
281 | MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1))), | ||
282 | MPP_MODE(37, | ||
283 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
284 | MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1)), | ||
285 | MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1)), | ||
286 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1)), | ||
287 | MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1))), | ||
288 | MPP_MODE(38, | ||
289 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
290 | MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1)), | ||
291 | MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1)), | ||
292 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1)), | ||
293 | MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1))), | ||
294 | MPP_MODE(39, | ||
295 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
296 | MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1)), | ||
297 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1)), | ||
298 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1)), | ||
299 | MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1))), | ||
300 | MPP_MODE(40, | ||
301 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
302 | MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1)), | ||
303 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1)), | ||
304 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1)), | ||
305 | MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1))), | ||
306 | MPP_MODE(41, | ||
307 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
308 | MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1)), | ||
309 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1)), | ||
310 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1)), | ||
311 | MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1))), | ||
312 | MPP_MODE(42, | ||
313 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
314 | MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1)), | ||
315 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1)), | ||
316 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1)), | ||
317 | MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1))), | ||
318 | MPP_MODE(43, | ||
319 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
320 | MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1)), | ||
321 | MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1)), | ||
322 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1)), | ||
323 | MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1))), | ||
324 | MPP_MODE(44, | ||
325 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
326 | MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1)), | ||
327 | MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1)), | ||
328 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1)), | ||
329 | MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1))), | ||
330 | MPP_MODE(45, | ||
331 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
332 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 1)), | ||
333 | MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 0, 1, 1)), | ||
334 | MPP_VAR_FUNCTION(0xb, "lcd", "e", V(0, 0, 0, 0, 1))), | ||
335 | MPP_MODE(46, | ||
336 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
337 | MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 0, 1, 1)), | ||
338 | MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 0, 1, 1)), | ||
339 | MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1))), | ||
340 | MPP_MODE(47, | ||
341 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
342 | MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 0, 1, 1)), | ||
343 | MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 0, 1, 1)), | ||
344 | MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))), | ||
345 | MPP_MODE(48, | ||
346 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
347 | MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 0, 1, 1)), | ||
348 | MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 0, 1, 1)), | ||
349 | MPP_VAR_FUNCTION(0xb, "lcd", "d16", V(0, 0, 0, 0, 1))), | ||
350 | MPP_MODE(49, | ||
351 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)), | ||
352 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 0, 0, 0, 1)), | ||
353 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 0)), | ||
354 | MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 0, 1, 1)), | ||
355 | MPP_VAR_FUNCTION(0x5, "ptp", "clk", V(0, 0, 0, 1, 0)), | ||
356 | MPP_VAR_FUNCTION(0xa, "pex", "clkreq", V(0, 0, 0, 0, 1)), | ||
357 | MPP_VAR_FUNCTION(0xb, "lcd", "d17", V(0, 0, 0, 0, 1))), | ||
358 | }; | ||
359 | |||
360 | static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = { | ||
361 | MPP_REG_CTRL(0, 29), | ||
362 | }; | ||
363 | |||
364 | static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = { | ||
365 | MPP_GPIO_RANGE(0, 0, 0, 30), | ||
366 | }; | ||
367 | |||
368 | static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = { | ||
369 | MPP_REG_CTRL(0, 35), | ||
370 | }; | ||
371 | |||
372 | static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = { | ||
373 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
374 | MPP_GPIO_RANGE(1, 32, 32, 4), | ||
375 | }; | ||
376 | |||
377 | static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = { | ||
378 | MPP_REG_CTRL(0, 49), | ||
379 | }; | ||
380 | |||
381 | static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = { | ||
382 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
383 | MPP_GPIO_RANGE(1, 32, 32, 18), | ||
384 | }; | ||
385 | |||
386 | static struct mvebu_pinctrl_soc_info mv88f6180_info = { | ||
387 | .variant = VARIANT_MV88F6180, | ||
388 | .controls = mv88f6180_mpp_controls, | ||
389 | .ncontrols = ARRAY_SIZE(mv88f6180_mpp_controls), | ||
390 | .modes = mv88f6xxx_mpp_modes, | ||
391 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
392 | .gpioranges = mv88f6180_gpio_ranges, | ||
393 | .ngpioranges = ARRAY_SIZE(mv88f6180_gpio_ranges), | ||
394 | }; | ||
395 | |||
396 | static struct mvebu_pinctrl_soc_info mv88f6190_info = { | ||
397 | .variant = VARIANT_MV88F6190, | ||
398 | .controls = mv88f619x_mpp_controls, | ||
399 | .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), | ||
400 | .modes = mv88f6xxx_mpp_modes, | ||
401 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
402 | .gpioranges = mv88f619x_gpio_ranges, | ||
403 | .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), | ||
404 | }; | ||
405 | |||
406 | static struct mvebu_pinctrl_soc_info mv88f6192_info = { | ||
407 | .variant = VARIANT_MV88F6192, | ||
408 | .controls = mv88f619x_mpp_controls, | ||
409 | .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), | ||
410 | .modes = mv88f6xxx_mpp_modes, | ||
411 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
412 | .gpioranges = mv88f619x_gpio_ranges, | ||
413 | .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), | ||
414 | }; | ||
415 | |||
416 | static struct mvebu_pinctrl_soc_info mv88f6281_info = { | ||
417 | .variant = VARIANT_MV88F6281, | ||
418 | .controls = mv88f628x_mpp_controls, | ||
419 | .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), | ||
420 | .modes = mv88f6xxx_mpp_modes, | ||
421 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
422 | .gpioranges = mv88f628x_gpio_ranges, | ||
423 | .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), | ||
424 | }; | ||
425 | |||
426 | static struct mvebu_pinctrl_soc_info mv88f6282_info = { | ||
427 | .variant = VARIANT_MV88F6282, | ||
428 | .controls = mv88f628x_mpp_controls, | ||
429 | .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), | ||
430 | .modes = mv88f6xxx_mpp_modes, | ||
431 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
432 | .gpioranges = mv88f628x_gpio_ranges, | ||
433 | .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), | ||
434 | }; | ||
435 | |||
436 | static struct of_device_id kirkwood_pinctrl_of_match[] __devinitdata = { | ||
437 | { .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info }, | ||
438 | { .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info }, | ||
439 | { .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info }, | ||
440 | { .compatible = "marvell,88f6281-pinctrl", .data = &mv88f6281_info }, | ||
441 | { .compatible = "marvell,88f6282-pinctrl", .data = &mv88f6282_info }, | ||
442 | { } | ||
443 | }; | ||
444 | |||
445 | static int __devinit kirkwood_pinctrl_probe(struct platform_device *pdev) | ||
446 | { | ||
447 | const struct of_device_id *match = | ||
448 | of_match_device(kirkwood_pinctrl_of_match, &pdev->dev); | ||
449 | pdev->dev.platform_data = match->data; | ||
450 | return mvebu_pinctrl_probe(pdev); | ||
451 | } | ||
452 | |||
453 | static int __devexit kirkwood_pinctrl_remove(struct platform_device *pdev) | ||
454 | { | ||
455 | return mvebu_pinctrl_remove(pdev); | ||
456 | } | ||
457 | |||
458 | static struct platform_driver kirkwood_pinctrl_driver = { | ||
459 | .driver = { | ||
460 | .name = "kirkwood-pinctrl", | ||
461 | .owner = THIS_MODULE, | ||
462 | .of_match_table = of_match_ptr(kirkwood_pinctrl_of_match), | ||
463 | }, | ||
464 | .probe = kirkwood_pinctrl_probe, | ||
465 | .remove = __devexit_p(kirkwood_pinctrl_remove), | ||
466 | }; | ||
467 | |||
468 | module_platform_driver(kirkwood_pinctrl_driver); | ||
469 | |||
470 | MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>"); | ||
471 | MODULE_DESCRIPTION("Marvell Kirkwood pinctrl driver"); | ||
472 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c index 07ba7682cf22..15f501d89026 100644 --- a/drivers/pinctrl/pinctrl-lantiq.c +++ b/drivers/pinctrl/pinctrl-lantiq.c | |||
@@ -46,8 +46,8 @@ static int ltq_get_group_pins(struct pinctrl_dev *pctrldev, | |||
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | 48 | ||
49 | void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, | 49 | static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, |
50 | struct pinctrl_map *map, unsigned num_maps) | 50 | struct pinctrl_map *map, unsigned num_maps) |
51 | { | 51 | { |
52 | int i; | 52 | int i; |
53 | 53 | ||
@@ -128,10 +128,10 @@ static int ltq_pinctrl_dt_subnode_size(struct device_node *np) | |||
128 | return ret; | 128 | return ret; |
129 | } | 129 | } |
130 | 130 | ||
131 | int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, | 131 | static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, |
132 | struct device_node *np_config, | 132 | struct device_node *np_config, |
133 | struct pinctrl_map **map, | 133 | struct pinctrl_map **map, |
134 | unsigned *num_maps) | 134 | unsigned *num_maps) |
135 | { | 135 | { |
136 | struct pinctrl_map *tmp; | 136 | struct pinctrl_map *tmp; |
137 | struct device_node *np; | 137 | struct device_node *np; |
@@ -275,16 +275,6 @@ static int ltq_pmx_enable(struct pinctrl_dev *pctrldev, | |||
275 | return 0; | 275 | return 0; |
276 | } | 276 | } |
277 | 277 | ||
278 | static void ltq_pmx_disable(struct pinctrl_dev *pctrldev, | ||
279 | unsigned func, | ||
280 | unsigned group) | ||
281 | { | ||
282 | /* | ||
283 | * Nothing to do here. However, pinconf_check_ops() requires this | ||
284 | * callback to be defined. | ||
285 | */ | ||
286 | } | ||
287 | |||
288 | static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev, | 278 | static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev, |
289 | struct pinctrl_gpio_range *range, | 279 | struct pinctrl_gpio_range *range, |
290 | unsigned pin) | 280 | unsigned pin) |
@@ -312,7 +302,6 @@ static struct pinmux_ops ltq_pmx_ops = { | |||
312 | .get_function_name = ltq_pmx_func_name, | 302 | .get_function_name = ltq_pmx_func_name, |
313 | .get_function_groups = ltq_pmx_get_groups, | 303 | .get_function_groups = ltq_pmx_get_groups, |
314 | .enable = ltq_pmx_enable, | 304 | .enable = ltq_pmx_enable, |
315 | .disable = ltq_pmx_disable, | ||
316 | .gpio_request_enable = ltq_pmx_gpio_request_enable, | 305 | .gpio_request_enable = ltq_pmx_gpio_request_enable, |
317 | }; | 306 | }; |
318 | 307 | ||
diff --git a/drivers/pinctrl/pinctrl-mmp2.c b/drivers/pinctrl/pinctrl-mmp2.c index 2cfed552bbe4..4fbb3db3f1c1 100644 --- a/drivers/pinctrl/pinctrl-mmp2.c +++ b/drivers/pinctrl/pinctrl-mmp2.c | |||
@@ -691,7 +691,7 @@ static int __devinit mmp2_pinmux_probe(struct platform_device *pdev) | |||
691 | return pxa3xx_pinctrl_register(pdev, &mmp2_info); | 691 | return pxa3xx_pinctrl_register(pdev, &mmp2_info); |
692 | } | 692 | } |
693 | 693 | ||
694 | static int __devexit mmp2_pinmux_remove(struct platform_device *pdev) | 694 | static int mmp2_pinmux_remove(struct platform_device *pdev) |
695 | { | 695 | { |
696 | return pxa3xx_pinctrl_unregister(pdev); | 696 | return pxa3xx_pinctrl_unregister(pdev); |
697 | } | 697 | } |
@@ -702,7 +702,7 @@ static struct platform_driver mmp2_pinmux_driver = { | |||
702 | .owner = THIS_MODULE, | 702 | .owner = THIS_MODULE, |
703 | }, | 703 | }, |
704 | .probe = mmp2_pinmux_probe, | 704 | .probe = mmp2_pinmux_probe, |
705 | .remove = __devexit_p(mmp2_pinmux_remove), | 705 | .remove = mmp2_pinmux_remove, |
706 | }; | 706 | }; |
707 | 707 | ||
708 | static int __init mmp2_pinmux_init(void) | 708 | static int __init mmp2_pinmux_init(void) |
diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index 4ba4636b6a4a..180f16379ec1 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c | |||
@@ -319,7 +319,7 @@ static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, | |||
319 | seq_printf(s, "0x%lx", config); | 319 | seq_printf(s, "0x%lx", config); |
320 | } | 320 | } |
321 | 321 | ||
322 | struct pinconf_ops mxs_pinconf_ops = { | 322 | static struct pinconf_ops mxs_pinconf_ops = { |
323 | .pin_config_get = mxs_pinconf_get, | 323 | .pin_config_get = mxs_pinconf_get, |
324 | .pin_config_set = mxs_pinconf_set, | 324 | .pin_config_set = mxs_pinconf_set, |
325 | .pin_config_group_get = mxs_pinconf_group_get, | 325 | .pin_config_group_get = mxs_pinconf_group_get, |
@@ -522,7 +522,7 @@ err: | |||
522 | } | 522 | } |
523 | EXPORT_SYMBOL_GPL(mxs_pinctrl_probe); | 523 | EXPORT_SYMBOL_GPL(mxs_pinctrl_probe); |
524 | 524 | ||
525 | int __devexit mxs_pinctrl_remove(struct platform_device *pdev) | 525 | int mxs_pinctrl_remove(struct platform_device *pdev) |
526 | { | 526 | { |
527 | struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); | 527 | struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); |
528 | 528 | ||
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c index debaa75b0552..7d88ae352119 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c | |||
@@ -475,8 +475,10 @@ static const unsigned hsit_a_1_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9, | |||
475 | DB8500_PIN_AG9, DB8500_PIN_AG8, DB8500_PIN_AF8 }; | 475 | DB8500_PIN_AG9, DB8500_PIN_AG8, DB8500_PIN_AF8 }; |
476 | static const unsigned hsit_a_2_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9, | 476 | static const unsigned hsit_a_2_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9, |
477 | DB8500_PIN_AG9, DB8500_PIN_AG8 }; | 477 | DB8500_PIN_AG9, DB8500_PIN_AG8 }; |
478 | static const unsigned clkout_a_1_pins[] = { DB8500_PIN_AH7, DB8500_PIN_AJ6 }; | 478 | static const unsigned clkout1_a_1_pins[] = { DB8500_PIN_AH7 }; |
479 | static const unsigned clkout_a_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 }; | 479 | static const unsigned clkout1_a_2_pins[] = { DB8500_PIN_AG7 }; |
480 | static const unsigned clkout2_a_1_pins[] = { DB8500_PIN_AJ6 }; | ||
481 | static const unsigned clkout2_a_2_pins[] = { DB8500_PIN_AF7 }; | ||
480 | static const unsigned usb_a_1_pins[] = { DB8500_PIN_AF28, DB8500_PIN_AE29, | 482 | static const unsigned usb_a_1_pins[] = { DB8500_PIN_AF28, DB8500_PIN_AE29, |
481 | DB8500_PIN_AD29, DB8500_PIN_AC29, DB8500_PIN_AD28, DB8500_PIN_AD26, | 483 | DB8500_PIN_AD29, DB8500_PIN_AC29, DB8500_PIN_AD28, DB8500_PIN_AD26, |
482 | DB8500_PIN_AE26, DB8500_PIN_AG29, DB8500_PIN_AE27, DB8500_PIN_AD27, | 484 | DB8500_PIN_AE26, DB8500_PIN_AG29, DB8500_PIN_AE27, DB8500_PIN_AD27, |
@@ -592,7 +594,8 @@ static const unsigned stmmod_c_1_pins[] = { DB8500_PIN_C20, DB8500_PIN_B21, | |||
592 | DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24 }; | 594 | DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24 }; |
593 | static const unsigned usbsim_c_1_pins[] = { DB8500_PIN_D22 }; | 595 | static const unsigned usbsim_c_1_pins[] = { DB8500_PIN_D22 }; |
594 | static const unsigned mc4rstn_c_1_pins[] = { DB8500_PIN_AF25 }; | 596 | static const unsigned mc4rstn_c_1_pins[] = { DB8500_PIN_AF25 }; |
595 | static const unsigned clkout_c_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12 }; | 597 | static const unsigned clkout1_c_1_pins[] = { DB8500_PIN_AH13 }; |
598 | static const unsigned clkout2_c_1_pins[] = { DB8500_PIN_AH12 }; | ||
596 | static const unsigned i2c3_c_1_pins[] = { DB8500_PIN_AG12, DB8500_PIN_AH11 }; | 599 | static const unsigned i2c3_c_1_pins[] = { DB8500_PIN_AG12, DB8500_PIN_AH11 }; |
597 | static const unsigned spi0_c_1_pins[] = { DB8500_PIN_AH10, DB8500_PIN_AH9, | 600 | static const unsigned spi0_c_1_pins[] = { DB8500_PIN_AH10, DB8500_PIN_AH9, |
598 | DB8500_PIN_AG9, DB8500_PIN_AG8 }; | 601 | DB8500_PIN_AG9, DB8500_PIN_AG8 }; |
@@ -600,14 +603,66 @@ static const unsigned usbsim_c_2_pins[] = { DB8500_PIN_AF8 }; | |||
600 | static const unsigned i2c3_c_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 }; | 603 | static const unsigned i2c3_c_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 }; |
601 | 604 | ||
602 | /* Other C1 column */ | 605 | /* Other C1 column */ |
606 | static const unsigned u2rx_oc1_1_pins[] = { DB8500_PIN_AB2 }; | ||
607 | static const unsigned stmape_oc1_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4, | ||
608 | DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 }; | ||
609 | static const unsigned remap0_oc1_1_pins[] = { DB8500_PIN_E1 }; | ||
610 | static const unsigned remap1_oc1_1_pins[] = { DB8500_PIN_E2 }; | ||
611 | static const unsigned ptma9_oc1_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, | ||
612 | DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2, | ||
613 | DB8500_PIN_J2, DB8500_PIN_H1 }; | ||
603 | static const unsigned kp_oc1_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3, | 614 | static const unsigned kp_oc1_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3, |
604 | DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6, | 615 | DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6, |
605 | DB8500_PIN_D6, DB8500_PIN_B7 }; | 616 | DB8500_PIN_D6, DB8500_PIN_B7 }; |
617 | static const unsigned rf_oc1_1_pins[] = { DB8500_PIN_D8, DB8500_PIN_D9 }; | ||
618 | static const unsigned hxclk_oc1_1_pins[] = { DB8500_PIN_D16 }; | ||
619 | static const unsigned uartmodrx_oc1_1_pins[] = { DB8500_PIN_B17 }; | ||
620 | static const unsigned uartmodtx_oc1_1_pins[] = { DB8500_PIN_C16 }; | ||
621 | static const unsigned stmmod_oc1_1_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17, | ||
622 | DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 }; | ||
623 | static const unsigned hxgpio_oc1_1_pins[] = { DB8500_PIN_D21, DB8500_PIN_D20, | ||
624 | DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22, | ||
625 | DB8500_PIN_B24, DB8500_PIN_C22 }; | ||
626 | static const unsigned rf_oc1_2_pins[] = { DB8500_PIN_C23, DB8500_PIN_D23 }; | ||
606 | static const unsigned spi2_oc1_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12, | 627 | static const unsigned spi2_oc1_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12, |
607 | DB8500_PIN_AH12, DB8500_PIN_AH11 }; | 628 | DB8500_PIN_AH12, DB8500_PIN_AH11 }; |
608 | static const unsigned spi2_oc1_2_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12, | 629 | static const unsigned spi2_oc1_2_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12, |
609 | DB8500_PIN_AH11 }; | 630 | DB8500_PIN_AH11 }; |
610 | 631 | ||
632 | /* Other C2 column */ | ||
633 | static const unsigned sbag_oc2_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_AB2, | ||
634 | DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 }; | ||
635 | static const unsigned etmr4_oc2_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, | ||
636 | DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2, | ||
637 | DB8500_PIN_J2, DB8500_PIN_H1 }; | ||
638 | static const unsigned ptma9_oc2_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, | ||
639 | DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, | ||
640 | DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, | ||
641 | DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, | ||
642 | DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; | ||
643 | |||
644 | /* Other C3 column */ | ||
645 | static const unsigned stmmod_oc3_1_pins[] = { DB8500_PIN_AB2, DB8500_PIN_W2, | ||
646 | DB8500_PIN_W3, DB8500_PIN_V3, DB8500_PIN_V2 }; | ||
647 | static const unsigned stmmod_oc3_2_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, | ||
648 | DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 }; | ||
649 | static const unsigned uartmodrx_oc3_1_pins[] = { DB8500_PIN_H2 }; | ||
650 | static const unsigned uartmodtx_oc3_1_pins[] = { DB8500_PIN_J2 }; | ||
651 | static const unsigned etmr4_oc3_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, | ||
652 | DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, | ||
653 | DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, | ||
654 | DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, | ||
655 | DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; | ||
656 | |||
657 | /* Other C4 column */ | ||
658 | static const unsigned sbag_oc4_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, | ||
659 | DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H1 }; | ||
660 | static const unsigned hwobs_oc4_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, | ||
661 | DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, | ||
662 | DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, | ||
663 | DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, | ||
664 | DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; | ||
665 | |||
611 | #define DB8500_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \ | 666 | #define DB8500_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \ |
612 | .npins = ARRAY_SIZE(a##_pins), .altsetting = b } | 667 | .npins = ARRAY_SIZE(a##_pins), .altsetting = b } |
613 | 668 | ||
@@ -639,6 +694,7 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { | |||
639 | DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), | 694 | DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), |
640 | DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A), | 695 | DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A), |
641 | DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A), | 696 | DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A), |
697 | DB8500_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A), | ||
642 | DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A), | 698 | DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A), |
643 | DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A), | 699 | DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A), |
644 | DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A), | 700 | DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A), |
@@ -647,8 +703,10 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { | |||
647 | DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), | 703 | DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), |
648 | DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), | 704 | DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), |
649 | DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), | 705 | DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), |
650 | DB8500_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A), | 706 | DB8500_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A), |
651 | DB8500_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A), | 707 | DB8500_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A), |
708 | DB8500_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A), | ||
709 | DB8500_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A), | ||
652 | DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), | 710 | DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), |
653 | /* Altfunction B column */ | 711 | /* Altfunction B column */ |
654 | DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B), | 712 | DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B), |
@@ -720,15 +778,41 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { | |||
720 | DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C), | 778 | DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C), |
721 | DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C), | 779 | DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C), |
722 | DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C), | 780 | DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C), |
723 | DB8500_PIN_GROUP(clkout_c_1, NMK_GPIO_ALT_C), | 781 | DB8500_PIN_GROUP(clkout1_c_1, NMK_GPIO_ALT_C), |
782 | DB8500_PIN_GROUP(clkout2_c_1, NMK_GPIO_ALT_C), | ||
724 | DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C), | 783 | DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C), |
725 | DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C), | 784 | DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C), |
726 | DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C), | 785 | DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C), |
727 | DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C), | 786 | DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C), |
728 | /* Other alt C1 column */ | 787 | /* Other alt C1 column */ |
788 | DB8500_PIN_GROUP(u2rx_oc1_1, NMK_GPIO_ALT_C1), | ||
789 | DB8500_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1), | ||
790 | DB8500_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1), | ||
791 | DB8500_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1), | ||
792 | DB8500_PIN_GROUP(ptma9_oc1_1, NMK_GPIO_ALT_C1), | ||
729 | DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1), | 793 | DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1), |
794 | DB8500_PIN_GROUP(rf_oc1_1, NMK_GPIO_ALT_C1), | ||
795 | DB8500_PIN_GROUP(hxclk_oc1_1, NMK_GPIO_ALT_C1), | ||
796 | DB8500_PIN_GROUP(uartmodrx_oc1_1, NMK_GPIO_ALT_C1), | ||
797 | DB8500_PIN_GROUP(uartmodtx_oc1_1, NMK_GPIO_ALT_C1), | ||
798 | DB8500_PIN_GROUP(stmmod_oc1_1, NMK_GPIO_ALT_C1), | ||
799 | DB8500_PIN_GROUP(hxgpio_oc1_1, NMK_GPIO_ALT_C1), | ||
800 | DB8500_PIN_GROUP(rf_oc1_2, NMK_GPIO_ALT_C1), | ||
730 | DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1), | 801 | DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1), |
731 | DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1), | 802 | DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1), |
803 | /* Other alt C2 column */ | ||
804 | DB8500_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2), | ||
805 | DB8500_PIN_GROUP(etmr4_oc2_1, NMK_GPIO_ALT_C2), | ||
806 | DB8500_PIN_GROUP(ptma9_oc2_1, NMK_GPIO_ALT_C2), | ||
807 | /* Other alt C3 column */ | ||
808 | DB8500_PIN_GROUP(stmmod_oc3_1, NMK_GPIO_ALT_C3), | ||
809 | DB8500_PIN_GROUP(stmmod_oc3_2, NMK_GPIO_ALT_C3), | ||
810 | DB8500_PIN_GROUP(uartmodrx_oc3_1, NMK_GPIO_ALT_C3), | ||
811 | DB8500_PIN_GROUP(uartmodtx_oc3_1, NMK_GPIO_ALT_C3), | ||
812 | DB8500_PIN_GROUP(etmr4_oc3_1, NMK_GPIO_ALT_C3), | ||
813 | /* Other alt C4 column */ | ||
814 | DB8500_PIN_GROUP(sbag_oc4_1, NMK_GPIO_ALT_C4), | ||
815 | DB8500_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4), | ||
732 | }; | 816 | }; |
733 | 817 | ||
734 | /* We use this macro to define the groups applicable to a function */ | 818 | /* We use this macro to define the groups applicable to a function */ |
@@ -742,7 +826,7 @@ DB8500_FUNC_GROUPS(u1, "u1rxtx_a_1", "u1ctsrts_a_1"); | |||
742 | * only available on two pins in alternative function C | 826 | * only available on two pins in alternative function C |
743 | */ | 827 | */ |
744 | DB8500_FUNC_GROUPS(u2, "u2rxtx_b_1", "u2rxtx_c_1", "u2ctsrts_c_1", | 828 | DB8500_FUNC_GROUPS(u2, "u2rxtx_b_1", "u2rxtx_c_1", "u2ctsrts_c_1", |
745 | "u2rxtx_c_2", "u2rxtx_c_3"); | 829 | "u2rxtx_c_2", "u2rxtx_c_3", "u2rx_oc1_1"); |
746 | DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2"); | 830 | DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2"); |
747 | /* | 831 | /* |
748 | * MSP0 can only be on a certain set of pins, but the TX/RX pins can be | 832 | * MSP0 can only be on a certain set of pins, but the TX/RX pins can be |
@@ -757,7 +841,7 @@ DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1"); | |||
757 | DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1"); | 841 | DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1"); |
758 | DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1", | 842 | DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1", |
759 | "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1"); | 843 | "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1"); |
760 | DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1"); | 844 | DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_a_2", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1"); |
761 | DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1"); | 845 | DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1"); |
762 | DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1"); | 846 | DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1"); |
763 | DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1"); | 847 | DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1"); |
@@ -773,7 +857,8 @@ DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1"); | |||
773 | DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); | 857 | DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); |
774 | DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2", "mc1dir_a_1"); | 858 | DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2", "mc1dir_a_1"); |
775 | DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); | 859 | DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); |
776 | DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1"); | 860 | DB8500_FUNC_GROUPS(clkout, "clkout1_a_1", "clkout1_a_2", "clkout1_c_1", |
861 | "clkout2_a_1", "clkout2_a_2", "clkout2_c_1"); | ||
777 | DB8500_FUNC_GROUPS(usb, "usb_a_1"); | 862 | DB8500_FUNC_GROUPS(usb, "usb_a_1"); |
778 | DB8500_FUNC_GROUPS(trig, "trig_b_1"); | 863 | DB8500_FUNC_GROUPS(trig, "trig_b_1"); |
779 | DB8500_FUNC_GROUPS(i2c4, "i2c4_b_1"); | 864 | DB8500_FUNC_GROUPS(i2c4, "i2c4_b_1"); |
@@ -784,8 +869,10 @@ DB8500_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2"); | |||
784 | * so select one of each. | 869 | * so select one of each. |
785 | */ | 870 | */ |
786 | DB8500_FUNC_GROUPS(uartmod, "uartmodtx_b_1", "uartmodrx_b_1", "uartmodrx_b_2", | 871 | DB8500_FUNC_GROUPS(uartmod, "uartmodtx_b_1", "uartmodrx_b_1", "uartmodrx_b_2", |
787 | "uartmodrx_c_1", "uartmod_tx_c_1"); | 872 | "uartmodrx_c_1", "uartmod_tx_c_1", "uartmodrx_oc1_1", |
788 | DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1"); | 873 | "uartmodtx_oc1_1", "uartmodrx_oc3_1", "uartmodtx_oc3_1"); |
874 | DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1", "stmmod_oc1_1", | ||
875 | "stmmod_oc3_1", "stmmod_oc3_2"); | ||
789 | DB8500_FUNC_GROUPS(spi3, "spi3_b_1"); | 876 | DB8500_FUNC_GROUPS(spi3, "spi3_b_1"); |
790 | /* Select between CS0 on alt B or PS1 on alt C */ | 877 | /* Select between CS0 on alt B or PS1 on alt C */ |
791 | DB8500_FUNC_GROUPS(sm, "sm_b_1", "smcs0_b_1", "smcs1_b_1", "smcleale_c_1", | 878 | DB8500_FUNC_GROUPS(sm, "sm_b_1", "smcs0_b_1", "smcs1_b_1", "smcleale_c_1", |
@@ -799,13 +886,19 @@ DB8500_FUNC_GROUPS(ipjtag, "ipjtag_c_1"); | |||
799 | DB8500_FUNC_GROUPS(slim0, "slim0_c_1"); | 886 | DB8500_FUNC_GROUPS(slim0, "slim0_c_1"); |
800 | DB8500_FUNC_GROUPS(ms, "ms_c_1"); | 887 | DB8500_FUNC_GROUPS(ms, "ms_c_1"); |
801 | DB8500_FUNC_GROUPS(iptrigout, "iptrigout_c_1"); | 888 | DB8500_FUNC_GROUPS(iptrigout, "iptrigout_c_1"); |
802 | DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2"); | 889 | DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2", "stmape_oc1_1"); |
803 | DB8500_FUNC_GROUPS(mc5, "mc5_c_1"); | 890 | DB8500_FUNC_GROUPS(mc5, "mc5_c_1"); |
804 | DB8500_FUNC_GROUPS(usbsim, "usbsim_c_1", "usbsim_c_2"); | 891 | DB8500_FUNC_GROUPS(usbsim, "usbsim_c_1", "usbsim_c_2"); |
805 | DB8500_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c3_c_2"); | 892 | DB8500_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c3_c_2"); |
806 | DB8500_FUNC_GROUPS(spi0, "spi0_c_1"); | 893 | DB8500_FUNC_GROUPS(spi0, "spi0_c_1"); |
807 | DB8500_FUNC_GROUPS(spi2, "spi2_oc1_1", "spi2_oc1_2"); | 894 | DB8500_FUNC_GROUPS(spi2, "spi2_oc1_1", "spi2_oc1_2"); |
808 | 895 | DB8500_FUNC_GROUPS(remap, "remap0_oc1_1", "remap1_oc1_1"); | |
896 | DB8500_FUNC_GROUPS(sbag, "sbag_oc2_1", "sbag_oc4_1"); | ||
897 | DB8500_FUNC_GROUPS(ptm, "ptma9_oc1_1", "ptma9_oc2_1"); | ||
898 | DB8500_FUNC_GROUPS(rf, "rf_oc1_1", "rf_oc1_2"); | ||
899 | DB8500_FUNC_GROUPS(hx, "hxclk_oc1_1", "hxgpio_oc1_1"); | ||
900 | DB8500_FUNC_GROUPS(etm, "etmr4_oc2_1", "etmr4_oc3_1"); | ||
901 | DB8500_FUNC_GROUPS(hwobs, "hwobs_oc4_1"); | ||
809 | #define FUNCTION(fname) \ | 902 | #define FUNCTION(fname) \ |
810 | { \ | 903 | { \ |
811 | .name = #fname, \ | 904 | .name = #fname, \ |
@@ -858,6 +951,12 @@ static const struct nmk_function nmk_db8500_functions[] = { | |||
858 | FUNCTION(i2c3), | 951 | FUNCTION(i2c3), |
859 | FUNCTION(spi0), | 952 | FUNCTION(spi0), |
860 | FUNCTION(spi2), | 953 | FUNCTION(spi2), |
954 | FUNCTION(remap), | ||
955 | FUNCTION(ptm), | ||
956 | FUNCTION(rf), | ||
957 | FUNCTION(hx), | ||
958 | FUNCTION(etm), | ||
959 | FUNCTION(hwobs), | ||
861 | }; | 960 | }; |
862 | 961 | ||
863 | static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = { | 962 | static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = { |
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/pinctrl-nomadik-db8540.c index 52fc30181f7e..bb6a4016322a 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8540.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8540.c | |||
@@ -460,8 +460,10 @@ static const unsigned hsit_a_1_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10, | |||
460 | DB8540_PIN_E10, DB8540_PIN_B12, DB8540_PIN_D10 }; | 460 | DB8540_PIN_E10, DB8540_PIN_B12, DB8540_PIN_D10 }; |
461 | static const unsigned hsit_a_2_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10, | 461 | static const unsigned hsit_a_2_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10, |
462 | DB8540_PIN_E10, DB8540_PIN_B12 }; | 462 | DB8540_PIN_E10, DB8540_PIN_B12 }; |
463 | static const unsigned clkout_a_1_pins[] = { DB8540_PIN_D11, DB8540_PIN_AJ6 }; | 463 | static const unsigned clkout1_a_1_pins[] = { DB8540_PIN_D11 }; |
464 | static const unsigned clkout_a_2_pins[] = { DB8540_PIN_B13, DB8540_PIN_C12 }; | 464 | static const unsigned clkout1_a_2_pins[] = { DB8540_PIN_B13 }; |
465 | static const unsigned clkout2_a_1_pins[] = { DB8540_PIN_AJ6 }; | ||
466 | static const unsigned clkout2_a_2_pins[] = { DB8540_PIN_C12 }; | ||
465 | static const unsigned msp4_a_1_pins[] = { DB8540_PIN_B14, DB8540_PIN_E11 }; | 467 | static const unsigned msp4_a_1_pins[] = { DB8540_PIN_B14, DB8540_PIN_E11 }; |
466 | static const unsigned usb_a_1_pins[] = { DB8540_PIN_D12, DB8540_PIN_D15, | 468 | static const unsigned usb_a_1_pins[] = { DB8540_PIN_D12, DB8540_PIN_D15, |
467 | DB8540_PIN_C13, DB8540_PIN_C14, DB8540_PIN_C18, DB8540_PIN_C16, | 469 | DB8540_PIN_C13, DB8540_PIN_C14, DB8540_PIN_C18, DB8540_PIN_C16, |
@@ -698,8 +700,10 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { | |||
698 | DB8540_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), | 700 | DB8540_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), |
699 | DB8540_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), | 701 | DB8540_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), |
700 | DB8540_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), | 702 | DB8540_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), |
701 | DB8540_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A), | 703 | DB8540_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A), |
702 | DB8540_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A), | 704 | DB8540_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A), |
705 | DB8540_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A), | ||
706 | DB8540_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A), | ||
703 | DB8540_PIN_GROUP(msp4_a_1, NMK_GPIO_ALT_A), | 707 | DB8540_PIN_GROUP(msp4_a_1, NMK_GPIO_ALT_A), |
704 | DB8540_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), | 708 | DB8540_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), |
705 | /* Altfunction B column */ | 709 | /* Altfunction B column */ |
@@ -822,6 +826,7 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { | |||
822 | DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4), | 826 | DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4), |
823 | DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4), | 827 | DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4), |
824 | DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4), | 828 | DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4), |
829 | DB8540_PIN_GROUP(moduartstmmux_oc4_1, NMK_GPIO_ALT_C4), | ||
825 | 830 | ||
826 | }; | 831 | }; |
827 | 832 | ||
@@ -830,7 +835,8 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { | |||
830 | static const char * const a##_groups[] = { b }; | 835 | static const char * const a##_groups[] = { b }; |
831 | 836 | ||
832 | DB8540_FUNC_GROUPS(apetrig, "apetrig_b_1"); | 837 | DB8540_FUNC_GROUPS(apetrig, "apetrig_b_1"); |
833 | DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout_a_1", "clkout_a_2"); | 838 | DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout1_a_1", "clkout1_a_2", |
839 | "clkout2_a_1", "clkout2_a_2"); | ||
834 | DB8540_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1"); | 840 | DB8540_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1"); |
835 | DB8540_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); | 841 | DB8540_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); |
836 | DB8540_FUNC_GROUPS(hwobs, "hwobs_oc4_1"); | 842 | DB8540_FUNC_GROUPS(hwobs, "hwobs_oc4_1"); |
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index cf82d9ce4dee..ef66f98e9202 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c | |||
@@ -30,26 +30,9 @@ | |||
30 | #include <linux/pinctrl/pinconf.h> | 30 | #include <linux/pinctrl/pinconf.h> |
31 | /* Since we request GPIOs from ourself */ | 31 | /* Since we request GPIOs from ourself */ |
32 | #include <linux/pinctrl/consumer.h> | 32 | #include <linux/pinctrl/consumer.h> |
33 | /* | 33 | #include <linux/platform_data/pinctrl-nomadik.h> |
34 | * For the U8500 archs, use the PRCMU register interface, for the older | ||
35 | * Nomadik, provide some stubs. The functions using these will only be | ||
36 | * called on the U8500 series. | ||
37 | */ | ||
38 | #ifdef CONFIG_ARCH_U8500 | ||
39 | #include <linux/mfd/dbx500-prcmu.h> | ||
40 | #else | ||
41 | static inline u32 prcmu_read(unsigned int reg) { | ||
42 | return 0; | ||
43 | } | ||
44 | static inline void prcmu_write(unsigned int reg, u32 value) {} | ||
45 | static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} | ||
46 | #endif | ||
47 | |||
48 | #include <asm/mach/irq.h> | 34 | #include <asm/mach/irq.h> |
49 | 35 | #include <mach/irqs.h> | |
50 | #include <plat/pincfg.h> | ||
51 | #include <plat/gpio-nomadik.h> | ||
52 | |||
53 | #include "pinctrl-nomadik.h" | 36 | #include "pinctrl-nomadik.h" |
54 | 37 | ||
55 | /* | 38 | /* |
@@ -60,8 +43,6 @@ static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} | |||
60 | * Symbols in this file are called "nmk_gpio" for "nomadik gpio" | 43 | * Symbols in this file are called "nmk_gpio" for "nomadik gpio" |
61 | */ | 44 | */ |
62 | 45 | ||
63 | #define NMK_GPIO_PER_CHIP 32 | ||
64 | |||
65 | struct nmk_gpio_chip { | 46 | struct nmk_gpio_chip { |
66 | struct gpio_chip chip; | 47 | struct gpio_chip chip; |
67 | struct irq_domain *domain; | 48 | struct irq_domain *domain; |
@@ -86,10 +67,18 @@ struct nmk_gpio_chip { | |||
86 | u32 lowemi; | 67 | u32 lowemi; |
87 | }; | 68 | }; |
88 | 69 | ||
70 | /** | ||
71 | * struct nmk_pinctrl - state container for the Nomadik pin controller | ||
72 | * @dev: containing device pointer | ||
73 | * @pctl: corresponding pin controller device | ||
74 | * @soc: SoC data for this specific chip | ||
75 | * @prcm_base: PRCM register range virtual base | ||
76 | */ | ||
89 | struct nmk_pinctrl { | 77 | struct nmk_pinctrl { |
90 | struct device *dev; | 78 | struct device *dev; |
91 | struct pinctrl_dev *pctl; | 79 | struct pinctrl_dev *pctl; |
92 | const struct nmk_pinctrl_soc_data *soc; | 80 | const struct nmk_pinctrl_soc_data *soc; |
81 | void __iomem *prcm_base; | ||
93 | }; | 82 | }; |
94 | 83 | ||
95 | static struct nmk_gpio_chip * | 84 | static struct nmk_gpio_chip * |
@@ -251,6 +240,15 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) | |||
251 | dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio); | 240 | dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio); |
252 | } | 241 | } |
253 | 242 | ||
243 | static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value) | ||
244 | { | ||
245 | u32 val; | ||
246 | |||
247 | val = readl(reg); | ||
248 | val = ((val & ~mask) | (value & mask)); | ||
249 | writel(val, reg); | ||
250 | } | ||
251 | |||
254 | static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, | 252 | static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, |
255 | unsigned offset, unsigned alt_num) | 253 | unsigned offset, unsigned alt_num) |
256 | { | 254 | { |
@@ -289,8 +287,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, | |||
289 | if (pin_desc->altcx[i].used == true) { | 287 | if (pin_desc->altcx[i].used == true) { |
290 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; | 288 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; |
291 | bit = pin_desc->altcx[i].control_bit; | 289 | bit = pin_desc->altcx[i].control_bit; |
292 | if (prcmu_read(reg) & BIT(bit)) { | 290 | if (readl(npct->prcm_base + reg) & BIT(bit)) { |
293 | prcmu_write_masked(reg, BIT(bit), 0); | 291 | nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); |
294 | dev_dbg(npct->dev, | 292 | dev_dbg(npct->dev, |
295 | "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", | 293 | "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", |
296 | offset, i+1); | 294 | offset, i+1); |
@@ -318,8 +316,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, | |||
318 | if (pin_desc->altcx[i].used == true) { | 316 | if (pin_desc->altcx[i].used == true) { |
319 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; | 317 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; |
320 | bit = pin_desc->altcx[i].control_bit; | 318 | bit = pin_desc->altcx[i].control_bit; |
321 | if (prcmu_read(reg) & BIT(bit)) { | 319 | if (readl(npct->prcm_base + reg) & BIT(bit)) { |
322 | prcmu_write_masked(reg, BIT(bit), 0); | 320 | nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); |
323 | dev_dbg(npct->dev, | 321 | dev_dbg(npct->dev, |
324 | "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", | 322 | "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", |
325 | offset, i+1); | 323 | offset, i+1); |
@@ -331,7 +329,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, | |||
331 | bit = pin_desc->altcx[alt_index].control_bit; | 329 | bit = pin_desc->altcx[alt_index].control_bit; |
332 | dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", | 330 | dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", |
333 | offset, alt_index+1); | 331 | offset, alt_index+1); |
334 | prcmu_write_masked(reg, BIT(bit), BIT(bit)); | 332 | nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit)); |
335 | } | 333 | } |
336 | 334 | ||
337 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | 335 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, |
@@ -536,7 +534,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) | |||
536 | * and its sleep mode based on the specified configuration. The @cfg is | 534 | * and its sleep mode based on the specified configuration. The @cfg is |
537 | * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These | 535 | * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These |
538 | * are constructed using, and can be further enhanced with, the macros in | 536 | * are constructed using, and can be further enhanced with, the macros in |
539 | * plat/pincfg.h. | 537 | * <linux/platform_data/pinctrl-nomadik.h> |
540 | * | 538 | * |
541 | * If a pin's mode is set to GPIO, it is configured as an input to avoid | 539 | * If a pin's mode is set to GPIO, it is configured as an input to avoid |
542 | * side-effects. The gpio can be manipulated later using standard GPIO API | 540 | * side-effects. The gpio can be manipulated later using standard GPIO API |
@@ -675,6 +673,35 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode) | |||
675 | } | 673 | } |
676 | EXPORT_SYMBOL(nmk_gpio_set_mode); | 674 | EXPORT_SYMBOL(nmk_gpio_set_mode); |
677 | 675 | ||
676 | static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) | ||
677 | { | ||
678 | int i; | ||
679 | u16 reg; | ||
680 | u8 bit; | ||
681 | struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); | ||
682 | const struct prcm_gpiocr_altcx_pin_desc *pin_desc; | ||
683 | const u16 *gpiocr_regs; | ||
684 | |||
685 | for (i = 0; i < npct->soc->npins_altcx; i++) { | ||
686 | if (npct->soc->altcx_pins[i].pin == gpio) | ||
687 | break; | ||
688 | } | ||
689 | if (i == npct->soc->npins_altcx) | ||
690 | return NMK_GPIO_ALT_C; | ||
691 | |||
692 | pin_desc = npct->soc->altcx_pins + i; | ||
693 | gpiocr_regs = npct->soc->prcm_gpiocr_registers; | ||
694 | for (i = 0; i < PRCM_IDX_GPIOCR_ALTC_MAX; i++) { | ||
695 | if (pin_desc->altcx[i].used == true) { | ||
696 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; | ||
697 | bit = pin_desc->altcx[i].control_bit; | ||
698 | if (readl(npct->prcm_base + reg) & BIT(bit)) | ||
699 | return NMK_GPIO_ALT_C+i+1; | ||
700 | } | ||
701 | } | ||
702 | return NMK_GPIO_ALT_C; | ||
703 | } | ||
704 | |||
678 | int nmk_gpio_get_mode(int gpio) | 705 | int nmk_gpio_get_mode(int gpio) |
679 | { | 706 | { |
680 | struct nmk_gpio_chip *nmk_chip; | 707 | struct nmk_gpio_chip *nmk_chip; |
@@ -1063,8 +1090,9 @@ static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
1063 | 1090 | ||
1064 | #include <linux/seq_file.h> | 1091 | #include <linux/seq_file.h> |
1065 | 1092 | ||
1066 | static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip, | 1093 | static void nmk_gpio_dbg_show_one(struct seq_file *s, |
1067 | unsigned offset, unsigned gpio) | 1094 | struct pinctrl_dev *pctldev, struct gpio_chip *chip, |
1095 | unsigned offset, unsigned gpio) | ||
1068 | { | 1096 | { |
1069 | const char *label = gpiochip_is_requested(chip, offset); | 1097 | const char *label = gpiochip_is_requested(chip, offset); |
1070 | struct nmk_gpio_chip *nmk_chip = | 1098 | struct nmk_gpio_chip *nmk_chip = |
@@ -1078,12 +1106,18 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip, | |||
1078 | [NMK_GPIO_ALT_A] = "altA", | 1106 | [NMK_GPIO_ALT_A] = "altA", |
1079 | [NMK_GPIO_ALT_B] = "altB", | 1107 | [NMK_GPIO_ALT_B] = "altB", |
1080 | [NMK_GPIO_ALT_C] = "altC", | 1108 | [NMK_GPIO_ALT_C] = "altC", |
1109 | [NMK_GPIO_ALT_C+1] = "altC1", | ||
1110 | [NMK_GPIO_ALT_C+2] = "altC2", | ||
1111 | [NMK_GPIO_ALT_C+3] = "altC3", | ||
1112 | [NMK_GPIO_ALT_C+4] = "altC4", | ||
1081 | }; | 1113 | }; |
1082 | 1114 | ||
1083 | clk_enable(nmk_chip->clk); | 1115 | clk_enable(nmk_chip->clk); |
1084 | is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit); | 1116 | is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit); |
1085 | pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); | 1117 | pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); |
1086 | mode = nmk_gpio_get_mode(gpio); | 1118 | mode = nmk_gpio_get_mode(gpio); |
1119 | if ((mode == NMK_GPIO_ALT_C) && pctldev) | ||
1120 | mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio); | ||
1087 | 1121 | ||
1088 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", | 1122 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", |
1089 | gpio, label ?: "(none)", | 1123 | gpio, label ?: "(none)", |
@@ -1127,13 +1161,14 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
1127 | unsigned gpio = chip->base; | 1161 | unsigned gpio = chip->base; |
1128 | 1162 | ||
1129 | for (i = 0; i < chip->ngpio; i++, gpio++) { | 1163 | for (i = 0; i < chip->ngpio; i++, gpio++) { |
1130 | nmk_gpio_dbg_show_one(s, chip, i, gpio); | 1164 | nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio); |
1131 | seq_printf(s, "\n"); | 1165 | seq_printf(s, "\n"); |
1132 | } | 1166 | } |
1133 | } | 1167 | } |
1134 | 1168 | ||
1135 | #else | 1169 | #else |
1136 | static inline void nmk_gpio_dbg_show_one(struct seq_file *s, | 1170 | static inline void nmk_gpio_dbg_show_one(struct seq_file *s, |
1171 | struct pinctrl_dev *pctldev, | ||
1137 | struct gpio_chip *chip, | 1172 | struct gpio_chip *chip, |
1138 | unsigned offset, unsigned gpio) | 1173 | unsigned offset, unsigned gpio) |
1139 | { | 1174 | { |
@@ -1250,8 +1285,8 @@ void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up) | |||
1250 | } | 1285 | } |
1251 | } | 1286 | } |
1252 | 1287 | ||
1253 | int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq, | 1288 | static int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq, |
1254 | irq_hw_number_t hwirq) | 1289 | irq_hw_number_t hwirq) |
1255 | { | 1290 | { |
1256 | struct nmk_gpio_chip *nmk_chip = d->host_data; | 1291 | struct nmk_gpio_chip *nmk_chip = d->host_data; |
1257 | 1292 | ||
@@ -1464,7 +1499,7 @@ static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, | |||
1464 | return; | 1499 | return; |
1465 | } | 1500 | } |
1466 | chip = range->gc; | 1501 | chip = range->gc; |
1467 | nmk_gpio_dbg_show_one(s, chip, offset - chip->base, offset); | 1502 | nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset); |
1468 | } | 1503 | } |
1469 | 1504 | ||
1470 | static struct pinctrl_ops nmk_pinctrl_ops = { | 1505 | static struct pinctrl_ops nmk_pinctrl_ops = { |
@@ -1635,9 +1670,9 @@ static void nmk_pmx_disable(struct pinctrl_dev *pctldev, | |||
1635 | dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins); | 1670 | dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins); |
1636 | } | 1671 | } |
1637 | 1672 | ||
1638 | int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, | 1673 | static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, |
1639 | struct pinctrl_gpio_range *range, | 1674 | struct pinctrl_gpio_range *range, |
1640 | unsigned offset) | 1675 | unsigned offset) |
1641 | { | 1676 | { |
1642 | struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); | 1677 | struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); |
1643 | struct nmk_gpio_chip *nmk_chip; | 1678 | struct nmk_gpio_chip *nmk_chip; |
@@ -1666,9 +1701,9 @@ int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, | |||
1666 | return 0; | 1701 | return 0; |
1667 | } | 1702 | } |
1668 | 1703 | ||
1669 | void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, | 1704 | static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, |
1670 | struct pinctrl_gpio_range *range, | 1705 | struct pinctrl_gpio_range *range, |
1671 | unsigned offset) | 1706 | unsigned offset) |
1672 | { | 1707 | { |
1673 | struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); | 1708 | struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); |
1674 | 1709 | ||
@@ -1686,17 +1721,15 @@ static struct pinmux_ops nmk_pinmux_ops = { | |||
1686 | .gpio_disable_free = nmk_gpio_disable_free, | 1721 | .gpio_disable_free = nmk_gpio_disable_free, |
1687 | }; | 1722 | }; |
1688 | 1723 | ||
1689 | int nmk_pin_config_get(struct pinctrl_dev *pctldev, | 1724 | static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, |
1690 | unsigned pin, | 1725 | unsigned long *config) |
1691 | unsigned long *config) | ||
1692 | { | 1726 | { |
1693 | /* Not implemented */ | 1727 | /* Not implemented */ |
1694 | return -EINVAL; | 1728 | return -EINVAL; |
1695 | } | 1729 | } |
1696 | 1730 | ||
1697 | int nmk_pin_config_set(struct pinctrl_dev *pctldev, | 1731 | static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, |
1698 | unsigned pin, | 1732 | unsigned long config) |
1699 | unsigned long config) | ||
1700 | { | 1733 | { |
1701 | static const char *pullnames[] = { | 1734 | static const char *pullnames[] = { |
1702 | [NMK_GPIO_PULL_NONE] = "none", | 1735 | [NMK_GPIO_PULL_NONE] = "none", |
@@ -1818,6 +1851,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) | |||
1818 | const struct platform_device_id *platid = platform_get_device_id(pdev); | 1851 | const struct platform_device_id *platid = platform_get_device_id(pdev); |
1819 | struct device_node *np = pdev->dev.of_node; | 1852 | struct device_node *np = pdev->dev.of_node; |
1820 | struct nmk_pinctrl *npct; | 1853 | struct nmk_pinctrl *npct; |
1854 | struct resource *res; | ||
1821 | unsigned int version = 0; | 1855 | unsigned int version = 0; |
1822 | int i; | 1856 | int i; |
1823 | 1857 | ||
@@ -1827,9 +1861,14 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) | |||
1827 | 1861 | ||
1828 | if (platid) | 1862 | if (platid) |
1829 | version = platid->driver_data; | 1863 | version = platid->driver_data; |
1830 | else if (np) | 1864 | else if (np) { |
1831 | version = (unsigned int) | 1865 | const struct of_device_id *match; |
1832 | of_match_device(nmk_pinctrl_match, &pdev->dev)->data; | 1866 | |
1867 | match = of_match_device(nmk_pinctrl_match, &pdev->dev); | ||
1868 | if (!match) | ||
1869 | return -ENODEV; | ||
1870 | version = (unsigned int) match->data; | ||
1871 | } | ||
1833 | 1872 | ||
1834 | /* Poke in other ASIC variants here */ | 1873 | /* Poke in other ASIC variants here */ |
1835 | if (version == PINCTRL_NMK_STN8815) | 1874 | if (version == PINCTRL_NMK_STN8815) |
@@ -1839,22 +1878,37 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) | |||
1839 | if (version == PINCTRL_NMK_DB8540) | 1878 | if (version == PINCTRL_NMK_DB8540) |
1840 | nmk_pinctrl_db8540_init(&npct->soc); | 1879 | nmk_pinctrl_db8540_init(&npct->soc); |
1841 | 1880 | ||
1881 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1882 | if (res) { | ||
1883 | npct->prcm_base = devm_ioremap(&pdev->dev, res->start, | ||
1884 | resource_size(res)); | ||
1885 | if (!npct->prcm_base) { | ||
1886 | dev_err(&pdev->dev, | ||
1887 | "failed to ioremap PRCM registers\n"); | ||
1888 | return -ENOMEM; | ||
1889 | } | ||
1890 | } else { | ||
1891 | dev_info(&pdev->dev, | ||
1892 | "No PRCM base, assume no ALT-Cx control is available\n"); | ||
1893 | } | ||
1894 | |||
1842 | /* | 1895 | /* |
1843 | * We need all the GPIO drivers to probe FIRST, or we will not be able | 1896 | * We need all the GPIO drivers to probe FIRST, or we will not be able |
1844 | * to obtain references to the struct gpio_chip * for them, and we | 1897 | * to obtain references to the struct gpio_chip * for them, and we |
1845 | * need this to proceed. | 1898 | * need this to proceed. |
1846 | */ | 1899 | */ |
1847 | for (i = 0; i < npct->soc->gpio_num_ranges; i++) { | 1900 | for (i = 0; i < npct->soc->gpio_num_ranges; i++) { |
1848 | if (!nmk_gpio_chips[i]) { | 1901 | if (!nmk_gpio_chips[npct->soc->gpio_ranges[i].id]) { |
1849 | dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); | 1902 | dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); |
1850 | return -EPROBE_DEFER; | 1903 | return -EPROBE_DEFER; |
1851 | } | 1904 | } |
1852 | npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip; | 1905 | npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[npct->soc->gpio_ranges[i].id]->chip; |
1853 | } | 1906 | } |
1854 | 1907 | ||
1855 | nmk_pinctrl_desc.pins = npct->soc->pins; | 1908 | nmk_pinctrl_desc.pins = npct->soc->pins; |
1856 | nmk_pinctrl_desc.npins = npct->soc->npins; | 1909 | nmk_pinctrl_desc.npins = npct->soc->npins; |
1857 | npct->dev = &pdev->dev; | 1910 | npct->dev = &pdev->dev; |
1911 | |||
1858 | npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct); | 1912 | npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct); |
1859 | if (!npct->pctl) { | 1913 | if (!npct->pctl) { |
1860 | dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n"); | 1914 | dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n"); |
@@ -1889,6 +1943,7 @@ static const struct platform_device_id nmk_pinctrl_id[] = { | |||
1889 | { "pinctrl-stn8815", PINCTRL_NMK_STN8815 }, | 1943 | { "pinctrl-stn8815", PINCTRL_NMK_STN8815 }, |
1890 | { "pinctrl-db8500", PINCTRL_NMK_DB8500 }, | 1944 | { "pinctrl-db8500", PINCTRL_NMK_DB8500 }, |
1891 | { "pinctrl-db8540", PINCTRL_NMK_DB8540 }, | 1945 | { "pinctrl-db8540", PINCTRL_NMK_DB8540 }, |
1946 | { } | ||
1892 | }; | 1947 | }; |
1893 | 1948 | ||
1894 | static struct platform_driver nmk_pinctrl_driver = { | 1949 | static struct platform_driver nmk_pinctrl_driver = { |
diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/pinctrl-nomadik.h index eef316e979a0..bcd4191e10ea 100644 --- a/drivers/pinctrl/pinctrl-nomadik.h +++ b/drivers/pinctrl/pinctrl-nomadik.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef PINCTRL_PINCTRL_NOMADIK_H | 1 | #ifndef PINCTRL_PINCTRL_NOMADIK_H |
2 | #define PINCTRL_PINCTRL_NOMADIK_H | 2 | #define PINCTRL_PINCTRL_NOMADIK_H |
3 | 3 | ||
4 | #include <plat/gpio-nomadik.h> | 4 | #include <linux/platform_data/pinctrl-nomadik.h> |
5 | 5 | ||
6 | /* Package definitions */ | 6 | /* Package definitions */ |
7 | #define PINCTRL_NMK_STN8815 0 | 7 | #define PINCTRL_NMK_STN8815 0 |
diff --git a/drivers/pinctrl/pinctrl-pxa168.c b/drivers/pinctrl/pinctrl-pxa168.c index c1997fa7f28c..cb771e4a6355 100644 --- a/drivers/pinctrl/pinctrl-pxa168.c +++ b/drivers/pinctrl/pinctrl-pxa168.c | |||
@@ -620,7 +620,7 @@ static int __devinit pxa168_pinmux_probe(struct platform_device *pdev) | |||
620 | return pxa3xx_pinctrl_register(pdev, &pxa168_info); | 620 | return pxa3xx_pinctrl_register(pdev, &pxa168_info); |
621 | } | 621 | } |
622 | 622 | ||
623 | static int __devexit pxa168_pinmux_remove(struct platform_device *pdev) | 623 | static int pxa168_pinmux_remove(struct platform_device *pdev) |
624 | { | 624 | { |
625 | return pxa3xx_pinctrl_unregister(pdev); | 625 | return pxa3xx_pinctrl_unregister(pdev); |
626 | } | 626 | } |
@@ -631,7 +631,7 @@ static struct platform_driver pxa168_pinmux_driver = { | |||
631 | .owner = THIS_MODULE, | 631 | .owner = THIS_MODULE, |
632 | }, | 632 | }, |
633 | .probe = pxa168_pinmux_probe, | 633 | .probe = pxa168_pinmux_probe, |
634 | .remove = __devexit_p(pxa168_pinmux_remove), | 634 | .remove = pxa168_pinmux_remove, |
635 | }; | 635 | }; |
636 | 636 | ||
637 | static int __init pxa168_pinmux_init(void) | 637 | static int __init pxa168_pinmux_init(void) |
diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c index f14cd6ba4c0b..51f8a388b917 100644 --- a/drivers/pinctrl/pinctrl-pxa3xx.c +++ b/drivers/pinctrl/pinctrl-pxa3xx.c | |||
@@ -173,7 +173,6 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev, | |||
173 | { | 173 | { |
174 | struct pinctrl_desc *desc; | 174 | struct pinctrl_desc *desc; |
175 | struct resource *res; | 175 | struct resource *res; |
176 | int ret = 0; | ||
177 | 176 | ||
178 | if (!info || !info->cputype) | 177 | if (!info || !info->cputype) |
179 | return -EINVAL; | 178 | return -EINVAL; |
@@ -188,23 +187,17 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev, | |||
188 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 187 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
189 | if (!res) | 188 | if (!res) |
190 | return -ENOENT; | 189 | return -ENOENT; |
191 | info->phy_base = res->start; | 190 | info->virt_base = devm_request_and_ioremap(&pdev->dev, res); |
192 | info->phy_size = resource_size(res); | ||
193 | info->virt_base = ioremap(info->phy_base, info->phy_size); | ||
194 | if (!info->virt_base) | 191 | if (!info->virt_base) |
195 | return -ENOMEM; | 192 | return -ENOMEM; |
196 | info->pctrl = pinctrl_register(desc, &pdev->dev, info); | 193 | info->pctrl = pinctrl_register(desc, &pdev->dev, info); |
197 | if (!info->pctrl) { | 194 | if (!info->pctrl) { |
198 | dev_err(&pdev->dev, "failed to register PXA pinmux driver\n"); | 195 | dev_err(&pdev->dev, "failed to register PXA pinmux driver\n"); |
199 | ret = -EINVAL; | 196 | return -EINVAL; |
200 | goto err; | ||
201 | } | 197 | } |
202 | pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range); | 198 | pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range); |
203 | platform_set_drvdata(pdev, info); | 199 | platform_set_drvdata(pdev, info); |
204 | return 0; | 200 | return 0; |
205 | err: | ||
206 | iounmap(info->virt_base); | ||
207 | return ret; | ||
208 | } | 201 | } |
209 | 202 | ||
210 | int pxa3xx_pinctrl_unregister(struct platform_device *pdev) | 203 | int pxa3xx_pinctrl_unregister(struct platform_device *pdev) |
@@ -212,7 +205,6 @@ int pxa3xx_pinctrl_unregister(struct platform_device *pdev) | |||
212 | struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev); | 205 | struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev); |
213 | 206 | ||
214 | pinctrl_unregister(info->pctrl); | 207 | pinctrl_unregister(info->pctrl); |
215 | iounmap(info->virt_base); | ||
216 | platform_set_drvdata(pdev, NULL); | 208 | platform_set_drvdata(pdev, NULL); |
217 | return 0; | 209 | return 0; |
218 | } | 210 | } |
diff --git a/drivers/pinctrl/pinctrl-pxa3xx.h b/drivers/pinctrl/pinctrl-pxa3xx.h index 8135744d6599..92fad0880834 100644 --- a/drivers/pinctrl/pinctrl-pxa3xx.h +++ b/drivers/pinctrl/pinctrl-pxa3xx.h | |||
@@ -60,8 +60,6 @@ struct pxa3xx_pinmux_info { | |||
60 | struct device *dev; | 60 | struct device *dev; |
61 | struct pinctrl_dev *pctrl; | 61 | struct pinctrl_dev *pctrl; |
62 | enum pxa_cpu_type cputype; | 62 | enum pxa_cpu_type cputype; |
63 | unsigned int phy_base; | ||
64 | unsigned int phy_size; | ||
65 | void __iomem *virt_base; | 63 | void __iomem *virt_base; |
66 | 64 | ||
67 | struct pxa3xx_mfp_pin *mfp; | 65 | struct pxa3xx_mfp_pin *mfp; |
diff --git a/drivers/pinctrl/pinctrl-pxa910.c b/drivers/pinctrl/pinctrl-pxa910.c index c72ab4b9cc8c..5fecd221b830 100644 --- a/drivers/pinctrl/pinctrl-pxa910.c +++ b/drivers/pinctrl/pinctrl-pxa910.c | |||
@@ -976,7 +976,7 @@ static int __devinit pxa910_pinmux_probe(struct platform_device *pdev) | |||
976 | return pxa3xx_pinctrl_register(pdev, &pxa910_info); | 976 | return pxa3xx_pinctrl_register(pdev, &pxa910_info); |
977 | } | 977 | } |
978 | 978 | ||
979 | static int __devexit pxa910_pinmux_remove(struct platform_device *pdev) | 979 | static int pxa910_pinmux_remove(struct platform_device *pdev) |
980 | { | 980 | { |
981 | return pxa3xx_pinctrl_unregister(pdev); | 981 | return pxa3xx_pinctrl_unregister(pdev); |
982 | } | 982 | } |
@@ -987,7 +987,7 @@ static struct platform_driver pxa910_pinmux_driver = { | |||
987 | .owner = THIS_MODULE, | 987 | .owner = THIS_MODULE, |
988 | }, | 988 | }, |
989 | .probe = pxa910_pinmux_probe, | 989 | .probe = pxa910_pinmux_probe, |
990 | .remove = __devexit_p(pxa910_pinmux_remove), | 990 | .remove = pxa910_pinmux_remove, |
991 | }; | 991 | }; |
992 | 992 | ||
993 | static int __init pxa910_pinmux_init(void) | 993 | static int __init pxa910_pinmux_init(void) |
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 861cd5f04d5e..8f31b656c4e9 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/irqdomain.h> | ||
29 | 30 | ||
30 | #include "core.h" | 31 | #include "core.h" |
31 | #include "pinctrl-samsung.h" | 32 | #include "pinctrl-samsung.h" |
@@ -46,6 +47,13 @@ struct pin_config { | |||
46 | { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, | 47 | { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, |
47 | }; | 48 | }; |
48 | 49 | ||
50 | static unsigned int pin_base; | ||
51 | |||
52 | static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) | ||
53 | { | ||
54 | return container_of(gc, struct samsung_pin_bank, gpio_chip); | ||
55 | } | ||
56 | |||
49 | /* check if the selector is a valid pin group selector */ | 57 | /* check if the selector is a valid pin group selector */ |
50 | static int samsung_get_group_count(struct pinctrl_dev *pctldev) | 58 | static int samsung_get_group_count(struct pinctrl_dev *pctldev) |
51 | { | 59 | { |
@@ -250,14 +258,12 @@ static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev, | |||
250 | * given a pin number that is local to a pin controller, find out the pin bank | 258 | * given a pin number that is local to a pin controller, find out the pin bank |
251 | * and the register base of the pin bank. | 259 | * and the register base of the pin bank. |
252 | */ | 260 | */ |
253 | static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin, | 261 | static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, |
254 | void __iomem **reg, u32 *offset, | 262 | unsigned pin, void __iomem **reg, u32 *offset, |
255 | struct samsung_pin_bank **bank) | 263 | struct samsung_pin_bank **bank) |
256 | { | 264 | { |
257 | struct samsung_pinctrl_drv_data *drvdata; | ||
258 | struct samsung_pin_bank *b; | 265 | struct samsung_pin_bank *b; |
259 | 266 | ||
260 | drvdata = dev_get_drvdata(gc->dev); | ||
261 | b = drvdata->ctrl->pin_banks; | 267 | b = drvdata->ctrl->pin_banks; |
262 | 268 | ||
263 | while ((pin >= b->pin_base) && | 269 | while ((pin >= b->pin_base) && |
@@ -292,7 +298,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, | |||
292 | * pin function number in the config register. | 298 | * pin function number in the config register. |
293 | */ | 299 | */ |
294 | for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { | 300 | for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { |
295 | pin_to_reg_bank(drvdata->gc, pins[cnt] - drvdata->ctrl->base, | 301 | pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base, |
296 | ®, &pin_offset, &bank); | 302 | ®, &pin_offset, &bank); |
297 | mask = (1 << bank->func_width) - 1; | 303 | mask = (1 << bank->func_width) - 1; |
298 | shift = pin_offset * bank->func_width; | 304 | shift = pin_offset * bank->func_width; |
@@ -329,10 +335,16 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, | |||
329 | struct pinctrl_gpio_range *range, unsigned offset, bool input) | 335 | struct pinctrl_gpio_range *range, unsigned offset, bool input) |
330 | { | 336 | { |
331 | struct samsung_pin_bank *bank; | 337 | struct samsung_pin_bank *bank; |
338 | struct samsung_pinctrl_drv_data *drvdata; | ||
332 | void __iomem *reg; | 339 | void __iomem *reg; |
333 | u32 data, pin_offset, mask, shift; | 340 | u32 data, pin_offset, mask, shift; |
334 | 341 | ||
335 | pin_to_reg_bank(range->gc, offset, ®, &pin_offset, &bank); | 342 | bank = gc_to_pin_bank(range->gc); |
343 | drvdata = pinctrl_dev_get_drvdata(pctldev); | ||
344 | |||
345 | pin_offset = offset - bank->pin_base; | ||
346 | reg = drvdata->virt_base + bank->pctl_offset; | ||
347 | |||
336 | mask = (1 << bank->func_width) - 1; | 348 | mask = (1 << bank->func_width) - 1; |
337 | shift = pin_offset * bank->func_width; | 349 | shift = pin_offset * bank->func_width; |
338 | 350 | ||
@@ -366,7 +378,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, | |||
366 | u32 cfg_value, cfg_reg; | 378 | u32 cfg_value, cfg_reg; |
367 | 379 | ||
368 | drvdata = pinctrl_dev_get_drvdata(pctldev); | 380 | drvdata = pinctrl_dev_get_drvdata(pctldev); |
369 | pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, ®_base, | 381 | pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, ®_base, |
370 | &pin_offset, &bank); | 382 | &pin_offset, &bank); |
371 | 383 | ||
372 | switch (cfg_type) { | 384 | switch (cfg_type) { |
@@ -391,6 +403,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, | |||
391 | return -EINVAL; | 403 | return -EINVAL; |
392 | } | 404 | } |
393 | 405 | ||
406 | if (!width) | ||
407 | return -EINVAL; | ||
408 | |||
394 | mask = (1 << width) - 1; | 409 | mask = (1 << width) - 1; |
395 | shift = pin_offset * width; | 410 | shift = pin_offset * width; |
396 | data = readl(reg_base + cfg_reg); | 411 | data = readl(reg_base + cfg_reg); |
@@ -463,14 +478,16 @@ static struct pinconf_ops samsung_pinconf_ops = { | |||
463 | /* gpiolib gpio_set callback function */ | 478 | /* gpiolib gpio_set callback function */ |
464 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | 479 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) |
465 | { | 480 | { |
481 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
466 | void __iomem *reg; | 482 | void __iomem *reg; |
467 | u32 pin_offset, data; | 483 | u32 data; |
484 | |||
485 | reg = bank->drvdata->virt_base + bank->pctl_offset; | ||
468 | 486 | ||
469 | pin_to_reg_bank(gc, offset, ®, &pin_offset, NULL); | ||
470 | data = readl(reg + DAT_REG); | 487 | data = readl(reg + DAT_REG); |
471 | data &= ~(1 << pin_offset); | 488 | data &= ~(1 << offset); |
472 | if (value) | 489 | if (value) |
473 | data |= 1 << pin_offset; | 490 | data |= 1 << offset; |
474 | writel(data, reg + DAT_REG); | 491 | writel(data, reg + DAT_REG); |
475 | } | 492 | } |
476 | 493 | ||
@@ -478,11 +495,13 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | |||
478 | static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) | 495 | static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) |
479 | { | 496 | { |
480 | void __iomem *reg; | 497 | void __iomem *reg; |
481 | u32 pin_offset, data; | 498 | u32 data; |
499 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
500 | |||
501 | reg = bank->drvdata->virt_base + bank->pctl_offset; | ||
482 | 502 | ||
483 | pin_to_reg_bank(gc, offset, ®, &pin_offset, NULL); | ||
484 | data = readl(reg + DAT_REG); | 503 | data = readl(reg + DAT_REG); |
485 | data >>= pin_offset; | 504 | data >>= offset; |
486 | data &= 1; | 505 | data &= 1; |
487 | return data; | 506 | return data; |
488 | } | 507 | } |
@@ -510,6 +529,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, | |||
510 | } | 529 | } |
511 | 530 | ||
512 | /* | 531 | /* |
532 | * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin | ||
533 | * and a virtual IRQ, if not already present. | ||
534 | */ | ||
535 | static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
536 | { | ||
537 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
538 | unsigned int virq; | ||
539 | |||
540 | if (!bank->irq_domain) | ||
541 | return -ENXIO; | ||
542 | |||
543 | virq = irq_create_mapping(bank->irq_domain, offset); | ||
544 | |||
545 | return (virq) ? : -ENXIO; | ||
546 | } | ||
547 | |||
548 | /* | ||
513 | * Parse the pin names listed in the 'samsung,pins' property and convert it | 549 | * Parse the pin names listed in the 'samsung,pins' property and convert it |
514 | * into a list of gpio numbers are create a pin group from it. | 550 | * into a list of gpio numbers are create a pin group from it. |
515 | */ | 551 | */ |
@@ -524,7 +560,7 @@ static int __devinit samsung_pinctrl_parse_dt_pins(struct platform_device *pdev, | |||
524 | const char *pin_name; | 560 | const char *pin_name; |
525 | 561 | ||
526 | *npins = of_property_count_strings(cfg_np, "samsung,pins"); | 562 | *npins = of_property_count_strings(cfg_np, "samsung,pins"); |
527 | if (*npins < 0) { | 563 | if (IS_ERR_VALUE(*npins)) { |
528 | dev_err(dev, "invalid pin list in %s node", cfg_np->name); | 564 | dev_err(dev, "invalid pin list in %s node", cfg_np->name); |
529 | return -EINVAL; | 565 | return -EINVAL; |
530 | } | 566 | } |
@@ -597,7 +633,7 @@ static int __devinit samsung_pinctrl_parse_dt(struct platform_device *pdev, | |||
597 | */ | 633 | */ |
598 | for_each_child_of_node(dev_np, cfg_np) { | 634 | for_each_child_of_node(dev_np, cfg_np) { |
599 | u32 function; | 635 | u32 function; |
600 | if (of_find_property(cfg_np, "interrupt-controller", NULL)) | 636 | if (!of_find_property(cfg_np, "samsung,pins", NULL)) |
601 | continue; | 637 | continue; |
602 | 638 | ||
603 | ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np, | 639 | ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np, |
@@ -712,12 +748,16 @@ static int __devinit samsung_pinctrl_register(struct platform_device *pdev, | |||
712 | return -EINVAL; | 748 | return -EINVAL; |
713 | } | 749 | } |
714 | 750 | ||
715 | drvdata->grange.name = "samsung-pctrl-gpio-range"; | 751 | for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) { |
716 | drvdata->grange.id = 0; | 752 | pin_bank = &drvdata->ctrl->pin_banks[bank]; |
717 | drvdata->grange.base = drvdata->ctrl->base; | 753 | pin_bank->grange.name = pin_bank->name; |
718 | drvdata->grange.npins = drvdata->ctrl->nr_pins; | 754 | pin_bank->grange.id = bank; |
719 | drvdata->grange.gc = drvdata->gc; | 755 | pin_bank->grange.pin_base = pin_bank->pin_base; |
720 | pinctrl_add_gpio_range(drvdata->pctl_dev, &drvdata->grange); | 756 | pin_bank->grange.base = pin_bank->gpio_chip.base; |
757 | pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; | ||
758 | pin_bank->grange.gc = &pin_bank->gpio_chip; | ||
759 | pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange); | ||
760 | } | ||
721 | 761 | ||
722 | ret = samsung_pinctrl_parse_dt(pdev, drvdata); | 762 | ret = samsung_pinctrl_parse_dt(pdev, drvdata); |
723 | if (ret) { | 763 | if (ret) { |
@@ -728,68 +768,117 @@ static int __devinit samsung_pinctrl_register(struct platform_device *pdev, | |||
728 | return 0; | 768 | return 0; |
729 | } | 769 | } |
730 | 770 | ||
771 | static const struct gpio_chip samsung_gpiolib_chip = { | ||
772 | .set = samsung_gpio_set, | ||
773 | .get = samsung_gpio_get, | ||
774 | .direction_input = samsung_gpio_direction_input, | ||
775 | .direction_output = samsung_gpio_direction_output, | ||
776 | .to_irq = samsung_gpio_to_irq, | ||
777 | .owner = THIS_MODULE, | ||
778 | }; | ||
779 | |||
731 | /* register the gpiolib interface with the gpiolib subsystem */ | 780 | /* register the gpiolib interface with the gpiolib subsystem */ |
732 | static int __devinit samsung_gpiolib_register(struct platform_device *pdev, | 781 | static int __devinit samsung_gpiolib_register(struct platform_device *pdev, |
733 | struct samsung_pinctrl_drv_data *drvdata) | 782 | struct samsung_pinctrl_drv_data *drvdata) |
734 | { | 783 | { |
784 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
785 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
735 | struct gpio_chip *gc; | 786 | struct gpio_chip *gc; |
736 | int ret; | 787 | int ret; |
737 | 788 | int i; | |
738 | gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL); | 789 | |
739 | if (!gc) { | 790 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { |
740 | dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n"); | 791 | bank->gpio_chip = samsung_gpiolib_chip; |
741 | return -ENOMEM; | 792 | |
742 | } | 793 | gc = &bank->gpio_chip; |
743 | 794 | gc->base = ctrl->base + bank->pin_base; | |
744 | drvdata->gc = gc; | 795 | gc->ngpio = bank->nr_pins; |
745 | gc->base = drvdata->ctrl->base; | 796 | gc->dev = &pdev->dev; |
746 | gc->ngpio = drvdata->ctrl->nr_pins; | 797 | gc->of_node = bank->of_node; |
747 | gc->dev = &pdev->dev; | 798 | gc->label = bank->name; |
748 | gc->set = samsung_gpio_set; | 799 | |
749 | gc->get = samsung_gpio_get; | 800 | ret = gpiochip_add(gc); |
750 | gc->direction_input = samsung_gpio_direction_input; | 801 | if (ret) { |
751 | gc->direction_output = samsung_gpio_direction_output; | 802 | dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", |
752 | gc->label = drvdata->ctrl->label; | 803 | gc->label, ret); |
753 | gc->owner = THIS_MODULE; | 804 | goto fail; |
754 | ret = gpiochip_add(gc); | 805 | } |
755 | if (ret) { | ||
756 | dev_err(&pdev->dev, "failed to register gpio_chip %s, error " | ||
757 | "code: %d\n", gc->label, ret); | ||
758 | return ret; | ||
759 | } | 806 | } |
760 | 807 | ||
761 | return 0; | 808 | return 0; |
809 | |||
810 | fail: | ||
811 | for (--i, --bank; i >= 0; --i, --bank) | ||
812 | if (gpiochip_remove(&bank->gpio_chip)) | ||
813 | dev_err(&pdev->dev, "gpio chip %s remove failed\n", | ||
814 | bank->gpio_chip.label); | ||
815 | return ret; | ||
762 | } | 816 | } |
763 | 817 | ||
764 | /* unregister the gpiolib interface with the gpiolib subsystem */ | 818 | /* unregister the gpiolib interface with the gpiolib subsystem */ |
765 | static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev, | 819 | static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev, |
766 | struct samsung_pinctrl_drv_data *drvdata) | 820 | struct samsung_pinctrl_drv_data *drvdata) |
767 | { | 821 | { |
768 | int ret = gpiochip_remove(drvdata->gc); | 822 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; |
769 | if (ret) { | 823 | struct samsung_pin_bank *bank = ctrl->pin_banks; |
824 | int ret = 0; | ||
825 | int i; | ||
826 | |||
827 | for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) | ||
828 | ret = gpiochip_remove(&bank->gpio_chip); | ||
829 | |||
830 | if (ret) | ||
770 | dev_err(&pdev->dev, "gpio chip remove failed\n"); | 831 | dev_err(&pdev->dev, "gpio chip remove failed\n"); |
771 | return ret; | 832 | |
772 | } | 833 | return ret; |
773 | return 0; | ||
774 | } | 834 | } |
775 | 835 | ||
776 | static const struct of_device_id samsung_pinctrl_dt_match[]; | 836 | static const struct of_device_id samsung_pinctrl_dt_match[]; |
777 | 837 | ||
778 | /* retrieve the soc specific data */ | 838 | /* retrieve the soc specific data */ |
779 | static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( | 839 | static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( |
840 | struct samsung_pinctrl_drv_data *d, | ||
780 | struct platform_device *pdev) | 841 | struct platform_device *pdev) |
781 | { | 842 | { |
782 | int id; | 843 | int id; |
783 | const struct of_device_id *match; | 844 | const struct of_device_id *match; |
784 | const struct device_node *node = pdev->dev.of_node; | 845 | struct device_node *node = pdev->dev.of_node; |
846 | struct device_node *np; | ||
847 | struct samsung_pin_ctrl *ctrl; | ||
848 | struct samsung_pin_bank *bank; | ||
849 | int i; | ||
785 | 850 | ||
786 | id = of_alias_get_id(pdev->dev.of_node, "pinctrl"); | 851 | id = of_alias_get_id(node, "pinctrl"); |
787 | if (id < 0) { | 852 | if (id < 0) { |
788 | dev_err(&pdev->dev, "failed to get alias id\n"); | 853 | dev_err(&pdev->dev, "failed to get alias id\n"); |
789 | return NULL; | 854 | return NULL; |
790 | } | 855 | } |
791 | match = of_match_node(samsung_pinctrl_dt_match, node); | 856 | match = of_match_node(samsung_pinctrl_dt_match, node); |
792 | return (struct samsung_pin_ctrl *)match->data + id; | 857 | ctrl = (struct samsung_pin_ctrl *)match->data + id; |
858 | |||
859 | bank = ctrl->pin_banks; | ||
860 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | ||
861 | bank->drvdata = d; | ||
862 | bank->pin_base = ctrl->nr_pins; | ||
863 | ctrl->nr_pins += bank->nr_pins; | ||
864 | } | ||
865 | |||
866 | for_each_child_of_node(node, np) { | ||
867 | if (!of_find_property(np, "gpio-controller", NULL)) | ||
868 | continue; | ||
869 | bank = ctrl->pin_banks; | ||
870 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | ||
871 | if (!strcmp(bank->name, np->name)) { | ||
872 | bank->of_node = np; | ||
873 | break; | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | |||
878 | ctrl->base = pin_base; | ||
879 | pin_base += ctrl->nr_pins; | ||
880 | |||
881 | return ctrl; | ||
793 | } | 882 | } |
794 | 883 | ||
795 | static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) | 884 | static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) |
@@ -805,18 +894,18 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) | |||
805 | return -ENODEV; | 894 | return -ENODEV; |
806 | } | 895 | } |
807 | 896 | ||
808 | ctrl = samsung_pinctrl_get_soc_data(pdev); | ||
809 | if (!ctrl) { | ||
810 | dev_err(&pdev->dev, "driver data not available\n"); | ||
811 | return -EINVAL; | ||
812 | } | ||
813 | |||
814 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); | 897 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); |
815 | if (!drvdata) { | 898 | if (!drvdata) { |
816 | dev_err(dev, "failed to allocate memory for driver's " | 899 | dev_err(dev, "failed to allocate memory for driver's " |
817 | "private data\n"); | 900 | "private data\n"); |
818 | return -ENOMEM; | 901 | return -ENOMEM; |
819 | } | 902 | } |
903 | |||
904 | ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev); | ||
905 | if (!ctrl) { | ||
906 | dev_err(&pdev->dev, "driver data not available\n"); | ||
907 | return -EINVAL; | ||
908 | } | ||
820 | drvdata->ctrl = ctrl; | 909 | drvdata->ctrl = ctrl; |
821 | drvdata->dev = dev; | 910 | drvdata->dev = dev; |
822 | 911 | ||
@@ -858,6 +947,8 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) | |||
858 | static const struct of_device_id samsung_pinctrl_dt_match[] = { | 947 | static const struct of_device_id samsung_pinctrl_dt_match[] = { |
859 | { .compatible = "samsung,pinctrl-exynos4210", | 948 | { .compatible = "samsung,pinctrl-exynos4210", |
860 | .data = (void *)exynos4210_pin_ctrl }, | 949 | .data = (void *)exynos4210_pin_ctrl }, |
950 | { .compatible = "samsung,pinctrl-exynos4x12", | ||
951 | .data = (void *)exynos4x12_pin_ctrl }, | ||
861 | {}, | 952 | {}, |
862 | }; | 953 | }; |
863 | MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match); | 954 | MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match); |
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index b8956934cda6..5addfd16e3cc 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/pinctrl/consumer.h> | 23 | #include <linux/pinctrl/consumer.h> |
24 | #include <linux/pinctrl/machine.h> | 24 | #include <linux/pinctrl/machine.h> |
25 | 25 | ||
26 | #include <linux/gpio.h> | ||
27 | |||
26 | /* register offsets within a pin bank */ | 28 | /* register offsets within a pin bank */ |
27 | #define DAT_REG 0x4 | 29 | #define DAT_REG 0x4 |
28 | #define PUD_REG 0x8 | 30 | #define PUD_REG 0x8 |
@@ -64,6 +66,7 @@ enum pincfg_type { | |||
64 | * @EINT_TYPE_NONE: bank does not support external interrupts | 66 | * @EINT_TYPE_NONE: bank does not support external interrupts |
65 | * @EINT_TYPE_GPIO: bank supportes external gpio interrupts | 67 | * @EINT_TYPE_GPIO: bank supportes external gpio interrupts |
66 | * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts | 68 | * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts |
69 | * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts | ||
67 | * | 70 | * |
68 | * Samsung GPIO controller groups all the available pins into banks. The pins | 71 | * Samsung GPIO controller groups all the available pins into banks. The pins |
69 | * in a pin bank can support external gpio interrupts or external wakeup | 72 | * in a pin bank can support external gpio interrupts or external wakeup |
@@ -76,6 +79,7 @@ enum eint_type { | |||
76 | EINT_TYPE_NONE, | 79 | EINT_TYPE_NONE, |
77 | EINT_TYPE_GPIO, | 80 | EINT_TYPE_GPIO, |
78 | EINT_TYPE_WKUP, | 81 | EINT_TYPE_WKUP, |
82 | EINT_TYPE_WKUP_MUX, | ||
79 | }; | 83 | }; |
80 | 84 | ||
81 | /* maximum length of a pin in pin descriptor (example: "gpa0-0") */ | 85 | /* maximum length of a pin in pin descriptor (example: "gpa0-0") */ |
@@ -109,8 +113,12 @@ struct samsung_pinctrl_drv_data; | |||
109 | * @conpdn_width: width of the sleep mode function selector bin field. | 113 | * @conpdn_width: width of the sleep mode function selector bin field. |
110 | * @pudpdn_width: width of the sleep mode pull up/down selector bit field. | 114 | * @pudpdn_width: width of the sleep mode pull up/down selector bit field. |
111 | * @eint_type: type of the external interrupt supported by the bank. | 115 | * @eint_type: type of the external interrupt supported by the bank. |
112 | * @irq_base: starting controller local irq number of the bank. | ||
113 | * @name: name to be prefixed for each pin in this pin bank. | 116 | * @name: name to be prefixed for each pin in this pin bank. |
117 | * @of_node: OF node of the bank. | ||
118 | * @drvdata: link to controller driver data | ||
119 | * @irq_domain: IRQ domain of the bank. | ||
120 | * @gpio_chip: GPIO chip of the bank. | ||
121 | * @grange: linux gpio pin range supported by this bank. | ||
114 | */ | 122 | */ |
115 | struct samsung_pin_bank { | 123 | struct samsung_pin_bank { |
116 | u32 pctl_offset; | 124 | u32 pctl_offset; |
@@ -122,8 +130,13 @@ struct samsung_pin_bank { | |||
122 | u8 conpdn_width; | 130 | u8 conpdn_width; |
123 | u8 pudpdn_width; | 131 | u8 pudpdn_width; |
124 | enum eint_type eint_type; | 132 | enum eint_type eint_type; |
125 | u32 irq_base; | 133 | u32 eint_offset; |
126 | char *name; | 134 | char *name; |
135 | struct device_node *of_node; | ||
136 | struct samsung_pinctrl_drv_data *drvdata; | ||
137 | struct irq_domain *irq_domain; | ||
138 | struct gpio_chip gpio_chip; | ||
139 | struct pinctrl_gpio_range grange; | ||
127 | }; | 140 | }; |
128 | 141 | ||
129 | /** | 142 | /** |
@@ -132,8 +145,6 @@ struct samsung_pin_bank { | |||
132 | * @nr_banks: number of pin banks. | 145 | * @nr_banks: number of pin banks. |
133 | * @base: starting system wide pin number. | 146 | * @base: starting system wide pin number. |
134 | * @nr_pins: number of pins supported by the controller. | 147 | * @nr_pins: number of pins supported by the controller. |
135 | * @nr_gint: number of external gpio interrupts supported. | ||
136 | * @nr_wint: number of external wakeup interrupts supported. | ||
137 | * @geint_con: offset of the ext-gpio controller registers. | 148 | * @geint_con: offset of the ext-gpio controller registers. |
138 | * @geint_mask: offset of the ext-gpio interrupt mask registers. | 149 | * @geint_mask: offset of the ext-gpio interrupt mask registers. |
139 | * @geint_pend: offset of the ext-gpio interrupt pending registers. | 150 | * @geint_pend: offset of the ext-gpio interrupt pending registers. |
@@ -153,8 +164,6 @@ struct samsung_pin_ctrl { | |||
153 | 164 | ||
154 | u32 base; | 165 | u32 base; |
155 | u32 nr_pins; | 166 | u32 nr_pins; |
156 | u32 nr_gint; | ||
157 | u32 nr_wint; | ||
158 | 167 | ||
159 | u32 geint_con; | 168 | u32 geint_con; |
160 | u32 geint_mask; | 169 | u32 geint_mask; |
@@ -183,8 +192,6 @@ struct samsung_pin_ctrl { | |||
183 | * @nr_groups: number of such pin groups. | 192 | * @nr_groups: number of such pin groups. |
184 | * @pmx_functions: list of pin functions available to the driver. | 193 | * @pmx_functions: list of pin functions available to the driver. |
185 | * @nr_function: number of such pin functions. | 194 | * @nr_function: number of such pin functions. |
186 | * @gc: gpio_chip instance registered with gpiolib. | ||
187 | * @grange: linux gpio pin range supported by this controller. | ||
188 | */ | 195 | */ |
189 | struct samsung_pinctrl_drv_data { | 196 | struct samsung_pinctrl_drv_data { |
190 | void __iomem *virt_base; | 197 | void __iomem *virt_base; |
@@ -199,12 +206,6 @@ struct samsung_pinctrl_drv_data { | |||
199 | unsigned int nr_groups; | 206 | unsigned int nr_groups; |
200 | const struct samsung_pmx_func *pmx_functions; | 207 | const struct samsung_pmx_func *pmx_functions; |
201 | unsigned int nr_functions; | 208 | unsigned int nr_functions; |
202 | |||
203 | struct irq_domain *gpio_irqd; | ||
204 | struct irq_domain *wkup_irqd; | ||
205 | |||
206 | struct gpio_chip *gc; | ||
207 | struct pinctrl_gpio_range grange; | ||
208 | }; | 209 | }; |
209 | 210 | ||
210 | /** | 211 | /** |
@@ -235,5 +236,6 @@ struct samsung_pmx_func { | |||
235 | 236 | ||
236 | /* list of all exported SoC specific data */ | 237 | /* list of all exported SoC specific data */ |
237 | extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; | 238 | extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; |
239 | extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; | ||
238 | 240 | ||
239 | #endif /* __PINCTRL_SAMSUNG_H */ | 241 | #endif /* __PINCTRL_SAMSUNG_H */ |
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 726a729a2ec9..79642831bba2 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #define PCS_MUX_BITS_NAME "pinctrl-single,bits" | 30 | #define PCS_MUX_BITS_NAME "pinctrl-single,bits" |
31 | #define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) | 31 | #define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) |
32 | #define PCS_OFF_DISABLED ~0U | 32 | #define PCS_OFF_DISABLED ~0U |
33 | #define PCS_MAX_GPIO_VALUES 2 | ||
33 | 34 | ||
34 | /** | 35 | /** |
35 | * struct pcs_pingroup - pingroups for a function | 36 | * struct pcs_pingroup - pingroups for a function |
@@ -77,6 +78,16 @@ struct pcs_function { | |||
77 | }; | 78 | }; |
78 | 79 | ||
79 | /** | 80 | /** |
81 | * struct pcs_gpio_range - pinctrl gpio range | ||
82 | * @range: subrange of the GPIO number space | ||
83 | * @gpio_func: gpio function value in the pinmux register | ||
84 | */ | ||
85 | struct pcs_gpio_range { | ||
86 | struct pinctrl_gpio_range range; | ||
87 | int gpio_func; | ||
88 | }; | ||
89 | |||
90 | /** | ||
80 | * struct pcs_data - wrapper for data needed by pinctrl framework | 91 | * struct pcs_data - wrapper for data needed by pinctrl framework |
81 | * @pa: pindesc array | 92 | * @pa: pindesc array |
82 | * @cur: index to current element | 93 | * @cur: index to current element |
@@ -244,15 +255,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev, | |||
244 | 255 | ||
245 | static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, | 256 | static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, |
246 | struct seq_file *s, | 257 | struct seq_file *s, |
247 | unsigned offset) | 258 | unsigned pin) |
248 | { | 259 | { |
249 | struct pcs_device *pcs; | 260 | struct pcs_device *pcs; |
250 | unsigned val; | 261 | unsigned val, mux_bytes; |
251 | 262 | ||
252 | pcs = pinctrl_dev_get_drvdata(pctldev); | 263 | pcs = pinctrl_dev_get_drvdata(pctldev); |
253 | 264 | ||
254 | val = pcs->read(pcs->base + offset); | 265 | mux_bytes = pcs->width / BITS_PER_BYTE; |
255 | val &= pcs->fmask; | 266 | val = pcs->read(pcs->base + pin * mux_bytes); |
256 | 267 | ||
257 | seq_printf(s, "%08x %s " , val, DRIVER_NAME); | 268 | seq_printf(s, "%08x %s " , val, DRIVER_NAME); |
258 | } | 269 | } |
@@ -403,9 +414,26 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, | |||
403 | } | 414 | } |
404 | 415 | ||
405 | static int pcs_request_gpio(struct pinctrl_dev *pctldev, | 416 | static int pcs_request_gpio(struct pinctrl_dev *pctldev, |
406 | struct pinctrl_gpio_range *range, unsigned offset) | 417 | struct pinctrl_gpio_range *range, unsigned pin) |
407 | { | 418 | { |
408 | return -ENOTSUPP; | 419 | struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); |
420 | struct pcs_gpio_range *gpio = NULL; | ||
421 | int end, mux_bytes; | ||
422 | unsigned data; | ||
423 | |||
424 | gpio = container_of(range, struct pcs_gpio_range, range); | ||
425 | end = range->pin_base + range->npins - 1; | ||
426 | if (pin < range->pin_base || pin > end) { | ||
427 | dev_err(pctldev->dev, | ||
428 | "pin %d isn't in the range of %d to %d\n", | ||
429 | pin, range->pin_base, end); | ||
430 | return -EINVAL; | ||
431 | } | ||
432 | mux_bytes = pcs->width / BITS_PER_BYTE; | ||
433 | data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask; | ||
434 | data |= gpio->gpio_func; | ||
435 | pcs->write(data, pcs->base + pin * mux_bytes); | ||
436 | return 0; | ||
409 | } | 437 | } |
410 | 438 | ||
411 | static struct pinmux_ops pcs_pinmux_ops = { | 439 | static struct pinmux_ops pcs_pinmux_ops = { |
@@ -772,7 +800,7 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
772 | pcs = pinctrl_dev_get_drvdata(pctldev); | 800 | pcs = pinctrl_dev_get_drvdata(pctldev); |
773 | 801 | ||
774 | *map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL); | 802 | *map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL); |
775 | if (!map) | 803 | if (!*map) |
776 | return -ENOMEM; | 804 | return -ENOMEM; |
777 | 805 | ||
778 | *num_maps = 0; | 806 | *num_maps = 0; |
@@ -879,6 +907,50 @@ static void pcs_free_resources(struct pcs_device *pcs) | |||
879 | 907 | ||
880 | static struct of_device_id pcs_of_match[]; | 908 | static struct of_device_id pcs_of_match[]; |
881 | 909 | ||
910 | static int __devinit pcs_add_gpio_range(struct device_node *node, | ||
911 | struct pcs_device *pcs) | ||
912 | { | ||
913 | struct pcs_gpio_range *gpio; | ||
914 | struct device_node *child; | ||
915 | struct resource r; | ||
916 | const char name[] = "pinctrl-single"; | ||
917 | u32 gpiores[PCS_MAX_GPIO_VALUES]; | ||
918 | int ret, i = 0, mux_bytes = 0; | ||
919 | |||
920 | for_each_child_of_node(node, child) { | ||
921 | ret = of_address_to_resource(child, 0, &r); | ||
922 | if (ret < 0) | ||
923 | continue; | ||
924 | memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES); | ||
925 | ret = of_property_read_u32_array(child, "pinctrl-single,gpio", | ||
926 | gpiores, PCS_MAX_GPIO_VALUES); | ||
927 | if (ret < 0) | ||
928 | continue; | ||
929 | gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL); | ||
930 | if (!gpio) { | ||
931 | dev_err(pcs->dev, "failed to allocate pcs gpio\n"); | ||
932 | return -ENOMEM; | ||
933 | } | ||
934 | gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name), | ||
935 | GFP_KERNEL); | ||
936 | if (!gpio->range.name) { | ||
937 | dev_err(pcs->dev, "failed to allocate range name\n"); | ||
938 | return -ENOMEM; | ||
939 | } | ||
940 | memcpy((char *)gpio->range.name, name, sizeof(name)); | ||
941 | |||
942 | gpio->range.id = i++; | ||
943 | gpio->range.base = gpiores[0]; | ||
944 | gpio->gpio_func = gpiores[1]; | ||
945 | mux_bytes = pcs->width / BITS_PER_BYTE; | ||
946 | gpio->range.pin_base = (r.start - pcs->res->start) / mux_bytes; | ||
947 | gpio->range.npins = (r.end - r.start) / mux_bytes + 1; | ||
948 | |||
949 | pinctrl_add_gpio_range(pcs->pctl, &gpio->range); | ||
950 | } | ||
951 | return 0; | ||
952 | } | ||
953 | |||
882 | static int __devinit pcs_probe(struct platform_device *pdev) | 954 | static int __devinit pcs_probe(struct platform_device *pdev) |
883 | { | 955 | { |
884 | struct device_node *np = pdev->dev.of_node; | 956 | struct device_node *np = pdev->dev.of_node; |
@@ -975,6 +1047,10 @@ static int __devinit pcs_probe(struct platform_device *pdev) | |||
975 | goto free; | 1047 | goto free; |
976 | } | 1048 | } |
977 | 1049 | ||
1050 | ret = pcs_add_gpio_range(np, pcs); | ||
1051 | if (ret < 0) | ||
1052 | goto free; | ||
1053 | |||
978 | dev_info(pcs->dev, "%i pins at pa %p size %u\n", | 1054 | dev_info(pcs->dev, "%i pins at pa %p size %u\n", |
979 | pcs->desc.npins, pcs->base, pcs->size); | 1055 | pcs->desc.npins, pcs->base, pcs->size); |
980 | 1056 | ||
@@ -986,7 +1062,7 @@ free: | |||
986 | return ret; | 1062 | return ret; |
987 | } | 1063 | } |
988 | 1064 | ||
989 | static int __devexit pcs_remove(struct platform_device *pdev) | 1065 | static int pcs_remove(struct platform_device *pdev) |
990 | { | 1066 | { |
991 | struct pcs_device *pcs = platform_get_drvdata(pdev); | 1067 | struct pcs_device *pcs = platform_get_drvdata(pdev); |
992 | 1068 | ||
@@ -998,7 +1074,7 @@ static int __devexit pcs_remove(struct platform_device *pdev) | |||
998 | return 0; | 1074 | return 0; |
999 | } | 1075 | } |
1000 | 1076 | ||
1001 | static struct of_device_id pcs_of_match[] __devinitdata = { | 1077 | static struct of_device_id pcs_of_match[] = { |
1002 | { .compatible = DRIVER_NAME, }, | 1078 | { .compatible = DRIVER_NAME, }, |
1003 | { }, | 1079 | { }, |
1004 | }; | 1080 | }; |
@@ -1006,7 +1082,7 @@ MODULE_DEVICE_TABLE(of, pcs_of_match); | |||
1006 | 1082 | ||
1007 | static struct platform_driver pcs_driver = { | 1083 | static struct platform_driver pcs_driver = { |
1008 | .probe = pcs_probe, | 1084 | .probe = pcs_probe, |
1009 | .remove = __devexit_p(pcs_remove), | 1085 | .remove = pcs_remove, |
1010 | .driver = { | 1086 | .driver = { |
1011 | .owner = THIS_MODULE, | 1087 | .owner = THIS_MODULE, |
1012 | .name = DRIVER_NAME, | 1088 | .name = DRIVER_NAME, |
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 9ecacf3d0a75..a4f0c5e487d5 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c | |||
@@ -32,10 +32,10 @@ | |||
32 | #define SIRFSOC_NUM_PADS 622 | 32 | #define SIRFSOC_NUM_PADS 622 |
33 | #define SIRFSOC_RSC_PIN_MUX 0x4 | 33 | #define SIRFSOC_RSC_PIN_MUX 0x4 |
34 | 34 | ||
35 | #define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) | 35 | #define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) |
36 | #define SIRFSOC_GPIO_PAD_EN_CLR(g) ((g)*0x100 + 0x90) | ||
36 | #define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4) | 37 | #define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4) |
37 | #define SIRFSOC_GPIO_DSP_EN0 (0x80) | 38 | #define SIRFSOC_GPIO_DSP_EN0 (0x80) |
38 | #define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) | ||
39 | #define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C) | 39 | #define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C) |
40 | 40 | ||
41 | #define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 | 41 | #define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 |
@@ -60,6 +60,7 @@ struct sirfsoc_gpio_bank { | |||
60 | int id; | 60 | int id; |
61 | int parent_irq; | 61 | int parent_irq; |
62 | spinlock_t lock; | 62 | spinlock_t lock; |
63 | bool is_marco; /* for marco, some registers are different with prima2 */ | ||
63 | }; | 64 | }; |
64 | 65 | ||
65 | static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; | 66 | static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; |
@@ -191,6 +192,7 @@ struct sirfsoc_pmx { | |||
191 | struct pinctrl_dev *pmx; | 192 | struct pinctrl_dev *pmx; |
192 | void __iomem *gpio_virtbase; | 193 | void __iomem *gpio_virtbase; |
193 | void __iomem *rsc_virtbase; | 194 | void __iomem *rsc_virtbase; |
195 | bool is_marco; | ||
194 | }; | 196 | }; |
195 | 197 | ||
196 | /* SIRFSOC_GPIO_PAD_EN set */ | 198 | /* SIRFSOC_GPIO_PAD_EN set */ |
@@ -1088,12 +1090,21 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector | |||
1088 | 1090 | ||
1089 | for (i = 0; i < mux->muxmask_counts; i++) { | 1091 | for (i = 0; i < mux->muxmask_counts; i++) { |
1090 | u32 muxval; | 1092 | u32 muxval; |
1091 | muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); | 1093 | if (!spmx->is_marco) { |
1092 | if (enable) | 1094 | muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); |
1093 | muxval = muxval & ~mask[i].mask; | 1095 | if (enable) |
1094 | else | 1096 | muxval = muxval & ~mask[i].mask; |
1095 | muxval = muxval | mask[i].mask; | 1097 | else |
1096 | writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); | 1098 | muxval = muxval | mask[i].mask; |
1099 | writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); | ||
1100 | } else { | ||
1101 | if (enable) | ||
1102 | writel(mask[i].mask, spmx->gpio_virtbase + | ||
1103 | SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group)); | ||
1104 | else | ||
1105 | writel(mask[i].mask, spmx->gpio_virtbase + | ||
1106 | SIRFSOC_GPIO_PAD_EN(mask[i].group)); | ||
1107 | } | ||
1097 | } | 1108 | } |
1098 | 1109 | ||
1099 | if (mux->funcmask && enable) { | 1110 | if (mux->funcmask && enable) { |
@@ -1158,9 +1169,14 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, | |||
1158 | 1169 | ||
1159 | spmx = pinctrl_dev_get_drvdata(pmxdev); | 1170 | spmx = pinctrl_dev_get_drvdata(pmxdev); |
1160 | 1171 | ||
1161 | muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); | 1172 | if (!spmx->is_marco) { |
1162 | muxval = muxval | (1 << (offset - range->pin_base)); | 1173 | muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); |
1163 | writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); | 1174 | muxval = muxval | (1 << (offset - range->pin_base)); |
1175 | writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); | ||
1176 | } else { | ||
1177 | writel(1 << (offset - range->pin_base), spmx->gpio_virtbase + | ||
1178 | SIRFSOC_GPIO_PAD_EN(group)); | ||
1179 | } | ||
1164 | 1180 | ||
1165 | return 0; | 1181 | return 0; |
1166 | } | 1182 | } |
@@ -1218,6 +1234,7 @@ static void __iomem *sirfsoc_rsc_of_iomap(void) | |||
1218 | { | 1234 | { |
1219 | const struct of_device_id rsc_ids[] = { | 1235 | const struct of_device_id rsc_ids[] = { |
1220 | { .compatible = "sirf,prima2-rsc" }, | 1236 | { .compatible = "sirf,prima2-rsc" }, |
1237 | { .compatible = "sirf,marco-rsc" }, | ||
1221 | {} | 1238 | {} |
1222 | }; | 1239 | }; |
1223 | struct device_node *np; | 1240 | struct device_node *np; |
@@ -1259,6 +1276,9 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) | |||
1259 | goto out_no_rsc_remap; | 1276 | goto out_no_rsc_remap; |
1260 | } | 1277 | } |
1261 | 1278 | ||
1279 | if (of_device_is_compatible(np, "sirf,marco-pinctrl")) | ||
1280 | spmx->is_marco = 1; | ||
1281 | |||
1262 | /* Now register the pin controller and all pins it handles */ | 1282 | /* Now register the pin controller and all pins it handles */ |
1263 | spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); | 1283 | spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); |
1264 | if (!spmx->pmx) { | 1284 | if (!spmx->pmx) { |
@@ -1285,8 +1305,9 @@ out_no_gpio_remap: | |||
1285 | return ret; | 1305 | return ret; |
1286 | } | 1306 | } |
1287 | 1307 | ||
1288 | static const struct of_device_id pinmux_ids[] __devinitconst = { | 1308 | static const struct of_device_id pinmux_ids[] = { |
1289 | { .compatible = "sirf,prima2-pinctrl" }, | 1309 | { .compatible = "sirf,prima2-pinctrl" }, |
1310 | { .compatible = "sirf,marco-pinctrl" }, | ||
1290 | {} | 1311 | {} |
1291 | }; | 1312 | }; |
1292 | 1313 | ||
@@ -1621,8 +1642,8 @@ static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, | |||
1621 | spin_unlock_irqrestore(&bank->lock, flags); | 1642 | spin_unlock_irqrestore(&bank->lock, flags); |
1622 | } | 1643 | } |
1623 | 1644 | ||
1624 | int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, | 1645 | static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, |
1625 | irq_hw_number_t hwirq) | 1646 | irq_hw_number_t hwirq) |
1626 | { | 1647 | { |
1627 | struct sirfsoc_gpio_bank *bank = d->host_data; | 1648 | struct sirfsoc_gpio_bank *bank = d->host_data; |
1628 | 1649 | ||
@@ -1648,6 +1669,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) | |||
1648 | struct sirfsoc_gpio_bank *bank; | 1669 | struct sirfsoc_gpio_bank *bank; |
1649 | void *regs; | 1670 | void *regs; |
1650 | struct platform_device *pdev; | 1671 | struct platform_device *pdev; |
1672 | bool is_marco = false; | ||
1651 | 1673 | ||
1652 | pdev = of_find_device_by_node(np); | 1674 | pdev = of_find_device_by_node(np); |
1653 | if (!pdev) | 1675 | if (!pdev) |
@@ -1657,6 +1679,9 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) | |||
1657 | if (!regs) | 1679 | if (!regs) |
1658 | return -ENOMEM; | 1680 | return -ENOMEM; |
1659 | 1681 | ||
1682 | if (of_device_is_compatible(np, "sirf,marco-pinctrl")) | ||
1683 | is_marco = 1; | ||
1684 | |||
1660 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { | 1685 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { |
1661 | bank = &sgpio_bank[i]; | 1686 | bank = &sgpio_bank[i]; |
1662 | spin_lock_init(&bank->lock); | 1687 | spin_lock_init(&bank->lock); |
@@ -1673,6 +1698,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) | |||
1673 | bank->chip.gc.of_node = np; | 1698 | bank->chip.gc.of_node = np; |
1674 | bank->chip.regs = regs; | 1699 | bank->chip.regs = regs; |
1675 | bank->id = i; | 1700 | bank->id = i; |
1701 | bank->is_marco = is_marco; | ||
1676 | bank->parent_irq = platform_get_irq(pdev, i); | 1702 | bank->parent_irq = platform_get_irq(pdev, i); |
1677 | if (bank->parent_irq < 0) { | 1703 | if (bank->parent_irq < 0) { |
1678 | err = bank->parent_irq; | 1704 | err = bank->parent_irq; |
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index 7da0b371fd65..e356b0380fa7 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c | |||
@@ -178,8 +178,9 @@ static int add_config(struct device *dev, unsigned long **configs, | |||
178 | return 0; | 178 | return 0; |
179 | } | 179 | } |
180 | 180 | ||
181 | void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, | 181 | static void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, |
182 | struct pinctrl_map *map, unsigned num_maps) | 182 | struct pinctrl_map *map, |
183 | unsigned num_maps) | ||
183 | { | 184 | { |
184 | int i; | 185 | int i; |
185 | 186 | ||
@@ -209,11 +210,11 @@ static const struct cfg_param { | |||
209 | {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, | 210 | {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, |
210 | }; | 211 | }; |
211 | 212 | ||
212 | int tegra_pinctrl_dt_subnode_to_map(struct device *dev, | 213 | static int tegra_pinctrl_dt_subnode_to_map(struct device *dev, |
213 | struct device_node *np, | 214 | struct device_node *np, |
214 | struct pinctrl_map **map, | 215 | struct pinctrl_map **map, |
215 | unsigned *reserved_maps, | 216 | unsigned *reserved_maps, |
216 | unsigned *num_maps) | 217 | unsigned *num_maps) |
217 | { | 218 | { |
218 | int ret, i; | 219 | int ret, i; |
219 | const char *function; | 220 | const char *function; |
@@ -288,9 +289,10 @@ exit: | |||
288 | return ret; | 289 | return ret; |
289 | } | 290 | } |
290 | 291 | ||
291 | int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, | 292 | static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, |
292 | struct device_node *np_config, | 293 | struct device_node *np_config, |
293 | struct pinctrl_map **map, unsigned *num_maps) | 294 | struct pinctrl_map **map, |
295 | unsigned *num_maps) | ||
294 | { | 296 | { |
295 | unsigned reserved_maps; | 297 | unsigned reserved_maps; |
296 | struct device_node *np; | 298 | struct device_node *np; |
@@ -660,7 +662,7 @@ static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, | |||
660 | } | 662 | } |
661 | #endif | 663 | #endif |
662 | 664 | ||
663 | struct pinconf_ops tegra_pinconf_ops = { | 665 | static struct pinconf_ops tegra_pinconf_ops = { |
664 | .pin_config_get = tegra_pinconf_get, | 666 | .pin_config_get = tegra_pinconf_get, |
665 | .pin_config_set = tegra_pinconf_set, | 667 | .pin_config_set = tegra_pinconf_set, |
666 | .pin_config_group_get = tegra_pinconf_group_get, | 668 | .pin_config_group_get = tegra_pinconf_group_get, |
@@ -758,7 +760,7 @@ int __devinit tegra_pinctrl_probe(struct platform_device *pdev, | |||
758 | } | 760 | } |
759 | EXPORT_SYMBOL_GPL(tegra_pinctrl_probe); | 761 | EXPORT_SYMBOL_GPL(tegra_pinctrl_probe); |
760 | 762 | ||
761 | int __devexit tegra_pinctrl_remove(struct platform_device *pdev) | 763 | int tegra_pinctrl_remove(struct platform_device *pdev) |
762 | { | 764 | { |
763 | struct tegra_pmx *pmx = platform_get_drvdata(pdev); | 765 | struct tegra_pmx *pmx = platform_get_drvdata(pdev); |
764 | 766 | ||
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c index a74f9a568536..1524bfd66602 100644 --- a/drivers/pinctrl/pinctrl-tegra20.c +++ b/drivers/pinctrl/pinctrl-tegra20.c | |||
@@ -2861,7 +2861,7 @@ static int __devinit tegra20_pinctrl_probe(struct platform_device *pdev) | |||
2861 | return tegra_pinctrl_probe(pdev, &tegra20_pinctrl); | 2861 | return tegra_pinctrl_probe(pdev, &tegra20_pinctrl); |
2862 | } | 2862 | } |
2863 | 2863 | ||
2864 | static struct of_device_id tegra20_pinctrl_of_match[] __devinitdata = { | 2864 | static struct of_device_id tegra20_pinctrl_of_match[] = { |
2865 | { .compatible = "nvidia,tegra20-pinmux", }, | 2865 | { .compatible = "nvidia,tegra20-pinmux", }, |
2866 | { }, | 2866 | { }, |
2867 | }; | 2867 | }; |
@@ -2873,7 +2873,7 @@ static struct platform_driver tegra20_pinctrl_driver = { | |||
2873 | .of_match_table = tegra20_pinctrl_of_match, | 2873 | .of_match_table = tegra20_pinctrl_of_match, |
2874 | }, | 2874 | }, |
2875 | .probe = tegra20_pinctrl_probe, | 2875 | .probe = tegra20_pinctrl_probe, |
2876 | .remove = __devexit_p(tegra_pinctrl_remove), | 2876 | .remove = tegra_pinctrl_remove, |
2877 | }; | 2877 | }; |
2878 | 2878 | ||
2879 | static int __init tegra20_pinctrl_init(void) | 2879 | static int __init tegra20_pinctrl_init(void) |
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c index 7894f14c7059..cf579ebf346f 100644 --- a/drivers/pinctrl/pinctrl-tegra30.c +++ b/drivers/pinctrl/pinctrl-tegra30.c | |||
@@ -3727,7 +3727,7 @@ static int __devinit tegra30_pinctrl_probe(struct platform_device *pdev) | |||
3727 | return tegra_pinctrl_probe(pdev, &tegra30_pinctrl); | 3727 | return tegra_pinctrl_probe(pdev, &tegra30_pinctrl); |
3728 | } | 3728 | } |
3729 | 3729 | ||
3730 | static struct of_device_id tegra30_pinctrl_of_match[] __devinitdata = { | 3730 | static struct of_device_id tegra30_pinctrl_of_match[] = { |
3731 | { .compatible = "nvidia,tegra30-pinmux", }, | 3731 | { .compatible = "nvidia,tegra30-pinmux", }, |
3732 | { }, | 3732 | { }, |
3733 | }; | 3733 | }; |
@@ -3739,7 +3739,7 @@ static struct platform_driver tegra30_pinctrl_driver = { | |||
3739 | .of_match_table = tegra30_pinctrl_of_match, | 3739 | .of_match_table = tegra30_pinctrl_of_match, |
3740 | }, | 3740 | }, |
3741 | .probe = tegra30_pinctrl_probe, | 3741 | .probe = tegra30_pinctrl_probe, |
3742 | .remove = __devexit_p(tegra_pinctrl_remove), | 3742 | .remove = tegra_pinctrl_remove, |
3743 | }; | 3743 | }; |
3744 | 3744 | ||
3745 | static int __init tegra30_pinctrl_init(void) | 3745 | static int __init tegra30_pinctrl_init(void) |
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index 309f5b9a70ec..8c039ad22baf 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c | |||
@@ -663,8 +663,6 @@ static const struct pinctrl_pin_desc u300_pads[] = { | |||
663 | struct u300_pmx { | 663 | struct u300_pmx { |
664 | struct device *dev; | 664 | struct device *dev; |
665 | struct pinctrl_dev *pctl; | 665 | struct pinctrl_dev *pctl; |
666 | u32 phybase; | ||
667 | u32 physize; | ||
668 | void __iomem *virtbase; | 666 | void __iomem *virtbase; |
669 | }; | 667 | }; |
670 | 668 | ||
@@ -1013,52 +1011,11 @@ static struct pinmux_ops u300_pmx_ops = { | |||
1013 | .disable = u300_pmx_disable, | 1011 | .disable = u300_pmx_disable, |
1014 | }; | 1012 | }; |
1015 | 1013 | ||
1016 | /* | 1014 | static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, |
1017 | * GPIO ranges handled by the application-side COH901XXX GPIO controller | 1015 | unsigned long *config) |
1018 | * Very many pins can be converted into GPIO pins, but we only list those | ||
1019 | * that are useful in practice to cut down on tables. | ||
1020 | */ | ||
1021 | #define U300_GPIO_RANGE(a, b, c) { .name = "COH901XXX", .id = a, .base= a, \ | ||
1022 | .pin_base = b, .npins = c } | ||
1023 | |||
1024 | static struct pinctrl_gpio_range u300_gpio_ranges[] = { | ||
1025 | U300_GPIO_RANGE(10, 426, 1), | ||
1026 | U300_GPIO_RANGE(11, 180, 1), | ||
1027 | U300_GPIO_RANGE(12, 165, 1), /* MS/MMC card insertion */ | ||
1028 | U300_GPIO_RANGE(13, 179, 1), | ||
1029 | U300_GPIO_RANGE(14, 178, 1), | ||
1030 | U300_GPIO_RANGE(16, 194, 1), | ||
1031 | U300_GPIO_RANGE(17, 193, 1), | ||
1032 | U300_GPIO_RANGE(18, 192, 1), | ||
1033 | U300_GPIO_RANGE(19, 191, 1), | ||
1034 | U300_GPIO_RANGE(20, 186, 1), | ||
1035 | U300_GPIO_RANGE(21, 185, 1), | ||
1036 | U300_GPIO_RANGE(22, 184, 1), | ||
1037 | U300_GPIO_RANGE(23, 183, 1), | ||
1038 | U300_GPIO_RANGE(24, 182, 1), | ||
1039 | U300_GPIO_RANGE(25, 181, 1), | ||
1040 | }; | ||
1041 | |||
1042 | static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin) | ||
1043 | { | ||
1044 | int i; | ||
1045 | |||
1046 | for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { | ||
1047 | struct pinctrl_gpio_range *range; | ||
1048 | |||
1049 | range = &u300_gpio_ranges[i]; | ||
1050 | if (pin >= range->pin_base && | ||
1051 | pin <= (range->pin_base + range->npins - 1)) | ||
1052 | return range; | ||
1053 | } | ||
1054 | return NULL; | ||
1055 | } | ||
1056 | |||
1057 | int u300_pin_config_get(struct pinctrl_dev *pctldev, | ||
1058 | unsigned pin, | ||
1059 | unsigned long *config) | ||
1060 | { | 1016 | { |
1061 | struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); | 1017 | struct pinctrl_gpio_range *range = |
1018 | pinctrl_find_gpio_range_from_pin(pctldev, pin); | ||
1062 | 1019 | ||
1063 | /* We get config for those pins we CAN get it for and that's it */ | 1020 | /* We get config for those pins we CAN get it for and that's it */ |
1064 | if (!range) | 1021 | if (!range) |
@@ -1069,11 +1026,11 @@ int u300_pin_config_get(struct pinctrl_dev *pctldev, | |||
1069 | config); | 1026 | config); |
1070 | } | 1027 | } |
1071 | 1028 | ||
1072 | int u300_pin_config_set(struct pinctrl_dev *pctldev, | 1029 | static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, |
1073 | unsigned pin, | 1030 | unsigned long config) |
1074 | unsigned long config) | ||
1075 | { | 1031 | { |
1076 | struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); | 1032 | struct pinctrl_gpio_range *range = |
1033 | pinctrl_find_gpio_range_from_pin(pctldev, pin); | ||
1077 | int ret; | 1034 | int ret; |
1078 | 1035 | ||
1079 | if (!range) | 1036 | if (!range) |
@@ -1109,9 +1066,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) | |||
1109 | { | 1066 | { |
1110 | struct u300_pmx *upmx; | 1067 | struct u300_pmx *upmx; |
1111 | struct resource *res; | 1068 | struct resource *res; |
1112 | struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev); | ||
1113 | int ret; | ||
1114 | int i; | ||
1115 | 1069 | ||
1116 | /* Create state holders etc for this driver */ | 1070 | /* Create state holders etc for this driver */ |
1117 | upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); | 1071 | upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); |
@@ -1123,32 +1077,15 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) | |||
1123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1077 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1124 | if (!res) | 1078 | if (!res) |
1125 | return -ENOENT; | 1079 | return -ENOENT; |
1126 | upmx->phybase = res->start; | ||
1127 | upmx->physize = resource_size(res); | ||
1128 | |||
1129 | if (request_mem_region(upmx->phybase, upmx->physize, | ||
1130 | DRIVER_NAME) == NULL) { | ||
1131 | ret = -ENOMEM; | ||
1132 | goto out_no_memregion; | ||
1133 | } | ||
1134 | 1080 | ||
1135 | upmx->virtbase = ioremap(upmx->phybase, upmx->physize); | 1081 | upmx->virtbase = devm_request_and_ioremap(&pdev->dev, res); |
1136 | if (!upmx->virtbase) { | 1082 | if (!upmx->virtbase) |
1137 | ret = -ENOMEM; | 1083 | return -ENOMEM; |
1138 | goto out_no_remap; | ||
1139 | } | ||
1140 | 1084 | ||
1141 | upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx); | 1085 | upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx); |
1142 | if (!upmx->pctl) { | 1086 | if (!upmx->pctl) { |
1143 | dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); | 1087 | dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); |
1144 | ret = -EINVAL; | 1088 | return -EINVAL; |
1145 | goto out_no_pmx; | ||
1146 | } | ||
1147 | |||
1148 | /* We will handle a range of GPIO pins */ | ||
1149 | for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { | ||
1150 | u300_gpio_ranges[i].gc = gpio_chip; | ||
1151 | pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); | ||
1152 | } | 1089 | } |
1153 | 1090 | ||
1154 | platform_set_drvdata(pdev, upmx); | 1091 | platform_set_drvdata(pdev, upmx); |
@@ -1156,23 +1093,13 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) | |||
1156 | dev_info(&pdev->dev, "initialized U300 pin control driver\n"); | 1093 | dev_info(&pdev->dev, "initialized U300 pin control driver\n"); |
1157 | 1094 | ||
1158 | return 0; | 1095 | return 0; |
1159 | |||
1160 | out_no_pmx: | ||
1161 | iounmap(upmx->virtbase); | ||
1162 | out_no_remap: | ||
1163 | platform_set_drvdata(pdev, NULL); | ||
1164 | out_no_memregion: | ||
1165 | release_mem_region(upmx->phybase, upmx->physize); | ||
1166 | return ret; | ||
1167 | } | 1096 | } |
1168 | 1097 | ||
1169 | static int __devexit u300_pmx_remove(struct platform_device *pdev) | 1098 | static int u300_pmx_remove(struct platform_device *pdev) |
1170 | { | 1099 | { |
1171 | struct u300_pmx *upmx = platform_get_drvdata(pdev); | 1100 | struct u300_pmx *upmx = platform_get_drvdata(pdev); |
1172 | 1101 | ||
1173 | pinctrl_unregister(upmx->pctl); | 1102 | pinctrl_unregister(upmx->pctl); |
1174 | iounmap(upmx->virtbase); | ||
1175 | release_mem_region(upmx->phybase, upmx->physize); | ||
1176 | platform_set_drvdata(pdev, NULL); | 1103 | platform_set_drvdata(pdev, NULL); |
1177 | 1104 | ||
1178 | return 0; | 1105 | return 0; |
@@ -1184,7 +1111,7 @@ static struct platform_driver u300_pmx_driver = { | |||
1184 | .owner = THIS_MODULE, | 1111 | .owner = THIS_MODULE, |
1185 | }, | 1112 | }, |
1186 | .probe = u300_pmx_probe, | 1113 | .probe = u300_pmx_probe, |
1187 | .remove = __devexit_p(u300_pmx_remove), | 1114 | .remove = u300_pmx_remove, |
1188 | }; | 1115 | }; |
1189 | 1116 | ||
1190 | static int __init u300_pmx_init(void) | 1117 | static int __init u300_pmx_init(void) |
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index b9bcaec66223..ad90984ec500 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c | |||
@@ -522,7 +522,7 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev, | |||
522 | return 0; | 522 | return 0; |
523 | } | 523 | } |
524 | 524 | ||
525 | struct pinconf_ops xway_pinconf_ops = { | 525 | static struct pinconf_ops xway_pinconf_ops = { |
526 | .pin_config_get = xway_pinconf_get, | 526 | .pin_config_get = xway_pinconf_get, |
527 | .pin_config_set = xway_pinconf_set, | 527 | .pin_config_set = xway_pinconf_set, |
528 | }; | 528 | }; |
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 9301a7a95eff..1a00658b3ea0 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
@@ -314,14 +314,11 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, | |||
314 | { | 314 | { |
315 | struct pinctrl_dev *pctldev = setting->pctldev; | 315 | struct pinctrl_dev *pctldev = setting->pctldev; |
316 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; | 316 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; |
317 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
318 | char const * const *groups; | 317 | char const * const *groups; |
319 | unsigned num_groups; | 318 | unsigned num_groups; |
320 | int ret; | 319 | int ret; |
321 | const char *group; | 320 | const char *group; |
322 | int i; | 321 | int i; |
323 | const unsigned *pins; | ||
324 | unsigned num_pins; | ||
325 | 322 | ||
326 | if (!pmxops) { | 323 | if (!pmxops) { |
327 | dev_err(pctldev->dev, "does not support mux function\n"); | 324 | dev_err(pctldev->dev, "does not support mux function\n"); |
@@ -376,53 +373,12 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, | |||
376 | } | 373 | } |
377 | setting->data.mux.group = ret; | 374 | setting->data.mux.group = ret; |
378 | 375 | ||
379 | ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins, | ||
380 | &num_pins); | ||
381 | if (ret) { | ||
382 | dev_err(pctldev->dev, | ||
383 | "could not get pins for device %s group selector %d\n", | ||
384 | pinctrl_dev_get_name(pctldev), setting->data.mux.group); | ||
385 | return -ENODEV; | ||
386 | } | ||
387 | |||
388 | /* Try to allocate all pins in this group, one by one */ | ||
389 | for (i = 0; i < num_pins; i++) { | ||
390 | ret = pin_request(pctldev, pins[i], map->dev_name, NULL); | ||
391 | if (ret) { | ||
392 | dev_err(pctldev->dev, | ||
393 | "could not request pin %d on device %s\n", | ||
394 | pins[i], pinctrl_dev_get_name(pctldev)); | ||
395 | /* On error release all taken pins */ | ||
396 | i--; /* this pin just failed */ | ||
397 | for (; i >= 0; i--) | ||
398 | pin_free(pctldev, pins[i], NULL); | ||
399 | return -ENODEV; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | return 0; | 376 | return 0; |
404 | } | 377 | } |
405 | 378 | ||
406 | void pinmux_free_setting(struct pinctrl_setting const *setting) | 379 | void pinmux_free_setting(struct pinctrl_setting const *setting) |
407 | { | 380 | { |
408 | struct pinctrl_dev *pctldev = setting->pctldev; | 381 | /* This function is currently unused */ |
409 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
410 | const unsigned *pins; | ||
411 | unsigned num_pins; | ||
412 | int ret; | ||
413 | int i; | ||
414 | |||
415 | ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, | ||
416 | &pins, &num_pins); | ||
417 | if (ret) { | ||
418 | dev_err(pctldev->dev, | ||
419 | "could not get pins for device %s group selector %d\n", | ||
420 | pinctrl_dev_get_name(pctldev), setting->data.mux.group); | ||
421 | return; | ||
422 | } | ||
423 | |||
424 | for (i = 0; i < num_pins; i++) | ||
425 | pin_free(pctldev, pins[i], NULL); | ||
426 | } | 382 | } |
427 | 383 | ||
428 | int pinmux_enable_setting(struct pinctrl_setting const *setting) | 384 | int pinmux_enable_setting(struct pinctrl_setting const *setting) |
@@ -446,6 +402,18 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) | |||
446 | num_pins = 0; | 402 | num_pins = 0; |
447 | } | 403 | } |
448 | 404 | ||
405 | /* Try to allocate all pins in this group, one by one */ | ||
406 | for (i = 0; i < num_pins; i++) { | ||
407 | ret = pin_request(pctldev, pins[i], setting->dev_name, NULL); | ||
408 | if (ret) { | ||
409 | dev_err(pctldev->dev, | ||
410 | "could not request pin %d on device %s\n", | ||
411 | pins[i], pinctrl_dev_get_name(pctldev)); | ||
412 | goto err_pin_request; | ||
413 | } | ||
414 | } | ||
415 | |||
416 | /* Now that we have acquired the pins, encode the mux setting */ | ||
449 | for (i = 0; i < num_pins; i++) { | 417 | for (i = 0; i < num_pins; i++) { |
450 | desc = pin_desc_get(pctldev, pins[i]); | 418 | desc = pin_desc_get(pctldev, pins[i]); |
451 | if (desc == NULL) { | 419 | if (desc == NULL) { |
@@ -457,8 +425,26 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) | |||
457 | desc->mux_setting = &(setting->data.mux); | 425 | desc->mux_setting = &(setting->data.mux); |
458 | } | 426 | } |
459 | 427 | ||
460 | return ops->enable(pctldev, setting->data.mux.func, | 428 | ret = ops->enable(pctldev, setting->data.mux.func, |
461 | setting->data.mux.group); | 429 | setting->data.mux.group); |
430 | |||
431 | if (ret) | ||
432 | goto err_enable; | ||
433 | |||
434 | return 0; | ||
435 | |||
436 | err_enable: | ||
437 | for (i = 0; i < num_pins; i++) { | ||
438 | desc = pin_desc_get(pctldev, pins[i]); | ||
439 | if (desc) | ||
440 | desc->mux_setting = NULL; | ||
441 | } | ||
442 | err_pin_request: | ||
443 | /* On error release all taken pins */ | ||
444 | while (--i >= 0) | ||
445 | pin_free(pctldev, pins[i], NULL); | ||
446 | |||
447 | return ret; | ||
462 | } | 448 | } |
463 | 449 | ||
464 | void pinmux_disable_setting(struct pinctrl_setting const *setting) | 450 | void pinmux_disable_setting(struct pinctrl_setting const *setting) |
@@ -482,6 +468,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) | |||
482 | num_pins = 0; | 468 | num_pins = 0; |
483 | } | 469 | } |
484 | 470 | ||
471 | /* Flag the descs that no setting is active */ | ||
485 | for (i = 0; i < num_pins; i++) { | 472 | for (i = 0; i < num_pins; i++) { |
486 | desc = pin_desc_get(pctldev, pins[i]); | 473 | desc = pin_desc_get(pctldev, pins[i]); |
487 | if (desc == NULL) { | 474 | if (desc == NULL) { |
@@ -493,6 +480,10 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) | |||
493 | desc->mux_setting = NULL; | 480 | desc->mux_setting = NULL; |
494 | } | 481 | } |
495 | 482 | ||
483 | /* And release the pins */ | ||
484 | for (i = 0; i < num_pins; i++) | ||
485 | pin_free(pctldev, pins[i], NULL); | ||
486 | |||
496 | if (ops->disable) | 487 | if (ops->disable) |
497 | ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); | 488 | ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); |
498 | } | 489 | } |
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig index 91558791e766..04d93e602674 100644 --- a/drivers/pinctrl/spear/Kconfig +++ b/drivers/pinctrl/spear/Kconfig | |||
@@ -25,20 +25,31 @@ config PINCTRL_SPEAR310 | |||
25 | bool "ST Microelectronics SPEAr310 SoC pin controller driver" | 25 | bool "ST Microelectronics SPEAr310 SoC pin controller driver" |
26 | depends on MACH_SPEAR310 | 26 | depends on MACH_SPEAR310 |
27 | select PINCTRL_SPEAR3XX | 27 | select PINCTRL_SPEAR3XX |
28 | select PINCTRL_SPEAR_PLGPIO | ||
28 | 29 | ||
29 | config PINCTRL_SPEAR320 | 30 | config PINCTRL_SPEAR320 |
30 | bool "ST Microelectronics SPEAr320 SoC pin controller driver" | 31 | bool "ST Microelectronics SPEAr320 SoC pin controller driver" |
31 | depends on MACH_SPEAR320 | 32 | depends on MACH_SPEAR320 |
32 | select PINCTRL_SPEAR3XX | 33 | select PINCTRL_SPEAR3XX |
34 | select PINCTRL_SPEAR_PLGPIO | ||
33 | 35 | ||
34 | config PINCTRL_SPEAR1310 | 36 | config PINCTRL_SPEAR1310 |
35 | bool "ST Microelectronics SPEAr1310 SoC pin controller driver" | 37 | bool "ST Microelectronics SPEAr1310 SoC pin controller driver" |
36 | depends on MACH_SPEAR1310 | 38 | depends on MACH_SPEAR1310 |
37 | select PINCTRL_SPEAR | 39 | select PINCTRL_SPEAR |
40 | select PINCTRL_SPEAR_PLGPIO | ||
38 | 41 | ||
39 | config PINCTRL_SPEAR1340 | 42 | config PINCTRL_SPEAR1340 |
40 | bool "ST Microelectronics SPEAr1340 SoC pin controller driver" | 43 | bool "ST Microelectronics SPEAr1340 SoC pin controller driver" |
41 | depends on MACH_SPEAR1340 | 44 | depends on MACH_SPEAR1340 |
42 | select PINCTRL_SPEAR | 45 | select PINCTRL_SPEAR |
46 | select PINCTRL_SPEAR_PLGPIO | ||
47 | |||
48 | config PINCTRL_SPEAR_PLGPIO | ||
49 | bool "SPEAr SoC PLGPIO Controller" | ||
50 | depends on GPIOLIB && PINCTRL_SPEAR | ||
51 | help | ||
52 | Say yes here to support PLGPIO controller on ST Microelectronics SPEAr | ||
53 | SoCs. | ||
43 | 54 | ||
44 | endif | 55 | endif |
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile index b28a7ba22443..0e400ebeb8ff 100644 --- a/drivers/pinctrl/spear/Makefile +++ b/drivers/pinctrl/spear/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | # SPEAr pinmux support | 1 | # SPEAr pinmux support |
2 | 2 | ||
3 | obj-$(CONFIG_PINCTRL_SPEAR_PLGPIO) += pinctrl-plgpio.o | ||
3 | obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o | 4 | obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o |
4 | obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o | 5 | obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o |
5 | obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o | 6 | obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o |
diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c new file mode 100644 index 000000000000..4c045053bbdd --- /dev/null +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c | |||
@@ -0,0 +1,758 @@ | |||
1 | /* | ||
2 | * SPEAr platform PLGPIO driver | ||
3 | * | ||
4 | * Copyright (C) 2012 ST Microelectronics | ||
5 | * Viresh Kumar <viresh.kumar@linaro.org> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/irqdomain.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/pinctrl/consumer.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/pm.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <asm/mach/irq.h> | ||
24 | |||
25 | #define MAX_GPIO_PER_REG 32 | ||
26 | #define PIN_OFFSET(pin) (pin % MAX_GPIO_PER_REG) | ||
27 | #define REG_OFFSET(base, reg, pin) (base + reg + (pin / MAX_GPIO_PER_REG) \ | ||
28 | * sizeof(int *)) | ||
29 | |||
30 | /* | ||
31 | * plgpio pins in all machines are not one to one mapped, bitwise with registers | ||
32 | * bits. These set of macros define register masks for which below functions | ||
33 | * (pin_to_offset and offset_to_pin) are required to be called. | ||
34 | */ | ||
35 | #define PTO_ENB_REG 0x001 | ||
36 | #define PTO_WDATA_REG 0x002 | ||
37 | #define PTO_DIR_REG 0x004 | ||
38 | #define PTO_IE_REG 0x008 | ||
39 | #define PTO_RDATA_REG 0x010 | ||
40 | #define PTO_MIS_REG 0x020 | ||
41 | |||
42 | struct plgpio_regs { | ||
43 | u32 enb; /* enable register */ | ||
44 | u32 wdata; /* write data register */ | ||
45 | u32 dir; /* direction set register */ | ||
46 | u32 rdata; /* read data register */ | ||
47 | u32 ie; /* interrupt enable register */ | ||
48 | u32 mis; /* mask interrupt status register */ | ||
49 | u32 eit; /* edge interrupt type */ | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * struct plgpio: plgpio driver specific structure | ||
54 | * | ||
55 | * lock: lock for guarding gpio registers | ||
56 | * base: base address of plgpio block | ||
57 | * irq_base: irq number of plgpio0 | ||
58 | * chip: gpio framework specific chip information structure | ||
59 | * p2o: function ptr for pin to offset conversion. This is required only for | ||
60 | * machines where mapping b/w pin and offset is not 1-to-1. | ||
61 | * o2p: function ptr for offset to pin conversion. This is required only for | ||
62 | * machines where mapping b/w pin and offset is not 1-to-1. | ||
63 | * p2o_regs: mask of registers for which p2o and o2p are applicable | ||
64 | * regs: register offsets | ||
65 | * csave_regs: context save registers for standby/sleep/hibernate cases | ||
66 | */ | ||
67 | struct plgpio { | ||
68 | spinlock_t lock; | ||
69 | void __iomem *base; | ||
70 | struct clk *clk; | ||
71 | unsigned irq_base; | ||
72 | struct irq_domain *irq_domain; | ||
73 | struct gpio_chip chip; | ||
74 | int (*p2o)(int pin); /* pin_to_offset */ | ||
75 | int (*o2p)(int offset); /* offset_to_pin */ | ||
76 | u32 p2o_regs; | ||
77 | struct plgpio_regs regs; | ||
78 | #ifdef CONFIG_PM | ||
79 | struct plgpio_regs *csave_regs; | ||
80 | #endif | ||
81 | }; | ||
82 | |||
83 | /* register manipulation inline functions */ | ||
84 | static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg) | ||
85 | { | ||
86 | u32 offset = PIN_OFFSET(pin); | ||
87 | void __iomem *reg_off = REG_OFFSET(base, reg, pin); | ||
88 | u32 val = readl_relaxed(reg_off); | ||
89 | |||
90 | return !!(val & (1 << offset)); | ||
91 | } | ||
92 | |||
93 | static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg) | ||
94 | { | ||
95 | u32 offset = PIN_OFFSET(pin); | ||
96 | void __iomem *reg_off = REG_OFFSET(base, reg, pin); | ||
97 | u32 val = readl_relaxed(reg_off); | ||
98 | |||
99 | writel_relaxed(val | (1 << offset), reg_off); | ||
100 | } | ||
101 | |||
102 | static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg) | ||
103 | { | ||
104 | u32 offset = PIN_OFFSET(pin); | ||
105 | void __iomem *reg_off = REG_OFFSET(base, reg, pin); | ||
106 | u32 val = readl_relaxed(reg_off); | ||
107 | |||
108 | writel_relaxed(val & ~(1 << offset), reg_off); | ||
109 | } | ||
110 | |||
111 | /* gpio framework specific routines */ | ||
112 | static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
113 | { | ||
114 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
115 | unsigned long flags; | ||
116 | |||
117 | /* get correct offset for "offset" pin */ | ||
118 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) { | ||
119 | offset = plgpio->p2o(offset); | ||
120 | if (offset == -1) | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | spin_lock_irqsave(&plgpio->lock, flags); | ||
125 | plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir); | ||
126 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
132 | int value) | ||
133 | { | ||
134 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
135 | unsigned long flags; | ||
136 | unsigned dir_offset = offset, wdata_offset = offset, tmp; | ||
137 | |||
138 | /* get correct offset for "offset" pin */ | ||
139 | if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) { | ||
140 | tmp = plgpio->p2o(offset); | ||
141 | if (tmp == -1) | ||
142 | return -EINVAL; | ||
143 | |||
144 | if (plgpio->p2o_regs & PTO_DIR_REG) | ||
145 | dir_offset = tmp; | ||
146 | if (plgpio->p2o_regs & PTO_WDATA_REG) | ||
147 | wdata_offset = tmp; | ||
148 | } | ||
149 | |||
150 | spin_lock_irqsave(&plgpio->lock, flags); | ||
151 | if (value) | ||
152 | plgpio_reg_set(plgpio->base, wdata_offset, | ||
153 | plgpio->regs.wdata); | ||
154 | else | ||
155 | plgpio_reg_reset(plgpio->base, wdata_offset, | ||
156 | plgpio->regs.wdata); | ||
157 | |||
158 | plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir); | ||
159 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int plgpio_get_value(struct gpio_chip *chip, unsigned offset) | ||
165 | { | ||
166 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
167 | |||
168 | if (offset >= chip->ngpio) | ||
169 | return -EINVAL; | ||
170 | |||
171 | /* get correct offset for "offset" pin */ | ||
172 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) { | ||
173 | offset = plgpio->p2o(offset); | ||
174 | if (offset == -1) | ||
175 | return -EINVAL; | ||
176 | } | ||
177 | |||
178 | return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata); | ||
179 | } | ||
180 | |||
181 | static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value) | ||
182 | { | ||
183 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
184 | |||
185 | if (offset >= chip->ngpio) | ||
186 | return; | ||
187 | |||
188 | /* get correct offset for "offset" pin */ | ||
189 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) { | ||
190 | offset = plgpio->p2o(offset); | ||
191 | if (offset == -1) | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | if (value) | ||
196 | plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata); | ||
197 | else | ||
198 | plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata); | ||
199 | } | ||
200 | |||
201 | static int plgpio_request(struct gpio_chip *chip, unsigned offset) | ||
202 | { | ||
203 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
204 | int gpio = chip->base + offset; | ||
205 | unsigned long flags; | ||
206 | int ret = 0; | ||
207 | |||
208 | if (offset >= chip->ngpio) | ||
209 | return -EINVAL; | ||
210 | |||
211 | ret = pinctrl_request_gpio(gpio); | ||
212 | if (ret) | ||
213 | return ret; | ||
214 | |||
215 | if (!IS_ERR(plgpio->clk)) { | ||
216 | ret = clk_enable(plgpio->clk); | ||
217 | if (ret) | ||
218 | goto err0; | ||
219 | } | ||
220 | |||
221 | if (plgpio->regs.enb == -1) | ||
222 | return 0; | ||
223 | |||
224 | /* | ||
225 | * put gpio in IN mode before enabling it. This make enabling gpio safe | ||
226 | */ | ||
227 | ret = plgpio_direction_input(chip, offset); | ||
228 | if (ret) | ||
229 | goto err1; | ||
230 | |||
231 | /* get correct offset for "offset" pin */ | ||
232 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { | ||
233 | offset = plgpio->p2o(offset); | ||
234 | if (offset == -1) { | ||
235 | ret = -EINVAL; | ||
236 | goto err1; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | spin_lock_irqsave(&plgpio->lock, flags); | ||
241 | plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb); | ||
242 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
243 | return 0; | ||
244 | |||
245 | err1: | ||
246 | if (!IS_ERR(plgpio->clk)) | ||
247 | clk_disable(plgpio->clk); | ||
248 | err0: | ||
249 | pinctrl_free_gpio(gpio); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | static void plgpio_free(struct gpio_chip *chip, unsigned offset) | ||
254 | { | ||
255 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
256 | int gpio = chip->base + offset; | ||
257 | unsigned long flags; | ||
258 | |||
259 | if (offset >= chip->ngpio) | ||
260 | return; | ||
261 | |||
262 | if (plgpio->regs.enb == -1) | ||
263 | goto disable_clk; | ||
264 | |||
265 | /* get correct offset for "offset" pin */ | ||
266 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { | ||
267 | offset = plgpio->p2o(offset); | ||
268 | if (offset == -1) | ||
269 | return; | ||
270 | } | ||
271 | |||
272 | spin_lock_irqsave(&plgpio->lock, flags); | ||
273 | plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb); | ||
274 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
275 | |||
276 | disable_clk: | ||
277 | if (!IS_ERR(plgpio->clk)) | ||
278 | clk_disable(plgpio->clk); | ||
279 | |||
280 | pinctrl_free_gpio(gpio); | ||
281 | } | ||
282 | |||
283 | static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
284 | { | ||
285 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
286 | |||
287 | if (IS_ERR_VALUE(plgpio->irq_base)) | ||
288 | return -EINVAL; | ||
289 | |||
290 | return irq_find_mapping(plgpio->irq_domain, offset); | ||
291 | } | ||
292 | |||
293 | /* PLGPIO IRQ */ | ||
294 | static void plgpio_irq_disable(struct irq_data *d) | ||
295 | { | ||
296 | struct plgpio *plgpio = irq_data_get_irq_chip_data(d); | ||
297 | int offset = d->irq - plgpio->irq_base; | ||
298 | unsigned long flags; | ||
299 | |||
300 | /* get correct offset for "offset" pin */ | ||
301 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { | ||
302 | offset = plgpio->p2o(offset); | ||
303 | if (offset == -1) | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | spin_lock_irqsave(&plgpio->lock, flags); | ||
308 | plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie); | ||
309 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
310 | } | ||
311 | |||
312 | static void plgpio_irq_enable(struct irq_data *d) | ||
313 | { | ||
314 | struct plgpio *plgpio = irq_data_get_irq_chip_data(d); | ||
315 | int offset = d->irq - plgpio->irq_base; | ||
316 | unsigned long flags; | ||
317 | |||
318 | /* get correct offset for "offset" pin */ | ||
319 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { | ||
320 | offset = plgpio->p2o(offset); | ||
321 | if (offset == -1) | ||
322 | return; | ||
323 | } | ||
324 | |||
325 | spin_lock_irqsave(&plgpio->lock, flags); | ||
326 | plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie); | ||
327 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
328 | } | ||
329 | |||
330 | static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger) | ||
331 | { | ||
332 | struct plgpio *plgpio = irq_data_get_irq_chip_data(d); | ||
333 | int offset = d->irq - plgpio->irq_base; | ||
334 | void __iomem *reg_off; | ||
335 | unsigned int supported_type = 0, val; | ||
336 | |||
337 | if (offset >= plgpio->chip.ngpio) | ||
338 | return -EINVAL; | ||
339 | |||
340 | if (plgpio->regs.eit == -1) | ||
341 | supported_type = IRQ_TYPE_LEVEL_HIGH; | ||
342 | else | ||
343 | supported_type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | ||
344 | |||
345 | if (!(trigger & supported_type)) | ||
346 | return -EINVAL; | ||
347 | |||
348 | if (plgpio->regs.eit == -1) | ||
349 | return 0; | ||
350 | |||
351 | reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset); | ||
352 | val = readl_relaxed(reg_off); | ||
353 | |||
354 | offset = PIN_OFFSET(offset); | ||
355 | if (trigger & IRQ_TYPE_EDGE_RISING) | ||
356 | writel_relaxed(val | (1 << offset), reg_off); | ||
357 | else | ||
358 | writel_relaxed(val & ~(1 << offset), reg_off); | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static struct irq_chip plgpio_irqchip = { | ||
364 | .name = "PLGPIO", | ||
365 | .irq_enable = plgpio_irq_enable, | ||
366 | .irq_disable = plgpio_irq_disable, | ||
367 | .irq_set_type = plgpio_irq_set_type, | ||
368 | }; | ||
369 | |||
370 | static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
371 | { | ||
372 | struct plgpio *plgpio = irq_get_handler_data(irq); | ||
373 | struct irq_chip *irqchip = irq_desc_get_chip(desc); | ||
374 | int regs_count, count, pin, offset, i = 0; | ||
375 | unsigned long pending; | ||
376 | |||
377 | count = plgpio->chip.ngpio; | ||
378 | regs_count = DIV_ROUND_UP(count, MAX_GPIO_PER_REG); | ||
379 | |||
380 | chained_irq_enter(irqchip, desc); | ||
381 | /* check all plgpio MIS registers for a possible interrupt */ | ||
382 | for (; i < regs_count; i++) { | ||
383 | pending = readl_relaxed(plgpio->base + plgpio->regs.mis + | ||
384 | i * sizeof(int *)); | ||
385 | if (!pending) | ||
386 | continue; | ||
387 | |||
388 | /* clear interrupts */ | ||
389 | writel_relaxed(~pending, plgpio->base + plgpio->regs.mis + | ||
390 | i * sizeof(int *)); | ||
391 | /* | ||
392 | * clear extra bits in last register having gpios < MAX/REG | ||
393 | * ex: Suppose there are max 102 plgpios. then last register | ||
394 | * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits | ||
395 | * so, we must not take other 28 bits into consideration for | ||
396 | * checking interrupt. so clear those bits. | ||
397 | */ | ||
398 | count = count - i * MAX_GPIO_PER_REG; | ||
399 | if (count < MAX_GPIO_PER_REG) | ||
400 | pending &= (1 << count) - 1; | ||
401 | |||
402 | for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) { | ||
403 | /* get correct pin for "offset" */ | ||
404 | if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) { | ||
405 | pin = plgpio->o2p(offset); | ||
406 | if (pin == -1) | ||
407 | continue; | ||
408 | } else | ||
409 | pin = offset; | ||
410 | |||
411 | /* get correct irq line number */ | ||
412 | pin = i * MAX_GPIO_PER_REG + pin; | ||
413 | generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin)); | ||
414 | } | ||
415 | } | ||
416 | chained_irq_exit(irqchip, desc); | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * pin to offset and offset to pin converter functions | ||
421 | * | ||
422 | * In spear310 there is inconsistency among bit positions in plgpio regiseters, | ||
423 | * for different plgpio pins. For example: for pin 27, bit offset is 23, pin | ||
424 | * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1 | ||
425 | */ | ||
426 | static int spear310_p2o(int pin) | ||
427 | { | ||
428 | int offset = pin; | ||
429 | |||
430 | if (pin <= 27) | ||
431 | offset += 4; | ||
432 | else if (pin <= 33) | ||
433 | offset = -1; | ||
434 | else if (pin <= 97) | ||
435 | offset -= 2; | ||
436 | else if (pin <= 101) | ||
437 | offset = 101 - pin; | ||
438 | else | ||
439 | offset = -1; | ||
440 | |||
441 | return offset; | ||
442 | } | ||
443 | |||
444 | int spear310_o2p(int offset) | ||
445 | { | ||
446 | if (offset <= 3) | ||
447 | return 101 - offset; | ||
448 | else if (offset <= 31) | ||
449 | return offset - 4; | ||
450 | else | ||
451 | return offset + 2; | ||
452 | } | ||
453 | |||
454 | static int __devinit plgpio_probe_dt(struct platform_device *pdev, | ||
455 | struct plgpio *plgpio) | ||
456 | { | ||
457 | struct device_node *np = pdev->dev.of_node; | ||
458 | int ret = -EINVAL; | ||
459 | u32 val; | ||
460 | |||
461 | if (of_machine_is_compatible("st,spear310")) { | ||
462 | plgpio->p2o = spear310_p2o; | ||
463 | plgpio->o2p = spear310_o2p; | ||
464 | plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG | | ||
465 | PTO_RDATA_REG | PTO_MIS_REG; | ||
466 | } | ||
467 | |||
468 | if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) { | ||
469 | plgpio->chip.ngpio = val; | ||
470 | } else { | ||
471 | dev_err(&pdev->dev, "DT: Invalid ngpio field\n"); | ||
472 | goto end; | ||
473 | } | ||
474 | |||
475 | if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val)) | ||
476 | plgpio->regs.enb = val; | ||
477 | else | ||
478 | plgpio->regs.enb = -1; | ||
479 | |||
480 | if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) { | ||
481 | plgpio->regs.wdata = val; | ||
482 | } else { | ||
483 | dev_err(&pdev->dev, "DT: Invalid wdata reg\n"); | ||
484 | goto end; | ||
485 | } | ||
486 | |||
487 | if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) { | ||
488 | plgpio->regs.dir = val; | ||
489 | } else { | ||
490 | dev_err(&pdev->dev, "DT: Invalid dir reg\n"); | ||
491 | goto end; | ||
492 | } | ||
493 | |||
494 | if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) { | ||
495 | plgpio->regs.ie = val; | ||
496 | } else { | ||
497 | dev_err(&pdev->dev, "DT: Invalid ie reg\n"); | ||
498 | goto end; | ||
499 | } | ||
500 | |||
501 | if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) { | ||
502 | plgpio->regs.rdata = val; | ||
503 | } else { | ||
504 | dev_err(&pdev->dev, "DT: Invalid rdata reg\n"); | ||
505 | goto end; | ||
506 | } | ||
507 | |||
508 | if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) { | ||
509 | plgpio->regs.mis = val; | ||
510 | } else { | ||
511 | dev_err(&pdev->dev, "DT: Invalid mis reg\n"); | ||
512 | goto end; | ||
513 | } | ||
514 | |||
515 | if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val)) | ||
516 | plgpio->regs.eit = val; | ||
517 | else | ||
518 | plgpio->regs.eit = -1; | ||
519 | |||
520 | return 0; | ||
521 | |||
522 | end: | ||
523 | return ret; | ||
524 | } | ||
525 | static int __devinit plgpio_probe(struct platform_device *pdev) | ||
526 | { | ||
527 | struct device_node *np = pdev->dev.of_node; | ||
528 | struct plgpio *plgpio; | ||
529 | struct resource *res; | ||
530 | int ret, irq, i; | ||
531 | |||
532 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
533 | if (!res) { | ||
534 | dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); | ||
535 | return -EBUSY; | ||
536 | } | ||
537 | |||
538 | plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL); | ||
539 | if (!plgpio) { | ||
540 | dev_err(&pdev->dev, "memory allocation fail\n"); | ||
541 | return -ENOMEM; | ||
542 | } | ||
543 | |||
544 | plgpio->base = devm_request_and_ioremap(&pdev->dev, res); | ||
545 | if (!plgpio->base) { | ||
546 | dev_err(&pdev->dev, "request and ioremap fail\n"); | ||
547 | return -ENOMEM; | ||
548 | } | ||
549 | |||
550 | ret = plgpio_probe_dt(pdev, plgpio); | ||
551 | if (ret) { | ||
552 | dev_err(&pdev->dev, "DT probe failed\n"); | ||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | plgpio->clk = devm_clk_get(&pdev->dev, NULL); | ||
557 | if (IS_ERR(plgpio->clk)) | ||
558 | dev_warn(&pdev->dev, "clk_get() failed, work without it\n"); | ||
559 | |||
560 | #ifdef CONFIG_PM | ||
561 | plgpio->csave_regs = devm_kzalloc(&pdev->dev, | ||
562 | sizeof(*plgpio->csave_regs) * | ||
563 | DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG), | ||
564 | GFP_KERNEL); | ||
565 | if (!plgpio->csave_regs) { | ||
566 | dev_err(&pdev->dev, "csave registers memory allocation fail\n"); | ||
567 | return -ENOMEM; | ||
568 | } | ||
569 | #endif | ||
570 | |||
571 | platform_set_drvdata(pdev, plgpio); | ||
572 | spin_lock_init(&plgpio->lock); | ||
573 | |||
574 | plgpio->irq_base = -1; | ||
575 | plgpio->chip.base = -1; | ||
576 | plgpio->chip.request = plgpio_request; | ||
577 | plgpio->chip.free = plgpio_free; | ||
578 | plgpio->chip.direction_input = plgpio_direction_input; | ||
579 | plgpio->chip.direction_output = plgpio_direction_output; | ||
580 | plgpio->chip.get = plgpio_get_value; | ||
581 | plgpio->chip.set = plgpio_set_value; | ||
582 | plgpio->chip.to_irq = plgpio_to_irq; | ||
583 | plgpio->chip.label = dev_name(&pdev->dev); | ||
584 | plgpio->chip.dev = &pdev->dev; | ||
585 | plgpio->chip.owner = THIS_MODULE; | ||
586 | |||
587 | if (!IS_ERR(plgpio->clk)) { | ||
588 | ret = clk_prepare(plgpio->clk); | ||
589 | if (ret) { | ||
590 | dev_err(&pdev->dev, "clk prepare failed\n"); | ||
591 | return ret; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | ret = gpiochip_add(&plgpio->chip); | ||
596 | if (ret) { | ||
597 | dev_err(&pdev->dev, "unable to add gpio chip\n"); | ||
598 | goto unprepare_clk; | ||
599 | } | ||
600 | |||
601 | irq = platform_get_irq(pdev, 0); | ||
602 | if (irq < 0) { | ||
603 | dev_info(&pdev->dev, "irqs not supported\n"); | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0); | ||
608 | if (IS_ERR_VALUE(plgpio->irq_base)) { | ||
609 | /* we would not support irq for gpio */ | ||
610 | dev_warn(&pdev->dev, "couldn't allocate irq base\n"); | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio, | ||
615 | plgpio->irq_base, 0, &irq_domain_simple_ops, NULL); | ||
616 | if (WARN_ON(!plgpio->irq_domain)) { | ||
617 | dev_err(&pdev->dev, "irq domain init failed\n"); | ||
618 | irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio); | ||
619 | ret = -ENXIO; | ||
620 | goto remove_gpiochip; | ||
621 | } | ||
622 | |||
623 | irq_set_chained_handler(irq, plgpio_irq_handler); | ||
624 | for (i = 0; i < plgpio->chip.ngpio; i++) { | ||
625 | irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip, | ||
626 | handle_simple_irq); | ||
627 | set_irq_flags(i + plgpio->irq_base, IRQF_VALID); | ||
628 | irq_set_chip_data(i + plgpio->irq_base, plgpio); | ||
629 | } | ||
630 | |||
631 | irq_set_handler_data(irq, plgpio); | ||
632 | dev_info(&pdev->dev, "PLGPIO registered with IRQs\n"); | ||
633 | |||
634 | return 0; | ||
635 | |||
636 | remove_gpiochip: | ||
637 | dev_info(&pdev->dev, "Remove gpiochip\n"); | ||
638 | if (gpiochip_remove(&plgpio->chip)) | ||
639 | dev_err(&pdev->dev, "unable to remove gpiochip\n"); | ||
640 | unprepare_clk: | ||
641 | if (!IS_ERR(plgpio->clk)) | ||
642 | clk_unprepare(plgpio->clk); | ||
643 | |||
644 | return ret; | ||
645 | } | ||
646 | |||
647 | #ifdef CONFIG_PM | ||
648 | static int plgpio_suspend(struct device *dev) | ||
649 | { | ||
650 | struct plgpio *plgpio = dev_get_drvdata(dev); | ||
651 | int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); | ||
652 | void __iomem *off; | ||
653 | |||
654 | for (i = 0; i < reg_count; i++) { | ||
655 | off = plgpio->base + i * sizeof(int *); | ||
656 | |||
657 | if (plgpio->regs.enb != -1) | ||
658 | plgpio->csave_regs[i].enb = | ||
659 | readl_relaxed(plgpio->regs.enb + off); | ||
660 | if (plgpio->regs.eit != -1) | ||
661 | plgpio->csave_regs[i].eit = | ||
662 | readl_relaxed(plgpio->regs.eit + off); | ||
663 | plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata + | ||
664 | off); | ||
665 | plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir + | ||
666 | off); | ||
667 | plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off); | ||
668 | } | ||
669 | |||
670 | return 0; | ||
671 | } | ||
672 | |||
673 | /* | ||
674 | * This is used to correct the values in end registers. End registers contain | ||
675 | * extra bits that might be used for other purpose in platform. So, we shouldn't | ||
676 | * overwrite these bits. This macro, reads given register again, preserves other | ||
677 | * bit values (non-plgpio bits), and retain captured value (plgpio bits). | ||
678 | */ | ||
679 | #define plgpio_prepare_reg(__reg, _off, _mask, _tmp) \ | ||
680 | { \ | ||
681 | _tmp = readl_relaxed(plgpio->regs.__reg + _off); \ | ||
682 | _tmp &= ~_mask; \ | ||
683 | plgpio->csave_regs[i].__reg = \ | ||
684 | _tmp | (plgpio->csave_regs[i].__reg & _mask); \ | ||
685 | } | ||
686 | |||
687 | static int plgpio_resume(struct device *dev) | ||
688 | { | ||
689 | struct plgpio *plgpio = dev_get_drvdata(dev); | ||
690 | int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); | ||
691 | void __iomem *off; | ||
692 | u32 mask, tmp; | ||
693 | |||
694 | for (i = 0; i < reg_count; i++) { | ||
695 | off = plgpio->base + i * sizeof(int *); | ||
696 | |||
697 | if (i == reg_count - 1) { | ||
698 | mask = (1 << (plgpio->chip.ngpio - i * | ||
699 | MAX_GPIO_PER_REG)) - 1; | ||
700 | |||
701 | if (plgpio->regs.enb != -1) | ||
702 | plgpio_prepare_reg(enb, off, mask, tmp); | ||
703 | |||
704 | if (plgpio->regs.eit != -1) | ||
705 | plgpio_prepare_reg(eit, off, mask, tmp); | ||
706 | |||
707 | plgpio_prepare_reg(wdata, off, mask, tmp); | ||
708 | plgpio_prepare_reg(dir, off, mask, tmp); | ||
709 | plgpio_prepare_reg(ie, off, mask, tmp); | ||
710 | } | ||
711 | |||
712 | writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata + | ||
713 | off); | ||
714 | writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir + | ||
715 | off); | ||
716 | |||
717 | if (plgpio->regs.eit != -1) | ||
718 | writel_relaxed(plgpio->csave_regs[i].eit, | ||
719 | plgpio->regs.eit + off); | ||
720 | |||
721 | writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off); | ||
722 | |||
723 | if (plgpio->regs.enb != -1) | ||
724 | writel_relaxed(plgpio->csave_regs[i].enb, | ||
725 | plgpio->regs.enb + off); | ||
726 | } | ||
727 | |||
728 | return 0; | ||
729 | } | ||
730 | #endif | ||
731 | |||
732 | static SIMPLE_DEV_PM_OPS(plgpio_dev_pm_ops, plgpio_suspend, plgpio_resume); | ||
733 | |||
734 | static const struct of_device_id plgpio_of_match[] = { | ||
735 | { .compatible = "st,spear-plgpio" }, | ||
736 | {} | ||
737 | }; | ||
738 | MODULE_DEVICE_TABLE(of, plgpio_of_match); | ||
739 | |||
740 | static struct platform_driver plgpio_driver = { | ||
741 | .probe = plgpio_probe, | ||
742 | .driver = { | ||
743 | .owner = THIS_MODULE, | ||
744 | .name = "spear-plgpio", | ||
745 | .pm = &plgpio_dev_pm_ops, | ||
746 | .of_match_table = of_match_ptr(plgpio_of_match), | ||
747 | }, | ||
748 | }; | ||
749 | |||
750 | static int __init plgpio_init(void) | ||
751 | { | ||
752 | return platform_driver_register(&plgpio_driver); | ||
753 | } | ||
754 | subsys_initcall(plgpio_init); | ||
755 | |||
756 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>"); | ||
757 | MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver"); | ||
758 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index b1fd6ee33c6c..922c057521a1 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c | |||
@@ -14,10 +14,10 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/io.h> | ||
18 | #include <linux/module.h> | 17 | #include <linux/module.h> |
19 | #include <linux/of.h> | 18 | #include <linux/of.h> |
20 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_gpio.h> | ||
21 | #include <linux/pinctrl/machine.h> | 21 | #include <linux/pinctrl/machine.h> |
22 | #include <linux/pinctrl/pinctrl.h> | 22 | #include <linux/pinctrl/pinctrl.h> |
23 | #include <linux/pinctrl/pinmux.h> | 23 | #include <linux/pinctrl/pinmux.h> |
@@ -28,14 +28,26 @@ | |||
28 | 28 | ||
29 | #define DRIVER_NAME "spear-pinmux" | 29 | #define DRIVER_NAME "spear-pinmux" |
30 | 30 | ||
31 | static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg) | 31 | static void muxregs_endisable(struct spear_pmx *pmx, |
32 | struct spear_muxreg *muxregs, u8 count, bool enable) | ||
32 | { | 33 | { |
33 | return readl_relaxed(pmx->vbase + reg); | 34 | struct spear_muxreg *muxreg; |
34 | } | 35 | u32 val, temp, j; |
35 | 36 | ||
36 | static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg) | 37 | for (j = 0; j < count; j++) { |
37 | { | 38 | muxreg = &muxregs[j]; |
38 | writel_relaxed(val, pmx->vbase + reg); | 39 | |
40 | val = pmx_readl(pmx, muxreg->reg); | ||
41 | val &= ~muxreg->mask; | ||
42 | |||
43 | if (enable) | ||
44 | temp = muxreg->val; | ||
45 | else | ||
46 | temp = ~muxreg->val; | ||
47 | |||
48 | val |= muxreg->mask & temp; | ||
49 | pmx_writel(pmx, val, muxreg->reg); | ||
50 | } | ||
39 | } | 51 | } |
40 | 52 | ||
41 | static int set_mode(struct spear_pmx *pmx, int mode) | 53 | static int set_mode(struct spear_pmx *pmx, int mode) |
@@ -70,6 +82,17 @@ static int set_mode(struct spear_pmx *pmx, int mode) | |||
70 | return 0; | 82 | return 0; |
71 | } | 83 | } |
72 | 84 | ||
85 | void __devinit | ||
86 | pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, | ||
87 | unsigned count, u16 reg) | ||
88 | { | ||
89 | int i, j; | ||
90 | |||
91 | for (i = 0; i < count; i++) | ||
92 | for (j = 0; j < gpio_pingroup[i].nmuxregs; j++) | ||
93 | gpio_pingroup[i].muxregs[j].reg = reg; | ||
94 | } | ||
95 | |||
73 | void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg) | 96 | void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg) |
74 | { | 97 | { |
75 | struct spear_pingroup *pgroup; | 98 | struct spear_pingroup *pgroup; |
@@ -121,9 +144,10 @@ static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, | |||
121 | seq_printf(s, " " DRIVER_NAME); | 144 | seq_printf(s, " " DRIVER_NAME); |
122 | } | 145 | } |
123 | 146 | ||
124 | int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, | 147 | static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, |
125 | struct device_node *np_config, | 148 | struct device_node *np_config, |
126 | struct pinctrl_map **map, unsigned *num_maps) | 149 | struct pinctrl_map **map, |
150 | unsigned *num_maps) | ||
127 | { | 151 | { |
128 | struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); | 152 | struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); |
129 | struct device_node *np; | 153 | struct device_node *np; |
@@ -168,8 +192,9 @@ int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
168 | return 0; | 192 | return 0; |
169 | } | 193 | } |
170 | 194 | ||
171 | void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, | 195 | static void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, |
172 | struct pinctrl_map *map, unsigned num_maps) | 196 | struct pinctrl_map *map, |
197 | unsigned num_maps) | ||
173 | { | 198 | { |
174 | kfree(map); | 199 | kfree(map); |
175 | } | 200 | } |
@@ -216,9 +241,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, | |||
216 | struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); | 241 | struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); |
217 | const struct spear_pingroup *pgroup; | 242 | const struct spear_pingroup *pgroup; |
218 | const struct spear_modemux *modemux; | 243 | const struct spear_modemux *modemux; |
219 | struct spear_muxreg *muxreg; | 244 | int i; |
220 | u32 val, temp; | ||
221 | int i, j; | ||
222 | bool found = false; | 245 | bool found = false; |
223 | 246 | ||
224 | pgroup = pmx->machdata->groups[group]; | 247 | pgroup = pmx->machdata->groups[group]; |
@@ -233,20 +256,8 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, | |||
233 | } | 256 | } |
234 | 257 | ||
235 | found = true; | 258 | found = true; |
236 | for (j = 0; j < modemux->nmuxregs; j++) { | 259 | muxregs_endisable(pmx, modemux->muxregs, modemux->nmuxregs, |
237 | muxreg = &modemux->muxregs[j]; | 260 | enable); |
238 | |||
239 | val = pmx_readl(pmx, muxreg->reg); | ||
240 | val &= ~muxreg->mask; | ||
241 | |||
242 | if (enable) | ||
243 | temp = muxreg->val; | ||
244 | else | ||
245 | temp = ~muxreg->val; | ||
246 | |||
247 | val |= muxreg->mask & temp; | ||
248 | pmx_writel(pmx, val, muxreg->reg); | ||
249 | } | ||
250 | } | 261 | } |
251 | 262 | ||
252 | if (!found) { | 263 | if (!found) { |
@@ -270,12 +281,74 @@ static void spear_pinctrl_disable(struct pinctrl_dev *pctldev, | |||
270 | spear_pinctrl_endisable(pctldev, function, group, false); | 281 | spear_pinctrl_endisable(pctldev, function, group, false); |
271 | } | 282 | } |
272 | 283 | ||
284 | /* gpio with pinmux */ | ||
285 | static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx, | ||
286 | unsigned pin) | ||
287 | { | ||
288 | struct spear_gpio_pingroup *gpio_pingroup; | ||
289 | int i, j; | ||
290 | |||
291 | if (!pmx->machdata->gpio_pingroups) | ||
292 | return NULL; | ||
293 | |||
294 | for (i = 0; i < pmx->machdata->ngpio_pingroups; i++) { | ||
295 | gpio_pingroup = &pmx->machdata->gpio_pingroups[i]; | ||
296 | |||
297 | for (j = 0; j < gpio_pingroup->npins; j++) { | ||
298 | if (gpio_pingroup->pins[j] == pin) | ||
299 | return gpio_pingroup; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | return NULL; | ||
304 | } | ||
305 | |||
306 | static int gpio_request_endisable(struct pinctrl_dev *pctldev, | ||
307 | struct pinctrl_gpio_range *range, unsigned offset, bool enable) | ||
308 | { | ||
309 | struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); | ||
310 | struct spear_pinctrl_machdata *machdata = pmx->machdata; | ||
311 | struct spear_gpio_pingroup *gpio_pingroup; | ||
312 | |||
313 | /* | ||
314 | * Some SoC have configuration options applicable to group of pins, | ||
315 | * rather than a single pin. | ||
316 | */ | ||
317 | gpio_pingroup = get_gpio_pingroup(pmx, offset); | ||
318 | if (gpio_pingroup) | ||
319 | muxregs_endisable(pmx, gpio_pingroup->muxregs, | ||
320 | gpio_pingroup->nmuxregs, enable); | ||
321 | |||
322 | /* | ||
323 | * SoC may need some extra configurations, or configurations for single | ||
324 | * pin | ||
325 | */ | ||
326 | if (machdata->gpio_request_endisable) | ||
327 | machdata->gpio_request_endisable(pmx, offset, enable); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int gpio_request_enable(struct pinctrl_dev *pctldev, | ||
333 | struct pinctrl_gpio_range *range, unsigned offset) | ||
334 | { | ||
335 | return gpio_request_endisable(pctldev, range, offset, true); | ||
336 | } | ||
337 | |||
338 | static void gpio_disable_free(struct pinctrl_dev *pctldev, | ||
339 | struct pinctrl_gpio_range *range, unsigned offset) | ||
340 | { | ||
341 | gpio_request_endisable(pctldev, range, offset, false); | ||
342 | } | ||
343 | |||
273 | static struct pinmux_ops spear_pinmux_ops = { | 344 | static struct pinmux_ops spear_pinmux_ops = { |
274 | .get_functions_count = spear_pinctrl_get_funcs_count, | 345 | .get_functions_count = spear_pinctrl_get_funcs_count, |
275 | .get_function_name = spear_pinctrl_get_func_name, | 346 | .get_function_name = spear_pinctrl_get_func_name, |
276 | .get_function_groups = spear_pinctrl_get_func_groups, | 347 | .get_function_groups = spear_pinctrl_get_func_groups, |
277 | .enable = spear_pinctrl_enable, | 348 | .enable = spear_pinctrl_enable, |
278 | .disable = spear_pinctrl_disable, | 349 | .disable = spear_pinctrl_disable, |
350 | .gpio_request_enable = gpio_request_enable, | ||
351 | .gpio_disable_free = gpio_disable_free, | ||
279 | }; | 352 | }; |
280 | 353 | ||
281 | static struct pinctrl_desc spear_pinctrl_desc = { | 354 | static struct pinctrl_desc spear_pinctrl_desc = { |
@@ -344,7 +417,7 @@ int __devinit spear_pinctrl_probe(struct platform_device *pdev, | |||
344 | return 0; | 417 | return 0; |
345 | } | 418 | } |
346 | 419 | ||
347 | int __devexit spear_pinctrl_remove(struct platform_device *pdev) | 420 | int spear_pinctrl_remove(struct platform_device *pdev) |
348 | { | 421 | { |
349 | struct spear_pmx *pmx = platform_get_drvdata(pdev); | 422 | struct spear_pmx *pmx = platform_get_drvdata(pdev); |
350 | 423 | ||
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index d950eb78d939..1be46ecc6d91 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h | |||
@@ -12,11 +12,14 @@ | |||
12 | #ifndef __PINMUX_SPEAR_H__ | 12 | #ifndef __PINMUX_SPEAR_H__ |
13 | #define __PINMUX_SPEAR_H__ | 13 | #define __PINMUX_SPEAR_H__ |
14 | 14 | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/io.h> | ||
15 | #include <linux/pinctrl/pinctrl.h> | 17 | #include <linux/pinctrl/pinctrl.h> |
16 | #include <linux/types.h> | 18 | #include <linux/types.h> |
17 | 19 | ||
18 | struct platform_device; | 20 | struct platform_device; |
19 | struct device; | 21 | struct device; |
22 | struct spear_pmx; | ||
20 | 23 | ||
21 | /** | 24 | /** |
22 | * struct spear_pmx_mode - SPEAr pmx mode | 25 | * struct spear_pmx_mode - SPEAr pmx mode |
@@ -46,6 +49,44 @@ struct spear_muxreg { | |||
46 | u32 val; | 49 | u32 val; |
47 | }; | 50 | }; |
48 | 51 | ||
52 | struct spear_gpio_pingroup { | ||
53 | const unsigned *pins; | ||
54 | unsigned npins; | ||
55 | struct spear_muxreg *muxregs; | ||
56 | u8 nmuxregs; | ||
57 | }; | ||
58 | |||
59 | /* ste: set to enable */ | ||
60 | #define DEFINE_MUXREG(__pins, __muxreg, __mask, __ste) \ | ||
61 | static struct spear_muxreg __pins##_muxregs[] = { \ | ||
62 | { \ | ||
63 | .reg = __muxreg, \ | ||
64 | .mask = __mask, \ | ||
65 | .val = __ste ? __mask : 0, \ | ||
66 | }, \ | ||
67 | } | ||
68 | |||
69 | #define DEFINE_2_MUXREG(__pins, __muxreg1, __muxreg2, __mask, __ste1, __ste2) \ | ||
70 | static struct spear_muxreg __pins##_muxregs[] = { \ | ||
71 | { \ | ||
72 | .reg = __muxreg1, \ | ||
73 | .mask = __mask, \ | ||
74 | .val = __ste1 ? __mask : 0, \ | ||
75 | }, { \ | ||
76 | .reg = __muxreg2, \ | ||
77 | .mask = __mask, \ | ||
78 | .val = __ste2 ? __mask : 0, \ | ||
79 | }, \ | ||
80 | } | ||
81 | |||
82 | #define GPIO_PINGROUP(__pins) \ | ||
83 | { \ | ||
84 | .pins = __pins, \ | ||
85 | .npins = ARRAY_SIZE(__pins), \ | ||
86 | .muxregs = __pins##_muxregs, \ | ||
87 | .nmuxregs = ARRAY_SIZE(__pins##_muxregs), \ | ||
88 | } | ||
89 | |||
49 | /** | 90 | /** |
50 | * struct spear_modemux - SPEAr mode mux configuration | 91 | * struct spear_modemux - SPEAr mode mux configuration |
51 | * @modes: mode ids supported by this group of muxregs | 92 | * @modes: mode ids supported by this group of muxregs |
@@ -100,6 +141,8 @@ struct spear_function { | |||
100 | * @nfunctions: The numbmer of entries in @functions. | 141 | * @nfunctions: The numbmer of entries in @functions. |
101 | * @groups: An array describing all pin groups the pin SoC supports. | 142 | * @groups: An array describing all pin groups the pin SoC supports. |
102 | * @ngroups: The numbmer of entries in @groups. | 143 | * @ngroups: The numbmer of entries in @groups. |
144 | * @gpio_pingroups: gpio pingroups | ||
145 | * @ngpio_pingroups: gpio pingroups count | ||
103 | * | 146 | * |
104 | * @modes_supported: Does SoC support modes | 147 | * @modes_supported: Does SoC support modes |
105 | * @mode: mode configured from probe | 148 | * @mode: mode configured from probe |
@@ -113,6 +156,10 @@ struct spear_pinctrl_machdata { | |||
113 | unsigned nfunctions; | 156 | unsigned nfunctions; |
114 | struct spear_pingroup **groups; | 157 | struct spear_pingroup **groups; |
115 | unsigned ngroups; | 158 | unsigned ngroups; |
159 | struct spear_gpio_pingroup *gpio_pingroups; | ||
160 | void (*gpio_request_endisable)(struct spear_pmx *pmx, int offset, | ||
161 | bool enable); | ||
162 | unsigned ngpio_pingroups; | ||
116 | 163 | ||
117 | bool modes_supported; | 164 | bool modes_supported; |
118 | u16 mode; | 165 | u16 mode; |
@@ -135,10 +182,23 @@ struct spear_pmx { | |||
135 | }; | 182 | }; |
136 | 183 | ||
137 | /* exported routines */ | 184 | /* exported routines */ |
185 | static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg) | ||
186 | { | ||
187 | return readl_relaxed(pmx->vbase + reg); | ||
188 | } | ||
189 | |||
190 | static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg) | ||
191 | { | ||
192 | writel_relaxed(val, pmx->vbase + reg); | ||
193 | } | ||
194 | |||
138 | void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg); | 195 | void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg); |
196 | void __devinit | ||
197 | pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, | ||
198 | unsigned count, u16 reg); | ||
139 | int __devinit spear_pinctrl_probe(struct platform_device *pdev, | 199 | int __devinit spear_pinctrl_probe(struct platform_device *pdev, |
140 | struct spear_pinctrl_machdata *machdata); | 200 | struct spear_pinctrl_machdata *machdata); |
141 | int __devexit spear_pinctrl_remove(struct platform_device *pdev); | 201 | int spear_pinctrl_remove(struct platform_device *pdev); |
142 | 202 | ||
143 | #define SPEAR_PIN_0_TO_101 \ | 203 | #define SPEAR_PIN_0_TO_101 \ |
144 | PINCTRL_PIN(0, "PLGPIO0"), \ | 204 | PINCTRL_PIN(0, "PLGPIO0"), \ |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index 0436fc7895d6..e40d785a3fc2 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c | |||
@@ -2418,6 +2418,268 @@ static struct spear_function *spear1310_functions[] = { | |||
2418 | &gpt64_function, | 2418 | &gpt64_function, |
2419 | }; | 2419 | }; |
2420 | 2420 | ||
2421 | static const unsigned pin18[] = { 18, }; | ||
2422 | static const unsigned pin19[] = { 19, }; | ||
2423 | static const unsigned pin20[] = { 20, }; | ||
2424 | static const unsigned pin21[] = { 21, }; | ||
2425 | static const unsigned pin22[] = { 22, }; | ||
2426 | static const unsigned pin23[] = { 23, }; | ||
2427 | static const unsigned pin54[] = { 54, }; | ||
2428 | static const unsigned pin55[] = { 55, }; | ||
2429 | static const unsigned pin56[] = { 56, }; | ||
2430 | static const unsigned pin57[] = { 57, }; | ||
2431 | static const unsigned pin58[] = { 58, }; | ||
2432 | static const unsigned pin59[] = { 59, }; | ||
2433 | static const unsigned pin60[] = { 60, }; | ||
2434 | static const unsigned pin61[] = { 61, }; | ||
2435 | static const unsigned pin62[] = { 62, }; | ||
2436 | static const unsigned pin63[] = { 63, }; | ||
2437 | static const unsigned pin143[] = { 143, }; | ||
2438 | static const unsigned pin144[] = { 144, }; | ||
2439 | static const unsigned pin145[] = { 145, }; | ||
2440 | static const unsigned pin146[] = { 146, }; | ||
2441 | static const unsigned pin147[] = { 147, }; | ||
2442 | static const unsigned pin148[] = { 148, }; | ||
2443 | static const unsigned pin149[] = { 149, }; | ||
2444 | static const unsigned pin150[] = { 150, }; | ||
2445 | static const unsigned pin151[] = { 151, }; | ||
2446 | static const unsigned pin152[] = { 152, }; | ||
2447 | static const unsigned pin205[] = { 205, }; | ||
2448 | static const unsigned pin206[] = { 206, }; | ||
2449 | static const unsigned pin211[] = { 211, }; | ||
2450 | static const unsigned pin212[] = { 212, }; | ||
2451 | static const unsigned pin213[] = { 213, }; | ||
2452 | static const unsigned pin214[] = { 214, }; | ||
2453 | static const unsigned pin215[] = { 215, }; | ||
2454 | static const unsigned pin216[] = { 216, }; | ||
2455 | static const unsigned pin217[] = { 217, }; | ||
2456 | static const unsigned pin218[] = { 218, }; | ||
2457 | static const unsigned pin219[] = { 219, }; | ||
2458 | static const unsigned pin220[] = { 220, }; | ||
2459 | static const unsigned pin221[] = { 221, }; | ||
2460 | static const unsigned pin222[] = { 222, }; | ||
2461 | static const unsigned pin223[] = { 223, }; | ||
2462 | static const unsigned pin224[] = { 224, }; | ||
2463 | static const unsigned pin225[] = { 225, }; | ||
2464 | static const unsigned pin226[] = { 226, }; | ||
2465 | static const unsigned pin227[] = { 227, }; | ||
2466 | static const unsigned pin228[] = { 228, }; | ||
2467 | static const unsigned pin229[] = { 229, }; | ||
2468 | static const unsigned pin230[] = { 230, }; | ||
2469 | static const unsigned pin231[] = { 231, }; | ||
2470 | static const unsigned pin232[] = { 232, }; | ||
2471 | static const unsigned pin233[] = { 233, }; | ||
2472 | static const unsigned pin234[] = { 234, }; | ||
2473 | static const unsigned pin235[] = { 235, }; | ||
2474 | static const unsigned pin236[] = { 236, }; | ||
2475 | static const unsigned pin237[] = { 237, }; | ||
2476 | static const unsigned pin238[] = { 238, }; | ||
2477 | static const unsigned pin239[] = { 239, }; | ||
2478 | static const unsigned pin240[] = { 240, }; | ||
2479 | static const unsigned pin241[] = { 241, }; | ||
2480 | static const unsigned pin242[] = { 242, }; | ||
2481 | static const unsigned pin243[] = { 243, }; | ||
2482 | static const unsigned pin244[] = { 244, }; | ||
2483 | static const unsigned pin245[] = { 245, }; | ||
2484 | |||
2485 | static const unsigned pin_grp0[] = { 173, 174, }; | ||
2486 | static const unsigned pin_grp1[] = { 175, 185, 188, 197, 198, }; | ||
2487 | static const unsigned pin_grp2[] = { 176, 177, 178, 179, 184, 186, 187, 189, | ||
2488 | 190, 191, 192, }; | ||
2489 | static const unsigned pin_grp3[] = { 180, 181, 182, 183, 193, 194, 195, 196, }; | ||
2490 | static const unsigned pin_grp4[] = { 199, 200, }; | ||
2491 | static const unsigned pin_grp5[] = { 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, | ||
2492 | 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, }; | ||
2493 | static const unsigned pin_grp6[] = { 86, 87, 88, 89, 90, 91, 92, 93, }; | ||
2494 | static const unsigned pin_grp7[] = { 98, 99, }; | ||
2495 | static const unsigned pin_grp8[] = { 158, 159, 160, 161, 162, 163, 164, 165, | ||
2496 | 166, 167, 168, 169, 170, 171, 172, }; | ||
2497 | |||
2498 | /* Define muxreg arrays */ | ||
2499 | DEFINE_2_MUXREG(i2c0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2C0_MASK, 0, 1); | ||
2500 | DEFINE_2_MUXREG(ssp0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SSP0_MASK, 0, 1); | ||
2501 | DEFINE_2_MUXREG(ssp0_cs0_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS0_MASK, 0, 1); | ||
2502 | DEFINE_2_MUXREG(ssp0_cs1_2_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS1_2_MASK, 0, 1); | ||
2503 | DEFINE_2_MUXREG(i2s0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2S0_MASK, 0, 1); | ||
2504 | DEFINE_2_MUXREG(i2s1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_I2S1_MASK, 0, 1); | ||
2505 | DEFINE_2_MUXREG(clcd_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_CLCD1_MASK, 0, 1); | ||
2506 | DEFINE_2_MUXREG(clcd_high_res_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_CLCD2_MASK, 0, 1); | ||
2507 | DEFINE_2_MUXREG(pin18, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO15_MASK, 0, 1); | ||
2508 | DEFINE_2_MUXREG(pin19, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO14_MASK, 0, 1); | ||
2509 | DEFINE_2_MUXREG(pin20, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO13_MASK, 0, 1); | ||
2510 | DEFINE_2_MUXREG(pin21, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO12_MASK, 0, 1); | ||
2511 | DEFINE_2_MUXREG(pin22, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO11_MASK, 0, 1); | ||
2512 | DEFINE_2_MUXREG(pin23, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO10_MASK, 0, 1); | ||
2513 | DEFINE_2_MUXREG(pin143, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO00_MASK, 0, 1); | ||
2514 | DEFINE_2_MUXREG(pin144, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO01_MASK, 0, 1); | ||
2515 | DEFINE_2_MUXREG(pin145, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO02_MASK, 0, 1); | ||
2516 | DEFINE_2_MUXREG(pin146, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO03_MASK, 0, 1); | ||
2517 | DEFINE_2_MUXREG(pin147, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO04_MASK, 0, 1); | ||
2518 | DEFINE_2_MUXREG(pin148, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO05_MASK, 0, 1); | ||
2519 | DEFINE_2_MUXREG(pin149, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO06_MASK, 0, 1); | ||
2520 | DEFINE_2_MUXREG(pin150, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO07_MASK, 0, 1); | ||
2521 | DEFINE_2_MUXREG(pin151, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO08_MASK, 0, 1); | ||
2522 | DEFINE_2_MUXREG(pin152, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO09_MASK, 0, 1); | ||
2523 | DEFINE_2_MUXREG(smi_2_chips_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SMI_MASK, 0, 1); | ||
2524 | DEFINE_2_MUXREG(pin54, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS3_MASK, 0, 1); | ||
2525 | DEFINE_2_MUXREG(pin55, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS2_MASK, 0, 1); | ||
2526 | DEFINE_2_MUXREG(pin56, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFRSTPWDWN3_MASK, 0, 1); | ||
2527 | DEFINE_2_MUXREG(pin57, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN2_MASK, 0, 1); | ||
2528 | DEFINE_2_MUXREG(pin58, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN1_MASK, 0, 1); | ||
2529 | DEFINE_2_MUXREG(pin59, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN0_MASK, 0, 1); | ||
2530 | DEFINE_2_MUXREG(pin60, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFWPRT3_MASK, 0, 1); | ||
2531 | DEFINE_2_MUXREG(pin61, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFCE3_MASK, 0, 1); | ||
2532 | DEFINE_2_MUXREG(pin62, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD25_MASK, 0, 1); | ||
2533 | DEFINE_2_MUXREG(pin63, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD24_MASK, 0, 1); | ||
2534 | DEFINE_2_MUXREG(pin_grp0, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICLK_MASK, 0, 1); | ||
2535 | DEFINE_2_MUXREG(pin_grp1, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK, 0, 1); | ||
2536 | DEFINE_2_MUXREG(pin_grp2, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_RXCLK_RDV_TXEN_D03_MASK, 0, 1); | ||
2537 | DEFINE_2_MUXREG(pin_grp3, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIID47_MASK, 0, 1); | ||
2538 | DEFINE_2_MUXREG(pin_grp4, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MDC_MDIO_MASK, 0, 1); | ||
2539 | DEFINE_2_MUXREG(pin_grp5, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD23_MASK, 0, 1); | ||
2540 | DEFINE_2_MUXREG(pin_grp6, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MCI_DATA8_15_MASK, 0, 1); | ||
2541 | DEFINE_2_MUXREG(pin_grp7, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFCE2_MASK, 0, 1); | ||
2542 | DEFINE_2_MUXREG(pin_grp8, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND8_MASK, 0, 1); | ||
2543 | DEFINE_2_MUXREG(nand_16bit_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND16BIT_1_MASK, 0, 1); | ||
2544 | DEFINE_2_MUXREG(pin205, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL1_MASK | PMX_NFCE1_MASK, 0, 1); | ||
2545 | DEFINE_2_MUXREG(pin206, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL0_MASK | PMX_NFCE2_MASK, 0, 1); | ||
2546 | DEFINE_2_MUXREG(pin211, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW1_MASK | PMX_NFWPRT1_MASK, 0, 1); | ||
2547 | DEFINE_2_MUXREG(pin212, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW0_MASK | PMX_NFWPRT2_MASK, 0, 1); | ||
2548 | DEFINE_2_MUXREG(pin213, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA0_MASK, 0, 1); | ||
2549 | DEFINE_2_MUXREG(pin214, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA1_MASK, 0, 1); | ||
2550 | DEFINE_2_MUXREG(pin215, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA2_MASK, 0, 1); | ||
2551 | DEFINE_2_MUXREG(pin216, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA3_MASK, 0, 1); | ||
2552 | DEFINE_2_MUXREG(pin217, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA4_MASK, 0, 1); | ||
2553 | DEFINE_2_MUXREG(pin218, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA5_MASK, 0, 1); | ||
2554 | DEFINE_2_MUXREG(pin219, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA6_MASK, 0, 1); | ||
2555 | DEFINE_2_MUXREG(pin220, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA7_MASK, 0, 1); | ||
2556 | DEFINE_2_MUXREG(pin221, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA1SD_MASK, 0, 1); | ||
2557 | DEFINE_2_MUXREG(pin222, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA2SD_MASK, 0, 1); | ||
2558 | DEFINE_2_MUXREG(pin223, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA3SD_MASK, 0, 1); | ||
2559 | DEFINE_2_MUXREG(pin224, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR0ALE_MASK, 0, 1); | ||
2560 | DEFINE_2_MUXREG(pin225, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR1CLECLK_MASK, 0, 1); | ||
2561 | DEFINE_2_MUXREG(pin226, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR2_MASK, 0, 1); | ||
2562 | DEFINE_2_MUXREG(pin227, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICECF_MASK, 0, 1); | ||
2563 | DEFINE_2_MUXREG(pin228, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICEXD_MASK, 0, 1); | ||
2564 | DEFINE_2_MUXREG(pin229, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICESDMMC_MASK, 0, 1); | ||
2565 | DEFINE_2_MUXREG(pin230, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF1_MASK, 0, 1); | ||
2566 | DEFINE_2_MUXREG(pin231, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF2_MASK, 0, 1); | ||
2567 | DEFINE_2_MUXREG(pin232, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDXD_MASK, 0, 1); | ||
2568 | DEFINE_2_MUXREG(pin233, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDSDMMC_MASK, 0, 1); | ||
2569 | DEFINE_2_MUXREG(pin234, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATADIR_MASK, 0, 1); | ||
2570 | DEFINE_2_MUXREG(pin235, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMARQWP_MASK, 0, 1); | ||
2571 | DEFINE_2_MUXREG(pin236, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDRE_MASK, 0, 1); | ||
2572 | DEFINE_2_MUXREG(pin237, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIOWRWE_MASK, 0, 1); | ||
2573 | DEFINE_2_MUXREG(pin238, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIRESETCF_MASK, 0, 1); | ||
2574 | DEFINE_2_MUXREG(pin239, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS0CE_MASK, 0, 1); | ||
2575 | DEFINE_2_MUXREG(pin240, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICFINTR_MASK, 0, 1); | ||
2576 | DEFINE_2_MUXREG(pin241, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDY_MASK, 0, 1); | ||
2577 | DEFINE_2_MUXREG(pin242, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS1_MASK, 0, 1); | ||
2578 | DEFINE_2_MUXREG(pin243, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMAACK_MASK, 0, 1); | ||
2579 | DEFINE_2_MUXREG(pin244, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCISDCMD_MASK, 0, 1); | ||
2580 | DEFINE_2_MUXREG(pin245, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCILEDS_MASK, 0, 1); | ||
2581 | DEFINE_2_MUXREG(keyboard_rowcol6_8_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROWCOL68_MASK, 0, 1); | ||
2582 | DEFINE_2_MUXREG(uart0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_UART0_MASK, 0, 1); | ||
2583 | DEFINE_2_MUXREG(uart0_modem_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_UART0_MODEM_MASK, 0, 1); | ||
2584 | DEFINE_2_MUXREG(gpt0_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR0_MASK, 0, 1); | ||
2585 | DEFINE_2_MUXREG(gpt0_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR1_MASK, 0, 1); | ||
2586 | DEFINE_2_MUXREG(gpt1_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR0_MASK, 0, 1); | ||
2587 | DEFINE_2_MUXREG(gpt1_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR1_MASK, 0, 1); | ||
2588 | DEFINE_2_MUXREG(touch_xy_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_TOUCH_XY_MASK, 0, 1); | ||
2589 | |||
2590 | static struct spear_gpio_pingroup spear1310_gpio_pingroup[] = { | ||
2591 | GPIO_PINGROUP(i2c0_pins), | ||
2592 | GPIO_PINGROUP(ssp0_pins), | ||
2593 | GPIO_PINGROUP(ssp0_cs0_pins), | ||
2594 | GPIO_PINGROUP(ssp0_cs1_2_pins), | ||
2595 | GPIO_PINGROUP(i2s0_pins), | ||
2596 | GPIO_PINGROUP(i2s1_pins), | ||
2597 | GPIO_PINGROUP(clcd_pins), | ||
2598 | GPIO_PINGROUP(clcd_high_res_pins), | ||
2599 | GPIO_PINGROUP(pin18), | ||
2600 | GPIO_PINGROUP(pin19), | ||
2601 | GPIO_PINGROUP(pin20), | ||
2602 | GPIO_PINGROUP(pin21), | ||
2603 | GPIO_PINGROUP(pin22), | ||
2604 | GPIO_PINGROUP(pin23), | ||
2605 | GPIO_PINGROUP(pin143), | ||
2606 | GPIO_PINGROUP(pin144), | ||
2607 | GPIO_PINGROUP(pin145), | ||
2608 | GPIO_PINGROUP(pin146), | ||
2609 | GPIO_PINGROUP(pin147), | ||
2610 | GPIO_PINGROUP(pin148), | ||
2611 | GPIO_PINGROUP(pin149), | ||
2612 | GPIO_PINGROUP(pin150), | ||
2613 | GPIO_PINGROUP(pin151), | ||
2614 | GPIO_PINGROUP(pin152), | ||
2615 | GPIO_PINGROUP(smi_2_chips_pins), | ||
2616 | GPIO_PINGROUP(pin54), | ||
2617 | GPIO_PINGROUP(pin55), | ||
2618 | GPIO_PINGROUP(pin56), | ||
2619 | GPIO_PINGROUP(pin57), | ||
2620 | GPIO_PINGROUP(pin58), | ||
2621 | GPIO_PINGROUP(pin59), | ||
2622 | GPIO_PINGROUP(pin60), | ||
2623 | GPIO_PINGROUP(pin61), | ||
2624 | GPIO_PINGROUP(pin62), | ||
2625 | GPIO_PINGROUP(pin63), | ||
2626 | GPIO_PINGROUP(pin_grp0), | ||
2627 | GPIO_PINGROUP(pin_grp1), | ||
2628 | GPIO_PINGROUP(pin_grp2), | ||
2629 | GPIO_PINGROUP(pin_grp3), | ||
2630 | GPIO_PINGROUP(pin_grp4), | ||
2631 | GPIO_PINGROUP(pin_grp5), | ||
2632 | GPIO_PINGROUP(pin_grp6), | ||
2633 | GPIO_PINGROUP(pin_grp7), | ||
2634 | GPIO_PINGROUP(pin_grp8), | ||
2635 | GPIO_PINGROUP(nand_16bit_pins), | ||
2636 | GPIO_PINGROUP(pin205), | ||
2637 | GPIO_PINGROUP(pin206), | ||
2638 | GPIO_PINGROUP(pin211), | ||
2639 | GPIO_PINGROUP(pin212), | ||
2640 | GPIO_PINGROUP(pin213), | ||
2641 | GPIO_PINGROUP(pin214), | ||
2642 | GPIO_PINGROUP(pin215), | ||
2643 | GPIO_PINGROUP(pin216), | ||
2644 | GPIO_PINGROUP(pin217), | ||
2645 | GPIO_PINGROUP(pin218), | ||
2646 | GPIO_PINGROUP(pin219), | ||
2647 | GPIO_PINGROUP(pin220), | ||
2648 | GPIO_PINGROUP(pin221), | ||
2649 | GPIO_PINGROUP(pin222), | ||
2650 | GPIO_PINGROUP(pin223), | ||
2651 | GPIO_PINGROUP(pin224), | ||
2652 | GPIO_PINGROUP(pin225), | ||
2653 | GPIO_PINGROUP(pin226), | ||
2654 | GPIO_PINGROUP(pin227), | ||
2655 | GPIO_PINGROUP(pin228), | ||
2656 | GPIO_PINGROUP(pin229), | ||
2657 | GPIO_PINGROUP(pin230), | ||
2658 | GPIO_PINGROUP(pin231), | ||
2659 | GPIO_PINGROUP(pin232), | ||
2660 | GPIO_PINGROUP(pin233), | ||
2661 | GPIO_PINGROUP(pin234), | ||
2662 | GPIO_PINGROUP(pin235), | ||
2663 | GPIO_PINGROUP(pin236), | ||
2664 | GPIO_PINGROUP(pin237), | ||
2665 | GPIO_PINGROUP(pin238), | ||
2666 | GPIO_PINGROUP(pin239), | ||
2667 | GPIO_PINGROUP(pin240), | ||
2668 | GPIO_PINGROUP(pin241), | ||
2669 | GPIO_PINGROUP(pin242), | ||
2670 | GPIO_PINGROUP(pin243), | ||
2671 | GPIO_PINGROUP(pin244), | ||
2672 | GPIO_PINGROUP(pin245), | ||
2673 | GPIO_PINGROUP(keyboard_rowcol6_8_pins), | ||
2674 | GPIO_PINGROUP(uart0_pins), | ||
2675 | GPIO_PINGROUP(uart0_modem_pins), | ||
2676 | GPIO_PINGROUP(gpt0_tmr0_pins), | ||
2677 | GPIO_PINGROUP(gpt0_tmr1_pins), | ||
2678 | GPIO_PINGROUP(gpt1_tmr0_pins), | ||
2679 | GPIO_PINGROUP(gpt1_tmr1_pins), | ||
2680 | GPIO_PINGROUP(touch_xy_pins), | ||
2681 | }; | ||
2682 | |||
2421 | static struct spear_pinctrl_machdata spear1310_machdata = { | 2683 | static struct spear_pinctrl_machdata spear1310_machdata = { |
2422 | .pins = spear1310_pins, | 2684 | .pins = spear1310_pins, |
2423 | .npins = ARRAY_SIZE(spear1310_pins), | 2685 | .npins = ARRAY_SIZE(spear1310_pins), |
@@ -2425,10 +2687,12 @@ static struct spear_pinctrl_machdata spear1310_machdata = { | |||
2425 | .ngroups = ARRAY_SIZE(spear1310_pingroups), | 2687 | .ngroups = ARRAY_SIZE(spear1310_pingroups), |
2426 | .functions = spear1310_functions, | 2688 | .functions = spear1310_functions, |
2427 | .nfunctions = ARRAY_SIZE(spear1310_functions), | 2689 | .nfunctions = ARRAY_SIZE(spear1310_functions), |
2690 | .gpio_pingroups = spear1310_gpio_pingroup, | ||
2691 | .ngpio_pingroups = ARRAY_SIZE(spear1310_gpio_pingroup), | ||
2428 | .modes_supported = false, | 2692 | .modes_supported = false, |
2429 | }; | 2693 | }; |
2430 | 2694 | ||
2431 | static struct of_device_id spear1310_pinctrl_of_match[] __devinitdata = { | 2695 | static struct of_device_id spear1310_pinctrl_of_match[] = { |
2432 | { | 2696 | { |
2433 | .compatible = "st,spear1310-pinmux", | 2697 | .compatible = "st,spear1310-pinmux", |
2434 | }, | 2698 | }, |
@@ -2440,7 +2704,7 @@ static int __devinit spear1310_pinctrl_probe(struct platform_device *pdev) | |||
2440 | return spear_pinctrl_probe(pdev, &spear1310_machdata); | 2704 | return spear_pinctrl_probe(pdev, &spear1310_machdata); |
2441 | } | 2705 | } |
2442 | 2706 | ||
2443 | static int __devexit spear1310_pinctrl_remove(struct platform_device *pdev) | 2707 | static int spear1310_pinctrl_remove(struct platform_device *pdev) |
2444 | { | 2708 | { |
2445 | return spear_pinctrl_remove(pdev); | 2709 | return spear_pinctrl_remove(pdev); |
2446 | } | 2710 | } |
@@ -2452,7 +2716,7 @@ static struct platform_driver spear1310_pinctrl_driver = { | |||
2452 | .of_match_table = spear1310_pinctrl_of_match, | 2716 | .of_match_table = spear1310_pinctrl_of_match, |
2453 | }, | 2717 | }, |
2454 | .probe = spear1310_pinctrl_probe, | 2718 | .probe = spear1310_pinctrl_probe, |
2455 | .remove = __devexit_p(spear1310_pinctrl_remove), | 2719 | .remove = spear1310_pinctrl_remove, |
2456 | }; | 2720 | }; |
2457 | 2721 | ||
2458 | static int __init spear1310_pinctrl_init(void) | 2722 | static int __init spear1310_pinctrl_init(void) |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index 0606b8cf3f2c..8deaaff3156c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c | |||
@@ -1971,6 +1971,32 @@ static struct spear_function *spear1340_functions[] = { | |||
1971 | &sata_function, | 1971 | &sata_function, |
1972 | }; | 1972 | }; |
1973 | 1973 | ||
1974 | static void gpio_request_endisable(struct spear_pmx *pmx, int pin, | ||
1975 | bool enable) | ||
1976 | { | ||
1977 | unsigned int regoffset, regindex, bitoffset; | ||
1978 | unsigned int val; | ||
1979 | |||
1980 | /* pin++ as gpio configuration starts from 2nd bit of base register */ | ||
1981 | pin++; | ||
1982 | |||
1983 | regindex = pin / 32; | ||
1984 | bitoffset = pin % 32; | ||
1985 | |||
1986 | if (regindex <= 3) | ||
1987 | regoffset = PAD_FUNCTION_EN_1 + regindex * sizeof(int *); | ||
1988 | else | ||
1989 | regoffset = PAD_FUNCTION_EN_5 + (regindex - 4) * sizeof(int *); | ||
1990 | |||
1991 | val = pmx_readl(pmx, regoffset); | ||
1992 | if (enable) | ||
1993 | val &= ~(0x1 << bitoffset); | ||
1994 | else | ||
1995 | val |= 0x1 << bitoffset; | ||
1996 | |||
1997 | pmx_writel(pmx, val, regoffset); | ||
1998 | } | ||
1999 | |||
1974 | static struct spear_pinctrl_machdata spear1340_machdata = { | 2000 | static struct spear_pinctrl_machdata spear1340_machdata = { |
1975 | .pins = spear1340_pins, | 2001 | .pins = spear1340_pins, |
1976 | .npins = ARRAY_SIZE(spear1340_pins), | 2002 | .npins = ARRAY_SIZE(spear1340_pins), |
@@ -1978,10 +2004,11 @@ static struct spear_pinctrl_machdata spear1340_machdata = { | |||
1978 | .ngroups = ARRAY_SIZE(spear1340_pingroups), | 2004 | .ngroups = ARRAY_SIZE(spear1340_pingroups), |
1979 | .functions = spear1340_functions, | 2005 | .functions = spear1340_functions, |
1980 | .nfunctions = ARRAY_SIZE(spear1340_functions), | 2006 | .nfunctions = ARRAY_SIZE(spear1340_functions), |
2007 | .gpio_request_endisable = gpio_request_endisable, | ||
1981 | .modes_supported = false, | 2008 | .modes_supported = false, |
1982 | }; | 2009 | }; |
1983 | 2010 | ||
1984 | static struct of_device_id spear1340_pinctrl_of_match[] __devinitdata = { | 2011 | static struct of_device_id spear1340_pinctrl_of_match[] = { |
1985 | { | 2012 | { |
1986 | .compatible = "st,spear1340-pinmux", | 2013 | .compatible = "st,spear1340-pinmux", |
1987 | }, | 2014 | }, |
@@ -1993,7 +2020,7 @@ static int __devinit spear1340_pinctrl_probe(struct platform_device *pdev) | |||
1993 | return spear_pinctrl_probe(pdev, &spear1340_machdata); | 2020 | return spear_pinctrl_probe(pdev, &spear1340_machdata); |
1994 | } | 2021 | } |
1995 | 2022 | ||
1996 | static int __devexit spear1340_pinctrl_remove(struct platform_device *pdev) | 2023 | static int spear1340_pinctrl_remove(struct platform_device *pdev) |
1997 | { | 2024 | { |
1998 | return spear_pinctrl_remove(pdev); | 2025 | return spear_pinctrl_remove(pdev); |
1999 | } | 2026 | } |
@@ -2005,7 +2032,7 @@ static struct platform_driver spear1340_pinctrl_driver = { | |||
2005 | .of_match_table = spear1340_pinctrl_of_match, | 2032 | .of_match_table = spear1340_pinctrl_of_match, |
2006 | }, | 2033 | }, |
2007 | .probe = spear1340_pinctrl_probe, | 2034 | .probe = spear1340_pinctrl_probe, |
2008 | .remove = __devexit_p(spear1340_pinctrl_remove), | 2035 | .remove = spear1340_pinctrl_remove, |
2009 | }; | 2036 | }; |
2010 | 2037 | ||
2011 | static int __init spear1340_pinctrl_init(void) | 2038 | static int __init spear1340_pinctrl_init(void) |
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index 4dfc2849b172..f48e466e605a 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c | |||
@@ -646,7 +646,7 @@ static struct spear_function *spear300_functions[] = { | |||
646 | &gpio1_function, | 646 | &gpio1_function, |
647 | }; | 647 | }; |
648 | 648 | ||
649 | static struct of_device_id spear300_pinctrl_of_match[] __devinitdata = { | 649 | static struct of_device_id spear300_pinctrl_of_match[] = { |
650 | { | 650 | { |
651 | .compatible = "st,spear300-pinmux", | 651 | .compatible = "st,spear300-pinmux", |
652 | }, | 652 | }, |
@@ -661,6 +661,8 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev) | |||
661 | spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups); | 661 | spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups); |
662 | spear3xx_machdata.functions = spear300_functions; | 662 | spear3xx_machdata.functions = spear300_functions; |
663 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions); | 663 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions); |
664 | spear3xx_machdata.gpio_pingroups = NULL; | ||
665 | spear3xx_machdata.ngpio_pingroups = 0; | ||
664 | 666 | ||
665 | spear3xx_machdata.modes_supported = true; | 667 | spear3xx_machdata.modes_supported = true; |
666 | spear3xx_machdata.pmx_modes = spear300_pmx_modes; | 668 | spear3xx_machdata.pmx_modes = spear300_pmx_modes; |
@@ -675,7 +677,7 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev) | |||
675 | return 0; | 677 | return 0; |
676 | } | 678 | } |
677 | 679 | ||
678 | static int __devexit spear300_pinctrl_remove(struct platform_device *pdev) | 680 | static int spear300_pinctrl_remove(struct platform_device *pdev) |
679 | { | 681 | { |
680 | return spear_pinctrl_remove(pdev); | 682 | return spear_pinctrl_remove(pdev); |
681 | } | 683 | } |
@@ -687,7 +689,7 @@ static struct platform_driver spear300_pinctrl_driver = { | |||
687 | .of_match_table = spear300_pinctrl_of_match, | 689 | .of_match_table = spear300_pinctrl_of_match, |
688 | }, | 690 | }, |
689 | .probe = spear300_pinctrl_probe, | 691 | .probe = spear300_pinctrl_probe, |
690 | .remove = __devexit_p(spear300_pinctrl_remove), | 692 | .remove = spear300_pinctrl_remove, |
691 | }; | 693 | }; |
692 | 694 | ||
693 | static int __init spear300_pinctrl_init(void) | 695 | static int __init spear300_pinctrl_init(void) |
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index 96883693fb7e..5b954c19a6d2 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c | |||
@@ -371,7 +371,7 @@ static struct spear_function *spear310_functions[] = { | |||
371 | &tdm_function, | 371 | &tdm_function, |
372 | }; | 372 | }; |
373 | 373 | ||
374 | static struct of_device_id spear310_pinctrl_of_match[] __devinitdata = { | 374 | static struct of_device_id spear310_pinctrl_of_match[] = { |
375 | { | 375 | { |
376 | .compatible = "st,spear310-pinmux", | 376 | .compatible = "st,spear310-pinmux", |
377 | }, | 377 | }, |
@@ -388,6 +388,8 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev) | |||
388 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions); | 388 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions); |
389 | 389 | ||
390 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); | 390 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); |
391 | pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, | ||
392 | spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); | ||
391 | 393 | ||
392 | spear3xx_machdata.modes_supported = false; | 394 | spear3xx_machdata.modes_supported = false; |
393 | 395 | ||
@@ -398,7 +400,7 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev) | |||
398 | return 0; | 400 | return 0; |
399 | } | 401 | } |
400 | 402 | ||
401 | static int __devexit spear310_pinctrl_remove(struct platform_device *pdev) | 403 | static int spear310_pinctrl_remove(struct platform_device *pdev) |
402 | { | 404 | { |
403 | return spear_pinctrl_remove(pdev); | 405 | return spear_pinctrl_remove(pdev); |
404 | } | 406 | } |
@@ -410,7 +412,7 @@ static struct platform_driver spear310_pinctrl_driver = { | |||
410 | .of_match_table = spear310_pinctrl_of_match, | 412 | .of_match_table = spear310_pinctrl_of_match, |
411 | }, | 413 | }, |
412 | .probe = spear310_pinctrl_probe, | 414 | .probe = spear310_pinctrl_probe, |
413 | .remove = __devexit_p(spear310_pinctrl_remove), | 415 | .remove = spear310_pinctrl_remove, |
414 | }; | 416 | }; |
415 | 417 | ||
416 | static int __init spear310_pinctrl_init(void) | 418 | static int __init spear310_pinctrl_init(void) |
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index ca47b0e50780..e9a5e6d39242 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c | |||
@@ -3410,7 +3410,7 @@ static struct spear_function *spear320_functions[] = { | |||
3410 | &i2c2_function, | 3410 | &i2c2_function, |
3411 | }; | 3411 | }; |
3412 | 3412 | ||
3413 | static struct of_device_id spear320_pinctrl_of_match[] __devinitdata = { | 3413 | static struct of_device_id spear320_pinctrl_of_match[] = { |
3414 | { | 3414 | { |
3415 | .compatible = "st,spear320-pinmux", | 3415 | .compatible = "st,spear320-pinmux", |
3416 | }, | 3416 | }, |
@@ -3431,6 +3431,8 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev) | |||
3431 | spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes); | 3431 | spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes); |
3432 | 3432 | ||
3433 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); | 3433 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); |
3434 | pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, | ||
3435 | spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); | ||
3434 | 3436 | ||
3435 | ret = spear_pinctrl_probe(pdev, &spear3xx_machdata); | 3437 | ret = spear_pinctrl_probe(pdev, &spear3xx_machdata); |
3436 | if (ret) | 3438 | if (ret) |
@@ -3439,7 +3441,7 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev) | |||
3439 | return 0; | 3441 | return 0; |
3440 | } | 3442 | } |
3441 | 3443 | ||
3442 | static int __devexit spear320_pinctrl_remove(struct platform_device *pdev) | 3444 | static int spear320_pinctrl_remove(struct platform_device *pdev) |
3443 | { | 3445 | { |
3444 | return spear_pinctrl_remove(pdev); | 3446 | return spear_pinctrl_remove(pdev); |
3445 | } | 3447 | } |
@@ -3451,7 +3453,7 @@ static struct platform_driver spear320_pinctrl_driver = { | |||
3451 | .of_match_table = spear320_pinctrl_of_match, | 3453 | .of_match_table = spear320_pinctrl_of_match, |
3452 | }, | 3454 | }, |
3453 | .probe = spear320_pinctrl_probe, | 3455 | .probe = spear320_pinctrl_probe, |
3454 | .remove = __devexit_p(spear320_pinctrl_remove), | 3456 | .remove = spear320_pinctrl_remove, |
3455 | }; | 3457 | }; |
3456 | 3458 | ||
3457 | static int __init spear320_pinctrl_init(void) | 3459 | static int __init spear320_pinctrl_init(void) |
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c index 0242378f7cb8..12ee21af766b 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c | |||
@@ -481,7 +481,44 @@ struct spear_function spear3xx_timer_2_3_function = { | |||
481 | .ngroups = ARRAY_SIZE(timer_2_3_grps), | 481 | .ngroups = ARRAY_SIZE(timer_2_3_grps), |
482 | }; | 482 | }; |
483 | 483 | ||
484 | /* Define muxreg arrays */ | ||
485 | DEFINE_MUXREG(firda_pins, 0, PMX_FIRDA_MASK, 0); | ||
486 | DEFINE_MUXREG(i2c_pins, 0, PMX_I2C_MASK, 0); | ||
487 | DEFINE_MUXREG(ssp_cs_pins, 0, PMX_SSP_CS_MASK, 0); | ||
488 | DEFINE_MUXREG(ssp_pins, 0, PMX_SSP_MASK, 0); | ||
489 | DEFINE_MUXREG(mii_pins, 0, PMX_MII_MASK, 0); | ||
490 | DEFINE_MUXREG(gpio0_pin0_pins, 0, PMX_GPIO_PIN0_MASK, 0); | ||
491 | DEFINE_MUXREG(gpio0_pin1_pins, 0, PMX_GPIO_PIN1_MASK, 0); | ||
492 | DEFINE_MUXREG(gpio0_pin2_pins, 0, PMX_GPIO_PIN2_MASK, 0); | ||
493 | DEFINE_MUXREG(gpio0_pin3_pins, 0, PMX_GPIO_PIN3_MASK, 0); | ||
494 | DEFINE_MUXREG(gpio0_pin4_pins, 0, PMX_GPIO_PIN4_MASK, 0); | ||
495 | DEFINE_MUXREG(gpio0_pin5_pins, 0, PMX_GPIO_PIN5_MASK, 0); | ||
496 | DEFINE_MUXREG(uart0_ext_pins, 0, PMX_UART0_MODEM_MASK, 0); | ||
497 | DEFINE_MUXREG(uart0_pins, 0, PMX_UART0_MASK, 0); | ||
498 | DEFINE_MUXREG(timer_0_1_pins, 0, PMX_TIMER_0_1_MASK, 0); | ||
499 | DEFINE_MUXREG(timer_2_3_pins, 0, PMX_TIMER_2_3_MASK, 0); | ||
500 | |||
501 | static struct spear_gpio_pingroup spear3xx_gpio_pingroup[] = { | ||
502 | GPIO_PINGROUP(firda_pins), | ||
503 | GPIO_PINGROUP(i2c_pins), | ||
504 | GPIO_PINGROUP(ssp_cs_pins), | ||
505 | GPIO_PINGROUP(ssp_pins), | ||
506 | GPIO_PINGROUP(mii_pins), | ||
507 | GPIO_PINGROUP(gpio0_pin0_pins), | ||
508 | GPIO_PINGROUP(gpio0_pin1_pins), | ||
509 | GPIO_PINGROUP(gpio0_pin2_pins), | ||
510 | GPIO_PINGROUP(gpio0_pin3_pins), | ||
511 | GPIO_PINGROUP(gpio0_pin4_pins), | ||
512 | GPIO_PINGROUP(gpio0_pin5_pins), | ||
513 | GPIO_PINGROUP(uart0_ext_pins), | ||
514 | GPIO_PINGROUP(uart0_pins), | ||
515 | GPIO_PINGROUP(timer_0_1_pins), | ||
516 | GPIO_PINGROUP(timer_2_3_pins), | ||
517 | }; | ||
518 | |||
484 | struct spear_pinctrl_machdata spear3xx_machdata = { | 519 | struct spear_pinctrl_machdata spear3xx_machdata = { |
485 | .pins = spear3xx_pins, | 520 | .pins = spear3xx_pins, |
486 | .npins = ARRAY_SIZE(spear3xx_pins), | 521 | .npins = ARRAY_SIZE(spear3xx_pins), |
522 | .gpio_pingroups = spear3xx_gpio_pingroup, | ||
523 | .ngpio_pingroups = ARRAY_SIZE(spear3xx_gpio_pingroup), | ||
487 | }; | 524 | }; |