diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 13:43:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 13:43:14 -0500 |
commit | c1b30e4d9466000c0e287e9245d4397da4d7d2f9 (patch) | |
tree | 18ac4c6bb435202cee8e7281f58b0c72f7fa0144 /drivers/pinctrl | |
parent | 92a578b064d0227a3a7fbbdb9e29dbab7f8d400e (diff) | |
parent | 853b6bf044dcced57c523dbddabf8942e907be6e (diff) |
Merge tag 'pinctrl-v3.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control changes from Linus Walleij:
"Here is a stash of pin control changes I have collected for the v3.19
series. Mainly new hardware support, with Intels new embedded SoC as
the especially interesting thing standing out, fully using the
subsystem.
- Force conversion of the ux500 pin control device trees and parsers
to use the generic pin control bindings.
- New driver and device tree bindings for the Qualcomm PMIC MPP pin
controller and GPIO.
- Some ACPI infrastructure for pin controllers.
- New driver for the Intel CherryView/Braswell pin controller, the
first Intel pin controller to fully take advantage of the pin
control subsystem.
- Support the Freescale i.MX VF610 variant.
- Support the sunxi A80 variant.
- Support the Samsung Exynos 4415 and Exynos 7 variants.
- Split out Intel pin controllers to their own subdirectory.
- A large slew of rockchip pin control updates, including
suspend/resume support.
- A large slew of Samsung Exynos pin controller updates.
- Various minor updates and fixes"
* tag 'pinctrl-v3.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (49 commits)
pinctrl: at91: enhance (debugfs) at91_gpio_dbg_show
pinctrl: meson: add device tree bindings documentation
gpio: tz1090: Fix error handling of irq_of_parse_and_map
pinctrl: tz1090-pinctrl.txt: Fix typo in binding
pinctrl: pinconf-generic: Declare dt_params/conf_items const
pinctrl: exynos: Add support for Exynos4415
pinctrl: exynos: Add initial driver data for Exynos7
pinctrl: exynos: Add irq_chip instance for Exynos7 wakeup interrupts
pinctrl: exynos: Consolidate irq domain callbacks
pinctrl: exynos: Generalize the eint16_31 demux code
pinctrl: samsung: Separate per-bank init and runtime data
pinctrl: samsung: Constify samsung_pin_ctrl struct
pinctrl: samsung: Constify samsung_pin_bank_type struct
pinctrl: samsung: Drop unused label field in samsung_pin_ctrl struct
pinctrl: samsung: Make samsung_pinctrl_get_soc_data use ERR_PTR()
pinctrl: Add Intel Cherryview/Braswell pin controller support
gpio / ACPI: Add knowledge about pin controllers to acpi_get_gpiod()
pinctrl: Fix path error in documentation
pinctrl: rockchip: save and restore gpio6_c6 pinmux in suspend/resume
pinctrl: rockchip: add suspend/resume functions
...
Diffstat (limited to 'drivers/pinctrl')
33 files changed, 4995 insertions, 344 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index c6a66de6ed72..d014f22f387a 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -67,18 +67,6 @@ config PINCTRL_AT91 | |||
67 | help | 67 | help |
68 | Say Y here to enable the at91 pinctrl driver | 68 | Say Y here to enable the at91 pinctrl driver |
69 | 69 | ||
70 | config PINCTRL_BAYTRAIL | ||
71 | bool "Intel Baytrail GPIO pin control" | ||
72 | depends on GPIOLIB && ACPI && X86 | ||
73 | select GPIOLIB_IRQCHIP | ||
74 | help | ||
75 | driver for memory mapped GPIO functionality on Intel Baytrail | ||
76 | platforms. Supports 3 banks with 102, 28 and 44 gpios. | ||
77 | Most pins are usually muxed to some other functionality by firmware, | ||
78 | so only a small amount is available for gpio use. | ||
79 | |||
80 | Requires ACPI device enumeration code to set up a platform device. | ||
81 | |||
82 | config PINCTRL_BCM2835 | 70 | config PINCTRL_BCM2835 |
83 | bool | 71 | bool |
84 | select PINMUX | 72 | select PINMUX |
@@ -205,6 +193,7 @@ config PINCTRL_PALMAS | |||
205 | 193 | ||
206 | source "drivers/pinctrl/berlin/Kconfig" | 194 | source "drivers/pinctrl/berlin/Kconfig" |
207 | source "drivers/pinctrl/freescale/Kconfig" | 195 | source "drivers/pinctrl/freescale/Kconfig" |
196 | source "drivers/pinctrl/intel/Kconfig" | ||
208 | source "drivers/pinctrl/mvebu/Kconfig" | 197 | source "drivers/pinctrl/mvebu/Kconfig" |
209 | source "drivers/pinctrl/nomadik/Kconfig" | 198 | source "drivers/pinctrl/nomadik/Kconfig" |
210 | source "drivers/pinctrl/qcom/Kconfig" | 199 | source "drivers/pinctrl/qcom/Kconfig" |
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 51f52d32859e..c030b3db8034 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
@@ -15,7 +15,6 @@ obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o | |||
15 | obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o | 15 | obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o |
16 | obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o | 16 | obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o |
17 | obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o | 17 | obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o |
18 | obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o | ||
19 | obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o | 18 | obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o |
20 | obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o | 19 | obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o |
21 | obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o | 20 | obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o |
@@ -39,6 +38,7 @@ obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o | |||
39 | 38 | ||
40 | obj-$(CONFIG_ARCH_BERLIN) += berlin/ | 39 | obj-$(CONFIG_ARCH_BERLIN) += berlin/ |
41 | obj-y += freescale/ | 40 | obj-y += freescale/ |
41 | obj-$(CONFIG_X86) += intel/ | ||
42 | obj-$(CONFIG_PLAT_ORION) += mvebu/ | 42 | obj-$(CONFIG_PLAT_ORION) += mvebu/ |
43 | obj-y += nomadik/ | 43 | obj-y += nomadik/ |
44 | obj-$(CONFIG_ARCH_QCOM) += qcom/ | 44 | obj-$(CONFIG_ARCH_QCOM) += qcom/ |
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index f2446769247f..52f2b9404fe0 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c | |||
@@ -294,11 +294,83 @@ static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, | |||
294 | return 0; | 294 | return 0; |
295 | } | 295 | } |
296 | 296 | ||
297 | static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, | ||
298 | struct pinctrl_gpio_range *range, unsigned offset) | ||
299 | { | ||
300 | struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | ||
301 | const struct imx_pinctrl_soc_info *info = ipctl->info; | ||
302 | const struct imx_pin_reg *pin_reg; | ||
303 | struct imx_pin_group *grp; | ||
304 | struct imx_pin *imx_pin; | ||
305 | unsigned int pin, group; | ||
306 | u32 reg; | ||
307 | |||
308 | /* Currently implementation only for shared mux/conf register */ | ||
309 | if (!(info->flags & SHARE_MUX_CONF_REG)) | ||
310 | return -EINVAL; | ||
311 | |||
312 | pin_reg = &info->pin_regs[offset]; | ||
313 | if (pin_reg->mux_reg == -1) | ||
314 | return -EINVAL; | ||
315 | |||
316 | /* Find the pinctrl config with GPIO mux mode for the requested pin */ | ||
317 | for (group = 0; group < info->ngroups; group++) { | ||
318 | grp = &info->groups[group]; | ||
319 | for (pin = 0; pin < grp->npins; pin++) { | ||
320 | imx_pin = &grp->pins[pin]; | ||
321 | if (imx_pin->pin == offset && !imx_pin->mux_mode) | ||
322 | goto mux_pin; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | return -EINVAL; | ||
327 | |||
328 | mux_pin: | ||
329 | reg = readl(ipctl->base + pin_reg->mux_reg); | ||
330 | reg &= ~(0x7 << 20); | ||
331 | reg |= imx_pin->config; | ||
332 | writel(reg, ipctl->base + pin_reg->mux_reg); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static int imx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | ||
338 | struct pinctrl_gpio_range *range, unsigned offset, bool input) | ||
339 | { | ||
340 | struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | ||
341 | const struct imx_pinctrl_soc_info *info = ipctl->info; | ||
342 | const struct imx_pin_reg *pin_reg; | ||
343 | u32 reg; | ||
344 | |||
345 | /* | ||
346 | * Only Vybrid has the input/output buffer enable flags (IBE/OBE) | ||
347 | * They are part of the shared mux/conf register. | ||
348 | */ | ||
349 | if (!(info->flags & SHARE_MUX_CONF_REG)) | ||
350 | return -EINVAL; | ||
351 | |||
352 | pin_reg = &info->pin_regs[offset]; | ||
353 | if (pin_reg->mux_reg == -1) | ||
354 | return -EINVAL; | ||
355 | |||
356 | /* IBE always enabled allows us to read the value "on the wire" */ | ||
357 | reg = readl(ipctl->base + pin_reg->mux_reg); | ||
358 | if (input) | ||
359 | reg &= ~0x2; | ||
360 | else | ||
361 | reg |= 0x2; | ||
362 | writel(reg, ipctl->base + pin_reg->mux_reg); | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
297 | static const struct pinmux_ops imx_pmx_ops = { | 367 | static const struct pinmux_ops imx_pmx_ops = { |
298 | .get_functions_count = imx_pmx_get_funcs_count, | 368 | .get_functions_count = imx_pmx_get_funcs_count, |
299 | .get_function_name = imx_pmx_get_func_name, | 369 | .get_function_name = imx_pmx_get_func_name, |
300 | .get_function_groups = imx_pmx_get_groups, | 370 | .get_function_groups = imx_pmx_get_groups, |
301 | .set_mux = imx_pmx_set, | 371 | .set_mux = imx_pmx_set, |
372 | .gpio_request_enable = imx_pmx_gpio_request_enable, | ||
373 | .gpio_set_direction = imx_pmx_gpio_set_direction, | ||
302 | }; | 374 | }; |
303 | 375 | ||
304 | static int imx_pinconf_get(struct pinctrl_dev *pctldev, | 376 | static int imx_pinconf_get(struct pinctrl_dev *pctldev, |
diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c index f98c6bb0f769..646d5c244af1 100644 --- a/drivers/pinctrl/freescale/pinctrl-mxs.c +++ b/drivers/pinctrl/freescale/pinctrl-mxs.c | |||
@@ -445,6 +445,31 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev, | |||
445 | if (of_property_read_u32(child, "reg", &val)) | 445 | if (of_property_read_u32(child, "reg", &val)) |
446 | continue; | 446 | continue; |
447 | if (strcmp(fn, child->name)) { | 447 | if (strcmp(fn, child->name)) { |
448 | struct device_node *child2; | ||
449 | |||
450 | /* | ||
451 | * This reference is dropped by | ||
452 | * of_get_next_child(np, * child) | ||
453 | */ | ||
454 | of_node_get(child); | ||
455 | |||
456 | /* | ||
457 | * The logic parsing the functions from dt currently | ||
458 | * doesn't handle if functions with the same name are | ||
459 | * not grouped together. Only the first contiguous | ||
460 | * cluster is usable for each function name. This is a | ||
461 | * bug that is not trivial to fix, but at least warn | ||
462 | * about it. | ||
463 | */ | ||
464 | for (child2 = of_get_next_child(np, child); | ||
465 | child2 != NULL; | ||
466 | child2 = of_get_next_child(np, child2)) { | ||
467 | if (!strcmp(child2->name, fn)) | ||
468 | dev_warn(&pdev->dev, | ||
469 | "function nodes must be grouped by name (failed for: %s)", | ||
470 | fn); | ||
471 | } | ||
472 | |||
448 | f = &soc->functions[idxf++]; | 473 | f = &soc->functions[idxf++]; |
449 | f->name = fn = child->name; | 474 | f->name = fn = child->name; |
450 | } | 475 | } |
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig new file mode 100644 index 000000000000..b801d869e91c --- /dev/null +++ b/drivers/pinctrl/intel/Kconfig | |||
@@ -0,0 +1,27 @@ | |||
1 | # | ||
2 | # Intel pin control drivers | ||
3 | # | ||
4 | |||
5 | config PINCTRL_BAYTRAIL | ||
6 | bool "Intel Baytrail GPIO pin control" | ||
7 | depends on GPIOLIB && ACPI | ||
8 | select GPIOLIB_IRQCHIP | ||
9 | help | ||
10 | driver for memory mapped GPIO functionality on Intel Baytrail | ||
11 | platforms. Supports 3 banks with 102, 28 and 44 gpios. | ||
12 | Most pins are usually muxed to some other functionality by firmware, | ||
13 | so only a small amount is available for gpio use. | ||
14 | |||
15 | Requires ACPI device enumeration code to set up a platform device. | ||
16 | |||
17 | config PINCTRL_CHERRYVIEW | ||
18 | tristate "Intel Cherryview/Braswell pinctrl and GPIO driver" | ||
19 | depends on ACPI | ||
20 | select PINMUX | ||
21 | select PINCONF | ||
22 | select GENERIC_PINCONF | ||
23 | select GPIOLIB | ||
24 | select GPIOLIB_IRQCHIP | ||
25 | help | ||
26 | Cherryview/Braswell pinctrl driver provides an interface that | ||
27 | allows configuring of SoC pins and using them as GPIOs. | ||
diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile new file mode 100644 index 000000000000..4c210e4139e2 --- /dev/null +++ b/drivers/pinctrl/intel/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | # Intel pin control drivers | ||
2 | |||
3 | obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o | ||
4 | obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o | ||
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 9dc38140194b..7db000431da7 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c | |||
@@ -616,5 +616,10 @@ static int __init byt_gpio_init(void) | |||
616 | { | 616 | { |
617 | return platform_driver_register(&byt_gpio_driver); | 617 | return platform_driver_register(&byt_gpio_driver); |
618 | } | 618 | } |
619 | |||
620 | subsys_initcall(byt_gpio_init); | 619 | subsys_initcall(byt_gpio_init); |
620 | |||
621 | static void __exit byt_gpio_exit(void) | ||
622 | { | ||
623 | platform_driver_unregister(&byt_gpio_driver); | ||
624 | } | ||
625 | module_exit(byt_gpio_exit); | ||
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c new file mode 100644 index 000000000000..e9f8b39d1a9f --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c | |||
@@ -0,0 +1,1519 @@ | |||
1 | /* | ||
2 | * Cherryview/Braswell pinctrl driver | ||
3 | * | ||
4 | * Copyright (C) 2014, Intel Corporation | ||
5 | * Author: Mika Westerberg <mika.westerberg@linux.intel.com> | ||
6 | * | ||
7 | * This driver is based on the original Cherryview GPIO driver by | ||
8 | * Ning Li <ning.li@intel.com> | ||
9 | * Alan Cox <alan@linux.intel.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <linux/gpio/driver.h> | ||
22 | #include <linux/acpi.h> | ||
23 | #include <linux/pinctrl/pinctrl.h> | ||
24 | #include <linux/pinctrl/pinmux.h> | ||
25 | #include <linux/pinctrl/pinconf.h> | ||
26 | #include <linux/pinctrl/pinconf-generic.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | |||
29 | #define CHV_INTSTAT 0x300 | ||
30 | #define CHV_INTMASK 0x380 | ||
31 | |||
32 | #define FAMILY_PAD_REGS_OFF 0x4400 | ||
33 | #define FAMILY_PAD_REGS_SIZE 0x400 | ||
34 | #define MAX_FAMILY_PAD_GPIO_NO 15 | ||
35 | #define GPIO_REGS_SIZE 8 | ||
36 | |||
37 | #define CHV_PADCTRL0 0x000 | ||
38 | #define CHV_PADCTRL0_INTSEL_SHIFT 28 | ||
39 | #define CHV_PADCTRL0_INTSEL_MASK (0xf << CHV_PADCTRL0_INTSEL_SHIFT) | ||
40 | #define CHV_PADCTRL0_TERM_UP BIT(23) | ||
41 | #define CHV_PADCTRL0_TERM_SHIFT 20 | ||
42 | #define CHV_PADCTRL0_TERM_MASK (7 << CHV_PADCTRL0_TERM_SHIFT) | ||
43 | #define CHV_PADCTRL0_TERM_20K 1 | ||
44 | #define CHV_PADCTRL0_TERM_5K 2 | ||
45 | #define CHV_PADCTRL0_TERM_1K 4 | ||
46 | #define CHV_PADCTRL0_PMODE_SHIFT 16 | ||
47 | #define CHV_PADCTRL0_PMODE_MASK (0xf << CHV_PADCTRL0_PMODE_SHIFT) | ||
48 | #define CHV_PADCTRL0_GPIOEN BIT(15) | ||
49 | #define CHV_PADCTRL0_GPIOCFG_SHIFT 8 | ||
50 | #define CHV_PADCTRL0_GPIOCFG_MASK (7 << CHV_PADCTRL0_GPIOCFG_SHIFT) | ||
51 | #define CHV_PADCTRL0_GPIOCFG_GPIO 0 | ||
52 | #define CHV_PADCTRL0_GPIOCFG_GPO 1 | ||
53 | #define CHV_PADCTRL0_GPIOCFG_GPI 2 | ||
54 | #define CHV_PADCTRL0_GPIOCFG_HIZ 3 | ||
55 | #define CHV_PADCTRL0_GPIOTXSTATE BIT(1) | ||
56 | #define CHV_PADCTRL0_GPIORXSTATE BIT(0) | ||
57 | |||
58 | #define CHV_PADCTRL1 0x004 | ||
59 | #define CHV_PADCTRL1_CFGLOCK BIT(31) | ||
60 | #define CHV_PADCTRL1_INVRXTX_SHIFT 4 | ||
61 | #define CHV_PADCTRL1_INVRXTX_MASK (0xf << CHV_PADCTRL1_INVRXTX_SHIFT) | ||
62 | #define CHV_PADCTRL1_INVRXTX_TXENABLE (2 << CHV_PADCTRL1_INVRXTX_SHIFT) | ||
63 | #define CHV_PADCTRL1_ODEN BIT(3) | ||
64 | #define CHV_PADCTRL1_INVRXTX_RXDATA (4 << CHV_PADCTRL1_INVRXTX_SHIFT) | ||
65 | #define CHV_PADCTRL1_INTWAKECFG_MASK 7 | ||
66 | #define CHV_PADCTRL1_INTWAKECFG_FALLING 1 | ||
67 | #define CHV_PADCTRL1_INTWAKECFG_RISING 2 | ||
68 | #define CHV_PADCTRL1_INTWAKECFG_BOTH 3 | ||
69 | #define CHV_PADCTRL1_INTWAKECFG_LEVEL 4 | ||
70 | |||
71 | /** | ||
72 | * struct chv_alternate_function - A per group or per pin alternate function | ||
73 | * @pin: Pin number (only used in per pin configs) | ||
74 | * @mode: Mode the pin should be set in | ||
75 | * @invert_oe: Invert OE for this pin | ||
76 | */ | ||
77 | struct chv_alternate_function { | ||
78 | unsigned pin; | ||
79 | u8 mode; | ||
80 | bool invert_oe; | ||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * struct chv_pincgroup - describes a CHV pin group | ||
85 | * @name: Name of the group | ||
86 | * @pins: An array of pins in this group | ||
87 | * @npins: Number of pins in this group | ||
88 | * @altfunc: Alternate function applied to all pins in this group | ||
89 | * @overrides: Alternate function override per pin or %NULL if not used | ||
90 | * @noverrides: Number of per pin alternate function overrides if | ||
91 | * @overrides != NULL. | ||
92 | */ | ||
93 | struct chv_pingroup { | ||
94 | const char *name; | ||
95 | const unsigned *pins; | ||
96 | size_t npins; | ||
97 | struct chv_alternate_function altfunc; | ||
98 | const struct chv_alternate_function *overrides; | ||
99 | size_t noverrides; | ||
100 | }; | ||
101 | |||
102 | /** | ||
103 | * struct chv_function - A CHV pinmux function | ||
104 | * @name: Name of the function | ||
105 | * @groups: An array of groups for this function | ||
106 | * @ngroups: Number of groups in @groups | ||
107 | */ | ||
108 | struct chv_function { | ||
109 | const char *name; | ||
110 | const char * const *groups; | ||
111 | size_t ngroups; | ||
112 | }; | ||
113 | |||
114 | /** | ||
115 | * struct chv_gpio_pinrange - A range of pins that can be used as GPIOs | ||
116 | * @base: Start pin number | ||
117 | * @npins: Number of pins in this range | ||
118 | */ | ||
119 | struct chv_gpio_pinrange { | ||
120 | unsigned base; | ||
121 | unsigned npins; | ||
122 | }; | ||
123 | |||
124 | /** | ||
125 | * struct chv_community - A community specific configuration | ||
126 | * @uid: ACPI _UID used to match the community | ||
127 | * @pins: All pins in this community | ||
128 | * @npins: Number of pins | ||
129 | * @groups: All groups in this community | ||
130 | * @ngroups: Number of groups | ||
131 | * @functions: All functions in this community | ||
132 | * @nfunctions: Number of functions | ||
133 | * @ngpios: Number of GPIOs in this community | ||
134 | * @gpio_ranges: An array of GPIO ranges in this community | ||
135 | * @ngpio_ranges: Number of GPIO ranges | ||
136 | * @ngpios: Total number of GPIOs in this community | ||
137 | */ | ||
138 | struct chv_community { | ||
139 | const char *uid; | ||
140 | const struct pinctrl_pin_desc *pins; | ||
141 | size_t npins; | ||
142 | const struct chv_pingroup *groups; | ||
143 | size_t ngroups; | ||
144 | const struct chv_function *functions; | ||
145 | size_t nfunctions; | ||
146 | const struct chv_gpio_pinrange *gpio_ranges; | ||
147 | size_t ngpio_ranges; | ||
148 | size_t ngpios; | ||
149 | }; | ||
150 | |||
151 | /** | ||
152 | * struct chv_pinctrl - CHV pinctrl private structure | ||
153 | * @dev: Pointer to the parent device | ||
154 | * @pctldesc: Pin controller description | ||
155 | * @pctldev: Pointer to the pin controller device | ||
156 | * @chip: GPIO chip in this pin controller | ||
157 | * @regs: MMIO registers | ||
158 | * @lock: Lock to serialize register accesses | ||
159 | * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO | ||
160 | * offset (in GPIO number space) | ||
161 | * @community: Community this pinctrl instance represents | ||
162 | * | ||
163 | * The first group in @groups is expected to contain all pins that can be | ||
164 | * used as GPIOs. | ||
165 | */ | ||
166 | struct chv_pinctrl { | ||
167 | struct device *dev; | ||
168 | struct pinctrl_desc pctldesc; | ||
169 | struct pinctrl_dev *pctldev; | ||
170 | struct gpio_chip chip; | ||
171 | void __iomem *regs; | ||
172 | spinlock_t lock; | ||
173 | unsigned intr_lines[16]; | ||
174 | const struct chv_community *community; | ||
175 | }; | ||
176 | |||
177 | #define gpiochip_to_pinctrl(c) container_of(c, struct chv_pinctrl, chip) | ||
178 | |||
179 | #define ALTERNATE_FUNCTION(p, m, i) \ | ||
180 | { \ | ||
181 | .pin = (p), \ | ||
182 | .mode = (m), \ | ||
183 | .invert_oe = (i), \ | ||
184 | } | ||
185 | |||
186 | #define PIN_GROUP(n, p, m, i) \ | ||
187 | { \ | ||
188 | .name = (n), \ | ||
189 | .pins = (p), \ | ||
190 | .npins = ARRAY_SIZE((p)), \ | ||
191 | .altfunc.mode = (m), \ | ||
192 | .altfunc.invert_oe = (i), \ | ||
193 | } | ||
194 | |||
195 | #define PIN_GROUP_WITH_OVERRIDE(n, p, m, i, o) \ | ||
196 | { \ | ||
197 | .name = (n), \ | ||
198 | .pins = (p), \ | ||
199 | .npins = ARRAY_SIZE((p)), \ | ||
200 | .altfunc.mode = (m), \ | ||
201 | .altfunc.invert_oe = (i), \ | ||
202 | .overrides = (o), \ | ||
203 | .noverrides = ARRAY_SIZE((o)), \ | ||
204 | } | ||
205 | |||
206 | #define FUNCTION(n, g) \ | ||
207 | { \ | ||
208 | .name = (n), \ | ||
209 | .groups = (g), \ | ||
210 | .ngroups = ARRAY_SIZE((g)), \ | ||
211 | } | ||
212 | |||
213 | #define GPIO_PINRANGE(start, end) \ | ||
214 | { \ | ||
215 | .base = (start), \ | ||
216 | .npins = (end) - (start) + 1, \ | ||
217 | } | ||
218 | |||
219 | static const struct pinctrl_pin_desc southwest_pins[] = { | ||
220 | PINCTRL_PIN(0, "FST_SPI_D2"), | ||
221 | PINCTRL_PIN(1, "FST_SPI_D0"), | ||
222 | PINCTRL_PIN(2, "FST_SPI_CLK"), | ||
223 | PINCTRL_PIN(3, "FST_SPI_D3"), | ||
224 | PINCTRL_PIN(4, "FST_SPI_CS1_B"), | ||
225 | PINCTRL_PIN(5, "FST_SPI_D1"), | ||
226 | PINCTRL_PIN(6, "FST_SPI_CS0_B"), | ||
227 | PINCTRL_PIN(7, "FST_SPI_CS2_B"), | ||
228 | |||
229 | PINCTRL_PIN(15, "UART1_RTS_B"), | ||
230 | PINCTRL_PIN(16, "UART1_RXD"), | ||
231 | PINCTRL_PIN(17, "UART2_RXD"), | ||
232 | PINCTRL_PIN(18, "UART1_CTS_B"), | ||
233 | PINCTRL_PIN(19, "UART2_RTS_B"), | ||
234 | PINCTRL_PIN(20, "UART1_TXD"), | ||
235 | PINCTRL_PIN(21, "UART2_TXD"), | ||
236 | PINCTRL_PIN(22, "UART2_CTS_B"), | ||
237 | |||
238 | PINCTRL_PIN(30, "MF_HDA_CLK"), | ||
239 | PINCTRL_PIN(31, "MF_HDA_RSTB"), | ||
240 | PINCTRL_PIN(32, "MF_HDA_SDIO"), | ||
241 | PINCTRL_PIN(33, "MF_HDA_SDO"), | ||
242 | PINCTRL_PIN(34, "MF_HDA_DOCKRSTB"), | ||
243 | PINCTRL_PIN(35, "MF_HDA_SYNC"), | ||
244 | PINCTRL_PIN(36, "MF_HDA_SDI1"), | ||
245 | PINCTRL_PIN(37, "MF_HDA_DOCKENB"), | ||
246 | |||
247 | PINCTRL_PIN(45, "I2C5_SDA"), | ||
248 | PINCTRL_PIN(46, "I2C4_SDA"), | ||
249 | PINCTRL_PIN(47, "I2C6_SDA"), | ||
250 | PINCTRL_PIN(48, "I2C5_SCL"), | ||
251 | PINCTRL_PIN(49, "I2C_NFC_SDA"), | ||
252 | PINCTRL_PIN(50, "I2C4_SCL"), | ||
253 | PINCTRL_PIN(51, "I2C6_SCL"), | ||
254 | PINCTRL_PIN(52, "I2C_NFC_SCL"), | ||
255 | |||
256 | PINCTRL_PIN(60, "I2C1_SDA"), | ||
257 | PINCTRL_PIN(61, "I2C0_SDA"), | ||
258 | PINCTRL_PIN(62, "I2C2_SDA"), | ||
259 | PINCTRL_PIN(63, "I2C1_SCL"), | ||
260 | PINCTRL_PIN(64, "I2C3_SDA"), | ||
261 | PINCTRL_PIN(65, "I2C0_SCL"), | ||
262 | PINCTRL_PIN(66, "I2C2_SCL"), | ||
263 | PINCTRL_PIN(67, "I2C3_SCL"), | ||
264 | |||
265 | PINCTRL_PIN(75, "SATA_GP0"), | ||
266 | PINCTRL_PIN(76, "SATA_GP1"), | ||
267 | PINCTRL_PIN(77, "SATA_LEDN"), | ||
268 | PINCTRL_PIN(78, "SATA_GP2"), | ||
269 | PINCTRL_PIN(79, "MF_SMB_ALERTB"), | ||
270 | PINCTRL_PIN(80, "SATA_GP3"), | ||
271 | PINCTRL_PIN(81, "MF_SMB_CLK"), | ||
272 | PINCTRL_PIN(82, "MF_SMB_DATA"), | ||
273 | |||
274 | PINCTRL_PIN(90, "PCIE_CLKREQ0B"), | ||
275 | PINCTRL_PIN(91, "PCIE_CLKREQ1B"), | ||
276 | PINCTRL_PIN(92, "GP_SSP_2_CLK"), | ||
277 | PINCTRL_PIN(93, "PCIE_CLKREQ2B"), | ||
278 | PINCTRL_PIN(94, "GP_SSP_2_RXD"), | ||
279 | PINCTRL_PIN(95, "PCIE_CLKREQ3B"), | ||
280 | PINCTRL_PIN(96, "GP_SSP_2_FS"), | ||
281 | PINCTRL_PIN(97, "GP_SSP_2_TXD"), | ||
282 | }; | ||
283 | |||
284 | static const unsigned southwest_fspi_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; | ||
285 | static const unsigned southwest_uart0_pins[] = { 16, 20 }; | ||
286 | static const unsigned southwest_uart1_pins[] = { 15, 16, 18, 20 }; | ||
287 | static const unsigned southwest_uart2_pins[] = { 17, 19, 21, 22 }; | ||
288 | static const unsigned southwest_i2c0_pins[] = { 61, 65 }; | ||
289 | static const unsigned southwest_hda_pins[] = { 30, 31, 32, 33, 34, 35, 36, 37 }; | ||
290 | static const unsigned southwest_lpe_pins[] = { | ||
291 | 30, 31, 32, 33, 34, 35, 36, 37, 92, 94, 96, 97, | ||
292 | }; | ||
293 | static const unsigned southwest_i2c1_pins[] = { 60, 63 }; | ||
294 | static const unsigned southwest_i2c2_pins[] = { 62, 66 }; | ||
295 | static const unsigned southwest_i2c3_pins[] = { 64, 67 }; | ||
296 | static const unsigned southwest_i2c4_pins[] = { 46, 50 }; | ||
297 | static const unsigned southwest_i2c5_pins[] = { 45, 48 }; | ||
298 | static const unsigned southwest_i2c6_pins[] = { 47, 51 }; | ||
299 | static const unsigned southwest_i2c_nfc_pins[] = { 49, 52 }; | ||
300 | static const unsigned southwest_smbus_pins[] = { 79, 81, 82 }; | ||
301 | static const unsigned southwest_spi3_pins[] = { 76, 79, 80, 81, 82 }; | ||
302 | |||
303 | /* LPE I2S TXD pins need to have invert_oe set */ | ||
304 | static const struct chv_alternate_function southwest_lpe_altfuncs[] = { | ||
305 | ALTERNATE_FUNCTION(30, 1, true), | ||
306 | ALTERNATE_FUNCTION(34, 1, true), | ||
307 | ALTERNATE_FUNCTION(97, 1, true), | ||
308 | }; | ||
309 | |||
310 | /* | ||
311 | * Two spi3 chipselects are available in different mode than the main spi3 | ||
312 | * functionality, which is using mode 1. | ||
313 | */ | ||
314 | static const struct chv_alternate_function southwest_spi3_altfuncs[] = { | ||
315 | ALTERNATE_FUNCTION(76, 3, false), | ||
316 | ALTERNATE_FUNCTION(80, 3, false), | ||
317 | }; | ||
318 | |||
319 | static const struct chv_pingroup southwest_groups[] = { | ||
320 | PIN_GROUP("uart0_grp", southwest_uart0_pins, 2, false), | ||
321 | PIN_GROUP("uart1_grp", southwest_uart1_pins, 1, false), | ||
322 | PIN_GROUP("uart2_grp", southwest_uart2_pins, 1, false), | ||
323 | PIN_GROUP("hda_grp", southwest_hda_pins, 2, false), | ||
324 | PIN_GROUP("i2c0_grp", southwest_i2c0_pins, 1, true), | ||
325 | PIN_GROUP("i2c1_grp", southwest_i2c1_pins, 1, true), | ||
326 | PIN_GROUP("i2c2_grp", southwest_i2c2_pins, 1, true), | ||
327 | PIN_GROUP("i2c3_grp", southwest_i2c3_pins, 1, true), | ||
328 | PIN_GROUP("i2c4_grp", southwest_i2c4_pins, 1, true), | ||
329 | PIN_GROUP("i2c5_grp", southwest_i2c5_pins, 1, true), | ||
330 | PIN_GROUP("i2c6_grp", southwest_i2c6_pins, 1, true), | ||
331 | PIN_GROUP("i2c_nfc_grp", southwest_i2c_nfc_pins, 2, true), | ||
332 | |||
333 | PIN_GROUP_WITH_OVERRIDE("lpe_grp", southwest_lpe_pins, 1, false, | ||
334 | southwest_lpe_altfuncs), | ||
335 | PIN_GROUP_WITH_OVERRIDE("spi3_grp", southwest_spi3_pins, 2, false, | ||
336 | southwest_spi3_altfuncs), | ||
337 | }; | ||
338 | |||
339 | static const char * const southwest_uart0_groups[] = { "uart0_grp" }; | ||
340 | static const char * const southwest_uart1_groups[] = { "uart1_grp" }; | ||
341 | static const char * const southwest_uart2_groups[] = { "uart2_grp" }; | ||
342 | static const char * const southwest_hda_groups[] = { "hda_grp" }; | ||
343 | static const char * const southwest_lpe_groups[] = { "lpe_grp" }; | ||
344 | static const char * const southwest_i2c0_groups[] = { "i2c0_grp" }; | ||
345 | static const char * const southwest_i2c1_groups[] = { "i2c1_grp" }; | ||
346 | static const char * const southwest_i2c2_groups[] = { "i2c2_grp" }; | ||
347 | static const char * const southwest_i2c3_groups[] = { "i2c3_grp" }; | ||
348 | static const char * const southwest_i2c4_groups[] = { "i2c4_grp" }; | ||
349 | static const char * const southwest_i2c5_groups[] = { "i2c5_grp" }; | ||
350 | static const char * const southwest_i2c6_groups[] = { "i2c6_grp" }; | ||
351 | static const char * const southwest_i2c_nfc_groups[] = { "i2c_nfc_grp" }; | ||
352 | static const char * const southwest_spi3_groups[] = { "spi3_grp" }; | ||
353 | |||
354 | /* | ||
355 | * Only do pinmuxing for certain LPSS devices for now. Rest of the pins are | ||
356 | * enabled only as GPIOs. | ||
357 | */ | ||
358 | static const struct chv_function southwest_functions[] = { | ||
359 | FUNCTION("uart0", southwest_uart0_groups), | ||
360 | FUNCTION("uart1", southwest_uart1_groups), | ||
361 | FUNCTION("uart2", southwest_uart2_groups), | ||
362 | FUNCTION("hda", southwest_hda_groups), | ||
363 | FUNCTION("lpe", southwest_lpe_groups), | ||
364 | FUNCTION("i2c0", southwest_i2c0_groups), | ||
365 | FUNCTION("i2c1", southwest_i2c1_groups), | ||
366 | FUNCTION("i2c2", southwest_i2c2_groups), | ||
367 | FUNCTION("i2c3", southwest_i2c3_groups), | ||
368 | FUNCTION("i2c4", southwest_i2c4_groups), | ||
369 | FUNCTION("i2c5", southwest_i2c5_groups), | ||
370 | FUNCTION("i2c6", southwest_i2c6_groups), | ||
371 | FUNCTION("i2c_nfc", southwest_i2c_nfc_groups), | ||
372 | FUNCTION("spi3", southwest_spi3_groups), | ||
373 | }; | ||
374 | |||
375 | static const struct chv_gpio_pinrange southwest_gpio_ranges[] = { | ||
376 | GPIO_PINRANGE(0, 7), | ||
377 | GPIO_PINRANGE(15, 22), | ||
378 | GPIO_PINRANGE(30, 37), | ||
379 | GPIO_PINRANGE(45, 52), | ||
380 | GPIO_PINRANGE(60, 67), | ||
381 | GPIO_PINRANGE(75, 82), | ||
382 | GPIO_PINRANGE(90, 97), | ||
383 | }; | ||
384 | |||
385 | static const struct chv_community southwest_community = { | ||
386 | .uid = "1", | ||
387 | .pins = southwest_pins, | ||
388 | .npins = ARRAY_SIZE(southwest_pins), | ||
389 | .groups = southwest_groups, | ||
390 | .ngroups = ARRAY_SIZE(southwest_groups), | ||
391 | .functions = southwest_functions, | ||
392 | .nfunctions = ARRAY_SIZE(southwest_functions), | ||
393 | .gpio_ranges = southwest_gpio_ranges, | ||
394 | .ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges), | ||
395 | .ngpios = ARRAY_SIZE(southwest_pins), | ||
396 | }; | ||
397 | |||
398 | static const struct pinctrl_pin_desc north_pins[] = { | ||
399 | PINCTRL_PIN(0, "GPIO_DFX_0"), | ||
400 | PINCTRL_PIN(1, "GPIO_DFX_3"), | ||
401 | PINCTRL_PIN(2, "GPIO_DFX_7"), | ||
402 | PINCTRL_PIN(3, "GPIO_DFX_1"), | ||
403 | PINCTRL_PIN(4, "GPIO_DFX_5"), | ||
404 | PINCTRL_PIN(5, "GPIO_DFX_4"), | ||
405 | PINCTRL_PIN(6, "GPIO_DFX_8"), | ||
406 | PINCTRL_PIN(7, "GPIO_DFX_2"), | ||
407 | PINCTRL_PIN(8, "GPIO_DFX_6"), | ||
408 | |||
409 | PINCTRL_PIN(15, "GPIO_SUS0"), | ||
410 | PINCTRL_PIN(16, "SEC_GPIO_SUS10"), | ||
411 | PINCTRL_PIN(17, "GPIO_SUS3"), | ||
412 | PINCTRL_PIN(18, "GPIO_SUS7"), | ||
413 | PINCTRL_PIN(19, "GPIO_SUS1"), | ||
414 | PINCTRL_PIN(20, "GPIO_SUS5"), | ||
415 | PINCTRL_PIN(21, "SEC_GPIO_SUS11"), | ||
416 | PINCTRL_PIN(22, "GPIO_SUS4"), | ||
417 | PINCTRL_PIN(23, "SEC_GPIO_SUS8"), | ||
418 | PINCTRL_PIN(24, "GPIO_SUS2"), | ||
419 | PINCTRL_PIN(25, "GPIO_SUS6"), | ||
420 | PINCTRL_PIN(26, "CX_PREQ_B"), | ||
421 | PINCTRL_PIN(27, "SEC_GPIO_SUS9"), | ||
422 | |||
423 | PINCTRL_PIN(30, "TRST_B"), | ||
424 | PINCTRL_PIN(31, "TCK"), | ||
425 | PINCTRL_PIN(32, "PROCHOT_B"), | ||
426 | PINCTRL_PIN(33, "SVIDO_DATA"), | ||
427 | PINCTRL_PIN(34, "TMS"), | ||
428 | PINCTRL_PIN(35, "CX_PRDY_B_2"), | ||
429 | PINCTRL_PIN(36, "TDO_2"), | ||
430 | PINCTRL_PIN(37, "CX_PRDY_B"), | ||
431 | PINCTRL_PIN(38, "SVIDO_ALERT_B"), | ||
432 | PINCTRL_PIN(39, "TDO"), | ||
433 | PINCTRL_PIN(40, "SVIDO_CLK"), | ||
434 | PINCTRL_PIN(41, "TDI"), | ||
435 | |||
436 | PINCTRL_PIN(45, "GP_CAMERASB_05"), | ||
437 | PINCTRL_PIN(46, "GP_CAMERASB_02"), | ||
438 | PINCTRL_PIN(47, "GP_CAMERASB_08"), | ||
439 | PINCTRL_PIN(48, "GP_CAMERASB_00"), | ||
440 | PINCTRL_PIN(49, "GP_CAMERASB_06"), | ||
441 | PINCTRL_PIN(50, "GP_CAMERASB_10"), | ||
442 | PINCTRL_PIN(51, "GP_CAMERASB_03"), | ||
443 | PINCTRL_PIN(52, "GP_CAMERASB_09"), | ||
444 | PINCTRL_PIN(53, "GP_CAMERASB_01"), | ||
445 | PINCTRL_PIN(54, "GP_CAMERASB_07"), | ||
446 | PINCTRL_PIN(55, "GP_CAMERASB_11"), | ||
447 | PINCTRL_PIN(56, "GP_CAMERASB_04"), | ||
448 | |||
449 | PINCTRL_PIN(60, "PANEL0_BKLTEN"), | ||
450 | PINCTRL_PIN(61, "HV_DDI0_HPD"), | ||
451 | PINCTRL_PIN(62, "HV_DDI2_DDC_SDA"), | ||
452 | PINCTRL_PIN(63, "PANEL1_BKLTCTL"), | ||
453 | PINCTRL_PIN(64, "HV_DDI1_HPD"), | ||
454 | PINCTRL_PIN(65, "PANEL0_BKLTCTL"), | ||
455 | PINCTRL_PIN(66, "HV_DDI0_DDC_SDA"), | ||
456 | PINCTRL_PIN(67, "HV_DDI2_DDC_SCL"), | ||
457 | PINCTRL_PIN(68, "HV_DDI2_HPD"), | ||
458 | PINCTRL_PIN(69, "PANEL1_VDDEN"), | ||
459 | PINCTRL_PIN(70, "PANEL1_BKLTEN"), | ||
460 | PINCTRL_PIN(71, "HV_DDI0_DDC_SCL"), | ||
461 | PINCTRL_PIN(72, "PANEL0_VDDEN"), | ||
462 | }; | ||
463 | |||
464 | static const struct chv_gpio_pinrange north_gpio_ranges[] = { | ||
465 | GPIO_PINRANGE(0, 8), | ||
466 | GPIO_PINRANGE(15, 27), | ||
467 | GPIO_PINRANGE(30, 41), | ||
468 | GPIO_PINRANGE(45, 56), | ||
469 | GPIO_PINRANGE(60, 72), | ||
470 | }; | ||
471 | |||
472 | static const struct chv_community north_community = { | ||
473 | .uid = "2", | ||
474 | .pins = north_pins, | ||
475 | .npins = ARRAY_SIZE(north_pins), | ||
476 | .gpio_ranges = north_gpio_ranges, | ||
477 | .ngpio_ranges = ARRAY_SIZE(north_gpio_ranges), | ||
478 | .ngpios = ARRAY_SIZE(north_pins), | ||
479 | }; | ||
480 | |||
481 | static const struct pinctrl_pin_desc east_pins[] = { | ||
482 | PINCTRL_PIN(0, "PMU_SLP_S3_B"), | ||
483 | PINCTRL_PIN(1, "PMU_BATLOW_B"), | ||
484 | PINCTRL_PIN(2, "SUS_STAT_B"), | ||
485 | PINCTRL_PIN(3, "PMU_SLP_S0IX_B"), | ||
486 | PINCTRL_PIN(4, "PMU_AC_PRESENT"), | ||
487 | PINCTRL_PIN(5, "PMU_PLTRST_B"), | ||
488 | PINCTRL_PIN(6, "PMU_SUSCLK"), | ||
489 | PINCTRL_PIN(7, "PMU_SLP_LAN_B"), | ||
490 | PINCTRL_PIN(8, "PMU_PWRBTN_B"), | ||
491 | PINCTRL_PIN(9, "PMU_SLP_S4_B"), | ||
492 | PINCTRL_PIN(10, "PMU_WAKE_B"), | ||
493 | PINCTRL_PIN(11, "PMU_WAKE_LAN_B"), | ||
494 | |||
495 | PINCTRL_PIN(15, "MF_ISH_GPIO_3"), | ||
496 | PINCTRL_PIN(16, "MF_ISH_GPIO_7"), | ||
497 | PINCTRL_PIN(17, "MF_ISH_I2C1_SCL"), | ||
498 | PINCTRL_PIN(18, "MF_ISH_GPIO_1"), | ||
499 | PINCTRL_PIN(19, "MF_ISH_GPIO_5"), | ||
500 | PINCTRL_PIN(20, "MF_ISH_GPIO_9"), | ||
501 | PINCTRL_PIN(21, "MF_ISH_GPIO_0"), | ||
502 | PINCTRL_PIN(22, "MF_ISH_GPIO_4"), | ||
503 | PINCTRL_PIN(23, "MF_ISH_GPIO_8"), | ||
504 | PINCTRL_PIN(24, "MF_ISH_GPIO_2"), | ||
505 | PINCTRL_PIN(25, "MF_ISH_GPIO_6"), | ||
506 | PINCTRL_PIN(26, "MF_ISH_I2C1_SDA"), | ||
507 | }; | ||
508 | |||
509 | static const struct chv_gpio_pinrange east_gpio_ranges[] = { | ||
510 | GPIO_PINRANGE(0, 11), | ||
511 | GPIO_PINRANGE(15, 26), | ||
512 | }; | ||
513 | |||
514 | static const struct chv_community east_community = { | ||
515 | .uid = "3", | ||
516 | .pins = east_pins, | ||
517 | .npins = ARRAY_SIZE(east_pins), | ||
518 | .gpio_ranges = east_gpio_ranges, | ||
519 | .ngpio_ranges = ARRAY_SIZE(east_gpio_ranges), | ||
520 | .ngpios = ARRAY_SIZE(east_pins), | ||
521 | }; | ||
522 | |||
523 | static const struct pinctrl_pin_desc southeast_pins[] = { | ||
524 | PINCTRL_PIN(0, "MF_PLT_CLK0"), | ||
525 | PINCTRL_PIN(1, "PWM1"), | ||
526 | PINCTRL_PIN(2, "MF_PLT_CLK1"), | ||
527 | PINCTRL_PIN(3, "MF_PLT_CLK4"), | ||
528 | PINCTRL_PIN(4, "MF_PLT_CLK3"), | ||
529 | PINCTRL_PIN(5, "PWM0"), | ||
530 | PINCTRL_PIN(6, "MF_PLT_CLK5"), | ||
531 | PINCTRL_PIN(7, "MF_PLT_CLK2"), | ||
532 | |||
533 | PINCTRL_PIN(15, "SDMMC2_D3_CD_B"), | ||
534 | PINCTRL_PIN(16, "SDMMC1_CLK"), | ||
535 | PINCTRL_PIN(17, "SDMMC1_D0"), | ||
536 | PINCTRL_PIN(18, "SDMMC2_D1"), | ||
537 | PINCTRL_PIN(19, "SDMMC2_CLK"), | ||
538 | PINCTRL_PIN(20, "SDMMC1_D2"), | ||
539 | PINCTRL_PIN(21, "SDMMC2_D2"), | ||
540 | PINCTRL_PIN(22, "SDMMC2_CMD"), | ||
541 | PINCTRL_PIN(23, "SDMMC1_CMD"), | ||
542 | PINCTRL_PIN(24, "SDMMC1_D1"), | ||
543 | PINCTRL_PIN(25, "SDMMC2_D0"), | ||
544 | PINCTRL_PIN(26, "SDMMC1_D3_CD_B"), | ||
545 | |||
546 | PINCTRL_PIN(30, "SDMMC3_D1"), | ||
547 | PINCTRL_PIN(31, "SDMMC3_CLK"), | ||
548 | PINCTRL_PIN(32, "SDMMC3_D3"), | ||
549 | PINCTRL_PIN(33, "SDMMC3_D2"), | ||
550 | PINCTRL_PIN(34, "SDMMC3_CMD"), | ||
551 | PINCTRL_PIN(35, "SDMMC3_D0"), | ||
552 | |||
553 | PINCTRL_PIN(45, "MF_LPC_AD2"), | ||
554 | PINCTRL_PIN(46, "LPC_CLKRUNB"), | ||
555 | PINCTRL_PIN(47, "MF_LPC_AD0"), | ||
556 | PINCTRL_PIN(48, "LPC_FRAMEB"), | ||
557 | PINCTRL_PIN(49, "MF_LPC_CLKOUT1"), | ||
558 | PINCTRL_PIN(50, "MF_LPC_AD3"), | ||
559 | PINCTRL_PIN(51, "MF_LPC_CLKOUT0"), | ||
560 | PINCTRL_PIN(52, "MF_LPC_AD1"), | ||
561 | |||
562 | PINCTRL_PIN(60, "SPI1_MISO"), | ||
563 | PINCTRL_PIN(61, "SPI1_CSO_B"), | ||
564 | PINCTRL_PIN(62, "SPI1_CLK"), | ||
565 | PINCTRL_PIN(63, "MMC1_D6"), | ||
566 | PINCTRL_PIN(64, "SPI1_MOSI"), | ||
567 | PINCTRL_PIN(65, "MMC1_D5"), | ||
568 | PINCTRL_PIN(66, "SPI1_CS1_B"), | ||
569 | PINCTRL_PIN(67, "MMC1_D4_SD_WE"), | ||
570 | PINCTRL_PIN(68, "MMC1_D7"), | ||
571 | PINCTRL_PIN(69, "MMC1_RCLK"), | ||
572 | |||
573 | PINCTRL_PIN(75, "USB_OC1_B"), | ||
574 | PINCTRL_PIN(76, "PMU_RESETBUTTON_B"), | ||
575 | PINCTRL_PIN(77, "GPIO_ALERT"), | ||
576 | PINCTRL_PIN(78, "SDMMC3_PWR_EN_B"), | ||
577 | PINCTRL_PIN(79, "ILB_SERIRQ"), | ||
578 | PINCTRL_PIN(80, "USB_OC0_B"), | ||
579 | PINCTRL_PIN(81, "SDMMC3_CD_B"), | ||
580 | PINCTRL_PIN(82, "SPKR"), | ||
581 | PINCTRL_PIN(83, "SUSPWRDNACK"), | ||
582 | PINCTRL_PIN(84, "SPARE_PIN"), | ||
583 | PINCTRL_PIN(85, "SDMMC3_1P8_EN"), | ||
584 | }; | ||
585 | |||
586 | static const unsigned southeast_pwm0_pins[] = { 5 }; | ||
587 | static const unsigned southeast_pwm1_pins[] = { 1 }; | ||
588 | static const unsigned southeast_sdmmc1_pins[] = { | ||
589 | 16, 17, 20, 23, 24, 26, 63, 65, 67, 68, 69, | ||
590 | }; | ||
591 | static const unsigned southeast_sdmmc2_pins[] = { 15, 18, 19, 21, 22, 25 }; | ||
592 | static const unsigned southeast_sdmmc3_pins[] = { | ||
593 | 30, 31, 32, 33, 34, 35, 78, 81, 85, | ||
594 | }; | ||
595 | static const unsigned southeast_spi1_pins[] = { 60, 61, 62, 64, 66 }; | ||
596 | static const unsigned southeast_spi2_pins[] = { 2, 3, 4, 6, 7 }; | ||
597 | |||
598 | static const struct chv_pingroup southeast_groups[] = { | ||
599 | PIN_GROUP("pwm0_grp", southeast_pwm0_pins, 1, false), | ||
600 | PIN_GROUP("pwm1_grp", southeast_pwm1_pins, 1, false), | ||
601 | PIN_GROUP("sdmmc1_grp", southeast_sdmmc1_pins, 1, false), | ||
602 | PIN_GROUP("sdmmc2_grp", southeast_sdmmc2_pins, 1, false), | ||
603 | PIN_GROUP("sdmmc3_grp", southeast_sdmmc3_pins, 1, false), | ||
604 | PIN_GROUP("spi1_grp", southeast_spi1_pins, 1, false), | ||
605 | PIN_GROUP("spi2_grp", southeast_spi2_pins, 4, false), | ||
606 | }; | ||
607 | |||
608 | static const char * const southeast_pwm0_groups[] = { "pwm0_grp" }; | ||
609 | static const char * const southeast_pwm1_groups[] = { "pwm1_grp" }; | ||
610 | static const char * const southeast_sdmmc1_groups[] = { "sdmmc1_grp" }; | ||
611 | static const char * const southeast_sdmmc2_groups[] = { "sdmmc2_grp" }; | ||
612 | static const char * const southeast_sdmmc3_groups[] = { "sdmmc3_grp" }; | ||
613 | static const char * const southeast_spi1_groups[] = { "spi1_grp" }; | ||
614 | static const char * const southeast_spi2_groups[] = { "spi2_grp" }; | ||
615 | |||
616 | static const struct chv_function southeast_functions[] = { | ||
617 | FUNCTION("pwm0", southeast_pwm0_groups), | ||
618 | FUNCTION("pwm1", southeast_pwm1_groups), | ||
619 | FUNCTION("sdmmc1", southeast_sdmmc1_groups), | ||
620 | FUNCTION("sdmmc2", southeast_sdmmc2_groups), | ||
621 | FUNCTION("sdmmc3", southeast_sdmmc3_groups), | ||
622 | FUNCTION("spi1", southeast_spi1_groups), | ||
623 | FUNCTION("spi2", southeast_spi2_groups), | ||
624 | }; | ||
625 | |||
626 | static const struct chv_gpio_pinrange southeast_gpio_ranges[] = { | ||
627 | GPIO_PINRANGE(0, 7), | ||
628 | GPIO_PINRANGE(15, 26), | ||
629 | GPIO_PINRANGE(30, 35), | ||
630 | GPIO_PINRANGE(45, 52), | ||
631 | GPIO_PINRANGE(60, 69), | ||
632 | GPIO_PINRANGE(75, 85), | ||
633 | }; | ||
634 | |||
635 | static const struct chv_community southeast_community = { | ||
636 | .uid = "4", | ||
637 | .pins = southeast_pins, | ||
638 | .npins = ARRAY_SIZE(southeast_pins), | ||
639 | .groups = southeast_groups, | ||
640 | .ngroups = ARRAY_SIZE(southeast_groups), | ||
641 | .functions = southeast_functions, | ||
642 | .nfunctions = ARRAY_SIZE(southeast_functions), | ||
643 | .gpio_ranges = southeast_gpio_ranges, | ||
644 | .ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges), | ||
645 | .ngpios = ARRAY_SIZE(southeast_pins), | ||
646 | }; | ||
647 | |||
648 | static const struct chv_community *chv_communities[] = { | ||
649 | &southwest_community, | ||
650 | &north_community, | ||
651 | &east_community, | ||
652 | &southeast_community, | ||
653 | }; | ||
654 | |||
655 | static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset, | ||
656 | unsigned reg) | ||
657 | { | ||
658 | unsigned family_no = offset / MAX_FAMILY_PAD_GPIO_NO; | ||
659 | unsigned pad_no = offset % MAX_FAMILY_PAD_GPIO_NO; | ||
660 | |||
661 | offset = FAMILY_PAD_REGS_OFF + FAMILY_PAD_REGS_SIZE * family_no + | ||
662 | GPIO_REGS_SIZE * pad_no; | ||
663 | |||
664 | return pctrl->regs + offset + reg; | ||
665 | } | ||
666 | |||
667 | static void chv_writel(u32 value, void __iomem *reg) | ||
668 | { | ||
669 | writel(value, reg); | ||
670 | /* simple readback to confirm the bus transferring done */ | ||
671 | readl(reg); | ||
672 | } | ||
673 | |||
674 | /* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */ | ||
675 | static bool chv_pad_locked(struct chv_pinctrl *pctrl, unsigned offset) | ||
676 | { | ||
677 | void __iomem *reg; | ||
678 | |||
679 | reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); | ||
680 | return readl(reg) & CHV_PADCTRL1_CFGLOCK; | ||
681 | } | ||
682 | |||
683 | static int chv_get_groups_count(struct pinctrl_dev *pctldev) | ||
684 | { | ||
685 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
686 | |||
687 | return pctrl->community->ngroups; | ||
688 | } | ||
689 | |||
690 | static const char *chv_get_group_name(struct pinctrl_dev *pctldev, | ||
691 | unsigned group) | ||
692 | { | ||
693 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
694 | |||
695 | return pctrl->community->groups[group].name; | ||
696 | } | ||
697 | |||
698 | static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, | ||
699 | const unsigned **pins, unsigned *npins) | ||
700 | { | ||
701 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
702 | |||
703 | *pins = pctrl->community->groups[group].pins; | ||
704 | *npins = pctrl->community->groups[group].npins; | ||
705 | return 0; | ||
706 | } | ||
707 | |||
708 | static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, | ||
709 | unsigned offset) | ||
710 | { | ||
711 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
712 | unsigned long flags; | ||
713 | u32 ctrl0, ctrl1; | ||
714 | bool locked; | ||
715 | |||
716 | spin_lock_irqsave(&pctrl->lock, flags); | ||
717 | |||
718 | ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); | ||
719 | ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1)); | ||
720 | locked = chv_pad_locked(pctrl, offset); | ||
721 | |||
722 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
723 | |||
724 | if (ctrl0 & CHV_PADCTRL0_GPIOEN) { | ||
725 | seq_puts(s, "GPIO "); | ||
726 | } else { | ||
727 | u32 mode; | ||
728 | |||
729 | mode = ctrl0 & CHV_PADCTRL0_PMODE_MASK; | ||
730 | mode >>= CHV_PADCTRL0_PMODE_SHIFT; | ||
731 | |||
732 | seq_printf(s, "mode %d ", mode); | ||
733 | } | ||
734 | |||
735 | seq_printf(s, "ctrl0 0x%08x ctrl1 0x%08x", ctrl0, ctrl1); | ||
736 | |||
737 | if (locked) | ||
738 | seq_puts(s, " [LOCKED]"); | ||
739 | } | ||
740 | |||
741 | static const struct pinctrl_ops chv_pinctrl_ops = { | ||
742 | .get_groups_count = chv_get_groups_count, | ||
743 | .get_group_name = chv_get_group_name, | ||
744 | .get_group_pins = chv_get_group_pins, | ||
745 | .pin_dbg_show = chv_pin_dbg_show, | ||
746 | }; | ||
747 | |||
748 | static int chv_get_functions_count(struct pinctrl_dev *pctldev) | ||
749 | { | ||
750 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
751 | |||
752 | return pctrl->community->nfunctions; | ||
753 | } | ||
754 | |||
755 | static const char *chv_get_function_name(struct pinctrl_dev *pctldev, | ||
756 | unsigned function) | ||
757 | { | ||
758 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
759 | |||
760 | return pctrl->community->functions[function].name; | ||
761 | } | ||
762 | |||
763 | static int chv_get_function_groups(struct pinctrl_dev *pctldev, | ||
764 | unsigned function, | ||
765 | const char * const **groups, | ||
766 | unsigned * const ngroups) | ||
767 | { | ||
768 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
769 | |||
770 | *groups = pctrl->community->functions[function].groups; | ||
771 | *ngroups = pctrl->community->functions[function].ngroups; | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function, | ||
776 | unsigned group) | ||
777 | { | ||
778 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
779 | const struct chv_pingroup *grp; | ||
780 | unsigned long flags; | ||
781 | int i; | ||
782 | |||
783 | grp = &pctrl->community->groups[group]; | ||
784 | |||
785 | spin_lock_irqsave(&pctrl->lock, flags); | ||
786 | |||
787 | /* Check first that the pad is not locked */ | ||
788 | for (i = 0; i < grp->npins; i++) { | ||
789 | if (chv_pad_locked(pctrl, grp->pins[i])) { | ||
790 | dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n", | ||
791 | grp->pins[i]); | ||
792 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
793 | return -EBUSY; | ||
794 | } | ||
795 | } | ||
796 | |||
797 | for (i = 0; i < grp->npins; i++) { | ||
798 | const struct chv_alternate_function *altfunc = &grp->altfunc; | ||
799 | int pin = grp->pins[i]; | ||
800 | void __iomem *reg; | ||
801 | u32 value; | ||
802 | |||
803 | /* Check if there is pin-specific config */ | ||
804 | if (grp->overrides) { | ||
805 | int j; | ||
806 | |||
807 | for (j = 0; j < grp->noverrides; j++) { | ||
808 | if (grp->overrides[j].pin == pin) { | ||
809 | altfunc = &grp->overrides[j]; | ||
810 | break; | ||
811 | } | ||
812 | } | ||
813 | } | ||
814 | |||
815 | reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); | ||
816 | value = readl(reg); | ||
817 | /* Disable GPIO mode */ | ||
818 | value &= ~CHV_PADCTRL0_GPIOEN; | ||
819 | /* Set to desired mode */ | ||
820 | value &= ~CHV_PADCTRL0_PMODE_MASK; | ||
821 | value |= altfunc->mode << CHV_PADCTRL0_PMODE_SHIFT; | ||
822 | chv_writel(value, reg); | ||
823 | |||
824 | /* Update for invert_oe */ | ||
825 | reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); | ||
826 | value = readl(reg) & ~CHV_PADCTRL1_INVRXTX_MASK; | ||
827 | if (altfunc->invert_oe) | ||
828 | value |= CHV_PADCTRL1_INVRXTX_TXENABLE; | ||
829 | chv_writel(value, reg); | ||
830 | |||
831 | dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n", | ||
832 | pin, altfunc->mode, altfunc->invert_oe ? "" : "not "); | ||
833 | } | ||
834 | |||
835 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
836 | |||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, | ||
841 | struct pinctrl_gpio_range *range, | ||
842 | unsigned offset) | ||
843 | { | ||
844 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
845 | unsigned long flags; | ||
846 | void __iomem *reg; | ||
847 | u32 value; | ||
848 | |||
849 | spin_lock_irqsave(&pctrl->lock, flags); | ||
850 | |||
851 | if (chv_pad_locked(pctrl, offset)) { | ||
852 | value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); | ||
853 | if (!(value & CHV_PADCTRL0_GPIOEN)) { | ||
854 | /* Locked so cannot enable */ | ||
855 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
856 | return -EBUSY; | ||
857 | } | ||
858 | } else { | ||
859 | int i; | ||
860 | |||
861 | /* Reset the interrupt mapping */ | ||
862 | for (i = 0; i < ARRAY_SIZE(pctrl->intr_lines); i++) { | ||
863 | if (pctrl->intr_lines[i] == offset) { | ||
864 | pctrl->intr_lines[i] = 0; | ||
865 | break; | ||
866 | } | ||
867 | } | ||
868 | |||
869 | /* Disable interrupt generation */ | ||
870 | reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); | ||
871 | value = readl(reg); | ||
872 | value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; | ||
873 | value &= ~CHV_PADCTRL1_INVRXTX_MASK; | ||
874 | chv_writel(value, reg); | ||
875 | |||
876 | /* Switch to a GPIO mode */ | ||
877 | reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); | ||
878 | value = readl(reg) | CHV_PADCTRL0_GPIOEN; | ||
879 | chv_writel(value, reg); | ||
880 | } | ||
881 | |||
882 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
883 | |||
884 | return 0; | ||
885 | } | ||
886 | |||
887 | static void chv_gpio_disable_free(struct pinctrl_dev *pctldev, | ||
888 | struct pinctrl_gpio_range *range, | ||
889 | unsigned offset) | ||
890 | { | ||
891 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
892 | unsigned long flags; | ||
893 | void __iomem *reg; | ||
894 | u32 value; | ||
895 | |||
896 | spin_lock_irqsave(&pctrl->lock, flags); | ||
897 | |||
898 | reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); | ||
899 | value = readl(reg) & ~CHV_PADCTRL0_GPIOEN; | ||
900 | chv_writel(value, reg); | ||
901 | |||
902 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
903 | } | ||
904 | |||
905 | static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, | ||
906 | struct pinctrl_gpio_range *range, | ||
907 | unsigned offset, bool input) | ||
908 | { | ||
909 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
910 | void __iomem *reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); | ||
911 | unsigned long flags; | ||
912 | u32 ctrl0; | ||
913 | |||
914 | spin_lock_irqsave(&pctrl->lock, flags); | ||
915 | |||
916 | ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK; | ||
917 | if (input) | ||
918 | ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; | ||
919 | else | ||
920 | ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT; | ||
921 | chv_writel(ctrl0, reg); | ||
922 | |||
923 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
924 | |||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static const struct pinmux_ops chv_pinmux_ops = { | ||
929 | .get_functions_count = chv_get_functions_count, | ||
930 | .get_function_name = chv_get_function_name, | ||
931 | .get_function_groups = chv_get_function_groups, | ||
932 | .set_mux = chv_pinmux_set_mux, | ||
933 | .gpio_request_enable = chv_gpio_request_enable, | ||
934 | .gpio_disable_free = chv_gpio_disable_free, | ||
935 | .gpio_set_direction = chv_gpio_set_direction, | ||
936 | }; | ||
937 | |||
938 | static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin, | ||
939 | unsigned long *config) | ||
940 | { | ||
941 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
942 | enum pin_config_param param = pinconf_to_config_param(*config); | ||
943 | unsigned long flags; | ||
944 | u32 ctrl0, ctrl1; | ||
945 | u16 arg = 0; | ||
946 | u32 term; | ||
947 | |||
948 | spin_lock_irqsave(&pctrl->lock, flags); | ||
949 | ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); | ||
950 | ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1)); | ||
951 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
952 | |||
953 | term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT; | ||
954 | |||
955 | switch (param) { | ||
956 | case PIN_CONFIG_BIAS_DISABLE: | ||
957 | if (term) | ||
958 | return -EINVAL; | ||
959 | break; | ||
960 | |||
961 | case PIN_CONFIG_BIAS_PULL_UP: | ||
962 | if (!(ctrl0 & CHV_PADCTRL0_TERM_UP)) | ||
963 | return -EINVAL; | ||
964 | |||
965 | switch (term) { | ||
966 | case CHV_PADCTRL0_TERM_20K: | ||
967 | arg = 20000; | ||
968 | break; | ||
969 | case CHV_PADCTRL0_TERM_5K: | ||
970 | arg = 5000; | ||
971 | break; | ||
972 | case CHV_PADCTRL0_TERM_1K: | ||
973 | arg = 1000; | ||
974 | break; | ||
975 | } | ||
976 | |||
977 | break; | ||
978 | |||
979 | case PIN_CONFIG_BIAS_PULL_DOWN: | ||
980 | if (!term || (ctrl0 & CHV_PADCTRL0_TERM_UP)) | ||
981 | return -EINVAL; | ||
982 | |||
983 | switch (term) { | ||
984 | case CHV_PADCTRL0_TERM_20K: | ||
985 | arg = 20000; | ||
986 | break; | ||
987 | case CHV_PADCTRL0_TERM_5K: | ||
988 | arg = 5000; | ||
989 | break; | ||
990 | } | ||
991 | |||
992 | break; | ||
993 | |||
994 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: | ||
995 | if (!(ctrl1 & CHV_PADCTRL1_ODEN)) | ||
996 | return -EINVAL; | ||
997 | break; | ||
998 | |||
999 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: { | ||
1000 | u32 cfg; | ||
1001 | |||
1002 | cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; | ||
1003 | cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; | ||
1004 | if (cfg != CHV_PADCTRL0_GPIOCFG_HIZ) | ||
1005 | return -EINVAL; | ||
1006 | |||
1007 | break; | ||
1008 | } | ||
1009 | |||
1010 | default: | ||
1011 | return -ENOTSUPP; | ||
1012 | } | ||
1013 | |||
1014 | *config = pinconf_to_config_packed(param, arg); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin, | ||
1019 | enum pin_config_param param, u16 arg) | ||
1020 | { | ||
1021 | void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); | ||
1022 | unsigned long flags; | ||
1023 | u32 ctrl0, pull; | ||
1024 | |||
1025 | spin_lock_irqsave(&pctrl->lock, flags); | ||
1026 | ctrl0 = readl(reg); | ||
1027 | |||
1028 | switch (param) { | ||
1029 | case PIN_CONFIG_BIAS_DISABLE: | ||
1030 | ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); | ||
1031 | break; | ||
1032 | |||
1033 | case PIN_CONFIG_BIAS_PULL_UP: | ||
1034 | ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); | ||
1035 | |||
1036 | switch (arg) { | ||
1037 | case 1000: | ||
1038 | /* For 1k there is only pull up */ | ||
1039 | pull = CHV_PADCTRL0_TERM_1K << CHV_PADCTRL0_TERM_SHIFT; | ||
1040 | break; | ||
1041 | case 5000: | ||
1042 | pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT; | ||
1043 | break; | ||
1044 | case 20000: | ||
1045 | pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; | ||
1046 | break; | ||
1047 | default: | ||
1048 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
1049 | return -EINVAL; | ||
1050 | } | ||
1051 | |||
1052 | ctrl0 |= CHV_PADCTRL0_TERM_UP | pull; | ||
1053 | break; | ||
1054 | |||
1055 | case PIN_CONFIG_BIAS_PULL_DOWN: | ||
1056 | ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); | ||
1057 | |||
1058 | switch (arg) { | ||
1059 | case 5000: | ||
1060 | pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT; | ||
1061 | break; | ||
1062 | case 20000: | ||
1063 | pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; | ||
1064 | break; | ||
1065 | default: | ||
1066 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
1067 | return -EINVAL; | ||
1068 | } | ||
1069 | |||
1070 | ctrl0 |= pull; | ||
1071 | break; | ||
1072 | |||
1073 | default: | ||
1074 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
1075 | return -EINVAL; | ||
1076 | } | ||
1077 | |||
1078 | chv_writel(ctrl0, reg); | ||
1079 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
1080 | |||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin, | ||
1085 | unsigned long *configs, unsigned nconfigs) | ||
1086 | { | ||
1087 | struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
1088 | enum pin_config_param param; | ||
1089 | int i, ret; | ||
1090 | u16 arg; | ||
1091 | |||
1092 | if (chv_pad_locked(pctrl, pin)) | ||
1093 | return -EBUSY; | ||
1094 | |||
1095 | for (i = 0; i < nconfigs; i++) { | ||
1096 | param = pinconf_to_config_param(configs[i]); | ||
1097 | arg = pinconf_to_config_argument(configs[i]); | ||
1098 | |||
1099 | switch (param) { | ||
1100 | case PIN_CONFIG_BIAS_DISABLE: | ||
1101 | case PIN_CONFIG_BIAS_PULL_UP: | ||
1102 | case PIN_CONFIG_BIAS_PULL_DOWN: | ||
1103 | ret = chv_config_set_pull(pctrl, pin, param, arg); | ||
1104 | if (ret) | ||
1105 | return ret; | ||
1106 | break; | ||
1107 | |||
1108 | default: | ||
1109 | return -ENOTSUPP; | ||
1110 | } | ||
1111 | |||
1112 | dev_dbg(pctrl->dev, "pin %d set config %d arg %u\n", pin, | ||
1113 | param, arg); | ||
1114 | } | ||
1115 | |||
1116 | return 0; | ||
1117 | } | ||
1118 | |||
1119 | static const struct pinconf_ops chv_pinconf_ops = { | ||
1120 | .is_generic = true, | ||
1121 | .pin_config_set = chv_config_set, | ||
1122 | .pin_config_get = chv_config_get, | ||
1123 | }; | ||
1124 | |||
1125 | static struct pinctrl_desc chv_pinctrl_desc = { | ||
1126 | .pctlops = &chv_pinctrl_ops, | ||
1127 | .pmxops = &chv_pinmux_ops, | ||
1128 | .confops = &chv_pinconf_ops, | ||
1129 | .owner = THIS_MODULE, | ||
1130 | }; | ||
1131 | |||
1132 | static int chv_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
1133 | { | ||
1134 | return pinctrl_request_gpio(chip->base + offset); | ||
1135 | } | ||
1136 | |||
1137 | static void chv_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
1138 | { | ||
1139 | pinctrl_free_gpio(chip->base + offset); | ||
1140 | } | ||
1141 | |||
1142 | static unsigned chv_gpio_offset_to_pin(struct chv_pinctrl *pctrl, | ||
1143 | unsigned offset) | ||
1144 | { | ||
1145 | return pctrl->community->pins[offset].number; | ||
1146 | } | ||
1147 | |||
1148 | static int chv_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
1149 | { | ||
1150 | struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(chip); | ||
1151 | int pin = chv_gpio_offset_to_pin(pctrl, offset); | ||
1152 | u32 ctrl0, cfg; | ||
1153 | |||
1154 | ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); | ||
1155 | |||
1156 | cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; | ||
1157 | cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; | ||
1158 | |||
1159 | if (cfg == CHV_PADCTRL0_GPIOCFG_GPO) | ||
1160 | return !!(ctrl0 & CHV_PADCTRL0_GPIOTXSTATE); | ||
1161 | return !!(ctrl0 & CHV_PADCTRL0_GPIORXSTATE); | ||
1162 | } | ||
1163 | |||
1164 | static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
1165 | { | ||
1166 | struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(chip); | ||
1167 | unsigned pin = chv_gpio_offset_to_pin(pctrl, offset); | ||
1168 | unsigned long flags; | ||
1169 | void __iomem *reg; | ||
1170 | u32 ctrl0; | ||
1171 | |||
1172 | spin_lock_irqsave(&pctrl->lock, flags); | ||
1173 | |||
1174 | reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); | ||
1175 | ctrl0 = readl(reg); | ||
1176 | |||
1177 | if (value) | ||
1178 | ctrl0 |= CHV_PADCTRL0_GPIOTXSTATE; | ||
1179 | else | ||
1180 | ctrl0 &= ~CHV_PADCTRL0_GPIOTXSTATE; | ||
1181 | |||
1182 | chv_writel(ctrl0, reg); | ||
1183 | |||
1184 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
1185 | } | ||
1186 | |||
1187 | static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset) | ||
1188 | { | ||
1189 | struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(chip); | ||
1190 | unsigned pin = chv_gpio_offset_to_pin(pctrl, offset); | ||
1191 | u32 ctrl0, direction; | ||
1192 | |||
1193 | ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); | ||
1194 | |||
1195 | direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; | ||
1196 | direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT; | ||
1197 | |||
1198 | return direction != CHV_PADCTRL0_GPIOCFG_GPO; | ||
1199 | } | ||
1200 | |||
1201 | static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
1202 | { | ||
1203 | return pinctrl_gpio_direction_input(chip->base + offset); | ||
1204 | } | ||
1205 | |||
1206 | static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
1207 | int value) | ||
1208 | { | ||
1209 | return pinctrl_gpio_direction_output(chip->base + offset); | ||
1210 | } | ||
1211 | |||
1212 | static const struct gpio_chip chv_gpio_chip = { | ||
1213 | .owner = THIS_MODULE, | ||
1214 | .request = chv_gpio_request, | ||
1215 | .free = chv_gpio_free, | ||
1216 | .get_direction = chv_gpio_get_direction, | ||
1217 | .direction_input = chv_gpio_direction_input, | ||
1218 | .direction_output = chv_gpio_direction_output, | ||
1219 | .get = chv_gpio_get, | ||
1220 | .set = chv_gpio_set, | ||
1221 | }; | ||
1222 | |||
1223 | static void chv_gpio_irq_ack(struct irq_data *d) | ||
1224 | { | ||
1225 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||
1226 | struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); | ||
1227 | int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d)); | ||
1228 | u32 intr_line; | ||
1229 | |||
1230 | spin_lock(&pctrl->lock); | ||
1231 | |||
1232 | intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); | ||
1233 | intr_line &= CHV_PADCTRL0_INTSEL_MASK; | ||
1234 | intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; | ||
1235 | chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT); | ||
1236 | |||
1237 | spin_unlock(&pctrl->lock); | ||
1238 | } | ||
1239 | |||
1240 | static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) | ||
1241 | { | ||
1242 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||
1243 | struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); | ||
1244 | int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d)); | ||
1245 | u32 value, intr_line; | ||
1246 | unsigned long flags; | ||
1247 | |||
1248 | spin_lock_irqsave(&pctrl->lock, flags); | ||
1249 | |||
1250 | intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); | ||
1251 | intr_line &= CHV_PADCTRL0_INTSEL_MASK; | ||
1252 | intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; | ||
1253 | |||
1254 | value = readl(pctrl->regs + CHV_INTMASK); | ||
1255 | if (mask) | ||
1256 | value &= ~BIT(intr_line); | ||
1257 | else | ||
1258 | value |= BIT(intr_line); | ||
1259 | chv_writel(value, pctrl->regs + CHV_INTMASK); | ||
1260 | |||
1261 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
1262 | } | ||
1263 | |||
1264 | static void chv_gpio_irq_mask(struct irq_data *d) | ||
1265 | { | ||
1266 | chv_gpio_irq_mask_unmask(d, true); | ||
1267 | } | ||
1268 | |||
1269 | static void chv_gpio_irq_unmask(struct irq_data *d) | ||
1270 | { | ||
1271 | chv_gpio_irq_mask_unmask(d, false); | ||
1272 | } | ||
1273 | |||
1274 | static int chv_gpio_irq_type(struct irq_data *d, unsigned type) | ||
1275 | { | ||
1276 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||
1277 | struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); | ||
1278 | unsigned offset = irqd_to_hwirq(d); | ||
1279 | int pin = chv_gpio_offset_to_pin(pctrl, offset); | ||
1280 | unsigned long flags; | ||
1281 | u32 value; | ||
1282 | |||
1283 | spin_lock_irqsave(&pctrl->lock, flags); | ||
1284 | |||
1285 | /* | ||
1286 | * Pins which can be used as shared interrupt are configured in | ||
1287 | * BIOS. Driver trusts BIOS configurations and assigns different | ||
1288 | * handler according to the irq type. | ||
1289 | * | ||
1290 | * Driver needs to save the mapping between each pin and | ||
1291 | * its interrupt line. | ||
1292 | * 1. If the pin cfg is locked in BIOS: | ||
1293 | * Trust BIOS has programmed IntWakeCfg bits correctly, | ||
1294 | * driver just needs to save the mapping. | ||
1295 | * 2. If the pin cfg is not locked in BIOS: | ||
1296 | * Driver programs the IntWakeCfg bits and save the mapping. | ||
1297 | */ | ||
1298 | if (!chv_pad_locked(pctrl, pin)) { | ||
1299 | void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); | ||
1300 | |||
1301 | value = readl(reg); | ||
1302 | value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; | ||
1303 | value &= ~CHV_PADCTRL1_INVRXTX_MASK; | ||
1304 | |||
1305 | if (type & IRQ_TYPE_EDGE_BOTH) { | ||
1306 | if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) | ||
1307 | value |= CHV_PADCTRL1_INTWAKECFG_BOTH; | ||
1308 | else if (type & IRQ_TYPE_EDGE_RISING) | ||
1309 | value |= CHV_PADCTRL1_INTWAKECFG_RISING; | ||
1310 | else if (type & IRQ_TYPE_EDGE_FALLING) | ||
1311 | value |= CHV_PADCTRL1_INTWAKECFG_FALLING; | ||
1312 | } else if (type & IRQ_TYPE_LEVEL_MASK) { | ||
1313 | value |= CHV_PADCTRL1_INTWAKECFG_LEVEL; | ||
1314 | if (type & IRQ_TYPE_LEVEL_LOW) | ||
1315 | value |= CHV_PADCTRL1_INVRXTX_RXDATA; | ||
1316 | } | ||
1317 | |||
1318 | chv_writel(value, reg); | ||
1319 | } | ||
1320 | |||
1321 | value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); | ||
1322 | value &= CHV_PADCTRL0_INTSEL_MASK; | ||
1323 | value >>= CHV_PADCTRL0_INTSEL_SHIFT; | ||
1324 | |||
1325 | pctrl->intr_lines[value] = offset; | ||
1326 | |||
1327 | if (type & IRQ_TYPE_EDGE_BOTH) | ||
1328 | __irq_set_handler_locked(d->irq, handle_edge_irq); | ||
1329 | else if (type & IRQ_TYPE_LEVEL_MASK) | ||
1330 | __irq_set_handler_locked(d->irq, handle_level_irq); | ||
1331 | |||
1332 | spin_unlock_irqrestore(&pctrl->lock, flags); | ||
1333 | |||
1334 | return 0; | ||
1335 | } | ||
1336 | |||
1337 | static struct irq_chip chv_gpio_irqchip = { | ||
1338 | .name = "chv-gpio", | ||
1339 | .irq_ack = chv_gpio_irq_ack, | ||
1340 | .irq_mask = chv_gpio_irq_mask, | ||
1341 | .irq_unmask = chv_gpio_irq_unmask, | ||
1342 | .irq_set_type = chv_gpio_irq_type, | ||
1343 | .flags = IRQCHIP_SKIP_SET_WAKE, | ||
1344 | }; | ||
1345 | |||
1346 | static void chv_gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
1347 | { | ||
1348 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); | ||
1349 | struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); | ||
1350 | struct irq_chip *chip = irq_get_chip(irq); | ||
1351 | unsigned long pending; | ||
1352 | u32 intr_line; | ||
1353 | |||
1354 | chained_irq_enter(chip, desc); | ||
1355 | |||
1356 | pending = readl(pctrl->regs + CHV_INTSTAT); | ||
1357 | for_each_set_bit(intr_line, &pending, 16) { | ||
1358 | unsigned irq, offset; | ||
1359 | |||
1360 | offset = pctrl->intr_lines[intr_line]; | ||
1361 | irq = irq_find_mapping(gc->irqdomain, offset); | ||
1362 | generic_handle_irq(irq); | ||
1363 | } | ||
1364 | |||
1365 | chained_irq_exit(chip, desc); | ||
1366 | } | ||
1367 | |||
1368 | static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) | ||
1369 | { | ||
1370 | const struct chv_gpio_pinrange *range; | ||
1371 | struct gpio_chip *chip = &pctrl->chip; | ||
1372 | int ret, i, offset; | ||
1373 | |||
1374 | *chip = chv_gpio_chip; | ||
1375 | |||
1376 | chip->ngpio = pctrl->community->ngpios; | ||
1377 | chip->label = dev_name(pctrl->dev); | ||
1378 | chip->dev = pctrl->dev; | ||
1379 | chip->base = -1; | ||
1380 | |||
1381 | ret = gpiochip_add(chip); | ||
1382 | if (ret) { | ||
1383 | dev_err(pctrl->dev, "Failed to register gpiochip\n"); | ||
1384 | return ret; | ||
1385 | } | ||
1386 | |||
1387 | for (i = 0, offset = 0; i < pctrl->community->ngpio_ranges; i++) { | ||
1388 | range = &pctrl->community->gpio_ranges[i]; | ||
1389 | ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), offset, | ||
1390 | range->base, range->npins); | ||
1391 | if (ret) { | ||
1392 | dev_err(pctrl->dev, "failed to add GPIO pin range\n"); | ||
1393 | goto fail; | ||
1394 | } | ||
1395 | |||
1396 | offset += range->npins; | ||
1397 | } | ||
1398 | |||
1399 | /* Mask and clear all interrupts */ | ||
1400 | chv_writel(0, pctrl->regs + CHV_INTMASK); | ||
1401 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); | ||
1402 | |||
1403 | ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0, | ||
1404 | handle_simple_irq, IRQ_TYPE_NONE); | ||
1405 | if (ret) { | ||
1406 | dev_err(pctrl->dev, "failed to add IRQ chip\n"); | ||
1407 | goto fail; | ||
1408 | } | ||
1409 | |||
1410 | gpiochip_set_chained_irqchip(chip, &chv_gpio_irqchip, irq, | ||
1411 | chv_gpio_irq_handler); | ||
1412 | return 0; | ||
1413 | |||
1414 | fail: | ||
1415 | gpiochip_remove(chip); | ||
1416 | |||
1417 | return ret; | ||
1418 | } | ||
1419 | |||
1420 | static int chv_pinctrl_probe(struct platform_device *pdev) | ||
1421 | { | ||
1422 | struct chv_pinctrl *pctrl; | ||
1423 | struct acpi_device *adev; | ||
1424 | struct resource *res; | ||
1425 | int ret, irq, i; | ||
1426 | |||
1427 | adev = ACPI_COMPANION(&pdev->dev); | ||
1428 | if (!adev) | ||
1429 | return -ENODEV; | ||
1430 | |||
1431 | pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); | ||
1432 | if (!pctrl) | ||
1433 | return -ENOMEM; | ||
1434 | |||
1435 | for (i = 0; i < ARRAY_SIZE(chv_communities); i++) | ||
1436 | if (!strcmp(adev->pnp.unique_id, chv_communities[i]->uid)) { | ||
1437 | pctrl->community = chv_communities[i]; | ||
1438 | break; | ||
1439 | } | ||
1440 | if (i == ARRAY_SIZE(chv_communities)) | ||
1441 | return -ENODEV; | ||
1442 | |||
1443 | spin_lock_init(&pctrl->lock); | ||
1444 | pctrl->dev = &pdev->dev; | ||
1445 | |||
1446 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1447 | pctrl->regs = devm_ioremap_resource(&pdev->dev, res); | ||
1448 | if (IS_ERR(pctrl->regs)) | ||
1449 | return PTR_ERR(pctrl->regs); | ||
1450 | |||
1451 | irq = platform_get_irq(pdev, 0); | ||
1452 | if (irq < 0) { | ||
1453 | dev_err(&pdev->dev, "failed to get interrupt number\n"); | ||
1454 | return irq; | ||
1455 | } | ||
1456 | |||
1457 | pctrl->pctldesc = chv_pinctrl_desc; | ||
1458 | pctrl->pctldesc.name = dev_name(&pdev->dev); | ||
1459 | pctrl->pctldesc.pins = pctrl->community->pins; | ||
1460 | pctrl->pctldesc.npins = pctrl->community->npins; | ||
1461 | |||
1462 | pctrl->pctldev = pinctrl_register(&pctrl->pctldesc, &pdev->dev, pctrl); | ||
1463 | if (!pctrl->pctldev) { | ||
1464 | dev_err(&pdev->dev, "failed to register pinctrl driver\n"); | ||
1465 | return -ENODEV; | ||
1466 | } | ||
1467 | |||
1468 | ret = chv_gpio_probe(pctrl, irq); | ||
1469 | if (ret) { | ||
1470 | pinctrl_unregister(pctrl->pctldev); | ||
1471 | return ret; | ||
1472 | } | ||
1473 | |||
1474 | platform_set_drvdata(pdev, pctrl); | ||
1475 | |||
1476 | return 0; | ||
1477 | } | ||
1478 | |||
1479 | static int chv_pinctrl_remove(struct platform_device *pdev) | ||
1480 | { | ||
1481 | struct chv_pinctrl *pctrl = platform_get_drvdata(pdev); | ||
1482 | |||
1483 | gpiochip_remove(&pctrl->chip); | ||
1484 | pinctrl_unregister(pctrl->pctldev); | ||
1485 | |||
1486 | return 0; | ||
1487 | } | ||
1488 | |||
1489 | static const struct acpi_device_id chv_pinctrl_acpi_match[] = { | ||
1490 | { "INT33FF" }, | ||
1491 | { } | ||
1492 | }; | ||
1493 | MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match); | ||
1494 | |||
1495 | static struct platform_driver chv_pinctrl_driver = { | ||
1496 | .probe = chv_pinctrl_probe, | ||
1497 | .remove = chv_pinctrl_remove, | ||
1498 | .driver = { | ||
1499 | .name = "cherryview-pinctrl", | ||
1500 | .owner = THIS_MODULE, | ||
1501 | .acpi_match_table = chv_pinctrl_acpi_match, | ||
1502 | }, | ||
1503 | }; | ||
1504 | |||
1505 | static int __init chv_pinctrl_init(void) | ||
1506 | { | ||
1507 | return platform_driver_register(&chv_pinctrl_driver); | ||
1508 | } | ||
1509 | subsys_initcall(chv_pinctrl_init); | ||
1510 | |||
1511 | static void __exit chv_pinctrl_exit(void) | ||
1512 | { | ||
1513 | platform_driver_unregister(&chv_pinctrl_driver); | ||
1514 | } | ||
1515 | module_exit(chv_pinctrl_exit); | ||
1516 | |||
1517 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); | ||
1518 | MODULE_DESCRIPTION("Intel Cherryview/Braswell pinctrl driver"); | ||
1519 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 228972827132..e1087c75e4f4 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c | |||
@@ -891,14 +891,13 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
891 | const char *function = NULL; | 891 | const char *function = NULL; |
892 | unsigned long *configs; | 892 | unsigned long *configs; |
893 | unsigned int nconfigs = 0; | 893 | unsigned int nconfigs = 0; |
894 | bool has_config = 0; | ||
895 | struct property *prop; | 894 | struct property *prop; |
896 | const char *group, *gpio_name; | ||
897 | struct device_node *np_config; | ||
898 | 895 | ||
899 | ret = of_property_read_string(np, "ste,function", &function); | 896 | ret = of_property_read_string(np, "function", &function); |
900 | if (ret >= 0) { | 897 | if (ret >= 0) { |
901 | ret = of_property_count_strings(np, "ste,pins"); | 898 | const char *group; |
899 | |||
900 | ret = of_property_count_strings(np, "groups"); | ||
902 | if (ret < 0) | 901 | if (ret < 0) |
903 | goto exit; | 902 | goto exit; |
904 | 903 | ||
@@ -907,7 +906,7 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
907 | if (ret < 0) | 906 | if (ret < 0) |
908 | goto exit; | 907 | goto exit; |
909 | 908 | ||
910 | of_property_for_each_string(np, "ste,pins", prop, group) { | 909 | of_property_for_each_string(np, "groups", prop, group) { |
911 | ret = abx500_dt_add_map_mux(map, reserved_maps, | 910 | ret = abx500_dt_add_map_mux(map, reserved_maps, |
912 | num_maps, group, function); | 911 | num_maps, group, function); |
913 | if (ret < 0) | 912 | if (ret < 0) |
@@ -916,18 +915,11 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
916 | } | 915 | } |
917 | 916 | ||
918 | ret = pinconf_generic_parse_dt_config(np, &configs, &nconfigs); | 917 | ret = pinconf_generic_parse_dt_config(np, &configs, &nconfigs); |
919 | if (nconfigs) | 918 | if (nconfigs) { |
920 | has_config = 1; | 919 | const char *gpio_name; |
921 | np_config = of_parse_phandle(np, "ste,config", 0); | 920 | const char *pin; |
922 | if (np_config) { | 921 | |
923 | ret = pinconf_generic_parse_dt_config(np_config, &configs, | 922 | ret = of_property_count_strings(np, "pins"); |
924 | &nconfigs); | ||
925 | if (ret) | ||
926 | goto exit; | ||
927 | has_config |= nconfigs; | ||
928 | } | ||
929 | if (has_config) { | ||
930 | ret = of_property_count_strings(np, "ste,pins"); | ||
931 | if (ret < 0) | 923 | if (ret < 0) |
932 | goto exit; | 924 | goto exit; |
933 | 925 | ||
@@ -937,8 +929,8 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
937 | if (ret < 0) | 929 | if (ret < 0) |
938 | goto exit; | 930 | goto exit; |
939 | 931 | ||
940 | of_property_for_each_string(np, "ste,pins", prop, group) { | 932 | of_property_for_each_string(np, "pins", prop, pin) { |
941 | gpio_name = abx500_find_pin_name(pctldev, group); | 933 | gpio_name = abx500_find_pin_name(pctldev, pin); |
942 | 934 | ||
943 | ret = abx500_dt_add_map_configs(map, reserved_maps, | 935 | ret = abx500_dt_add_map_configs(map, reserved_maps, |
944 | num_maps, gpio_name, configs, 1); | 936 | num_maps, gpio_name, configs, 1); |
@@ -1112,6 +1104,7 @@ out: | |||
1112 | static const struct pinconf_ops abx500_pinconf_ops = { | 1104 | static const struct pinconf_ops abx500_pinconf_ops = { |
1113 | .pin_config_get = abx500_pin_config_get, | 1105 | .pin_config_get = abx500_pin_config_get, |
1114 | .pin_config_set = abx500_pin_config_set, | 1106 | .pin_config_set = abx500_pin_config_set, |
1107 | .is_generic = true, | ||
1115 | }; | 1108 | }; |
1116 | 1109 | ||
1117 | static struct pinctrl_desc abx500_pinctrl_desc = { | 1110 | static struct pinctrl_desc abx500_pinctrl_desc = { |
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c index ed39dcafd4f8..2cd71470f270 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c | |||
@@ -291,6 +291,7 @@ static const unsigned u0_a_1_pins[] = { STN8815_PIN_B4, STN8815_PIN_D5, | |||
291 | static const unsigned mmcsd_a_1_pins[] = { STN8815_PIN_B10, STN8815_PIN_A10, | 291 | static const unsigned mmcsd_a_1_pins[] = { STN8815_PIN_B10, STN8815_PIN_A10, |
292 | STN8815_PIN_C11, STN8815_PIN_B11, STN8815_PIN_A11, STN8815_PIN_C12, | 292 | STN8815_PIN_C11, STN8815_PIN_B11, STN8815_PIN_A11, STN8815_PIN_C12, |
293 | STN8815_PIN_B12, STN8815_PIN_A12, STN8815_PIN_C13, STN8815_PIN_C15 }; | 293 | STN8815_PIN_B12, STN8815_PIN_A12, STN8815_PIN_C13, STN8815_PIN_C15 }; |
294 | static const unsigned mmcsd_b_1_pins[] = { STN8815_PIN_D15 }; | ||
294 | static const unsigned u1_a_1_pins[] = { STN8815_PIN_M2, STN8815_PIN_L1, | 295 | static const unsigned u1_a_1_pins[] = { STN8815_PIN_M2, STN8815_PIN_L1, |
295 | STN8815_PIN_F3, STN8815_PIN_F2 }; | 296 | STN8815_PIN_F3, STN8815_PIN_F2 }; |
296 | static const unsigned i2c1_a_1_pins[] = { STN8815_PIN_L4, STN8815_PIN_L3 }; | 297 | static const unsigned i2c1_a_1_pins[] = { STN8815_PIN_L4, STN8815_PIN_L3 }; |
@@ -305,6 +306,7 @@ static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 }; | |||
305 | static const struct nmk_pingroup nmk_stn8815_groups[] = { | 306 | static const struct nmk_pingroup nmk_stn8815_groups[] = { |
306 | STN8815_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A), | 307 | STN8815_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A), |
307 | STN8815_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A), | 308 | STN8815_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A), |
309 | STN8815_PIN_GROUP(mmcsd_b_1, NMK_GPIO_ALT_B), | ||
308 | STN8815_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A), | 310 | STN8815_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A), |
309 | STN8815_PIN_GROUP(i2c1_a_1, NMK_GPIO_ALT_A), | 311 | STN8815_PIN_GROUP(i2c1_a_1, NMK_GPIO_ALT_A), |
310 | STN8815_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), | 312 | STN8815_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), |
@@ -317,7 +319,7 @@ static const struct nmk_pingroup nmk_stn8815_groups[] = { | |||
317 | static const char * const a##_groups[] = { b }; | 319 | static const char * const a##_groups[] = { b }; |
318 | 320 | ||
319 | STN8815_FUNC_GROUPS(u0, "u0_a_1"); | 321 | STN8815_FUNC_GROUPS(u0, "u0_a_1"); |
320 | STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1"); | 322 | STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1", "mmcsd_b_1"); |
321 | STN8815_FUNC_GROUPS(u1, "u1_a_1", "u1_b_1"); | 323 | STN8815_FUNC_GROUPS(u1, "u1_a_1", "u1_b_1"); |
322 | STN8815_FUNC_GROUPS(i2c1, "i2c1_a_1"); | 324 | STN8815_FUNC_GROUPS(i2c1, "i2c1_a_1"); |
323 | STN8815_FUNC_GROUPS(i2c0, "i2c0_a_1"); | 325 | STN8815_FUNC_GROUPS(i2c0, "i2c0_a_1"); |
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 746db6acf648..ad99ba886e50 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c | |||
@@ -1520,12 +1520,13 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
1520 | unsigned long configs = 0; | 1520 | unsigned long configs = 0; |
1521 | bool has_config = 0; | 1521 | bool has_config = 0; |
1522 | struct property *prop; | 1522 | struct property *prop; |
1523 | const char *group, *gpio_name; | ||
1524 | struct device_node *np_config; | 1523 | struct device_node *np_config; |
1525 | 1524 | ||
1526 | ret = of_property_read_string(np, "ste,function", &function); | 1525 | ret = of_property_read_string(np, "function", &function); |
1527 | if (ret >= 0) { | 1526 | if (ret >= 0) { |
1528 | ret = of_property_count_strings(np, "ste,pins"); | 1527 | const char *group; |
1528 | |||
1529 | ret = of_property_count_strings(np, "groups"); | ||
1529 | if (ret < 0) | 1530 | if (ret < 0) |
1530 | goto exit; | 1531 | goto exit; |
1531 | 1532 | ||
@@ -1535,7 +1536,7 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
1535 | if (ret < 0) | 1536 | if (ret < 0) |
1536 | goto exit; | 1537 | goto exit; |
1537 | 1538 | ||
1538 | of_property_for_each_string(np, "ste,pins", prop, group) { | 1539 | of_property_for_each_string(np, "groups", prop, group) { |
1539 | ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps, | 1540 | ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps, |
1540 | group, function); | 1541 | group, function); |
1541 | if (ret < 0) | 1542 | if (ret < 0) |
@@ -1548,7 +1549,10 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
1548 | if (np_config) | 1549 | if (np_config) |
1549 | has_config |= nmk_pinctrl_dt_get_config(np_config, &configs); | 1550 | has_config |= nmk_pinctrl_dt_get_config(np_config, &configs); |
1550 | if (has_config) { | 1551 | if (has_config) { |
1551 | ret = of_property_count_strings(np, "ste,pins"); | 1552 | const char *gpio_name; |
1553 | const char *pin; | ||
1554 | |||
1555 | ret = of_property_count_strings(np, "pins"); | ||
1552 | if (ret < 0) | 1556 | if (ret < 0) |
1553 | goto exit; | 1557 | goto exit; |
1554 | ret = pinctrl_utils_reserve_map(pctldev, map, | 1558 | ret = pinctrl_utils_reserve_map(pctldev, map, |
@@ -1557,8 +1561,8 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
1557 | if (ret < 0) | 1561 | if (ret < 0) |
1558 | goto exit; | 1562 | goto exit; |
1559 | 1563 | ||
1560 | of_property_for_each_string(np, "ste,pins", prop, group) { | 1564 | of_property_for_each_string(np, "pins", prop, pin) { |
1561 | gpio_name = nmk_find_pin_name(pctldev, group); | 1565 | gpio_name = nmk_find_pin_name(pctldev, pin); |
1562 | 1566 | ||
1563 | ret = nmk_dt_add_map_configs(map, reserved_maps, | 1567 | ret = nmk_dt_add_map_configs(map, reserved_maps, |
1564 | num_maps, | 1568 | num_maps, |
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 29ff77f90fcb..f78b416d7984 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c | |||
@@ -32,30 +32,32 @@ struct pin_config_item { | |||
32 | const enum pin_config_param param; | 32 | const enum pin_config_param param; |
33 | const char * const display; | 33 | const char * const display; |
34 | const char * const format; | 34 | const char * const format; |
35 | bool has_arg; | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | #define PCONFDUMP(a, b, c) { .param = a, .display = b, .format = c } | 38 | #define PCONFDUMP(a, b, c, d) { .param = a, .display = b, .format = c, \ |
39 | .has_arg = d } | ||
38 | 40 | ||
39 | static struct pin_config_item conf_items[] = { | 41 | static const struct pin_config_item conf_items[] = { |
40 | PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL), | 42 | PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL, false), |
41 | PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL), | 43 | PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL, false), |
42 | PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL), | 44 | PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL, false), |
43 | PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL), | 45 | PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false), |
44 | PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL), | 46 | PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL, false), |
45 | PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, | 47 | PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, |
46 | "input bias pull to pin specific state", NULL), | 48 | "input bias pull to pin specific state", NULL, false), |
47 | PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL), | 49 | PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false), |
48 | PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL), | 50 | PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false), |
49 | PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL), | 51 | PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false), |
50 | PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA"), | 52 | PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA", true), |
51 | PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", NULL), | 53 | PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", NULL, false), |
52 | PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL), | 54 | PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL, false), |
53 | PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL), | 55 | PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL, false), |
54 | PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "usec"), | 56 | PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "usec", true), |
55 | PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"), | 57 | PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector", true), |
56 | PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL), | 58 | PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL, true), |
57 | PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"), | 59 | PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode", true), |
58 | PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level"), | 60 | PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level", true), |
59 | }; | 61 | }; |
60 | 62 | ||
61 | void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, | 63 | void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, |
@@ -85,11 +87,14 @@ void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, | |||
85 | seq_puts(s, " "); | 87 | seq_puts(s, " "); |
86 | seq_puts(s, conf_items[i].display); | 88 | seq_puts(s, conf_items[i].display); |
87 | /* Print unit if available */ | 89 | /* Print unit if available */ |
88 | if (conf_items[i].format && | 90 | if (conf_items[i].has_arg) { |
89 | pinconf_to_config_argument(config) != 0) | 91 | seq_printf(s, " (%u", |
90 | seq_printf(s, " (%u %s)", | 92 | pinconf_to_config_argument(config)); |
91 | pinconf_to_config_argument(config), | 93 | if (conf_items[i].format) |
92 | conf_items[i].format); | 94 | seq_printf(s, " %s)", conf_items[i].format); |
95 | else | ||
96 | seq_puts(s, ")"); | ||
97 | } | ||
93 | } | 98 | } |
94 | } | 99 | } |
95 | 100 | ||
@@ -121,10 +126,14 @@ void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, | |||
121 | seq_puts(s, " "); | 126 | seq_puts(s, " "); |
122 | seq_puts(s, conf_items[i].display); | 127 | seq_puts(s, conf_items[i].display); |
123 | /* Print unit if available */ | 128 | /* Print unit if available */ |
124 | if (conf_items[i].format && config != 0) | 129 | if (conf_items[i].has_arg) { |
125 | seq_printf(s, " (%u %s)", | 130 | seq_printf(s, " (%u", |
126 | pinconf_to_config_argument(config), | 131 | pinconf_to_config_argument(config)); |
127 | conf_items[i].format); | 132 | if (conf_items[i].format) |
133 | seq_printf(s, " %s)", conf_items[i].format); | ||
134 | else | ||
135 | seq_puts(s, ")"); | ||
136 | } | ||
128 | } | 137 | } |
129 | } | 138 | } |
130 | 139 | ||
@@ -150,7 +159,7 @@ struct pinconf_generic_dt_params { | |||
150 | u32 default_value; | 159 | u32 default_value; |
151 | }; | 160 | }; |
152 | 161 | ||
153 | static struct pinconf_generic_dt_params dt_params[] = { | 162 | static const struct pinconf_generic_dt_params dt_params[] = { |
154 | { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, | 163 | { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, |
155 | { "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 }, | 164 | { "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 }, |
156 | { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, | 165 | { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, |
@@ -200,7 +209,7 @@ int pinconf_generic_parse_dt_config(struct device_node *np, | |||
200 | return -ENOMEM; | 209 | return -ENOMEM; |
201 | 210 | ||
202 | for (i = 0; i < ARRAY_SIZE(dt_params); i++) { | 211 | for (i = 0; i < ARRAY_SIZE(dt_params); i++) { |
203 | struct pinconf_generic_dt_params *par = &dt_params[i]; | 212 | const struct pinconf_generic_dt_params *par = &dt_params[i]; |
204 | ret = of_property_read_u32(np, par->property, &val); | 213 | ret = of_property_read_u32(np, par->property, &val); |
205 | 214 | ||
206 | /* property not found */ | 215 | /* property not found */ |
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 354a81d40925..66db9849aca8 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c | |||
@@ -25,9 +25,7 @@ | |||
25 | /* Since we request GPIOs from ourself */ | 25 | /* Since we request GPIOs from ourself */ |
26 | #include <linux/pinctrl/consumer.h> | 26 | #include <linux/pinctrl/consumer.h> |
27 | 27 | ||
28 | #include <mach/hardware.h> | 28 | #include "pinctrl-at91.h" |
29 | #include <mach/at91_pio.h> | ||
30 | |||
31 | #include "core.h" | 29 | #include "core.h" |
32 | 30 | ||
33 | #define MAX_GPIO_BANKS 5 | 31 | #define MAX_GPIO_BANKS 5 |
@@ -1344,7 +1342,6 @@ static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
1344 | for (i = 0; i < chip->ngpio; i++) { | 1342 | for (i = 0; i < chip->ngpio; i++) { |
1345 | unsigned mask = pin_to_mask(i); | 1343 | unsigned mask = pin_to_mask(i); |
1346 | const char *gpio_label; | 1344 | const char *gpio_label; |
1347 | u32 pdsr; | ||
1348 | 1345 | ||
1349 | gpio_label = gpiochip_is_requested(chip, i); | 1346 | gpio_label = gpiochip_is_requested(chip, i); |
1350 | if (!gpio_label) | 1347 | if (!gpio_label) |
@@ -1353,11 +1350,13 @@ static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
1353 | seq_printf(s, "[%s] GPIO%s%d: ", | 1350 | seq_printf(s, "[%s] GPIO%s%d: ", |
1354 | gpio_label, chip->label, i); | 1351 | gpio_label, chip->label, i); |
1355 | if (mode == AT91_MUX_GPIO) { | 1352 | if (mode == AT91_MUX_GPIO) { |
1356 | pdsr = readl_relaxed(pio + PIO_PDSR); | 1353 | seq_printf(s, "[gpio] "); |
1357 | 1354 | seq_printf(s, "%s ", | |
1358 | seq_printf(s, "[gpio] %s\n", | 1355 | readl_relaxed(pio + PIO_OSR) & mask ? |
1359 | pdsr & mask ? | 1356 | "output" : "input"); |
1360 | "set" : "clear"); | 1357 | seq_printf(s, "%s\n", |
1358 | readl_relaxed(pio + PIO_PDSR) & mask ? | ||
1359 | "set" : "clear"); | ||
1361 | } else { | 1360 | } else { |
1362 | seq_printf(s, "[periph %c]\n", | 1361 | seq_printf(s, "[periph %c]\n", |
1363 | mode + 'A' - 1); | 1362 | mode + 'A' - 1); |
diff --git a/drivers/pinctrl/pinctrl-at91.h b/drivers/pinctrl/pinctrl-at91.h new file mode 100644 index 000000000000..79b957f1dfa2 --- /dev/null +++ b/drivers/pinctrl/pinctrl-at91.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Ivan Kokshaysky | ||
3 | * Copyright (C) SAN People | ||
4 | * | ||
5 | * Parallel I/O Controller (PIO) - System peripherals registers. | ||
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 | #ifndef __PINCTRL_AT91_H | ||
14 | #define __PINCTRL_AT91_H | ||
15 | |||
16 | #define PIO_PER 0x00 /* Enable Register */ | ||
17 | #define PIO_PDR 0x04 /* Disable Register */ | ||
18 | #define PIO_PSR 0x08 /* Status Register */ | ||
19 | #define PIO_OER 0x10 /* Output Enable Register */ | ||
20 | #define PIO_ODR 0x14 /* Output Disable Register */ | ||
21 | #define PIO_OSR 0x18 /* Output Status Register */ | ||
22 | #define PIO_IFER 0x20 /* Glitch Input Filter Enable */ | ||
23 | #define PIO_IFDR 0x24 /* Glitch Input Filter Disable */ | ||
24 | #define PIO_IFSR 0x28 /* Glitch Input Filter Status */ | ||
25 | #define PIO_SODR 0x30 /* Set Output Data Register */ | ||
26 | #define PIO_CODR 0x34 /* Clear Output Data Register */ | ||
27 | #define PIO_ODSR 0x38 /* Output Data Status Register */ | ||
28 | #define PIO_PDSR 0x3c /* Pin Data Status Register */ | ||
29 | #define PIO_IER 0x40 /* Interrupt Enable Register */ | ||
30 | #define PIO_IDR 0x44 /* Interrupt Disable Register */ | ||
31 | #define PIO_IMR 0x48 /* Interrupt Mask Register */ | ||
32 | #define PIO_ISR 0x4c /* Interrupt Status Register */ | ||
33 | #define PIO_MDER 0x50 /* Multi-driver Enable Register */ | ||
34 | #define PIO_MDDR 0x54 /* Multi-driver Disable Register */ | ||
35 | #define PIO_MDSR 0x58 /* Multi-driver Status Register */ | ||
36 | #define PIO_PUDR 0x60 /* Pull-up Disable Register */ | ||
37 | #define PIO_PUER 0x64 /* Pull-up Enable Register */ | ||
38 | #define PIO_PUSR 0x68 /* Pull-up Status Register */ | ||
39 | #define PIO_ASR 0x70 /* Peripheral A Select Register */ | ||
40 | #define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 [some sam9 only] */ | ||
41 | #define PIO_BSR 0x74 /* Peripheral B Select Register */ | ||
42 | #define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 [some sam9 only] */ | ||
43 | #define PIO_ABSR 0x78 /* AB Status Register */ | ||
44 | #define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */ | ||
45 | #define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */ | ||
46 | #define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */ | ||
47 | #define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */ | ||
48 | #define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */ | ||
49 | #define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */ | ||
50 | #define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */ | ||
51 | #define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */ | ||
52 | #define PIO_OWER 0xa0 /* Output Write Enable Register */ | ||
53 | #define PIO_OWDR 0xa4 /* Output Write Disable Register */ | ||
54 | #define PIO_OWSR 0xa8 /* Output Write Status Register */ | ||
55 | #define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */ | ||
56 | #define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */ | ||
57 | #define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */ | ||
58 | #define PIO_ESR 0xc0 /* Edge Select Register */ | ||
59 | #define PIO_LSR 0xc4 /* Level Select Register */ | ||
60 | #define PIO_ELSR 0xc8 /* Edge/Level Status Register */ | ||
61 | #define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */ | ||
62 | #define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */ | ||
63 | #define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */ | ||
64 | #define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */ | ||
65 | |||
66 | #define SAMA5D3_PIO_DRIVER1 0x118 /*PIO Driver 1 register offset*/ | ||
67 | #define SAMA5D3_PIO_DRIVER2 0x11C /*PIO Driver 2 register offset*/ | ||
68 | |||
69 | #define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/ | ||
70 | #define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/ | ||
71 | |||
72 | #endif | ||
diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c index a26e0c2ba33e..2b25047fef8d 100644 --- a/drivers/pinctrl/pinctrl-bcm281xx.c +++ b/drivers/pinctrl/pinctrl-bcm281xx.c | |||
@@ -1404,11 +1404,6 @@ static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev) | |||
1404 | 1404 | ||
1405 | /* So far We can assume there is only 1 bank of registers */ | 1405 | /* So far We can assume there is only 1 bank of registers */ |
1406 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1406 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1407 | if (!res) { | ||
1408 | dev_err(&pdev->dev, "Missing MEM resource\n"); | ||
1409 | return -ENODEV; | ||
1410 | } | ||
1411 | |||
1412 | pdata->reg_base = devm_ioremap_resource(&pdev->dev, res); | 1407 | pdata->reg_base = devm_ioremap_resource(&pdev->dev, res); |
1413 | if (IS_ERR(pdata->reg_base)) { | 1408 | if (IS_ERR(pdata->reg_base)) { |
1414 | dev_err(&pdev->dev, "Failed to ioremap MEM resource\n"); | 1409 | dev_err(&pdev->dev, "Failed to ioremap MEM resource\n"); |
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 016f4578e494..40970c305dd0 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c | |||
@@ -856,27 +856,22 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, | |||
856 | * leads to this function call (via the pinctrl_gpio_direction_{input|output}() | 856 | * leads to this function call (via the pinctrl_gpio_direction_{input|output}() |
857 | * function called from the gpiolib interface). | 857 | * function called from the gpiolib interface). |
858 | */ | 858 | */ |
859 | static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | 859 | static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip, |
860 | struct pinctrl_gpio_range *range, | 860 | int pin, bool input) |
861 | unsigned offset, bool input) | ||
862 | { | 861 | { |
863 | struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
864 | struct rockchip_pin_bank *bank; | 862 | struct rockchip_pin_bank *bank; |
865 | struct gpio_chip *chip; | 863 | int ret; |
866 | int pin, ret; | 864 | unsigned long flags; |
867 | u32 data; | 865 | u32 data; |
868 | 866 | ||
869 | chip = range->gc; | ||
870 | bank = gc_to_pin_bank(chip); | 867 | bank = gc_to_pin_bank(chip); |
871 | pin = offset - chip->base; | ||
872 | |||
873 | dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", | ||
874 | offset, range->name, pin, input ? "input" : "output"); | ||
875 | 868 | ||
876 | ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); | 869 | ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); |
877 | if (ret < 0) | 870 | if (ret < 0) |
878 | return ret; | 871 | return ret; |
879 | 872 | ||
873 | spin_lock_irqsave(&bank->slock, flags); | ||
874 | |||
880 | data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); | 875 | data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); |
881 | /* set bit to 1 for output, 0 for input */ | 876 | /* set bit to 1 for output, 0 for input */ |
882 | if (!input) | 877 | if (!input) |
@@ -885,9 +880,28 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | |||
885 | data &= ~BIT(pin); | 880 | data &= ~BIT(pin); |
886 | writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); | 881 | writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); |
887 | 882 | ||
883 | spin_unlock_irqrestore(&bank->slock, flags); | ||
884 | |||
888 | return 0; | 885 | return 0; |
889 | } | 886 | } |
890 | 887 | ||
888 | static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | ||
889 | struct pinctrl_gpio_range *range, | ||
890 | unsigned offset, bool input) | ||
891 | { | ||
892 | struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
893 | struct gpio_chip *chip; | ||
894 | int pin; | ||
895 | |||
896 | chip = range->gc; | ||
897 | pin = offset - chip->base; | ||
898 | dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", | ||
899 | offset, range->name, pin, input ? "input" : "output"); | ||
900 | |||
901 | return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base, | ||
902 | input); | ||
903 | } | ||
904 | |||
891 | static const struct pinmux_ops rockchip_pmx_ops = { | 905 | static const struct pinmux_ops rockchip_pmx_ops = { |
892 | .get_functions_count = rockchip_pmx_get_funcs_count, | 906 | .get_functions_count = rockchip_pmx_get_funcs_count, |
893 | .get_function_name = rockchip_pmx_get_func_name, | 907 | .get_function_name = rockchip_pmx_get_func_name, |
@@ -917,8 +931,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, | |||
917 | return false; | 931 | return false; |
918 | } | 932 | } |
919 | 933 | ||
920 | static int rockchip_gpio_direction_output(struct gpio_chip *gc, | 934 | static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value); |
921 | unsigned offset, int value); | ||
922 | static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); | 935 | static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); |
923 | 936 | ||
924 | /* set the pin config settings for a specified pin */ | 937 | /* set the pin config settings for a specified pin */ |
@@ -959,9 +972,10 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | |||
959 | return rc; | 972 | return rc; |
960 | break; | 973 | break; |
961 | case PIN_CONFIG_OUTPUT: | 974 | case PIN_CONFIG_OUTPUT: |
962 | rc = rockchip_gpio_direction_output(&bank->gpio_chip, | 975 | rockchip_gpio_set(&bank->gpio_chip, |
963 | pin - bank->pin_base, | 976 | pin - bank->pin_base, arg); |
964 | arg); | 977 | rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip, |
978 | pin - bank->pin_base, false); | ||
965 | if (rc) | 979 | if (rc) |
966 | return rc; | 980 | return rc; |
967 | break; | 981 | break; |
@@ -1253,6 +1267,10 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, | |||
1253 | } | 1267 | } |
1254 | } | 1268 | } |
1255 | 1269 | ||
1270 | ret = rockchip_pinctrl_parse_dt(pdev, info); | ||
1271 | if (ret) | ||
1272 | return ret; | ||
1273 | |||
1256 | info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); | 1274 | info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); |
1257 | if (!info->pctl_dev) { | 1275 | if (!info->pctl_dev) { |
1258 | dev_err(&pdev->dev, "could not register pinctrl driver\n"); | 1276 | dev_err(&pdev->dev, "could not register pinctrl driver\n"); |
@@ -1270,12 +1288,6 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, | |||
1270 | pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); | 1288 | pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); |
1271 | } | 1289 | } |
1272 | 1290 | ||
1273 | ret = rockchip_pinctrl_parse_dt(pdev, info); | ||
1274 | if (ret) { | ||
1275 | pinctrl_unregister(info->pctl_dev); | ||
1276 | return ret; | ||
1277 | } | ||
1278 | |||
1279 | return 0; | 1291 | return 0; |
1280 | } | 1292 | } |
1281 | 1293 | ||
@@ -1387,6 +1399,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1387 | u32 polarity = 0, data = 0; | 1399 | u32 polarity = 0, data = 0; |
1388 | u32 pend; | 1400 | u32 pend; |
1389 | bool edge_changed = false; | 1401 | bool edge_changed = false; |
1402 | unsigned long flags; | ||
1390 | 1403 | ||
1391 | dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); | 1404 | dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); |
1392 | 1405 | ||
@@ -1432,10 +1445,14 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1432 | 1445 | ||
1433 | if (bank->toggle_edge_mode && edge_changed) { | 1446 | if (bank->toggle_edge_mode && edge_changed) { |
1434 | /* Interrupt params should only be set with ints disabled */ | 1447 | /* Interrupt params should only be set with ints disabled */ |
1448 | spin_lock_irqsave(&bank->slock, flags); | ||
1449 | |||
1435 | data = readl_relaxed(bank->reg_base + GPIO_INTEN); | 1450 | data = readl_relaxed(bank->reg_base + GPIO_INTEN); |
1436 | writel_relaxed(0, bank->reg_base + GPIO_INTEN); | 1451 | writel_relaxed(0, bank->reg_base + GPIO_INTEN); |
1437 | writel(polarity, bank->reg_base + GPIO_INT_POLARITY); | 1452 | writel(polarity, bank->reg_base + GPIO_INT_POLARITY); |
1438 | writel(data, bank->reg_base + GPIO_INTEN); | 1453 | writel(data, bank->reg_base + GPIO_INTEN); |
1454 | |||
1455 | spin_unlock_irqrestore(&bank->slock, flags); | ||
1439 | } | 1456 | } |
1440 | 1457 | ||
1441 | chained_irq_exit(chip, desc); | 1458 | chained_irq_exit(chip, desc); |
@@ -1449,6 +1466,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1449 | u32 polarity; | 1466 | u32 polarity; |
1450 | u32 level; | 1467 | u32 level; |
1451 | u32 data; | 1468 | u32 data; |
1469 | unsigned long flags; | ||
1452 | int ret; | 1470 | int ret; |
1453 | 1471 | ||
1454 | /* make sure the pin is configured as gpio input */ | 1472 | /* make sure the pin is configured as gpio input */ |
@@ -1456,15 +1474,20 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1456 | if (ret < 0) | 1474 | if (ret < 0) |
1457 | return ret; | 1475 | return ret; |
1458 | 1476 | ||
1477 | spin_lock_irqsave(&bank->slock, flags); | ||
1478 | |||
1459 | data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); | 1479 | data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); |
1460 | data &= ~mask; | 1480 | data &= ~mask; |
1461 | writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); | 1481 | writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); |
1462 | 1482 | ||
1483 | spin_unlock_irqrestore(&bank->slock, flags); | ||
1484 | |||
1463 | if (type & IRQ_TYPE_EDGE_BOTH) | 1485 | if (type & IRQ_TYPE_EDGE_BOTH) |
1464 | __irq_set_handler_locked(d->irq, handle_edge_irq); | 1486 | __irq_set_handler_locked(d->irq, handle_edge_irq); |
1465 | else | 1487 | else |
1466 | __irq_set_handler_locked(d->irq, handle_level_irq); | 1488 | __irq_set_handler_locked(d->irq, handle_level_irq); |
1467 | 1489 | ||
1490 | spin_lock_irqsave(&bank->slock, flags); | ||
1468 | irq_gc_lock(gc); | 1491 | irq_gc_lock(gc); |
1469 | 1492 | ||
1470 | level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); | 1493 | level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); |
@@ -1507,6 +1530,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1507 | break; | 1530 | break; |
1508 | default: | 1531 | default: |
1509 | irq_gc_unlock(gc); | 1532 | irq_gc_unlock(gc); |
1533 | spin_unlock_irqrestore(&bank->slock, flags); | ||
1510 | return -EINVAL; | 1534 | return -EINVAL; |
1511 | } | 1535 | } |
1512 | 1536 | ||
@@ -1514,6 +1538,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1514 | writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); | 1538 | writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); |
1515 | 1539 | ||
1516 | irq_gc_unlock(gc); | 1540 | irq_gc_unlock(gc); |
1541 | spin_unlock_irqrestore(&bank->slock, flags); | ||
1517 | 1542 | ||
1518 | return 0; | 1543 | return 0; |
1519 | } | 1544 | } |
@@ -1563,6 +1588,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev, | |||
1563 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | 1588 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; |
1564 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; | 1589 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; |
1565 | gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; | 1590 | gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; |
1591 | gc->wake_enabled = IRQ_MSK(bank->nr_pins); | ||
1566 | 1592 | ||
1567 | irq_set_handler_data(bank->irq, bank); | 1593 | irq_set_handler_data(bank->irq, bank); |
1568 | irq_set_chained_handler(bank->irq, rockchip_irq_demux); | 1594 | irq_set_chained_handler(bank->irq, rockchip_irq_demux); |
@@ -1770,6 +1796,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( | |||
1770 | return ctrl; | 1796 | return ctrl; |
1771 | } | 1797 | } |
1772 | 1798 | ||
1799 | #define RK3288_GRF_GPIO6C_IOMUX 0x64 | ||
1800 | #define GPIO6C6_SEL_WRITE_ENABLE BIT(28) | ||
1801 | |||
1802 | static u32 rk3288_grf_gpio6c_iomux; | ||
1803 | |||
1804 | static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) | ||
1805 | { | ||
1806 | struct rockchip_pinctrl *info = dev_get_drvdata(dev); | ||
1807 | int ret = pinctrl_force_sleep(info->pctl_dev); | ||
1808 | |||
1809 | if (ret) | ||
1810 | return ret; | ||
1811 | |||
1812 | /* | ||
1813 | * RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save | ||
1814 | * the setting here, and restore it at resume. | ||
1815 | */ | ||
1816 | if (info->ctrl->type == RK3288) { | ||
1817 | ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, | ||
1818 | &rk3288_grf_gpio6c_iomux); | ||
1819 | if (ret) { | ||
1820 | pinctrl_force_default(info->pctl_dev); | ||
1821 | return ret; | ||
1822 | } | ||
1823 | } | ||
1824 | |||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1828 | static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) | ||
1829 | { | ||
1830 | struct rockchip_pinctrl *info = dev_get_drvdata(dev); | ||
1831 | int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, | ||
1832 | rk3288_grf_gpio6c_iomux | | ||
1833 | GPIO6C6_SEL_WRITE_ENABLE); | ||
1834 | |||
1835 | if (ret) | ||
1836 | return ret; | ||
1837 | |||
1838 | return pinctrl_force_default(info->pctl_dev); | ||
1839 | } | ||
1840 | |||
1841 | static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend, | ||
1842 | rockchip_pinctrl_resume); | ||
1843 | |||
1773 | static int rockchip_pinctrl_probe(struct platform_device *pdev) | 1844 | static int rockchip_pinctrl_probe(struct platform_device *pdev) |
1774 | { | 1845 | { |
1775 | struct rockchip_pinctrl *info; | 1846 | struct rockchip_pinctrl *info; |
@@ -1983,6 +2054,7 @@ static struct platform_driver rockchip_pinctrl_driver = { | |||
1983 | .driver = { | 2054 | .driver = { |
1984 | .name = "rockchip-pinctrl", | 2055 | .name = "rockchip-pinctrl", |
1985 | .owner = THIS_MODULE, | 2056 | .owner = THIS_MODULE, |
2057 | .pm = &rockchip_pinctrl_dev_pm_ops, | ||
1986 | .of_match_table = rockchip_pinctrl_dt_match, | 2058 | .of_match_table = rockchip_pinctrl_dt_match, |
1987 | }, | 2059 | }, |
1988 | }; | 2060 | }; |
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 4b1792aad3d8..caeeb1c65b0f 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c | |||
@@ -1512,7 +1512,7 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info, | |||
1512 | gpio_irq, st_gpio_irq_handler); | 1512 | gpio_irq, st_gpio_irq_handler); |
1513 | } | 1513 | } |
1514 | 1514 | ||
1515 | if (info->irqmux_base > 0 || gpio_irq > 0) { | 1515 | if (info->irqmux_base || gpio_irq > 0) { |
1516 | err = gpiochip_irqchip_add(&bank->gpio_chip, &st_gpio_irqchip, | 1516 | err = gpiochip_irqchip_add(&bank->gpio_chip, &st_gpio_irqchip, |
1517 | 0, handle_simple_irq, | 1517 | 0, handle_simple_irq, |
1518 | IRQ_TYPE_LEVEL_LOW); | 1518 | IRQ_TYPE_LEVEL_LOW); |
diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c index 3b9bfcf717ac..9363563f9777 100644 --- a/drivers/pinctrl/pinctrl-tb10x.c +++ b/drivers/pinctrl/pinctrl-tb10x.c | |||
@@ -759,7 +759,7 @@ static struct pinctrl_desc tb10x_pindesc = { | |||
759 | static int tb10x_pinctrl_probe(struct platform_device *pdev) | 759 | static int tb10x_pinctrl_probe(struct platform_device *pdev) |
760 | { | 760 | { |
761 | int ret = -EINVAL; | 761 | int ret = -EINVAL; |
762 | struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 762 | struct resource *mem; |
763 | struct device *dev = &pdev->dev; | 763 | struct device *dev = &pdev->dev; |
764 | struct device_node *of_node = dev->of_node; | 764 | struct device_node *of_node = dev->of_node; |
765 | struct device_node *child; | 765 | struct device_node *child; |
@@ -771,11 +771,6 @@ static int tb10x_pinctrl_probe(struct platform_device *pdev) | |||
771 | return -EINVAL; | 771 | return -EINVAL; |
772 | } | 772 | } |
773 | 773 | ||
774 | if (!mem) { | ||
775 | dev_err(dev, "No memory resource defined.\n"); | ||
776 | return -EINVAL; | ||
777 | } | ||
778 | |||
779 | state = devm_kzalloc(dev, sizeof(struct tb10x_pinctrl) + | 774 | state = devm_kzalloc(dev, sizeof(struct tb10x_pinctrl) + |
780 | of_get_child_count(of_node) | 775 | of_get_child_count(of_node) |
781 | * sizeof(struct tb10x_of_pinfunc), | 776 | * sizeof(struct tb10x_of_pinfunc), |
@@ -787,6 +782,7 @@ static int tb10x_pinctrl_probe(struct platform_device *pdev) | |||
787 | state->pinfuncs = (struct tb10x_of_pinfunc *)(state + 1); | 782 | state->pinfuncs = (struct tb10x_of_pinfunc *)(state + 1); |
788 | mutex_init(&state->mutex); | 783 | mutex_init(&state->mutex); |
789 | 784 | ||
785 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
790 | state->base = devm_ioremap_resource(dev, mem); | 786 | state->base = devm_ioremap_resource(dev, mem); |
791 | if (IS_ERR(state->base)) { | 787 | if (IS_ERR(state->base)) { |
792 | ret = PTR_ERR(state->base); | 788 | ret = PTR_ERR(state->base); |
diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c index 1631ec94fb02..080ec7723ef2 100644 --- a/drivers/pinctrl/pinctrl-tegra-xusb.c +++ b/drivers/pinctrl/pinctrl-tegra-xusb.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/pinctrl/pinmux.h> | 20 | #include <linux/pinctrl/pinmux.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/reset.h> | 22 | #include <linux/reset.h> |
23 | #include <linux/slab.h> | ||
23 | 24 | ||
24 | #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> | 25 | #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> |
25 | 26 | ||
@@ -171,7 +172,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, | |||
171 | if (err == -EINVAL) | 172 | if (err == -EINVAL) |
172 | continue; | 173 | continue; |
173 | 174 | ||
174 | return err; | 175 | goto out; |
175 | } | 176 | } |
176 | 177 | ||
177 | config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value); | 178 | config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value); |
@@ -179,7 +180,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, | |||
179 | err = pinctrl_utils_add_config(padctl->pinctrl, &configs, | 180 | err = pinctrl_utils_add_config(padctl->pinctrl, &configs, |
180 | &num_configs, config); | 181 | &num_configs, config); |
181 | if (err < 0) | 182 | if (err < 0) |
182 | return err; | 183 | goto out; |
183 | } | 184 | } |
184 | 185 | ||
185 | if (function) | 186 | if (function) |
@@ -190,14 +191,14 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, | |||
190 | 191 | ||
191 | err = of_property_count_strings(np, "nvidia,lanes"); | 192 | err = of_property_count_strings(np, "nvidia,lanes"); |
192 | if (err < 0) | 193 | if (err < 0) |
193 | return err; | 194 | goto out; |
194 | 195 | ||
195 | reserve *= err; | 196 | reserve *= err; |
196 | 197 | ||
197 | err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps, | 198 | err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps, |
198 | num_maps, reserve); | 199 | num_maps, reserve); |
199 | if (err < 0) | 200 | if (err < 0) |
200 | return err; | 201 | goto out; |
201 | 202 | ||
202 | of_property_for_each_string(np, "nvidia,lanes", prop, group) { | 203 | of_property_for_each_string(np, "nvidia,lanes", prop, group) { |
203 | if (function) { | 204 | if (function) { |
@@ -205,7 +206,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, | |||
205 | reserved_maps, num_maps, group, | 206 | reserved_maps, num_maps, group, |
206 | function); | 207 | function); |
207 | if (err < 0) | 208 | if (err < 0) |
208 | return err; | 209 | goto out; |
209 | } | 210 | } |
210 | 211 | ||
211 | if (num_configs) { | 212 | if (num_configs) { |
@@ -214,11 +215,15 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, | |||
214 | configs, num_configs, | 215 | configs, num_configs, |
215 | PIN_MAP_TYPE_CONFIGS_GROUP); | 216 | PIN_MAP_TYPE_CONFIGS_GROUP); |
216 | if (err < 0) | 217 | if (err < 0) |
217 | return err; | 218 | goto out; |
218 | } | 219 | } |
219 | } | 220 | } |
220 | 221 | ||
221 | return 0; | 222 | err = 0; |
223 | |||
224 | out: | ||
225 | kfree(configs); | ||
226 | return err; | ||
222 | } | 227 | } |
223 | 228 | ||
224 | static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl, | 229 | static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl, |
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 81275af9638b..3cd243c26b7d 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig | |||
@@ -47,4 +47,17 @@ config PINCTRL_MSM8X74 | |||
47 | This is the pinctrl, pinmux, pinconf and gpiolib driver for the | 47 | This is the pinctrl, pinmux, pinconf and gpiolib driver for the |
48 | Qualcomm TLMM block found in the Qualcomm 8974 platform. | 48 | Qualcomm TLMM block found in the Qualcomm 8974 platform. |
49 | 49 | ||
50 | config PINCTRL_QCOM_SPMI_PMIC | ||
51 | tristate "Qualcomm SPMI PMIC pin controller driver" | ||
52 | depends on GPIOLIB && OF && SPMI | ||
53 | select REGMAP_SPMI | ||
54 | select PINMUX | ||
55 | select PINCONF | ||
56 | select GENERIC_PINCONF | ||
57 | help | ||
58 | This is the pinctrl, pinmux, pinconf and gpiolib driver for the | ||
59 | Qualcomm GPIO and MPP blocks found in the Qualcomm PMIC's chips, | ||
60 | which are using SPMI for communication with SoC. Example PMIC's | ||
61 | devices are pm8841, pm8941 and pma8084. | ||
62 | |||
50 | endif | 63 | endif |
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index ba8519fcd8d3..bfd79af5f982 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile | |||
@@ -5,3 +5,5 @@ obj-$(CONFIG_PINCTRL_APQ8084) += pinctrl-apq8084.o | |||
5 | obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o | 5 | obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o |
6 | obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o | 6 | obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o |
7 | obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o | 7 | obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o |
8 | obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o | ||
9 | obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o | ||
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c new file mode 100644 index 000000000000..b863b5080890 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | |||
@@ -0,0 +1,933 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/pinctrl/pinconf-generic.h> | ||
18 | #include <linux/pinctrl/pinconf.h> | ||
19 | #include <linux/pinctrl/pinmux.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/regmap.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/types.h> | ||
24 | |||
25 | #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> | ||
26 | |||
27 | #include "../core.h" | ||
28 | #include "../pinctrl-utils.h" | ||
29 | |||
30 | #define PMIC_GPIO_ADDRESS_RANGE 0x100 | ||
31 | |||
32 | /* type and subtype registers base address offsets */ | ||
33 | #define PMIC_GPIO_REG_TYPE 0x4 | ||
34 | #define PMIC_GPIO_REG_SUBTYPE 0x5 | ||
35 | |||
36 | /* GPIO peripheral type and subtype out_values */ | ||
37 | #define PMIC_GPIO_TYPE 0x10 | ||
38 | #define PMIC_GPIO_SUBTYPE_GPIO_4CH 0x1 | ||
39 | #define PMIC_GPIO_SUBTYPE_GPIOC_4CH 0x5 | ||
40 | #define PMIC_GPIO_SUBTYPE_GPIO_8CH 0x9 | ||
41 | #define PMIC_GPIO_SUBTYPE_GPIOC_8CH 0xd | ||
42 | |||
43 | #define PMIC_MPP_REG_RT_STS 0x10 | ||
44 | #define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1 | ||
45 | |||
46 | /* control register base address offsets */ | ||
47 | #define PMIC_GPIO_REG_MODE_CTL 0x40 | ||
48 | #define PMIC_GPIO_REG_DIG_VIN_CTL 0x41 | ||
49 | #define PMIC_GPIO_REG_DIG_PULL_CTL 0x42 | ||
50 | #define PMIC_GPIO_REG_DIG_OUT_CTL 0x45 | ||
51 | #define PMIC_GPIO_REG_EN_CTL 0x46 | ||
52 | |||
53 | /* PMIC_GPIO_REG_MODE_CTL */ | ||
54 | #define PMIC_GPIO_REG_MODE_VALUE_SHIFT 0x1 | ||
55 | #define PMIC_GPIO_REG_MODE_FUNCTION_SHIFT 1 | ||
56 | #define PMIC_GPIO_REG_MODE_FUNCTION_MASK 0x7 | ||
57 | #define PMIC_GPIO_REG_MODE_DIR_SHIFT 4 | ||
58 | #define PMIC_GPIO_REG_MODE_DIR_MASK 0x7 | ||
59 | |||
60 | /* PMIC_GPIO_REG_DIG_VIN_CTL */ | ||
61 | #define PMIC_GPIO_REG_VIN_SHIFT 0 | ||
62 | #define PMIC_GPIO_REG_VIN_MASK 0x7 | ||
63 | |||
64 | /* PMIC_GPIO_REG_DIG_PULL_CTL */ | ||
65 | #define PMIC_GPIO_REG_PULL_SHIFT 0 | ||
66 | #define PMIC_GPIO_REG_PULL_MASK 0x7 | ||
67 | |||
68 | #define PMIC_GPIO_PULL_DOWN 4 | ||
69 | #define PMIC_GPIO_PULL_DISABLE 5 | ||
70 | |||
71 | /* PMIC_GPIO_REG_DIG_OUT_CTL */ | ||
72 | #define PMIC_GPIO_REG_OUT_STRENGTH_SHIFT 0 | ||
73 | #define PMIC_GPIO_REG_OUT_STRENGTH_MASK 0x3 | ||
74 | #define PMIC_GPIO_REG_OUT_TYPE_SHIFT 4 | ||
75 | #define PMIC_GPIO_REG_OUT_TYPE_MASK 0x3 | ||
76 | |||
77 | /* | ||
78 | * Output type - indicates pin should be configured as push-pull, | ||
79 | * open drain or open source. | ||
80 | */ | ||
81 | #define PMIC_GPIO_OUT_BUF_CMOS 0 | ||
82 | #define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS 1 | ||
83 | #define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS 2 | ||
84 | |||
85 | /* PMIC_GPIO_REG_EN_CTL */ | ||
86 | #define PMIC_GPIO_REG_MASTER_EN_SHIFT 7 | ||
87 | |||
88 | #define PMIC_GPIO_PHYSICAL_OFFSET 1 | ||
89 | |||
90 | /* Qualcomm specific pin configurations */ | ||
91 | #define PMIC_GPIO_CONF_PULL_UP (PIN_CONFIG_END + 1) | ||
92 | #define PMIC_GPIO_CONF_STRENGTH (PIN_CONFIG_END + 2) | ||
93 | |||
94 | /** | ||
95 | * struct pmic_gpio_pad - keep current GPIO settings | ||
96 | * @base: Address base in SPMI device. | ||
97 | * @irq: IRQ number which this GPIO generate. | ||
98 | * @is_enabled: Set to false when GPIO should be put in high Z state. | ||
99 | * @out_value: Cached pin output value | ||
100 | * @have_buffer: Set to true if GPIO output could be configured in push-pull, | ||
101 | * open-drain or open-source mode. | ||
102 | * @output_enabled: Set to true if GPIO output logic is enabled. | ||
103 | * @input_enabled: Set to true if GPIO input buffer logic is enabled. | ||
104 | * @num_sources: Number of power-sources supported by this GPIO. | ||
105 | * @power_source: Current power-source used. | ||
106 | * @buffer_type: Push-pull, open-drain or open-source. | ||
107 | * @pullup: Constant current which flow trough GPIO output buffer. | ||
108 | * @strength: No, Low, Medium, High | ||
109 | * @function: See pmic_gpio_functions[] | ||
110 | */ | ||
111 | struct pmic_gpio_pad { | ||
112 | u16 base; | ||
113 | int irq; | ||
114 | bool is_enabled; | ||
115 | bool out_value; | ||
116 | bool have_buffer; | ||
117 | bool output_enabled; | ||
118 | bool input_enabled; | ||
119 | unsigned int num_sources; | ||
120 | unsigned int power_source; | ||
121 | unsigned int buffer_type; | ||
122 | unsigned int pullup; | ||
123 | unsigned int strength; | ||
124 | unsigned int function; | ||
125 | }; | ||
126 | |||
127 | struct pmic_gpio_state { | ||
128 | struct device *dev; | ||
129 | struct regmap *map; | ||
130 | struct pinctrl_dev *ctrl; | ||
131 | struct gpio_chip chip; | ||
132 | }; | ||
133 | |||
134 | struct pmic_gpio_bindings { | ||
135 | const char *property; | ||
136 | unsigned param; | ||
137 | }; | ||
138 | |||
139 | static struct pmic_gpio_bindings pmic_gpio_bindings[] = { | ||
140 | {"qcom,pull-up-strength", PMIC_GPIO_CONF_PULL_UP}, | ||
141 | {"qcom,drive-strength", PMIC_GPIO_CONF_STRENGTH}, | ||
142 | }; | ||
143 | |||
144 | static const char *const pmic_gpio_groups[] = { | ||
145 | "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8", | ||
146 | "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15", | ||
147 | "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", | ||
148 | "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", | ||
149 | "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36", | ||
150 | }; | ||
151 | |||
152 | static const char *const pmic_gpio_functions[] = { | ||
153 | PMIC_GPIO_FUNC_NORMAL, PMIC_GPIO_FUNC_PAIRED, | ||
154 | PMIC_GPIO_FUNC_FUNC1, PMIC_GPIO_FUNC_FUNC2, | ||
155 | PMIC_GPIO_FUNC_DTEST1, PMIC_GPIO_FUNC_DTEST2, | ||
156 | PMIC_GPIO_FUNC_DTEST3, PMIC_GPIO_FUNC_DTEST4, | ||
157 | }; | ||
158 | |||
159 | static inline struct pmic_gpio_state *to_gpio_state(struct gpio_chip *chip) | ||
160 | { | ||
161 | return container_of(chip, struct pmic_gpio_state, chip); | ||
162 | }; | ||
163 | |||
164 | static int pmic_gpio_read(struct pmic_gpio_state *state, | ||
165 | struct pmic_gpio_pad *pad, unsigned int addr) | ||
166 | { | ||
167 | unsigned int val; | ||
168 | int ret; | ||
169 | |||
170 | ret = regmap_read(state->map, pad->base + addr, &val); | ||
171 | if (ret < 0) | ||
172 | dev_err(state->dev, "read 0x%x failed\n", addr); | ||
173 | else | ||
174 | ret = val; | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int pmic_gpio_write(struct pmic_gpio_state *state, | ||
180 | struct pmic_gpio_pad *pad, unsigned int addr, | ||
181 | unsigned int val) | ||
182 | { | ||
183 | int ret; | ||
184 | |||
185 | ret = regmap_write(state->map, pad->base + addr, val); | ||
186 | if (ret < 0) | ||
187 | dev_err(state->dev, "write 0x%x failed\n", addr); | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static int pmic_gpio_get_groups_count(struct pinctrl_dev *pctldev) | ||
193 | { | ||
194 | /* Every PIN is a group */ | ||
195 | return pctldev->desc->npins; | ||
196 | } | ||
197 | |||
198 | static const char *pmic_gpio_get_group_name(struct pinctrl_dev *pctldev, | ||
199 | unsigned pin) | ||
200 | { | ||
201 | return pctldev->desc->pins[pin].name; | ||
202 | } | ||
203 | |||
204 | static int pmic_gpio_get_group_pins(struct pinctrl_dev *pctldev, unsigned pin, | ||
205 | const unsigned **pins, unsigned *num_pins) | ||
206 | { | ||
207 | *pins = &pctldev->desc->pins[pin].number; | ||
208 | *num_pins = 1; | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int pmic_gpio_parse_dt_config(struct device_node *np, | ||
213 | struct pinctrl_dev *pctldev, | ||
214 | unsigned long **configs, | ||
215 | unsigned int *nconfs) | ||
216 | { | ||
217 | struct pmic_gpio_bindings *par; | ||
218 | unsigned long cfg; | ||
219 | int ret, i; | ||
220 | u32 val; | ||
221 | |||
222 | for (i = 0; i < ARRAY_SIZE(pmic_gpio_bindings); i++) { | ||
223 | par = &pmic_gpio_bindings[i]; | ||
224 | ret = of_property_read_u32(np, par->property, &val); | ||
225 | |||
226 | /* property not found */ | ||
227 | if (ret == -EINVAL) | ||
228 | continue; | ||
229 | |||
230 | /* use zero as default value */ | ||
231 | if (ret) | ||
232 | val = 0; | ||
233 | |||
234 | dev_dbg(pctldev->dev, "found %s with value %u\n", | ||
235 | par->property, val); | ||
236 | |||
237 | cfg = pinconf_to_config_packed(par->param, val); | ||
238 | |||
239 | ret = pinctrl_utils_add_config(pctldev, configs, nconfs, cfg); | ||
240 | if (ret) | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int pmic_gpio_dt_subnode_to_map(struct pinctrl_dev *pctldev, | ||
248 | struct device_node *np, | ||
249 | struct pinctrl_map **map, | ||
250 | unsigned *reserv, unsigned *nmaps, | ||
251 | enum pinctrl_map_type type) | ||
252 | { | ||
253 | unsigned long *configs = NULL; | ||
254 | unsigned nconfs = 0; | ||
255 | struct property *prop; | ||
256 | const char *group; | ||
257 | int ret; | ||
258 | |||
259 | ret = pmic_gpio_parse_dt_config(np, pctldev, &configs, &nconfs); | ||
260 | if (ret < 0) | ||
261 | return ret; | ||
262 | |||
263 | if (!nconfs) | ||
264 | return 0; | ||
265 | |||
266 | ret = of_property_count_strings(np, "pins"); | ||
267 | if (ret < 0) | ||
268 | goto exit; | ||
269 | |||
270 | ret = pinctrl_utils_reserve_map(pctldev, map, reserv, nmaps, ret); | ||
271 | if (ret < 0) | ||
272 | goto exit; | ||
273 | |||
274 | of_property_for_each_string(np, "pins", prop, group) { | ||
275 | ret = pinctrl_utils_add_map_configs(pctldev, map, | ||
276 | reserv, nmaps, group, | ||
277 | configs, nconfs, type); | ||
278 | if (ret < 0) | ||
279 | break; | ||
280 | } | ||
281 | exit: | ||
282 | kfree(configs); | ||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | static int pmic_gpio_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
287 | struct device_node *np_config, | ||
288 | struct pinctrl_map **map, unsigned *nmaps) | ||
289 | { | ||
290 | enum pinctrl_map_type type; | ||
291 | struct device_node *np; | ||
292 | unsigned reserv; | ||
293 | int ret; | ||
294 | |||
295 | ret = 0; | ||
296 | *map = NULL; | ||
297 | *nmaps = 0; | ||
298 | reserv = 0; | ||
299 | type = PIN_MAP_TYPE_CONFIGS_GROUP; | ||
300 | |||
301 | for_each_child_of_node(np_config, np) { | ||
302 | ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map, | ||
303 | &reserv, nmaps, type); | ||
304 | if (ret) | ||
305 | break; | ||
306 | |||
307 | ret = pmic_gpio_dt_subnode_to_map(pctldev, np, map, &reserv, | ||
308 | nmaps, type); | ||
309 | if (ret) | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | if (ret < 0) | ||
314 | pinctrl_utils_dt_free_map(pctldev, *map, *nmaps); | ||
315 | |||
316 | return ret; | ||
317 | } | ||
318 | |||
319 | static const struct pinctrl_ops pmic_gpio_pinctrl_ops = { | ||
320 | .get_groups_count = pmic_gpio_get_groups_count, | ||
321 | .get_group_name = pmic_gpio_get_group_name, | ||
322 | .get_group_pins = pmic_gpio_get_group_pins, | ||
323 | .dt_node_to_map = pmic_gpio_dt_node_to_map, | ||
324 | .dt_free_map = pinctrl_utils_dt_free_map, | ||
325 | }; | ||
326 | |||
327 | static int pmic_gpio_get_functions_count(struct pinctrl_dev *pctldev) | ||
328 | { | ||
329 | return ARRAY_SIZE(pmic_gpio_functions); | ||
330 | } | ||
331 | |||
332 | static const char *pmic_gpio_get_function_name(struct pinctrl_dev *pctldev, | ||
333 | unsigned function) | ||
334 | { | ||
335 | return pmic_gpio_functions[function]; | ||
336 | } | ||
337 | |||
338 | static int pmic_gpio_get_function_groups(struct pinctrl_dev *pctldev, | ||
339 | unsigned function, | ||
340 | const char *const **groups, | ||
341 | unsigned *const num_qgroups) | ||
342 | { | ||
343 | *groups = pmic_gpio_groups; | ||
344 | *num_qgroups = pctldev->desc->npins; | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned function, | ||
349 | unsigned pin) | ||
350 | { | ||
351 | struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); | ||
352 | struct pmic_gpio_pad *pad; | ||
353 | unsigned int val; | ||
354 | int ret; | ||
355 | |||
356 | pad = pctldev->desc->pins[pin].drv_data; | ||
357 | |||
358 | pad->function = function; | ||
359 | |||
360 | val = 0; | ||
361 | if (pad->output_enabled) { | ||
362 | if (pad->input_enabled) | ||
363 | val = 2; | ||
364 | else | ||
365 | val = 1; | ||
366 | } | ||
367 | |||
368 | val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; | ||
369 | val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; | ||
370 | |||
371 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val); | ||
372 | if (ret < 0) | ||
373 | return ret; | ||
374 | |||
375 | val = pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT; | ||
376 | |||
377 | return pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val); | ||
378 | } | ||
379 | |||
380 | static const struct pinmux_ops pmic_gpio_pinmux_ops = { | ||
381 | .get_functions_count = pmic_gpio_get_functions_count, | ||
382 | .get_function_name = pmic_gpio_get_function_name, | ||
383 | .get_function_groups = pmic_gpio_get_function_groups, | ||
384 | .set_mux = pmic_gpio_set_mux, | ||
385 | }; | ||
386 | |||
387 | static int pmic_gpio_config_get(struct pinctrl_dev *pctldev, | ||
388 | unsigned int pin, unsigned long *config) | ||
389 | { | ||
390 | unsigned param = pinconf_to_config_param(*config); | ||
391 | struct pmic_gpio_pad *pad; | ||
392 | unsigned arg; | ||
393 | |||
394 | pad = pctldev->desc->pins[pin].drv_data; | ||
395 | |||
396 | switch (param) { | ||
397 | case PIN_CONFIG_DRIVE_PUSH_PULL: | ||
398 | arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_CMOS; | ||
399 | break; | ||
400 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: | ||
401 | arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS; | ||
402 | break; | ||
403 | case PIN_CONFIG_DRIVE_OPEN_SOURCE: | ||
404 | arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS; | ||
405 | break; | ||
406 | case PIN_CONFIG_BIAS_PULL_DOWN: | ||
407 | arg = pad->pullup == PMIC_GPIO_PULL_DOWN; | ||
408 | break; | ||
409 | case PIN_CONFIG_BIAS_DISABLE: | ||
410 | arg = pad->pullup = PMIC_GPIO_PULL_DISABLE; | ||
411 | break; | ||
412 | case PIN_CONFIG_BIAS_PULL_UP: | ||
413 | arg = pad->pullup == PMIC_GPIO_PULL_UP_30; | ||
414 | break; | ||
415 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: | ||
416 | arg = !pad->is_enabled; | ||
417 | break; | ||
418 | case PIN_CONFIG_POWER_SOURCE: | ||
419 | arg = pad->power_source; | ||
420 | break; | ||
421 | case PIN_CONFIG_INPUT_ENABLE: | ||
422 | arg = pad->input_enabled; | ||
423 | break; | ||
424 | case PIN_CONFIG_OUTPUT: | ||
425 | arg = pad->out_value; | ||
426 | break; | ||
427 | case PMIC_GPIO_CONF_PULL_UP: | ||
428 | arg = pad->pullup; | ||
429 | break; | ||
430 | case PMIC_GPIO_CONF_STRENGTH: | ||
431 | arg = pad->strength; | ||
432 | break; | ||
433 | default: | ||
434 | return -EINVAL; | ||
435 | } | ||
436 | |||
437 | *config = pinconf_to_config_packed(param, arg); | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin, | ||
442 | unsigned long *configs, unsigned nconfs) | ||
443 | { | ||
444 | struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); | ||
445 | struct pmic_gpio_pad *pad; | ||
446 | unsigned param, arg; | ||
447 | unsigned int val; | ||
448 | int i, ret; | ||
449 | |||
450 | pad = pctldev->desc->pins[pin].drv_data; | ||
451 | |||
452 | for (i = 0; i < nconfs; i++) { | ||
453 | param = pinconf_to_config_param(configs[i]); | ||
454 | arg = pinconf_to_config_argument(configs[i]); | ||
455 | |||
456 | switch (param) { | ||
457 | case PIN_CONFIG_DRIVE_PUSH_PULL: | ||
458 | pad->buffer_type = PMIC_GPIO_OUT_BUF_CMOS; | ||
459 | break; | ||
460 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: | ||
461 | if (!pad->have_buffer) | ||
462 | return -EINVAL; | ||
463 | pad->buffer_type = PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS; | ||
464 | break; | ||
465 | case PIN_CONFIG_DRIVE_OPEN_SOURCE: | ||
466 | if (!pad->have_buffer) | ||
467 | return -EINVAL; | ||
468 | pad->buffer_type = PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS; | ||
469 | break; | ||
470 | case PIN_CONFIG_BIAS_DISABLE: | ||
471 | pad->pullup = PMIC_GPIO_PULL_DISABLE; | ||
472 | break; | ||
473 | case PIN_CONFIG_BIAS_PULL_UP: | ||
474 | pad->pullup = PMIC_GPIO_PULL_UP_30; | ||
475 | break; | ||
476 | case PIN_CONFIG_BIAS_PULL_DOWN: | ||
477 | if (arg) | ||
478 | pad->pullup = PMIC_GPIO_PULL_DOWN; | ||
479 | else | ||
480 | pad->pullup = PMIC_GPIO_PULL_DISABLE; | ||
481 | break; | ||
482 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: | ||
483 | pad->is_enabled = false; | ||
484 | break; | ||
485 | case PIN_CONFIG_POWER_SOURCE: | ||
486 | if (arg > pad->num_sources) | ||
487 | return -EINVAL; | ||
488 | pad->power_source = arg; | ||
489 | break; | ||
490 | case PIN_CONFIG_INPUT_ENABLE: | ||
491 | pad->input_enabled = arg ? true : false; | ||
492 | break; | ||
493 | case PIN_CONFIG_OUTPUT: | ||
494 | pad->output_enabled = true; | ||
495 | pad->out_value = arg; | ||
496 | break; | ||
497 | case PMIC_GPIO_CONF_PULL_UP: | ||
498 | if (arg > PMIC_GPIO_PULL_UP_1P5_30) | ||
499 | return -EINVAL; | ||
500 | pad->pullup = arg; | ||
501 | break; | ||
502 | case PMIC_GPIO_CONF_STRENGTH: | ||
503 | if (arg > PMIC_GPIO_STRENGTH_LOW) | ||
504 | return -EINVAL; | ||
505 | pad->strength = arg; | ||
506 | break; | ||
507 | default: | ||
508 | return -EINVAL; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | val = pad->power_source << PMIC_GPIO_REG_VIN_SHIFT; | ||
513 | |||
514 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_VIN_CTL, val); | ||
515 | if (ret < 0) | ||
516 | return ret; | ||
517 | |||
518 | val = pad->pullup << PMIC_GPIO_REG_PULL_SHIFT; | ||
519 | |||
520 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_PULL_CTL, val); | ||
521 | if (ret < 0) | ||
522 | return ret; | ||
523 | |||
524 | val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT; | ||
525 | val = pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; | ||
526 | |||
527 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val); | ||
528 | if (ret < 0) | ||
529 | return ret; | ||
530 | |||
531 | val = 0; | ||
532 | if (pad->output_enabled) { | ||
533 | if (pad->input_enabled) | ||
534 | val = 2; | ||
535 | else | ||
536 | val = 1; | ||
537 | } | ||
538 | |||
539 | val = val << PMIC_GPIO_REG_MODE_DIR_SHIFT; | ||
540 | val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; | ||
541 | val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; | ||
542 | |||
543 | return pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val); | ||
544 | } | ||
545 | |||
546 | static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev, | ||
547 | struct seq_file *s, unsigned pin) | ||
548 | { | ||
549 | struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); | ||
550 | struct pmic_gpio_pad *pad; | ||
551 | int ret, val; | ||
552 | |||
553 | static const char *const biases[] = { | ||
554 | "pull-up 30uA", "pull-up 1.5uA", "pull-up 31.5uA", | ||
555 | "pull-up 1.5uA + 30uA boost", "pull-down 10uA", "no pull" | ||
556 | }; | ||
557 | static const char *const buffer_types[] = { | ||
558 | "push-pull", "open-drain", "open-source" | ||
559 | }; | ||
560 | static const char *const strengths[] = { | ||
561 | "no", "high", "medium", "low" | ||
562 | }; | ||
563 | |||
564 | pad = pctldev->desc->pins[pin].drv_data; | ||
565 | |||
566 | seq_printf(s, " gpio%-2d:", pin + PMIC_GPIO_PHYSICAL_OFFSET); | ||
567 | |||
568 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_EN_CTL); | ||
569 | |||
570 | if (val < 0 || !(val >> PMIC_GPIO_REG_MASTER_EN_SHIFT)) { | ||
571 | seq_puts(s, " ---"); | ||
572 | } else { | ||
573 | |||
574 | if (!pad->input_enabled) { | ||
575 | ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); | ||
576 | if (!ret) { | ||
577 | ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; | ||
578 | pad->out_value = ret; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); | ||
583 | seq_printf(s, " %-7s", pmic_gpio_functions[pad->function]); | ||
584 | seq_printf(s, " vin-%d", pad->power_source); | ||
585 | seq_printf(s, " %-27s", biases[pad->pullup]); | ||
586 | seq_printf(s, " %-10s", buffer_types[pad->buffer_type]); | ||
587 | seq_printf(s, " %-4s", pad->out_value ? "high" : "low"); | ||
588 | seq_printf(s, " %-7s", strengths[pad->strength]); | ||
589 | } | ||
590 | } | ||
591 | |||
592 | static const struct pinconf_ops pmic_gpio_pinconf_ops = { | ||
593 | .pin_config_group_get = pmic_gpio_config_get, | ||
594 | .pin_config_group_set = pmic_gpio_config_set, | ||
595 | .pin_config_group_dbg_show = pmic_gpio_config_dbg_show, | ||
596 | }; | ||
597 | |||
598 | static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned pin) | ||
599 | { | ||
600 | struct pmic_gpio_state *state = to_gpio_state(chip); | ||
601 | unsigned long config; | ||
602 | |||
603 | config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1); | ||
604 | |||
605 | return pmic_gpio_config_set(state->ctrl, pin, &config, 1); | ||
606 | } | ||
607 | |||
608 | static int pmic_gpio_direction_output(struct gpio_chip *chip, | ||
609 | unsigned pin, int val) | ||
610 | { | ||
611 | struct pmic_gpio_state *state = to_gpio_state(chip); | ||
612 | unsigned long config; | ||
613 | |||
614 | config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val); | ||
615 | |||
616 | return pmic_gpio_config_set(state->ctrl, pin, &config, 1); | ||
617 | } | ||
618 | |||
619 | static int pmic_gpio_get(struct gpio_chip *chip, unsigned pin) | ||
620 | { | ||
621 | struct pmic_gpio_state *state = to_gpio_state(chip); | ||
622 | struct pmic_gpio_pad *pad; | ||
623 | int ret; | ||
624 | |||
625 | pad = state->ctrl->desc->pins[pin].drv_data; | ||
626 | |||
627 | if (!pad->is_enabled) | ||
628 | return -EINVAL; | ||
629 | |||
630 | if (pad->input_enabled) { | ||
631 | ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); | ||
632 | if (ret < 0) | ||
633 | return ret; | ||
634 | |||
635 | pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK; | ||
636 | } | ||
637 | |||
638 | return pad->out_value; | ||
639 | } | ||
640 | |||
641 | static void pmic_gpio_set(struct gpio_chip *chip, unsigned pin, int value) | ||
642 | { | ||
643 | struct pmic_gpio_state *state = to_gpio_state(chip); | ||
644 | unsigned long config; | ||
645 | |||
646 | config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value); | ||
647 | |||
648 | pmic_gpio_config_set(state->ctrl, pin, &config, 1); | ||
649 | } | ||
650 | |||
651 | static int pmic_gpio_request(struct gpio_chip *chip, unsigned base) | ||
652 | { | ||
653 | return pinctrl_request_gpio(chip->base + base); | ||
654 | } | ||
655 | |||
656 | static void pmic_gpio_free(struct gpio_chip *chip, unsigned base) | ||
657 | { | ||
658 | pinctrl_free_gpio(chip->base + base); | ||
659 | } | ||
660 | |||
661 | static int pmic_gpio_of_xlate(struct gpio_chip *chip, | ||
662 | const struct of_phandle_args *gpio_desc, | ||
663 | u32 *flags) | ||
664 | { | ||
665 | if (chip->of_gpio_n_cells < 2) | ||
666 | return -EINVAL; | ||
667 | |||
668 | if (flags) | ||
669 | *flags = gpio_desc->args[1]; | ||
670 | |||
671 | return gpio_desc->args[0] - PMIC_GPIO_PHYSICAL_OFFSET; | ||
672 | } | ||
673 | |||
674 | static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned pin) | ||
675 | { | ||
676 | struct pmic_gpio_state *state = to_gpio_state(chip); | ||
677 | struct pmic_gpio_pad *pad; | ||
678 | |||
679 | pad = state->ctrl->desc->pins[pin].drv_data; | ||
680 | |||
681 | return pad->irq; | ||
682 | } | ||
683 | |||
684 | static void pmic_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | ||
685 | { | ||
686 | struct pmic_gpio_state *state = to_gpio_state(chip); | ||
687 | unsigned i; | ||
688 | |||
689 | for (i = 0; i < chip->ngpio; i++) { | ||
690 | pmic_gpio_config_dbg_show(state->ctrl, s, i); | ||
691 | seq_puts(s, "\n"); | ||
692 | } | ||
693 | } | ||
694 | |||
695 | static const struct gpio_chip pmic_gpio_gpio_template = { | ||
696 | .direction_input = pmic_gpio_direction_input, | ||
697 | .direction_output = pmic_gpio_direction_output, | ||
698 | .get = pmic_gpio_get, | ||
699 | .set = pmic_gpio_set, | ||
700 | .request = pmic_gpio_request, | ||
701 | .free = pmic_gpio_free, | ||
702 | .of_xlate = pmic_gpio_of_xlate, | ||
703 | .to_irq = pmic_gpio_to_irq, | ||
704 | .dbg_show = pmic_gpio_dbg_show, | ||
705 | }; | ||
706 | |||
707 | static int pmic_gpio_populate(struct pmic_gpio_state *state, | ||
708 | struct pmic_gpio_pad *pad) | ||
709 | { | ||
710 | int type, subtype, val, dir; | ||
711 | |||
712 | type = pmic_gpio_read(state, pad, PMIC_GPIO_REG_TYPE); | ||
713 | if (type < 0) | ||
714 | return type; | ||
715 | |||
716 | if (type != PMIC_GPIO_TYPE) { | ||
717 | dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n", | ||
718 | type, pad->base); | ||
719 | return -ENODEV; | ||
720 | } | ||
721 | |||
722 | subtype = pmic_gpio_read(state, pad, PMIC_GPIO_REG_SUBTYPE); | ||
723 | if (subtype < 0) | ||
724 | return subtype; | ||
725 | |||
726 | switch (subtype) { | ||
727 | case PMIC_GPIO_SUBTYPE_GPIO_4CH: | ||
728 | pad->have_buffer = true; | ||
729 | case PMIC_GPIO_SUBTYPE_GPIOC_4CH: | ||
730 | pad->num_sources = 4; | ||
731 | break; | ||
732 | case PMIC_GPIO_SUBTYPE_GPIO_8CH: | ||
733 | pad->have_buffer = true; | ||
734 | case PMIC_GPIO_SUBTYPE_GPIOC_8CH: | ||
735 | pad->num_sources = 8; | ||
736 | break; | ||
737 | default: | ||
738 | dev_err(state->dev, "unknown GPIO type 0x%x\n", subtype); | ||
739 | return -ENODEV; | ||
740 | } | ||
741 | |||
742 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_MODE_CTL); | ||
743 | if (val < 0) | ||
744 | return val; | ||
745 | |||
746 | pad->out_value = val & PMIC_GPIO_REG_MODE_VALUE_SHIFT; | ||
747 | |||
748 | dir = val >> PMIC_GPIO_REG_MODE_DIR_SHIFT; | ||
749 | dir &= PMIC_GPIO_REG_MODE_DIR_MASK; | ||
750 | switch (dir) { | ||
751 | case 0: | ||
752 | pad->input_enabled = true; | ||
753 | pad->output_enabled = false; | ||
754 | break; | ||
755 | case 1: | ||
756 | pad->input_enabled = false; | ||
757 | pad->output_enabled = true; | ||
758 | break; | ||
759 | case 2: | ||
760 | pad->input_enabled = true; | ||
761 | pad->output_enabled = true; | ||
762 | break; | ||
763 | default: | ||
764 | dev_err(state->dev, "unknown GPIO direction\n"); | ||
765 | return -ENODEV; | ||
766 | } | ||
767 | |||
768 | pad->function = val >> PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; | ||
769 | pad->function &= PMIC_GPIO_REG_MODE_FUNCTION_MASK; | ||
770 | |||
771 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_VIN_CTL); | ||
772 | if (val < 0) | ||
773 | return val; | ||
774 | |||
775 | pad->power_source = val >> PMIC_GPIO_REG_VIN_SHIFT; | ||
776 | pad->power_source &= PMIC_GPIO_REG_VIN_MASK; | ||
777 | |||
778 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_PULL_CTL); | ||
779 | if (val < 0) | ||
780 | return val; | ||
781 | |||
782 | pad->pullup = val >> PMIC_GPIO_REG_PULL_SHIFT; | ||
783 | pad->pullup &= PMIC_GPIO_REG_PULL_MASK; | ||
784 | |||
785 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL); | ||
786 | if (val < 0) | ||
787 | return val; | ||
788 | |||
789 | pad->strength = val >> PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; | ||
790 | pad->strength &= PMIC_GPIO_REG_OUT_STRENGTH_MASK; | ||
791 | |||
792 | pad->buffer_type = val >> PMIC_GPIO_REG_OUT_TYPE_SHIFT; | ||
793 | pad->buffer_type &= PMIC_GPIO_REG_OUT_TYPE_MASK; | ||
794 | |||
795 | /* Pin could be disabled with PIN_CONFIG_BIAS_HIGH_IMPEDANCE */ | ||
796 | pad->is_enabled = true; | ||
797 | return 0; | ||
798 | } | ||
799 | |||
800 | static int pmic_gpio_probe(struct platform_device *pdev) | ||
801 | { | ||
802 | struct device *dev = &pdev->dev; | ||
803 | struct pinctrl_pin_desc *pindesc; | ||
804 | struct pinctrl_desc *pctrldesc; | ||
805 | struct pmic_gpio_pad *pad, *pads; | ||
806 | struct pmic_gpio_state *state; | ||
807 | int ret, npins, i; | ||
808 | u32 res[2]; | ||
809 | |||
810 | ret = of_property_read_u32_array(dev->of_node, "reg", res, 2); | ||
811 | if (ret < 0) { | ||
812 | dev_err(dev, "missing base address and/or range"); | ||
813 | return ret; | ||
814 | } | ||
815 | |||
816 | npins = res[1] / PMIC_GPIO_ADDRESS_RANGE; | ||
817 | |||
818 | if (!npins) | ||
819 | return -EINVAL; | ||
820 | |||
821 | BUG_ON(npins > ARRAY_SIZE(pmic_gpio_groups)); | ||
822 | |||
823 | state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); | ||
824 | if (!state) | ||
825 | return -ENOMEM; | ||
826 | |||
827 | platform_set_drvdata(pdev, state); | ||
828 | |||
829 | state->dev = &pdev->dev; | ||
830 | state->map = dev_get_regmap(dev->parent, NULL); | ||
831 | |||
832 | pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL); | ||
833 | if (!pindesc) | ||
834 | return -ENOMEM; | ||
835 | |||
836 | pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL); | ||
837 | if (!pads) | ||
838 | return -ENOMEM; | ||
839 | |||
840 | pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL); | ||
841 | if (!pctrldesc) | ||
842 | return -ENOMEM; | ||
843 | |||
844 | pctrldesc->pctlops = &pmic_gpio_pinctrl_ops; | ||
845 | pctrldesc->pmxops = &pmic_gpio_pinmux_ops; | ||
846 | pctrldesc->confops = &pmic_gpio_pinconf_ops; | ||
847 | pctrldesc->owner = THIS_MODULE; | ||
848 | pctrldesc->name = dev_name(dev); | ||
849 | pctrldesc->pins = pindesc; | ||
850 | pctrldesc->npins = npins; | ||
851 | |||
852 | for (i = 0; i < npins; i++, pindesc++) { | ||
853 | pad = &pads[i]; | ||
854 | pindesc->drv_data = pad; | ||
855 | pindesc->number = i; | ||
856 | pindesc->name = pmic_gpio_groups[i]; | ||
857 | |||
858 | pad->irq = platform_get_irq(pdev, i); | ||
859 | if (pad->irq < 0) | ||
860 | return pad->irq; | ||
861 | |||
862 | pad->base = res[0] + i * PMIC_GPIO_ADDRESS_RANGE; | ||
863 | |||
864 | ret = pmic_gpio_populate(state, pad); | ||
865 | if (ret < 0) | ||
866 | return ret; | ||
867 | } | ||
868 | |||
869 | state->chip = pmic_gpio_gpio_template; | ||
870 | state->chip.dev = dev; | ||
871 | state->chip.base = -1; | ||
872 | state->chip.ngpio = npins; | ||
873 | state->chip.label = dev_name(dev); | ||
874 | state->chip.of_gpio_n_cells = 2; | ||
875 | state->chip.can_sleep = false; | ||
876 | |||
877 | state->ctrl = pinctrl_register(pctrldesc, dev, state); | ||
878 | if (!state->ctrl) | ||
879 | return -ENODEV; | ||
880 | |||
881 | ret = gpiochip_add(&state->chip); | ||
882 | if (ret) { | ||
883 | dev_err(state->dev, "can't add gpio chip\n"); | ||
884 | goto err_chip; | ||
885 | } | ||
886 | |||
887 | ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins); | ||
888 | if (ret) { | ||
889 | dev_err(dev, "failed to add pin range\n"); | ||
890 | goto err_range; | ||
891 | } | ||
892 | |||
893 | return 0; | ||
894 | |||
895 | err_range: | ||
896 | gpiochip_remove(&state->chip); | ||
897 | err_chip: | ||
898 | pinctrl_unregister(state->ctrl); | ||
899 | return ret; | ||
900 | } | ||
901 | |||
902 | static int pmic_gpio_remove(struct platform_device *pdev) | ||
903 | { | ||
904 | struct pmic_gpio_state *state = platform_get_drvdata(pdev); | ||
905 | |||
906 | gpiochip_remove(&state->chip); | ||
907 | pinctrl_unregister(state->ctrl); | ||
908 | return 0; | ||
909 | } | ||
910 | |||
911 | static const struct of_device_id pmic_gpio_of_match[] = { | ||
912 | { .compatible = "qcom,pm8941-gpio" }, /* 36 GPIO's */ | ||
913 | { .compatible = "qcom,pma8084-gpio" }, /* 22 GPIO's */ | ||
914 | { }, | ||
915 | }; | ||
916 | |||
917 | MODULE_DEVICE_TABLE(of, pmic_gpio_of_match); | ||
918 | |||
919 | static struct platform_driver pmic_gpio_driver = { | ||
920 | .driver = { | ||
921 | .name = "qcom-spmi-gpio", | ||
922 | .of_match_table = pmic_gpio_of_match, | ||
923 | }, | ||
924 | .probe = pmic_gpio_probe, | ||
925 | .remove = pmic_gpio_remove, | ||
926 | }; | ||
927 | |||
928 | module_platform_driver(pmic_gpio_driver); | ||
929 | |||
930 | MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>"); | ||
931 | MODULE_DESCRIPTION("Qualcomm SPMI PMIC GPIO pin control driver"); | ||
932 | MODULE_ALIAS("platform:qcom-spmi-gpio"); | ||
933 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c new file mode 100644 index 000000000000..a8924dba335e --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | |||
@@ -0,0 +1,949 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/pinctrl/pinconf-generic.h> | ||
18 | #include <linux/pinctrl/pinconf.h> | ||
19 | #include <linux/pinctrl/pinmux.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/regmap.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/types.h> | ||
24 | |||
25 | #include <dt-bindings/pinctrl/qcom,pmic-mpp.h> | ||
26 | |||
27 | #include "../core.h" | ||
28 | #include "../pinctrl-utils.h" | ||
29 | |||
30 | #define PMIC_MPP_ADDRESS_RANGE 0x100 | ||
31 | |||
32 | /* | ||
33 | * Pull Up Values - it indicates whether a pull-up should be | ||
34 | * applied for bidirectional mode only. The hardware ignores the | ||
35 | * configuration when operating in other modes. | ||
36 | */ | ||
37 | #define PMIC_MPP_PULL_UP_0P6KOHM 0 | ||
38 | #define PMIC_MPP_PULL_UP_10KOHM 1 | ||
39 | #define PMIC_MPP_PULL_UP_30KOHM 2 | ||
40 | #define PMIC_MPP_PULL_UP_OPEN 3 | ||
41 | |||
42 | /* type registers base address bases */ | ||
43 | #define PMIC_MPP_REG_TYPE 0x4 | ||
44 | #define PMIC_MPP_REG_SUBTYPE 0x5 | ||
45 | |||
46 | /* mpp peripheral type and subtype values */ | ||
47 | #define PMIC_MPP_TYPE 0x11 | ||
48 | #define PMIC_MPP_SUBTYPE_4CH_NO_ANA_OUT 0x3 | ||
49 | #define PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT 0x4 | ||
50 | #define PMIC_MPP_SUBTYPE_4CH_NO_SINK 0x5 | ||
51 | #define PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK 0x6 | ||
52 | #define PMIC_MPP_SUBTYPE_4CH_FULL_FUNC 0x7 | ||
53 | #define PMIC_MPP_SUBTYPE_8CH_FULL_FUNC 0xf | ||
54 | |||
55 | #define PMIC_MPP_REG_RT_STS 0x10 | ||
56 | #define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1 | ||
57 | |||
58 | /* control register base address bases */ | ||
59 | #define PMIC_MPP_REG_MODE_CTL 0x40 | ||
60 | #define PMIC_MPP_REG_DIG_VIN_CTL 0x41 | ||
61 | #define PMIC_MPP_REG_DIG_PULL_CTL 0x42 | ||
62 | #define PMIC_MPP_REG_DIG_IN_CTL 0x43 | ||
63 | #define PMIC_MPP_REG_EN_CTL 0x46 | ||
64 | #define PMIC_MPP_REG_AIN_CTL 0x4a | ||
65 | |||
66 | /* PMIC_MPP_REG_MODE_CTL */ | ||
67 | #define PMIC_MPP_REG_MODE_VALUE_MASK 0x1 | ||
68 | #define PMIC_MPP_REG_MODE_FUNCTION_SHIFT 1 | ||
69 | #define PMIC_MPP_REG_MODE_FUNCTION_MASK 0x7 | ||
70 | #define PMIC_MPP_REG_MODE_DIR_SHIFT 4 | ||
71 | #define PMIC_MPP_REG_MODE_DIR_MASK 0x7 | ||
72 | |||
73 | /* PMIC_MPP_REG_DIG_VIN_CTL */ | ||
74 | #define PMIC_MPP_REG_VIN_SHIFT 0 | ||
75 | #define PMIC_MPP_REG_VIN_MASK 0x7 | ||
76 | |||
77 | /* PMIC_MPP_REG_DIG_PULL_CTL */ | ||
78 | #define PMIC_MPP_REG_PULL_SHIFT 0 | ||
79 | #define PMIC_MPP_REG_PULL_MASK 0x7 | ||
80 | |||
81 | /* PMIC_MPP_REG_EN_CTL */ | ||
82 | #define PMIC_MPP_REG_MASTER_EN_SHIFT 7 | ||
83 | |||
84 | /* PMIC_MPP_REG_AIN_CTL */ | ||
85 | #define PMIC_MPP_REG_AIN_ROUTE_SHIFT 0 | ||
86 | #define PMIC_MPP_REG_AIN_ROUTE_MASK 0x7 | ||
87 | |||
88 | #define PMIC_MPP_PHYSICAL_OFFSET 1 | ||
89 | |||
90 | /* Qualcomm specific pin configurations */ | ||
91 | #define PMIC_MPP_CONF_AMUX_ROUTE (PIN_CONFIG_END + 1) | ||
92 | #define PMIC_MPP_CONF_ANALOG_MODE (PIN_CONFIG_END + 2) | ||
93 | |||
94 | /** | ||
95 | * struct pmic_mpp_pad - keep current MPP settings | ||
96 | * @base: Address base in SPMI device. | ||
97 | * @irq: IRQ number which this MPP generate. | ||
98 | * @is_enabled: Set to false when MPP should be put in high Z state. | ||
99 | * @out_value: Cached pin output value. | ||
100 | * @output_enabled: Set to true if MPP output logic is enabled. | ||
101 | * @input_enabled: Set to true if MPP input buffer logic is enabled. | ||
102 | * @analog_mode: Set to true when MPP should operate in Analog Input, Analog | ||
103 | * Output or Bidirectional Analog mode. | ||
104 | * @num_sources: Number of power-sources supported by this MPP. | ||
105 | * @power_source: Current power-source used. | ||
106 | * @amux_input: Set the source for analog input. | ||
107 | * @pullup: Pullup resistor value. Valid in Bidirectional mode only. | ||
108 | * @function: See pmic_mpp_functions[]. | ||
109 | */ | ||
110 | struct pmic_mpp_pad { | ||
111 | u16 base; | ||
112 | int irq; | ||
113 | bool is_enabled; | ||
114 | bool out_value; | ||
115 | bool output_enabled; | ||
116 | bool input_enabled; | ||
117 | bool analog_mode; | ||
118 | unsigned int num_sources; | ||
119 | unsigned int power_source; | ||
120 | unsigned int amux_input; | ||
121 | unsigned int pullup; | ||
122 | unsigned int function; | ||
123 | }; | ||
124 | |||
125 | struct pmic_mpp_state { | ||
126 | struct device *dev; | ||
127 | struct regmap *map; | ||
128 | struct pinctrl_dev *ctrl; | ||
129 | struct gpio_chip chip; | ||
130 | }; | ||
131 | |||
132 | struct pmic_mpp_bindings { | ||
133 | const char *property; | ||
134 | unsigned param; | ||
135 | }; | ||
136 | |||
137 | static struct pmic_mpp_bindings pmic_mpp_bindings[] = { | ||
138 | {"qcom,amux-route", PMIC_MPP_CONF_AMUX_ROUTE}, | ||
139 | {"qcom,analog-mode", PMIC_MPP_CONF_ANALOG_MODE}, | ||
140 | }; | ||
141 | |||
142 | static const char *const pmic_mpp_groups[] = { | ||
143 | "mpp1", "mpp2", "mpp3", "mpp4", "mpp5", "mpp6", "mpp7", "mpp8", | ||
144 | }; | ||
145 | |||
146 | static const char *const pmic_mpp_functions[] = { | ||
147 | PMIC_MPP_FUNC_NORMAL, PMIC_MPP_FUNC_PAIRED, | ||
148 | "reserved1", "reserved2", | ||
149 | PMIC_MPP_FUNC_DTEST1, PMIC_MPP_FUNC_DTEST2, | ||
150 | PMIC_MPP_FUNC_DTEST3, PMIC_MPP_FUNC_DTEST4, | ||
151 | }; | ||
152 | |||
153 | static inline struct pmic_mpp_state *to_mpp_state(struct gpio_chip *chip) | ||
154 | { | ||
155 | return container_of(chip, struct pmic_mpp_state, chip); | ||
156 | }; | ||
157 | |||
158 | static int pmic_mpp_read(struct pmic_mpp_state *state, | ||
159 | struct pmic_mpp_pad *pad, unsigned int addr) | ||
160 | { | ||
161 | unsigned int val; | ||
162 | int ret; | ||
163 | |||
164 | ret = regmap_read(state->map, pad->base + addr, &val); | ||
165 | if (ret < 0) | ||
166 | dev_err(state->dev, "read 0x%x failed\n", addr); | ||
167 | else | ||
168 | ret = val; | ||
169 | |||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static int pmic_mpp_write(struct pmic_mpp_state *state, | ||
174 | struct pmic_mpp_pad *pad, unsigned int addr, | ||
175 | unsigned int val) | ||
176 | { | ||
177 | int ret; | ||
178 | |||
179 | ret = regmap_write(state->map, pad->base + addr, val); | ||
180 | if (ret < 0) | ||
181 | dev_err(state->dev, "write 0x%x failed\n", addr); | ||
182 | |||
183 | return ret; | ||
184 | } | ||
185 | |||
186 | static int pmic_mpp_get_groups_count(struct pinctrl_dev *pctldev) | ||
187 | { | ||
188 | /* Every PIN is a group */ | ||
189 | return pctldev->desc->npins; | ||
190 | } | ||
191 | |||
192 | static const char *pmic_mpp_get_group_name(struct pinctrl_dev *pctldev, | ||
193 | unsigned pin) | ||
194 | { | ||
195 | return pctldev->desc->pins[pin].name; | ||
196 | } | ||
197 | |||
198 | static int pmic_mpp_get_group_pins(struct pinctrl_dev *pctldev, | ||
199 | unsigned pin, | ||
200 | const unsigned **pins, unsigned *num_pins) | ||
201 | { | ||
202 | *pins = &pctldev->desc->pins[pin].number; | ||
203 | *num_pins = 1; | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int pmic_mpp_parse_dt_config(struct device_node *np, | ||
208 | struct pinctrl_dev *pctldev, | ||
209 | unsigned long **configs, | ||
210 | unsigned int *nconfs) | ||
211 | { | ||
212 | struct pmic_mpp_bindings *par; | ||
213 | unsigned long cfg; | ||
214 | int ret, i; | ||
215 | u32 val; | ||
216 | |||
217 | for (i = 0; i < ARRAY_SIZE(pmic_mpp_bindings); i++) { | ||
218 | par = &pmic_mpp_bindings[i]; | ||
219 | ret = of_property_read_u32(np, par->property, &val); | ||
220 | |||
221 | /* property not found */ | ||
222 | if (ret == -EINVAL) | ||
223 | continue; | ||
224 | |||
225 | /* use zero as default value, when no value is specified */ | ||
226 | if (ret) | ||
227 | val = 0; | ||
228 | |||
229 | dev_dbg(pctldev->dev, "found %s with value %u\n", | ||
230 | par->property, val); | ||
231 | |||
232 | cfg = pinconf_to_config_packed(par->param, val); | ||
233 | |||
234 | ret = pinctrl_utils_add_config(pctldev, configs, nconfs, cfg); | ||
235 | if (ret) | ||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static int pmic_mpp_dt_subnode_to_map(struct pinctrl_dev *pctldev, | ||
243 | struct device_node *np, | ||
244 | struct pinctrl_map **map, | ||
245 | unsigned *reserv, unsigned *nmaps, | ||
246 | enum pinctrl_map_type type) | ||
247 | { | ||
248 | unsigned long *configs = NULL; | ||
249 | unsigned nconfs = 0; | ||
250 | struct property *prop; | ||
251 | const char *group; | ||
252 | int ret; | ||
253 | |||
254 | ret = pmic_mpp_parse_dt_config(np, pctldev, &configs, &nconfs); | ||
255 | if (ret < 0) | ||
256 | return ret; | ||
257 | |||
258 | if (!nconfs) | ||
259 | return 0; | ||
260 | |||
261 | ret = of_property_count_strings(np, "pins"); | ||
262 | if (ret < 0) | ||
263 | goto exit; | ||
264 | |||
265 | ret = pinctrl_utils_reserve_map(pctldev, map, reserv, nmaps, ret); | ||
266 | if (ret < 0) | ||
267 | goto exit; | ||
268 | |||
269 | of_property_for_each_string(np, "pins", prop, group) { | ||
270 | ret = pinctrl_utils_add_map_configs(pctldev, map, | ||
271 | reserv, nmaps, group, | ||
272 | configs, nconfs, type); | ||
273 | if (ret < 0) | ||
274 | break; | ||
275 | } | ||
276 | exit: | ||
277 | kfree(configs); | ||
278 | return ret; | ||
279 | } | ||
280 | |||
281 | static int pmic_mpp_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
282 | struct device_node *np_config, | ||
283 | struct pinctrl_map **map, unsigned *nmaps) | ||
284 | { | ||
285 | struct device_node *np; | ||
286 | enum pinctrl_map_type type; | ||
287 | unsigned reserv; | ||
288 | int ret; | ||
289 | |||
290 | ret = 0; | ||
291 | *map = NULL; | ||
292 | *nmaps = 0; | ||
293 | reserv = 0; | ||
294 | type = PIN_MAP_TYPE_CONFIGS_GROUP; | ||
295 | |||
296 | for_each_child_of_node(np_config, np) { | ||
297 | ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map, | ||
298 | &reserv, nmaps, type); | ||
299 | if (ret) | ||
300 | break; | ||
301 | |||
302 | ret = pmic_mpp_dt_subnode_to_map(pctldev, np, map, &reserv, | ||
303 | nmaps, type); | ||
304 | if (ret) | ||
305 | break; | ||
306 | } | ||
307 | |||
308 | if (ret < 0) | ||
309 | pinctrl_utils_dt_free_map(pctldev, *map, *nmaps); | ||
310 | |||
311 | return ret; | ||
312 | } | ||
313 | |||
314 | static const struct pinctrl_ops pmic_mpp_pinctrl_ops = { | ||
315 | .get_groups_count = pmic_mpp_get_groups_count, | ||
316 | .get_group_name = pmic_mpp_get_group_name, | ||
317 | .get_group_pins = pmic_mpp_get_group_pins, | ||
318 | .dt_node_to_map = pmic_mpp_dt_node_to_map, | ||
319 | .dt_free_map = pinctrl_utils_dt_free_map, | ||
320 | }; | ||
321 | |||
322 | static int pmic_mpp_get_functions_count(struct pinctrl_dev *pctldev) | ||
323 | { | ||
324 | return ARRAY_SIZE(pmic_mpp_functions); | ||
325 | } | ||
326 | |||
327 | static const char *pmic_mpp_get_function_name(struct pinctrl_dev *pctldev, | ||
328 | unsigned function) | ||
329 | { | ||
330 | return pmic_mpp_functions[function]; | ||
331 | } | ||
332 | |||
333 | static int pmic_mpp_get_function_groups(struct pinctrl_dev *pctldev, | ||
334 | unsigned function, | ||
335 | const char *const **groups, | ||
336 | unsigned *const num_qgroups) | ||
337 | { | ||
338 | *groups = pmic_mpp_groups; | ||
339 | *num_qgroups = pctldev->desc->npins; | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static int pmic_mpp_set_mux(struct pinctrl_dev *pctldev, unsigned function, | ||
344 | unsigned pin) | ||
345 | { | ||
346 | struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev); | ||
347 | struct pmic_mpp_pad *pad; | ||
348 | unsigned int val; | ||
349 | int ret; | ||
350 | |||
351 | pad = pctldev->desc->pins[pin].drv_data; | ||
352 | |||
353 | pad->function = function; | ||
354 | |||
355 | if (!pad->analog_mode) { | ||
356 | val = 0; /* just digital input */ | ||
357 | if (pad->output_enabled) { | ||
358 | if (pad->input_enabled) | ||
359 | val = 2; /* digital input and output */ | ||
360 | else | ||
361 | val = 1; /* just digital output */ | ||
362 | } | ||
363 | } else { | ||
364 | val = 4; /* just analog input */ | ||
365 | if (pad->output_enabled) { | ||
366 | if (pad->input_enabled) | ||
367 | val = 3; /* analog input and output */ | ||
368 | else | ||
369 | val = 5; /* just analog output */ | ||
370 | } | ||
371 | } | ||
372 | |||
373 | val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT; | ||
374 | val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK; | ||
375 | |||
376 | ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val); | ||
377 | if (ret < 0) | ||
378 | return ret; | ||
379 | |||
380 | val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT; | ||
381 | |||
382 | return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val); | ||
383 | } | ||
384 | |||
385 | static const struct pinmux_ops pmic_mpp_pinmux_ops = { | ||
386 | .get_functions_count = pmic_mpp_get_functions_count, | ||
387 | .get_function_name = pmic_mpp_get_function_name, | ||
388 | .get_function_groups = pmic_mpp_get_function_groups, | ||
389 | .set_mux = pmic_mpp_set_mux, | ||
390 | }; | ||
391 | |||
392 | static int pmic_mpp_config_get(struct pinctrl_dev *pctldev, | ||
393 | unsigned int pin, unsigned long *config) | ||
394 | { | ||
395 | unsigned param = pinconf_to_config_param(*config); | ||
396 | struct pmic_mpp_pad *pad; | ||
397 | unsigned arg = 0; | ||
398 | |||
399 | pad = pctldev->desc->pins[pin].drv_data; | ||
400 | |||
401 | switch (param) { | ||
402 | case PIN_CONFIG_BIAS_DISABLE: | ||
403 | arg = pad->pullup == PMIC_MPP_PULL_UP_OPEN; | ||
404 | break; | ||
405 | case PIN_CONFIG_BIAS_PULL_UP: | ||
406 | switch (pad->pullup) { | ||
407 | case PMIC_MPP_PULL_UP_OPEN: | ||
408 | arg = 0; | ||
409 | break; | ||
410 | case PMIC_MPP_PULL_UP_0P6KOHM: | ||
411 | arg = 600; | ||
412 | break; | ||
413 | case PMIC_MPP_PULL_UP_10KOHM: | ||
414 | arg = 10000; | ||
415 | break; | ||
416 | case PMIC_MPP_PULL_UP_30KOHM: | ||
417 | arg = 30000; | ||
418 | break; | ||
419 | default: | ||
420 | return -EINVAL; | ||
421 | } | ||
422 | break; | ||
423 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: | ||
424 | arg = !pad->is_enabled; | ||
425 | break; | ||
426 | case PIN_CONFIG_POWER_SOURCE: | ||
427 | arg = pad->power_source; | ||
428 | break; | ||
429 | case PIN_CONFIG_INPUT_ENABLE: | ||
430 | arg = pad->input_enabled; | ||
431 | break; | ||
432 | case PIN_CONFIG_OUTPUT: | ||
433 | arg = pad->out_value; | ||
434 | break; | ||
435 | case PMIC_MPP_CONF_AMUX_ROUTE: | ||
436 | arg = pad->amux_input; | ||
437 | break; | ||
438 | case PMIC_MPP_CONF_ANALOG_MODE: | ||
439 | arg = pad->analog_mode; | ||
440 | break; | ||
441 | default: | ||
442 | return -EINVAL; | ||
443 | } | ||
444 | |||
445 | /* Convert register value to pinconf value */ | ||
446 | *config = pinconf_to_config_packed(param, arg); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin, | ||
451 | unsigned long *configs, unsigned nconfs) | ||
452 | { | ||
453 | struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev); | ||
454 | struct pmic_mpp_pad *pad; | ||
455 | unsigned param, arg; | ||
456 | unsigned int val; | ||
457 | int i, ret; | ||
458 | |||
459 | pad = pctldev->desc->pins[pin].drv_data; | ||
460 | |||
461 | for (i = 0; i < nconfs; i++) { | ||
462 | param = pinconf_to_config_param(configs[i]); | ||
463 | arg = pinconf_to_config_argument(configs[i]); | ||
464 | |||
465 | switch (param) { | ||
466 | case PIN_CONFIG_BIAS_DISABLE: | ||
467 | pad->pullup = PMIC_MPP_PULL_UP_OPEN; | ||
468 | break; | ||
469 | case PIN_CONFIG_BIAS_PULL_UP: | ||
470 | switch (arg) { | ||
471 | case 600: | ||
472 | pad->pullup = PMIC_MPP_PULL_UP_0P6KOHM; | ||
473 | break; | ||
474 | case 10000: | ||
475 | pad->pullup = PMIC_MPP_PULL_UP_10KOHM; | ||
476 | break; | ||
477 | case 30000: | ||
478 | pad->pullup = PMIC_MPP_PULL_UP_30KOHM; | ||
479 | break; | ||
480 | default: | ||
481 | return -EINVAL; | ||
482 | } | ||
483 | break; | ||
484 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: | ||
485 | pad->is_enabled = false; | ||
486 | break; | ||
487 | case PIN_CONFIG_POWER_SOURCE: | ||
488 | if (arg >= pad->num_sources) | ||
489 | return -EINVAL; | ||
490 | pad->power_source = arg; | ||
491 | break; | ||
492 | case PIN_CONFIG_INPUT_ENABLE: | ||
493 | pad->input_enabled = arg ? true : false; | ||
494 | break; | ||
495 | case PIN_CONFIG_OUTPUT: | ||
496 | pad->output_enabled = true; | ||
497 | pad->out_value = arg; | ||
498 | break; | ||
499 | case PMIC_MPP_CONF_AMUX_ROUTE: | ||
500 | if (arg >= PMIC_MPP_AMUX_ROUTE_ABUS4) | ||
501 | return -EINVAL; | ||
502 | pad->amux_input = arg; | ||
503 | break; | ||
504 | case PMIC_MPP_CONF_ANALOG_MODE: | ||
505 | pad->analog_mode = true; | ||
506 | break; | ||
507 | default: | ||
508 | return -EINVAL; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | val = pad->power_source << PMIC_MPP_REG_VIN_SHIFT; | ||
513 | |||
514 | ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_VIN_CTL, val); | ||
515 | if (ret < 0) | ||
516 | return ret; | ||
517 | |||
518 | val = pad->pullup << PMIC_MPP_REG_PULL_SHIFT; | ||
519 | |||
520 | ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_PULL_CTL, val); | ||
521 | if (ret < 0) | ||
522 | return ret; | ||
523 | |||
524 | val = pad->amux_input & PMIC_MPP_REG_AIN_ROUTE_MASK; | ||
525 | |||
526 | ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AIN_CTL, val); | ||
527 | if (ret < 0) | ||
528 | return ret; | ||
529 | |||
530 | if (!pad->analog_mode) { | ||
531 | val = 0; /* just digital input */ | ||
532 | if (pad->output_enabled) { | ||
533 | if (pad->input_enabled) | ||
534 | val = 2; /* digital input and output */ | ||
535 | else | ||
536 | val = 1; /* just digital output */ | ||
537 | } | ||
538 | } else { | ||
539 | val = 4; /* just analog input */ | ||
540 | if (pad->output_enabled) { | ||
541 | if (pad->input_enabled) | ||
542 | val = 3; /* analog input and output */ | ||
543 | else | ||
544 | val = 5; /* just analog output */ | ||
545 | } | ||
546 | } | ||
547 | |||
548 | val = val << PMIC_MPP_REG_MODE_DIR_SHIFT; | ||
549 | val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT; | ||
550 | val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK; | ||
551 | |||
552 | return pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val); | ||
553 | } | ||
554 | |||
555 | static void pmic_mpp_config_dbg_show(struct pinctrl_dev *pctldev, | ||
556 | struct seq_file *s, unsigned pin) | ||
557 | { | ||
558 | struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev); | ||
559 | struct pmic_mpp_pad *pad; | ||
560 | int ret, val; | ||
561 | |||
562 | static const char *const biases[] = { | ||
563 | "0.6kOhm", "10kOhm", "30kOhm", "Disabled" | ||
564 | }; | ||
565 | |||
566 | |||
567 | pad = pctldev->desc->pins[pin].drv_data; | ||
568 | |||
569 | seq_printf(s, " mpp%-2d:", pin + PMIC_MPP_PHYSICAL_OFFSET); | ||
570 | |||
571 | val = pmic_mpp_read(state, pad, PMIC_MPP_REG_EN_CTL); | ||
572 | |||
573 | if (val < 0 || !(val >> PMIC_MPP_REG_MASTER_EN_SHIFT)) { | ||
574 | seq_puts(s, " ---"); | ||
575 | } else { | ||
576 | |||
577 | if (pad->input_enabled) { | ||
578 | ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS); | ||
579 | if (!ret) { | ||
580 | ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; | ||
581 | pad->out_value = ret; | ||
582 | } | ||
583 | } | ||
584 | |||
585 | seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); | ||
586 | seq_printf(s, " %-4s", pad->analog_mode ? "ana" : "dig"); | ||
587 | seq_printf(s, " %-7s", pmic_mpp_functions[pad->function]); | ||
588 | seq_printf(s, " vin-%d", pad->power_source); | ||
589 | seq_printf(s, " %-8s", biases[pad->pullup]); | ||
590 | seq_printf(s, " %-4s", pad->out_value ? "high" : "low"); | ||
591 | } | ||
592 | } | ||
593 | |||
594 | static const struct pinconf_ops pmic_mpp_pinconf_ops = { | ||
595 | .pin_config_group_get = pmic_mpp_config_get, | ||
596 | .pin_config_group_set = pmic_mpp_config_set, | ||
597 | .pin_config_group_dbg_show = pmic_mpp_config_dbg_show, | ||
598 | }; | ||
599 | |||
600 | static int pmic_mpp_direction_input(struct gpio_chip *chip, unsigned pin) | ||
601 | { | ||
602 | struct pmic_mpp_state *state = to_mpp_state(chip); | ||
603 | unsigned long config; | ||
604 | |||
605 | config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1); | ||
606 | |||
607 | return pmic_mpp_config_set(state->ctrl, pin, &config, 1); | ||
608 | } | ||
609 | |||
610 | static int pmic_mpp_direction_output(struct gpio_chip *chip, | ||
611 | unsigned pin, int val) | ||
612 | { | ||
613 | struct pmic_mpp_state *state = to_mpp_state(chip); | ||
614 | unsigned long config; | ||
615 | |||
616 | config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val); | ||
617 | |||
618 | return pmic_mpp_config_set(state->ctrl, pin, &config, 1); | ||
619 | } | ||
620 | |||
621 | static int pmic_mpp_get(struct gpio_chip *chip, unsigned pin) | ||
622 | { | ||
623 | struct pmic_mpp_state *state = to_mpp_state(chip); | ||
624 | struct pmic_mpp_pad *pad; | ||
625 | int ret; | ||
626 | |||
627 | pad = state->ctrl->desc->pins[pin].drv_data; | ||
628 | |||
629 | if (pad->input_enabled) { | ||
630 | ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS); | ||
631 | if (ret < 0) | ||
632 | return ret; | ||
633 | |||
634 | pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK; | ||
635 | } | ||
636 | |||
637 | return pad->out_value; | ||
638 | } | ||
639 | |||
640 | static void pmic_mpp_set(struct gpio_chip *chip, unsigned pin, int value) | ||
641 | { | ||
642 | struct pmic_mpp_state *state = to_mpp_state(chip); | ||
643 | unsigned long config; | ||
644 | |||
645 | config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value); | ||
646 | |||
647 | pmic_mpp_config_set(state->ctrl, pin, &config, 1); | ||
648 | } | ||
649 | |||
650 | static int pmic_mpp_request(struct gpio_chip *chip, unsigned base) | ||
651 | { | ||
652 | return pinctrl_request_gpio(chip->base + base); | ||
653 | } | ||
654 | |||
655 | static void pmic_mpp_free(struct gpio_chip *chip, unsigned base) | ||
656 | { | ||
657 | pinctrl_free_gpio(chip->base + base); | ||
658 | } | ||
659 | |||
660 | static int pmic_mpp_of_xlate(struct gpio_chip *chip, | ||
661 | const struct of_phandle_args *gpio_desc, | ||
662 | u32 *flags) | ||
663 | { | ||
664 | if (chip->of_gpio_n_cells < 2) | ||
665 | return -EINVAL; | ||
666 | |||
667 | if (flags) | ||
668 | *flags = gpio_desc->args[1]; | ||
669 | |||
670 | return gpio_desc->args[0] - PMIC_MPP_PHYSICAL_OFFSET; | ||
671 | } | ||
672 | |||
673 | static int pmic_mpp_to_irq(struct gpio_chip *chip, unsigned pin) | ||
674 | { | ||
675 | struct pmic_mpp_state *state = to_mpp_state(chip); | ||
676 | struct pmic_mpp_pad *pad; | ||
677 | |||
678 | pad = state->ctrl->desc->pins[pin].drv_data; | ||
679 | |||
680 | return pad->irq; | ||
681 | } | ||
682 | |||
683 | static void pmic_mpp_dbg_show(struct seq_file *s, struct gpio_chip *chip) | ||
684 | { | ||
685 | struct pmic_mpp_state *state = to_mpp_state(chip); | ||
686 | unsigned i; | ||
687 | |||
688 | for (i = 0; i < chip->ngpio; i++) { | ||
689 | pmic_mpp_config_dbg_show(state->ctrl, s, i); | ||
690 | seq_puts(s, "\n"); | ||
691 | } | ||
692 | } | ||
693 | |||
694 | static const struct gpio_chip pmic_mpp_gpio_template = { | ||
695 | .direction_input = pmic_mpp_direction_input, | ||
696 | .direction_output = pmic_mpp_direction_output, | ||
697 | .get = pmic_mpp_get, | ||
698 | .set = pmic_mpp_set, | ||
699 | .request = pmic_mpp_request, | ||
700 | .free = pmic_mpp_free, | ||
701 | .of_xlate = pmic_mpp_of_xlate, | ||
702 | .to_irq = pmic_mpp_to_irq, | ||
703 | .dbg_show = pmic_mpp_dbg_show, | ||
704 | }; | ||
705 | |||
706 | static int pmic_mpp_populate(struct pmic_mpp_state *state, | ||
707 | struct pmic_mpp_pad *pad) | ||
708 | { | ||
709 | int type, subtype, val, dir; | ||
710 | |||
711 | type = pmic_mpp_read(state, pad, PMIC_MPP_REG_TYPE); | ||
712 | if (type < 0) | ||
713 | return type; | ||
714 | |||
715 | if (type != PMIC_MPP_TYPE) { | ||
716 | dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n", | ||
717 | type, pad->base); | ||
718 | return -ENODEV; | ||
719 | } | ||
720 | |||
721 | subtype = pmic_mpp_read(state, pad, PMIC_MPP_REG_SUBTYPE); | ||
722 | if (subtype < 0) | ||
723 | return subtype; | ||
724 | |||
725 | switch (subtype) { | ||
726 | case PMIC_MPP_SUBTYPE_4CH_NO_ANA_OUT: | ||
727 | case PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT: | ||
728 | case PMIC_MPP_SUBTYPE_4CH_NO_SINK: | ||
729 | case PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK: | ||
730 | case PMIC_MPP_SUBTYPE_4CH_FULL_FUNC: | ||
731 | pad->num_sources = 4; | ||
732 | break; | ||
733 | case PMIC_MPP_SUBTYPE_8CH_FULL_FUNC: | ||
734 | pad->num_sources = 8; | ||
735 | break; | ||
736 | default: | ||
737 | dev_err(state->dev, "unknown MPP type 0x%x at 0x%x\n", | ||
738 | subtype, pad->base); | ||
739 | return -ENODEV; | ||
740 | } | ||
741 | |||
742 | val = pmic_mpp_read(state, pad, PMIC_MPP_REG_MODE_CTL); | ||
743 | if (val < 0) | ||
744 | return val; | ||
745 | |||
746 | pad->out_value = val & PMIC_MPP_REG_MODE_VALUE_MASK; | ||
747 | |||
748 | dir = val >> PMIC_MPP_REG_MODE_DIR_SHIFT; | ||
749 | dir &= PMIC_MPP_REG_MODE_DIR_MASK; | ||
750 | |||
751 | switch (dir) { | ||
752 | case 0: | ||
753 | pad->input_enabled = true; | ||
754 | pad->output_enabled = false; | ||
755 | pad->analog_mode = false; | ||
756 | break; | ||
757 | case 1: | ||
758 | pad->input_enabled = false; | ||
759 | pad->output_enabled = true; | ||
760 | pad->analog_mode = false; | ||
761 | break; | ||
762 | case 2: | ||
763 | pad->input_enabled = true; | ||
764 | pad->output_enabled = true; | ||
765 | pad->analog_mode = false; | ||
766 | break; | ||
767 | case 3: | ||
768 | pad->input_enabled = true; | ||
769 | pad->output_enabled = true; | ||
770 | pad->analog_mode = true; | ||
771 | break; | ||
772 | case 4: | ||
773 | pad->input_enabled = true; | ||
774 | pad->output_enabled = false; | ||
775 | pad->analog_mode = true; | ||
776 | break; | ||
777 | case 5: | ||
778 | pad->input_enabled = false; | ||
779 | pad->output_enabled = true; | ||
780 | pad->analog_mode = true; | ||
781 | break; | ||
782 | default: | ||
783 | dev_err(state->dev, "unknown MPP direction\n"); | ||
784 | return -ENODEV; | ||
785 | } | ||
786 | |||
787 | pad->function = val >> PMIC_MPP_REG_MODE_FUNCTION_SHIFT; | ||
788 | pad->function &= PMIC_MPP_REG_MODE_FUNCTION_MASK; | ||
789 | |||
790 | val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_VIN_CTL); | ||
791 | if (val < 0) | ||
792 | return val; | ||
793 | |||
794 | pad->power_source = val >> PMIC_MPP_REG_VIN_SHIFT; | ||
795 | pad->power_source &= PMIC_MPP_REG_VIN_MASK; | ||
796 | |||
797 | val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_PULL_CTL); | ||
798 | if (val < 0) | ||
799 | return val; | ||
800 | |||
801 | pad->pullup = val >> PMIC_MPP_REG_PULL_SHIFT; | ||
802 | pad->pullup &= PMIC_MPP_REG_PULL_MASK; | ||
803 | |||
804 | val = pmic_mpp_read(state, pad, PMIC_MPP_REG_AIN_CTL); | ||
805 | if (val < 0) | ||
806 | return val; | ||
807 | |||
808 | pad->amux_input = val >> PMIC_MPP_REG_AIN_ROUTE_SHIFT; | ||
809 | pad->amux_input &= PMIC_MPP_REG_AIN_ROUTE_MASK; | ||
810 | |||
811 | /* Pin could be disabled with PIN_CONFIG_BIAS_HIGH_IMPEDANCE */ | ||
812 | pad->is_enabled = true; | ||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | static int pmic_mpp_probe(struct platform_device *pdev) | ||
817 | { | ||
818 | struct device *dev = &pdev->dev; | ||
819 | struct pinctrl_pin_desc *pindesc; | ||
820 | struct pinctrl_desc *pctrldesc; | ||
821 | struct pmic_mpp_pad *pad, *pads; | ||
822 | struct pmic_mpp_state *state; | ||
823 | int ret, npins, i; | ||
824 | u32 res[2]; | ||
825 | |||
826 | ret = of_property_read_u32_array(dev->of_node, "reg", res, 2); | ||
827 | if (ret < 0) { | ||
828 | dev_err(dev, "missing base address and/or range"); | ||
829 | return ret; | ||
830 | } | ||
831 | |||
832 | npins = res[1] / PMIC_MPP_ADDRESS_RANGE; | ||
833 | if (!npins) | ||
834 | return -EINVAL; | ||
835 | |||
836 | BUG_ON(npins > ARRAY_SIZE(pmic_mpp_groups)); | ||
837 | |||
838 | state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); | ||
839 | if (!state) | ||
840 | return -ENOMEM; | ||
841 | |||
842 | platform_set_drvdata(pdev, state); | ||
843 | |||
844 | state->dev = &pdev->dev; | ||
845 | state->map = dev_get_regmap(dev->parent, NULL); | ||
846 | |||
847 | pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL); | ||
848 | if (!pindesc) | ||
849 | return -ENOMEM; | ||
850 | |||
851 | pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL); | ||
852 | if (!pads) | ||
853 | return -ENOMEM; | ||
854 | |||
855 | pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL); | ||
856 | if (!pctrldesc) | ||
857 | return -ENOMEM; | ||
858 | |||
859 | pctrldesc->pctlops = &pmic_mpp_pinctrl_ops; | ||
860 | pctrldesc->pmxops = &pmic_mpp_pinmux_ops; | ||
861 | pctrldesc->confops = &pmic_mpp_pinconf_ops; | ||
862 | pctrldesc->owner = THIS_MODULE; | ||
863 | pctrldesc->name = dev_name(dev); | ||
864 | pctrldesc->pins = pindesc; | ||
865 | pctrldesc->npins = npins; | ||
866 | |||
867 | for (i = 0; i < npins; i++, pindesc++) { | ||
868 | pad = &pads[i]; | ||
869 | pindesc->drv_data = pad; | ||
870 | pindesc->number = i; | ||
871 | pindesc->name = pmic_mpp_groups[i]; | ||
872 | |||
873 | pad->irq = platform_get_irq(pdev, i); | ||
874 | if (pad->irq < 0) | ||
875 | return pad->irq; | ||
876 | |||
877 | pad->base = res[0] + i * PMIC_MPP_ADDRESS_RANGE; | ||
878 | |||
879 | ret = pmic_mpp_populate(state, pad); | ||
880 | if (ret < 0) | ||
881 | return ret; | ||
882 | } | ||
883 | |||
884 | state->chip = pmic_mpp_gpio_template; | ||
885 | state->chip.dev = dev; | ||
886 | state->chip.base = -1; | ||
887 | state->chip.ngpio = npins; | ||
888 | state->chip.label = dev_name(dev); | ||
889 | state->chip.of_gpio_n_cells = 2; | ||
890 | state->chip.can_sleep = false; | ||
891 | |||
892 | state->ctrl = pinctrl_register(pctrldesc, dev, state); | ||
893 | if (!state->ctrl) | ||
894 | return -ENODEV; | ||
895 | |||
896 | ret = gpiochip_add(&state->chip); | ||
897 | if (ret) { | ||
898 | dev_err(state->dev, "can't add gpio chip\n"); | ||
899 | goto err_chip; | ||
900 | } | ||
901 | |||
902 | ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins); | ||
903 | if (ret) { | ||
904 | dev_err(dev, "failed to add pin range\n"); | ||
905 | goto err_range; | ||
906 | } | ||
907 | |||
908 | return 0; | ||
909 | |||
910 | err_range: | ||
911 | gpiochip_remove(&state->chip); | ||
912 | err_chip: | ||
913 | pinctrl_unregister(state->ctrl); | ||
914 | return ret; | ||
915 | } | ||
916 | |||
917 | static int pmic_mpp_remove(struct platform_device *pdev) | ||
918 | { | ||
919 | struct pmic_mpp_state *state = platform_get_drvdata(pdev); | ||
920 | |||
921 | gpiochip_remove(&state->chip); | ||
922 | pinctrl_unregister(state->ctrl); | ||
923 | return 0; | ||
924 | } | ||
925 | |||
926 | static const struct of_device_id pmic_mpp_of_match[] = { | ||
927 | { .compatible = "qcom,pm8841-mpp" }, /* 4 MPP's */ | ||
928 | { .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */ | ||
929 | { .compatible = "qcom,pma8084-mpp" }, /* 8 MPP's */ | ||
930 | { }, | ||
931 | }; | ||
932 | |||
933 | MODULE_DEVICE_TABLE(of, pmic_mpp_of_match); | ||
934 | |||
935 | static struct platform_driver pmic_mpp_driver = { | ||
936 | .driver = { | ||
937 | .name = "qcom-spmi-mpp", | ||
938 | .of_match_table = pmic_mpp_of_match, | ||
939 | }, | ||
940 | .probe = pmic_mpp_probe, | ||
941 | .remove = pmic_mpp_remove, | ||
942 | }; | ||
943 | |||
944 | module_platform_driver(pmic_mpp_driver); | ||
945 | |||
946 | MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>"); | ||
947 | MODULE_DESCRIPTION("Qualcomm SPMI PMIC MPP pin control driver"); | ||
948 | MODULE_ALIAS("platform:qcom-spmi-mpp"); | ||
949 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index d7154ed0b0eb..d5d4cfc55873 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c | |||
@@ -46,22 +46,16 @@ static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip) | |||
46 | return container_of(chip, struct exynos_irq_chip, chip); | 46 | return container_of(chip, struct exynos_irq_chip, chip); |
47 | } | 47 | } |
48 | 48 | ||
49 | static struct samsung_pin_bank_type bank_type_off = { | 49 | static const struct samsung_pin_bank_type bank_type_off = { |
50 | .fld_width = { 4, 1, 2, 2, 2, 2, }, | 50 | .fld_width = { 4, 1, 2, 2, 2, 2, }, |
51 | .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, }, | 51 | .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, }, |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static struct samsung_pin_bank_type bank_type_alive = { | 54 | static const struct samsung_pin_bank_type bank_type_alive = { |
55 | .fld_width = { 4, 1, 2, 2, }, | 55 | .fld_width = { 4, 1, 2, 2, }, |
56 | .reg_offset = { 0x00, 0x04, 0x08, 0x0c, }, | 56 | .reg_offset = { 0x00, 0x04, 0x08, 0x0c, }, |
57 | }; | 57 | }; |
58 | 58 | ||
59 | /* list of external wakeup controllers supported */ | ||
60 | static const struct of_device_id exynos_wkup_irq_ids[] = { | ||
61 | { .compatible = "samsung,exynos4210-wakeup-eint", }, | ||
62 | { } | ||
63 | }; | ||
64 | |||
65 | static void exynos_irq_mask(struct irq_data *irqd) | 59 | static void exynos_irq_mask(struct irq_data *irqd) |
66 | { | 60 | { |
67 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); | 61 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); |
@@ -171,7 +165,7 @@ static int exynos_irq_request_resources(struct irq_data *irqd) | |||
171 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); | 165 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); |
172 | struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); | 166 | struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); |
173 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); | 167 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
174 | struct samsung_pin_bank_type *bank_type = bank->type; | 168 | const struct samsung_pin_bank_type *bank_type = bank->type; |
175 | struct samsung_pinctrl_drv_data *d = bank->drvdata; | 169 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
176 | unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; | 170 | unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; |
177 | unsigned long reg_con = our_chip->eint_con + bank->eint_offset; | 171 | unsigned long reg_con = our_chip->eint_con + bank->eint_offset; |
@@ -210,7 +204,7 @@ static void exynos_irq_release_resources(struct irq_data *irqd) | |||
210 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); | 204 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); |
211 | struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); | 205 | struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); |
212 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); | 206 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
213 | struct samsung_pin_bank_type *bank_type = bank->type; | 207 | const struct samsung_pin_bank_type *bank_type = bank->type; |
214 | struct samsung_pinctrl_drv_data *d = bank->drvdata; | 208 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
215 | unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; | 209 | unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; |
216 | unsigned long reg_con = our_chip->eint_con + bank->eint_offset; | 210 | unsigned long reg_con = our_chip->eint_con + bank->eint_offset; |
@@ -254,31 +248,30 @@ static struct exynos_irq_chip exynos_gpio_irq_chip = { | |||
254 | .eint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 248 | .eint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
255 | }; | 249 | }; |
256 | 250 | ||
257 | static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, | 251 | static int exynos_eint_irq_map(struct irq_domain *h, unsigned int virq, |
258 | irq_hw_number_t hw) | 252 | irq_hw_number_t hw) |
259 | { | 253 | { |
260 | struct samsung_pin_bank *b = h->host_data; | 254 | struct samsung_pin_bank *b = h->host_data; |
261 | 255 | ||
262 | irq_set_chip_data(virq, b); | 256 | irq_set_chip_data(virq, b); |
263 | irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip, | 257 | irq_set_chip_and_handler(virq, &b->irq_chip->chip, |
264 | handle_level_irq); | 258 | handle_level_irq); |
265 | set_irq_flags(virq, IRQF_VALID); | 259 | set_irq_flags(virq, IRQF_VALID); |
266 | return 0; | 260 | return 0; |
267 | } | 261 | } |
268 | 262 | ||
269 | /* | 263 | /* |
270 | * irq domain callbacks for external gpio interrupt controller. | 264 | * irq domain callbacks for external gpio and wakeup interrupt controllers. |
271 | */ | 265 | */ |
272 | static const struct irq_domain_ops exynos_gpio_irqd_ops = { | 266 | static const struct irq_domain_ops exynos_eint_irqd_ops = { |
273 | .map = exynos_gpio_irq_map, | 267 | .map = exynos_eint_irq_map, |
274 | .xlate = irq_domain_xlate_twocell, | 268 | .xlate = irq_domain_xlate_twocell, |
275 | }; | 269 | }; |
276 | 270 | ||
277 | static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) | 271 | static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) |
278 | { | 272 | { |
279 | struct samsung_pinctrl_drv_data *d = data; | 273 | struct samsung_pinctrl_drv_data *d = data; |
280 | struct samsung_pin_ctrl *ctrl = d->ctrl; | 274 | struct samsung_pin_bank *bank = d->pin_banks; |
281 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
282 | unsigned int svc, group, pin, virq; | 275 | unsigned int svc, group, pin, virq; |
283 | 276 | ||
284 | svc = readl(d->virt_base + EXYNOS_SVC_OFFSET); | 277 | svc = readl(d->virt_base + EXYNOS_SVC_OFFSET); |
@@ -325,12 +318,12 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
325 | return -ENXIO; | 318 | return -ENXIO; |
326 | } | 319 | } |
327 | 320 | ||
328 | bank = d->ctrl->pin_banks; | 321 | bank = d->pin_banks; |
329 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | 322 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
330 | if (bank->eint_type != EINT_TYPE_GPIO) | 323 | if (bank->eint_type != EINT_TYPE_GPIO) |
331 | continue; | 324 | continue; |
332 | bank->irq_domain = irq_domain_add_linear(bank->of_node, | 325 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
333 | bank->nr_pins, &exynos_gpio_irqd_ops, bank); | 326 | bank->nr_pins, &exynos_eint_irqd_ops, bank); |
334 | if (!bank->irq_domain) { | 327 | if (!bank->irq_domain) { |
335 | dev_err(dev, "gpio irq domain add failed\n"); | 328 | dev_err(dev, "gpio irq domain add failed\n"); |
336 | ret = -ENXIO; | 329 | ret = -ENXIO; |
@@ -344,6 +337,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
344 | ret = -ENOMEM; | 337 | ret = -ENOMEM; |
345 | goto err_domains; | 338 | goto err_domains; |
346 | } | 339 | } |
340 | |||
341 | bank->irq_chip = &exynos_gpio_irq_chip; | ||
347 | } | 342 | } |
348 | 343 | ||
349 | return 0; | 344 | return 0; |
@@ -383,9 +378,9 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on) | |||
383 | /* | 378 | /* |
384 | * irq_chip for wakeup interrupts | 379 | * irq_chip for wakeup interrupts |
385 | */ | 380 | */ |
386 | static struct exynos_irq_chip exynos_wkup_irq_chip = { | 381 | static struct exynos_irq_chip exynos4210_wkup_irq_chip __initdata = { |
387 | .chip = { | 382 | .chip = { |
388 | .name = "exynos_wkup_irq_chip", | 383 | .name = "exynos4210_wkup_irq_chip", |
389 | .irq_unmask = exynos_irq_unmask, | 384 | .irq_unmask = exynos_irq_unmask, |
390 | .irq_mask = exynos_irq_mask, | 385 | .irq_mask = exynos_irq_mask, |
391 | .irq_ack = exynos_irq_ack, | 386 | .irq_ack = exynos_irq_ack, |
@@ -399,6 +394,31 @@ static struct exynos_irq_chip exynos_wkup_irq_chip = { | |||
399 | .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, | 394 | .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, |
400 | }; | 395 | }; |
401 | 396 | ||
397 | static struct exynos_irq_chip exynos7_wkup_irq_chip __initdata = { | ||
398 | .chip = { | ||
399 | .name = "exynos7_wkup_irq_chip", | ||
400 | .irq_unmask = exynos_irq_unmask, | ||
401 | .irq_mask = exynos_irq_mask, | ||
402 | .irq_ack = exynos_irq_ack, | ||
403 | .irq_set_type = exynos_irq_set_type, | ||
404 | .irq_set_wake = exynos_wkup_irq_set_wake, | ||
405 | .irq_request_resources = exynos_irq_request_resources, | ||
406 | .irq_release_resources = exynos_irq_release_resources, | ||
407 | }, | ||
408 | .eint_con = EXYNOS7_WKUP_ECON_OFFSET, | ||
409 | .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET, | ||
410 | .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET, | ||
411 | }; | ||
412 | |||
413 | /* list of external wakeup controllers supported */ | ||
414 | static const struct of_device_id exynos_wkup_irq_ids[] = { | ||
415 | { .compatible = "samsung,exynos4210-wakeup-eint", | ||
416 | .data = &exynos4210_wkup_irq_chip }, | ||
417 | { .compatible = "samsung,exynos7-wakeup-eint", | ||
418 | .data = &exynos7_wkup_irq_chip }, | ||
419 | { } | ||
420 | }; | ||
421 | |||
402 | /* interrupt handler for wakeup interrupts 0..15 */ | 422 | /* interrupt handler for wakeup interrupts 0..15 */ |
403 | static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | 423 | static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) |
404 | { | 424 | { |
@@ -445,9 +465,9 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | |||
445 | 465 | ||
446 | for (i = 0; i < eintd->nr_banks; ++i) { | 466 | for (i = 0; i < eintd->nr_banks; ++i) { |
447 | struct samsung_pin_bank *b = eintd->banks[i]; | 467 | struct samsung_pin_bank *b = eintd->banks[i]; |
448 | pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET | 468 | pend = readl(d->virt_base + b->irq_chip->eint_pend |
449 | + b->eint_offset); | 469 | + b->eint_offset); |
450 | mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET | 470 | mask = readl(d->virt_base + b->irq_chip->eint_mask |
451 | + b->eint_offset); | 471 | + b->eint_offset); |
452 | exynos_irq_demux_eint(pend & ~mask, b->irq_domain); | 472 | exynos_irq_demux_eint(pend & ~mask, b->irq_domain); |
453 | } | 473 | } |
@@ -455,24 +475,6 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | |||
455 | chained_irq_exit(chip, desc); | 475 | chained_irq_exit(chip, desc); |
456 | } | 476 | } |
457 | 477 | ||
458 | static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq, | ||
459 | irq_hw_number_t hw) | ||
460 | { | ||
461 | irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip, | ||
462 | handle_level_irq); | ||
463 | irq_set_chip_data(virq, h->host_data); | ||
464 | set_irq_flags(virq, IRQF_VALID); | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | /* | ||
469 | * irq domain callbacks for external wakeup interrupt controller. | ||
470 | */ | ||
471 | static const struct irq_domain_ops exynos_wkup_irqd_ops = { | ||
472 | .map = exynos_wkup_irq_map, | ||
473 | .xlate = irq_domain_xlate_twocell, | ||
474 | }; | ||
475 | |||
476 | /* | 478 | /* |
477 | * exynos_eint_wkup_init() - setup handling of external wakeup interrupts. | 479 | * exynos_eint_wkup_init() - setup handling of external wakeup interrupts. |
478 | * @d: driver data of samsung pinctrl driver. | 480 | * @d: driver data of samsung pinctrl driver. |
@@ -485,12 +487,18 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
485 | struct samsung_pin_bank *bank; | 487 | struct samsung_pin_bank *bank; |
486 | struct exynos_weint_data *weint_data; | 488 | struct exynos_weint_data *weint_data; |
487 | struct exynos_muxed_weint_data *muxed_data; | 489 | struct exynos_muxed_weint_data *muxed_data; |
490 | struct exynos_irq_chip *irq_chip; | ||
488 | unsigned int muxed_banks = 0; | 491 | unsigned int muxed_banks = 0; |
489 | unsigned int i; | 492 | unsigned int i; |
490 | int idx, irq; | 493 | int idx, irq; |
491 | 494 | ||
492 | for_each_child_of_node(dev->of_node, np) { | 495 | for_each_child_of_node(dev->of_node, np) { |
493 | if (of_match_node(exynos_wkup_irq_ids, np)) { | 496 | const struct of_device_id *match; |
497 | |||
498 | match = of_match_node(exynos_wkup_irq_ids, np); | ||
499 | if (match) { | ||
500 | irq_chip = kmemdup(match->data, | ||
501 | sizeof(*irq_chip), GFP_KERNEL); | ||
494 | wkup_np = np; | 502 | wkup_np = np; |
495 | break; | 503 | break; |
496 | } | 504 | } |
@@ -498,18 +506,20 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
498 | if (!wkup_np) | 506 | if (!wkup_np) |
499 | return -ENODEV; | 507 | return -ENODEV; |
500 | 508 | ||
501 | bank = d->ctrl->pin_banks; | 509 | bank = d->pin_banks; |
502 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | 510 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
503 | if (bank->eint_type != EINT_TYPE_WKUP) | 511 | if (bank->eint_type != EINT_TYPE_WKUP) |
504 | continue; | 512 | continue; |
505 | 513 | ||
506 | bank->irq_domain = irq_domain_add_linear(bank->of_node, | 514 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
507 | bank->nr_pins, &exynos_wkup_irqd_ops, bank); | 515 | bank->nr_pins, &exynos_eint_irqd_ops, bank); |
508 | if (!bank->irq_domain) { | 516 | if (!bank->irq_domain) { |
509 | dev_err(dev, "wkup irq domain add failed\n"); | 517 | dev_err(dev, "wkup irq domain add failed\n"); |
510 | return -ENXIO; | 518 | return -ENXIO; |
511 | } | 519 | } |
512 | 520 | ||
521 | bank->irq_chip = irq_chip; | ||
522 | |||
513 | if (!of_find_property(bank->of_node, "interrupts", NULL)) { | 523 | if (!of_find_property(bank->of_node, "interrupts", NULL)) { |
514 | bank->eint_type = EINT_TYPE_WKUP_MUX; | 524 | bank->eint_type = EINT_TYPE_WKUP_MUX; |
515 | ++muxed_banks; | 525 | ++muxed_banks; |
@@ -556,9 +566,9 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
556 | irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); | 566 | irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); |
557 | irq_set_handler_data(irq, muxed_data); | 567 | irq_set_handler_data(irq, muxed_data); |
558 | 568 | ||
559 | bank = d->ctrl->pin_banks; | 569 | bank = d->pin_banks; |
560 | idx = 0; | 570 | idx = 0; |
561 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | 571 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
562 | if (bank->eint_type != EINT_TYPE_WKUP_MUX) | 572 | if (bank->eint_type != EINT_TYPE_WKUP_MUX) |
563 | continue; | 573 | continue; |
564 | 574 | ||
@@ -590,11 +600,10 @@ static void exynos_pinctrl_suspend_bank( | |||
590 | 600 | ||
591 | static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) | 601 | static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) |
592 | { | 602 | { |
593 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | 603 | struct samsung_pin_bank *bank = drvdata->pin_banks; |
594 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
595 | int i; | 604 | int i; |
596 | 605 | ||
597 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) | 606 | for (i = 0; i < drvdata->nr_banks; ++i, ++bank) |
598 | if (bank->eint_type == EINT_TYPE_GPIO) | 607 | if (bank->eint_type == EINT_TYPE_GPIO) |
599 | exynos_pinctrl_suspend_bank(drvdata, bank); | 608 | exynos_pinctrl_suspend_bank(drvdata, bank); |
600 | } | 609 | } |
@@ -626,17 +635,16 @@ static void exynos_pinctrl_resume_bank( | |||
626 | 635 | ||
627 | static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) | 636 | static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) |
628 | { | 637 | { |
629 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | 638 | struct samsung_pin_bank *bank = drvdata->pin_banks; |
630 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
631 | int i; | 639 | int i; |
632 | 640 | ||
633 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) | 641 | for (i = 0; i < drvdata->nr_banks; ++i, ++bank) |
634 | if (bank->eint_type == EINT_TYPE_GPIO) | 642 | if (bank->eint_type == EINT_TYPE_GPIO) |
635 | exynos_pinctrl_resume_bank(drvdata, bank); | 643 | exynos_pinctrl_resume_bank(drvdata, bank); |
636 | } | 644 | } |
637 | 645 | ||
638 | /* pin banks of s5pv210 pin-controller */ | 646 | /* pin banks of s5pv210 pin-controller */ |
639 | static struct samsung_pin_bank s5pv210_pin_bank[] = { | 647 | static const struct samsung_pin_bank_data s5pv210_pin_bank[] __initconst = { |
640 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 648 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
641 | EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpa1", 0x04), | 649 | EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpa1", 0x04), |
642 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), | 650 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), |
@@ -673,7 +681,7 @@ static struct samsung_pin_bank s5pv210_pin_bank[] = { | |||
673 | EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c), | 681 | EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c), |
674 | }; | 682 | }; |
675 | 683 | ||
676 | struct samsung_pin_ctrl s5pv210_pin_ctrl[] = { | 684 | const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = { |
677 | { | 685 | { |
678 | /* pin-controller instance 0 data */ | 686 | /* pin-controller instance 0 data */ |
679 | .pin_banks = s5pv210_pin_bank, | 687 | .pin_banks = s5pv210_pin_bank, |
@@ -682,12 +690,11 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = { | |||
682 | .eint_wkup_init = exynos_eint_wkup_init, | 690 | .eint_wkup_init = exynos_eint_wkup_init, |
683 | .suspend = exynos_pinctrl_suspend, | 691 | .suspend = exynos_pinctrl_suspend, |
684 | .resume = exynos_pinctrl_resume, | 692 | .resume = exynos_pinctrl_resume, |
685 | .label = "s5pv210-gpio-ctrl0", | ||
686 | }, | 693 | }, |
687 | }; | 694 | }; |
688 | 695 | ||
689 | /* pin banks of exynos3250 pin-controller 0 */ | 696 | /* pin banks of exynos3250 pin-controller 0 */ |
690 | static struct samsung_pin_bank exynos3250_pin_banks0[] = { | 697 | static const struct samsung_pin_bank_data exynos3250_pin_banks0[] __initconst = { |
691 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 698 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
692 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), | 699 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), |
693 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), | 700 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), |
@@ -698,7 +705,7 @@ static struct samsung_pin_bank exynos3250_pin_banks0[] = { | |||
698 | }; | 705 | }; |
699 | 706 | ||
700 | /* pin banks of exynos3250 pin-controller 1 */ | 707 | /* pin banks of exynos3250 pin-controller 1 */ |
701 | static struct samsung_pin_bank exynos3250_pin_banks1[] = { | 708 | static const struct samsung_pin_bank_data exynos3250_pin_banks1[] __initconst = { |
702 | EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpe0"), | 709 | EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpe0"), |
703 | EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpe1"), | 710 | EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpe1"), |
704 | EXYNOS_PIN_BANK_EINTN(3, 0x180, "gpe2"), | 711 | EXYNOS_PIN_BANK_EINTN(3, 0x180, "gpe2"), |
@@ -721,7 +728,7 @@ static struct samsung_pin_bank exynos3250_pin_banks1[] = { | |||
721 | * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes | 728 | * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes |
722 | * two gpio/pin-mux/pinconfig controllers. | 729 | * two gpio/pin-mux/pinconfig controllers. |
723 | */ | 730 | */ |
724 | struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { | 731 | const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = { |
725 | { | 732 | { |
726 | /* pin-controller instance 0 data */ | 733 | /* pin-controller instance 0 data */ |
727 | .pin_banks = exynos3250_pin_banks0, | 734 | .pin_banks = exynos3250_pin_banks0, |
@@ -729,7 +736,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { | |||
729 | .eint_gpio_init = exynos_eint_gpio_init, | 736 | .eint_gpio_init = exynos_eint_gpio_init, |
730 | .suspend = exynos_pinctrl_suspend, | 737 | .suspend = exynos_pinctrl_suspend, |
731 | .resume = exynos_pinctrl_resume, | 738 | .resume = exynos_pinctrl_resume, |
732 | .label = "exynos3250-gpio-ctrl0", | ||
733 | }, { | 739 | }, { |
734 | /* pin-controller instance 1 data */ | 740 | /* pin-controller instance 1 data */ |
735 | .pin_banks = exynos3250_pin_banks1, | 741 | .pin_banks = exynos3250_pin_banks1, |
@@ -738,12 +744,11 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { | |||
738 | .eint_wkup_init = exynos_eint_wkup_init, | 744 | .eint_wkup_init = exynos_eint_wkup_init, |
739 | .suspend = exynos_pinctrl_suspend, | 745 | .suspend = exynos_pinctrl_suspend, |
740 | .resume = exynos_pinctrl_resume, | 746 | .resume = exynos_pinctrl_resume, |
741 | .label = "exynos3250-gpio-ctrl1", | ||
742 | }, | 747 | }, |
743 | }; | 748 | }; |
744 | 749 | ||
745 | /* pin banks of exynos4210 pin-controller 0 */ | 750 | /* pin banks of exynos4210 pin-controller 0 */ |
746 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { | 751 | static const struct samsung_pin_bank_data exynos4210_pin_banks0[] __initconst = { |
747 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 752 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
748 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), | 753 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), |
749 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), | 754 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), |
@@ -763,7 +768,7 @@ static struct samsung_pin_bank exynos4210_pin_banks0[] = { | |||
763 | }; | 768 | }; |
764 | 769 | ||
765 | /* pin banks of exynos4210 pin-controller 1 */ | 770 | /* pin banks of exynos4210 pin-controller 1 */ |
766 | static struct samsung_pin_bank exynos4210_pin_banks1[] = { | 771 | static const struct samsung_pin_bank_data exynos4210_pin_banks1[] __initconst = { |
767 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00), | 772 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00), |
768 | EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04), | 773 | EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04), |
769 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), | 774 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), |
@@ -787,7 +792,7 @@ static struct samsung_pin_bank exynos4210_pin_banks1[] = { | |||
787 | }; | 792 | }; |
788 | 793 | ||
789 | /* pin banks of exynos4210 pin-controller 2 */ | 794 | /* pin banks of exynos4210 pin-controller 2 */ |
790 | static struct samsung_pin_bank exynos4210_pin_banks2[] = { | 795 | static const struct samsung_pin_bank_data exynos4210_pin_banks2[] __initconst = { |
791 | EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"), | 796 | EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"), |
792 | }; | 797 | }; |
793 | 798 | ||
@@ -795,7 +800,7 @@ static struct samsung_pin_bank exynos4210_pin_banks2[] = { | |||
795 | * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes | 800 | * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes |
796 | * three gpio/pin-mux/pinconfig controllers. | 801 | * three gpio/pin-mux/pinconfig controllers. |
797 | */ | 802 | */ |
798 | struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | 803 | const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = { |
799 | { | 804 | { |
800 | /* pin-controller instance 0 data */ | 805 | /* pin-controller instance 0 data */ |
801 | .pin_banks = exynos4210_pin_banks0, | 806 | .pin_banks = exynos4210_pin_banks0, |
@@ -803,7 +808,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
803 | .eint_gpio_init = exynos_eint_gpio_init, | 808 | .eint_gpio_init = exynos_eint_gpio_init, |
804 | .suspend = exynos_pinctrl_suspend, | 809 | .suspend = exynos_pinctrl_suspend, |
805 | .resume = exynos_pinctrl_resume, | 810 | .resume = exynos_pinctrl_resume, |
806 | .label = "exynos4210-gpio-ctrl0", | ||
807 | }, { | 811 | }, { |
808 | /* pin-controller instance 1 data */ | 812 | /* pin-controller instance 1 data */ |
809 | .pin_banks = exynos4210_pin_banks1, | 813 | .pin_banks = exynos4210_pin_banks1, |
@@ -812,17 +816,15 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
812 | .eint_wkup_init = exynos_eint_wkup_init, | 816 | .eint_wkup_init = exynos_eint_wkup_init, |
813 | .suspend = exynos_pinctrl_suspend, | 817 | .suspend = exynos_pinctrl_suspend, |
814 | .resume = exynos_pinctrl_resume, | 818 | .resume = exynos_pinctrl_resume, |
815 | .label = "exynos4210-gpio-ctrl1", | ||
816 | }, { | 819 | }, { |
817 | /* pin-controller instance 2 data */ | 820 | /* pin-controller instance 2 data */ |
818 | .pin_banks = exynos4210_pin_banks2, | 821 | .pin_banks = exynos4210_pin_banks2, |
819 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), | 822 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), |
820 | .label = "exynos4210-gpio-ctrl2", | ||
821 | }, | 823 | }, |
822 | }; | 824 | }; |
823 | 825 | ||
824 | /* pin banks of exynos4x12 pin-controller 0 */ | 826 | /* pin banks of exynos4x12 pin-controller 0 */ |
825 | static struct samsung_pin_bank exynos4x12_pin_banks0[] = { | 827 | static const struct samsung_pin_bank_data exynos4x12_pin_banks0[] __initconst = { |
826 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 828 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
827 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), | 829 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), |
828 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), | 830 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), |
@@ -839,7 +841,7 @@ static struct samsung_pin_bank exynos4x12_pin_banks0[] = { | |||
839 | }; | 841 | }; |
840 | 842 | ||
841 | /* pin banks of exynos4x12 pin-controller 1 */ | 843 | /* pin banks of exynos4x12 pin-controller 1 */ |
842 | static struct samsung_pin_bank exynos4x12_pin_banks1[] = { | 844 | static const struct samsung_pin_bank_data exynos4x12_pin_banks1[] __initconst = { |
843 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), | 845 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), |
844 | EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), | 846 | EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), |
845 | EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), | 847 | EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), |
@@ -866,12 +868,12 @@ static struct samsung_pin_bank exynos4x12_pin_banks1[] = { | |||
866 | }; | 868 | }; |
867 | 869 | ||
868 | /* pin banks of exynos4x12 pin-controller 2 */ | 870 | /* pin banks of exynos4x12 pin-controller 2 */ |
869 | static struct samsung_pin_bank exynos4x12_pin_banks2[] = { | 871 | static const struct samsung_pin_bank_data exynos4x12_pin_banks2[] __initconst = { |
870 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), | 872 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), |
871 | }; | 873 | }; |
872 | 874 | ||
873 | /* pin banks of exynos4x12 pin-controller 3 */ | 875 | /* pin banks of exynos4x12 pin-controller 3 */ |
874 | static struct samsung_pin_bank exynos4x12_pin_banks3[] = { | 876 | static const struct samsung_pin_bank_data exynos4x12_pin_banks3[] __initconst = { |
875 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), | 877 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), |
876 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), | 878 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), |
877 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08), | 879 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08), |
@@ -883,7 +885,7 @@ static struct samsung_pin_bank exynos4x12_pin_banks3[] = { | |||
883 | * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes | 885 | * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes |
884 | * four gpio/pin-mux/pinconfig controllers. | 886 | * four gpio/pin-mux/pinconfig controllers. |
885 | */ | 887 | */ |
886 | struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | 888 | const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = { |
887 | { | 889 | { |
888 | /* pin-controller instance 0 data */ | 890 | /* pin-controller instance 0 data */ |
889 | .pin_banks = exynos4x12_pin_banks0, | 891 | .pin_banks = exynos4x12_pin_banks0, |
@@ -891,7 +893,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | |||
891 | .eint_gpio_init = exynos_eint_gpio_init, | 893 | .eint_gpio_init = exynos_eint_gpio_init, |
892 | .suspend = exynos_pinctrl_suspend, | 894 | .suspend = exynos_pinctrl_suspend, |
893 | .resume = exynos_pinctrl_resume, | 895 | .resume = exynos_pinctrl_resume, |
894 | .label = "exynos4x12-gpio-ctrl0", | ||
895 | }, { | 896 | }, { |
896 | /* pin-controller instance 1 data */ | 897 | /* pin-controller instance 1 data */ |
897 | .pin_banks = exynos4x12_pin_banks1, | 898 | .pin_banks = exynos4x12_pin_banks1, |
@@ -900,7 +901,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | |||
900 | .eint_wkup_init = exynos_eint_wkup_init, | 901 | .eint_wkup_init = exynos_eint_wkup_init, |
901 | .suspend = exynos_pinctrl_suspend, | 902 | .suspend = exynos_pinctrl_suspend, |
902 | .resume = exynos_pinctrl_resume, | 903 | .resume = exynos_pinctrl_resume, |
903 | .label = "exynos4x12-gpio-ctrl1", | ||
904 | }, { | 904 | }, { |
905 | /* pin-controller instance 2 data */ | 905 | /* pin-controller instance 2 data */ |
906 | .pin_banks = exynos4x12_pin_banks2, | 906 | .pin_banks = exynos4x12_pin_banks2, |
@@ -908,7 +908,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | |||
908 | .eint_gpio_init = exynos_eint_gpio_init, | 908 | .eint_gpio_init = exynos_eint_gpio_init, |
909 | .suspend = exynos_pinctrl_suspend, | 909 | .suspend = exynos_pinctrl_suspend, |
910 | .resume = exynos_pinctrl_resume, | 910 | .resume = exynos_pinctrl_resume, |
911 | .label = "exynos4x12-gpio-ctrl2", | ||
912 | }, { | 911 | }, { |
913 | /* pin-controller instance 3 data */ | 912 | /* pin-controller instance 3 data */ |
914 | .pin_banks = exynos4x12_pin_banks3, | 913 | .pin_banks = exynos4x12_pin_banks3, |
@@ -916,12 +915,86 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | |||
916 | .eint_gpio_init = exynos_eint_gpio_init, | 915 | .eint_gpio_init = exynos_eint_gpio_init, |
917 | .suspend = exynos_pinctrl_suspend, | 916 | .suspend = exynos_pinctrl_suspend, |
918 | .resume = exynos_pinctrl_resume, | 917 | .resume = exynos_pinctrl_resume, |
919 | .label = "exynos4x12-gpio-ctrl3", | 918 | }, |
919 | }; | ||
920 | |||
921 | /* pin banks of exynos4415 pin-controller 0 */ | ||
922 | static const struct samsung_pin_bank_data exynos4415_pin_banks0[] = { | ||
923 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | ||
924 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), | ||
925 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), | ||
926 | EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c), | ||
927 | EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10), | ||
928 | EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14), | ||
929 | EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18), | ||
930 | EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30), | ||
931 | EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34), | ||
932 | EXYNOS_PIN_BANK_EINTG(1, 0x1C0, "gpf2", 0x38), | ||
933 | }; | ||
934 | |||
935 | /* pin banks of exynos4415 pin-controller 1 */ | ||
936 | static const struct samsung_pin_bank_data exynos4415_pin_banks1[] = { | ||
937 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpk0", 0x08), | ||
938 | EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), | ||
939 | EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), | ||
940 | EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14), | ||
941 | EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpl0", 0x18), | ||
942 | EXYNOS_PIN_BANK_EINTN(6, 0x120, "mp00"), | ||
943 | EXYNOS_PIN_BANK_EINTN(4, 0x140, "mp01"), | ||
944 | EXYNOS_PIN_BANK_EINTN(6, 0x160, "mp02"), | ||
945 | EXYNOS_PIN_BANK_EINTN(8, 0x180, "mp03"), | ||
946 | EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "mp04"), | ||
947 | EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "mp05"), | ||
948 | EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "mp06"), | ||
949 | EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24), | ||
950 | EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28), | ||
951 | EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c), | ||
952 | EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30), | ||
953 | EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34), | ||
954 | EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), | ||
955 | EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), | ||
956 | EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), | ||
957 | EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), | ||
958 | }; | ||
959 | |||
960 | /* pin banks of exynos4415 pin-controller 2 */ | ||
961 | static const struct samsung_pin_bank_data exynos4415_pin_banks2[] = { | ||
962 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), | ||
963 | EXYNOS_PIN_BANK_EINTN(2, 0x000, "etc1"), | ||
964 | }; | ||
965 | |||
966 | /* | ||
967 | * Samsung pinctrl driver data for Exynos4415 SoC. Exynos4415 SoC includes | ||
968 | * three gpio/pin-mux/pinconfig controllers. | ||
969 | */ | ||
970 | const struct samsung_pin_ctrl exynos4415_pin_ctrl[] = { | ||
971 | { | ||
972 | /* pin-controller instance 0 data */ | ||
973 | .pin_banks = exynos4415_pin_banks0, | ||
974 | .nr_banks = ARRAY_SIZE(exynos4415_pin_banks0), | ||
975 | .eint_gpio_init = exynos_eint_gpio_init, | ||
976 | .suspend = exynos_pinctrl_suspend, | ||
977 | .resume = exynos_pinctrl_resume, | ||
978 | }, { | ||
979 | /* pin-controller instance 1 data */ | ||
980 | .pin_banks = exynos4415_pin_banks1, | ||
981 | .nr_banks = ARRAY_SIZE(exynos4415_pin_banks1), | ||
982 | .eint_gpio_init = exynos_eint_gpio_init, | ||
983 | .eint_wkup_init = exynos_eint_wkup_init, | ||
984 | .suspend = exynos_pinctrl_suspend, | ||
985 | .resume = exynos_pinctrl_resume, | ||
986 | }, { | ||
987 | /* pin-controller instance 2 data */ | ||
988 | .pin_banks = exynos4415_pin_banks2, | ||
989 | .nr_banks = ARRAY_SIZE(exynos4415_pin_banks2), | ||
990 | .eint_gpio_init = exynos_eint_gpio_init, | ||
991 | .suspend = exynos_pinctrl_suspend, | ||
992 | .resume = exynos_pinctrl_resume, | ||
920 | }, | 993 | }, |
921 | }; | 994 | }; |
922 | 995 | ||
923 | /* pin banks of exynos5250 pin-controller 0 */ | 996 | /* pin banks of exynos5250 pin-controller 0 */ |
924 | static struct samsung_pin_bank exynos5250_pin_banks0[] = { | 997 | static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = { |
925 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 998 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
926 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), | 999 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), |
927 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), | 1000 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), |
@@ -950,7 +1023,7 @@ static struct samsung_pin_bank exynos5250_pin_banks0[] = { | |||
950 | }; | 1023 | }; |
951 | 1024 | ||
952 | /* pin banks of exynos5250 pin-controller 1 */ | 1025 | /* pin banks of exynos5250 pin-controller 1 */ |
953 | static struct samsung_pin_bank exynos5250_pin_banks1[] = { | 1026 | static const struct samsung_pin_bank_data exynos5250_pin_banks1[] __initconst = { |
954 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00), | 1027 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00), |
955 | EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04), | 1028 | EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04), |
956 | EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08), | 1029 | EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08), |
@@ -963,7 +1036,7 @@ static struct samsung_pin_bank exynos5250_pin_banks1[] = { | |||
963 | }; | 1036 | }; |
964 | 1037 | ||
965 | /* pin banks of exynos5250 pin-controller 2 */ | 1038 | /* pin banks of exynos5250 pin-controller 2 */ |
966 | static struct samsung_pin_bank exynos5250_pin_banks2[] = { | 1039 | static const struct samsung_pin_bank_data exynos5250_pin_banks2[] __initconst = { |
967 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), | 1040 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), |
968 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), | 1041 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), |
969 | EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08), | 1042 | EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08), |
@@ -972,7 +1045,7 @@ static struct samsung_pin_bank exynos5250_pin_banks2[] = { | |||
972 | }; | 1045 | }; |
973 | 1046 | ||
974 | /* pin banks of exynos5250 pin-controller 3 */ | 1047 | /* pin banks of exynos5250 pin-controller 3 */ |
975 | static struct samsung_pin_bank exynos5250_pin_banks3[] = { | 1048 | static const struct samsung_pin_bank_data exynos5250_pin_banks3[] __initconst = { |
976 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), | 1049 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), |
977 | }; | 1050 | }; |
978 | 1051 | ||
@@ -980,7 +1053,7 @@ static struct samsung_pin_bank exynos5250_pin_banks3[] = { | |||
980 | * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes | 1053 | * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes |
981 | * four gpio/pin-mux/pinconfig controllers. | 1054 | * four gpio/pin-mux/pinconfig controllers. |
982 | */ | 1055 | */ |
983 | struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | 1056 | const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = { |
984 | { | 1057 | { |
985 | /* pin-controller instance 0 data */ | 1058 | /* pin-controller instance 0 data */ |
986 | .pin_banks = exynos5250_pin_banks0, | 1059 | .pin_banks = exynos5250_pin_banks0, |
@@ -989,7 +1062,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | |||
989 | .eint_wkup_init = exynos_eint_wkup_init, | 1062 | .eint_wkup_init = exynos_eint_wkup_init, |
990 | .suspend = exynos_pinctrl_suspend, | 1063 | .suspend = exynos_pinctrl_suspend, |
991 | .resume = exynos_pinctrl_resume, | 1064 | .resume = exynos_pinctrl_resume, |
992 | .label = "exynos5250-gpio-ctrl0", | ||
993 | }, { | 1065 | }, { |
994 | /* pin-controller instance 1 data */ | 1066 | /* pin-controller instance 1 data */ |
995 | .pin_banks = exynos5250_pin_banks1, | 1067 | .pin_banks = exynos5250_pin_banks1, |
@@ -997,7 +1069,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | |||
997 | .eint_gpio_init = exynos_eint_gpio_init, | 1069 | .eint_gpio_init = exynos_eint_gpio_init, |
998 | .suspend = exynos_pinctrl_suspend, | 1070 | .suspend = exynos_pinctrl_suspend, |
999 | .resume = exynos_pinctrl_resume, | 1071 | .resume = exynos_pinctrl_resume, |
1000 | .label = "exynos5250-gpio-ctrl1", | ||
1001 | }, { | 1072 | }, { |
1002 | /* pin-controller instance 2 data */ | 1073 | /* pin-controller instance 2 data */ |
1003 | .pin_banks = exynos5250_pin_banks2, | 1074 | .pin_banks = exynos5250_pin_banks2, |
@@ -1005,7 +1076,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | |||
1005 | .eint_gpio_init = exynos_eint_gpio_init, | 1076 | .eint_gpio_init = exynos_eint_gpio_init, |
1006 | .suspend = exynos_pinctrl_suspend, | 1077 | .suspend = exynos_pinctrl_suspend, |
1007 | .resume = exynos_pinctrl_resume, | 1078 | .resume = exynos_pinctrl_resume, |
1008 | .label = "exynos5250-gpio-ctrl2", | ||
1009 | }, { | 1079 | }, { |
1010 | /* pin-controller instance 3 data */ | 1080 | /* pin-controller instance 3 data */ |
1011 | .pin_banks = exynos5250_pin_banks3, | 1081 | .pin_banks = exynos5250_pin_banks3, |
@@ -1013,12 +1083,11 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | |||
1013 | .eint_gpio_init = exynos_eint_gpio_init, | 1083 | .eint_gpio_init = exynos_eint_gpio_init, |
1014 | .suspend = exynos_pinctrl_suspend, | 1084 | .suspend = exynos_pinctrl_suspend, |
1015 | .resume = exynos_pinctrl_resume, | 1085 | .resume = exynos_pinctrl_resume, |
1016 | .label = "exynos5250-gpio-ctrl3", | ||
1017 | }, | 1086 | }, |
1018 | }; | 1087 | }; |
1019 | 1088 | ||
1020 | /* pin banks of exynos5260 pin-controller 0 */ | 1089 | /* pin banks of exynos5260 pin-controller 0 */ |
1021 | static struct samsung_pin_bank exynos5260_pin_banks0[] = { | 1090 | static const struct samsung_pin_bank_data exynos5260_pin_banks0[] __initconst = { |
1022 | EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00), | 1091 | EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00), |
1023 | EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpa1", 0x04), | 1092 | EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpa1", 0x04), |
1024 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), | 1093 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), |
@@ -1043,7 +1112,7 @@ static struct samsung_pin_bank exynos5260_pin_banks0[] = { | |||
1043 | }; | 1112 | }; |
1044 | 1113 | ||
1045 | /* pin banks of exynos5260 pin-controller 1 */ | 1114 | /* pin banks of exynos5260 pin-controller 1 */ |
1046 | static struct samsung_pin_bank exynos5260_pin_banks1[] = { | 1115 | static const struct samsung_pin_bank_data exynos5260_pin_banks1[] __initconst = { |
1047 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpc0", 0x00), | 1116 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpc0", 0x00), |
1048 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpc1", 0x04), | 1117 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpc1", 0x04), |
1049 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08), | 1118 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08), |
@@ -1052,7 +1121,7 @@ static struct samsung_pin_bank exynos5260_pin_banks1[] = { | |||
1052 | }; | 1121 | }; |
1053 | 1122 | ||
1054 | /* pin banks of exynos5260 pin-controller 2 */ | 1123 | /* pin banks of exynos5260 pin-controller 2 */ |
1055 | static struct samsung_pin_bank exynos5260_pin_banks2[] = { | 1124 | static const struct samsung_pin_bank_data exynos5260_pin_banks2[] __initconst = { |
1056 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00), | 1125 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00), |
1057 | EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), | 1126 | EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), |
1058 | }; | 1127 | }; |
@@ -1061,31 +1130,28 @@ static struct samsung_pin_bank exynos5260_pin_banks2[] = { | |||
1061 | * Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes | 1130 | * Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes |
1062 | * three gpio/pin-mux/pinconfig controllers. | 1131 | * three gpio/pin-mux/pinconfig controllers. |
1063 | */ | 1132 | */ |
1064 | struct samsung_pin_ctrl exynos5260_pin_ctrl[] = { | 1133 | const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = { |
1065 | { | 1134 | { |
1066 | /* pin-controller instance 0 data */ | 1135 | /* pin-controller instance 0 data */ |
1067 | .pin_banks = exynos5260_pin_banks0, | 1136 | .pin_banks = exynos5260_pin_banks0, |
1068 | .nr_banks = ARRAY_SIZE(exynos5260_pin_banks0), | 1137 | .nr_banks = ARRAY_SIZE(exynos5260_pin_banks0), |
1069 | .eint_gpio_init = exynos_eint_gpio_init, | 1138 | .eint_gpio_init = exynos_eint_gpio_init, |
1070 | .eint_wkup_init = exynos_eint_wkup_init, | 1139 | .eint_wkup_init = exynos_eint_wkup_init, |
1071 | .label = "exynos5260-gpio-ctrl0", | ||
1072 | }, { | 1140 | }, { |
1073 | /* pin-controller instance 1 data */ | 1141 | /* pin-controller instance 1 data */ |
1074 | .pin_banks = exynos5260_pin_banks1, | 1142 | .pin_banks = exynos5260_pin_banks1, |
1075 | .nr_banks = ARRAY_SIZE(exynos5260_pin_banks1), | 1143 | .nr_banks = ARRAY_SIZE(exynos5260_pin_banks1), |
1076 | .eint_gpio_init = exynos_eint_gpio_init, | 1144 | .eint_gpio_init = exynos_eint_gpio_init, |
1077 | .label = "exynos5260-gpio-ctrl1", | ||
1078 | }, { | 1145 | }, { |
1079 | /* pin-controller instance 2 data */ | 1146 | /* pin-controller instance 2 data */ |
1080 | .pin_banks = exynos5260_pin_banks2, | 1147 | .pin_banks = exynos5260_pin_banks2, |
1081 | .nr_banks = ARRAY_SIZE(exynos5260_pin_banks2), | 1148 | .nr_banks = ARRAY_SIZE(exynos5260_pin_banks2), |
1082 | .eint_gpio_init = exynos_eint_gpio_init, | 1149 | .eint_gpio_init = exynos_eint_gpio_init, |
1083 | .label = "exynos5260-gpio-ctrl2", | ||
1084 | }, | 1150 | }, |
1085 | }; | 1151 | }; |
1086 | 1152 | ||
1087 | /* pin banks of exynos5420 pin-controller 0 */ | 1153 | /* pin banks of exynos5420 pin-controller 0 */ |
1088 | static struct samsung_pin_bank exynos5420_pin_banks0[] = { | 1154 | static const struct samsung_pin_bank_data exynos5420_pin_banks0[] __initconst = { |
1089 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00), | 1155 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00), |
1090 | EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), | 1156 | EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), |
1091 | EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), | 1157 | EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), |
@@ -1094,7 +1160,7 @@ static struct samsung_pin_bank exynos5420_pin_banks0[] = { | |||
1094 | }; | 1160 | }; |
1095 | 1161 | ||
1096 | /* pin banks of exynos5420 pin-controller 1 */ | 1162 | /* pin banks of exynos5420 pin-controller 1 */ |
1097 | static struct samsung_pin_bank exynos5420_pin_banks1[] = { | 1163 | static const struct samsung_pin_bank_data exynos5420_pin_banks1[] __initconst = { |
1098 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpc0", 0x00), | 1164 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpc0", 0x00), |
1099 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc1", 0x04), | 1165 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc1", 0x04), |
1100 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08), | 1166 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08), |
@@ -1111,7 +1177,7 @@ static struct samsung_pin_bank exynos5420_pin_banks1[] = { | |||
1111 | }; | 1177 | }; |
1112 | 1178 | ||
1113 | /* pin banks of exynos5420 pin-controller 2 */ | 1179 | /* pin banks of exynos5420 pin-controller 2 */ |
1114 | static struct samsung_pin_bank exynos5420_pin_banks2[] = { | 1180 | static const struct samsung_pin_bank_data exynos5420_pin_banks2[] __initconst = { |
1115 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00), | 1181 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00), |
1116 | EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04), | 1182 | EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04), |
1117 | EXYNOS_PIN_BANK_EINTG(6, 0x040, "gpf0", 0x08), | 1183 | EXYNOS_PIN_BANK_EINTG(6, 0x040, "gpf0", 0x08), |
@@ -1123,7 +1189,7 @@ static struct samsung_pin_bank exynos5420_pin_banks2[] = { | |||
1123 | }; | 1189 | }; |
1124 | 1190 | ||
1125 | /* pin banks of exynos5420 pin-controller 3 */ | 1191 | /* pin banks of exynos5420 pin-controller 3 */ |
1126 | static struct samsung_pin_bank exynos5420_pin_banks3[] = { | 1192 | static const struct samsung_pin_bank_data exynos5420_pin_banks3[] __initconst = { |
1127 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 1193 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
1128 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), | 1194 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), |
1129 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), | 1195 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), |
@@ -1136,7 +1202,7 @@ static struct samsung_pin_bank exynos5420_pin_banks3[] = { | |||
1136 | }; | 1202 | }; |
1137 | 1203 | ||
1138 | /* pin banks of exynos5420 pin-controller 4 */ | 1204 | /* pin banks of exynos5420 pin-controller 4 */ |
1139 | static struct samsung_pin_bank exynos5420_pin_banks4[] = { | 1205 | static const struct samsung_pin_bank_data exynos5420_pin_banks4[] __initconst = { |
1140 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), | 1206 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), |
1141 | }; | 1207 | }; |
1142 | 1208 | ||
@@ -1144,37 +1210,137 @@ static struct samsung_pin_bank exynos5420_pin_banks4[] = { | |||
1144 | * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes | 1210 | * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes |
1145 | * four gpio/pin-mux/pinconfig controllers. | 1211 | * four gpio/pin-mux/pinconfig controllers. |
1146 | */ | 1212 | */ |
1147 | struct samsung_pin_ctrl exynos5420_pin_ctrl[] = { | 1213 | const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { |
1148 | { | 1214 | { |
1149 | /* pin-controller instance 0 data */ | 1215 | /* pin-controller instance 0 data */ |
1150 | .pin_banks = exynos5420_pin_banks0, | 1216 | .pin_banks = exynos5420_pin_banks0, |
1151 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks0), | 1217 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks0), |
1152 | .eint_gpio_init = exynos_eint_gpio_init, | 1218 | .eint_gpio_init = exynos_eint_gpio_init, |
1153 | .eint_wkup_init = exynos_eint_wkup_init, | 1219 | .eint_wkup_init = exynos_eint_wkup_init, |
1154 | .label = "exynos5420-gpio-ctrl0", | ||
1155 | }, { | 1220 | }, { |
1156 | /* pin-controller instance 1 data */ | 1221 | /* pin-controller instance 1 data */ |
1157 | .pin_banks = exynos5420_pin_banks1, | 1222 | .pin_banks = exynos5420_pin_banks1, |
1158 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks1), | 1223 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks1), |
1159 | .eint_gpio_init = exynos_eint_gpio_init, | 1224 | .eint_gpio_init = exynos_eint_gpio_init, |
1160 | .label = "exynos5420-gpio-ctrl1", | ||
1161 | }, { | 1225 | }, { |
1162 | /* pin-controller instance 2 data */ | 1226 | /* pin-controller instance 2 data */ |
1163 | .pin_banks = exynos5420_pin_banks2, | 1227 | .pin_banks = exynos5420_pin_banks2, |
1164 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks2), | 1228 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks2), |
1165 | .eint_gpio_init = exynos_eint_gpio_init, | 1229 | .eint_gpio_init = exynos_eint_gpio_init, |
1166 | .label = "exynos5420-gpio-ctrl2", | ||
1167 | }, { | 1230 | }, { |
1168 | /* pin-controller instance 3 data */ | 1231 | /* pin-controller instance 3 data */ |
1169 | .pin_banks = exynos5420_pin_banks3, | 1232 | .pin_banks = exynos5420_pin_banks3, |
1170 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks3), | 1233 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks3), |
1171 | .eint_gpio_init = exynos_eint_gpio_init, | 1234 | .eint_gpio_init = exynos_eint_gpio_init, |
1172 | .label = "exynos5420-gpio-ctrl3", | ||
1173 | }, { | 1235 | }, { |
1174 | /* pin-controller instance 4 data */ | 1236 | /* pin-controller instance 4 data */ |
1175 | .pin_banks = exynos5420_pin_banks4, | 1237 | .pin_banks = exynos5420_pin_banks4, |
1176 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks4), | 1238 | .nr_banks = ARRAY_SIZE(exynos5420_pin_banks4), |
1177 | .eint_gpio_init = exynos_eint_gpio_init, | 1239 | .eint_gpio_init = exynos_eint_gpio_init, |
1178 | .label = "exynos5420-gpio-ctrl4", | 1240 | }, |
1241 | }; | ||
1242 | |||
1243 | /* pin banks of exynos7 pin-controller - ALIVE */ | ||
1244 | static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = { | ||
1245 | EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), | ||
1246 | EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04), | ||
1247 | EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08), | ||
1248 | EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c), | ||
1249 | }; | ||
1250 | |||
1251 | /* pin banks of exynos7 pin-controller - BUS0 */ | ||
1252 | static const struct samsung_pin_bank_data exynos7_pin_banks1[] __initconst = { | ||
1253 | EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00), | ||
1254 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc0", 0x04), | ||
1255 | EXYNOS_PIN_BANK_EINTG(2, 0x040, "gpc1", 0x08), | ||
1256 | EXYNOS_PIN_BANK_EINTG(6, 0x060, "gpc2", 0x0c), | ||
1257 | EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpc3", 0x10), | ||
1258 | EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14), | ||
1259 | EXYNOS_PIN_BANK_EINTG(6, 0x0c0, "gpd1", 0x18), | ||
1260 | EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpd2", 0x1c), | ||
1261 | EXYNOS_PIN_BANK_EINTG(5, 0x100, "gpd4", 0x20), | ||
1262 | EXYNOS_PIN_BANK_EINTG(4, 0x120, "gpd5", 0x24), | ||
1263 | EXYNOS_PIN_BANK_EINTG(6, 0x140, "gpd6", 0x28), | ||
1264 | EXYNOS_PIN_BANK_EINTG(3, 0x160, "gpd7", 0x2c), | ||
1265 | EXYNOS_PIN_BANK_EINTG(2, 0x180, "gpd8", 0x30), | ||
1266 | EXYNOS_PIN_BANK_EINTG(2, 0x1a0, "gpg0", 0x34), | ||
1267 | EXYNOS_PIN_BANK_EINTG(4, 0x1c0, "gpg3", 0x38), | ||
1268 | }; | ||
1269 | |||
1270 | /* pin banks of exynos7 pin-controller - NFC */ | ||
1271 | static const struct samsung_pin_bank_data exynos7_pin_banks2[] __initconst = { | ||
1272 | EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00), | ||
1273 | }; | ||
1274 | |||
1275 | /* pin banks of exynos7 pin-controller - TOUCH */ | ||
1276 | static const struct samsung_pin_bank_data exynos7_pin_banks3[] __initconst = { | ||
1277 | EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), | ||
1278 | }; | ||
1279 | |||
1280 | /* pin banks of exynos7 pin-controller - FF */ | ||
1281 | static const struct samsung_pin_bank_data exynos7_pin_banks4[] __initconst = { | ||
1282 | EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpg4", 0x00), | ||
1283 | }; | ||
1284 | |||
1285 | /* pin banks of exynos7 pin-controller - ESE */ | ||
1286 | static const struct samsung_pin_bank_data exynos7_pin_banks5[] __initconst = { | ||
1287 | EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpv7", 0x00), | ||
1288 | }; | ||
1289 | |||
1290 | /* pin banks of exynos7 pin-controller - FSYS0 */ | ||
1291 | static const struct samsung_pin_bank_data exynos7_pin_banks6[] __initconst = { | ||
1292 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpr4", 0x00), | ||
1293 | }; | ||
1294 | |||
1295 | /* pin banks of exynos7 pin-controller - FSYS1 */ | ||
1296 | static const struct samsung_pin_bank_data exynos7_pin_banks7[] __initconst = { | ||
1297 | EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpr0", 0x00), | ||
1298 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpr1", 0x04), | ||
1299 | EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr2", 0x08), | ||
1300 | EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr3", 0x0c), | ||
1301 | }; | ||
1302 | |||
1303 | const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = { | ||
1304 | { | ||
1305 | /* pin-controller instance 0 Alive data */ | ||
1306 | .pin_banks = exynos7_pin_banks0, | ||
1307 | .nr_banks = ARRAY_SIZE(exynos7_pin_banks0), | ||
1308 | .eint_gpio_init = exynos_eint_gpio_init, | ||
1309 | .eint_wkup_init = exynos_eint_wkup_init, | ||
1310 | }, { | ||
1311 | /* pin-controller instance 1 BUS0 data */ | ||
1312 | .pin_banks = exynos7_pin_banks1, | ||
1313 | .nr_banks = ARRAY_SIZE(exynos7_pin_banks1), | ||
1314 | .eint_gpio_init = exynos_eint_gpio_init, | ||
1315 | }, { | ||
1316 | /* pin-controller instance 2 NFC data */ | ||
1317 | .pin_banks = exynos7_pin_banks2, | ||
1318 | .nr_banks = ARRAY_SIZE(exynos7_pin_banks2), | ||
1319 | .eint_gpio_init = exynos_eint_gpio_init, | ||
1320 | }, { | ||
1321 | /* pin-controller instance 3 TOUCH data */ | ||
1322 | .pin_banks = exynos7_pin_banks3, | ||
1323 | .nr_banks = ARRAY_SIZE(exynos7_pin_banks3), | ||
1324 | .eint_gpio_init = exynos_eint_gpio_init, | ||
1325 | }, { | ||
1326 | /* pin-controller instance 4 FF data */ | ||
1327 | .pin_banks = exynos7_pin_banks4, | ||
1328 | .nr_banks = ARRAY_SIZE(exynos7_pin_banks4), | ||
1329 | .eint_gpio_init = exynos_eint_gpio_init, | ||
1330 | }, { | ||
1331 | /* pin-controller instance 5 ESE data */ | ||
1332 | .pin_banks = exynos7_pin_banks5, | ||
1333 | .nr_banks = ARRAY_SIZE(exynos7_pin_banks5), | ||
1334 | .eint_gpio_init = exynos_eint_gpio_init, | ||
1335 | }, { | ||
1336 | /* pin-controller instance 6 FSYS0 data */ | ||
1337 | .pin_banks = exynos7_pin_banks6, | ||
1338 | .nr_banks = ARRAY_SIZE(exynos7_pin_banks6), | ||
1339 | .eint_gpio_init = exynos_eint_gpio_init, | ||
1340 | }, { | ||
1341 | /* pin-controller instance 7 FSYS1 data */ | ||
1342 | .pin_banks = exynos7_pin_banks7, | ||
1343 | .nr_banks = ARRAY_SIZE(exynos7_pin_banks7), | ||
1344 | .eint_gpio_init = exynos_eint_gpio_init, | ||
1179 | }, | 1345 | }, |
1180 | }; | 1346 | }; |
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h index 3c91c357792f..0f0f7cedb2dc 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.h +++ b/drivers/pinctrl/samsung/pinctrl-exynos.h | |||
@@ -25,6 +25,9 @@ | |||
25 | #define EXYNOS_WKUP_ECON_OFFSET 0xE00 | 25 | #define EXYNOS_WKUP_ECON_OFFSET 0xE00 |
26 | #define EXYNOS_WKUP_EMASK_OFFSET 0xF00 | 26 | #define EXYNOS_WKUP_EMASK_OFFSET 0xF00 |
27 | #define EXYNOS_WKUP_EPEND_OFFSET 0xF40 | 27 | #define EXYNOS_WKUP_EPEND_OFFSET 0xF40 |
28 | #define EXYNOS7_WKUP_ECON_OFFSET 0x700 | ||
29 | #define EXYNOS7_WKUP_EMASK_OFFSET 0x900 | ||
30 | #define EXYNOS7_WKUP_EPEND_OFFSET 0xA00 | ||
28 | #define EXYNOS_SVC_OFFSET 0xB08 | 31 | #define EXYNOS_SVC_OFFSET 0xB08 |
29 | #define EXYNOS_EINT_FUNC 0xF | 32 | #define EXYNOS_EINT_FUNC 0xF |
30 | 33 | ||
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index ad3eaad17001..f1993f42114c 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c | |||
@@ -44,12 +44,12 @@ | |||
44 | #define EINT_EDGE_BOTH 6 | 44 | #define EINT_EDGE_BOTH 6 |
45 | #define EINT_MASK 0xf | 45 | #define EINT_MASK 0xf |
46 | 46 | ||
47 | static struct samsung_pin_bank_type bank_type_1bit = { | 47 | static const struct samsung_pin_bank_type bank_type_1bit = { |
48 | .fld_width = { 1, 1, }, | 48 | .fld_width = { 1, 1, }, |
49 | .reg_offset = { 0x00, 0x04, }, | 49 | .reg_offset = { 0x00, 0x04, }, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static struct samsung_pin_bank_type bank_type_2bit = { | 52 | static const struct samsung_pin_bank_type bank_type_2bit = { |
53 | .fld_width = { 2, 1, 2, }, | 53 | .fld_width = { 2, 1, 2, }, |
54 | .reg_offset = { 0x00, 0x04, 0x08, }, | 54 | .reg_offset = { 0x00, 0x04, 0x08, }, |
55 | }; | 55 | }; |
@@ -143,7 +143,7 @@ static void s3c24xx_eint_set_handler(unsigned int irq, unsigned int type) | |||
143 | static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d, | 143 | static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d, |
144 | struct samsung_pin_bank *bank, int pin) | 144 | struct samsung_pin_bank *bank, int pin) |
145 | { | 145 | { |
146 | struct samsung_pin_bank_type *bank_type = bank->type; | 146 | const struct samsung_pin_bank_type *bank_type = bank->type; |
147 | unsigned long flags; | 147 | unsigned long flags; |
148 | void __iomem *reg; | 148 | void __iomem *reg; |
149 | u8 shift; | 149 | u8 shift; |
@@ -518,8 +518,8 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d) | |||
518 | irq_set_handler_data(irq, eint_data); | 518 | irq_set_handler_data(irq, eint_data); |
519 | } | 519 | } |
520 | 520 | ||
521 | bank = d->ctrl->pin_banks; | 521 | bank = d->pin_banks; |
522 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | 522 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
523 | struct s3c24xx_eint_domain_data *ddata; | 523 | struct s3c24xx_eint_domain_data *ddata; |
524 | unsigned int mask; | 524 | unsigned int mask; |
525 | unsigned int irq; | 525 | unsigned int irq; |
@@ -561,7 +561,7 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d) | |||
561 | return 0; | 561 | return 0; |
562 | } | 562 | } |
563 | 563 | ||
564 | static struct samsung_pin_bank s3c2412_pin_banks[] = { | 564 | static const struct samsung_pin_bank_data s3c2412_pin_banks[] __initconst = { |
565 | PIN_BANK_A(23, 0x000, "gpa"), | 565 | PIN_BANK_A(23, 0x000, "gpa"), |
566 | PIN_BANK_2BIT(11, 0x010, "gpb"), | 566 | PIN_BANK_2BIT(11, 0x010, "gpb"), |
567 | PIN_BANK_2BIT(16, 0x020, "gpc"), | 567 | PIN_BANK_2BIT(16, 0x020, "gpc"), |
@@ -573,16 +573,15 @@ static struct samsung_pin_bank s3c2412_pin_banks[] = { | |||
573 | PIN_BANK_2BIT(13, 0x080, "gpj"), | 573 | PIN_BANK_2BIT(13, 0x080, "gpj"), |
574 | }; | 574 | }; |
575 | 575 | ||
576 | struct samsung_pin_ctrl s3c2412_pin_ctrl[] = { | 576 | const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = { |
577 | { | 577 | { |
578 | .pin_banks = s3c2412_pin_banks, | 578 | .pin_banks = s3c2412_pin_banks, |
579 | .nr_banks = ARRAY_SIZE(s3c2412_pin_banks), | 579 | .nr_banks = ARRAY_SIZE(s3c2412_pin_banks), |
580 | .eint_wkup_init = s3c24xx_eint_init, | 580 | .eint_wkup_init = s3c24xx_eint_init, |
581 | .label = "S3C2412-GPIO", | ||
582 | }, | 581 | }, |
583 | }; | 582 | }; |
584 | 583 | ||
585 | static struct samsung_pin_bank s3c2416_pin_banks[] = { | 584 | static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = { |
586 | PIN_BANK_A(27, 0x000, "gpa"), | 585 | PIN_BANK_A(27, 0x000, "gpa"), |
587 | PIN_BANK_2BIT(11, 0x010, "gpb"), | 586 | PIN_BANK_2BIT(11, 0x010, "gpb"), |
588 | PIN_BANK_2BIT(16, 0x020, "gpc"), | 587 | PIN_BANK_2BIT(16, 0x020, "gpc"), |
@@ -596,16 +595,15 @@ static struct samsung_pin_bank s3c2416_pin_banks[] = { | |||
596 | PIN_BANK_2BIT(2, 0x100, "gpm"), | 595 | PIN_BANK_2BIT(2, 0x100, "gpm"), |
597 | }; | 596 | }; |
598 | 597 | ||
599 | struct samsung_pin_ctrl s3c2416_pin_ctrl[] = { | 598 | const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = { |
600 | { | 599 | { |
601 | .pin_banks = s3c2416_pin_banks, | 600 | .pin_banks = s3c2416_pin_banks, |
602 | .nr_banks = ARRAY_SIZE(s3c2416_pin_banks), | 601 | .nr_banks = ARRAY_SIZE(s3c2416_pin_banks), |
603 | .eint_wkup_init = s3c24xx_eint_init, | 602 | .eint_wkup_init = s3c24xx_eint_init, |
604 | .label = "S3C2416-GPIO", | ||
605 | }, | 603 | }, |
606 | }; | 604 | }; |
607 | 605 | ||
608 | static struct samsung_pin_bank s3c2440_pin_banks[] = { | 606 | static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = { |
609 | PIN_BANK_A(25, 0x000, "gpa"), | 607 | PIN_BANK_A(25, 0x000, "gpa"), |
610 | PIN_BANK_2BIT(11, 0x010, "gpb"), | 608 | PIN_BANK_2BIT(11, 0x010, "gpb"), |
611 | PIN_BANK_2BIT(16, 0x020, "gpc"), | 609 | PIN_BANK_2BIT(16, 0x020, "gpc"), |
@@ -617,16 +615,15 @@ static struct samsung_pin_bank s3c2440_pin_banks[] = { | |||
617 | PIN_BANK_2BIT(13, 0x0d0, "gpj"), | 615 | PIN_BANK_2BIT(13, 0x0d0, "gpj"), |
618 | }; | 616 | }; |
619 | 617 | ||
620 | struct samsung_pin_ctrl s3c2440_pin_ctrl[] = { | 618 | const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = { |
621 | { | 619 | { |
622 | .pin_banks = s3c2440_pin_banks, | 620 | .pin_banks = s3c2440_pin_banks, |
623 | .nr_banks = ARRAY_SIZE(s3c2440_pin_banks), | 621 | .nr_banks = ARRAY_SIZE(s3c2440_pin_banks), |
624 | .eint_wkup_init = s3c24xx_eint_init, | 622 | .eint_wkup_init = s3c24xx_eint_init, |
625 | .label = "S3C2440-GPIO", | ||
626 | }, | 623 | }, |
627 | }; | 624 | }; |
628 | 625 | ||
629 | static struct samsung_pin_bank s3c2450_pin_banks[] = { | 626 | static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = { |
630 | PIN_BANK_A(28, 0x000, "gpa"), | 627 | PIN_BANK_A(28, 0x000, "gpa"), |
631 | PIN_BANK_2BIT(11, 0x010, "gpb"), | 628 | PIN_BANK_2BIT(11, 0x010, "gpb"), |
632 | PIN_BANK_2BIT(16, 0x020, "gpc"), | 629 | PIN_BANK_2BIT(16, 0x020, "gpc"), |
@@ -641,11 +638,10 @@ static struct samsung_pin_bank s3c2450_pin_banks[] = { | |||
641 | PIN_BANK_2BIT(2, 0x100, "gpm"), | 638 | PIN_BANK_2BIT(2, 0x100, "gpm"), |
642 | }; | 639 | }; |
643 | 640 | ||
644 | struct samsung_pin_ctrl s3c2450_pin_ctrl[] = { | 641 | const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = { |
645 | { | 642 | { |
646 | .pin_banks = s3c2450_pin_banks, | 643 | .pin_banks = s3c2450_pin_banks, |
647 | .nr_banks = ARRAY_SIZE(s3c2450_pin_banks), | 644 | .nr_banks = ARRAY_SIZE(s3c2450_pin_banks), |
648 | .eint_wkup_init = s3c24xx_eint_init, | 645 | .eint_wkup_init = s3c24xx_eint_init, |
649 | .label = "S3C2450-GPIO", | ||
650 | }, | 646 | }, |
651 | }; | 647 | }; |
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index 89143c903000..7756c1e9e763 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c | |||
@@ -68,32 +68,32 @@ | |||
68 | #define EINT_CON_MASK 0xF | 68 | #define EINT_CON_MASK 0xF |
69 | #define EINT_CON_LEN 4 | 69 | #define EINT_CON_LEN 4 |
70 | 70 | ||
71 | static struct samsung_pin_bank_type bank_type_4bit_off = { | 71 | static const struct samsung_pin_bank_type bank_type_4bit_off = { |
72 | .fld_width = { 4, 1, 2, 0, 2, 2, }, | 72 | .fld_width = { 4, 1, 2, 0, 2, 2, }, |
73 | .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, }, | 73 | .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, }, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static struct samsung_pin_bank_type bank_type_4bit_alive = { | 76 | static const struct samsung_pin_bank_type bank_type_4bit_alive = { |
77 | .fld_width = { 4, 1, 2, }, | 77 | .fld_width = { 4, 1, 2, }, |
78 | .reg_offset = { 0x00, 0x04, 0x08, }, | 78 | .reg_offset = { 0x00, 0x04, 0x08, }, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static struct samsung_pin_bank_type bank_type_4bit2_off = { | 81 | static const struct samsung_pin_bank_type bank_type_4bit2_off = { |
82 | .fld_width = { 4, 1, 2, 0, 2, 2, }, | 82 | .fld_width = { 4, 1, 2, 0, 2, 2, }, |
83 | .reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, }, | 83 | .reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, }, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static struct samsung_pin_bank_type bank_type_4bit2_alive = { | 86 | static const struct samsung_pin_bank_type bank_type_4bit2_alive = { |
87 | .fld_width = { 4, 1, 2, }, | 87 | .fld_width = { 4, 1, 2, }, |
88 | .reg_offset = { 0x00, 0x08, 0x0c, }, | 88 | .reg_offset = { 0x00, 0x08, 0x0c, }, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static struct samsung_pin_bank_type bank_type_2bit_off = { | 91 | static const struct samsung_pin_bank_type bank_type_2bit_off = { |
92 | .fld_width = { 2, 1, 2, 0, 2, 2, }, | 92 | .fld_width = { 2, 1, 2, 0, 2, 2, }, |
93 | .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, }, | 93 | .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, }, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static struct samsung_pin_bank_type bank_type_2bit_alive = { | 96 | static const struct samsung_pin_bank_type bank_type_2bit_alive = { |
97 | .fld_width = { 2, 1, 2, }, | 97 | .fld_width = { 2, 1, 2, }, |
98 | .reg_offset = { 0x00, 0x04, 0x08, }, | 98 | .reg_offset = { 0x00, 0x04, 0x08, }, |
99 | }; | 99 | }; |
@@ -272,7 +272,7 @@ static void s3c64xx_irq_set_handler(unsigned int irq, unsigned int type) | |||
272 | static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, | 272 | static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, |
273 | struct samsung_pin_bank *bank, int pin) | 273 | struct samsung_pin_bank *bank, int pin) |
274 | { | 274 | { |
275 | struct samsung_pin_bank_type *bank_type = bank->type; | 275 | const struct samsung_pin_bank_type *bank_type = bank->type; |
276 | unsigned long flags; | 276 | unsigned long flags; |
277 | void __iomem *reg; | 277 | void __iomem *reg; |
278 | u8 shift; | 278 | u8 shift; |
@@ -468,8 +468,8 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
468 | } | 468 | } |
469 | 469 | ||
470 | nr_domains = 0; | 470 | nr_domains = 0; |
471 | bank = d->ctrl->pin_banks; | 471 | bank = d->pin_banks; |
472 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | 472 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
473 | unsigned int nr_eints; | 473 | unsigned int nr_eints; |
474 | unsigned int mask; | 474 | unsigned int mask; |
475 | 475 | ||
@@ -497,9 +497,9 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
497 | } | 497 | } |
498 | data->drvdata = d; | 498 | data->drvdata = d; |
499 | 499 | ||
500 | bank = d->ctrl->pin_banks; | 500 | bank = d->pin_banks; |
501 | nr_domains = 0; | 501 | nr_domains = 0; |
502 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | 502 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
503 | if (bank->eint_type != EINT_TYPE_GPIO) | 503 | if (bank->eint_type != EINT_TYPE_GPIO) |
504 | continue; | 504 | continue; |
505 | 505 | ||
@@ -735,8 +735,8 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d) | |||
735 | irq_set_handler_data(irq, data); | 735 | irq_set_handler_data(irq, data); |
736 | } | 736 | } |
737 | 737 | ||
738 | bank = d->ctrl->pin_banks; | 738 | bank = d->pin_banks; |
739 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | 739 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
740 | struct s3c64xx_eint0_domain_data *ddata; | 740 | struct s3c64xx_eint0_domain_data *ddata; |
741 | unsigned int nr_eints; | 741 | unsigned int nr_eints; |
742 | unsigned int mask; | 742 | unsigned int mask; |
@@ -780,7 +780,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d) | |||
780 | } | 780 | } |
781 | 781 | ||
782 | /* pin banks of s3c64xx pin-controller 0 */ | 782 | /* pin banks of s3c64xx pin-controller 0 */ |
783 | static struct samsung_pin_bank s3c64xx_pin_banks0[] = { | 783 | static const struct samsung_pin_bank_data s3c64xx_pin_banks0[] __initconst = { |
784 | PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0), | 784 | PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0), |
785 | PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8), | 785 | PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8), |
786 | PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16), | 786 | PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16), |
@@ -804,13 +804,12 @@ static struct samsung_pin_bank s3c64xx_pin_banks0[] = { | |||
804 | * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes | 804 | * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes |
805 | * one gpio/pin-mux/pinconfig controller. | 805 | * one gpio/pin-mux/pinconfig controller. |
806 | */ | 806 | */ |
807 | struct samsung_pin_ctrl s3c64xx_pin_ctrl[] = { | 807 | const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = { |
808 | { | 808 | { |
809 | /* pin-controller instance 1 data */ | 809 | /* pin-controller instance 1 data */ |
810 | .pin_banks = s3c64xx_pin_banks0, | 810 | .pin_banks = s3c64xx_pin_banks0, |
811 | .nr_banks = ARRAY_SIZE(s3c64xx_pin_banks0), | 811 | .nr_banks = ARRAY_SIZE(s3c64xx_pin_banks0), |
812 | .eint_gpio_init = s3c64xx_eint_gpio_init, | 812 | .eint_gpio_init = s3c64xx_eint_gpio_init, |
813 | .eint_wkup_init = s3c64xx_eint_eint0_init, | 813 | .eint_wkup_init = s3c64xx_eint_eint0_init, |
814 | .label = "S3C64xx-GPIO", | ||
815 | }, | 814 | }, |
816 | }; | 815 | }; |
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 2d37c8f49f3c..32940a01a84f 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c | |||
@@ -349,7 +349,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, | |||
349 | { | 349 | { |
350 | struct samsung_pin_bank *b; | 350 | struct samsung_pin_bank *b; |
351 | 351 | ||
352 | b = drvdata->ctrl->pin_banks; | 352 | b = drvdata->pin_banks; |
353 | 353 | ||
354 | while ((pin >= b->pin_base) && | 354 | while ((pin >= b->pin_base) && |
355 | ((b->pin_base + b->nr_pins - 1) < pin)) | 355 | ((b->pin_base + b->nr_pins - 1) < pin)) |
@@ -366,7 +366,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, | |||
366 | unsigned group, bool enable) | 366 | unsigned group, bool enable) |
367 | { | 367 | { |
368 | struct samsung_pinctrl_drv_data *drvdata; | 368 | struct samsung_pinctrl_drv_data *drvdata; |
369 | struct samsung_pin_bank_type *type; | 369 | const struct samsung_pin_bank_type *type; |
370 | struct samsung_pin_bank *bank; | 370 | struct samsung_pin_bank *bank; |
371 | void __iomem *reg; | 371 | void __iomem *reg; |
372 | u32 mask, shift, data, pin_offset; | 372 | u32 mask, shift, data, pin_offset; |
@@ -378,7 +378,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, | |||
378 | func = &drvdata->pmx_functions[selector]; | 378 | func = &drvdata->pmx_functions[selector]; |
379 | grp = &drvdata->pin_groups[group]; | 379 | grp = &drvdata->pin_groups[group]; |
380 | 380 | ||
381 | pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base, | 381 | pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->pin_base, |
382 | ®, &pin_offset, &bank); | 382 | ®, &pin_offset, &bank); |
383 | type = bank->type; | 383 | type = bank->type; |
384 | mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; | 384 | mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; |
@@ -422,7 +422,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, | |||
422 | unsigned long *config, bool set) | 422 | unsigned long *config, bool set) |
423 | { | 423 | { |
424 | struct samsung_pinctrl_drv_data *drvdata; | 424 | struct samsung_pinctrl_drv_data *drvdata; |
425 | struct samsung_pin_bank_type *type; | 425 | const struct samsung_pin_bank_type *type; |
426 | struct samsung_pin_bank *bank; | 426 | struct samsung_pin_bank *bank; |
427 | void __iomem *reg_base; | 427 | void __iomem *reg_base; |
428 | enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config); | 428 | enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config); |
@@ -431,7 +431,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, | |||
431 | unsigned long flags; | 431 | unsigned long flags; |
432 | 432 | ||
433 | drvdata = pinctrl_dev_get_drvdata(pctldev); | 433 | drvdata = pinctrl_dev_get_drvdata(pctldev); |
434 | pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, ®_base, | 434 | pin_to_reg_bank(drvdata, pin - drvdata->pin_base, ®_base, |
435 | &pin_offset, &bank); | 435 | &pin_offset, &bank); |
436 | type = bank->type; | 436 | type = bank->type; |
437 | 437 | ||
@@ -528,7 +528,7 @@ static const struct pinconf_ops samsung_pinconf_ops = { | |||
528 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | 528 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) |
529 | { | 529 | { |
530 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | 530 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); |
531 | struct samsung_pin_bank_type *type = bank->type; | 531 | const struct samsung_pin_bank_type *type = bank->type; |
532 | unsigned long flags; | 532 | unsigned long flags; |
533 | void __iomem *reg; | 533 | void __iomem *reg; |
534 | u32 data; | 534 | u32 data; |
@@ -552,7 +552,7 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) | |||
552 | void __iomem *reg; | 552 | void __iomem *reg; |
553 | u32 data; | 553 | u32 data; |
554 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | 554 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); |
555 | struct samsung_pin_bank_type *type = bank->type; | 555 | const struct samsung_pin_bank_type *type = bank->type; |
556 | 556 | ||
557 | reg = bank->drvdata->virt_base + bank->pctl_offset; | 557 | reg = bank->drvdata->virt_base + bank->pctl_offset; |
558 | 558 | ||
@@ -569,7 +569,7 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) | |||
569 | static int samsung_gpio_set_direction(struct gpio_chip *gc, | 569 | static int samsung_gpio_set_direction(struct gpio_chip *gc, |
570 | unsigned offset, bool input) | 570 | unsigned offset, bool input) |
571 | { | 571 | { |
572 | struct samsung_pin_bank_type *type; | 572 | const struct samsung_pin_bank_type *type; |
573 | struct samsung_pin_bank *bank; | 573 | struct samsung_pin_bank *bank; |
574 | struct samsung_pinctrl_drv_data *drvdata; | 574 | struct samsung_pinctrl_drv_data *drvdata; |
575 | void __iomem *reg; | 575 | void __iomem *reg; |
@@ -834,32 +834,32 @@ static int samsung_pinctrl_register(struct platform_device *pdev, | |||
834 | ctrldesc->confops = &samsung_pinconf_ops; | 834 | ctrldesc->confops = &samsung_pinconf_ops; |
835 | 835 | ||
836 | pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * | 836 | pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * |
837 | drvdata->ctrl->nr_pins, GFP_KERNEL); | 837 | drvdata->nr_pins, GFP_KERNEL); |
838 | if (!pindesc) { | 838 | if (!pindesc) { |
839 | dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); | 839 | dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); |
840 | return -ENOMEM; | 840 | return -ENOMEM; |
841 | } | 841 | } |
842 | ctrldesc->pins = pindesc; | 842 | ctrldesc->pins = pindesc; |
843 | ctrldesc->npins = drvdata->ctrl->nr_pins; | 843 | ctrldesc->npins = drvdata->nr_pins; |
844 | 844 | ||
845 | /* dynamically populate the pin number and pin name for pindesc */ | 845 | /* dynamically populate the pin number and pin name for pindesc */ |
846 | for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++) | 846 | for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++) |
847 | pdesc->number = pin + drvdata->ctrl->base; | 847 | pdesc->number = pin + drvdata->pin_base; |
848 | 848 | ||
849 | /* | 849 | /* |
850 | * allocate space for storing the dynamically generated names for all | 850 | * allocate space for storing the dynamically generated names for all |
851 | * the pins which belong to this pin-controller. | 851 | * the pins which belong to this pin-controller. |
852 | */ | 852 | */ |
853 | pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH * | 853 | pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH * |
854 | drvdata->ctrl->nr_pins, GFP_KERNEL); | 854 | drvdata->nr_pins, GFP_KERNEL); |
855 | if (!pin_names) { | 855 | if (!pin_names) { |
856 | dev_err(&pdev->dev, "mem alloc for pin names failed\n"); | 856 | dev_err(&pdev->dev, "mem alloc for pin names failed\n"); |
857 | return -ENOMEM; | 857 | return -ENOMEM; |
858 | } | 858 | } |
859 | 859 | ||
860 | /* for each pin, the name of the pin is pin-bank name + pin number */ | 860 | /* for each pin, the name of the pin is pin-bank name + pin number */ |
861 | for (bank = 0; bank < drvdata->ctrl->nr_banks; bank++) { | 861 | for (bank = 0; bank < drvdata->nr_banks; bank++) { |
862 | pin_bank = &drvdata->ctrl->pin_banks[bank]; | 862 | pin_bank = &drvdata->pin_banks[bank]; |
863 | for (pin = 0; pin < pin_bank->nr_pins; pin++) { | 863 | for (pin = 0; pin < pin_bank->nr_pins; pin++) { |
864 | sprintf(pin_names, "%s-%d", pin_bank->name, pin); | 864 | sprintf(pin_names, "%s-%d", pin_bank->name, pin); |
865 | pdesc = pindesc + pin_bank->pin_base + pin; | 865 | pdesc = pindesc + pin_bank->pin_base + pin; |
@@ -878,11 +878,11 @@ static int samsung_pinctrl_register(struct platform_device *pdev, | |||
878 | return -EINVAL; | 878 | return -EINVAL; |
879 | } | 879 | } |
880 | 880 | ||
881 | for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) { | 881 | for (bank = 0; bank < drvdata->nr_banks; ++bank) { |
882 | pin_bank = &drvdata->ctrl->pin_banks[bank]; | 882 | pin_bank = &drvdata->pin_banks[bank]; |
883 | pin_bank->grange.name = pin_bank->name; | 883 | pin_bank->grange.name = pin_bank->name; |
884 | pin_bank->grange.id = bank; | 884 | pin_bank->grange.id = bank; |
885 | pin_bank->grange.pin_base = drvdata->ctrl->base | 885 | pin_bank->grange.pin_base = drvdata->pin_base |
886 | + pin_bank->pin_base; | 886 | + pin_bank->pin_base; |
887 | pin_bank->grange.base = pin_bank->gpio_chip.base; | 887 | pin_bank->grange.base = pin_bank->gpio_chip.base; |
888 | pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; | 888 | pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; |
@@ -918,17 +918,16 @@ static const struct gpio_chip samsung_gpiolib_chip = { | |||
918 | static int samsung_gpiolib_register(struct platform_device *pdev, | 918 | static int samsung_gpiolib_register(struct platform_device *pdev, |
919 | struct samsung_pinctrl_drv_data *drvdata) | 919 | struct samsung_pinctrl_drv_data *drvdata) |
920 | { | 920 | { |
921 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | 921 | struct samsung_pin_bank *bank = drvdata->pin_banks; |
922 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
923 | struct gpio_chip *gc; | 922 | struct gpio_chip *gc; |
924 | int ret; | 923 | int ret; |
925 | int i; | 924 | int i; |
926 | 925 | ||
927 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | 926 | for (i = 0; i < drvdata->nr_banks; ++i, ++bank) { |
928 | bank->gpio_chip = samsung_gpiolib_chip; | 927 | bank->gpio_chip = samsung_gpiolib_chip; |
929 | 928 | ||
930 | gc = &bank->gpio_chip; | 929 | gc = &bank->gpio_chip; |
931 | gc->base = ctrl->base + bank->pin_base; | 930 | gc->base = drvdata->pin_base + bank->pin_base; |
932 | gc->ngpio = bank->nr_pins; | 931 | gc->ngpio = bank->nr_pins; |
933 | gc->dev = &pdev->dev; | 932 | gc->dev = &pdev->dev; |
934 | gc->of_node = bank->of_node; | 933 | gc->of_node = bank->of_node; |
@@ -954,51 +953,70 @@ fail: | |||
954 | static int samsung_gpiolib_unregister(struct platform_device *pdev, | 953 | static int samsung_gpiolib_unregister(struct platform_device *pdev, |
955 | struct samsung_pinctrl_drv_data *drvdata) | 954 | struct samsung_pinctrl_drv_data *drvdata) |
956 | { | 955 | { |
957 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | 956 | struct samsung_pin_bank *bank = drvdata->pin_banks; |
958 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
959 | int i; | 957 | int i; |
960 | 958 | ||
961 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) | 959 | for (i = 0; i < drvdata->nr_banks; ++i, ++bank) |
962 | gpiochip_remove(&bank->gpio_chip); | 960 | gpiochip_remove(&bank->gpio_chip); |
961 | |||
963 | return 0; | 962 | return 0; |
964 | } | 963 | } |
965 | 964 | ||
966 | static const struct of_device_id samsung_pinctrl_dt_match[]; | 965 | static const struct of_device_id samsung_pinctrl_dt_match[]; |
967 | 966 | ||
968 | /* retrieve the soc specific data */ | 967 | /* retrieve the soc specific data */ |
969 | static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( | 968 | static const struct samsung_pin_ctrl * |
970 | struct samsung_pinctrl_drv_data *d, | 969 | samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, |
971 | struct platform_device *pdev) | 970 | struct platform_device *pdev) |
972 | { | 971 | { |
973 | int id; | 972 | int id; |
974 | const struct of_device_id *match; | 973 | const struct of_device_id *match; |
975 | struct device_node *node = pdev->dev.of_node; | 974 | struct device_node *node = pdev->dev.of_node; |
976 | struct device_node *np; | 975 | struct device_node *np; |
977 | struct samsung_pin_ctrl *ctrl; | 976 | const struct samsung_pin_bank_data *bdata; |
977 | const struct samsung_pin_ctrl *ctrl; | ||
978 | struct samsung_pin_bank *bank; | 978 | struct samsung_pin_bank *bank; |
979 | int i; | 979 | int i; |
980 | 980 | ||
981 | id = of_alias_get_id(node, "pinctrl"); | 981 | id = of_alias_get_id(node, "pinctrl"); |
982 | if (id < 0) { | 982 | if (id < 0) { |
983 | dev_err(&pdev->dev, "failed to get alias id\n"); | 983 | dev_err(&pdev->dev, "failed to get alias id\n"); |
984 | return NULL; | 984 | return ERR_PTR(-ENOENT); |
985 | } | 985 | } |
986 | match = of_match_node(samsung_pinctrl_dt_match, node); | 986 | match = of_match_node(samsung_pinctrl_dt_match, node); |
987 | ctrl = (struct samsung_pin_ctrl *)match->data + id; | 987 | ctrl = (struct samsung_pin_ctrl *)match->data + id; |
988 | 988 | ||
989 | bank = ctrl->pin_banks; | 989 | d->suspend = ctrl->suspend; |
990 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | 990 | d->resume = ctrl->resume; |
991 | d->nr_banks = ctrl->nr_banks; | ||
992 | d->pin_banks = devm_kcalloc(&pdev->dev, d->nr_banks, | ||
993 | sizeof(*d->pin_banks), GFP_KERNEL); | ||
994 | if (!d->pin_banks) | ||
995 | return ERR_PTR(-ENOMEM); | ||
996 | |||
997 | bank = d->pin_banks; | ||
998 | bdata = ctrl->pin_banks; | ||
999 | for (i = 0; i < ctrl->nr_banks; ++i, ++bdata, ++bank) { | ||
1000 | bank->type = bdata->type; | ||
1001 | bank->pctl_offset = bdata->pctl_offset; | ||
1002 | bank->nr_pins = bdata->nr_pins; | ||
1003 | bank->eint_func = bdata->eint_func; | ||
1004 | bank->eint_type = bdata->eint_type; | ||
1005 | bank->eint_mask = bdata->eint_mask; | ||
1006 | bank->eint_offset = bdata->eint_offset; | ||
1007 | bank->name = bdata->name; | ||
1008 | |||
991 | spin_lock_init(&bank->slock); | 1009 | spin_lock_init(&bank->slock); |
992 | bank->drvdata = d; | 1010 | bank->drvdata = d; |
993 | bank->pin_base = ctrl->nr_pins; | 1011 | bank->pin_base = d->nr_pins; |
994 | ctrl->nr_pins += bank->nr_pins; | 1012 | d->nr_pins += bank->nr_pins; |
995 | } | 1013 | } |
996 | 1014 | ||
997 | for_each_child_of_node(node, np) { | 1015 | for_each_child_of_node(node, np) { |
998 | if (!of_find_property(np, "gpio-controller", NULL)) | 1016 | if (!of_find_property(np, "gpio-controller", NULL)) |
999 | continue; | 1017 | continue; |
1000 | bank = ctrl->pin_banks; | 1018 | bank = d->pin_banks; |
1001 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | 1019 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
1002 | if (!strcmp(bank->name, np->name)) { | 1020 | if (!strcmp(bank->name, np->name)) { |
1003 | bank->of_node = np; | 1021 | bank->of_node = np; |
1004 | break; | 1022 | break; |
@@ -1006,8 +1024,8 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( | |||
1006 | } | 1024 | } |
1007 | } | 1025 | } |
1008 | 1026 | ||
1009 | ctrl->base = pin_base; | 1027 | d->pin_base = pin_base; |
1010 | pin_base += ctrl->nr_pins; | 1028 | pin_base += d->nr_pins; |
1011 | 1029 | ||
1012 | return ctrl; | 1030 | return ctrl; |
1013 | } | 1031 | } |
@@ -1015,8 +1033,8 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( | |||
1015 | static int samsung_pinctrl_probe(struct platform_device *pdev) | 1033 | static int samsung_pinctrl_probe(struct platform_device *pdev) |
1016 | { | 1034 | { |
1017 | struct samsung_pinctrl_drv_data *drvdata; | 1035 | struct samsung_pinctrl_drv_data *drvdata; |
1036 | const struct samsung_pin_ctrl *ctrl; | ||
1018 | struct device *dev = &pdev->dev; | 1037 | struct device *dev = &pdev->dev; |
1019 | struct samsung_pin_ctrl *ctrl; | ||
1020 | struct resource *res; | 1038 | struct resource *res; |
1021 | int ret; | 1039 | int ret; |
1022 | 1040 | ||
@@ -1033,11 +1051,10 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) | |||
1033 | } | 1051 | } |
1034 | 1052 | ||
1035 | ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev); | 1053 | ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev); |
1036 | if (!ctrl) { | 1054 | if (IS_ERR(ctrl)) { |
1037 | dev_err(&pdev->dev, "driver data not available\n"); | 1055 | dev_err(&pdev->dev, "driver data not available\n"); |
1038 | return -EINVAL; | 1056 | return PTR_ERR(ctrl); |
1039 | } | 1057 | } |
1040 | drvdata->ctrl = ctrl; | ||
1041 | drvdata->dev = dev; | 1058 | drvdata->dev = dev; |
1042 | 1059 | ||
1043 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1060 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -1082,16 +1099,14 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) | |||
1082 | static void samsung_pinctrl_suspend_dev( | 1099 | static void samsung_pinctrl_suspend_dev( |
1083 | struct samsung_pinctrl_drv_data *drvdata) | 1100 | struct samsung_pinctrl_drv_data *drvdata) |
1084 | { | 1101 | { |
1085 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
1086 | void __iomem *virt_base = drvdata->virt_base; | 1102 | void __iomem *virt_base = drvdata->virt_base; |
1087 | int i; | 1103 | int i; |
1088 | 1104 | ||
1089 | for (i = 0; i < ctrl->nr_banks; i++) { | 1105 | for (i = 0; i < drvdata->nr_banks; i++) { |
1090 | struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; | 1106 | struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; |
1091 | void __iomem *reg = virt_base + bank->pctl_offset; | 1107 | void __iomem *reg = virt_base + bank->pctl_offset; |
1092 | 1108 | const u8 *offs = bank->type->reg_offset; | |
1093 | u8 *offs = bank->type->reg_offset; | 1109 | const u8 *widths = bank->type->fld_width; |
1094 | u8 *widths = bank->type->fld_width; | ||
1095 | enum pincfg_type type; | 1110 | enum pincfg_type type; |
1096 | 1111 | ||
1097 | /* Registers without a powerdown config aren't lost */ | 1112 | /* Registers without a powerdown config aren't lost */ |
@@ -1116,8 +1131,8 @@ static void samsung_pinctrl_suspend_dev( | |||
1116 | } | 1131 | } |
1117 | } | 1132 | } |
1118 | 1133 | ||
1119 | if (ctrl->suspend) | 1134 | if (drvdata->suspend) |
1120 | ctrl->suspend(drvdata); | 1135 | drvdata->suspend(drvdata); |
1121 | } | 1136 | } |
1122 | 1137 | ||
1123 | /** | 1138 | /** |
@@ -1130,19 +1145,17 @@ static void samsung_pinctrl_suspend_dev( | |||
1130 | */ | 1145 | */ |
1131 | static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata) | 1146 | static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata) |
1132 | { | 1147 | { |
1133 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
1134 | void __iomem *virt_base = drvdata->virt_base; | 1148 | void __iomem *virt_base = drvdata->virt_base; |
1135 | int i; | 1149 | int i; |
1136 | 1150 | ||
1137 | if (ctrl->resume) | 1151 | if (drvdata->resume) |
1138 | ctrl->resume(drvdata); | 1152 | drvdata->resume(drvdata); |
1139 | 1153 | ||
1140 | for (i = 0; i < ctrl->nr_banks; i++) { | 1154 | for (i = 0; i < drvdata->nr_banks; i++) { |
1141 | struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; | 1155 | struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; |
1142 | void __iomem *reg = virt_base + bank->pctl_offset; | 1156 | void __iomem *reg = virt_base + bank->pctl_offset; |
1143 | 1157 | const u8 *offs = bank->type->reg_offset; | |
1144 | u8 *offs = bank->type->reg_offset; | 1158 | const u8 *widths = bank->type->fld_width; |
1145 | u8 *widths = bank->type->fld_width; | ||
1146 | enum pincfg_type type; | 1159 | enum pincfg_type type; |
1147 | 1160 | ||
1148 | /* Registers without a powerdown config aren't lost */ | 1161 | /* Registers without a powerdown config aren't lost */ |
@@ -1218,6 +1231,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { | |||
1218 | .data = (void *)exynos4210_pin_ctrl }, | 1231 | .data = (void *)exynos4210_pin_ctrl }, |
1219 | { .compatible = "samsung,exynos4x12-pinctrl", | 1232 | { .compatible = "samsung,exynos4x12-pinctrl", |
1220 | .data = (void *)exynos4x12_pin_ctrl }, | 1233 | .data = (void *)exynos4x12_pin_ctrl }, |
1234 | { .compatible = "samsung,exynos4415-pinctrl", | ||
1235 | .data = (void *)exynos4415_pin_ctrl }, | ||
1221 | { .compatible = "samsung,exynos5250-pinctrl", | 1236 | { .compatible = "samsung,exynos5250-pinctrl", |
1222 | .data = (void *)exynos5250_pin_ctrl }, | 1237 | .data = (void *)exynos5250_pin_ctrl }, |
1223 | { .compatible = "samsung,exynos5260-pinctrl", | 1238 | { .compatible = "samsung,exynos5260-pinctrl", |
@@ -1226,6 +1241,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { | |||
1226 | .data = (void *)exynos5420_pin_ctrl }, | 1241 | .data = (void *)exynos5420_pin_ctrl }, |
1227 | { .compatible = "samsung,s5pv210-pinctrl", | 1242 | { .compatible = "samsung,s5pv210-pinctrl", |
1228 | .data = (void *)s5pv210_pin_ctrl }, | 1243 | .data = (void *)s5pv210_pin_ctrl }, |
1244 | { .compatible = "samsung,exynos7-pinctrl", | ||
1245 | .data = (void *)exynos7_pin_ctrl }, | ||
1229 | #endif | 1246 | #endif |
1230 | #ifdef CONFIG_PINCTRL_S3C64XX | 1247 | #ifdef CONFIG_PINCTRL_S3C64XX |
1231 | { .compatible = "samsung,s3c64xx-pinctrl", | 1248 | { .compatible = "samsung,s3c64xx-pinctrl", |
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 5cedc9d26390..1b8c0139d604 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h | |||
@@ -113,39 +113,66 @@ struct samsung_pin_bank_type { | |||
113 | }; | 113 | }; |
114 | 114 | ||
115 | /** | 115 | /** |
116 | * struct samsung_pin_bank_data: represent a controller pin-bank (init data). | ||
117 | * @type: type of the bank (register offsets and bitfield widths) | ||
118 | * @pctl_offset: starting offset of the pin-bank registers. | ||
119 | * @nr_pins: number of pins included in this bank. | ||
120 | * @eint_func: function to set in CON register to configure pin as EINT. | ||
121 | * @eint_type: type of the external interrupt supported by the bank. | ||
122 | * @eint_mask: bit mask of pins which support EINT function. | ||
123 | * @eint_offset: SoC-specific EINT register or interrupt offset of bank. | ||
124 | * @name: name to be prefixed for each pin in this pin bank. | ||
125 | */ | ||
126 | struct samsung_pin_bank_data { | ||
127 | const struct samsung_pin_bank_type *type; | ||
128 | u32 pctl_offset; | ||
129 | u8 nr_pins; | ||
130 | u8 eint_func; | ||
131 | enum eint_type eint_type; | ||
132 | u32 eint_mask; | ||
133 | u32 eint_offset; | ||
134 | const char *name; | ||
135 | }; | ||
136 | |||
137 | /** | ||
116 | * struct samsung_pin_bank: represent a controller pin-bank. | 138 | * struct samsung_pin_bank: represent a controller pin-bank. |
117 | * @type: type of the bank (register offsets and bitfield widths) | 139 | * @type: type of the bank (register offsets and bitfield widths) |
118 | * @pctl_offset: starting offset of the pin-bank registers. | 140 | * @pctl_offset: starting offset of the pin-bank registers. |
119 | * @pin_base: starting pin number of the bank. | ||
120 | * @nr_pins: number of pins included in this bank. | 141 | * @nr_pins: number of pins included in this bank. |
121 | * @eint_func: function to set in CON register to configure pin as EINT. | 142 | * @eint_func: function to set in CON register to configure pin as EINT. |
122 | * @eint_type: type of the external interrupt supported by the bank. | 143 | * @eint_type: type of the external interrupt supported by the bank. |
123 | * @eint_mask: bit mask of pins which support EINT function. | 144 | * @eint_mask: bit mask of pins which support EINT function. |
145 | * @eint_offset: SoC-specific EINT register or interrupt offset of bank. | ||
124 | * @name: name to be prefixed for each pin in this pin bank. | 146 | * @name: name to be prefixed for each pin in this pin bank. |
147 | * @pin_base: starting pin number of the bank. | ||
148 | * @soc_priv: per-bank private data for SoC-specific code. | ||
125 | * @of_node: OF node of the bank. | 149 | * @of_node: OF node of the bank. |
126 | * @drvdata: link to controller driver data | 150 | * @drvdata: link to controller driver data |
127 | * @irq_domain: IRQ domain of the bank. | 151 | * @irq_domain: IRQ domain of the bank. |
128 | * @gpio_chip: GPIO chip of the bank. | 152 | * @gpio_chip: GPIO chip of the bank. |
129 | * @grange: linux gpio pin range supported by this bank. | 153 | * @grange: linux gpio pin range supported by this bank. |
154 | * @irq_chip: link to irq chip for external gpio and wakeup interrupts. | ||
130 | * @slock: spinlock protecting bank registers | 155 | * @slock: spinlock protecting bank registers |
131 | * @pm_save: saved register values during suspend | 156 | * @pm_save: saved register values during suspend |
132 | */ | 157 | */ |
133 | struct samsung_pin_bank { | 158 | struct samsung_pin_bank { |
134 | struct samsung_pin_bank_type *type; | 159 | const struct samsung_pin_bank_type *type; |
135 | u32 pctl_offset; | 160 | u32 pctl_offset; |
136 | u32 pin_base; | ||
137 | u8 nr_pins; | 161 | u8 nr_pins; |
138 | u8 eint_func; | 162 | u8 eint_func; |
139 | enum eint_type eint_type; | 163 | enum eint_type eint_type; |
140 | u32 eint_mask; | 164 | u32 eint_mask; |
141 | u32 eint_offset; | 165 | u32 eint_offset; |
142 | char *name; | 166 | const char *name; |
167 | |||
168 | u32 pin_base; | ||
143 | void *soc_priv; | 169 | void *soc_priv; |
144 | struct device_node *of_node; | 170 | struct device_node *of_node; |
145 | struct samsung_pinctrl_drv_data *drvdata; | 171 | struct samsung_pinctrl_drv_data *drvdata; |
146 | struct irq_domain *irq_domain; | 172 | struct irq_domain *irq_domain; |
147 | struct gpio_chip gpio_chip; | 173 | struct gpio_chip gpio_chip; |
148 | struct pinctrl_gpio_range grange; | 174 | struct pinctrl_gpio_range grange; |
175 | struct exynos_irq_chip *irq_chip; | ||
149 | spinlock_t slock; | 176 | spinlock_t slock; |
150 | 177 | ||
151 | u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ | 178 | u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ |
@@ -155,27 +182,19 @@ struct samsung_pin_bank { | |||
155 | * struct samsung_pin_ctrl: represent a pin controller. | 182 | * struct samsung_pin_ctrl: represent a pin controller. |
156 | * @pin_banks: list of pin banks included in this controller. | 183 | * @pin_banks: list of pin banks included in this controller. |
157 | * @nr_banks: number of pin banks. | 184 | * @nr_banks: number of pin banks. |
158 | * @base: starting system wide pin number. | ||
159 | * @nr_pins: number of pins supported by the controller. | ||
160 | * @eint_gpio_init: platform specific callback to setup the external gpio | 185 | * @eint_gpio_init: platform specific callback to setup the external gpio |
161 | * interrupts for the controller. | 186 | * interrupts for the controller. |
162 | * @eint_wkup_init: platform specific callback to setup the external wakeup | 187 | * @eint_wkup_init: platform specific callback to setup the external wakeup |
163 | * interrupts for the controller. | 188 | * interrupts for the controller. |
164 | * @label: for debug information. | ||
165 | */ | 189 | */ |
166 | struct samsung_pin_ctrl { | 190 | struct samsung_pin_ctrl { |
167 | struct samsung_pin_bank *pin_banks; | 191 | const struct samsung_pin_bank_data *pin_banks; |
168 | u32 nr_banks; | 192 | u32 nr_banks; |
169 | 193 | ||
170 | u32 base; | ||
171 | u32 nr_pins; | ||
172 | |||
173 | int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); | 194 | int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); |
174 | int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); | 195 | int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); |
175 | void (*suspend)(struct samsung_pinctrl_drv_data *); | 196 | void (*suspend)(struct samsung_pinctrl_drv_data *); |
176 | void (*resume)(struct samsung_pinctrl_drv_data *); | 197 | void (*resume)(struct samsung_pinctrl_drv_data *); |
177 | |||
178 | char *label; | ||
179 | }; | 198 | }; |
180 | 199 | ||
181 | /** | 200 | /** |
@@ -191,6 +210,8 @@ struct samsung_pin_ctrl { | |||
191 | * @nr_groups: number of such pin groups. | 210 | * @nr_groups: number of such pin groups. |
192 | * @pmx_functions: list of pin functions available to the driver. | 211 | * @pmx_functions: list of pin functions available to the driver. |
193 | * @nr_function: number of such pin functions. | 212 | * @nr_function: number of such pin functions. |
213 | * @pin_base: starting system wide pin number. | ||
214 | * @nr_pins: number of pins supported by the controller. | ||
194 | */ | 215 | */ |
195 | struct samsung_pinctrl_drv_data { | 216 | struct samsung_pinctrl_drv_data { |
196 | struct list_head node; | 217 | struct list_head node; |
@@ -198,7 +219,6 @@ struct samsung_pinctrl_drv_data { | |||
198 | struct device *dev; | 219 | struct device *dev; |
199 | int irq; | 220 | int irq; |
200 | 221 | ||
201 | struct samsung_pin_ctrl *ctrl; | ||
202 | struct pinctrl_desc pctl; | 222 | struct pinctrl_desc pctl; |
203 | struct pinctrl_dev *pctl_dev; | 223 | struct pinctrl_dev *pctl_dev; |
204 | 224 | ||
@@ -206,6 +226,14 @@ struct samsung_pinctrl_drv_data { | |||
206 | unsigned int nr_groups; | 226 | unsigned int nr_groups; |
207 | const struct samsung_pmx_func *pmx_functions; | 227 | const struct samsung_pmx_func *pmx_functions; |
208 | unsigned int nr_functions; | 228 | unsigned int nr_functions; |
229 | |||
230 | struct samsung_pin_bank *pin_banks; | ||
231 | u32 nr_banks; | ||
232 | unsigned int pin_base; | ||
233 | unsigned int nr_pins; | ||
234 | |||
235 | void (*suspend)(struct samsung_pinctrl_drv_data *); | ||
236 | void (*resume)(struct samsung_pinctrl_drv_data *); | ||
209 | }; | 237 | }; |
210 | 238 | ||
211 | /** | 239 | /** |
@@ -236,17 +264,19 @@ struct samsung_pmx_func { | |||
236 | }; | 264 | }; |
237 | 265 | ||
238 | /* list of all exported SoC specific data */ | 266 | /* list of all exported SoC specific data */ |
239 | extern struct samsung_pin_ctrl exynos3250_pin_ctrl[]; | 267 | extern const struct samsung_pin_ctrl exynos3250_pin_ctrl[]; |
240 | extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; | 268 | extern const struct samsung_pin_ctrl exynos4210_pin_ctrl[]; |
241 | extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; | 269 | extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; |
242 | extern struct samsung_pin_ctrl exynos5250_pin_ctrl[]; | 270 | extern const struct samsung_pin_ctrl exynos4415_pin_ctrl[]; |
243 | extern struct samsung_pin_ctrl exynos5260_pin_ctrl[]; | 271 | extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[]; |
244 | extern struct samsung_pin_ctrl exynos5420_pin_ctrl[]; | 272 | extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[]; |
245 | extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; | 273 | extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[]; |
246 | extern struct samsung_pin_ctrl s3c2412_pin_ctrl[]; | 274 | extern const struct samsung_pin_ctrl exynos7_pin_ctrl[]; |
247 | extern struct samsung_pin_ctrl s3c2416_pin_ctrl[]; | 275 | extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; |
248 | extern struct samsung_pin_ctrl s3c2440_pin_ctrl[]; | 276 | extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[]; |
249 | extern struct samsung_pin_ctrl s3c2450_pin_ctrl[]; | 277 | extern const struct samsung_pin_ctrl s3c2416_pin_ctrl[]; |
250 | extern struct samsung_pin_ctrl s5pv210_pin_ctrl[]; | 278 | extern const struct samsung_pin_ctrl s3c2440_pin_ctrl[]; |
279 | extern const struct samsung_pin_ctrl s3c2450_pin_ctrl[]; | ||
280 | extern const struct samsung_pin_ctrl s5pv210_pin_ctrl[]; | ||
251 | 281 | ||
252 | #endif /* __PINCTRL_SAMSUNG_H */ | 282 | #endif /* __PINCTRL_SAMSUNG_H */ |
diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index a5e10f777ed2..230a952608cb 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig | |||
@@ -39,4 +39,8 @@ config PINCTRL_SUN8I_A23_R | |||
39 | depends on RESET_CONTROLLER | 39 | depends on RESET_CONTROLLER |
40 | select PINCTRL_SUNXI_COMMON | 40 | select PINCTRL_SUNXI_COMMON |
41 | 41 | ||
42 | config PINCTRL_SUN9I_A80 | ||
43 | def_bool MACH_SUN9I | ||
44 | select PINCTRL_SUNXI_COMMON | ||
45 | |||
42 | endif | 46 | endif |
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile index e797efb02901..c7d92e4673b5 100644 --- a/drivers/pinctrl/sunxi/Makefile +++ b/drivers/pinctrl/sunxi/Makefile | |||
@@ -10,3 +10,4 @@ obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o | |||
10 | obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o | 10 | obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o |
11 | obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o | 11 | obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o |
12 | obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o | 12 | obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o |
13 | obj-$(CONFIG_PINCTRL_SUN9I_A80) += pinctrl-sun9i-a80.o | ||
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c new file mode 100644 index 000000000000..adb29422efc9 --- /dev/null +++ b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c | |||
@@ -0,0 +1,749 @@ | |||
1 | /* | ||
2 | * Allwinner A80 SoCs pinctrl driver. | ||
3 | * | ||
4 | * Copyright (C) 2014 Maxime Ripard | ||
5 | * | ||
6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_device.h> | ||
17 | #include <linux/pinctrl/pinctrl.h> | ||
18 | |||
19 | #include "pinctrl-sunxi.h" | ||
20 | |||
21 | static const struct sunxi_desc_pin sun9i_a80_pins[] = { | ||
22 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0), | ||
23 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
24 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
25 | SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */ | ||
26 | SUNXI_FUNCTION(0x4, "uart1"), /* TX */ | ||
27 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */ | ||
28 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1), | ||
29 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
30 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
31 | SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */ | ||
32 | SUNXI_FUNCTION(0x4, "uart1"), /* RX */ | ||
33 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */ | ||
34 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2), | ||
35 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
36 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
37 | SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */ | ||
38 | SUNXI_FUNCTION(0x4, "uart1"), /* RTS */ | ||
39 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */ | ||
40 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3), | ||
41 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
42 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
43 | SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */ | ||
44 | SUNXI_FUNCTION(0x4, "uart1"), /* CTS */ | ||
45 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */ | ||
46 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4), | ||
47 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
48 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
49 | SUNXI_FUNCTION(0x2, "gmac"), /* RXCK */ | ||
50 | SUNXI_FUNCTION(0x4, "uart1"), /* DTR */ | ||
51 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */ | ||
52 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5), | ||
53 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
54 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
55 | SUNXI_FUNCTION(0x2, "gmac"), /* RXCTL */ | ||
56 | SUNXI_FUNCTION(0x4, "uart1"), /* DSR */ | ||
57 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */ | ||
58 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6), | ||
59 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
60 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
61 | SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */ | ||
62 | SUNXI_FUNCTION(0x4, "uart1"), /* DCD */ | ||
63 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */ | ||
64 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7), | ||
65 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
66 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
67 | SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */ | ||
68 | SUNXI_FUNCTION(0x4, "uart1"), /* RING */ | ||
69 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */ | ||
70 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8), | ||
71 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
72 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
73 | SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */ | ||
74 | SUNXI_FUNCTION(0x4, "eclk"), /* IN0 */ | ||
75 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */ | ||
76 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9), | ||
77 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
78 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
79 | SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */ | ||
80 | SUNXI_FUNCTION(0x4, "eclk"), /* IN1 */ | ||
81 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */ | ||
82 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10), | ||
83 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
84 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
85 | SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */ | ||
86 | SUNXI_FUNCTION(0x4, "clk_out_a"), | ||
87 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */ | ||
88 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11), | ||
89 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
90 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
91 | SUNXI_FUNCTION(0x2, "gmac"), /* MII-CRS */ | ||
92 | SUNXI_FUNCTION(0x4, "clk_out_b"), | ||
93 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */ | ||
94 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12), | ||
95 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
96 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
97 | SUNXI_FUNCTION(0x2, "gmac"), /* TXCK */ | ||
98 | SUNXI_FUNCTION(0x4, "pwm3"), /* PWM_P */ | ||
99 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */ | ||
100 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13), | ||
101 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
102 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
103 | SUNXI_FUNCTION(0x2, "gmac"), /* RGMII-TXCK / GMII-TXEN */ | ||
104 | SUNXI_FUNCTION(0x4, "pwm3"), /* PWM_N */ | ||
105 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */ | ||
106 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14), | ||
107 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
108 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
109 | SUNXI_FUNCTION(0x2, "gmac"), /* MII-TXERR */ | ||
110 | SUNXI_FUNCTION(0x4, "spi1"), /* CS0 */ | ||
111 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */ | ||
112 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15), | ||
113 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
114 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
115 | SUNXI_FUNCTION(0x2, "gmac"), /* RGMII-CLKIN / MII-COL */ | ||
116 | SUNXI_FUNCTION(0x4, "spi1"), /* CLK */ | ||
117 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */ | ||
118 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16), | ||
119 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
120 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
121 | SUNXI_FUNCTION(0x2, "gmac"), /* EMDC */ | ||
122 | SUNXI_FUNCTION(0x4, "spi1"), /* MOSI */ | ||
123 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */ | ||
124 | SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17), | ||
125 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
126 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
127 | SUNXI_FUNCTION(0x2, "gmac"), /* EMDIO */ | ||
128 | SUNXI_FUNCTION(0x4, "spi1"), /* MISO */ | ||
129 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */ | ||
130 | |||
131 | /* Hole */ | ||
132 | SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5), | ||
133 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
134 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
135 | SUNXI_FUNCTION(0x3, "uart3"), /* TX */ | ||
136 | SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PB_EINT5 */ | ||
137 | SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6), | ||
138 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
139 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
140 | SUNXI_FUNCTION(0x3, "uart3"), /* RX */ | ||
141 | SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PB_EINT6 */ | ||
142 | |||
143 | /* Hole */ | ||
144 | SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 14), | ||
145 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
146 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
147 | SUNXI_FUNCTION(0x3, "mcsi"), /* MCLK */ | ||
148 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PB_EINT14 */ | ||
149 | SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 15), | ||
150 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
151 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
152 | SUNXI_FUNCTION(0x3, "mcsi"), /* SCK */ | ||
153 | SUNXI_FUNCTION(0x4, "i2c4"), /* SCK */ | ||
154 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PB_EINT15 */ | ||
155 | SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 16), | ||
156 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
157 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
158 | SUNXI_FUNCTION(0x3, "mcsi"), /* SDA */ | ||
159 | SUNXI_FUNCTION(0x4, "i2c4"), /* SDA */ | ||
160 | SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PB_EINT16 */ | ||
161 | |||
162 | /* Hole */ | ||
163 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0), | ||
164 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
165 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
166 | SUNXI_FUNCTION(0x2, "nand0"), /* WE */ | ||
167 | SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */ | ||
168 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1), | ||
169 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
170 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
171 | SUNXI_FUNCTION(0x2, "nand0"), /* ALE */ | ||
172 | SUNXI_FUNCTION(0x3, "spi0")), /* MISO */ | ||
173 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2), | ||
174 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
175 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
176 | SUNXI_FUNCTION(0x2, "nand0"), /* CLE */ | ||
177 | SUNXI_FUNCTION(0x3, "spi0")), /* CLK */ | ||
178 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3), | ||
179 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
180 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
181 | SUNXI_FUNCTION(0x2, "nand0")), /* CE1 */ | ||
182 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4), | ||
183 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
184 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
185 | SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */ | ||
186 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5), | ||
187 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
188 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
189 | SUNXI_FUNCTION(0x2, "nand0")), /* RE */ | ||
190 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6), | ||
191 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
192 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
193 | SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */ | ||
194 | SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */ | ||
195 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7), | ||
196 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
197 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
198 | SUNXI_FUNCTION(0x2, "nand0"), /* RB1 */ | ||
199 | SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */ | ||
200 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8), | ||
201 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
202 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
203 | SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */ | ||
204 | SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */ | ||
205 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9), | ||
206 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
207 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
208 | SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */ | ||
209 | SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */ | ||
210 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10), | ||
211 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
212 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
213 | SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */ | ||
214 | SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */ | ||
215 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11), | ||
216 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
217 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
218 | SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */ | ||
219 | SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */ | ||
220 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12), | ||
221 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
222 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
223 | SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */ | ||
224 | SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */ | ||
225 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13), | ||
226 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
227 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
228 | SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */ | ||
229 | SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */ | ||
230 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), | ||
231 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
232 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
233 | SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */ | ||
234 | SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ | ||
235 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), | ||
236 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
237 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
238 | SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */ | ||
239 | SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ | ||
240 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), | ||
241 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
242 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
243 | SUNXI_FUNCTION(0x2, "nand0"), /* DQS */ | ||
244 | SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ | ||
245 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17), | ||
246 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
247 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
248 | SUNXI_FUNCTION(0x2, "nand0"), /* CE2 */ | ||
249 | SUNXI_FUNCTION(0x3, "nand0_b")), /* RE */ | ||
250 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18), | ||
251 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
252 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
253 | SUNXI_FUNCTION(0x2, "nand0"), /* CE3 */ | ||
254 | SUNXI_FUNCTION(0x3, "nand0_b")), /* DQS */ | ||
255 | SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 19), | ||
256 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
257 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
258 | SUNXI_FUNCTION(0x3, "spi0")), /* CS0 */ | ||
259 | |||
260 | /* Hole */ | ||
261 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0), | ||
262 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
263 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
264 | SUNXI_FUNCTION(0x2, "lcd0"), /* D0 */ | ||
265 | SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */ | ||
266 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1), | ||
267 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
268 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
269 | SUNXI_FUNCTION(0x2, "lcd0"), /* D1 */ | ||
270 | SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */ | ||
271 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2), | ||
272 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
273 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
274 | SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */ | ||
275 | SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */ | ||
276 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3), | ||
277 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
278 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
279 | SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */ | ||
280 | SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */ | ||
281 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4), | ||
282 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
283 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
284 | SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */ | ||
285 | SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */ | ||
286 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5), | ||
287 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
288 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
289 | SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */ | ||
290 | SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */ | ||
291 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6), | ||
292 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
293 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
294 | SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */ | ||
295 | SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */ | ||
296 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7), | ||
297 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
298 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
299 | SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */ | ||
300 | SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */ | ||
301 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8), | ||
302 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
303 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
304 | SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */ | ||
305 | SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */ | ||
306 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9), | ||
307 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
308 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
309 | SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */ | ||
310 | SUNXI_FUNCTION(0x3, "lvds0")), /* VN3 */ | ||
311 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10), | ||
312 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
313 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
314 | SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */ | ||
315 | SUNXI_FUNCTION(0x3, "lvds1")), /* VP0 */ | ||
316 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11), | ||
317 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
318 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
319 | SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */ | ||
320 | SUNXI_FUNCTION(0x3, "lvds1")), /* VN0 */ | ||
321 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12), | ||
322 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
323 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
324 | SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */ | ||
325 | SUNXI_FUNCTION(0x3, "lvds1")), /* VP1 */ | ||
326 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13), | ||
327 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
328 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
329 | SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */ | ||
330 | SUNXI_FUNCTION(0x3, "lvds1")), /* VN1 */ | ||
331 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14), | ||
332 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
333 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
334 | SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */ | ||
335 | SUNXI_FUNCTION(0x3, "lvds1")), /* VP2 */ | ||
336 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15), | ||
337 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
338 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
339 | SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */ | ||
340 | SUNXI_FUNCTION(0x3, "lvds1")), /* VN2 */ | ||
341 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16), | ||
342 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
343 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
344 | SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */ | ||
345 | SUNXI_FUNCTION(0x3, "lvds1")), /* VPC */ | ||
346 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17), | ||
347 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
348 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
349 | SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */ | ||
350 | SUNXI_FUNCTION(0x3, "lvds1")), /* VNC */ | ||
351 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18), | ||
352 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
353 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
354 | SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */ | ||
355 | SUNXI_FUNCTION(0x3, "lvds1")), /* VP3 */ | ||
356 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19), | ||
357 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
358 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
359 | SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */ | ||
360 | SUNXI_FUNCTION(0x3, "lvds1")), /* VN3 */ | ||
361 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20), | ||
362 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
363 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
364 | SUNXI_FUNCTION(0x2, "lcd0")), /* D20 */ | ||
365 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21), | ||
366 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
367 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
368 | SUNXI_FUNCTION(0x2, "lcd0")), /* D21 */ | ||
369 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22), | ||
370 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
371 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
372 | SUNXI_FUNCTION(0x2, "lcd0")), /* D22 */ | ||
373 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23), | ||
374 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
375 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
376 | SUNXI_FUNCTION(0x2, "lcd0")), /* D23 */ | ||
377 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24), | ||
378 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
379 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
380 | SUNXI_FUNCTION(0x2, "lcd0")), /* CLK */ | ||
381 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25), | ||
382 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
383 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
384 | SUNXI_FUNCTION(0x2, "lcd0")), /* DE */ | ||
385 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26), | ||
386 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
387 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
388 | SUNXI_FUNCTION(0x2, "lcd0")), /* HSYNC */ | ||
389 | SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27), | ||
390 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
391 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
392 | SUNXI_FUNCTION(0x2, "lcd0")), /* VSYNC */ | ||
393 | |||
394 | /* Hole */ | ||
395 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0), | ||
396 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
397 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
398 | SUNXI_FUNCTION(0x2, "csi"), /* PCLK */ | ||
399 | SUNXI_FUNCTION(0x3, "ts"), /* CLK */ | ||
400 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PE_EINT0 */ | ||
401 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1), | ||
402 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
403 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
404 | SUNXI_FUNCTION(0x2, "csi"), /* MCLK */ | ||
405 | SUNXI_FUNCTION(0x3, "ts"), /* ERR */ | ||
406 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PE_EINT1 */ | ||
407 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2), | ||
408 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
409 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
410 | SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */ | ||
411 | SUNXI_FUNCTION(0x3, "ts"), /* SYNC */ | ||
412 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PE_EINT2 */ | ||
413 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3), | ||
414 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
415 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
416 | SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */ | ||
417 | SUNXI_FUNCTION(0x3, "ts"), /* DVLD */ | ||
418 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PE_EINT3 */ | ||
419 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4), | ||
420 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
421 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
422 | SUNXI_FUNCTION(0x2, "csi"), /* D0 */ | ||
423 | SUNXI_FUNCTION(0x3, "spi2"), /* CS0 */ | ||
424 | SUNXI_FUNCTION(0x4, "uart5"), /* TX */ | ||
425 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PE_EINT4 */ | ||
426 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5), | ||
427 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
428 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
429 | SUNXI_FUNCTION(0x2, "csi"), /* D1 */ | ||
430 | SUNXI_FUNCTION(0x3, "spi2"), /* CLK */ | ||
431 | SUNXI_FUNCTION(0x4, "uart5"), /* RX */ | ||
432 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PE_EINT5 */ | ||
433 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6), | ||
434 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
435 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
436 | SUNXI_FUNCTION(0x2, "csi"), /* D2 */ | ||
437 | SUNXI_FUNCTION(0x3, "spi2"), /* MOSI */ | ||
438 | SUNXI_FUNCTION(0x4, "uart5"), /* RTS */ | ||
439 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PE_EINT6 */ | ||
440 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7), | ||
441 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
442 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
443 | SUNXI_FUNCTION(0x2, "csi"), /* D3 */ | ||
444 | SUNXI_FUNCTION(0x3, "spi2"), /* MISO */ | ||
445 | SUNXI_FUNCTION(0x4, "uart5"), /* CTS */ | ||
446 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PE_EINT7 */ | ||
447 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8), | ||
448 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
449 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
450 | SUNXI_FUNCTION(0x2, "csi"), /* D4 */ | ||
451 | SUNXI_FUNCTION(0x3, "ts"), /* D0 */ | ||
452 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PE_EINT8 */ | ||
453 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9), | ||
454 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
455 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
456 | SUNXI_FUNCTION(0x2, "csi"), /* D5 */ | ||
457 | SUNXI_FUNCTION(0x3, "ts"), /* D1 */ | ||
458 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PE_EINT9 */ | ||
459 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10), | ||
460 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
461 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
462 | SUNXI_FUNCTION(0x2, "csi"), /* D6 */ | ||
463 | SUNXI_FUNCTION(0x3, "ts"), /* D2 */ | ||
464 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PE_EINT10 */ | ||
465 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11), | ||
466 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
467 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
468 | SUNXI_FUNCTION(0x2, "csi"), /* D7 */ | ||
469 | SUNXI_FUNCTION(0x3, "ts"), /* D3 */ | ||
470 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PE_EINT11 */ | ||
471 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12), | ||
472 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
473 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
474 | SUNXI_FUNCTION(0x2, "csi"), /* D8 */ | ||
475 | SUNXI_FUNCTION(0x3, "ts"), /* D4 */ | ||
476 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PE_EINT12 */ | ||
477 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13), | ||
478 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
479 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
480 | SUNXI_FUNCTION(0x2, "csi"), /* D9 */ | ||
481 | SUNXI_FUNCTION(0x3, "ts"), /* D5 */ | ||
482 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PE_EINT13 */ | ||
483 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14), | ||
484 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
485 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
486 | SUNXI_FUNCTION(0x2, "csi"), /* D10 */ | ||
487 | SUNXI_FUNCTION(0x3, "ts"), /* D6 */ | ||
488 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PE_EINT14 */ | ||
489 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15), | ||
490 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
491 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
492 | SUNXI_FUNCTION(0x2, "csi"), /* D11 */ | ||
493 | SUNXI_FUNCTION(0x3, "ts"), /* D7 */ | ||
494 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PE_EINT15 */ | ||
495 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16), | ||
496 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
497 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
498 | SUNXI_FUNCTION(0x2, "csi"), /* SCK */ | ||
499 | SUNXI_FUNCTION(0x3, "i2c4"), /* SCK */ | ||
500 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PE_EINT16 */ | ||
501 | SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17), | ||
502 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
503 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
504 | SUNXI_FUNCTION(0x2, "csi"), /* SDA */ | ||
505 | SUNXI_FUNCTION(0x3, "i2c4"), /* SDA */ | ||
506 | SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 17)), /* PE_EINT17 */ | ||
507 | |||
508 | /* Hole */ | ||
509 | SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0), | ||
510 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
511 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
512 | SUNXI_FUNCTION(0x2, "mmc0")), /* D1 */ | ||
513 | SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1), | ||
514 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
515 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
516 | SUNXI_FUNCTION(0x2, "mmc0")), /* D0 */ | ||
517 | SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2), | ||
518 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
519 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
520 | SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */ | ||
521 | SUNXI_FUNCTION(0x4, "uart0")), /* TX */ | ||
522 | SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3), | ||
523 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
524 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
525 | SUNXI_FUNCTION(0x2, "mmc0")), /* CMD */ | ||
526 | SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4), | ||
527 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
528 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
529 | SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */ | ||
530 | SUNXI_FUNCTION(0x4, "uart0")), /* RX */ | ||
531 | SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5), | ||
532 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
533 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
534 | SUNXI_FUNCTION(0x2, "mmc0")), /* D2 */ | ||
535 | |||
536 | /* Hole */ | ||
537 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), | ||
538 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
539 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
540 | SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */ | ||
541 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)), /* PG_EINT0 */ | ||
542 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1), | ||
543 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
544 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
545 | SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */ | ||
546 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)), /* PG_EINT1 */ | ||
547 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2), | ||
548 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
549 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
550 | SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */ | ||
551 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)), /* PG_EINT2 */ | ||
552 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3), | ||
553 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
554 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
555 | SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */ | ||
556 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)), /* PG_EINT3 */ | ||
557 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4), | ||
558 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
559 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
560 | SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */ | ||
561 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)), /* PG_EINT4 */ | ||
562 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5), | ||
563 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
564 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
565 | SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */ | ||
566 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)), /* PG_EINT5 */ | ||
567 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6), | ||
568 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
569 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
570 | SUNXI_FUNCTION(0x2, "uart2"), /* TX */ | ||
571 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)), /* PG_EINT6 */ | ||
572 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7), | ||
573 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
574 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
575 | SUNXI_FUNCTION(0x2, "uart2"), /* RX */ | ||
576 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)), /* PG_EINT7 */ | ||
577 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), | ||
578 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
579 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
580 | SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ | ||
581 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PG_EINT8 */ | ||
582 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), | ||
583 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
584 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
585 | SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ | ||
586 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PG_EINT9 */ | ||
587 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), | ||
588 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
589 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
590 | SUNXI_FUNCTION(0x2, "i2c3"), /* SCK */ | ||
591 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 10)), /* PG_EINT10 */ | ||
592 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11), | ||
593 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
594 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
595 | SUNXI_FUNCTION(0x2, "i2c3"), /* SDA */ | ||
596 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 11)), /* PG_EINT11 */ | ||
597 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12), | ||
598 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
599 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
600 | SUNXI_FUNCTION(0x2, "uart4"), /* TX */ | ||
601 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 12)), /* PG_EINT12 */ | ||
602 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13), | ||
603 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
604 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
605 | SUNXI_FUNCTION(0x2, "uart4"), /* RX */ | ||
606 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 13)), /* PG_EINT13 */ | ||
607 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14), | ||
608 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
609 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
610 | SUNXI_FUNCTION(0x2, "uart4"), /* RTS */ | ||
611 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 14)), /* PG_EINT14 */ | ||
612 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15), | ||
613 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
614 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
615 | SUNXI_FUNCTION(0x2, "uart4"), /* CTS */ | ||
616 | SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 15)), /* PG_EINT15 */ | ||
617 | |||
618 | /* Hole */ | ||
619 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0), | ||
620 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
621 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
622 | SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */ | ||
623 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1), | ||
624 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
625 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
626 | SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */ | ||
627 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2), | ||
628 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
629 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
630 | SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */ | ||
631 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3), | ||
632 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
633 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
634 | SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */ | ||
635 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4), | ||
636 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
637 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
638 | SUNXI_FUNCTION(0x2, "i2c2")), /* SCK */ | ||
639 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5), | ||
640 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
641 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
642 | SUNXI_FUNCTION(0x2, "i2c2")), /* SDA */ | ||
643 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6), | ||
644 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
645 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
646 | SUNXI_FUNCTION(0x2, "pwm0")), | ||
647 | |||
648 | /* Hole */ | ||
649 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8), | ||
650 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
651 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
652 | SUNXI_FUNCTION(0x3, "pwm1"), /* Positive */ | ||
653 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 8)), /* PH_EINT8 */ | ||
654 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9), | ||
655 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
656 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
657 | SUNXI_FUNCTION(0x3, "pwm1"), /* Negative */ | ||
658 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 9)), /* PH_EINT9 */ | ||
659 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10), | ||
660 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
661 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
662 | SUNXI_FUNCTION(0x3, "pwm2"), /* Positive */ | ||
663 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 10)), /* PH_EINT10 */ | ||
664 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11), | ||
665 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
666 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
667 | SUNXI_FUNCTION(0x3, "pwm2"), /* Negative */ | ||
668 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 11)), /* PH_EINT12 */ | ||
669 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 12), | ||
670 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
671 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
672 | SUNXI_FUNCTION(0x2, "uart0"), /* TX */ | ||
673 | SUNXI_FUNCTION(0x3, "spi3"), /* CS2 */ | ||
674 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 12)), /* PH_EINT12 */ | ||
675 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 13), | ||
676 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
677 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
678 | SUNXI_FUNCTION(0x2, "uart0"), /* RX */ | ||
679 | SUNXI_FUNCTION(0x3, "spi3"), /* CS2 */ | ||
680 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 13)), /* PH_EINT13 */ | ||
681 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 14), | ||
682 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
683 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
684 | SUNXI_FUNCTION(0x2, "spi3"), /* CLK */ | ||
685 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 14)), /* PH_EINT14 */ | ||
686 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 15), | ||
687 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
688 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
689 | SUNXI_FUNCTION(0x2, "spi3"), /* MOSI */ | ||
690 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 15)), /* PH_EINT15 */ | ||
691 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 16), | ||
692 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
693 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
694 | SUNXI_FUNCTION(0x2, "spi3"), /* MISO */ | ||
695 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 16)), /* PH_EINT16 */ | ||
696 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 17), | ||
697 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
698 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
699 | SUNXI_FUNCTION(0x2, "spi3"), /* CS0 */ | ||
700 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 17)), /* PH_EINT17 */ | ||
701 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 18), | ||
702 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
703 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
704 | SUNXI_FUNCTION(0x2, "spi3"), /* CS1 */ | ||
705 | SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 18)), /* PH_EINT18 */ | ||
706 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 19), | ||
707 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
708 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
709 | SUNXI_FUNCTION(0x2, "hdmi")), /* SCL */ | ||
710 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 20), | ||
711 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
712 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
713 | SUNXI_FUNCTION(0x2, "hdmi")), /* SDA */ | ||
714 | SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 21), | ||
715 | SUNXI_FUNCTION(0x0, "gpio_in"), | ||
716 | SUNXI_FUNCTION(0x1, "gpio_out"), | ||
717 | SUNXI_FUNCTION(0x2, "hdmi")), /* CEC */ | ||
718 | }; | ||
719 | |||
720 | static const struct sunxi_pinctrl_desc sun9i_a80_pinctrl_data = { | ||
721 | .pins = sun9i_a80_pins, | ||
722 | .npins = ARRAY_SIZE(sun9i_a80_pins), | ||
723 | .irq_banks = 5, | ||
724 | }; | ||
725 | |||
726 | static int sun9i_a80_pinctrl_probe(struct platform_device *pdev) | ||
727 | { | ||
728 | return sunxi_pinctrl_init(pdev, | ||
729 | &sun9i_a80_pinctrl_data); | ||
730 | } | ||
731 | |||
732 | static struct of_device_id sun9i_a80_pinctrl_match[] = { | ||
733 | { .compatible = "allwinner,sun9i-a80-pinctrl", }, | ||
734 | {} | ||
735 | }; | ||
736 | MODULE_DEVICE_TABLE(of, sun9i_a80_pinctrl_match); | ||
737 | |||
738 | static struct platform_driver sun9i_a80_pinctrl_driver = { | ||
739 | .probe = sun9i_a80_pinctrl_probe, | ||
740 | .driver = { | ||
741 | .name = "sun9i-a80-pinctrl", | ||
742 | .of_match_table = sun9i_a80_pinctrl_match, | ||
743 | }, | ||
744 | }; | ||
745 | module_platform_driver(sun9i_a80_pinctrl_driver); | ||
746 | |||
747 | MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); | ||
748 | MODULE_DESCRIPTION("Allwinner A80 pinctrl driver"); | ||
749 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h index 4245b96c7996..5a51523a3459 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define PI_BASE 256 | 27 | #define PI_BASE 256 |
28 | #define PL_BASE 352 | 28 | #define PL_BASE 352 |
29 | #define PM_BASE 384 | 29 | #define PM_BASE 384 |
30 | #define PN_BASE 416 | ||
30 | 31 | ||
31 | #define SUNXI_PINCTRL_PIN(bank, pin) \ | 32 | #define SUNXI_PINCTRL_PIN(bank, pin) \ |
32 | PINCTRL_PIN(P ## bank ## _BASE + (pin), "P" #bank #pin) | 33 | PINCTRL_PIN(P ## bank ## _BASE + (pin), "P" #bank #pin) |