summaryrefslogtreecommitdiff
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-07 17:20:53 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-07 17:20:53 -0700
commite0b8b78651350e8dcf9cc60a959ccbcfc5bc3061 (patch)
tree87cf0ed233021bb5c7486b35c2e34f1ea98b81c2 /drivers/pinctrl
parent54c72d5987ff9f3cf59529d5d4f5cf19eae3f695 (diff)
parente1ee5c578fb1fa24b7ccaf1a11237a2bd70b6f9a (diff)
Merge tag 'pinctrl-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pinctrl updates from Linus Walleij: "This is the bulk pin control changes for the v3.17 merge development cycle: - get rid of the .disable() callback from the driver callback vtable. This callback was abused and counterintuitive since a pin or group of pins can be said to always be in some setting, and never really disabled. We now only enable a certain muxing, and move between some certain muxings, we never "disable" a mux setting - some janitorial moving the MSM, Samsung and Nomadik and drivers to their own subdirectories for a clearer view in the subsystem. This will continue - kill off the use of the return value from gpiochip_remove(), this will be done in parallel in the GPIO subsystem and hopefully not trigger too many unchecked return value warnings before we get rid of this altogether - a huge set of changes and improvements to the Allwinner sunxi drivers especially for their latest A23 and A31 SoCs, and some ground work for the new sun8i platform family - a large set of Rockchip driver improvements adding support for the RK3288 SoC - advances in migration of older Freescale platforms to pin control, especially i.MX1 - Samsung and Exynos improvements - support for the Qualcomm MSM8960 SoC - use the gpiolib irqchip helpers for the ST SPEAr and Intel Baytrail drivers - a bunch of nice janitorial work done with cppcheck" * tag 'pinctrl-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (61 commits) pinctrl: baytrail: Convert to use gpiolib irqchip pinctrl: sunxi: number gpio ranges starting from 0 pinctrl: sunxi: use gpiolib API to mark a GPIO used as an IRQ pinctrl: rockchip: add drive-strength control for rk3288 pinctrl: rockchip: add separate type for rk3288 pinctrl: rockchip: set is_generic in pinconf_ops pinctrl: msm: drop negativity check on unsigned value pinctrl: remove all usage of gpio_remove ret val in driver/pinctl pinctrl: qcom: Make muxing of gpio function explicit pinctrl: nomadik: move all Nomadik drivers to subdir pinctrl: samsung: Group all drivers in a sub-dir sh-pfc: sh73a0: Introduce the use of devm_regulator_register sh-pfc: Add renesas,pfc-r8a7791 to binding documentation pinctrl: msm: move all qualcomm drivers to subdir pinctrl: msm: Add msm8960 definitions pinctrl: samsung: Allow pin value to be initialized using pinfunc pinctrl: samsung: Allow grouping multiple pinmux/pinconf nodes pinctrl: exynos: Consolidate irq_chips of GPIO and WKUP EINTs pinctrl: samsung: Handle GPIO request and free using pinctrl helpers pinctrl: samsung: Decouple direction setting from pinctrl ...
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/Kconfig117
-rw-r--r--drivers/pinctrl/Makefile24
-rw-r--r--drivers/pinctrl/core.c24
-rw-r--r--drivers/pinctrl/nomadik/Kconfig51
-rw-r--r--drivers/pinctrl/nomadik/Makefile10
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-ab8500.c (renamed from drivers/pinctrl/pinctrl-ab8500.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-ab8505.c (renamed from drivers/pinctrl/pinctrl-ab8505.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-ab8540.c (renamed from drivers/pinctrl/pinctrl-ab8540.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-ab9540.c (renamed from drivers/pinctrl/pinctrl-ab9540.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-abx500.c (renamed from drivers/pinctrl/pinctrl-abx500.c)19
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-abx500.h (renamed from drivers/pinctrl/pinctrl-abx500.h)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c (renamed from drivers/pinctrl/pinctrl-nomadik-db8500.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c (renamed from drivers/pinctrl/pinctrl-nomadik-db8540.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c (renamed from drivers/pinctrl/pinctrl-nomadik-stn8815.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik.c (renamed from drivers/pinctrl/pinctrl-nomadik.c)18
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik.h (renamed from drivers/pinctrl/pinctrl-nomadik.h)0
-rw-r--r--drivers/pinctrl/pinctrl-adi2.c41
-rw-r--r--drivers/pinctrl/pinctrl-as3722.c11
-rw-r--r--drivers/pinctrl/pinctrl-at91.c27
-rw-r--r--drivers/pinctrl/pinctrl-baytrail.c103
-rw-r--r--drivers/pinctrl/pinctrl-bcm281xx.c2
-rw-r--r--drivers/pinctrl/pinctrl-bcm2835.c11
-rw-r--r--drivers/pinctrl/pinctrl-coh901.c10
-rw-r--r--drivers/pinctrl/pinctrl-imx.c2
-rw-r--r--drivers/pinctrl/pinctrl-imx1-core.c2
-rw-r--r--drivers/pinctrl/pinctrl-imx1.c279
-rw-r--r--drivers/pinctrl/pinctrl-imx27.c52
-rw-r--r--drivers/pinctrl/pinctrl-rockchip.c401
-rw-r--r--drivers/pinctrl/pinctrl-single.c61
-rw-r--r--drivers/pinctrl/pinctrl-st.c15
-rw-r--r--drivers/pinctrl/pinctrl-tb10x.c17
-rw-r--r--drivers/pinctrl/pinctrl-tegra.c13
-rw-r--r--drivers/pinctrl/pinctrl-tz1090-pdc.c28
-rw-r--r--drivers/pinctrl/pinctrl-tz1090.c58
-rw-r--r--drivers/pinctrl/pinctrl-u300.c14
-rw-r--r--drivers/pinctrl/pinmux.c4
-rw-r--r--drivers/pinctrl/qcom/Kconfig42
-rw-r--r--drivers/pinctrl/qcom/Makefile6
-rw-r--r--drivers/pinctrl/qcom/pinctrl-apq8064.c (renamed from drivers/pinctrl/pinctrl-apq8064.c)19
-rw-r--r--drivers/pinctrl/qcom/pinctrl-ipq8064.c (renamed from drivers/pinctrl/pinctrl-ipq8064.c)17
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm.c (renamed from drivers/pinctrl/pinctrl-msm.c)42
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm.h (renamed from drivers/pinctrl/pinctrl-msm.h)0
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm8960.c1282
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm8x74.c (renamed from drivers/pinctrl/pinctrl-msm8x74.c)29
-rw-r--r--drivers/pinctrl/samsung/Kconfig28
-rw-r--r--drivers/pinctrl/samsung/Makefile7
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.c (renamed from drivers/pinctrl/pinctrl-exynos.c)307
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.h (renamed from drivers/pinctrl/pinctrl-exynos.h)0
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos5440.c (renamed from drivers/pinctrl/pinctrl-exynos5440.c)10
-rw-r--r--drivers/pinctrl/samsung/pinctrl-s3c24xx.c (renamed from drivers/pinctrl/pinctrl-s3c24xx.c)0
-rw-r--r--drivers/pinctrl/samsung/pinctrl-s3c64xx.c (renamed from drivers/pinctrl/pinctrl-s3c64xx.c)0
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.c (renamed from drivers/pinctrl/pinctrl-samsung.c)728
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.h (renamed from drivers/pinctrl/pinctrl-samsung.h)18
-rw-r--r--drivers/pinctrl/sh-pfc/gpio.c9
-rw-r--r--drivers/pinctrl/sh-pfc/pfc-r8a7791.c417
-rw-r--r--drivers/pinctrl/sh-pfc/pfc-sh73a0.c11
-rw-r--r--drivers/pinctrl/sh-pfc/pinctrl.c22
-rw-r--r--drivers/pinctrl/sirf/pinctrl-sirf.c10
-rw-r--r--drivers/pinctrl/spear/Kconfig1
-rw-r--r--drivers/pinctrl/spear/pinctrl-plgpio.c84
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.c7
-rw-r--r--drivers/pinctrl/sunxi/Kconfig24
-rw-r--r--drivers/pinctrl/sunxi/Makefile2
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c1
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c1
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c4
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c1
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c217
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c1
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c142
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c593
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sunxi.c187
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sunxi.h44
-rw-r--r--drivers/pinctrl/vt8500/pinctrl-wmt.c21
74 files changed, 4198 insertions, 1550 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 0042ccb46b9a..4e3231ad03cd 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -11,10 +11,10 @@ menu "Pin controllers"
depends on PINCTRL
config PINMUX
- bool "Support pin multiplexing controllers"
+ bool "Support pin multiplexing controllers" if COMPILE_TEST
config PINCONF
- bool "Support pin configuration controllers"
+ bool "Support pin configuration controllers" if COMPILE_TEST
config GENERIC_PINCONF
bool
@@ -26,29 +26,6 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
-config PINCTRL_ABX500
- bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
- depends on AB8500_CORE
- select GENERIC_PINCONF
- help
- Select this to enable the ABx500 family IC GPIO driver
-
-config PINCTRL_AB8500
- bool "AB8500 pin controller driver"
- depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB8540
- bool "AB8540 pin controller driver"
- depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB9540
- bool "AB9540 pin controller driver"
- depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB8505
- bool "AB8505 pin controller driver"
- depends on PINCTRL_ABX500 && ARCH_U8500
-
config PINCTRL_ADI2
bool "ADI pin controller driver"
depends on BLACKFIN
@@ -93,7 +70,7 @@ config PINCTRL_AT91
config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control"
depends on GPIOLIB && ACPI && X86
- select IRQ_DOMAIN
+ select GPIOLIB_IRQCHIP
help
driver for memory mapped GPIO functionality on Intel Baytrail
platforms. Supports 3 banks with 102, 28 and 44 gpios.
@@ -130,6 +107,13 @@ config PINCTRL_IMX1_CORE
select PINMUX
select PINCONF
+config PINCTRL_IMX1
+ bool "IMX1 pinctrl driver"
+ depends on SOC_IMX1
+ select PINCTRL_IMX1_CORE
+ help
+ Say Y here to enable the imx1 pinctrl driver
+
config PINCTRL_IMX27
bool "IMX27 pinctrl driver"
depends on SOC_IMX27
@@ -226,58 +210,6 @@ config PINCTRL_IMX28
bool
select PINCTRL_MXS
-config PINCTRL_MSM
- bool
- select PINMUX
- select PINCONF
- select GENERIC_PINCONF
- select GPIOLIB_IRQCHIP
-
-config PINCTRL_APQ8064
- tristate "Qualcomm APQ8064 pin controller driver"
- depends on GPIOLIB && OF
- select PINCTRL_MSM
- help
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
- Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
-
-config PINCTRL_IPQ8064
- tristate "Qualcomm IPQ8064 pin controller driver"
- depends on GPIOLIB && OF
- select PINCTRL_MSM
- help
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
- Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
-
-config PINCTRL_MSM8X74
- tristate "Qualcomm 8x74 pin controller driver"
- depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST)
- select PINCTRL_MSM
- help
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
- Qualcomm TLMM block found in the Qualcomm 8974 platform.
-
-config PINCTRL_NOMADIK
- bool "Nomadik pin controller driver"
- depends on ARCH_U8500 || ARCH_NOMADIK
- select PINMUX
- select PINCONF
- select GPIOLIB
- select OF_GPIO
- select GPIOLIB_IRQCHIP
-
-config PINCTRL_STN8815
- bool "STN8815 pin controller driver"
- depends on PINCTRL_NOMADIK && ARCH_NOMADIK
-
-config PINCTRL_DB8500
- bool "DB8500 pin controller driver"
- depends on PINCTRL_NOMADIK && ARCH_U8500
-
-config PINCTRL_DB8540
- bool "DB8540 pin controller driver"
- depends on PINCTRL_NOMADIK && ARCH_U8500
-
config PINCTRL_ROCKCHIP
bool
select PINMUX
@@ -356,22 +288,6 @@ config PINCTRL_COH901
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
ports of 8 GPIO pins each.
-config PINCTRL_SAMSUNG
- bool
- select PINMUX
- select PINCONF
-
-config PINCTRL_EXYNOS
- bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
- depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210)
- select PINCTRL_SAMSUNG
-
-config PINCTRL_EXYNOS5440
- bool "Samsung EXYNOS5440 SoC pinctrl driver"
- depends on SOC_EXYNOS5440
- select PINMUX
- select PINCONF
-
config PINCTRL_PALMAS
bool "Pinctrl driver for the PALMAS Series MFD devices"
depends on OF && MFD_PALMAS
@@ -383,18 +299,11 @@ config PINCTRL_PALMAS
open drain configuration for the Palmas series devices like
TPS65913, TPS80036 etc.
-config PINCTRL_S3C24XX
- bool "Samsung S3C24XX SoC pinctrl driver"
- depends on ARCH_S3C24XX
- select PINCTRL_SAMSUNG
-
-config PINCTRL_S3C64XX
- bool "Samsung S3C64XX SoC pinctrl driver"
- depends on ARCH_S3C64XX
- select PINCTRL_SAMSUNG
-
source "drivers/pinctrl/berlin/Kconfig"
source "drivers/pinctrl/mvebu/Kconfig"
+source "drivers/pinctrl/nomadik/Kconfig"
+source "drivers/pinctrl/qcom/Kconfig"
+source "drivers/pinctrl/samsung/Kconfig"
source "drivers/pinctrl/sh-pfc/Kconfig"
source "drivers/pinctrl/spear/Kconfig"
source "drivers/pinctrl/sunxi/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index c4b5d405b8f5..e90817c1f584 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -9,11 +9,6 @@ ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_PINCTRL) += devicetree.o
endif
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
-obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o
-obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
-obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o
-obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o
-obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o
obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
@@ -24,6 +19,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.o
+obj-$(CONFIG_PINCTRL_IMX1) += pinctrl-imx1.o
obj-$(CONFIG_PINCTRL_IMX27) += pinctrl-imx27.o
obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o
obj-$(CONFIG_PINCTRL_IMX50) += pinctrl-imx50.o
@@ -38,14 +34,6 @@ obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
-obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
-obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o
-obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
-obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
-obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
-obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
-obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
-obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
@@ -59,11 +47,6 @@ obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o
obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
-obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
-obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
-obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
-obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
-obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
@@ -72,8 +55,11 @@ obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-$(CONFIG_PLAT_ORION) += mvebu/
+obj-y += nomadik/
+obj-$(CONFIG_ARCH_QCOM) += qcom/
+obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/
obj-$(CONFIG_SUPERH) += sh-pfc/
obj-$(CONFIG_PLAT_SPEAR) += spear/
-obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
+obj-$(CONFIG_ARCH_VT8500) += vt8500/
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index e09474ecde23..e4f65510c87e 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -992,29 +992,15 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
if (p->state) {
/*
- * The set of groups with a mux configuration in the old state
- * may not be identical to the set of groups with a mux setting
- * in the new state. While this might be unusual, it's entirely
- * possible for the "user"-supplied mapping table to be written
- * that way. For each group that was configured in the old state
- * but not in the new state, this code puts that group into a
- * safe/disabled state.
+ * For each pinmux setting in the old state, forget SW's record
+ * of mux owner for that pingroup. Any pingroups which are
+ * still owned by the new state will be re-acquired by the call
+ * to pinmux_enable_setting() in the loop below.
*/
list_for_each_entry(setting, &p->state->settings, node) {
- bool found = false;
if (setting->type != PIN_MAP_TYPE_MUX_GROUP)
continue;
- list_for_each_entry(setting2, &state->settings, node) {
- if (setting2->type != PIN_MAP_TYPE_MUX_GROUP)
- continue;
- if (setting2->data.mux.group ==
- setting->data.mux.group) {
- found = true;
- break;
- }
- }
- if (!found)
- pinmux_disable_setting(setting);
+ pinmux_disable_setting(setting);
}
}
diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig
new file mode 100644
index 000000000000..d48a5aa24a29
--- /dev/null
+++ b/drivers/pinctrl/nomadik/Kconfig
@@ -0,0 +1,51 @@
+if ARCH_U8500
+
+config PINCTRL_ABX500
+ bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
+ depends on AB8500_CORE
+ select GENERIC_PINCONF
+ help
+ Select this to enable the ABx500 family IC GPIO driver
+
+config PINCTRL_AB8500
+ bool "AB8500 pin controller driver"
+ depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB8540
+ bool "AB8540 pin controller driver"
+ depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB9540
+ bool "AB9540 pin controller driver"
+ depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB8505
+ bool "AB8505 pin controller driver"
+ depends on PINCTRL_ABX500 && ARCH_U8500
+
+endif
+
+if (ARCH_U8500 || ARCH_NOMADIK)
+
+config PINCTRL_NOMADIK
+ bool "Nomadik pin controller driver"
+ depends on ARCH_U8500 || ARCH_NOMADIK
+ select PINMUX
+ select PINCONF
+ select GPIOLIB
+ select OF_GPIO
+ select GPIOLIB_IRQCHIP
+
+config PINCTRL_STN8815
+ bool "STN8815 pin controller driver"
+ depends on PINCTRL_NOMADIK && ARCH_NOMADIK
+
+config PINCTRL_DB8500
+ bool "DB8500 pin controller driver"
+ depends on PINCTRL_NOMADIK && ARCH_U8500
+
+config PINCTRL_DB8540
+ bool "DB8540 pin controller driver"
+ depends on PINCTRL_NOMADIK && ARCH_U8500
+
+endif
diff --git a/drivers/pinctrl/nomadik/Makefile b/drivers/pinctrl/nomadik/Makefile
new file mode 100644
index 000000000000..30b27f18cd52
--- /dev/null
+++ b/drivers/pinctrl/nomadik/Makefile
@@ -0,0 +1,10 @@
+# Nomadik family pin control drivers
+obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o
+obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
+obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o
+obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o
+obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o
+obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
+obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
+obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
+obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o
diff --git a/drivers/pinctrl/pinctrl-ab8500.c b/drivers/pinctrl/nomadik/pinctrl-ab8500.c
index 2ac2d0ad3025..2ac2d0ad3025 100644
--- a/drivers/pinctrl/pinctrl-ab8500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-ab8500.c
diff --git a/drivers/pinctrl/pinctrl-ab8505.c b/drivers/pinctrl/nomadik/pinctrl-ab8505.c
index bf0ef4ac376f..bf0ef4ac376f 100644
--- a/drivers/pinctrl/pinctrl-ab8505.c
+++ b/drivers/pinctrl/nomadik/pinctrl-ab8505.c
diff --git a/drivers/pinctrl/pinctrl-ab8540.c b/drivers/pinctrl/nomadik/pinctrl-ab8540.c
index 9867535d49c1..9867535d49c1 100644
--- a/drivers/pinctrl/pinctrl-ab8540.c
+++ b/drivers/pinctrl/nomadik/pinctrl-ab8540.c
diff --git a/drivers/pinctrl/pinctrl-ab9540.c b/drivers/pinctrl/nomadik/pinctrl-ab9540.c
index 1a281ca95dac..1a281ca95dac 100644
--- a/drivers/pinctrl/pinctrl-ab9540.c
+++ b/drivers/pinctrl/nomadik/pinctrl-ab9540.c
diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c
index 163da9c3ea0e..a53a689a2bfa 100644
--- a/drivers/pinctrl/pinctrl-abx500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c
@@ -32,8 +32,8 @@
#include <linux/pinctrl/machine.h>
#include "pinctrl-abx500.h"
-#include "core.h"
-#include "pinconf.h"
+#include "../core.h"
+#include "../pinconf.h"
/*
* The AB9540 and AB8540 GPIO support are extended versions
@@ -737,20 +737,6 @@ static int abx500_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
return ret;
}
-static void abx500_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned function, unsigned group)
-{
- struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
- const struct abx500_pingroup *g;
-
- g = &pct->soc->groups[group];
- if (g->altsetting < 0)
- return;
-
- /* FIXME: poke out the mux, set the pin to some default state? */
- dev_dbg(pct->dev, "disable group %s, %u pins\n", g->name, g->npins);
-}
-
static int abx500_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -799,7 +785,6 @@ static const struct pinmux_ops abx500_pinmux_ops = {
.get_function_name = abx500_pmx_get_func_name,
.get_function_groups = abx500_pmx_get_func_groups,
.enable = abx500_pmx_enable,
- .disable = abx500_pmx_disable,
.gpio_request_enable = abx500_gpio_request_enable,
.gpio_disable_free = abx500_gpio_disable_free,
};
diff --git a/drivers/pinctrl/pinctrl-abx500.h b/drivers/pinctrl/nomadik/pinctrl-abx500.h
index 2beef3bfe9ca..2beef3bfe9ca 100644
--- a/drivers/pinctrl/pinctrl-abx500.h
+++ b/drivers/pinctrl/nomadik/pinctrl-abx500.h
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
index c74840729648..c74840729648 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c
index d7ba5443bae0..d7ba5443bae0 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8540.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c
diff --git a/drivers/pinctrl/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
index ed39dcafd4f8..ed39dcafd4f8 100644
--- a/drivers/pinctrl/pinctrl-nomadik-stn8815.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 8f6f16ef73f3..e7cab07eef47 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -31,7 +31,7 @@
/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
#include "pinctrl-nomadik.h"
-#include "core.h"
+#include "../core.h"
/*
* The GPIO module in the Nomadik family of Systems-on-Chip is an
@@ -1765,21 +1765,6 @@ out_glitch:
return ret;
}
-static void nmk_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned function, unsigned group)
-{
- struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
- const struct nmk_pingroup *g;
-
- g = &npct->soc->groups[group];
-
- if (g->altsetting < 0)
- return;
-
- /* Poke out the mux, set the pin to some default state? */
- dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins);
-}
-
static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -1826,7 +1811,6 @@ static const struct pinmux_ops nmk_pinmux_ops = {
.get_function_name = nmk_pmx_get_func_name,
.get_function_groups = nmk_pmx_get_func_groups,
.enable = nmk_pmx_enable,
- .disable = nmk_pmx_disable,
.gpio_request_enable = nmk_gpio_request_enable,
.gpio_disable_free = nmk_gpio_disable_free,
};
diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h
index d8215f1e70c7..d8215f1e70c7 100644
--- a/drivers/pinctrl/pinctrl-nomadik.h
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.h
diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c
index 5c44feb54ebb..b092b93c67a1 100644
--- a/drivers/pinctrl/pinctrl-adi2.c
+++ b/drivers/pinctrl/pinctrl-adi2.c
@@ -401,7 +401,7 @@ static int adi_gpio_irq_type(struct irq_data *d, unsigned int type)
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
- snprintf(buf, 16, "gpio-irq%d", irq);
+ snprintf(buf, 16, "gpio-irq%u", irq);
port_setup(port, d->hwirq, true);
} else
goto out;
@@ -652,35 +652,6 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id,
return 0;
}
-static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned func_id,
- unsigned group_id)
-{
- struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
- struct gpio_port *port;
- struct pinctrl_gpio_range *range;
- unsigned long flags;
- unsigned short *mux, pin;
-
- mux = (unsigned short *)pinctrl->soc->groups[group_id].mux;
-
- while (*mux) {
- pin = P_IDENT(*mux);
-
- range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
- if (range == NULL) /* should not happen */
- return;
-
- port = container_of(range->gc, struct gpio_port, chip);
-
- spin_lock_irqsave(&port->lock, flags);
-
- port_setup(port, pin_to_offset(range, pin), true);
- mux++;
-
- spin_unlock_irqrestore(&port->lock, flags);
- }
-}
-
static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
{
struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
@@ -728,7 +699,6 @@ static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev,
static struct pinmux_ops adi_pinmux_ops = {
.enable = adi_pinmux_enable,
- .disable = adi_pinmux_disable,
.get_functions_count = adi_pinmux_get_funcs_count,
.get_function_name = adi_pinmux_get_func_name,
.get_function_groups = adi_pinmux_get_groups,
@@ -979,7 +949,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
struct gpio_port *port;
char pinctrl_devname[DEVNAME_SIZE];
static int gpio;
- int ret = 0, ret1;
+ int ret = 0;
pdata = dev->platform_data;
if (!pdata)
@@ -1057,7 +1027,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
return 0;
out_remove_gpiochip:
- ret1 = gpiochip_remove(&port->chip);
+ gpiochip_remove(&port->chip);
out_remove_domain:
if (port->pint)
irq_domain_remove(port->domain);
@@ -1068,12 +1038,11 @@ out_remove_domain:
static int adi_gpio_remove(struct platform_device *pdev)
{
struct gpio_port *port = platform_get_drvdata(pdev);
- int ret;
u8 offset;
list_del(&port->node);
gpiochip_remove_pin_ranges(&port->chip);
- ret = gpiochip_remove(&port->chip);
+ gpiochip_remove(&port->chip);
if (port->pint) {
for (offset = 0; offset < port->width; offset++)
irq_dispose_mapping(irq_find_mapping(port->domain,
@@ -1081,7 +1050,7 @@ static int adi_gpio_remove(struct platform_device *pdev)
irq_domain_remove(port->domain);
}
- return ret;
+ return 0;
}
static int adi_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/pinctrl-as3722.c b/drivers/pinctrl/pinctrl-as3722.c
index c862f9c0e9ce..0e4ec91f4d49 100644
--- a/drivers/pinctrl/pinctrl-as3722.c
+++ b/drivers/pinctrl/pinctrl-as3722.c
@@ -565,7 +565,6 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
{
struct as3722_pctrl_info *as_pci;
int ret;
- int tret;
as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
if (!as_pci)
@@ -611,10 +610,7 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
return 0;
fail_range_add:
- tret = gpiochip_remove(&as_pci->gpio_chip);
- if (tret < 0)
- dev_warn(&pdev->dev, "Couldn't remove gpio chip, %d\n", tret);
-
+ gpiochip_remove(&as_pci->gpio_chip);
fail_chip_add:
pinctrl_unregister(as_pci->pctl);
return ret;
@@ -623,11 +619,8 @@ fail_chip_add:
static int as3722_pinctrl_remove(struct platform_device *pdev)
{
struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
- int ret;
- ret = gpiochip_remove(&as_pci->gpio_chip);
- if (ret < 0)
- return ret;
+ gpiochip_remove(&as_pci->gpio_chip);
pinctrl_unregister(as_pci->pctl);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 421493cb490c..af1ba4fc150d 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -611,26 +611,6 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
-static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf;
- const struct at91_pmx_pin *pin;
- uint32_t npins = info->groups[group].npins;
- int i;
- unsigned mask;
- void __iomem *pio;
-
- for (i = 0; i < npins; i++) {
- pin = &pins_conf[i];
- at91_pin_dbg(info->dev, pin);
- pio = pin_to_controller(info, pin->bank);
- mask = pin_to_mask(pin->pin);
- at91_mux_gpio_enable(pio, mask, 1);
- }
-}
-
static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
{
struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
@@ -705,7 +685,6 @@ static const struct pinmux_ops at91_pmx_ops = {
.get_function_name = at91_pmx_get_func_name,
.get_function_groups = at91_pmx_get_groups,
.enable = at91_pmx_enable,
- .disable = at91_pmx_disable,
.gpio_request_enable = at91_gpio_request_enable,
.gpio_disable_free = at91_gpio_disable_free,
};
@@ -793,9 +772,9 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin_id)
{
unsigned long config;
- int ret, val, num_conf = 0;
+ int val, num_conf = 0;
- ret = at91_pinconf_get(pctldev, pin_id, &config);
+ at91_pinconf_get(pctldev, pin_id, &config);
DBG_SHOW_FLAG(MULTI_DRIVE);
DBG_SHOW_FLAG(PULL_UP);
@@ -945,7 +924,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */
func->name = np->name;
func->ngroups = of_get_child_count(np);
- if (func->ngroups <= 0) {
+ if (func->ngroups == 0) {
dev_err(info->dev, "no groups defined\n");
return -EINVAL;
}
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c
index 975572e2f260..9ca59a018743 100644
--- a/drivers/pinctrl/pinctrl-baytrail.c
+++ b/drivers/pinctrl/pinctrl-baytrail.c
@@ -25,9 +25,7 @@
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
-#include <linux/irq.h>
#include <linux/gpio.h>
-#include <linux/irqdomain.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>
@@ -44,6 +42,7 @@
/* BYT_CONF0_REG register bits */
#define BYT_IODEN BIT(31)
+#define BYT_DIRECT_IRQ_EN BIT(27)
#define BYT_TRIG_NEG BIT(26)
#define BYT_TRIG_POS BIT(25)
#define BYT_TRIG_LVL BIT(24)
@@ -137,7 +136,6 @@ static struct pinctrl_gpio_range byt_ranges[] = {
struct byt_gpio {
struct gpio_chip chip;
- struct irq_domain *domain;
struct platform_device *pdev;
spinlock_t lock;
void __iomem *reg_base;
@@ -217,7 +215,7 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
static int byt_irq_type(struct irq_data *d, unsigned type)
{
- struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
+ struct byt_gpio *vg = to_byt_gpio(irq_data_get_irq_chip_data(d));
u32 offset = irqd_to_hwirq(d);
u32 value;
unsigned long flags;
@@ -303,12 +301,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value)
{
struct byt_gpio *vg = to_byt_gpio(chip);
+ void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
unsigned long flags;
u32 reg_val;
spin_lock_irqsave(&vg->lock, flags);
+ /*
+ * Before making any direction modifications, do a check if gpio
+ * is set for direct IRQ. On baytrail, setting GPIO to output does
+ * not make sense, so let's at least warn the caller before they shoot
+ * themselves in the foot.
+ */
+ WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
+ "Potential Error: Setting GPIO with direct_irq_en to output");
+
reg_val = readl(reg) | BYT_DIR_MASK;
reg_val &= ~BYT_OUTPUT_EN;
@@ -393,16 +401,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
spin_unlock_irqrestore(&vg->lock, flags);
}
-static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct byt_gpio *vg = to_byt_gpio(chip);
- return irq_create_mapping(vg->domain, offset);
-}
-
static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct irq_data *data = irq_desc_get_irq_data(desc);
- struct byt_gpio *vg = irq_data_get_irq_handler_data(data);
+ struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
struct irq_chip *chip = irq_data_get_irq_chip(data);
u32 base, pin, mask;
void __iomem *reg;
@@ -421,7 +423,7 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
/* Clear before handling so we can't lose an edge */
writel(mask, reg);
- virq = irq_find_mapping(vg->domain, base + pin);
+ virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
generic_handle_irq(virq);
/* In case bios or user sets triggering incorretly a pin
@@ -454,33 +456,11 @@ static void byt_irq_mask(struct irq_data *d)
{
}
-static int byt_irq_reqres(struct irq_data *d)
-{
- struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
-
- if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d))) {
- dev_err(vg->chip.dev,
- "unable to lock HW IRQ %lu for IRQ\n",
- irqd_to_hwirq(d));
- return -EINVAL;
- }
- return 0;
-}
-
-static void byt_irq_relres(struct irq_data *d)
-{
- struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
-
- gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
-}
-
static struct irq_chip byt_irqchip = {
.name = "BYT-GPIO",
.irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type,
- .irq_request_resources = byt_irq_reqres,
- .irq_release_resources = byt_irq_relres,
};
static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
@@ -501,23 +481,6 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
}
}
-static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct byt_gpio *vg = d->host_data;
-
- irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq,
- "demux");
- irq_set_chip_data(virq, vg);
- irq_set_irq_type(virq, IRQ_TYPE_NONE);
-
- return 0;
-}
-
-static const struct irq_domain_ops byt_gpio_irq_ops = {
- .map = byt_gpio_irq_map,
-};
-
static int byt_gpio_probe(struct platform_device *pdev)
{
struct byt_gpio *vg;
@@ -527,7 +490,6 @@ static int byt_gpio_probe(struct platform_device *pdev)
struct acpi_device *acpi_dev;
struct pinctrl_gpio_range *range;
acpi_handle handle = ACPI_HANDLE(dev);
- unsigned hwirq;
int ret;
if (acpi_bus_get_device(handle, &acpi_dev))
@@ -574,27 +536,27 @@ static int byt_gpio_probe(struct platform_device *pdev)
gc->can_sleep = false;
gc->dev = dev;
+ ret = gpiochip_add(gc);
+ if (ret) {
+ dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
+ return ret;
+ }
+
/* set up interrupts */
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq_rc && irq_rc->start) {
- hwirq = irq_rc->start;
- gc->to_irq = byt_gpio_to_irq;
-
- vg->domain = irq_domain_add_linear(NULL, gc->ngpio,
- &byt_gpio_irq_ops, vg);
- if (!vg->domain)
- return -ENXIO;
-
byt_gpio_irq_init_hw(vg);
+ ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
+ handle_simple_irq, IRQ_TYPE_NONE);
+ if (ret) {
+ dev_err(dev, "failed to add irqchip\n");
+ gpiochip_remove(gc);
+ return ret;
+ }
- irq_set_handler_data(hwirq, vg);
- irq_set_chained_handler(hwirq, byt_gpio_irq_handler);
- }
-
- ret = gpiochip_add(gc);
- if (ret) {
- dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
- return ret;
+ gpiochip_set_chained_irqchip(gc, &byt_irqchip,
+ (unsigned)irq_rc->start,
+ byt_gpio_irq_handler);
}
pm_runtime_enable(dev);
@@ -627,12 +589,9 @@ MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
static int byt_gpio_remove(struct platform_device *pdev)
{
struct byt_gpio *vg = platform_get_drvdata(pdev);
- int err;
pm_runtime_disable(&pdev->dev);
- err = gpiochip_remove(&vg->chip);
- if (err)
- dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
+ gpiochip_remove(&vg->chip);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c
index 3bed792b2c03..c5ca9e633fff 100644
--- a/drivers/pinctrl/pinctrl-bcm281xx.c
+++ b/drivers/pinctrl/pinctrl-bcm281xx.c
@@ -1396,7 +1396,7 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = {
.owner = THIS_MODULE,
};
-int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
+static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
{
struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
struct resource *res;
diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c
index 3d907de9bc91..5bcfd7ace0cd 100644
--- a/drivers/pinctrl/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/pinctrl-bcm2835.c
@@ -841,16 +841,6 @@ static int bcm2835_pmx_enable(struct pinctrl_dev *pctldev,
return 0;
}
-static void bcm2835_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned func_selector,
- unsigned group_selector)
-{
- struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
-
- /* disable by setting to GPIO_IN */
- bcm2835_pinctrl_fsel_set(pc, group_selector, BCM2835_FSEL_GPIO_IN);
-}
-
static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -880,7 +870,6 @@ static const struct pinmux_ops bcm2835_pmx_ops = {
.get_function_name = bcm2835_pmx_get_function_name,
.get_function_groups = bcm2835_pmx_get_function_groups,
.enable = bcm2835_pmx_enable,
- .disable = bcm2835_pmx_disable,
.gpio_disable_free = bcm2835_pmx_gpio_disable_free,
.gpio_set_direction = bcm2835_pmx_gpio_set_direction,
};
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c
index d182fdd2e715..29cbbab8c3a6 100644
--- a/drivers/pinctrl/pinctrl-coh901.c
+++ b/drivers/pinctrl/pinctrl-coh901.c
@@ -756,8 +756,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
err_no_range:
err_no_irqchip:
- if (gpiochip_remove(&gpio->chip))
- dev_err(&pdev->dev, "failed to remove gpio chip\n");
+ gpiochip_remove(&gpio->chip);
err_no_chip:
clk_disable_unprepare(gpio->clk);
dev_err(&pdev->dev, "module ERROR:%d\n", err);
@@ -767,16 +766,11 @@ err_no_chip:
static int __exit u300_gpio_remove(struct platform_device *pdev)
{
struct u300_gpio *gpio = platform_get_drvdata(pdev);
- int err;
/* Turn off the GPIO block */
writel(0x00000000U, gpio->base + U300_GPIO_CR);
- err = gpiochip_remove(&gpio->chip);
- if (err < 0) {
- dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err);
- return err;
- }
+ gpiochip_remove(&gpio->chip);
clk_disable_unprepare(gpio->clk);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c
index a24448e5d399..946d594a64dd 100644
--- a/drivers/pinctrl/pinctrl-imx.c
+++ b/drivers/pinctrl/pinctrl-imx.c
@@ -515,7 +515,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */
func->name = np->name;
func->num_groups = of_get_child_count(np);
- if (func->num_groups <= 0) {
+ if (func->num_groups == 0) {
dev_err(info->dev, "no groups defined in %s\n", np->full_name);
return -EINVAL;
}
diff --git a/drivers/pinctrl/pinctrl-imx1-core.c b/drivers/pinctrl/pinctrl-imx1-core.c
index 815384b377b5..483420757c9f 100644
--- a/drivers/pinctrl/pinctrl-imx1-core.c
+++ b/drivers/pinctrl/pinctrl-imx1-core.c
@@ -526,7 +526,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */
func->name = np->name;
func->num_groups = of_get_child_count(np);
- if (func->num_groups <= 0)
+ if (func->num_groups == 0)
return -EINVAL;
func->groups = devm_kzalloc(info->dev,
diff --git a/drivers/pinctrl/pinctrl-imx1.c b/drivers/pinctrl/pinctrl-imx1.c
new file mode 100644
index 000000000000..533a6e519648
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-imx1.c
@@ -0,0 +1,279 @@
+/*
+ * i.MX1 pinctrl driver based on imx pinmux core
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx1.h"
+
+#define PAD_ID(port, pin) ((port) * 32 + (pin))
+#define PA 0
+#define PB 1
+#define PC 2
+#define PD 3
+
+enum imx1_pads {
+ MX1_PAD_A24 = PAD_ID(PA, 0),
+ MX1_PAD_TIN = PAD_ID(PA, 1),
+ MX1_PAD_PWMO = PAD_ID(PA, 2),
+ MX1_PAD_CSI_MCLK = PAD_ID(PA, 3),
+ MX1_PAD_CSI_D0 = PAD_ID(PA, 4),
+ MX1_PAD_CSI_D1 = PAD_ID(PA, 5),
+ MX1_PAD_CSI_D2 = PAD_ID(PA, 6),
+ MX1_PAD_CSI_D3 = PAD_ID(PA, 7),
+ MX1_PAD_CSI_D4 = PAD_ID(PA, 8),
+ MX1_PAD_CSI_D5 = PAD_ID(PA, 9),
+ MX1_PAD_CSI_D6 = PAD_ID(PA, 10),
+ MX1_PAD_CSI_D7 = PAD_ID(PA, 11),
+ MX1_PAD_CSI_VSYNC = PAD_ID(PA, 12),
+ MX1_PAD_CSI_HSYNC = PAD_ID(PA, 13),
+ MX1_PAD_CSI_PIXCLK = PAD_ID(PA, 14),
+ MX1_PAD_I2C_SDA = PAD_ID(PA, 15),
+ MX1_PAD_I2C_SCL = PAD_ID(PA, 16),
+ MX1_PAD_DTACK = PAD_ID(PA, 17),
+ MX1_PAD_BCLK = PAD_ID(PA, 18),
+ MX1_PAD_LBA = PAD_ID(PA, 19),
+ MX1_PAD_ECB = PAD_ID(PA, 20),
+ MX1_PAD_A0 = PAD_ID(PA, 21),
+ MX1_PAD_CS4 = PAD_ID(PA, 22),
+ MX1_PAD_CS5 = PAD_ID(PA, 23),
+ MX1_PAD_A16 = PAD_ID(PA, 24),
+ MX1_PAD_A17 = PAD_ID(PA, 25),
+ MX1_PAD_A18 = PAD_ID(PA, 26),
+ MX1_PAD_A19 = PAD_ID(PA, 27),
+ MX1_PAD_A20 = PAD_ID(PA, 28),
+ MX1_PAD_A21 = PAD_ID(PA, 29),
+ MX1_PAD_A22 = PAD_ID(PA, 30),
+ MX1_PAD_A23 = PAD_ID(PA, 31),
+ MX1_PAD_SD_DAT0 = PAD_ID(PB, 8),
+ MX1_PAD_SD_DAT1 = PAD_ID(PB, 9),
+ MX1_PAD_SD_DAT2 = PAD_ID(PB, 10),
+ MX1_PAD_SD_DAT3 = PAD_ID(PB, 11),
+ MX1_PAD_SD_SCLK = PAD_ID(PB, 12),
+ MX1_PAD_SD_CMD = PAD_ID(PB, 13),
+ MX1_PAD_SIM_SVEN = PAD_ID(PB, 14),
+ MX1_PAD_SIM_PD = PAD_ID(PB, 15),
+ MX1_PAD_SIM_TX = PAD_ID(PB, 16),
+ MX1_PAD_SIM_RX = PAD_ID(PB, 17),
+ MX1_PAD_SIM_RST = PAD_ID(PB, 18),
+ MX1_PAD_SIM_CLK = PAD_ID(PB, 19),
+ MX1_PAD_USBD_AFE = PAD_ID(PB, 20),
+ MX1_PAD_USBD_OE = PAD_ID(PB, 21),
+ MX1_PAD_USBD_RCV = PAD_ID(PB, 22),
+ MX1_PAD_USBD_SUSPND = PAD_ID(PB, 23),
+ MX1_PAD_USBD_VP = PAD_ID(PB, 24),
+ MX1_PAD_USBD_VM = PAD_ID(PB, 25),
+ MX1_PAD_USBD_VPO = PAD_ID(PB, 26),
+ MX1_PAD_USBD_VMO = PAD_ID(PB, 27),
+ MX1_PAD_UART2_CTS = PAD_ID(PB, 28),
+ MX1_PAD_UART2_RTS = PAD_ID(PB, 29),
+ MX1_PAD_UART2_TXD = PAD_ID(PB, 30),
+ MX1_PAD_UART2_RXD = PAD_ID(PB, 31),
+ MX1_PAD_SSI_RXFS = PAD_ID(PC, 3),
+ MX1_PAD_SSI_RXCLK = PAD_ID(PC, 4),
+ MX1_PAD_SSI_RXDAT = PAD_ID(PC, 5),
+ MX1_PAD_SSI_TXDAT = PAD_ID(PC, 6),
+ MX1_PAD_SSI_TXFS = PAD_ID(PC, 7),
+ MX1_PAD_SSI_TXCLK = PAD_ID(PC, 8),
+ MX1_PAD_UART1_CTS = PAD_ID(PC, 9),
+ MX1_PAD_UART1_RTS = PAD_ID(PC, 10),
+ MX1_PAD_UART1_TXD = PAD_ID(PC, 11),
+ MX1_PAD_UART1_RXD = PAD_ID(PC, 12),
+ MX1_PAD_SPI1_RDY = PAD_ID(PC, 13),
+ MX1_PAD_SPI1_SCLK = PAD_ID(PC, 14),
+ MX1_PAD_SPI1_SS = PAD_ID(PC, 15),
+ MX1_PAD_SPI1_MISO = PAD_ID(PC, 16),
+ MX1_PAD_SPI1_MOSI = PAD_ID(PC, 17),
+ MX1_PAD_BT13 = PAD_ID(PC, 19),
+ MX1_PAD_BT12 = PAD_ID(PC, 20),
+ MX1_PAD_BT11 = PAD_ID(PC, 21),
+ MX1_PAD_BT10 = PAD_ID(PC, 22),
+ MX1_PAD_BT9 = PAD_ID(PC, 23),
+ MX1_PAD_BT8 = PAD_ID(PC, 24),
+ MX1_PAD_BT7 = PAD_ID(PC, 25),
+ MX1_PAD_BT6 = PAD_ID(PC, 26),
+ MX1_PAD_BT5 = PAD_ID(PC, 27),
+ MX1_PAD_BT4 = PAD_ID(PC, 28),
+ MX1_PAD_BT3 = PAD_ID(PC, 29),
+ MX1_PAD_BT2 = PAD_ID(PC, 30),
+ MX1_PAD_BT1 = PAD_ID(PC, 31),
+ MX1_PAD_LSCLK = PAD_ID(PD, 6),
+ MX1_PAD_REV = PAD_ID(PD, 7),
+ MX1_PAD_CLS = PAD_ID(PD, 8),
+ MX1_PAD_PS = PAD_ID(PD, 9),
+ MX1_PAD_SPL_SPR = PAD_ID(PD, 10),
+ MX1_PAD_CONTRAST = PAD_ID(PD, 11),
+ MX1_PAD_ACD_OE = PAD_ID(PD, 12),
+ MX1_PAD_LP_HSYNC = PAD_ID(PD, 13),
+ MX1_PAD_FLM_VSYNC = PAD_ID(PD, 14),
+ MX1_PAD_LD0 = PAD_ID(PD, 15),
+ MX1_PAD_LD1 = PAD_ID(PD, 16),
+ MX1_PAD_LD2 = PAD_ID(PD, 17),
+ MX1_PAD_LD3 = PAD_ID(PD, 18),
+ MX1_PAD_LD4 = PAD_ID(PD, 19),
+ MX1_PAD_LD5 = PAD_ID(PD, 20),
+ MX1_PAD_LD6 = PAD_ID(PD, 21),
+ MX1_PAD_LD7 = PAD_ID(PD, 22),
+ MX1_PAD_LD8 = PAD_ID(PD, 23),
+ MX1_PAD_LD9 = PAD_ID(PD, 24),
+ MX1_PAD_LD10 = PAD_ID(PD, 25),
+ MX1_PAD_LD11 = PAD_ID(PD, 26),
+ MX1_PAD_LD12 = PAD_ID(PD, 27),
+ MX1_PAD_LD13 = PAD_ID(PD, 28),
+ MX1_PAD_LD14 = PAD_ID(PD, 29),
+ MX1_PAD_LD15 = PAD_ID(PD, 30),
+ MX1_PAD_TMR2OUT = PAD_ID(PD, 31),
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx1_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(MX1_PAD_A24),
+ IMX_PINCTRL_PIN(MX1_PAD_TIN),
+ IMX_PINCTRL_PIN(MX1_PAD_PWMO),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_MCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D0),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D1),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D2),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D3),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D4),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D5),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D6),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D7),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_VSYNC),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_HSYNC),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_PIXCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_I2C_SDA),
+ IMX_PINCTRL_PIN(MX1_PAD_I2C_SCL),
+ IMX_PINCTRL_PIN(MX1_PAD_DTACK),
+ IMX_PINCTRL_PIN(MX1_PAD_BCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_LBA),
+ IMX_PINCTRL_PIN(MX1_PAD_ECB),
+ IMX_PINCTRL_PIN(MX1_PAD_A0),
+ IMX_PINCTRL_PIN(MX1_PAD_CS4),
+ IMX_PINCTRL_PIN(MX1_PAD_CS5),
+ IMX_PINCTRL_PIN(MX1_PAD_A16),
+ IMX_PINCTRL_PIN(MX1_PAD_A17),
+ IMX_PINCTRL_PIN(MX1_PAD_A18),
+ IMX_PINCTRL_PIN(MX1_PAD_A19),
+ IMX_PINCTRL_PIN(MX1_PAD_A20),
+ IMX_PINCTRL_PIN(MX1_PAD_A21),
+ IMX_PINCTRL_PIN(MX1_PAD_A22),
+ IMX_PINCTRL_PIN(MX1_PAD_A23),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_DAT0),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_DAT1),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_DAT2),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_DAT3),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_SCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_CMD),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_SVEN),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_PD),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_TX),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_RX),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_CLK),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_AFE),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_OE),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_RCV),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_SUSPND),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_VP),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_VM),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_VPO),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_VMO),
+ IMX_PINCTRL_PIN(MX1_PAD_UART2_CTS),
+ IMX_PINCTRL_PIN(MX1_PAD_UART2_RTS),
+ IMX_PINCTRL_PIN(MX1_PAD_UART2_TXD),
+ IMX_PINCTRL_PIN(MX1_PAD_UART2_RXD),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_RXFS),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_RXCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_RXDAT),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_TXDAT),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_TXFS),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_TXCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_UART1_CTS),
+ IMX_PINCTRL_PIN(MX1_PAD_UART1_RTS),
+ IMX_PINCTRL_PIN(MX1_PAD_UART1_TXD),
+ IMX_PINCTRL_PIN(MX1_PAD_UART1_RXD),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_RDY),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_SCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_SS),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_MISO),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_MOSI),
+ IMX_PINCTRL_PIN(MX1_PAD_BT13),
+ IMX_PINCTRL_PIN(MX1_PAD_BT12),
+ IMX_PINCTRL_PIN(MX1_PAD_BT11),
+ IMX_PINCTRL_PIN(MX1_PAD_BT10),
+ IMX_PINCTRL_PIN(MX1_PAD_BT9),
+ IMX_PINCTRL_PIN(MX1_PAD_BT8),
+ IMX_PINCTRL_PIN(MX1_PAD_BT7),
+ IMX_PINCTRL_PIN(MX1_PAD_BT6),
+ IMX_PINCTRL_PIN(MX1_PAD_BT5),
+ IMX_PINCTRL_PIN(MX1_PAD_BT4),
+ IMX_PINCTRL_PIN(MX1_PAD_BT3),
+ IMX_PINCTRL_PIN(MX1_PAD_BT2),
+ IMX_PINCTRL_PIN(MX1_PAD_BT1),
+ IMX_PINCTRL_PIN(MX1_PAD_LSCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_REV),
+ IMX_PINCTRL_PIN(MX1_PAD_CLS),
+ IMX_PINCTRL_PIN(MX1_PAD_PS),
+ IMX_PINCTRL_PIN(MX1_PAD_SPL_SPR),
+ IMX_PINCTRL_PIN(MX1_PAD_CONTRAST),
+ IMX_PINCTRL_PIN(MX1_PAD_ACD_OE),
+ IMX_PINCTRL_PIN(MX1_PAD_LP_HSYNC),
+ IMX_PINCTRL_PIN(MX1_PAD_FLM_VSYNC),
+ IMX_PINCTRL_PIN(MX1_PAD_LD0),
+ IMX_PINCTRL_PIN(MX1_PAD_LD1),
+ IMX_PINCTRL_PIN(MX1_PAD_LD2),
+ IMX_PINCTRL_PIN(MX1_PAD_LD3),
+ IMX_PINCTRL_PIN(MX1_PAD_LD4),
+ IMX_PINCTRL_PIN(MX1_PAD_LD5),
+ IMX_PINCTRL_PIN(MX1_PAD_LD6),
+ IMX_PINCTRL_PIN(MX1_PAD_LD7),
+ IMX_PINCTRL_PIN(MX1_PAD_LD8),
+ IMX_PINCTRL_PIN(MX1_PAD_LD9),
+ IMX_PINCTRL_PIN(MX1_PAD_LD10),
+ IMX_PINCTRL_PIN(MX1_PAD_LD11),
+ IMX_PINCTRL_PIN(MX1_PAD_LD12),
+ IMX_PINCTRL_PIN(MX1_PAD_LD13),
+ IMX_PINCTRL_PIN(MX1_PAD_LD14),
+ IMX_PINCTRL_PIN(MX1_PAD_LD15),
+ IMX_PINCTRL_PIN(MX1_PAD_TMR2OUT),
+};
+
+static struct imx1_pinctrl_soc_info imx1_pinctrl_info = {
+ .pins = imx1_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx1_pinctrl_pads),
+};
+
+static int __init imx1_pinctrl_probe(struct platform_device *pdev)
+{
+ return imx1_pinctrl_core_probe(pdev, &imx1_pinctrl_info);
+}
+
+static const struct of_device_id imx1_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx1-iomuxc", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match);
+
+static struct platform_driver imx1_pinctrl_driver = {
+ .driver = {
+ .name = "imx1-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = imx1_pinctrl_of_match,
+ },
+ .remove = imx1_pinctrl_core_remove,
+};
+module_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe);
+
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Freescale i.MX1 pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/pinctrl-imx27.c b/drivers/pinctrl/pinctrl-imx27.c
index 417c99205bc2..f8dfefb69968 100644
--- a/drivers/pinctrl/pinctrl-imx27.c
+++ b/drivers/pinctrl/pinctrl-imx27.c
@@ -63,10 +63,6 @@ enum imx27_pads {
MX27_PAD_CONTRAST = PAD_ID(PA, 30),
MX27_PAD_OE_ACD = PAD_ID(PA, 31),
- MX27_PAD_UNUSED0 = PAD_ID(PB, 0),
- MX27_PAD_UNUSED1 = PAD_ID(PB, 1),
- MX27_PAD_UNUSED2 = PAD_ID(PB, 2),
- MX27_PAD_UNUSED3 = PAD_ID(PB, 3),
MX27_PAD_SD2_D0 = PAD_ID(PB, 4),
MX27_PAD_SD2_D1 = PAD_ID(PB, 5),
MX27_PAD_SD2_D2 = PAD_ID(PB, 6),
@@ -96,11 +92,6 @@ enum imx27_pads {
MX27_PAD_USBH1_RXDM = PAD_ID(PB, 30),
MX27_PAD_USBH1_RXDP = PAD_ID(PB, 31),
- MX27_PAD_UNUSED4 = PAD_ID(PC, 0),
- MX27_PAD_UNUSED5 = PAD_ID(PC, 1),
- MX27_PAD_UNUSED6 = PAD_ID(PC, 2),
- MX27_PAD_UNUSED7 = PAD_ID(PC, 3),
- MX27_PAD_UNUSED8 = PAD_ID(PC, 4),
MX27_PAD_I2C2_SDA = PAD_ID(PC, 5),
MX27_PAD_I2C2_SCL = PAD_ID(PC, 6),
MX27_PAD_USBOTG_DATA5 = PAD_ID(PC, 7),
@@ -188,12 +179,6 @@ enum imx27_pads {
MX27_PAD_SD1_CLK = PAD_ID(PE, 23),
MX27_PAD_USBOTG_CLK = PAD_ID(PE, 24),
MX27_PAD_USBOTG_DATA7 = PAD_ID(PE, 25),
- MX27_PAD_UNUSED9 = PAD_ID(PE, 26),
- MX27_PAD_UNUSED10 = PAD_ID(PE, 27),
- MX27_PAD_UNUSED11 = PAD_ID(PE, 28),
- MX27_PAD_UNUSED12 = PAD_ID(PE, 29),
- MX27_PAD_UNUSED13 = PAD_ID(PE, 30),
- MX27_PAD_UNUSED14 = PAD_ID(PE, 31),
MX27_PAD_NFRB = PAD_ID(PF, 0),
MX27_PAD_NFCLE = PAD_ID(PF, 1),
@@ -219,14 +204,6 @@ enum imx27_pads {
MX27_PAD_CS4_B = PAD_ID(PF, 21),
MX27_PAD_CS5_B = PAD_ID(PF, 22),
MX27_PAD_ATA_DATA15 = PAD_ID(PF, 23),
- MX27_PAD_UNUSED15 = PAD_ID(PF, 24),
- MX27_PAD_UNUSED16 = PAD_ID(PF, 25),
- MX27_PAD_UNUSED17 = PAD_ID(PF, 26),
- MX27_PAD_UNUSED18 = PAD_ID(PF, 27),
- MX27_PAD_UNUSED19 = PAD_ID(PF, 28),
- MX27_PAD_UNUSED20 = PAD_ID(PF, 29),
- MX27_PAD_UNUSED21 = PAD_ID(PF, 30),
- MX27_PAD_UNUSED22 = PAD_ID(PF, 31),
};
/* Pad names for the pinmux subsystem */
@@ -264,10 +241,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_CONTRAST),
IMX_PINCTRL_PIN(MX27_PAD_OE_ACD),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED0),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED1),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED2),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED3),
IMX_PINCTRL_PIN(MX27_PAD_SD2_D0),
IMX_PINCTRL_PIN(MX27_PAD_SD2_D1),
IMX_PINCTRL_PIN(MX27_PAD_SD2_D2),
@@ -297,11 +270,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDM),
IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDP),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED4),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED5),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED6),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED7),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED8),
IMX_PINCTRL_PIN(MX27_PAD_I2C2_SDA),
IMX_PINCTRL_PIN(MX27_PAD_I2C2_SCL),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA5),
@@ -389,12 +357,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_SD1_CLK),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_CLK),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA7),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED9),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED10),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED11),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED12),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED13),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED14),
IMX_PINCTRL_PIN(MX27_PAD_NFRB),
IMX_PINCTRL_PIN(MX27_PAD_NFCLE),
@@ -420,14 +382,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_CS4_B),
IMX_PINCTRL_PIN(MX27_PAD_CS5_B),
IMX_PINCTRL_PIN(MX27_PAD_ATA_DATA15),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED15),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED16),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED17),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED18),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED19),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED20),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED21),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED22),
};
static struct imx1_pinctrl_soc_info imx27_pinctrl_info = {
@@ -440,12 +394,6 @@ static struct of_device_id imx27_pinctrl_of_match[] = {
{ /* sentinel */ }
};
-struct imx27_pinctrl_private {
- int num_gpio_childs;
- struct platform_device **gpio_dev;
- struct mxc_gpio_platform_data *gpio_pdata;
-};
-
static int imx27_pinctrl_probe(struct platform_device *pdev)
{
return imx1_pinctrl_core_probe(pdev, &imx27_pinctrl_info);
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index bb805d5e9ff0..5e8b2e04cd7a 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -62,11 +62,26 @@ enum rockchip_pinctrl_type {
RK2928,
RK3066B,
RK3188,
+ RK3288,
};
-enum rockchip_pin_bank_type {
- COMMON_BANK,
- RK3188_BANK0,
+/**
+ * Encode variants of iomux registers into a type variable
+ */
+#define IOMUX_GPIO_ONLY BIT(0)
+#define IOMUX_WIDTH_4BIT BIT(1)
+#define IOMUX_SOURCE_PMU BIT(2)
+#define IOMUX_UNROUTED BIT(3)
+
+/**
+ * @type: iomux variant using IOMUX_* constants
+ * @offset: if initialized to -1 it will be autocalculated, by specifying
+ * an initial offset value the relevant source offset can be reset
+ * to a new value for autocalculating the following iomux registers.
+ */
+struct rockchip_iomux {
+ int type;
+ int offset;
};
/**
@@ -78,6 +93,7 @@ enum rockchip_pin_bank_type {
* @nr_pins: number of pins in this bank
* @name: name of the bank
* @bank_num: number of the bank, to account for holes
+ * @iomux: array describing the 4 iomux sources of the bank
* @valid: are all necessary informations present
* @of_node: dt node of this bank
* @drvdata: common pinctrl basedata
@@ -95,7 +111,7 @@ struct rockchip_pin_bank {
u8 nr_pins;
char *name;
u8 bank_num;
- enum rockchip_pin_bank_type bank_type;
+ struct rockchip_iomux iomux[4];
bool valid;
struct device_node *of_node;
struct rockchip_pinctrl *drvdata;
@@ -111,6 +127,25 @@ struct rockchip_pin_bank {
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
+ .iomux = { \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ }, \
+ }
+
+#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .iomux = { \
+ { .type = iom0, .offset = -1 }, \
+ { .type = iom1, .offset = -1 }, \
+ { .type = iom2, .offset = -1 }, \
+ { .type = iom3, .offset = -1 }, \
+ }, \
}
/**
@@ -121,7 +156,8 @@ struct rockchip_pin_ctrl {
u32 nr_pins;
char *label;
enum rockchip_pinctrl_type type;
- int mux_offset;
+ int grf_mux_offset;
+ int pmu_mux_offset;
void (*pull_calc_reg)(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit);
@@ -343,24 +379,42 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{
struct rockchip_pinctrl *info = bank->drvdata;
+ int iomux_num = (pin / 8);
+ struct regmap *regmap;
unsigned int val;
- int reg, ret;
+ int reg, ret, mask;
u8 bit;
- if (bank->bank_type == RK3188_BANK0 && pin < 16)
+ if (iomux_num > 3)
+ return -EINVAL;
+
+ if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
+ dev_err(info->dev, "pin %d is unrouted\n", pin);
+ return -EINVAL;
+ }
+
+ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
return RK_FUNC_GPIO;
+ regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+ ? info->regmap_pmu : info->regmap_base;
+
/* get basic quadrupel of mux registers and the correct reg inside */
- reg = info->ctrl->mux_offset;
- reg += bank->bank_num * 0x10;
- reg += (pin / 8) * 4;
- bit = (pin % 8) * 2;
+ mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
+ reg = bank->iomux[iomux_num].offset;
+ if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
+ if ((pin % 8) >= 4)
+ reg += 0x4;
+ bit = (pin % 4) * 4;
+ } else {
+ bit = (pin % 8) * 2;
+ }
- ret = regmap_read(info->regmap_base, reg, &val);
+ ret = regmap_read(regmap, reg, &val);
if (ret)
return ret;
- return ((val >> bit) & 3);
+ return ((val >> bit) & mask);
}
/*
@@ -379,16 +433,22 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{
struct rockchip_pinctrl *info = bank->drvdata;
- int reg, ret;
+ int iomux_num = (pin / 8);
+ struct regmap *regmap;
+ int reg, ret, mask;
unsigned long flags;
u8 bit;
u32 data;
- /*
- * The first 16 pins of rk3188_bank0 are always gpios and do not have
- * a mux register at all.
- */
- if (bank->bank_type == RK3188_BANK0 && pin < 16) {
+ if (iomux_num > 3)
+ return -EINVAL;
+
+ if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
+ dev_err(info->dev, "pin %d is unrouted\n", pin);
+ return -EINVAL;
+ }
+
+ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
if (mux != RK_FUNC_GPIO) {
dev_err(info->dev,
"pin %d only supports a gpio mux\n", pin);
@@ -401,17 +461,25 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
bank->bank_num, pin, mux);
+ regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+ ? info->regmap_pmu : info->regmap_base;
+
/* get basic quadrupel of mux registers and the correct reg inside */
- reg = info->ctrl->mux_offset;
- reg += bank->bank_num * 0x10;
- reg += (pin / 8) * 4;
- bit = (pin % 8) * 2;
+ mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
+ reg = bank->iomux[iomux_num].offset;
+ if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
+ if ((pin % 8) >= 4)
+ reg += 0x4;
+ bit = (pin % 4) * 4;
+ } else {
+ bit = (pin % 8) * 2;
+ }
spin_lock_irqsave(&bank->slock, flags);
- data = (3 << (bit + 16));
- data |= (mux & 3) << bit;
- ret = regmap_write(info->regmap_base, reg, data);
+ data = (mask << (bit + 16));
+ data |= (mux & mask) << bit;
+ ret = regmap_write(regmap, reg, data);
spin_unlock_irqrestore(&bank->slock, flags);
@@ -449,7 +517,7 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
struct rockchip_pinctrl *info = bank->drvdata;
/* The first 12 pins of the first bank are located elsewhere */
- if (bank->bank_type == RK3188_BANK0 && pin_num < 12) {
+ if (bank->bank_num == 0 && pin_num < 12) {
*regmap = info->regmap_pmu ? info->regmap_pmu
: bank->regmap_pull;
*reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0;
@@ -476,6 +544,127 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
}
}
+#define RK3288_PULL_OFFSET 0x140
+static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+ /* The first 24 pins of the first bank are located in PMU */
+ if (bank->bank_num == 0) {
+ *regmap = info->regmap_pmu;
+ *reg = RK3188_PULL_PMU_OFFSET;
+
+ *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+ *bit = pin_num % RK3188_PULL_PINS_PER_REG;
+ *bit *= RK3188_PULL_BITS_PER_PIN;
+ } else {
+ *regmap = info->regmap_base;
+ *reg = RK3288_PULL_OFFSET;
+
+ /* correct the offset, as we're starting with the 2nd bank */
+ *reg -= 0x10;
+ *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
+ *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+
+ *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+ *bit *= RK3188_PULL_BITS_PER_PIN;
+ }
+}
+
+#define RK3288_DRV_PMU_OFFSET 0x70
+#define RK3288_DRV_GRF_OFFSET 0x1c0
+#define RK3288_DRV_BITS_PER_PIN 2
+#define RK3288_DRV_PINS_PER_REG 8
+#define RK3288_DRV_BANK_STRIDE 16
+static int rk3288_drv_list[] = { 2, 4, 8, 12 };
+
+static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+ /* The first 24 pins of the first bank are located in PMU */
+ if (bank->bank_num == 0) {
+ *regmap = info->regmap_pmu;
+ *reg = RK3288_DRV_PMU_OFFSET;
+
+ *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
+ *bit = pin_num % RK3288_DRV_PINS_PER_REG;
+ *bit *= RK3288_DRV_BITS_PER_PIN;
+ } else {
+ *regmap = info->regmap_base;
+ *reg = RK3288_DRV_GRF_OFFSET;
+
+ /* correct the offset, as we're starting with the 2nd bank */
+ *reg -= 0x10;
+ *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
+ *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
+
+ *bit = (pin_num % RK3288_DRV_PINS_PER_REG);
+ *bit *= RK3288_DRV_BITS_PER_PIN;
+ }
+}
+
+static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num)
+{
+ struct regmap *regmap;
+ int reg, ret;
+ u32 data;
+ u8 bit;
+
+ rk3288_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+ ret = regmap_read(regmap, reg, &data);
+ if (ret)
+ return ret;
+
+ data >>= bit;
+ data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1;
+
+ return rk3288_drv_list[data];
+}
+
+static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num,
+ int strength)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct regmap *regmap;
+ unsigned long flags;
+ int reg, ret, i;
+ u32 data;
+ u8 bit;
+
+ rk3288_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+ ret = -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(rk3288_drv_list); i++) {
+ if (rk3288_drv_list[i] == strength) {
+ ret = i;
+ break;
+ }
+ }
+
+ if (ret < 0) {
+ dev_err(info->dev, "unsupported driver strength %d\n",
+ strength);
+ return ret;
+ }
+
+ spin_lock_irqsave(&bank->slock, flags);
+
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16);
+ data |= (ret << bit);
+
+ ret = regmap_write(regmap, reg, data);
+ spin_unlock_irqrestore(&bank->slock, flags);
+
+ return ret;
+}
+
static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
{
struct rockchip_pinctrl *info = bank->drvdata;
@@ -501,6 +690,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
: PIN_CONFIG_BIAS_DISABLE;
case RK3188:
+ case RK3288:
data >>= bit;
data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
@@ -555,6 +745,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
spin_unlock_irqrestore(&bank->slock, flags);
break;
case RK3188:
+ case RK3288:
spin_lock_irqsave(&bank->slock, flags);
/* enable the write to the equivalent lower bits */
@@ -657,23 +848,6 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
-static void rockchip_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned selector, unsigned group)
-{
- struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- const unsigned int *pins = info->groups[group].pins;
- struct rockchip_pin_bank *bank;
- int cnt;
-
- dev_dbg(info->dev, "disable function %s group %s\n",
- info->functions[selector].name, info->groups[group].name);
-
- for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
- bank = pin_to_bank(info, pins[cnt]);
- rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
- }
-}
-
/*
* The calls to gpio_direction_output() and gpio_direction_input()
* leads to this function call (via the pinctrl_gpio_direction_{input|output}()
@@ -716,7 +890,6 @@ static const struct pinmux_ops rockchip_pmx_ops = {
.get_function_name = rockchip_pmx_get_func_name,
.get_function_groups = rockchip_pmx_get_groups,
.enable = rockchip_pmx_enable,
- .disable = rockchip_pmx_disable,
.gpio_set_direction = rockchip_pmx_gpio_set_direction,
};
@@ -734,6 +907,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
case RK3066B:
return pull ? false : true;
case RK3188:
+ case RK3288:
return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
}
@@ -788,6 +962,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
if (rc)
return rc;
break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ /* rk3288 is the first with per-pin drive-strength */
+ if (info->ctrl->type != RK3288)
+ return -ENOTSUPP;
+
+ rc = rk3288_set_drive(bank, pin - bank->pin_base, arg);
+ if (rc < 0)
+ return rc;
+ break;
default:
return -ENOTSUPP;
break;
@@ -837,6 +1020,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
arg = rc ? 1 : 0;
break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ /* rk3288 is the first with per-pin drive-strength */
+ if (info->ctrl->type != RK3288)
+ return -ENOTSUPP;
+
+ rc = rk3288_get_drive(bank, pin - bank->pin_base);
+ if (rc < 0)
+ return rc;
+
+ arg = rc;
+ break;
default:
return -ENOTSUPP;
break;
@@ -850,6 +1044,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
static const struct pinconf_ops rockchip_pinconf_ops = {
.pin_config_get = rockchip_pinconf_get,
.pin_config_set = rockchip_pinconf_set,
+ .is_generic = true,
};
static const struct of_device_id rockchip_bank_match[] = {
@@ -1414,10 +1609,7 @@ fail:
for (--i, --bank; i >= 0; --i, --bank) {
if (!bank->valid)
continue;
-
- if (gpiochip_remove(&bank->gpio_chip))
- dev_err(&pdev->dev, "gpio chip %s remove failed\n",
- bank->gpio_chip.label);
+ gpiochip_remove(&bank->gpio_chip);
}
return ret;
}
@@ -1427,20 +1619,15 @@ static int rockchip_gpiolib_unregister(struct platform_device *pdev,
{
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct rockchip_pin_bank *bank = ctrl->pin_banks;
- int ret = 0;
int i;
- for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) {
+ for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
if (!bank->valid)
continue;
-
- ret = gpiochip_remove(&bank->gpio_chip);
+ gpiochip_remove(&bank->gpio_chip);
}
- if (ret)
- dev_err(&pdev->dev, "gpio chip remove failed\n");
-
- return ret;
+ return 0;
}
static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
@@ -1466,8 +1653,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
"rockchip,rk3188-gpio-bank0")) {
struct device_node *node;
- bank->bank_type = RK3188_BANK0;
-
node = of_parse_phandle(bank->of_node->parent,
"rockchip,pmu", 0);
if (!node) {
@@ -1487,9 +1672,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
base,
&rockchip_regmap_config);
}
-
- } else {
- bank->bank_type = COMMON_BANK;
}
bank->irq = irq_of_parse_and_map(bank->of_node, 0);
@@ -1513,7 +1695,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
struct device_node *np;
struct rockchip_pin_ctrl *ctrl;
struct rockchip_pin_bank *bank;
- int i;
+ int grf_offs, pmu_offs, i, j;
match = of_match_node(rockchip_pinctrl_dt_match, node);
ctrl = (struct rockchip_pin_ctrl *)match->data;
@@ -1535,12 +1717,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
}
}
+ grf_offs = ctrl->grf_mux_offset;
+ pmu_offs = ctrl->pmu_mux_offset;
bank = ctrl->pin_banks;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+ int bank_pins = 0;
+
spin_lock_init(&bank->slock);
bank->drvdata = d;
bank->pin_base = ctrl->nr_pins;
ctrl->nr_pins += bank->nr_pins;
+
+ /* calculate iomux offsets */
+ for (j = 0; j < 4; j++) {
+ struct rockchip_iomux *iom = &bank->iomux[j];
+ int inc;
+
+ if (bank_pins >= bank->nr_pins)
+ break;
+
+ /* preset offset value, set new start value */
+ if (iom->offset >= 0) {
+ if (iom->type & IOMUX_SOURCE_PMU)
+ pmu_offs = iom->offset;
+ else
+ grf_offs = iom->offset;
+ } else { /* set current offset */
+ iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
+ pmu_offs : grf_offs;
+ }
+
+ dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n",
+ i, j, iom->offset);
+
+ /*
+ * Increase offset according to iomux width.
+ * 4bit iomux'es are spread over two registers.
+ */
+ inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4;
+ if (iom->type & IOMUX_SOURCE_PMU)
+ pmu_offs += inc;
+ else
+ grf_offs += inc;
+
+ bank_pins += 8;
+ }
}
return ctrl;
@@ -1644,7 +1865,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk2928_pin_banks),
.label = "RK2928-GPIO",
.type = RK2928,
- .mux_offset = 0xa8,
+ .grf_mux_offset = 0xa8,
.pull_calc_reg = rk2928_calc_pull_reg_and_bit,
};
@@ -1662,7 +1883,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3066a_pin_banks),
.label = "RK3066a-GPIO",
.type = RK2928,
- .mux_offset = 0xa8,
+ .grf_mux_offset = 0xa8,
.pull_calc_reg = rk2928_calc_pull_reg_and_bit,
};
@@ -1678,11 +1899,11 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3066b_pin_banks),
.label = "RK3066b-GPIO",
.type = RK3066B,
- .mux_offset = 0x60,
+ .grf_mux_offset = 0x60,
};
static struct rockchip_pin_bank rk3188_pin_banks[] = {
- PIN_BANK(0, 32, "gpio0"),
+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
PIN_BANK(1, 32, "gpio1"),
PIN_BANK(2, 32, "gpio2"),
PIN_BANK(3, 32, "gpio3"),
@@ -1693,10 +1914,52 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3188_pin_banks),
.label = "RK3188-GPIO",
.type = RK3188,
- .mux_offset = 0x60,
+ .grf_mux_offset = 0x60,
.pull_calc_reg = rk3188_calc_pull_reg_and_bit,
};
+static struct rockchip_pin_bank rk3288_pin_banks[] = {
+ PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
+ IOMUX_SOURCE_PMU,
+ IOMUX_SOURCE_PMU,
+ IOMUX_UNROUTED
+ ),
+ PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
+ IOMUX_UNROUTED,
+ IOMUX_UNROUTED,
+ 0
+ ),
+ PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
+ PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
+ PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0,
+ 0
+ ),
+ PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
+ 0,
+ 0,
+ IOMUX_UNROUTED
+ ),
+ PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
+ PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
+ 0,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_UNROUTED
+ ),
+ PIN_BANK(8, 16, "gpio8"),
+};
+
+static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
+ .pin_banks = rk3288_pin_banks,
+ .nr_banks = ARRAY_SIZE(rk3288_pin_banks),
+ .label = "RK3288-GPIO",
+ .type = RK3288,
+ .grf_mux_offset = 0x0,
+ .pmu_mux_offset = 0x84,
+ .pull_calc_reg = rk3288_calc_pull_reg_and_bit,
+};
+
static const struct of_device_id rockchip_pinctrl_dt_match[] = {
{ .compatible = "rockchip,rk2928-pinctrl",
.data = (void *)&rk2928_pin_ctrl },
@@ -1706,6 +1969,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
.data = (void *)&rk3066b_pin_ctrl },
{ .compatible = "rockchip,rk3188-pinctrl",
.data = (void *)&rk3188_pin_ctrl },
+ { .compatible = "rockchip,rk3288-pinctrl",
+ .data = (void *)&rk3288_pin_ctrl },
{},
};
MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 2960557bfed9..95dd9cf55cb3 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -488,61 +488,6 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
return 0;
}
-static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
- unsigned group)
-{
- struct pcs_device *pcs;
- struct pcs_function *func;
- int i;
-
- pcs = pinctrl_dev_get_drvdata(pctldev);
- /* If function mask is null, needn't disable it. */
- if (!pcs->fmask)
- return;
-
- func = radix_tree_lookup(&pcs->ftree, fselector);
- if (!func) {
- dev_err(pcs->dev, "%s could not find function%i\n",
- __func__, fselector);
- return;
- }
-
- /*
- * Ignore disable if function-off is not specified. Some hardware
- * does not have clearly defined disable function. For pin specific
- * off modes, you can use alternate named states as described in
- * pinctrl-bindings.txt.
- */
- if (pcs->foff == PCS_OFF_DISABLED) {
- dev_dbg(pcs->dev, "ignoring disable for %s function%i\n",
- func->name, fselector);
- return;
- }
-
- dev_dbg(pcs->dev, "disabling function%i %s\n",
- fselector, func->name);
-
- for (i = 0; i < func->nvals; i++) {
- struct pcs_func_vals *vals;
- unsigned long flags;
- unsigned val, mask;
-
- vals = &func->vals[i];
- raw_spin_lock_irqsave(&pcs->lock, flags);
- val = pcs->read(vals->reg);
-
- if (pcs->bits_per_mux)
- mask = vals->mask;
- else
- mask = pcs->fmask;
-
- val &= ~mask;
- val |= pcs->foff << pcs->fshift;
- pcs->write(val, vals->reg);
- raw_spin_unlock_irqrestore(&pcs->lock, flags);
- }
-}
-
static int pcs_request_gpio(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned pin)
{
@@ -575,7 +520,6 @@ static const struct pinmux_ops pcs_pinmux_ops = {
.get_function_name = pcs_get_function_name,
.get_function_groups = pcs_get_function_groups,
.enable = pcs_enable,
- .disable = pcs_disable,
.gpio_request_enable = pcs_request_gpio,
};
@@ -836,7 +780,7 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
pin = &pcs->pins.pa[i];
pn = &pcs->names[i];
- sprintf(pn->name, "%lx.%d",
+ sprintf(pn->name, "%lx.%u",
(unsigned long)pcs->res->start + offset, pin_pos);
pin->name = pn->name;
pin->number = i;
@@ -1739,11 +1683,10 @@ static void pcs_irq_chain_handler(unsigned int irq, struct irq_desc *desc)
{
struct pcs_soc_data *pcs_soc = irq_desc_get_handler_data(desc);
struct irq_chip *chip;
- int res;
chip = irq_get_chip(irq);
chained_irq_enter(chip, desc);
- res = pcs_irq_handle(pcs_soc);
+ pcs_irq_handle(pcs_soc);
/* REVISIT: export and add handle_bad_irq(irq, desc)? */
chained_irq_exit(chip, desc);
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
index 9f43916637ca..5475374d803f 100644
--- a/drivers/pinctrl/pinctrl-st.c
+++ b/drivers/pinctrl/pinctrl-st.c
@@ -930,11 +930,6 @@ static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector,
return 0;
}
-static void st_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
-}
-
static int st_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned gpio,
bool input)
@@ -957,7 +952,6 @@ static struct pinmux_ops st_pmxops = {
.get_function_name = st_pmx_get_fname,
.get_function_groups = st_pmx_get_groups,
.enable = st_pmx_enable,
- .disable = st_pmx_disable,
.gpio_set_direction = st_pmx_set_gpio_direction,
};
@@ -1178,9 +1172,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
const __be32 *list;
struct property *pp;
struct st_pinconf *conf;
- phandle phandle;
struct device_node *pins;
- u32 pin;
int i = 0, npins = 0, nr_props;
pins = of_get_child_by_name(np, "st,pins");
@@ -1218,8 +1210,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
conf = &grp->pin_conf[i];
/* bank & offset */
- phandle = be32_to_cpup(list++);
- pin = be32_to_cpup(list++);
+ be32_to_cpup(list++);
+ be32_to_cpup(list++);
conf->pin = of_get_named_gpio(pins, pp->name, 0);
conf->name = pp->name;
grp->pins[i] = conf->pin;
@@ -1256,7 +1248,7 @@ static int st_pctl_parse_functions(struct device_node *np,
func = &info->functions[index];
func->name = np->name;
func->ngroups = of_get_child_count(np);
- if (func->ngroups <= 0) {
+ if (func->ngroups == 0) {
dev_err(info->dev, "No groups defined\n");
return -EINVAL;
}
@@ -1454,6 +1446,7 @@ static struct irq_chip st_gpio_irqchip = {
.irq_mask = st_gpio_irq_mask,
.irq_unmask = st_gpio_irq_unmask,
.irq_set_type = st_gpio_irq_set_type,
+ .flags = IRQCHIP_SKIP_SET_WAKE,
};
static int st_gpiolib_register_bank(struct st_pinctrl *info,
diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c
index 26ca6855f478..71c5d4f0c538 100644
--- a/drivers/pinctrl/pinctrl-tb10x.c
+++ b/drivers/pinctrl/pinctrl-tb10x.c
@@ -738,22 +738,6 @@ static int tb10x_pctl_enable(struct pinctrl_dev *pctl,
return 0;
}
-static void tb10x_pctl_disable(struct pinctrl_dev *pctl,
- unsigned func_selector, unsigned group_selector)
-{
- struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
- const struct tb10x_pinfuncgrp *grp = &state->pingroups[group_selector];
-
- if (grp->port < 0)
- return;
-
- mutex_lock(&state->mutex);
-
- state->ports[grp->port].count--;
-
- mutex_unlock(&state->mutex);
-}
-
static struct pinmux_ops tb10x_pinmux_ops = {
.get_functions_count = tb10x_get_functions_count,
.get_function_name = tb10x_get_function_name,
@@ -761,7 +745,6 @@ static struct pinmux_ops tb10x_pinmux_ops = {
.gpio_request_enable = tb10x_gpio_request_enable,
.gpio_disable_free = tb10x_gpio_disable_free,
.enable = tb10x_pctl_enable,
- .disable = tb10x_pctl_disable,
};
static struct pinctrl_desc tb10x_pindesc = {
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index 2d43bff74f59..150af5503c09 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -290,24 +290,11 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
return 0;
}
-static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
- unsigned function, unsigned group)
-{
- struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
- const struct tegra_pingroup *g;
-
- g = &pmx->soc->groups[group];
-
- if (WARN_ON(g->mux_reg < 0))
- return;
-}
-
static const struct pinmux_ops tegra_pinmux_ops = {
.get_functions_count = tegra_pinctrl_get_funcs_count,
.get_function_name = tegra_pinctrl_get_func_name,
.get_function_groups = tegra_pinctrl_get_func_groups,
.enable = tegra_pinctrl_enable,
- .disable = tegra_pinctrl_disable,
};
static int tegra_pinconf_reg(struct tegra_pmx *pmx,
diff --git a/drivers/pinctrl/pinctrl-tz1090-pdc.c b/drivers/pinctrl/pinctrl-tz1090-pdc.c
index 5bf01c28925e..41e81a35cabb 100644
--- a/drivers/pinctrl/pinctrl-tz1090-pdc.c
+++ b/drivers/pinctrl/pinctrl-tz1090-pdc.c
@@ -574,33 +574,6 @@ static int tz1090_pdc_pinctrl_enable(struct pinctrl_dev *pctldev,
return 0;
}
-static void tz1090_pdc_pinctrl_disable(struct pinctrl_dev *pctldev,
- unsigned int function,
- unsigned int group)
-{
- struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
- const struct tz1090_pdc_pingroup *grp = &tz1090_pdc_groups[group];
-
- dev_dbg(pctldev->dev, "%s(func=%u (%s), group=%u (%s))\n",
- __func__,
- function, tz1090_pdc_functions[function].name,
- group, tz1090_pdc_groups[group].name);
-
- /* is it even a mux? */
- if (grp->drv)
- return;
-
- /* does this group even control the function? */
- if (function != grp->func)
- return;
-
- /* record the pin being unmuxed and update mux bit */
- spin_lock(&pmx->lock);
- pmx->mux_en &= ~BIT(grp->pins[0]);
- tz1090_pdc_pinctrl_mux(pmx, grp);
- spin_unlock(&pmx->lock);
-}
-
static const struct tz1090_pdc_pingroup *find_mux_group(
struct tz1090_pdc_pmx *pmx,
unsigned int pin)
@@ -662,7 +635,6 @@ static struct pinmux_ops tz1090_pdc_pinmux_ops = {
.get_function_name = tz1090_pdc_pinctrl_get_func_name,
.get_function_groups = tz1090_pdc_pinctrl_get_func_groups,
.enable = tz1090_pdc_pinctrl_enable,
- .disable = tz1090_pdc_pinctrl_disable,
.gpio_request_enable = tz1090_pdc_pinctrl_gpio_request_enable,
.gpio_disable_free = tz1090_pdc_pinctrl_gpio_disable_free,
};
diff --git a/drivers/pinctrl/pinctrl-tz1090.c b/drivers/pinctrl/pinctrl-tz1090.c
index bc9cd7a7602e..24082216842e 100644
--- a/drivers/pinctrl/pinctrl-tz1090.c
+++ b/drivers/pinctrl/pinctrl-tz1090.c
@@ -1479,63 +1479,6 @@ mux_pins:
}
/**
- * tz1090_pinctrl_disable() - Disable a function on a pin group.
- * @pctldev: Pin control data
- * @function: Function index to disable
- * @group: Group index to disable
- *
- * Disable a particular function on a group of pins. The per GPIO pin pseudo pin
- * groups can be used (in which case the pin will be taken out of peripheral
- * mode. Some convenience pin groups can also be used in which case the effect
- * is the same as enabling the function on each individual pin in the group.
- */
-static void tz1090_pinctrl_disable(struct pinctrl_dev *pctldev,
- unsigned int function, unsigned int group)
-{
- struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
- struct tz1090_pingroup *grp;
- unsigned int pin_num, mux_group, i, npins;
- const unsigned int *pins;
-
- /* group of pins? */
- if (group < ARRAY_SIZE(tz1090_groups)) {
- grp = &tz1090_groups[group];
- npins = grp->npins;
- pins = grp->pins;
- /*
- * All pins in the group must belong to the same mux group,
- * which allows us to just use the mux group of the first pin.
- * By explicitly listing permitted pingroups for each function
- * the pinmux core should ensure this is always the case.
- */
- } else {
- pin_num = group - ARRAY_SIZE(tz1090_groups);
- npins = 1;
- pins = &pin_num;
- }
- mux_group = tz1090_mux_pins[*pins];
-
- /* no mux group, but can still be individually muxed to peripheral */
- if (mux_group >= TZ1090_MUX_GROUP_MAX) {
- if (function == TZ1090_MUX_PERIP)
- goto unmux_pins;
- return;
- }
-
- /* mux group already set to a different function? */
- grp = &tz1090_mux_groups[mux_group];
- dev_dbg(pctldev->dev, "%s: unmuxing %u pin(s) in '%s' from '%s'\n",
- __func__, npins, grp->name, tz1090_functions[function].name);
-
- /* subtract pins from ref count and unmux individually */
- WARN_ON(grp->func_count < npins);
- grp->func_count -= npins;
-unmux_pins:
- for (i = 0; i < npins; ++i)
- tz1090_pinctrl_perip_select(pmx, pins[i], false);
-}
-
-/**
* tz1090_pinctrl_gpio_request_enable() - Put pin in GPIO mode.
* @pctldev: Pin control data
* @range: GPIO range
@@ -1575,7 +1518,6 @@ static struct pinmux_ops tz1090_pinmux_ops = {
.get_function_name = tz1090_pinctrl_get_func_name,
.get_function_groups = tz1090_pinctrl_get_func_groups,
.enable = tz1090_pinctrl_enable,
- .disable = tz1090_pinctrl_disable,
.gpio_request_enable = tz1090_pinctrl_gpio_request_enable,
.gpio_disable_free = tz1090_pinctrl_gpio_disable_free,
};
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c
index 209a01b8bd3b..0959bb36450f 100644
--- a/drivers/pinctrl/pinctrl-u300.c
+++ b/drivers/pinctrl/pinctrl-u300.c
@@ -970,19 +970,6 @@ static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
-static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- struct u300_pmx *upmx;
-
- /* There is nothing to do with the power pins */
- if (selector == 0)
- return;
-
- upmx = pinctrl_dev_get_drvdata(pctldev);
- u300_pmx_endisable(upmx, selector, false);
-}
-
static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(u300_pmx_functions);
@@ -1008,7 +995,6 @@ static const struct pinmux_ops u300_pmx_ops = {
.get_function_name = u300_pmx_get_func_name,
.get_function_groups = u300_pmx_get_groups,
.enable = u300_pmx_enable,
- .disable = u300_pmx_disable,
};
static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 051e8592990e..c055daf9a80f 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -471,7 +471,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
{
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
- const struct pinmux_ops *ops = pctldev->desc->pmxops;
int ret = 0;
const unsigned *pins = NULL;
unsigned num_pins = 0;
@@ -518,9 +517,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
pins[i], desc->name, gname);
}
}
-
- if (ops->disable)
- ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
}
#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
new file mode 100644
index 000000000000..d160a710d704
--- /dev/null
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -0,0 +1,42 @@
+if (ARCH_QCOM || COMPILE_TEST)
+
+config PINCTRL_MSM
+ bool
+ select PINMUX
+ select PINCONF
+ select GENERIC_PINCONF
+ select GPIOLIB_IRQCHIP
+
+config PINCTRL_APQ8064
+ tristate "Qualcomm APQ8064 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
+
+config PINCTRL_IPQ8064
+ tristate "Qualcomm IPQ8064 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
+
+config PINCTRL_MSM8960
+ tristate "Qualcomm 8960 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm TLMM block found in the Qualcomm 8960 platform.
+
+config PINCTRL_MSM8X74
+ tristate "Qualcomm 8x74 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm TLMM block found in the Qualcomm 8974 platform.
+
+endif
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
new file mode 100644
index 000000000000..2a02602d715c
--- /dev/null
+++ b/drivers/pinctrl/qcom/Makefile
@@ -0,0 +1,6 @@
+# Qualcomm pin control drivers
+obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
+obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o
+obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
+obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o
+obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
diff --git a/drivers/pinctrl/pinctrl-apq8064.c b/drivers/pinctrl/qcom/pinctrl-apq8064.c
index 519f7886b0f1..feb6f152f9b7 100644
--- a/drivers/pinctrl/pinctrl-apq8064.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8064.c
@@ -230,7 +230,7 @@ static const unsigned int sdc3_data_pins[] = { 95 };
.pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \
- APQ_MUX_NA, /* gpio mode */ \
+ APQ_MUX_gpio, \
APQ_MUX_##f1, \
APQ_MUX_##f2, \
APQ_MUX_##f3, \
@@ -293,6 +293,7 @@ enum apq8064_functions {
APQ_MUX_cam_mclk,
APQ_MUX_codec_mic_i2s,
APQ_MUX_codec_spkr_i2s,
+ APQ_MUX_gpio,
APQ_MUX_gsbi1,
APQ_MUX_gsbi2,
APQ_MUX_gsbi3,
@@ -335,6 +336,21 @@ static const char * const codec_mic_i2s_groups[] = {
static const char * const codec_spkr_i2s_groups[] = {
"gpio39", "gpio40", "gpio41", "gpio42"
};
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89"
+};
static const char * const gsbi1_groups[] = {
"gpio18", "gpio19", "gpio20", "gpio21"
};
@@ -430,6 +446,7 @@ static const struct msm_function apq8064_functions[] = {
FUNCTION(cam_mclk),
FUNCTION(codec_mic_i2s),
FUNCTION(codec_spkr_i2s),
+ FUNCTION(gpio),
FUNCTION(gsbi1),
FUNCTION(gsbi2),
FUNCTION(gsbi3),
diff --git a/drivers/pinctrl/pinctrl-ipq8064.c b/drivers/pinctrl/qcom/pinctrl-ipq8064.c
index acafea4c3a33..767cf1120b20 100644
--- a/drivers/pinctrl/pinctrl-ipq8064.c
+++ b/drivers/pinctrl/qcom/pinctrl-ipq8064.c
@@ -183,7 +183,7 @@ static const unsigned int sdc3_data_pins[] = { 71 };
.pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \
- IPQ_MUX_NA, /* gpio mode */ \
+ IPQ_MUX_gpio, \
IPQ_MUX_##f1, \
IPQ_MUX_##f2, \
IPQ_MUX_##f3, \
@@ -243,6 +243,7 @@ static const unsigned int sdc3_data_pins[] = { 71 };
}
enum ipq8064_functions {
+ IPQ_MUX_gpio,
IPQ_MUX_mdio,
IPQ_MUX_mi2s,
IPQ_MUX_pdm,
@@ -291,6 +292,19 @@ enum ipq8064_functions {
IPQ_MUX_NA,
};
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
+};
+
static const char * const mdio_groups[] = {
"gpio0", "gpio1", "gpio10", "gpio11",
};
@@ -481,6 +495,7 @@ static const char * const ps_hold_groups[] = {
};
static const struct msm_function ipq8064_functions[] = {
+ FUNCTION(gpio),
FUNCTION(mdio),
FUNCTION(ssbi),
FUNCTION(spmi),
diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index df6dda4ce803..2738108caff2 100644
--- a/drivers/pinctrl/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -27,10 +27,10 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
-#include "core.h"
-#include "pinconf.h"
+#include "../core.h"
+#include "../pinconf.h"
#include "pinctrl-msm.h"
-#include "pinctrl-utils.h"
+#include "../pinctrl-utils.h"
#define MAX_NR_GPIO 300
@@ -142,9 +142,6 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
g = &pctrl->soc->groups[group];
- if (WARN_ON(g->mux_bit < 0))
- return -EINVAL;
-
for (i = 0; i < g->nfuncs; i++) {
if (g->funcs[i] == function)
break;
@@ -165,36 +162,11 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
return 0;
}
-static void msm_pinmux_disable(struct pinctrl_dev *pctldev,
- unsigned function,
- unsigned group)
-{
- struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
- const struct msm_pingroup *g;
- unsigned long flags;
- u32 val;
-
- g = &pctrl->soc->groups[group];
-
- if (WARN_ON(g->mux_bit < 0))
- return;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
- /* Clear the mux bits to select gpio mode */
- val = readl(pctrl->regs + g->ctl_reg);
- val &= ~(0x7 << g->mux_bit);
- writel(val, pctrl->regs + g->ctl_reg);
-
- spin_unlock_irqrestore(&pctrl->lock, flags);
-}
-
static const struct pinmux_ops msm_pinmux_ops = {
.get_functions_count = msm_get_functions_count,
.get_function_name = msm_get_function_name,
.get_function_groups = msm_get_function_groups,
.enable = msm_pinmux_enable,
- .disable = msm_pinmux_disable,
};
static int msm_config_reg(struct msm_pinctrl *pctrl,
@@ -206,6 +178,7 @@ static int msm_config_reg(struct msm_pinctrl *pctrl,
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_BUS_HOLD:
case PIN_CONFIG_BIAS_PULL_UP:
*bit = g->pull_bit;
*mask = 3;
@@ -243,6 +216,7 @@ static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
#define MSM_NO_PULL 0
#define MSM_PULL_DOWN 1
+#define MSM_KEEPER 2
#define MSM_PULL_UP 3
static unsigned msm_regval_to_drive(u32 val)
@@ -280,6 +254,9 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = arg == MSM_PULL_DOWN;
break;
+ case PIN_CONFIG_BIAS_BUS_HOLD:
+ arg = arg == MSM_KEEPER;
+ break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = arg == MSM_PULL_UP;
break;
@@ -339,6 +316,9 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = MSM_PULL_DOWN;
break;
+ case PIN_CONFIG_BIAS_BUS_HOLD:
+ arg = MSM_KEEPER;
+ break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = MSM_PULL_UP;
break;
diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h
index 7b2a227a590a..7b2a227a590a 100644
--- a/drivers/pinctrl/pinctrl-msm.h
+++ b/drivers/pinctrl/qcom/pinctrl-msm.h
diff --git a/drivers/pinctrl/qcom/pinctrl-msm8960.c b/drivers/pinctrl/qcom/pinctrl-msm8960.c
new file mode 100644
index 000000000000..35047036a053
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-msm8960.c
@@ -0,0 +1,1282 @@
+/*
+ * Copyright (c) 2014, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-msm.h"
+
+static const struct pinctrl_pin_desc msm8960_pins[] = {
+ PINCTRL_PIN(0, "GPIO_0"),
+ PINCTRL_PIN(1, "GPIO_1"),
+ PINCTRL_PIN(2, "GPIO_2"),
+ PINCTRL_PIN(3, "GPIO_3"),
+ PINCTRL_PIN(4, "GPIO_4"),
+ PINCTRL_PIN(5, "GPIO_5"),
+ PINCTRL_PIN(6, "GPIO_6"),
+ PINCTRL_PIN(7, "GPIO_7"),
+ PINCTRL_PIN(8, "GPIO_8"),
+ PINCTRL_PIN(9, "GPIO_9"),
+ PINCTRL_PIN(10, "GPIO_10"),
+ PINCTRL_PIN(11, "GPIO_11"),
+ PINCTRL_PIN(12, "GPIO_12"),
+ PINCTRL_PIN(13, "GPIO_13"),
+ PINCTRL_PIN(14, "GPIO_14"),
+ PINCTRL_PIN(15, "GPIO_15"),
+ PINCTRL_PIN(16, "GPIO_16"),
+ PINCTRL_PIN(17, "GPIO_17"),
+ PINCTRL_PIN(18, "GPIO_18"),
+ PINCTRL_PIN(19, "GPIO_19"),
+ PINCTRL_PIN(20, "GPIO_20"),
+ PINCTRL_PIN(21, "GPIO_21"),
+ PINCTRL_PIN(22, "GPIO_22"),
+ PINCTRL_PIN(23, "GPIO_23"),
+ PINCTRL_PIN(24, "GPIO_24"),
+ PINCTRL_PIN(25, "GPIO_25"),
+ PINCTRL_PIN(26, "GPIO_26"),
+ PINCTRL_PIN(27, "GPIO_27"),
+ PINCTRL_PIN(28, "GPIO_28"),
+ PINCTRL_PIN(29, "GPIO_29"),
+ PINCTRL_PIN(30, "GPIO_30"),
+ PINCTRL_PIN(31, "GPIO_31"),
+ PINCTRL_PIN(32, "GPIO_32"),
+ PINCTRL_PIN(33, "GPIO_33"),
+ PINCTRL_PIN(34, "GPIO_34"),
+ PINCTRL_PIN(35, "GPIO_35"),
+ PINCTRL_PIN(36, "GPIO_36"),
+ PINCTRL_PIN(37, "GPIO_37"),
+ PINCTRL_PIN(38, "GPIO_38"),
+ PINCTRL_PIN(39, "GPIO_39"),
+ PINCTRL_PIN(40, "GPIO_40"),
+ PINCTRL_PIN(41, "GPIO_41"),
+ PINCTRL_PIN(42, "GPIO_42"),
+ PINCTRL_PIN(43, "GPIO_43"),
+ PINCTRL_PIN(44, "GPIO_44"),
+ PINCTRL_PIN(45, "GPIO_45"),
+ PINCTRL_PIN(46, "GPIO_46"),
+ PINCTRL_PIN(47, "GPIO_47"),
+ PINCTRL_PIN(48, "GPIO_48"),
+ PINCTRL_PIN(49, "GPIO_49"),
+ PINCTRL_PIN(50, "GPIO_50"),
+ PINCTRL_PIN(51, "GPIO_51"),
+ PINCTRL_PIN(52, "GPIO_52"),
+ PINCTRL_PIN(53, "GPIO_53"),
+ PINCTRL_PIN(54, "GPIO_54"),
+ PINCTRL_PIN(55, "GPIO_55"),
+ PINCTRL_PIN(56, "GPIO_56"),
+ PINCTRL_PIN(57, "GPIO_57"),
+ PINCTRL_PIN(58, "GPIO_58"),
+ PINCTRL_PIN(59, "GPIO_59"),
+ PINCTRL_PIN(60, "GPIO_60"),
+ PINCTRL_PIN(61, "GPIO_61"),
+ PINCTRL_PIN(62, "GPIO_62"),
+ PINCTRL_PIN(63, "GPIO_63"),
+ PINCTRL_PIN(64, "GPIO_64"),
+ PINCTRL_PIN(65, "GPIO_65"),
+ PINCTRL_PIN(66, "GPIO_66"),
+ PINCTRL_PIN(67, "GPIO_67"),
+ PINCTRL_PIN(68, "GPIO_68"),
+ PINCTRL_PIN(69, "GPIO_69"),
+ PINCTRL_PIN(70, "GPIO_70"),
+ PINCTRL_PIN(71, "GPIO_71"),
+ PINCTRL_PIN(72, "GPIO_72"),
+ PINCTRL_PIN(73, "GPIO_73"),
+ PINCTRL_PIN(74, "GPIO_74"),
+ PINCTRL_PIN(75, "GPIO_75"),
+ PINCTRL_PIN(76, "GPIO_76"),
+ PINCTRL_PIN(77, "GPIO_77"),
+ PINCTRL_PIN(78, "GPIO_78"),
+ PINCTRL_PIN(79, "GPIO_79"),
+ PINCTRL_PIN(80, "GPIO_80"),
+ PINCTRL_PIN(81, "GPIO_81"),
+ PINCTRL_PIN(82, "GPIO_82"),
+ PINCTRL_PIN(83, "GPIO_83"),
+ PINCTRL_PIN(84, "GPIO_84"),
+ PINCTRL_PIN(85, "GPIO_85"),
+ PINCTRL_PIN(86, "GPIO_86"),
+ PINCTRL_PIN(87, "GPIO_87"),
+ PINCTRL_PIN(88, "GPIO_88"),
+ PINCTRL_PIN(89, "GPIO_89"),
+ PINCTRL_PIN(90, "GPIO_90"),
+ PINCTRL_PIN(91, "GPIO_91"),
+ PINCTRL_PIN(92, "GPIO_92"),
+ PINCTRL_PIN(93, "GPIO_93"),
+ PINCTRL_PIN(94, "GPIO_94"),
+ PINCTRL_PIN(95, "GPIO_95"),
+ PINCTRL_PIN(96, "GPIO_96"),
+ PINCTRL_PIN(97, "GPIO_97"),
+ PINCTRL_PIN(98, "GPIO_98"),
+ PINCTRL_PIN(99, "GPIO_99"),
+ PINCTRL_PIN(100, "GPIO_100"),
+ PINCTRL_PIN(101, "GPIO_101"),
+ PINCTRL_PIN(102, "GPIO_102"),
+ PINCTRL_PIN(103, "GPIO_103"),
+ PINCTRL_PIN(104, "GPIO_104"),
+ PINCTRL_PIN(105, "GPIO_105"),
+ PINCTRL_PIN(106, "GPIO_106"),
+ PINCTRL_PIN(107, "GPIO_107"),
+ PINCTRL_PIN(108, "GPIO_108"),
+ PINCTRL_PIN(109, "GPIO_109"),
+ PINCTRL_PIN(110, "GPIO_110"),
+ PINCTRL_PIN(111, "GPIO_111"),
+ PINCTRL_PIN(112, "GPIO_112"),
+ PINCTRL_PIN(113, "GPIO_113"),
+ PINCTRL_PIN(114, "GPIO_114"),
+ PINCTRL_PIN(115, "GPIO_115"),
+ PINCTRL_PIN(116, "GPIO_116"),
+ PINCTRL_PIN(117, "GPIO_117"),
+ PINCTRL_PIN(118, "GPIO_118"),
+ PINCTRL_PIN(119, "GPIO_119"),
+ PINCTRL_PIN(120, "GPIO_120"),
+ PINCTRL_PIN(121, "GPIO_121"),
+ PINCTRL_PIN(122, "GPIO_122"),
+ PINCTRL_PIN(123, "GPIO_123"),
+ PINCTRL_PIN(124, "GPIO_124"),
+ PINCTRL_PIN(125, "GPIO_125"),
+ PINCTRL_PIN(126, "GPIO_126"),
+ PINCTRL_PIN(127, "GPIO_127"),
+ PINCTRL_PIN(128, "GPIO_128"),
+ PINCTRL_PIN(129, "GPIO_129"),
+ PINCTRL_PIN(130, "GPIO_130"),
+ PINCTRL_PIN(131, "GPIO_131"),
+ PINCTRL_PIN(132, "GPIO_132"),
+ PINCTRL_PIN(133, "GPIO_133"),
+ PINCTRL_PIN(134, "GPIO_134"),
+ PINCTRL_PIN(135, "GPIO_135"),
+ PINCTRL_PIN(136, "GPIO_136"),
+ PINCTRL_PIN(137, "GPIO_137"),
+ PINCTRL_PIN(138, "GPIO_138"),
+ PINCTRL_PIN(139, "GPIO_139"),
+ PINCTRL_PIN(140, "GPIO_140"),
+ PINCTRL_PIN(141, "GPIO_141"),
+ PINCTRL_PIN(142, "GPIO_142"),
+ PINCTRL_PIN(143, "GPIO_143"),
+ PINCTRL_PIN(144, "GPIO_144"),
+ PINCTRL_PIN(145, "GPIO_145"),
+ PINCTRL_PIN(146, "GPIO_146"),
+ PINCTRL_PIN(147, "GPIO_147"),
+ PINCTRL_PIN(148, "GPIO_148"),
+ PINCTRL_PIN(149, "GPIO_149"),
+ PINCTRL_PIN(150, "GPIO_150"),
+ PINCTRL_PIN(151, "GPIO_151"),
+
+ PINCTRL_PIN(152, "SDC1_CLK"),
+ PINCTRL_PIN(153, "SDC1_CMD"),
+ PINCTRL_PIN(154, "SDC1_DATA"),
+ PINCTRL_PIN(155, "SDC3_CLK"),
+ PINCTRL_PIN(156, "SDC3_CMD"),
+ PINCTRL_PIN(157, "SDC3_DATA"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+DECLARE_MSM_GPIO_PINS(142);
+DECLARE_MSM_GPIO_PINS(143);
+DECLARE_MSM_GPIO_PINS(144);
+DECLARE_MSM_GPIO_PINS(145);
+DECLARE_MSM_GPIO_PINS(146);
+DECLARE_MSM_GPIO_PINS(147);
+DECLARE_MSM_GPIO_PINS(148);
+DECLARE_MSM_GPIO_PINS(149);
+DECLARE_MSM_GPIO_PINS(150);
+DECLARE_MSM_GPIO_PINS(151);
+
+static const unsigned int sdc1_clk_pins[] = { 152 };
+static const unsigned int sdc1_cmd_pins[] = { 153 };
+static const unsigned int sdc1_data_pins[] = { 154 };
+static const unsigned int sdc3_clk_pins[] = { 155 };
+static const unsigned int sdc3_cmd_pins[] = { 156 };
+static const unsigned int sdc3_data_pins[] = { 157 };
+
+#define FUNCTION(fname) \
+ [MSM_MUX_##fname] = { \
+ .name = #fname, \
+ .groups = fname##_groups, \
+ .ngroups = ARRAY_SIZE(fname##_groups), \
+ }
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \
+ { \
+ .name = "gpio" #id, \
+ .pins = gpio##id##_pins, \
+ .npins = ARRAY_SIZE(gpio##id##_pins), \
+ .funcs = (int[]){ \
+ MSM_MUX_gpio, \
+ MSM_MUX_##f1, \
+ MSM_MUX_##f2, \
+ MSM_MUX_##f3, \
+ MSM_MUX_##f4, \
+ MSM_MUX_##f5, \
+ MSM_MUX_##f6, \
+ MSM_MUX_##f7, \
+ MSM_MUX_##f8, \
+ MSM_MUX_##f9, \
+ MSM_MUX_##f10, \
+ MSM_MUX_##f11 \
+ }, \
+ .nfuncs = 12, \
+ .ctl_reg = 0x1000 + 0x10 * id, \
+ .io_reg = 0x1004 + 0x10 * id, \
+ .intr_cfg_reg = 0x1008 + 0x10 * id, \
+ .intr_status_reg = 0x100c + 0x10 * id, \
+ .intr_target_reg = 0x400 + 0x4 * id, \
+ .mux_bit = 2, \
+ .pull_bit = 0, \
+ .drv_bit = 6, \
+ .oe_bit = 9, \
+ .in_bit = 0, \
+ .out_bit = 1, \
+ .intr_enable_bit = 0, \
+ .intr_status_bit = 0, \
+ .intr_ack_high = 1, \
+ .intr_target_bit = 0, \
+ .intr_raw_status_bit = 3, \
+ .intr_polarity_bit = 1, \
+ .intr_detection_bit = 2, \
+ .intr_detection_width = 1, \
+ }
+
+#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = ARRAY_SIZE(pg_name##_pins), \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+ .mux_bit = -1, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ .intr_enable_bit = -1, \
+ .intr_status_bit = -1, \
+ .intr_target_bit = -1, \
+ .intr_raw_status_bit = -1, \
+ .intr_polarity_bit = -1, \
+ .intr_detection_bit = -1, \
+ .intr_detection_width = -1, \
+ }
+
+enum msm8960_functions {
+ MSM_MUX_audio_pcm,
+ MSM_MUX_bt,
+ MSM_MUX_cam_mclk0,
+ MSM_MUX_cam_mclk1,
+ MSM_MUX_cam_mclk2,
+ MSM_MUX_codec_mic_i2s,
+ MSM_MUX_codec_spkr_i2s,
+ MSM_MUX_ext_gps,
+ MSM_MUX_fm,
+ MSM_MUX_gps_blanking,
+ MSM_MUX_gps_pps_in,
+ MSM_MUX_gps_pps_out,
+ MSM_MUX_gp_clk_0a,
+ MSM_MUX_gp_clk_0b,
+ MSM_MUX_gp_clk_1a,
+ MSM_MUX_gp_clk_1b,
+ MSM_MUX_gp_clk_2a,
+ MSM_MUX_gp_clk_2b,
+ MSM_MUX_gp_mn,
+ MSM_MUX_gp_pdm_0a,
+ MSM_MUX_gp_pdm_0b,
+ MSM_MUX_gp_pdm_1a,
+ MSM_MUX_gp_pdm_1b,
+ MSM_MUX_gp_pdm_2a,
+ MSM_MUX_gp_pdm_2b,
+ MSM_MUX_gpio,
+ MSM_MUX_gsbi1,
+ MSM_MUX_gsbi1_spi_cs1_n,
+ MSM_MUX_gsbi1_spi_cs2a_n,
+ MSM_MUX_gsbi1_spi_cs2b_n,
+ MSM_MUX_gsbi1_spi_cs3_n,
+ MSM_MUX_gsbi2,
+ MSM_MUX_gsbi2_spi_cs1_n,
+ MSM_MUX_gsbi2_spi_cs2_n,
+ MSM_MUX_gsbi2_spi_cs3_n,
+ MSM_MUX_gsbi3,
+ MSM_MUX_gsbi4,
+ MSM_MUX_gsbi4_3d_cam_i2c_l,
+ MSM_MUX_gsbi4_3d_cam_i2c_r,
+ MSM_MUX_gsbi5,
+ MSM_MUX_gsbi5_3d_cam_i2c_l,
+ MSM_MUX_gsbi5_3d_cam_i2c_r,
+ MSM_MUX_gsbi6,
+ MSM_MUX_gsbi7,
+ MSM_MUX_gsbi8,
+ MSM_MUX_gsbi9,
+ MSM_MUX_gsbi10,
+ MSM_MUX_gsbi11,
+ MSM_MUX_gsbi11_spi_cs1a_n,
+ MSM_MUX_gsbi11_spi_cs1b_n,
+ MSM_MUX_gsbi11_spi_cs2a_n,
+ MSM_MUX_gsbi11_spi_cs2b_n,
+ MSM_MUX_gsbi11_spi_cs3_n,
+ MSM_MUX_gsbi12,
+ MSM_MUX_hdmi_cec,
+ MSM_MUX_hdmi_ddc_clock,
+ MSM_MUX_hdmi_ddc_data,
+ MSM_MUX_hdmi_hot_plug_detect,
+ MSM_MUX_hsic,
+ MSM_MUX_mdp_vsync,
+ MSM_MUX_mi2s,
+ MSM_MUX_mic_i2s,
+ MSM_MUX_pmb_clk,
+ MSM_MUX_pmb_ext_ctrl,
+ MSM_MUX_ps_hold,
+ MSM_MUX_rpm_wdog,
+ MSM_MUX_sdc2,
+ MSM_MUX_sdc4,
+ MSM_MUX_sdc5,
+ MSM_MUX_slimbus1,
+ MSM_MUX_slimbus2,
+ MSM_MUX_spkr_i2s,
+ MSM_MUX_ssbi1,
+ MSM_MUX_ssbi2,
+ MSM_MUX_ssbi_ext_gps,
+ MSM_MUX_ssbi_pmic2,
+ MSM_MUX_ssbi_qpa1,
+ MSM_MUX_ssbi_ts,
+ MSM_MUX_tsif1,
+ MSM_MUX_tsif2,
+ MSM_MUX_ts_eoc,
+ MSM_MUX_usb_fs1,
+ MSM_MUX_usb_fs1_oe,
+ MSM_MUX_usb_fs1_oe_n,
+ MSM_MUX_usb_fs2,
+ MSM_MUX_usb_fs2_oe,
+ MSM_MUX_usb_fs2_oe_n,
+ MSM_MUX_vfe_camif_timer1_a,
+ MSM_MUX_vfe_camif_timer1_b,
+ MSM_MUX_vfe_camif_timer2,
+ MSM_MUX_vfe_camif_timer3_a,
+ MSM_MUX_vfe_camif_timer3_b,
+ MSM_MUX_vfe_camif_timer4_a,
+ MSM_MUX_vfe_camif_timer4_b,
+ MSM_MUX_vfe_camif_timer4_c,
+ MSM_MUX_vfe_camif_timer5_a,
+ MSM_MUX_vfe_camif_timer5_b,
+ MSM_MUX_vfe_camif_timer6_a,
+ MSM_MUX_vfe_camif_timer6_b,
+ MSM_MUX_vfe_camif_timer6_c,
+ MSM_MUX_vfe_camif_timer7_a,
+ MSM_MUX_vfe_camif_timer7_b,
+ MSM_MUX_vfe_camif_timer7_c,
+ MSM_MUX_wlan,
+ MSM_MUX_NA,
+};
+
+static const char * const audio_pcm_groups[] = {
+ "gpio63", "gpio64", "gpio65", "gpio66"
+};
+
+static const char * const bt_groups[] = {
+ "gpio28", "gpio29", "gpio83"
+};
+
+static const char * const cam_mclk0_groups[] = {
+ "gpio5"
+};
+
+static const char * const cam_mclk1_groups[] = {
+ "gpio4"
+};
+
+static const char * const cam_mclk2_groups[] = {
+ "gpio2"
+};
+
+static const char * const codec_mic_i2s_groups[] = {
+ "gpio54", "gpio55", "gpio56", "gpio57", "gpio58"
+};
+
+static const char * const codec_spkr_i2s_groups[] = {
+ "gpio59", "gpio60", "gpio61", "gpio62"
+};
+
+static const char * const ext_gps_groups[] = {
+ "gpio22", "gpio23", "gpio24", "gpio25"
+};
+
+static const char * const fm_groups[] = {
+ "gpio26", "gpio27"
+};
+
+static const char * const gps_blanking_groups[] = {
+ "gpio137"
+};
+
+static const char * const gps_pps_in_groups[] = {
+ "gpio37"
+};
+
+static const char * const gps_pps_out_groups[] = {
+ "gpio37"
+};
+
+static const char * const gp_clk_0a_groups[] = {
+ "gpio3"
+};
+
+static const char * const gp_clk_0b_groups[] = {
+ "gpio54"
+};
+
+static const char * const gp_clk_1a_groups[] = {
+ "gpio4"
+};
+
+static const char * const gp_clk_1b_groups[] = {
+ "gpio70"
+};
+
+static const char * const gp_clk_2a_groups[] = {
+ "gpio52"
+};
+
+static const char * const gp_clk_2b_groups[] = {
+ "gpio37"
+};
+
+static const char * const gp_mn_groups[] = {
+ "gpio2"
+};
+
+static const char * const gp_pdm_0a_groups[] = {
+ "gpio58"
+};
+
+static const char * const gp_pdm_0b_groups[] = {
+ "gpio39"
+};
+
+static const char * const gp_pdm_1a_groups[] = {
+ "gpio94"
+};
+
+static const char * const gp_pdm_1b_groups[] = {
+ "gpio64"
+};
+
+static const char * const gp_pdm_2a_groups[] = {
+ "gpio69"
+};
+
+static const char * const gp_pdm_2b_groups[] = {
+ "gpio53"
+};
+
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+ "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+ "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+ "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+ "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+ "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "gpio146",
+ "gpio147", "gpio148", "gpio149", "gpio150", "gpio151"
+};
+
+static const char * const gsbi1_groups[] = {
+ "gpio6", "gpio7", "gpio8", "gpio9"
+};
+
+static const char * const gsbi1_spi_cs1_n_groups[] = {
+ "gpio14"
+};
+
+static const char * const gsbi1_spi_cs2a_n_groups[] = {
+ "gpio15"
+};
+
+static const char * const gsbi1_spi_cs2b_n_groups[] = {
+ "gpio17"
+};
+
+static const char * const gsbi1_spi_cs3_n_groups[] = {
+ "gpio16"
+};
+
+static const char * const gsbi2_groups[] = {
+ "gpio10", "gpio11", "gpio12", "gpio13"
+};
+
+static const char * const gsbi2_spi_cs1_n_groups[] = {
+ "gpio52"
+};
+
+static const char * const gsbi2_spi_cs2_n_groups[] = {
+ "gpio68"
+};
+
+static const char * const gsbi2_spi_cs3_n_groups[] = {
+ "gpio56"
+};
+
+static const char * const gsbi3_groups[] = {
+ "gpio14", "gpio15", "gpio16", "gpio17"
+};
+
+static const char * const gsbi4_groups[] = {
+ "gpio18", "gpio19", "gpio20", "gpio21"
+};
+
+static const char * const gsbi4_3d_cam_i2c_l_groups[] = {
+ "gpio18", "gpio19"
+};
+
+static const char * const gsbi4_3d_cam_i2c_r_groups[] = {
+ "gpio20", "gpio21"
+};
+
+static const char * const gsbi5_groups[] = {
+ "gpio22", "gpio23", "gpio24", "gpio25"
+};
+
+static const char * const gsbi5_3d_cam_i2c_l_groups[] = {
+ "gpio22", "gpio23"
+};
+
+static const char * const gsbi5_3d_cam_i2c_r_groups[] = {
+ "gpio24", "gpio25"
+};
+
+static const char * const gsbi6_groups[] = {
+ "gpio26", "gpio27", "gpio28", "gpio29"
+};
+
+static const char * const gsbi7_groups[] = {
+ "gpio30", "gpio31", "gpio32", "gpio33"
+};
+
+static const char * const gsbi8_groups[] = {
+ "gpio34", "gpio35", "gpio36", "gpio37"
+};
+
+static const char * const gsbi9_groups[] = {
+ "gpio93", "gpio94", "gpio95", "gpio96"
+};
+
+static const char * const gsbi10_groups[] = {
+ "gpio71", "gpio72", "gpio73", "gpio74"
+};
+
+static const char * const gsbi11_groups[] = {
+ "gpio38", "gpio39", "gpio40", "gpio41"
+};
+
+static const char * const gsbi11_spi_cs1a_n_groups[] = {
+ "gpio36"
+};
+
+static const char * const gsbi11_spi_cs1b_n_groups[] = {
+ "gpio18"
+};
+
+static const char * const gsbi11_spi_cs2a_n_groups[] = {
+ "gpio37"
+};
+
+static const char * const gsbi11_spi_cs2b_n_groups[] = {
+ "gpio19"
+};
+
+static const char * const gsbi11_spi_cs3_n_groups[] = {
+ "gpio76"
+};
+
+static const char * const gsbi12_groups[] = {
+ "gpio42", "gpio43", "gpio44", "gpio45"
+};
+
+static const char * const hdmi_cec_groups[] = {
+ "gpio99"
+};
+
+static const char * const hdmi_ddc_clock_groups[] = {
+ "gpio100"
+};
+
+static const char * const hdmi_ddc_data_groups[] = {
+ "gpio101"
+};
+
+static const char * const hdmi_hot_plug_detect_groups[] = {
+ "gpio102"
+};
+
+static const char * const hsic_groups[] = {
+ "gpio150", "gpio151"
+};
+
+static const char * const mdp_vsync_groups[] = {
+ "gpio0", "gpio1", "gpio19"
+};
+
+static const char * const mi2s_groups[] = {
+ "gpio47", "gpio48", "gpio49", "gpio50", "gpio51", "gpio52", "gpio53"
+};
+
+static const char * const mic_i2s_groups[] = {
+ "gpio71", "gpio72", "gpio73", "gpio74"
+};
+
+static const char * const pmb_clk_groups[] = {
+ "gpio21", "gpio86", "gpio112"
+};
+
+static const char * const pmb_ext_ctrl_groups[] = {
+ "gpio4", "gpio5"
+};
+
+static const char * const ps_hold_groups[] = {
+ "gpio108"
+};
+
+static const char * const rpm_wdog_groups[] = {
+ "gpio12"
+};
+
+static const char * const sdc2_groups[] = {
+ "gpio89", "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95",
+ "gpio96", "gpio97", "gpio98"
+};
+
+static const char * const sdc4_groups[] = {
+ "gpio83", "gpio84", "gpio85", "gpio86", "gpio87", "gpio88"
+};
+
+static const char * const sdc5_groups[] = {
+ "gpio77", "gpio78", "gpio79", "gpio80", "gpio81", "gpio82"
+};
+
+static const char * const slimbus1_groups[] = {
+ "gpio50", "gpio51", "gpio60", "gpio61"
+};
+
+static const char * const slimbus2_groups[] = {
+ "gpio42", "gpio43"
+};
+
+static const char * const spkr_i2s_groups[] = {
+ "gpio67", "gpio68", "gpio69", "gpio70"
+};
+
+static const char * const ssbi1_groups[] = {
+ "gpio141", "gpio143"
+};
+
+static const char * const ssbi2_groups[] = {
+ "gpio140", "gpio142"
+};
+
+static const char * const ssbi_ext_gps_groups[] = {
+ "gpio23"
+};
+
+static const char * const ssbi_pmic2_groups[] = {
+ "gpio149"
+};
+
+static const char * const ssbi_qpa1_groups[] = {
+ "gpio131"
+};
+
+static const char * const ssbi_ts_groups[] = {
+ "gpio10"
+};
+
+static const char * const tsif1_groups[] = {
+ "gpio75", "gpio76", "gpio77", "gpio82"
+};
+
+static const char * const tsif2_groups[] = {
+ "gpio78", "gpio79", "gpio80", "gpio81"
+};
+
+static const char * const ts_eoc_groups[] = {
+ "gpio11"
+};
+
+static const char * const usb_fs1_groups[] = {
+ "gpio32", "gpio33"
+};
+
+static const char * const usb_fs1_oe_groups[] = {
+ "gpio31"
+};
+
+static const char * const usb_fs1_oe_n_groups[] = {
+ "gpio31"
+};
+
+static const char * const usb_fs2_groups[] = {
+ "gpio34", "gpio35"
+};
+
+static const char * const usb_fs2_oe_groups[] = {
+ "gpio36"
+};
+
+static const char * const usb_fs2_oe_n_groups[] = {
+ "gpio36"
+};
+
+static const char * const vfe_camif_timer1_a_groups[] = {
+ "gpio2"
+};
+
+static const char * const vfe_camif_timer1_b_groups[] = {
+ "gpio38"
+};
+
+static const char * const vfe_camif_timer2_groups[] = {
+ "gpio3"
+};
+
+static const char * const vfe_camif_timer3_a_groups[] = {
+ "gpio4"
+};
+
+static const char * const vfe_camif_timer3_b_groups[] = {
+ "gpio151"
+};
+
+static const char * const vfe_camif_timer4_a_groups[] = {
+ "gpio65"
+};
+
+static const char * const vfe_camif_timer4_b_groups[] = {
+ "gpio150"
+};
+
+static const char * const vfe_camif_timer4_c_groups[] = {
+ "gpio10"
+};
+
+static const char * const vfe_camif_timer5_a_groups[] = {
+ "gpio66"
+};
+
+static const char * const vfe_camif_timer5_b_groups[] = {
+ "gpio39"
+};
+
+static const char * const vfe_camif_timer6_a_groups[] = {
+ "gpio71"
+};
+
+static const char * const vfe_camif_timer6_b_groups[] = {
+ "gpio0"
+};
+
+static const char * const vfe_camif_timer6_c_groups[] = {
+ "gpio18"
+};
+
+static const char * const vfe_camif_timer7_a_groups[] = {
+ "gpio67"
+};
+
+static const char * const vfe_camif_timer7_b_groups[] = {
+ "gpio1"
+};
+
+static const char * const vfe_camif_timer7_c_groups[] = {
+ "gpio19"
+};
+
+static const char * const wlan_groups[] = {
+ "gpio84", "gpio85", "gpio86", "gpio87", "gpio88"
+};
+
+static const struct msm_function msm8960_functions[] = {
+ FUNCTION(audio_pcm),
+ FUNCTION(bt),
+ FUNCTION(cam_mclk0),
+ FUNCTION(cam_mclk1),
+ FUNCTION(cam_mclk2),
+ FUNCTION(codec_mic_i2s),
+ FUNCTION(codec_spkr_i2s),
+ FUNCTION(ext_gps),
+ FUNCTION(fm),
+ FUNCTION(gps_blanking),
+ FUNCTION(gps_pps_in),
+ FUNCTION(gps_pps_out),
+ FUNCTION(gp_clk_0a),
+ FUNCTION(gp_clk_0b),
+ FUNCTION(gp_clk_1a),
+ FUNCTION(gp_clk_1b),
+ FUNCTION(gp_clk_2a),
+ FUNCTION(gp_clk_2b),
+ FUNCTION(gp_mn),
+ FUNCTION(gp_pdm_0a),
+ FUNCTION(gp_pdm_0b),
+ FUNCTION(gp_pdm_1a),
+ FUNCTION(gp_pdm_1b),
+ FUNCTION(gp_pdm_2a),
+ FUNCTION(gp_pdm_2b),
+ FUNCTION(gpio),
+ FUNCTION(gsbi1),
+ FUNCTION(gsbi1_spi_cs1_n),
+ FUNCTION(gsbi1_spi_cs2a_n),
+ FUNCTION(gsbi1_spi_cs2b_n),
+ FUNCTION(gsbi1_spi_cs3_n),
+ FUNCTION(gsbi2),
+ FUNCTION(gsbi2_spi_cs1_n),
+ FUNCTION(gsbi2_spi_cs2_n),
+ FUNCTION(gsbi2_spi_cs3_n),
+ FUNCTION(gsbi3),
+ FUNCTION(gsbi4),
+ FUNCTION(gsbi4_3d_cam_i2c_l),
+ FUNCTION(gsbi4_3d_cam_i2c_r),
+ FUNCTION(gsbi5),
+ FUNCTION(gsbi5_3d_cam_i2c_l),
+ FUNCTION(gsbi5_3d_cam_i2c_r),
+ FUNCTION(gsbi6),
+ FUNCTION(gsbi7),
+ FUNCTION(gsbi8),
+ FUNCTION(gsbi9),
+ FUNCTION(gsbi10),
+ FUNCTION(gsbi11),
+ FUNCTION(gsbi11_spi_cs1a_n),
+ FUNCTION(gsbi11_spi_cs1b_n),
+ FUNCTION(gsbi11_spi_cs2a_n),
+ FUNCTION(gsbi11_spi_cs2b_n),
+ FUNCTION(gsbi11_spi_cs3_n),
+ FUNCTION(gsbi12),
+ FUNCTION(hdmi_cec),
+ FUNCTION(hdmi_ddc_clock),
+ FUNCTION(hdmi_ddc_data),
+ FUNCTION(hdmi_hot_plug_detect),
+ FUNCTION(hsic),
+ FUNCTION(mdp_vsync),
+ FUNCTION(mi2s),
+ FUNCTION(mic_i2s),
+ FUNCTION(pmb_clk),
+ FUNCTION(pmb_ext_ctrl),
+ FUNCTION(ps_hold),
+ FUNCTION(rpm_wdog),
+ FUNCTION(sdc2),
+ FUNCTION(sdc4),
+ FUNCTION(sdc5),
+ FUNCTION(slimbus1),
+ FUNCTION(slimbus2),
+ FUNCTION(spkr_i2s),
+ FUNCTION(ssbi1),
+ FUNCTION(ssbi2),
+ FUNCTION(ssbi_ext_gps),
+ FUNCTION(ssbi_pmic2),
+ FUNCTION(ssbi_qpa1),
+ FUNCTION(ssbi_ts),
+ FUNCTION(tsif1),
+ FUNCTION(tsif2),
+ FUNCTION(ts_eoc),
+ FUNCTION(usb_fs1),
+ FUNCTION(usb_fs1_oe),
+ FUNCTION(usb_fs1_oe_n),
+ FUNCTION(usb_fs2),
+ FUNCTION(usb_fs2_oe),
+ FUNCTION(usb_fs2_oe_n),
+ FUNCTION(vfe_camif_timer1_a),
+ FUNCTION(vfe_camif_timer1_b),
+ FUNCTION(vfe_camif_timer2),
+ FUNCTION(vfe_camif_timer3_a),
+ FUNCTION(vfe_camif_timer3_b),
+ FUNCTION(vfe_camif_timer4_a),
+ FUNCTION(vfe_camif_timer4_b),
+ FUNCTION(vfe_camif_timer4_c),
+ FUNCTION(vfe_camif_timer5_a),
+ FUNCTION(vfe_camif_timer5_b),
+ FUNCTION(vfe_camif_timer6_a),
+ FUNCTION(vfe_camif_timer6_b),
+ FUNCTION(vfe_camif_timer6_c),
+ FUNCTION(vfe_camif_timer7_a),
+ FUNCTION(vfe_camif_timer7_b),
+ FUNCTION(vfe_camif_timer7_c),
+ FUNCTION(wlan),
+};
+
+static const struct msm_pingroup msm8960_groups[] = {
+ PINGROUP(0, mdp_vsync, vfe_camif_timer6_b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(1, mdp_vsync, vfe_camif_timer7_b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(2, vfe_camif_timer1_a, gp_mn, NA, cam_mclk2, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(3, vfe_camif_timer2, gp_clk_0a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(4, vfe_camif_timer3_a, cam_mclk1, gp_clk_1a, pmb_ext_ctrl, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(5, cam_mclk0, pmb_ext_ctrl, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(6, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(7, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(8, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(9, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(10, gsbi2, ssbi_ts, NA, vfe_camif_timer4_c, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(11, gsbi2, ts_eoc, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(12, gsbi2, rpm_wdog, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(13, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(14, gsbi3, gsbi1_spi_cs1_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(15, gsbi3, gsbi1_spi_cs2a_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(16, gsbi3, gsbi1_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(17, gsbi3, gsbi1_spi_cs2b_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(18, gsbi4, gsbi11_spi_cs1b_n, NA, NA, gsbi4_3d_cam_i2c_l, vfe_camif_timer6_c, NA, NA, NA, NA, NA),
+ PINGROUP(19, gsbi4, gsbi11_spi_cs2b_n, NA, mdp_vsync, NA, gsbi4_3d_cam_i2c_l, vfe_camif_timer7_c, NA, NA, NA, NA),
+ PINGROUP(20, gsbi4, gsbi4_3d_cam_i2c_r, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(21, gsbi4, pmb_clk, gsbi4_3d_cam_i2c_r, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(22, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_l, NA),
+ PINGROUP(23, gsbi5, ssbi_ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_l, NA),
+ PINGROUP(24, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_r, NA),
+ PINGROUP(25, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_r, NA),
+ PINGROUP(26, fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(27, fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(28, bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(29, bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(30, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(31, gsbi7, usb_fs1_oe, usb_fs1_oe_n, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(32, gsbi7, usb_fs1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(33, gsbi7, usb_fs1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(34, gsbi8, usb_fs2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(35, gsbi8, usb_fs2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(36, gsbi8, usb_fs2_oe, usb_fs2_oe_n, gsbi11_spi_cs1a_n, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(37, gsbi8, gps_pps_out, gps_pps_in, gsbi11_spi_cs2a_n, gp_clk_2b, NA, NA, NA, NA, NA, NA),
+ PINGROUP(38, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, vfe_camif_timer1_b, NA),
+ PINGROUP(39, gsbi11, gp_pdm_0b, NA, NA, NA, NA, NA, NA, NA, NA, vfe_camif_timer5_b),
+ PINGROUP(40, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(41, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(42, gsbi12, slimbus2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(43, gsbi12, slimbus2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(44, gsbi12, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(45, gsbi12, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(47, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(48, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(49, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(50, mi2s, slimbus1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(51, mi2s, slimbus1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(52, mi2s, gp_clk_2a, gsbi2_spi_cs1_n, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(53, mi2s, gp_pdm_2b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(54, codec_mic_i2s, gp_clk_0b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(55, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(56, codec_mic_i2s, gsbi2_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(57, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(58, codec_mic_i2s, gp_pdm_0a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(59, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(60, slimbus1, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(61, slimbus1, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(62, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(63, audio_pcm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(64, audio_pcm, gp_pdm_1b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(65, audio_pcm, vfe_camif_timer4_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(66, audio_pcm, vfe_camif_timer5_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(67, spkr_i2s, vfe_camif_timer7_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(68, spkr_i2s, gsbi2_spi_cs2_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(69, spkr_i2s, gp_pdm_2a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(70, spkr_i2s, gp_clk_1b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(71, mic_i2s, gsbi10, vfe_camif_timer6_a, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(72, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(73, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(74, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(75, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(76, tsif1, gsbi11_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(77, tsif1, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(78, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(79, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(80, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(81, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(82, tsif1, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(83, bt, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(84, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(85, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(86, wlan, sdc4, pmb_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(87, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(88, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(89, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(90, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(91, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(92, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(93, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(94, sdc2, gsbi9, gp_pdm_1a, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(95, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(96, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(97, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(98, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(99, hdmi_cec, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(100, hdmi_ddc_clock, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(101, hdmi_ddc_data, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(102, hdmi_hot_plug_detect, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(103, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(104, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(105, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(106, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(107, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(108, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(109, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(110, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(111, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(112, NA, pmb_clk, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(113, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(114, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(115, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(116, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(117, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(118, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(119, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(120, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(121, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(122, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(123, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(124, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(125, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(126, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(127, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(128, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(129, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(130, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(131, NA, ssbi_qpa1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(132, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(133, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(134, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(135, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(136, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(137, gps_blanking, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(138, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(139, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(140, ssbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(141, ssbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(142, ssbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(143, ssbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(144, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(145, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(146, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(147, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(148, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(149, ssbi_pmic2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(150, hsic, NA, vfe_camif_timer4_b, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(151, hsic, NA, vfe_camif_timer3_b, NA, NA, NA, NA, NA, NA, NA, NA),
+
+ SDC_PINGROUP(sdc1_clk, 0x20a0, 13, 6),
+ SDC_PINGROUP(sdc1_cmd, 0x20a0, 11, 3),
+ SDC_PINGROUP(sdc1_data, 0x20a0, 9, 0),
+
+ SDC_PINGROUP(sdc3_clk, 0x20a4, 14, 6),
+ SDC_PINGROUP(sdc3_cmd, 0x20a4, 11, 3),
+ SDC_PINGROUP(sdc3_data, 0x20a4, 9, 0),
+};
+
+#define NUM_GPIO_PINGROUPS 152
+
+static const struct msm_pinctrl_soc_data msm8960_pinctrl = {
+ .pins = msm8960_pins,
+ .npins = ARRAY_SIZE(msm8960_pins),
+ .functions = msm8960_functions,
+ .nfunctions = ARRAY_SIZE(msm8960_functions),
+ .groups = msm8960_groups,
+ .ngroups = ARRAY_SIZE(msm8960_groups),
+ .ngpios = NUM_GPIO_PINGROUPS,
+};
+
+static int msm8960_pinctrl_probe(struct platform_device *pdev)
+{
+ return msm_pinctrl_probe(pdev, &msm8960_pinctrl);
+}
+
+static const struct of_device_id msm8960_pinctrl_of_match[] = {
+ { .compatible = "qcom,msm8960-pinctrl", },
+ { },
+};
+
+static struct platform_driver msm8960_pinctrl_driver = {
+ .driver = {
+ .name = "msm8960-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = msm8960_pinctrl_of_match,
+ },
+ .probe = msm8960_pinctrl_probe,
+ .remove = msm_pinctrl_remove,
+};
+
+static int __init msm8960_pinctrl_init(void)
+{
+ return platform_driver_register(&msm8960_pinctrl_driver);
+}
+arch_initcall(msm8960_pinctrl_init);
+
+static void __exit msm8960_pinctrl_exit(void)
+{
+ platform_driver_unregister(&msm8960_pinctrl_driver);
+}
+module_exit(msm8960_pinctrl_exit);
+
+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
+MODULE_DESCRIPTION("Qualcomm MSM8960 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, msm8960_pinctrl_of_match);
diff --git a/drivers/pinctrl/pinctrl-msm8x74.c b/drivers/pinctrl/qcom/pinctrl-msm8x74.c
index 418306911a6f..8c9720154d1e 100644
--- a/drivers/pinctrl/pinctrl-msm8x74.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm8x74.c
@@ -342,7 +342,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
.pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \
- MSM_MUX_NA, /* gpio mode */ \
+ MSM_MUX_gpio, \
MSM_MUX_##f1, \
MSM_MUX_##f2, \
MSM_MUX_##f3, \
@@ -402,6 +402,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
* the pingroup table below.
*/
enum msm8x74_functions {
+ MSM_MUX_gpio,
MSM_MUX_cci_i2c0,
MSM_MUX_cci_i2c1,
MSM_MUX_blsp_i2c1,
@@ -509,6 +510,31 @@ enum msm8x74_functions {
MSM_MUX_NA,
};
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+ "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+ "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+ "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+ "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+ "gpio141", "gpio142", "gpio143", "gpio144", "gpio145"
+};
+
static const char * const blsp_uart1_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3"
};
@@ -728,6 +754,7 @@ static const char * const wlan_groups[] = {
static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
static const struct msm_function msm8x74_functions[] = {
+ FUNCTION(gpio),
FUNCTION(cci_i2c0),
FUNCTION(cci_i2c1),
FUNCTION(uim1),
diff --git a/drivers/pinctrl/samsung/Kconfig b/drivers/pinctrl/samsung/Kconfig
new file mode 100644
index 000000000000..d0461cd5d707
--- /dev/null
+++ b/drivers/pinctrl/samsung/Kconfig
@@ -0,0 +1,28 @@
+#
+# Samsung Pin control drivers
+#
+config PINCTRL_SAMSUNG
+ bool
+ select PINMUX
+ select PINCONF
+
+config PINCTRL_EXYNOS
+ bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
+ depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210)
+ select PINCTRL_SAMSUNG
+
+config PINCTRL_EXYNOS5440
+ bool "Samsung EXYNOS5440 SoC pinctrl driver"
+ depends on SOC_EXYNOS5440
+ select PINMUX
+ select PINCONF
+
+config PINCTRL_S3C24XX
+ bool "Samsung S3C24XX SoC pinctrl driver"
+ depends on ARCH_S3C24XX
+ select PINCTRL_SAMSUNG
+
+config PINCTRL_S3C64XX
+ bool "Samsung S3C64XX SoC pinctrl driver"
+ depends on ARCH_S3C64XX
+ select PINCTRL_SAMSUNG
diff --git a/drivers/pinctrl/samsung/Makefile b/drivers/pinctrl/samsung/Makefile
new file mode 100644
index 000000000000..70160c059edd
--- /dev/null
+++ b/drivers/pinctrl/samsung/Makefile
@@ -0,0 +1,7 @@
+# Samsung pin control drivers
+
+obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
+obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
+obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
+obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
+obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 9609c23834ce..003bfd874a61 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -33,6 +33,18 @@
#include "pinctrl-samsung.h"
#include "pinctrl-exynos.h"
+struct exynos_irq_chip {
+ struct irq_chip chip;
+
+ u32 eint_con;
+ u32 eint_mask;
+ u32 eint_pend;
+};
+
+static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
+{
+ return container_of(chip, struct exynos_irq_chip, chip);
+}
static struct samsung_pin_bank_type bank_type_off = {
.fld_width = { 4, 1, 2, 2, 2, 2, },
@@ -50,11 +62,13 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
{ }
};
-static void exynos_gpio_irq_mask(struct irq_data *irqd)
+static void exynos_irq_mask(struct irq_data *irqd)
{
+ struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
- unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
+ unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
unsigned long mask;
unsigned long flags;
@@ -67,20 +81,24 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd)
spin_unlock_irqrestore(&bank->slock, flags);
}
-static void exynos_gpio_irq_ack(struct irq_data *irqd)
+static void exynos_irq_ack(struct irq_data *irqd)
{
+ struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
- unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
+ unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
writel(1 << irqd->hwirq, d->virt_base + reg_pend);
}
-static void exynos_gpio_irq_unmask(struct irq_data *irqd)
+static void exynos_irq_unmask(struct irq_data *irqd)
{
+ struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
- unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
+ unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
unsigned long mask;
unsigned long flags;
@@ -93,7 +111,7 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
* masked.
*/
if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
- exynos_gpio_irq_ack(irqd);
+ exynos_irq_ack(irqd);
spin_lock_irqsave(&bank->slock, flags);
@@ -104,16 +122,17 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
spin_unlock_irqrestore(&bank->slock, flags);
}
-static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
+static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
{
+ struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pin_bank_type *bank_type = bank->type;
struct samsung_pinctrl_drv_data *d = bank->drvdata;
- struct samsung_pin_ctrl *ctrl = d->ctrl;
unsigned int pin = irqd->hwirq;
unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
unsigned int con, trig_type;
- unsigned long reg_con = ctrl->geint_con + bank->eint_offset;
+ unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
unsigned long flags;
unsigned int mask;
@@ -167,12 +186,17 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
/*
* irq_chip for gpio interrupts.
*/
-static struct irq_chip exynos_gpio_irq_chip = {
- .name = "exynos_gpio_irq_chip",
- .irq_unmask = exynos_gpio_irq_unmask,
- .irq_mask = exynos_gpio_irq_mask,
- .irq_ack = exynos_gpio_irq_ack,
- .irq_set_type = exynos_gpio_irq_set_type,
+static struct exynos_irq_chip exynos_gpio_irq_chip = {
+ .chip = {
+ .name = "exynos_gpio_irq_chip",
+ .irq_unmask = exynos_irq_unmask,
+ .irq_mask = exynos_irq_mask,
+ .irq_ack = exynos_irq_ack,
+ .irq_set_type = exynos_irq_set_type,
+ },
+ .eint_con = EXYNOS_GPIO_ECON_OFFSET,
+ .eint_mask = EXYNOS_GPIO_EMASK_OFFSET,
+ .eint_pend = EXYNOS_GPIO_EPEND_OFFSET,
};
static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
@@ -181,7 +205,7 @@ static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
struct samsung_pin_bank *b = h->host_data;
irq_set_chip_data(virq, b);
- irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip,
+ irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip,
handle_level_irq);
set_irq_flags(virq, IRQF_VALID);
return 0;
@@ -202,7 +226,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
struct samsung_pin_bank *bank = ctrl->pin_banks;
unsigned int svc, group, pin, virq;
- svc = readl(d->virt_base + ctrl->svc);
+ svc = readl(d->virt_base + EXYNOS_SVC_OFFSET);
group = EXYNOS_SVC_GROUP(svc);
pin = svc & EXYNOS_SVC_NUM_MASK;
@@ -279,119 +303,6 @@ err_domains:
return ret;
}
-static void exynos_wkup_irq_mask(struct irq_data *irqd)
-{
- struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
- struct samsung_pinctrl_drv_data *d = b->drvdata;
- unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
- unsigned long mask;
- unsigned long flags;
-
- spin_lock_irqsave(&b->slock, flags);
-
- mask = readl(d->virt_base + reg_mask);
- mask |= 1 << irqd->hwirq;
- writel(mask, d->virt_base + reg_mask);
-
- spin_unlock_irqrestore(&b->slock, flags);
-}
-
-static void exynos_wkup_irq_ack(struct irq_data *irqd)
-{
- struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
- struct samsung_pinctrl_drv_data *d = b->drvdata;
- unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
-
- writel(1 << irqd->hwirq, d->virt_base + pend);
-}
-
-static void exynos_wkup_irq_unmask(struct irq_data *irqd)
-{
- struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
- struct samsung_pinctrl_drv_data *d = b->drvdata;
- unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
- unsigned long mask;
- unsigned long flags;
-
- /*
- * Ack level interrupts right before unmask
- *
- * If we don't do this we'll get a double-interrupt. Level triggered
- * interrupts must not fire an interrupt if the level is not
- * _currently_ active, even if it was active while the interrupt was
- * masked.
- */
- if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
- exynos_wkup_irq_ack(irqd);
-
- spin_lock_irqsave(&b->slock, flags);
-
- mask = readl(d->virt_base + reg_mask);
- mask &= ~(1 << irqd->hwirq);
- writel(mask, d->virt_base + reg_mask);
-
- spin_unlock_irqrestore(&b->slock, flags);
-}
-
-static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
-{
- struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
- struct samsung_pin_bank_type *bank_type = bank->type;
- struct samsung_pinctrl_drv_data *d = bank->drvdata;
- unsigned int pin = irqd->hwirq;
- unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
- unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
- unsigned long con, trig_type;
- unsigned long flags;
- unsigned int mask;
-
- switch (type) {
- case IRQ_TYPE_EDGE_RISING:
- trig_type = EXYNOS_EINT_EDGE_RISING;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- trig_type = EXYNOS_EINT_EDGE_FALLING;
- break;
- case IRQ_TYPE_EDGE_BOTH:
- trig_type = EXYNOS_EINT_EDGE_BOTH;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- trig_type = EXYNOS_EINT_LEVEL_HIGH;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- trig_type = EXYNOS_EINT_LEVEL_LOW;
- break;
- default:
- pr_err("unsupported external interrupt type\n");
- return -EINVAL;
- }
-
- if (type & IRQ_TYPE_EDGE_BOTH)
- __irq_set_handler_locked(irqd->irq, handle_edge_irq);
- else
- __irq_set_handler_locked(irqd->irq, handle_level_irq);
-
- con = readl(d->virt_base + reg_con);
- con &= ~(EXYNOS_EINT_CON_MASK << shift);
- con |= trig_type << shift;
- writel(con, d->virt_base + reg_con);
-
- reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
- shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
- mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
-
- spin_lock_irqsave(&bank->slock, flags);
-
- con = readl(d->virt_base + reg_con);
- con &= ~(mask << shift);
- con |= EXYNOS_EINT_FUNC << shift;
- writel(con, d->virt_base + reg_con);
-
- spin_unlock_irqrestore(&bank->slock, flags);
-
- return 0;
-}
-
static u32 exynos_eint_wake_mask = 0xffffffff;
u32 exynos_get_eint_wake_mask(void)
@@ -417,13 +328,18 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
/*
* irq_chip for wakeup interrupts
*/
-static struct irq_chip exynos_wkup_irq_chip = {
- .name = "exynos_wkup_irq_chip",
- .irq_unmask = exynos_wkup_irq_unmask,
- .irq_mask = exynos_wkup_irq_mask,
- .irq_ack = exynos_wkup_irq_ack,
- .irq_set_type = exynos_wkup_irq_set_type,
- .irq_set_wake = exynos_wkup_irq_set_wake,
+static struct exynos_irq_chip exynos_wkup_irq_chip = {
+ .chip = {
+ .name = "exynos_wkup_irq_chip",
+ .irq_unmask = exynos_irq_unmask,
+ .irq_mask = exynos_irq_mask,
+ .irq_ack = exynos_irq_ack,
+ .irq_set_type = exynos_irq_set_type,
+ .irq_set_wake = exynos_wkup_irq_set_wake,
+ },
+ .eint_con = EXYNOS_WKUP_ECON_OFFSET,
+ .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
+ .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
};
/* interrupt handler for wakeup interrupts 0..15 */
@@ -464,7 +380,6 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
struct irq_chip *chip = irq_get_chip(irq);
struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
- struct samsung_pin_ctrl *ctrl = d->ctrl;
unsigned long pend;
unsigned long mask;
int i;
@@ -473,8 +388,10 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
for (i = 0; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i];
- pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset);
- mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset);
+ pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET
+ + b->eint_offset);
+ mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET
+ + b->eint_offset);
exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
}
@@ -484,7 +401,8 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
- irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip,
+ handle_level_irq);
irq_set_chip_data(virq, h->host_data);
set_irq_flags(virq, IRQF_VALID);
return 0;
@@ -703,13 +621,6 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = s5pv210_pin_bank,
.nr_banks = ARRAY_SIZE(s5pv210_pin_bank),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -758,10 +669,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos3250_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos3250_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -770,13 +677,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos3250_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos3250_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -843,10 +743,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos4210_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -855,13 +751,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos4210_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -942,10 +831,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos4x12_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -954,13 +839,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos4x12_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -970,10 +848,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 2 data */
.pin_banks = exynos4x12_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks2),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -982,10 +856,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 3 data */
.pin_banks = exynos4x12_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks3),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -1058,13 +928,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos5250_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -1074,10 +937,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos5250_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -1086,10 +945,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 2 data */
.pin_banks = exynos5250_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks2),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -1098,10 +953,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 3 data */
.pin_banks = exynos5250_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks3),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -1158,13 +1009,6 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos5260_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5260-gpio-ctrl0",
@@ -1172,20 +1016,12 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos5260_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5260_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks2),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl2",
},
@@ -1256,13 +1092,6 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos5420_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5420-gpio-ctrl0",
@@ -1270,40 +1099,24 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos5420_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5420_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks2),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl2",
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5420_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks3),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl3",
}, {
/* pin-controller instance 4 data */
.pin_banks = exynos5420_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks4),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl4",
},
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
index 3c91c357792f..3c91c357792f 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c
index 8fe2ab0a7698..603da2f9dd95 100644
--- a/drivers/pinctrl/pinctrl-exynos5440.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos5440.c
@@ -23,7 +23,7 @@
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/of_irq.h>
-#include "core.h"
+#include "../core.h"
/* EXYNOS5440 GPIO and Pinctrl register offsets */
#define GPIO_MUX 0x00
@@ -371,13 +371,6 @@ static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned select
return 0;
}
-/* disable a specified pinmux by writing to registers */
-static void exynos5440_pinmux_disable(struct pinctrl_dev *pctldev,
- unsigned selector, unsigned group)
-{
- exynos5440_pinmux_setup(pctldev, selector, group, false);
-}
-
/*
* The calls to gpio_direction_output() and gpio_direction_input()
* leads to this function call (via the pinctrl_gpio_direction_{input|output}()
@@ -395,7 +388,6 @@ static const struct pinmux_ops exynos5440_pinmux_ops = {
.get_function_name = exynos5440_pinmux_get_fname,
.get_function_groups = exynos5440_pinmux_get_groups,
.enable = exynos5440_pinmux_enable,
- .disable = exynos5440_pinmux_disable,
.gpio_set_direction = exynos5440_pinmux_gpio_set_direction,
};
diff --git a/drivers/pinctrl/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
index ad3eaad17001..ad3eaad17001 100644
--- a/drivers/pinctrl/pinctrl-s3c24xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
diff --git a/drivers/pinctrl/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
index 89143c903000..89143c903000 100644
--- a/drivers/pinctrl/pinctrl-s3c64xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 3e61d0f8f146..b07406da333c 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -30,7 +30,7 @@
#include <linux/spinlock.h>
#include <linux/syscore_ops.h>
-#include "core.h"
+#include "../core.h"
#include "pinctrl-samsung.h"
#define GROUP_SUFFIX "-grp"
@@ -40,13 +40,14 @@
/* list of all possible config options supported */
static struct pin_config {
- char *prop_cfg;
- unsigned int cfg_type;
-} pcfgs[] = {
+ const char *property;
+ enum pincfg_type param;
+} cfg_params[] = {
{ "samsung,pin-pud", PINCFG_TYPE_PUD },
{ "samsung,pin-drv", PINCFG_TYPE_DRV },
{ "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },
{ "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
+ { "samsung,pin-val", PINCFG_TYPE_DAT },
};
/* Global list of devices (struct samsung_pinctrl_drv_data) */
@@ -59,163 +60,242 @@ static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
return container_of(gc, struct samsung_pin_bank, gpio_chip);
}
-/* check if the selector is a valid pin group selector */
static int samsung_get_group_count(struct pinctrl_dev *pctldev)
{
- struct samsung_pinctrl_drv_data *drvdata;
+ struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
- drvdata = pinctrl_dev_get_drvdata(pctldev);
- return drvdata->nr_groups;
+ return pmx->nr_groups;
}
-/* return the name of the group selected by the group selector */
static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
- unsigned selector)
+ unsigned group)
{
- struct samsung_pinctrl_drv_data *drvdata;
+ struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
- drvdata = pinctrl_dev_get_drvdata(pctldev);
- return drvdata->pin_groups[selector].name;
+ return pmx->pin_groups[group].name;
}
-/* return the pin numbers associated with the specified group */
static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
- unsigned selector, const unsigned **pins, unsigned *num_pins)
+ unsigned group,
+ const unsigned **pins,
+ unsigned *num_pins)
{
- struct samsung_pinctrl_drv_data *drvdata;
+ struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = pmx->pin_groups[group].pins;
+ *num_pins = pmx->pin_groups[group].num_pins;
- drvdata = pinctrl_dev_get_drvdata(pctldev);
- *pins = drvdata->pin_groups[selector].pins;
- *num_pins = drvdata->pin_groups[selector].num_pins;
return 0;
}
-/* create pinctrl_map entries by parsing device tree nodes */
-static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
- struct device_node *np, struct pinctrl_map **maps,
- unsigned *nmaps)
+static int reserve_map(struct device *dev, struct pinctrl_map **map,
+ unsigned *reserved_maps, unsigned *num_maps,
+ unsigned reserve)
{
- struct device *dev = pctldev->dev;
- struct pinctrl_map *map;
- unsigned long *cfg = NULL;
- char *gname, *fname;
- int cfg_cnt = 0, map_cnt = 0, idx = 0;
-
- /* count the number of config options specfied in the node */
- for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
- if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
- cfg_cnt++;
- }
+ unsigned old_num = *reserved_maps;
+ unsigned new_num = *num_maps + reserve;
+ struct pinctrl_map *new_map;
- /*
- * Find out the number of map entries to create. All the config options
- * can be accomadated into a single config map entry.
- */
- if (cfg_cnt)
- map_cnt = 1;
- if (of_find_property(np, "samsung,pin-function", NULL))
- map_cnt++;
- if (!map_cnt) {
- dev_err(dev, "node %s does not have either config or function "
- "configurations\n", np->name);
- return -EINVAL;
- }
+ if (old_num >= new_num)
+ return 0;
- /* Allocate memory for pin-map entries */
- map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
- if (!map) {
- dev_err(dev, "could not alloc memory for pin-maps\n");
+ new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
+ if (!new_map) {
+ dev_err(dev, "krealloc(map) failed\n");
return -ENOMEM;
}
- *nmaps = 0;
- /*
- * Allocate memory for pin group name. The pin group name is derived
- * from the node name from which these map entries are be created.
- */
- gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
- if (!gname) {
- dev_err(dev, "failed to alloc memory for group name\n");
- goto free_map;
+ memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
+
+ *map = new_map;
+ *reserved_maps = new_num;
+
+ return 0;
+}
+
+static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
+ unsigned *num_maps, const char *group,
+ const char *function)
+{
+ if (WARN_ON(*num_maps == *reserved_maps))
+ return -ENOSPC;
+
+ (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+ (*map)[*num_maps].data.mux.group = group;
+ (*map)[*num_maps].data.mux.function = function;
+ (*num_maps)++;
+
+ return 0;
+}
+
+static int add_map_configs(struct device *dev, struct pinctrl_map **map,
+ unsigned *reserved_maps, unsigned *num_maps,
+ const char *group, unsigned long *configs,
+ unsigned num_configs)
+{
+ unsigned long *dup_configs;
+
+ if (WARN_ON(*num_maps == *reserved_maps))
+ return -ENOSPC;
+
+ dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
+ GFP_KERNEL);
+ if (!dup_configs) {
+ dev_err(dev, "kmemdup(configs) failed\n");
+ return -ENOMEM;
}
- sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
- /*
- * don't have config options? then skip over to creating function
- * map entries.
- */
- if (!cfg_cnt)
- goto skip_cfgs;
-
- /* Allocate memory for config entries */
- cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
- if (!cfg) {
- dev_err(dev, "failed to alloc memory for configs\n");
- goto free_gname;
+ (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+ (*map)[*num_maps].data.configs.group_or_pin = group;
+ (*map)[*num_maps].data.configs.configs = dup_configs;
+ (*map)[*num_maps].data.configs.num_configs = num_configs;
+ (*num_maps)++;
+
+ return 0;
+}
+
+static int add_config(struct device *dev, unsigned long **configs,
+ unsigned *num_configs, unsigned long config)
+{
+ unsigned old_num = *num_configs;
+ unsigned new_num = old_num + 1;
+ unsigned long *new_configs;
+
+ new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
+ GFP_KERNEL);
+ if (!new_configs) {
+ dev_err(dev, "krealloc(configs) failed\n");
+ return -ENOMEM;
}
- /* Prepare a list of config settings */
- for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
- u32 value;
- if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
- cfg[cfg_cnt++] =
- PINCFG_PACK(pcfgs[idx].cfg_type, value);
+ new_configs[old_num] = config;
+
+ *configs = new_configs;
+ *num_configs = new_num;
+
+ return 0;
+}
+
+static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map,
+ unsigned num_maps)
+{
+ int i;
+
+ for (i = 0; i < num_maps; i++)
+ if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
+ kfree(map[i].data.configs.configs);
+
+ kfree(map);
+}
+
+static int samsung_dt_subnode_to_map(struct samsung_pinctrl_drv_data *drvdata,
+ struct device *dev,
+ struct device_node *np,
+ struct pinctrl_map **map,
+ unsigned *reserved_maps,
+ unsigned *num_maps)
+{
+ int ret, i;
+ u32 val;
+ unsigned long config;
+ unsigned long *configs = NULL;
+ unsigned num_configs = 0;
+ unsigned reserve;
+ struct property *prop;
+ const char *group;
+ bool has_func = false;
+
+ ret = of_property_read_u32(np, "samsung,pin-function", &val);
+ if (!ret)
+ has_func = true;
+
+ for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
+ ret = of_property_read_u32(np, cfg_params[i].property, &val);
+ if (!ret) {
+ config = PINCFG_PACK(cfg_params[i].param, val);
+ ret = add_config(dev, &configs, &num_configs, config);
+ if (ret < 0)
+ goto exit;
+ /* EINVAL=missing, which is fine since it's optional */
+ } else if (ret != -EINVAL) {
+ dev_err(dev, "could not parse property %s\n",
+ cfg_params[i].property);
+ }
}
- /* create the config map entry */
- map[*nmaps].data.configs.group_or_pin = gname;
- map[*nmaps].data.configs.configs = cfg;
- map[*nmaps].data.configs.num_configs = cfg_cnt;
- map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
- *nmaps += 1;
-
-skip_cfgs:
- /* create the function map entry */
- if (of_find_property(np, "samsung,pin-function", NULL)) {
- fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
- if (!fname) {
- dev_err(dev, "failed to alloc memory for func name\n");
- goto free_cfg;
+ reserve = 0;
+ if (has_func)
+ reserve++;
+ if (num_configs)
+ reserve++;
+ ret = of_property_count_strings(np, "samsung,pins");
+ if (ret < 0) {
+ dev_err(dev, "could not parse property samsung,pins\n");
+ goto exit;
+ }
+ reserve *= ret;
+
+ ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);
+ if (ret < 0)
+ goto exit;
+
+ of_property_for_each_string(np, "samsung,pins", prop, group) {
+ if (has_func) {
+ ret = add_map_mux(map, reserved_maps,
+ num_maps, group, np->full_name);
+ if (ret < 0)
+ goto exit;
}
- sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
- map[*nmaps].data.mux.group = gname;
- map[*nmaps].data.mux.function = fname;
- map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
- *nmaps += 1;
+ if (num_configs) {
+ ret = add_map_configs(dev, map, reserved_maps,
+ num_maps, group, configs,
+ num_configs);
+ if (ret < 0)
+ goto exit;
+ }
}
- *maps = map;
- return 0;
+ ret = 0;
-free_cfg:
- kfree(cfg);
-free_gname:
- kfree(gname);
-free_map:
- kfree(map);
- return -ENOMEM;
+exit:
+ kfree(configs);
+ return ret;
}
-/* free the memory allocated to hold the pin-map table */
-static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
- struct pinctrl_map *map, unsigned num_maps)
+static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map,
+ unsigned *num_maps)
{
- int idx;
-
- for (idx = 0; idx < num_maps; idx++) {
- if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
- kfree(map[idx].data.mux.function);
- if (!idx)
- kfree(map[idx].data.mux.group);
- } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
- kfree(map[idx].data.configs.configs);
- if (!idx)
- kfree(map[idx].data.configs.group_or_pin);
+ struct samsung_pinctrl_drv_data *drvdata;
+ unsigned reserved_maps;
+ struct device_node *np;
+ int ret;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+
+ reserved_maps = 0;
+ *map = NULL;
+ *num_maps = 0;
+
+ if (!of_get_child_count(np_config))
+ return samsung_dt_subnode_to_map(drvdata, pctldev->dev,
+ np_config, map,
+ &reserved_maps,
+ num_maps);
+
+ for_each_child_of_node(np_config, np) {
+ ret = samsung_dt_subnode_to_map(drvdata, pctldev->dev, np, map,
+ &reserved_maps, num_maps);
+ if (ret < 0) {
+ samsung_dt_free_map(pctldev, *map, *num_maps);
+ return ret;
}
- };
+ }
- kfree(map);
+ return 0;
}
/* list of pinctrl callbacks for the pinctrl core */
@@ -286,83 +366,21 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group, bool enable)
{
struct samsung_pinctrl_drv_data *drvdata;
- const unsigned int *pins;
- struct samsung_pin_bank *bank;
- void __iomem *reg;
- u32 mask, shift, data, pin_offset, cnt;
- unsigned long flags;
-
- drvdata = pinctrl_dev_get_drvdata(pctldev);
- pins = drvdata->pin_groups[group].pins;
-
- /*
- * for each pin in the pin group selected, program the correspoding pin
- * pin function number in the config register.
- */
- for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
- struct samsung_pin_bank_type *type;
-
- pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
- &reg, &pin_offset, &bank);
- type = bank->type;
- mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
- shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
- if (shift >= 32) {
- /* Some banks have two config registers */
- shift -= 32;
- reg += 4;
- }
-
- spin_lock_irqsave(&bank->slock, flags);
-
- data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
- data &= ~(mask << shift);
- if (enable)
- data |= drvdata->pin_groups[group].func << shift;
- writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
-
- spin_unlock_irqrestore(&bank->slock, flags);
- }
-}
-
-/* enable a specified pinmux by writing to registers */
-static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- samsung_pinmux_setup(pctldev, selector, group, true);
- return 0;
-}
-
-/* disable a specified pinmux by writing to registers */
-static void samsung_pinmux_disable(struct pinctrl_dev *pctldev,
- unsigned selector, unsigned group)
-{
- samsung_pinmux_setup(pctldev, selector, group, false);
-}
-
-/*
- * The calls to gpio_direction_output() and gpio_direction_input()
- * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
- * function called from the gpiolib interface).
- */
-static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range, unsigned offset, bool input)
-{
struct samsung_pin_bank_type *type;
struct samsung_pin_bank *bank;
- struct samsung_pinctrl_drv_data *drvdata;
void __iomem *reg;
- u32 data, pin_offset, mask, shift;
+ u32 mask, shift, data, pin_offset;
unsigned long flags;
+ const struct samsung_pmx_func *func;
+ const struct samsung_pin_group *grp;
- bank = gc_to_pin_bank(range->gc);
- type = bank->type;
drvdata = pinctrl_dev_get_drvdata(pctldev);
+ func = &drvdata->pmx_functions[selector];
+ grp = &drvdata->pin_groups[group];
- pin_offset = offset - bank->pin_base;
- reg = drvdata->virt_base + bank->pctl_offset +
- type->reg_offset[PINCFG_TYPE_FUNC];
-
+ pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base,
+ &reg, &pin_offset, &bank);
+ type = bank->type;
mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
if (shift >= 32) {
@@ -373,14 +391,20 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
spin_lock_irqsave(&bank->slock, flags);
- data = readl(reg);
+ data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
data &= ~(mask << shift);
- if (!input)
- data |= FUNC_OUTPUT << shift;
- writel(data, reg);
+ if (enable)
+ data |= func->val << shift;
+ writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
spin_unlock_irqrestore(&bank->slock, flags);
+}
+/* enable a specified pinmux by writing to registers */
+static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
+ unsigned group)
+{
+ samsung_pinmux_setup(pctldev, selector, group, true);
return 0;
}
@@ -390,8 +414,6 @@ static const struct pinmux_ops samsung_pinmux_ops = {
.get_function_name = samsung_pinmux_get_fname,
.get_function_groups = samsung_pinmux_get_groups,
.enable = samsung_pinmux_enable,
- .disable = samsung_pinmux_disable,
- .gpio_set_direction = samsung_pinmux_gpio_set_direction,
};
/* set or get the pin config settings for a specified pin */
@@ -540,25 +562,59 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
}
/*
- * gpiolib gpio_direction_input callback function. The setting of the pin
- * mux function as 'gpio input' will be handled by the pinctrl susbsystem
- * interface.
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call.
*/
+static int samsung_gpio_set_direction(struct gpio_chip *gc,
+ unsigned offset, bool input)
+{
+ struct samsung_pin_bank_type *type;
+ struct samsung_pin_bank *bank;
+ struct samsung_pinctrl_drv_data *drvdata;
+ void __iomem *reg;
+ u32 data, mask, shift;
+ unsigned long flags;
+
+ bank = gc_to_pin_bank(gc);
+ type = bank->type;
+ drvdata = bank->drvdata;
+
+ reg = drvdata->virt_base + bank->pctl_offset +
+ type->reg_offset[PINCFG_TYPE_FUNC];
+
+ mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
+ shift = offset * type->fld_width[PINCFG_TYPE_FUNC];
+ if (shift >= 32) {
+ /* Some banks have two config registers */
+ shift -= 32;
+ reg += 4;
+ }
+
+ spin_lock_irqsave(&bank->slock, flags);
+
+ data = readl(reg);
+ data &= ~(mask << shift);
+ if (!input)
+ data |= FUNC_OUTPUT << shift;
+ writel(data, reg);
+
+ spin_unlock_irqrestore(&bank->slock, flags);
+
+ return 0;
+}
+
+/* gpiolib gpio_direction_input callback function. */
static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
- return pinctrl_gpio_direction_input(gc->base + offset);
+ return samsung_gpio_set_direction(gc, offset, true);
}
-/*
- * gpiolib gpio_direction_output callback function. The setting of the pin
- * mux function as 'gpio output' will be handled by the pinctrl susbsystem
- * interface.
- */
+/* gpiolib gpio_direction_output callback function. */
static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
int value)
{
samsung_gpio_set(gc, offset, value);
- return pinctrl_gpio_direction_output(gc->base + offset);
+ return samsung_gpio_set_direction(gc, offset, false);
}
/*
@@ -578,87 +634,115 @@ static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
return (virq) ? : -ENXIO;
}
-/*
- * Parse the pin names listed in the 'samsung,pins' property and convert it
- * into a list of gpio numbers are create a pin group from it.
- */
-static int samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
- struct device_node *cfg_np,
- struct pinctrl_desc *pctl,
- unsigned int **pin_list,
- unsigned int *npins)
+static struct samsung_pin_group *samsung_pinctrl_create_groups(
+ struct device *dev,
+ struct samsung_pinctrl_drv_data *drvdata,
+ unsigned int *cnt)
{
- struct device *dev = &pdev->dev;
- struct property *prop;
- struct pinctrl_pin_desc const *pdesc = pctl->pins;
- unsigned int idx = 0, cnt;
- const char *pin_name;
+ struct pinctrl_desc *ctrldesc = &drvdata->pctl;
+ struct samsung_pin_group *groups, *grp;
+ const struct pinctrl_pin_desc *pdesc;
+ int i;
- *npins = of_property_count_strings(cfg_np, "samsung,pins");
- if (IS_ERR_VALUE(*npins)) {
- dev_err(dev, "invalid pin list in %s node", cfg_np->name);
+ groups = devm_kzalloc(dev, ctrldesc->npins * sizeof(*groups),
+ GFP_KERNEL);
+ if (!groups)
+ return ERR_PTR(-EINVAL);
+ grp = groups;
+
+ pdesc = ctrldesc->pins;
+ for (i = 0; i < ctrldesc->npins; ++i, ++pdesc, ++grp) {
+ grp->name = pdesc->name;
+ grp->pins = &pdesc->number;
+ grp->num_pins = 1;
+ }
+
+ *cnt = ctrldesc->npins;
+ return groups;
+}
+
+static int samsung_pinctrl_create_function(struct device *dev,
+ struct samsung_pinctrl_drv_data *drvdata,
+ struct device_node *func_np,
+ struct samsung_pmx_func *func)
+{
+ int npins;
+ int ret;
+ int i;
+
+ if (of_property_read_u32(func_np, "samsung,pin-function", &func->val))
+ return 0;
+
+ npins = of_property_count_strings(func_np, "samsung,pins");
+ if (npins < 1) {
+ dev_err(dev, "invalid pin list in %s node", func_np->name);
return -EINVAL;
}
- *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
- if (!*pin_list) {
- dev_err(dev, "failed to allocate memory for pin list\n");
+ func->name = func_np->full_name;
+
+ func->groups = devm_kzalloc(dev, npins * sizeof(char *), GFP_KERNEL);
+ if (!func->groups)
return -ENOMEM;
- }
- of_property_for_each_string(cfg_np, "samsung,pins", prop, pin_name) {
- for (cnt = 0; cnt < pctl->npins; cnt++) {
- if (pdesc[cnt].name) {
- if (!strcmp(pin_name, pdesc[cnt].name)) {
- (*pin_list)[idx++] = pdesc[cnt].number;
- break;
- }
- }
- }
- if (cnt == pctl->npins) {
- dev_err(dev, "pin %s not valid in %s node\n",
- pin_name, cfg_np->name);
- devm_kfree(dev, *pin_list);
- return -EINVAL;
+ for (i = 0; i < npins; ++i) {
+ const char *gname;
+
+ ret = of_property_read_string_index(func_np, "samsung,pins",
+ i, &gname);
+ if (ret) {
+ dev_err(dev,
+ "failed to read pin name %d from %s node\n",
+ i, func_np->name);
+ return ret;
}
+
+ func->groups[i] = gname;
}
- return 0;
+ func->num_groups = npins;
+ return 1;
}
-/*
- * Parse the information about all the available pin groups and pin functions
- * from device node of the pin-controller. A pin group is formed with all
- * the pins listed in the "samsung,pins" property.
- */
-static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
- struct samsung_pinctrl_drv_data *drvdata)
+static struct samsung_pmx_func *samsung_pinctrl_create_functions(
+ struct device *dev,
+ struct samsung_pinctrl_drv_data *drvdata,
+ unsigned int *cnt)
{
- struct device *dev = &pdev->dev;
+ struct samsung_pmx_func *functions, *func;
struct device_node *dev_np = dev->of_node;
struct device_node *cfg_np;
- struct samsung_pin_group *groups, *grp;
- struct samsung_pmx_func *functions, *func;
- unsigned *pin_list;
- unsigned int npins, grp_cnt, func_idx = 0;
- char *gname, *fname;
+ unsigned int func_cnt = 0;
int ret;
- grp_cnt = of_get_child_count(dev_np);
- if (!grp_cnt)
- return -EINVAL;
+ /*
+ * Iterate over all the child nodes of the pin controller node
+ * and create pin groups and pin function lists.
+ */
+ for_each_child_of_node(dev_np, cfg_np) {
+ struct device_node *func_np;
- groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
- if (!groups) {
- dev_err(dev, "failed allocate memory for ping group list\n");
- return -EINVAL;
+ if (!of_get_child_count(cfg_np)) {
+ if (!of_find_property(cfg_np,
+ "samsung,pin-function", NULL))
+ continue;
+ ++func_cnt;
+ continue;
+ }
+
+ for_each_child_of_node(cfg_np, func_np) {
+ if (!of_find_property(func_np,
+ "samsung,pin-function", NULL))
+ continue;
+ ++func_cnt;
+ }
}
- grp = groups;
- functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
+ functions = devm_kzalloc(dev, func_cnt * sizeof(*functions),
+ GFP_KERNEL);
if (!functions) {
dev_err(dev, "failed to allocate memory for function list\n");
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
func = functions;
@@ -666,61 +750,68 @@ static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
* Iterate over all the child nodes of the pin controller node
* and create pin groups and pin function lists.
*/
+ func_cnt = 0;
for_each_child_of_node(dev_np, cfg_np) {
- u32 function;
- if (!of_find_property(cfg_np, "samsung,pins", NULL))
+ struct device_node *func_np;
+
+ if (!of_get_child_count(cfg_np)) {
+ ret = samsung_pinctrl_create_function(dev, drvdata,
+ cfg_np, func);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ if (ret > 0) {
+ ++func;
+ ++func_cnt;
+ }
continue;
+ }
- ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
- &drvdata->pctl, &pin_list, &npins);
- if (ret)
- return ret;
-
- /* derive pin group name from the node name */
- gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
- GFP_KERNEL);
- if (!gname) {
- dev_err(dev, "failed to alloc memory for group name\n");
- return -ENOMEM;
+ for_each_child_of_node(cfg_np, func_np) {
+ ret = samsung_pinctrl_create_function(dev, drvdata,
+ func_np, func);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ if (ret > 0) {
+ ++func;
+ ++func_cnt;
+ }
}
- sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
+ }
- grp->name = gname;
- grp->pins = pin_list;
- grp->num_pins = npins;
- of_property_read_u32(cfg_np, "samsung,pin-function", &function);
- grp->func = function;
- grp++;
+ *cnt = func_cnt;
+ return functions;
+}
- if (!of_find_property(cfg_np, "samsung,pin-function", NULL))
- continue;
+/*
+ * Parse the information about all the available pin groups and pin functions
+ * from device node of the pin-controller. A pin group is formed with all
+ * the pins listed in the "samsung,pins" property.
+ */
- /* derive function name from the node name */
- fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
- GFP_KERNEL);
- if (!fname) {
- dev_err(dev, "failed to alloc memory for func name\n");
- return -ENOMEM;
- }
- sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
-
- func->name = fname;
- func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
- if (!func->groups) {
- dev_err(dev, "failed to alloc memory for group list "
- "in pin function");
- return -ENOMEM;
- }
- func->groups[0] = gname;
- func->num_groups = 1;
- func++;
- func_idx++;
+static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
+ struct samsung_pinctrl_drv_data *drvdata)
+{
+ struct device *dev = &pdev->dev;
+ struct samsung_pin_group *groups;
+ struct samsung_pmx_func *functions;
+ unsigned int grp_cnt = 0, func_cnt = 0;
+
+ groups = samsung_pinctrl_create_groups(dev, drvdata, &grp_cnt);
+ if (IS_ERR(groups)) {
+ dev_err(dev, "failed to parse pin groups\n");
+ return PTR_ERR(groups);
+ }
+
+ functions = samsung_pinctrl_create_functions(dev, drvdata, &func_cnt);
+ if (IS_ERR(functions)) {
+ dev_err(dev, "failed to parse pin functions\n");
+ return PTR_ERR(groups);
}
drvdata->pin_groups = groups;
drvdata->nr_groups = grp_cnt;
drvdata->pmx_functions = functions;
- drvdata->nr_functions = func_idx;
+ drvdata->nr_functions = func_cnt;
return 0;
}
@@ -790,7 +881,8 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
pin_bank = &drvdata->ctrl->pin_banks[bank];
pin_bank->grange.name = pin_bank->name;
pin_bank->grange.id = bank;
- pin_bank->grange.pin_base = pin_bank->pin_base;
+ pin_bank->grange.pin_base = drvdata->ctrl->base
+ + pin_bank->pin_base;
pin_bank->grange.base = pin_bank->gpio_chip.base;
pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
pin_bank->grange.gc = &pin_bank->gpio_chip;
@@ -800,7 +892,19 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
return 0;
}
+static int samsung_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void samsung_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ pinctrl_free_gpio(chip->base + offset);
+}
+
static const struct gpio_chip samsung_gpiolib_chip = {
+ .request = samsung_gpio_request,
+ .free = samsung_gpio_free,
.set = samsung_gpio_set,
.get = samsung_gpio_get,
.direction_input = samsung_gpio_direction_input,
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index b3e41fa5798b..2b882320e8e9 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -156,13 +156,6 @@ struct samsung_pin_bank {
* @nr_banks: number of pin banks.
* @base: starting system wide pin number.
* @nr_pins: number of pins supported by the controller.
- * @geint_con: offset of the ext-gpio controller registers.
- * @geint_mask: offset of the ext-gpio interrupt mask registers.
- * @geint_pend: offset of the ext-gpio interrupt pending registers.
- * @weint_con: offset of the ext-wakeup controller registers.
- * @weint_mask: offset of the ext-wakeup interrupt mask registers.
- * @weint_pend: offset of the ext-wakeup interrupt pending registers.
- * @svc: offset of the interrupt service register.
* @eint_gpio_init: platform specific callback to setup the external gpio
* interrupts for the controller.
* @eint_wkup_init: platform specific callback to setup the external wakeup
@@ -176,16 +169,6 @@ struct samsung_pin_ctrl {
u32 base;
u32 nr_pins;
- u32 geint_con;
- u32 geint_mask;
- u32 geint_pend;
-
- u32 weint_con;
- u32 weint_mask;
- u32 weint_pend;
-
- u32 svc;
-
int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
void (*suspend)(struct samsung_pinctrl_drv_data *);
@@ -248,6 +231,7 @@ struct samsung_pmx_func {
const char *name;
const char **groups;
u8 num_groups;
+ u32 val;
};
/* list of all exported SoC specific data */
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index a9288ab01f7b..80f641ee4dea 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -409,11 +409,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
{
- int err;
- int ret;
-
- ret = gpiochip_remove(&pfc->gpio->gpio_chip);
- err = gpiochip_remove(&pfc->func->gpio_chip);
+ gpiochip_remove(&pfc->gpio->gpio_chip);
+ gpiochip_remove(&pfc->func->gpio_chip);
- return ret < 0 ? ret : err;
+ return 0;
}
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
index 2e688dc4a3c8..576d41b459e9 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
@@ -1726,6 +1726,133 @@ static const unsigned int audio_clkout_mux[] = {
AUDIO_CLKOUT_MARK,
};
+/* - CAN -------------------------------------------------------------------- */
+
+static const unsigned int can0_data_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 29),
+};
+
+static const unsigned int can0_data_mux[] = {
+ CAN0_TX_MARK, CAN0_RX_MARK,
+};
+
+static const unsigned int can0_data_b_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(7, 4), RCAR_GP_PIN(7, 3),
+};
+
+static const unsigned int can0_data_b_mux[] = {
+ CAN0_TX_B_MARK, CAN0_RX_B_MARK,
+};
+
+static const unsigned int can0_data_c_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 18),
+};
+
+static const unsigned int can0_data_c_mux[] = {
+ CAN0_TX_C_MARK, CAN0_RX_C_MARK,
+};
+
+static const unsigned int can0_data_d_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 27),
+};
+
+static const unsigned int can0_data_d_mux[] = {
+ CAN0_TX_D_MARK, CAN0_RX_D_MARK,
+};
+
+static const unsigned int can0_data_e_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 28),
+};
+
+static const unsigned int can0_data_e_mux[] = {
+ CAN0_TX_E_MARK, CAN0_RX_E_MARK,
+};
+
+static const unsigned int can0_data_f_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(6, 7), RCAR_GP_PIN(6, 6),
+};
+
+static const unsigned int can0_data_f_mux[] = {
+ CAN0_TX_F_MARK, CAN0_RX_F_MARK,
+};
+
+static const unsigned int can1_data_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 20),
+};
+
+static const unsigned int can1_data_mux[] = {
+ CAN1_TX_MARK, CAN1_RX_MARK,
+};
+
+static const unsigned int can1_data_b_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(7, 8), RCAR_GP_PIN(7, 9),
+};
+
+static const unsigned int can1_data_b_mux[] = {
+ CAN1_TX_B_MARK, CAN1_RX_B_MARK,
+};
+
+static const unsigned int can1_data_c_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(5, 20), RCAR_GP_PIN(5, 19),
+};
+
+static const unsigned int can1_data_c_mux[] = {
+ CAN1_TX_C_MARK, CAN1_RX_C_MARK,
+};
+
+static const unsigned int can1_data_d_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(4, 29), RCAR_GP_PIN(4, 31),
+};
+
+static const unsigned int can1_data_d_mux[] = {
+ CAN1_TX_D_MARK, CAN1_RX_D_MARK,
+};
+
+static const unsigned int can_clk_pins[] = {
+ /* CLK */
+ RCAR_GP_PIN(7, 2),
+};
+
+static const unsigned int can_clk_mux[] = {
+ CAN_CLK_MARK,
+};
+
+static const unsigned int can_clk_b_pins[] = {
+ /* CLK */
+ RCAR_GP_PIN(5, 21),
+};
+
+static const unsigned int can_clk_b_mux[] = {
+ CAN_CLK_B_MARK,
+};
+
+static const unsigned int can_clk_c_pins[] = {
+ /* CLK */
+ RCAR_GP_PIN(4, 30),
+};
+
+static const unsigned int can_clk_c_mux[] = {
+ CAN_CLK_C_MARK,
+};
+
+static const unsigned int can_clk_d_pins[] = {
+ /* CLK */
+ RCAR_GP_PIN(7, 19),
+};
+
+static const unsigned int can_clk_d_mux[] = {
+ CAN_CLK_D_MARK,
+};
/* - DU --------------------------------------------------------------------- */
static const unsigned int du_rgb666_pins[] = {
@@ -1867,6 +1994,192 @@ static const unsigned int eth_rmii_mux[] = {
ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_RX_ER_MARK, ETH_CRS_DV_MARK,
ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK, ETH_REFCLK_MARK,
};
+
+/* - HSCIF0 ----------------------------------------------------------------- */
+static const unsigned int hscif0_data_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(7, 3), RCAR_GP_PIN(7, 4),
+};
+static const unsigned int hscif0_data_mux[] = {
+ HRX0_MARK, HTX0_MARK,
+};
+static const unsigned int hscif0_clk_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(7, 2),
+};
+static const unsigned int hscif0_clk_mux[] = {
+ HSCK0_MARK,
+};
+static const unsigned int hscif0_ctrl_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(7, 1), RCAR_GP_PIN(7, 0),
+};
+static const unsigned int hscif0_ctrl_mux[] = {
+ HRTS0_N_MARK, HCTS0_N_MARK,
+};
+static const unsigned int hscif0_data_b_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 15),
+};
+static const unsigned int hscif0_data_b_mux[] = {
+ HRX0_B_MARK, HTX0_B_MARK,
+};
+static const unsigned int hscif0_ctrl_b_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 13),
+};
+static const unsigned int hscif0_ctrl_b_mux[] = {
+ HRTS0_N_B_MARK, HCTS0_N_B_MARK,
+};
+static const unsigned int hscif0_data_c_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
+};
+static const unsigned int hscif0_data_c_mux[] = {
+ HRX0_C_MARK, HTX0_C_MARK,
+};
+static const unsigned int hscif0_clk_c_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif0_clk_c_mux[] = {
+ HSCK0_C_MARK,
+};
+/* - HSCIF1 ----------------------------------------------------------------- */
+static const unsigned int hscif1_data_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(7, 5), RCAR_GP_PIN(7, 6),
+};
+static const unsigned int hscif1_data_mux[] = {
+ HRX1_MARK, HTX1_MARK,
+};
+static const unsigned int hscif1_clk_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(7, 7),
+};
+static const unsigned int hscif1_clk_mux[] = {
+ HSCK1_MARK,
+};
+static const unsigned int hscif1_ctrl_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(7, 9), RCAR_GP_PIN(7, 8),
+};
+static const unsigned int hscif1_ctrl_mux[] = {
+ HRTS1_N_MARK, HCTS1_N_MARK,
+};
+static const unsigned int hscif1_data_b_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 18),
+};
+static const unsigned int hscif1_data_b_mux[] = {
+ HRX1_B_MARK, HTX1_B_MARK,
+};
+static const unsigned int hscif1_data_c_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15),
+};
+static const unsigned int hscif1_data_c_mux[] = {
+ HRX1_C_MARK, HTX1_C_MARK,
+};
+static const unsigned int hscif1_clk_c_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(7, 16),
+};
+static const unsigned int hscif1_clk_c_mux[] = {
+ HSCK1_C_MARK,
+};
+static const unsigned int hscif1_ctrl_c_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(7, 18), RCAR_GP_PIN(7, 17),
+};
+static const unsigned int hscif1_ctrl_c_mux[] = {
+ HRTS1_N_C_MARK, HCTS1_N_C_MARK,
+};
+static const unsigned int hscif1_data_d_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 18),
+};
+static const unsigned int hscif1_data_d_mux[] = {
+ HRX1_D_MARK, HTX1_D_MARK,
+};
+static const unsigned int hscif1_data_e_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15),
+};
+static const unsigned int hscif1_data_e_mux[] = {
+ HRX1_C_MARK, HTX1_C_MARK,
+};
+static const unsigned int hscif1_clk_e_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(2, 6),
+};
+static const unsigned int hscif1_clk_e_mux[] = {
+ HSCK1_E_MARK,
+};
+static const unsigned int hscif1_ctrl_e_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 7),
+};
+static const unsigned int hscif1_ctrl_e_mux[] = {
+ HRTS1_N_E_MARK, HCTS1_N_E_MARK,
+};
+/* - HSCIF2 ----------------------------------------------------------------- */
+static const unsigned int hscif2_data_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 17),
+};
+static const unsigned int hscif2_data_mux[] = {
+ HRX2_MARK, HTX2_MARK,
+};
+static const unsigned int hscif2_clk_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(4, 15),
+};
+static const unsigned int hscif2_clk_mux[] = {
+ HSCK2_MARK,
+};
+static const unsigned int hscif2_ctrl_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13),
+};
+static const unsigned int hscif2_ctrl_mux[] = {
+ HRTS2_N_MARK, HCTS2_N_MARK,
+};
+static const unsigned int hscif2_data_b_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 22),
+};
+static const unsigned int hscif2_data_b_mux[] = {
+ HRX2_B_MARK, HTX2_B_MARK,
+};
+static const unsigned int hscif2_ctrl_b_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 21),
+};
+static const unsigned int hscif2_ctrl_b_mux[] = {
+ HRTS2_N_B_MARK, HCTS2_N_B_MARK,
+};
+static const unsigned int hscif2_data_c_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
+};
+static const unsigned int hscif2_data_c_mux[] = {
+ HRX2_C_MARK, HTX2_C_MARK,
+};
+static const unsigned int hscif2_clk_c_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif2_clk_c_mux[] = {
+ HSCK2_C_MARK,
+};
+static const unsigned int hscif2_data_d_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(1, 20), RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif2_data_d_mux[] = {
+ HRX2_B_MARK, HTX2_D_MARK,
+};
/* - I2C0 ------------------------------------------------------------------- */
static const unsigned int i2c0_pins[] = {
/* SCL, SDA */
@@ -3869,6 +4182,20 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(audio_clk_b_b),
SH_PFC_PIN_GROUP(audio_clk_c),
SH_PFC_PIN_GROUP(audio_clkout),
+ SH_PFC_PIN_GROUP(can0_data),
+ SH_PFC_PIN_GROUP(can0_data_b),
+ SH_PFC_PIN_GROUP(can0_data_c),
+ SH_PFC_PIN_GROUP(can0_data_d),
+ SH_PFC_PIN_GROUP(can0_data_e),
+ SH_PFC_PIN_GROUP(can0_data_f),
+ SH_PFC_PIN_GROUP(can1_data),
+ SH_PFC_PIN_GROUP(can1_data_b),
+ SH_PFC_PIN_GROUP(can1_data_c),
+ SH_PFC_PIN_GROUP(can1_data_d),
+ SH_PFC_PIN_GROUP(can_clk),
+ SH_PFC_PIN_GROUP(can_clk_b),
+ SH_PFC_PIN_GROUP(can_clk_c),
+ SH_PFC_PIN_GROUP(can_clk_d),
SH_PFC_PIN_GROUP(du_rgb666),
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
@@ -3885,6 +4212,32 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(eth_magic),
SH_PFC_PIN_GROUP(eth_mdio),
SH_PFC_PIN_GROUP(eth_rmii),
+ SH_PFC_PIN_GROUP(hscif0_data),
+ SH_PFC_PIN_GROUP(hscif0_clk),
+ SH_PFC_PIN_GROUP(hscif0_ctrl),
+ SH_PFC_PIN_GROUP(hscif0_data_b),
+ SH_PFC_PIN_GROUP(hscif0_ctrl_b),
+ SH_PFC_PIN_GROUP(hscif0_data_c),
+ SH_PFC_PIN_GROUP(hscif0_clk_c),
+ SH_PFC_PIN_GROUP(hscif1_data),
+ SH_PFC_PIN_GROUP(hscif1_clk),
+ SH_PFC_PIN_GROUP(hscif1_ctrl),
+ SH_PFC_PIN_GROUP(hscif1_data_b),
+ SH_PFC_PIN_GROUP(hscif1_data_c),
+ SH_PFC_PIN_GROUP(hscif1_clk_c),
+ SH_PFC_PIN_GROUP(hscif1_ctrl_c),
+ SH_PFC_PIN_GROUP(hscif1_data_d),
+ SH_PFC_PIN_GROUP(hscif1_data_e),
+ SH_PFC_PIN_GROUP(hscif1_clk_e),
+ SH_PFC_PIN_GROUP(hscif1_ctrl_e),
+ SH_PFC_PIN_GROUP(hscif2_data),
+ SH_PFC_PIN_GROUP(hscif2_clk),
+ SH_PFC_PIN_GROUP(hscif2_ctrl),
+ SH_PFC_PIN_GROUP(hscif2_data_b),
+ SH_PFC_PIN_GROUP(hscif2_ctrl_b),
+ SH_PFC_PIN_GROUP(hscif2_data_c),
+ SH_PFC_PIN_GROUP(hscif2_clk_c),
+ SH_PFC_PIN_GROUP(hscif2_data_d),
SH_PFC_PIN_GROUP(i2c0),
SH_PFC_PIN_GROUP(i2c0_b),
SH_PFC_PIN_GROUP(i2c0_c),
@@ -4155,6 +4508,30 @@ static const char * const audio_clk_groups[] = {
"audio_clkout",
};
+static const char * const can0_groups[] = {
+ "can0_data_a",
+ "can0_data_b",
+ "can0_data_c",
+ "can0_data_d",
+ "can0_data_e",
+ "can0_data_f",
+ "can_clk_a",
+ "can_clk_b",
+ "can_clk_c",
+ "can_clk_d",
+};
+
+static const char * const can1_groups[] = {
+ "can1_data_a",
+ "can1_data_b",
+ "can1_data_c",
+ "can1_data_d",
+ "can_clk_a",
+ "can_clk_b",
+ "can_clk_c",
+ "can_clk_d",
+};
+
static const char * const du_groups[] = {
"du_rgb666",
"du_rgb888",
@@ -4183,6 +4560,41 @@ static const char * const eth_groups[] = {
"eth_rmii",
};
+static const char * const hscif0_groups[] = {
+ "hscif0_data",
+ "hscif0_clk",
+ "hscif0_ctrl",
+ "hscif0_data_b",
+ "hscif0_ctrl_b",
+ "hscif0_data_c",
+ "hscif0_clk_c",
+};
+
+static const char * const hscif1_groups[] = {
+ "hscif1_data",
+ "hscif1_clk",
+ "hscif1_ctrl",
+ "hscif1_data_b",
+ "hscif1_data_c",
+ "hscif1_clk_c",
+ "hscif1_ctrl_c",
+ "hscif1_data_d",
+ "hscif1_data_e",
+ "hscif1_clk_e",
+ "hscif1_ctrl_e",
+};
+
+static const char * const hscif2_groups[] = {
+ "hscif2_data",
+ "hscif2_clk",
+ "hscif2_ctrl",
+ "hscif2_data_b",
+ "hscif2_ctrl_b",
+ "hscif2_data_c",
+ "hscif2_clk_c",
+ "hscif2_data_d",
+};
+
static const char * const i2c0_groups[] = {
"i2c0",
"i2c0_b",
@@ -4543,10 +4955,15 @@ static const char * const vin2_groups[] = {
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(audio_clk),
+ SH_PFC_FUNCTION(can0),
+ SH_PFC_FUNCTION(can1),
SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(du0),
SH_PFC_FUNCTION(du1),
SH_PFC_FUNCTION(eth),
+ SH_PFC_FUNCTION(hscif0),
+ SH_PFC_FUNCTION(hscif1),
+ SH_PFC_FUNCTION(hscif2),
SH_PFC_FUNCTION(i2c0),
SH_PFC_FUNCTION(i2c1),
SH_PFC_FUNCTION(i2c2),
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
index ee370de4609a..0bd8f4401b42 100644
--- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
+++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
@@ -3842,7 +3842,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
cfg.init_data = &sh73a0_vccq_mc0_init_data;
cfg.driver_data = pfc;
- data->vccq_mc0 = regulator_register(&sh73a0_vccq_mc0_desc, &cfg);
+ data->vccq_mc0 = devm_regulator_register(pfc->dev,
+ &sh73a0_vccq_mc0_desc, &cfg);
if (IS_ERR(data->vccq_mc0)) {
ret = PTR_ERR(data->vccq_mc0);
dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n",
@@ -3855,16 +3856,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
return 0;
}
-static void sh73a0_pinmux_soc_exit(struct sh_pfc *pfc)
-{
- struct sh73a0_pinmux_data *data = pfc->soc_data;
-
- regulator_unregister(data->vccq_mc0);
-}
-
static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
.init = sh73a0_pinmux_soc_init,
- .exit = sh73a0_pinmux_soc_exit,
.get_bias = sh73a0_pinmux_get_bias,
.set_bias = sh73a0_pinmux_set_bias,
};
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c
index e758af95c209..11db3ee39d40 100644
--- a/drivers/pinctrl/sh-pfc/pinctrl.c
+++ b/drivers/pinctrl/sh-pfc/pinctrl.c
@@ -345,27 +345,6 @@ done:
return ret;
}
-static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
- struct sh_pfc *pfc = pmx->pfc;
- const struct sh_pfc_pin_group *grp = &pfc->info->groups[group];
- unsigned long flags;
- unsigned int i;
-
- spin_lock_irqsave(&pfc->lock, flags);
-
- for (i = 0; i < grp->nr_pins; ++i) {
- int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
- struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
-
- cfg->type = PINMUX_TYPE_NONE;
- }
-
- spin_unlock_irqrestore(&pfc->lock, flags);
-}
-
static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -464,7 +443,6 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = {
.get_function_name = sh_pfc_get_function_name,
.get_function_groups = sh_pfc_get_function_groups,
.enable = sh_pfc_func_enable,
- .disable = sh_pfc_func_disable,
.gpio_request_enable = sh_pfc_gpio_request_enable,
.gpio_disable_free = sh_pfc_gpio_disable_free,
.gpio_set_direction = sh_pfc_gpio_set_direction,
diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c
index 014f5b1fee55..4c1d7c68666d 100644
--- a/drivers/pinctrl/sirf/pinctrl-sirf.c
+++ b/drivers/pinctrl/sirf/pinctrl-sirf.c
@@ -186,15 +186,6 @@ static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector,
return 0;
}
-static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector,
- unsigned group)
-{
- struct sirfsoc_pmx *spmx;
-
- spmx = pinctrl_dev_get_drvdata(pmxdev);
- sirfsoc_pinmux_endisable(spmx, selector, false);
-}
-
static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
{
return sirfsoc_pmxfunc_cnt;
@@ -240,7 +231,6 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
static struct pinmux_ops sirfsoc_pinmux_ops = {
.enable = sirfsoc_pinmux_enable,
- .disable = sirfsoc_pinmux_disable,
.get_functions_count = sirfsoc_pinmux_get_funcs_count,
.get_function_name = sirfsoc_pinmux_get_func_name,
.get_function_groups = sirfsoc_pinmux_get_groups,
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
index 04d93e602674..9ef18eb958e1 100644
--- a/drivers/pinctrl/spear/Kconfig
+++ b/drivers/pinctrl/spear/Kconfig
@@ -48,6 +48,7 @@ config PINCTRL_SPEAR1340
config PINCTRL_SPEAR_PLGPIO
bool "SPEAr SoC PLGPIO Controller"
depends on GPIOLIB && PINCTRL_SPEAR
+ select GPIOLIB_IRQCHIP
help
Say yes here to support PLGPIO controller on ST Microelectronics SPEAr
SoCs.
diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c
index ff2940e9f2a7..bddb79105d67 100644
--- a/drivers/pinctrl/spear/pinctrl-plgpio.c
+++ b/drivers/pinctrl/spear/pinctrl-plgpio.c
@@ -11,12 +11,11 @@
#include <linux/clk.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/irqchip/chained_irq.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
@@ -54,7 +53,6 @@ struct plgpio_regs {
*
* lock: lock for guarding gpio registers
* base: base address of plgpio block
- * irq_base: irq number of plgpio0
* chip: gpio framework specific chip information structure
* p2o: function ptr for pin to offset conversion. This is required only for
* machines where mapping b/w pin and offset is not 1-to-1.
@@ -68,8 +66,6 @@ struct plgpio {
spinlock_t lock;
void __iomem *base;
struct clk *clk;
- unsigned irq_base;
- struct irq_domain *irq_domain;
struct gpio_chip chip;
int (*p2o)(int pin); /* pin_to_offset */
int (*o2p)(int offset); /* offset_to_pin */
@@ -280,21 +276,12 @@ disable_clk:
pinctrl_free_gpio(gpio);
}
-static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
-
- if (IS_ERR_VALUE(plgpio->irq_base))
- return -EINVAL;
-
- return irq_find_mapping(plgpio->irq_domain, offset);
-}
-
/* PLGPIO IRQ */
static void plgpio_irq_disable(struct irq_data *d)
{
- struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - plgpio->irq_base;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+ int offset = d->hwirq;
unsigned long flags;
/* get correct offset for "offset" pin */
@@ -311,8 +298,9 @@ static void plgpio_irq_disable(struct irq_data *d)
static void plgpio_irq_enable(struct irq_data *d)
{
- struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - plgpio->irq_base;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+ int offset = d->hwirq;
unsigned long flags;
/* get correct offset for "offset" pin */
@@ -329,8 +317,9 @@ static void plgpio_irq_enable(struct irq_data *d)
static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
{
- struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - plgpio->irq_base;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+ int offset = d->hwirq;
void __iomem *reg_off;
unsigned int supported_type = 0, val;
@@ -369,7 +358,8 @@ static struct irq_chip plgpio_irqchip = {
static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct plgpio *plgpio = irq_get_handler_data(irq);
+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+ struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
struct irq_chip *irqchip = irq_desc_get_chip(desc);
int regs_count, count, pin, offset, i = 0;
unsigned long pending;
@@ -410,7 +400,8 @@ static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
/* get correct irq line number */
pin = i * MAX_GPIO_PER_REG + pin;
- generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin));
+ generic_handle_irq(
+ irq_find_mapping(gc->irqdomain, pin));
}
}
chained_irq_exit(irqchip, desc);
@@ -523,10 +514,9 @@ end:
}
static int plgpio_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
struct plgpio *plgpio;
struct resource *res;
- int ret, irq, i;
+ int ret, irq;
plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
if (!plgpio) {
@@ -563,7 +553,6 @@ static int plgpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, plgpio);
spin_lock_init(&plgpio->lock);
- plgpio->irq_base = -1;
plgpio->chip.base = -1;
plgpio->chip.request = plgpio_request;
plgpio->chip.free = plgpio_free;
@@ -571,10 +560,10 @@ static int plgpio_probe(struct platform_device *pdev)
plgpio->chip.direction_output = plgpio_direction_output;
plgpio->chip.get = plgpio_get_value;
plgpio->chip.set = plgpio_set_value;
- plgpio->chip.to_irq = plgpio_to_irq;
plgpio->chip.label = dev_name(&pdev->dev);
plgpio->chip.dev = &pdev->dev;
plgpio->chip.owner = THIS_MODULE;
+ plgpio->chip.of_node = pdev->dev.of_node;
if (!IS_ERR(plgpio->clk)) {
ret = clk_prepare(plgpio->clk);
@@ -592,43 +581,32 @@ static int plgpio_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_info(&pdev->dev, "irqs not supported\n");
- return 0;
- }
-
- plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0);
- if (IS_ERR_VALUE(plgpio->irq_base)) {
- /* we would not support irq for gpio */
- dev_warn(&pdev->dev, "couldn't allocate irq base\n");
+ dev_info(&pdev->dev, "PLGPIO registered without IRQs\n");
return 0;
}
- plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio,
- plgpio->irq_base, 0, &irq_domain_simple_ops, NULL);
- if (WARN_ON(!plgpio->irq_domain)) {
- dev_err(&pdev->dev, "irq domain init failed\n");
- irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio);
- ret = -ENXIO;
+ ret = gpiochip_irqchip_add(&plgpio->chip,
+ &plgpio_irqchip,
+ 0,
+ handle_simple_irq,
+ IRQ_TYPE_NONE);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n");
goto remove_gpiochip;
}
- irq_set_chained_handler(irq, plgpio_irq_handler);
- for (i = 0; i < plgpio->chip.ngpio; i++) {
- irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip,
- handle_simple_irq);
- set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
- irq_set_chip_data(i + plgpio->irq_base, plgpio);
- }
+ gpiochip_set_chained_irqchip(&plgpio->chip,
+ &plgpio_irqchip,
+ irq,
+ plgpio_irq_handler);
- irq_set_handler_data(irq, plgpio);
dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
return 0;
remove_gpiochip:
dev_info(&pdev->dev, "Remove gpiochip\n");
- if (gpiochip_remove(&plgpio->chip))
- dev_err(&pdev->dev, "unable to remove gpiochip\n");
+ gpiochip_remove(&plgpio->chip);
unprepare_clk:
if (!IS_ERR(plgpio->clk))
clk_unprepare(plgpio->clk);
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index 58bf6867aa17..f72cc4e192bd 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -274,12 +274,6 @@ static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
return spear_pinctrl_endisable(pctldev, function, group, true);
}
-static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
- unsigned function, unsigned group)
-{
- spear_pinctrl_endisable(pctldev, function, group, false);
-}
-
/* gpio with pinmux */
static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
unsigned pin)
@@ -345,7 +339,6 @@ static const struct pinmux_ops spear_pinmux_ops = {
.get_function_name = spear_pinctrl_get_func_name,
.get_function_groups = spear_pinctrl_get_func_groups,
.enable = spear_pinctrl_enable,
- .disable = spear_pinctrl_disable,
.gpio_request_enable = gpio_request_enable,
.gpio_disable_free = gpio_disable_free,
};
diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 73e0a305ea13..a5e10f777ed2 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -1,36 +1,42 @@
if ARCH_SUNXI
-config PINCTRL_SUNXI
- bool
-
config PINCTRL_SUNXI_COMMON
bool
select PINMUX
select GENERIC_PINCONF
config PINCTRL_SUN4I_A10
- def_bool PINCTRL_SUNXI || MACH_SUN4I
+ def_bool MACH_SUN4I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN5I_A10S
- def_bool PINCTRL_SUNXI || MACH_SUN5I
+ def_bool MACH_SUN5I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN5I_A13
- def_bool PINCTRL_SUNXI || MACH_SUN5I
+ def_bool MACH_SUN5I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN6I_A31
- def_bool PINCTRL_SUNXI || MACH_SUN6I
+ def_bool MACH_SUN6I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN6I_A31_R
- def_bool PINCTRL_SUNXI || MACH_SUN6I
+ def_bool MACH_SUN6I
depends on RESET_CONTROLLER
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN7I_A20
- def_bool PINCTRL_SUNXI || MACH_SUN7I
+ def_bool MACH_SUN7I
+ select PINCTRL_SUNXI_COMMON
+
+config PINCTRL_SUN8I_A23
+ def_bool MACH_SUN8I
+ select PINCTRL_SUNXI_COMMON
+
+config PINCTRL_SUN8I_A23_R
+ def_bool MACH_SUN8I
+ depends on RESET_CONTROLLER
select PINCTRL_SUNXI_COMMON
endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index 0f4461cbe11d..e797efb02901 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_PINCTRL_SUN5I_A13) += pinctrl-sun5i-a13.o
obj-$(CONFIG_PINCTRL_SUN6I_A31) += pinctrl-sun6i-a31.o
obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o
obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o
+obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o
+obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index fa1ff7c7e357..86b608bedca6 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -1010,6 +1010,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = {
.pins = sun4i_a10_pins,
.npins = ARRAY_SIZE(sun4i_a10_pins),
+ .irq_banks = 1,
};
static int sun4i_a10_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
index 164d743f526c..2fa7430cabaf 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
@@ -661,6 +661,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = {
static const struct sunxi_pinctrl_desc sun5i_a10s_pinctrl_data = {
.pins = sun5i_a10s_pins,
.npins = ARRAY_SIZE(sun5i_a10s_pins),
+ .irq_banks = 1,
};
static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c
index 1188a2b7b988..e47c33dbae3a 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c
@@ -330,15 +330,12 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
- SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 0)), /* EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
- SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 1)), /* EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
- SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 2)), /* EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -382,6 +379,7 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
.pins = sun5i_a13_pins,
.npins = ARRAY_SIZE(sun5i_a13_pins),
+ .irq_banks = 1,
};
static int sun5i_a13_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c
index 8fcba48e0a42..9a2517b65113 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c
@@ -93,6 +93,7 @@ static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = {
.pins = sun6i_a31_r_pins,
.npins = ARRAY_SIZE(sun6i_a31_r_pins),
.pin_base = PL_BASE,
+ .irq_banks = 2,
};
static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c
index 8dea5856458b..a2b4b85c5ad5 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c
@@ -24,208 +24,244 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D0 */
- SUNXI_FUNCTION(0x4, "uart1")), /* DTR */
+ SUNXI_FUNCTION(0x4, "uart1"), /* DTR */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD1 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D1 */
- SUNXI_FUNCTION(0x4, "uart1")), /* DSR */
+ SUNXI_FUNCTION(0x4, "uart1"), /* DSR */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D2 */
- SUNXI_FUNCTION(0x4, "uart1")), /* DCD */
+ SUNXI_FUNCTION(0x4, "uart1"), /* DCD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D3 */
- SUNXI_FUNCTION(0x4, "uart1")), /* RING */
+ SUNXI_FUNCTION(0x4, "uart1"), /* RING */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD4 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D4 */
- SUNXI_FUNCTION(0x4, "uart1")), /* TX */
+ SUNXI_FUNCTION(0x4, "uart1"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD5 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D5 */
- SUNXI_FUNCTION(0x4, "uart1")), /* RX */
+ SUNXI_FUNCTION(0x4, "uart1"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD6 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D6 */
- SUNXI_FUNCTION(0x4, "uart1")), /* RTS */
+ SUNXI_FUNCTION(0x4, "uart1"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD7 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D7 */
- SUNXI_FUNCTION(0x4, "uart1")), /* CTS */
+ SUNXI_FUNCTION(0x4, "uart1"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXCLK */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D8 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D8 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */
SUNXI_FUNCTION(0x3, "lcd1"), /* D9 */
SUNXI_FUNCTION(0x4, "mmc3"), /* CMD */
- SUNXI_FUNCTION(0x5, "mmc2")), /* CMD */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* CMD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* GTXCLK */
SUNXI_FUNCTION(0x3, "lcd1"), /* D10 */
SUNXI_FUNCTION(0x4, "mmc3"), /* CLK */
- SUNXI_FUNCTION(0x5, "mmc2")), /* CLK */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D11 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D0 */
- SUNXI_FUNCTION(0x5, "mmc2")), /* D0 */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D12 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D1 */
- SUNXI_FUNCTION(0x5, "mmc2")), /* D1 */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D13 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D2 */
- SUNXI_FUNCTION(0x5, "mmc2")), /* D2 */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D14 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D3 */
- SUNXI_FUNCTION(0x5, "mmc2")), /* D3 */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD4 */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D15 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D15 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD5 */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D16 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D16 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD6 */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D17 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D17 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD7 */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D18 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D18 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 18)), /* PA_EINT18 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 19),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXDV */
SUNXI_FUNCTION(0x3, "lcd1"), /* D19 */
- SUNXI_FUNCTION(0x4, "pwm3")), /* Positive */
+ SUNXI_FUNCTION(0x4, "pwm3"), /* Positive */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 19)), /* PA_EINT19 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 20),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXCLK */
SUNXI_FUNCTION(0x3, "lcd1"), /* D20 */
- SUNXI_FUNCTION(0x4, "pwm3")), /* Negative */
+ SUNXI_FUNCTION(0x4, "pwm3"), /* Negative */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 20)), /* PA_EINT20 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 21),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXERR */
SUNXI_FUNCTION(0x3, "lcd1"), /* D21 */
- SUNXI_FUNCTION(0x4, "spi3")), /* CS0 */
+ SUNXI_FUNCTION(0x4, "spi3"), /* CS0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 21)), /* PA_EINT21 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 22),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */
SUNXI_FUNCTION(0x3, "lcd1"), /* D22 */
- SUNXI_FUNCTION(0x4, "spi3")), /* CLK */
+ SUNXI_FUNCTION(0x4, "spi3"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 22)), /* PA_EINT22 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 23),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* COL */
SUNXI_FUNCTION(0x3, "lcd1"), /* D23 */
- SUNXI_FUNCTION(0x4, "spi3")), /* MOSI */
+ SUNXI_FUNCTION(0x4, "spi3"), /* MOSI */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 23)), /* PA_EINT23 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 24),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* CRS */
SUNXI_FUNCTION(0x3, "lcd1"), /* CLK */
- SUNXI_FUNCTION(0x4, "spi3")), /* MISO */
+ SUNXI_FUNCTION(0x4, "spi3"), /* MISO */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 24)), /* PA_EINT24 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 25),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* CLKIN */
SUNXI_FUNCTION(0x3, "lcd1"), /* DE */
- SUNXI_FUNCTION(0x4, "spi3")), /* CS1 */
+ SUNXI_FUNCTION(0x4, "spi3"), /* CS1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 25)), /* PA_EINT25 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 26),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* MDC */
- SUNXI_FUNCTION(0x3, "lcd1")), /* HSYNC */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* HSYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 26)), /* PA_EINT26 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 27),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* MDIO */
- SUNXI_FUNCTION(0x3, "lcd1")), /* VSYNC */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* VSYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 27)), /* PA_EINT27 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* MCLK */
SUNXI_FUNCTION(0x3, "uart3"), /* CTS */
- SUNXI_FUNCTION(0x4, "csi")), /* MCLK1 */
+ SUNXI_FUNCTION(0x4, "csi"), /* MCLK1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)), /* PB_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "i2s0")), /* BCLK */
+ SUNXI_FUNCTION(0x2, "i2s0"), /* BCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)), /* PB_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "i2s0")), /* LRCK */
+ SUNXI_FUNCTION(0x2, "i2s0"), /* LRCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)), /* PB_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "i2s0")), /* DO0 */
+ SUNXI_FUNCTION(0x2, "i2s0"), /* DO0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)), /* PB_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO1 */
- SUNXI_FUNCTION(0x3, "uart3")), /* RTS */
+ SUNXI_FUNCTION(0x3, "uart3"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)), /* PB_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO2 */
SUNXI_FUNCTION(0x3, "uart3"), /* TX */
- SUNXI_FUNCTION(0x4, "i2c3")), /* SCK */
+ SUNXI_FUNCTION(0x4, "i2c3"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PB_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO3 */
SUNXI_FUNCTION(0x3, "uart3"), /* RX */
- SUNXI_FUNCTION(0x4, "i2c3")), /* SDA */
+ SUNXI_FUNCTION(0x4, "i2c3"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PB_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x3, "i2s0")), /* DI */
+ SUNXI_FUNCTION(0x3, "i2s0"), /* DI */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)), /* PB_EINT7 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -510,86 +546,103 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* PCLK */
- SUNXI_FUNCTION(0x3, "ts")), /* CLK */
+ SUNXI_FUNCTION(0x3, "ts"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PE_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* MCLK */
- SUNXI_FUNCTION(0x3, "ts")), /* ERR */
+ SUNXI_FUNCTION(0x3, "ts"), /* ERR */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PE_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */
- SUNXI_FUNCTION(0x3, "ts")), /* SYNC */
+ SUNXI_FUNCTION(0x3, "ts"), /* SYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PE_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */
- SUNXI_FUNCTION(0x3, "ts")), /* DVLD */
+ SUNXI_FUNCTION(0x3, "ts"), /* DVLD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PE_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D0 */
- SUNXI_FUNCTION(0x3, "uart5")), /* TX */
+ SUNXI_FUNCTION(0x3, "uart5"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PE_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D1 */
- SUNXI_FUNCTION(0x3, "uart5")), /* RX */
+ SUNXI_FUNCTION(0x3, "uart5"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PE_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D2 */
- SUNXI_FUNCTION(0x3, "uart5")), /* RTS */
+ SUNXI_FUNCTION(0x3, "uart5"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PE_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D3 */
- SUNXI_FUNCTION(0x3, "uart5")), /* CTS */
+ SUNXI_FUNCTION(0x3, "uart5"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PE_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D4 */
- SUNXI_FUNCTION(0x3, "ts")), /* D0 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PE_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D5 */
- SUNXI_FUNCTION(0x3, "ts")), /* D1 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PE_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D6 */
- SUNXI_FUNCTION(0x3, "ts")), /* D2 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PE_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D7 */
- SUNXI_FUNCTION(0x3, "ts")), /* D3 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PE_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D8 */
- SUNXI_FUNCTION(0x3, "ts")), /* D4 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D4 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PE_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D9 */
- SUNXI_FUNCTION(0x3, "ts")), /* D5 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D5 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PE_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D10 */
- SUNXI_FUNCTION(0x3, "ts")), /* D6 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D6 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PE_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D11 */
- SUNXI_FUNCTION(0x3, "ts")), /* D7 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D7 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PE_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "csi")), /* MIPI CSI MCLK */
+ SUNXI_FUNCTION(0x2, "csi"), /* MIPI CSI MCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PE_EINT16 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -625,86 +678,105 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* CLK */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)), /* PG_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* CMD */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)), /* PG_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* D0 */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)), /* PG_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* D1 */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)), /* PG_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* D2 */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)), /* PG_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* D3 */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)), /* PG_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart2")), /* TX */
+ SUNXI_FUNCTION(0x2, "uart2"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)), /* PG_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart2")), /* RX */
+ SUNXI_FUNCTION(0x2, "uart2"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)), /* PG_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart2")), /* RTS */
+ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PG_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart2")), /* CTS */
+ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PG_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c3"), /* SCK */
- SUNXI_FUNCTION(0x3, "usb")), /* DP3 */
+ SUNXI_FUNCTION(0x3, "usb"), /* DP3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 10)), /* PG_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c3"), /* SDA */
- SUNXI_FUNCTION(0x3, "usb")), /* DM3 */
+ SUNXI_FUNCTION(0x3, "usb"), /* DM3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 11)), /* PG_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CS1 */
- SUNXI_FUNCTION(0x3, "i2s1")), /* MCLK */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* MCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 12)), /* PG_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */
- SUNXI_FUNCTION(0x3, "i2s1")), /* BCLK */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* BCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 13)), /* PG_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CLK */
- SUNXI_FUNCTION(0x3, "i2s1")), /* LRCK */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* LRCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 14)), /* PG_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */
- SUNXI_FUNCTION(0x3, "i2s1")), /* DIN */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* DIN */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 15)), /* PG_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* MISO */
- SUNXI_FUNCTION(0x3, "i2s1")), /* DOUT */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* DOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 16)), /* PG_EINT16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart4")), /* TX */
+ SUNXI_FUNCTION(0x2, "uart4"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 17)), /* PG_EINT17 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart4")), /* RX */
+ SUNXI_FUNCTION(0x2, "uart4"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 18)), /* PG_EINT18 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -836,6 +908,7 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
static const struct sunxi_pinctrl_desc sun6i_a31_pinctrl_data = {
.pins = sun6i_a31_pins,
.npins = ARRAY_SIZE(sun6i_a31_pins),
+ .irq_banks = 4,
};
static int sun6i_a31_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c
index d8577ce5f1a4..dac99e02bfdb 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c
@@ -1036,6 +1036,7 @@ static const struct sunxi_desc_pin sun7i_a20_pins[] = {
static const struct sunxi_pinctrl_desc sun7i_a20_pinctrl_data = {
.pins = sun7i_a20_pins,
.npins = ARRAY_SIZE(sun7i_a20_pins),
+ .irq_banks = 1,
};
static int sun7i_a20_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
new file mode 100644
index 000000000000..90f3b3a7c51e
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
@@ -0,0 +1,142 @@
+/*
+ * Allwinner A23 SoCs special pins pinctrl driver.
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * Copyright (C) 2014 Boris Brezillon
+ * Boris Brezillon <boris.brezillon@free-electrons.com>
+ *
+ * Copyright (C) 2014 Maxime Ripard
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/reset.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun8i_a23_r_pins[] = {
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */
+ SUNXI_FUNCTION(0x3, "s_twi"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)), /* PL_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */
+ SUNXI_FUNCTION(0x3, "s_twi"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)), /* PL_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_uart"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)), /* PL_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_uart"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)), /* PL_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* MS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)), /* PL_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* CK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)), /* PL_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* DO */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)), /* PL_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* DI */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)), /* PL_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_twi"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 8)), /* PL_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_twi"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 9)), /* PL_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_pwm"),
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 10)), /* PL_EINT10 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 11)), /* PL_EINT11 */
+};
+
+static const struct sunxi_pinctrl_desc sun8i_a23_r_pinctrl_data = {
+ .pins = sun8i_a23_r_pins,
+ .npins = ARRAY_SIZE(sun8i_a23_r_pins),
+ .pin_base = PL_BASE,
+ .irq_banks = 1,
+};
+
+static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev)
+{
+ struct reset_control *rstc;
+ int ret;
+
+ rstc = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(rstc)) {
+ dev_err(&pdev->dev, "Reset controller missing\n");
+ return PTR_ERR(rstc);
+ }
+
+ ret = reset_control_deassert(rstc);
+ if (ret)
+ return ret;
+
+ ret = sunxi_pinctrl_init(pdev,
+ &sun8i_a23_r_pinctrl_data);
+
+ if (ret)
+ reset_control_assert(rstc);
+
+ return ret;
+}
+
+static struct of_device_id sun8i_a23_r_pinctrl_match[] = {
+ { .compatible = "allwinner,sun8i-a23-r-pinctrl", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sun8i_a23_r_pinctrl_match);
+
+static struct platform_driver sun8i_a23_r_pinctrl_driver = {
+ .probe = sun8i_a23_r_pinctrl_probe,
+ .driver = {
+ .name = "sun8i-a23-r-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = sun8i_a23_r_pinctrl_match,
+ },
+};
+module_platform_driver(sun8i_a23_r_pinctrl_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
+MODULE_DESCRIPTION("Allwinner A23 R_PIO pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
new file mode 100644
index 000000000000..ac71e8c5901b
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
@@ -0,0 +1,593 @@
+/*
+ * Allwinner A23 SoCs pinctrl driver.
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * Copyright (C) 2014 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun8i_a23_pins[] = {
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* CS */
+ SUNXI_FUNCTION(0x3, "jtag"), /* MS0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)), /* PA_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* CLK */
+ SUNXI_FUNCTION(0x3, "jtag"), /* CKO */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)), /* PA_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */
+ SUNXI_FUNCTION(0x3, "jtag"), /* DOO */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)), /* PA_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* MISO */
+ SUNXI_FUNCTION(0x3, "jtag"), /* DIO */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)), /* PA_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart4"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)), /* PA_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart4"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)), /* PA_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart4"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)), /* PA_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart4"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)), /* PA_EINT7 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 0)), /* PB_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 1)), /* PB_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 2)), /* PB_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 3)), /* PB_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* SYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 4)), /* PB_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* DOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 5)), /* PB_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* DIN */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 6)), /* PB_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "i2s0"), /* DI */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 7)), /* PB_EINT7 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* WE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* ALE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* MISO */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* CLE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* CE1 */
+ SUNXI_FUNCTION(0x3, "spi0")), /* CS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* RE */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* RB1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQS */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* CE2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* CE3 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* CMD */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* D2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* D3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */
+ SUNXI_FUNCTION(0x3, "uart3")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */
+ SUNXI_FUNCTION(0x3, "uart3")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */
+ SUNXI_FUNCTION(0x3, "uart1")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */
+ SUNXI_FUNCTION(0x3, "uart1")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */
+ SUNXI_FUNCTION(0x3, "uart1")), /* RTS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */
+ SUNXI_FUNCTION(0x3, "uart1")), /* CTS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */
+ SUNXI_FUNCTION(0x3, "i2s1")), /* SYNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */
+ SUNXI_FUNCTION(0x3, "i2s1")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */
+ SUNXI_FUNCTION(0x3, "i2s1")), /* DOUT */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */
+ SUNXI_FUNCTION(0x3, "i2s1")), /* DIN */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D20 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D21 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D22 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D23 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* CLK */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* DE */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* HSYNC */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* VSYNC */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VN3 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* PCLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* MCLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* HSYNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* VSYNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* SCK */
+ SUNXI_FUNCTION(0x3, "i2c2")), /* SCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* SDA */
+ SUNXI_FUNCTION(0x3, "i2c2")), /* SDA */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* MS1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* DI1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */
+ SUNXI_FUNCTION(0x3, "uart0")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */
+ SUNXI_FUNCTION(0x3, "jtag")), /* DO1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */
+ SUNXI_FUNCTION(0x3, "uart0")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* CK1 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 0)), /* PG_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 1)), /* PG_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 2)), /* PG_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 3)), /* PG_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 4)), /* PG_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 5)), /* PG_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 6)), /* PG_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 7)), /* PG_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 8)), /* PG_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 9)), /* PG_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* SYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 10)), /* PG_EINT10 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 11)), /* PG_EINT11 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* DOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 12)), /* PG_EINT12 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* DIN */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 13)), /* PG_EINT13 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "pwm0")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "pwm1")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi0"), /* CS */
+ SUNXI_FUNCTION(0x3, "uart3")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi0"), /* CLK */
+ SUNXI_FUNCTION(0x3, "uart3")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi0"), /* DOUT */
+ SUNXI_FUNCTION(0x3, "uart3")), /* RTS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi0"), /* DIN */
+ SUNXI_FUNCTION(0x3, "uart3")), /* CTS */
+};
+
+static const struct sunxi_pinctrl_desc sun8i_a23_pinctrl_data = {
+ .pins = sun8i_a23_pins,
+ .npins = ARRAY_SIZE(sun8i_a23_pins),
+ .irq_banks = 3,
+};
+
+static int sun8i_a23_pinctrl_probe(struct platform_device *pdev)
+{
+ return sunxi_pinctrl_init(pdev,
+ &sun8i_a23_pinctrl_data);
+}
+
+static struct of_device_id sun8i_a23_pinctrl_match[] = {
+ { .compatible = "allwinner,sun8i-a23-pinctrl", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sun8i_a23_pinctrl_match);
+
+static struct platform_driver sun8i_a23_pinctrl_driver = {
+ .probe = sun8i_a23_pinctrl_probe,
+ .driver = {
+ .name = "sun8i-a23-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = sun8i_a23_pinctrl_match,
+ },
+};
+module_platform_driver(sun8i_a23_pinctrl_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
+MODULE_DESCRIPTION("Allwinner A23 pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 5f38c7f67834..3df66e366c87 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -31,6 +31,9 @@
#include "../core.h"
#include "pinctrl-sunxi.h"
+static struct irq_chip sunxi_pinctrl_edge_irq_chip;
+static struct irq_chip sunxi_pinctrl_level_irq_chip;
+
static struct sunxi_pinctrl_group *
sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
{
@@ -508,7 +511,7 @@ static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
base = PINS_PER_BANK * gpiospec->args[0];
pin = base + gpiospec->args[1];
- if (pin > (gc->base + gc->ngpio))
+ if (pin > gc->ngpio)
return -EINVAL;
if (flags)
@@ -521,25 +524,61 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
struct sunxi_desc_function *desc;
+ unsigned pinnum = pctl->desc->pin_base + offset;
+ unsigned irqnum;
if (offset >= chip->ngpio)
return -ENXIO;
- desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq");
+ desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pinnum, "irq");
if (!desc)
return -EINVAL;
+ irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum;
+
dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
- chip->label, offset + chip->base, desc->irqnum);
+ chip->label, offset + chip->base, irqnum);
- return irq_find_mapping(pctl->domain, desc->irqnum);
+ return irq_find_mapping(pctl->domain, irqnum);
}
+static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
+{
+ struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+ struct sunxi_desc_function *func;
+ int ret;
+
+ func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
+ pctl->irq_array[d->hwirq], "irq");
+ if (!func)
+ return -EINVAL;
+
+ ret = gpio_lock_as_irq(pctl->chip,
+ pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
+ if (ret) {
+ dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
+ irqd_to_hwirq(d));
+ return ret;
+ }
+
+ /* Change muxing to INT mode */
+ sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
-static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
- unsigned int type)
+ return 0;
+}
+
+static void sunxi_pinctrl_irq_release_resources(struct irq_data *d)
+{
+ struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+
+ gpio_unlock_as_irq(pctl->chip,
+ pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
+}
+
+static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
{
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+ struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
u32 reg = sunxi_irq_cfg_reg(d->hwirq);
u8 index = sunxi_irq_cfg_offset(d->hwirq);
unsigned long flags;
@@ -566,6 +605,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
return -EINVAL;
}
+ if (type & IRQ_TYPE_LEVEL_MASK) {
+ d->chip = &sunxi_pinctrl_level_irq_chip;
+ desc->handle_irq = handle_fasteoi_irq;
+ } else {
+ d->chip = &sunxi_pinctrl_edge_irq_chip;
+ desc->handle_irq = handle_edge_irq;
+ }
+
spin_lock_irqsave(&pctl->lock, flags);
regval = readl(pctl->membase + reg);
@@ -577,26 +624,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
return 0;
}
-static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d)
+static void sunxi_pinctrl_irq_ack(struct irq_data *d)
{
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- u32 ctrl_reg = sunxi_irq_ctrl_reg(d->hwirq);
- u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq);
u32 status_reg = sunxi_irq_status_reg(d->hwirq);
u8 status_idx = sunxi_irq_status_offset(d->hwirq);
- unsigned long flags;
- u32 val;
-
- spin_lock_irqsave(&pctl->lock, flags);
-
- /* Mask the IRQ */
- val = readl(pctl->membase + ctrl_reg);
- writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg);
/* Clear the IRQ */
writel(1 << status_idx, pctl->membase + status_reg);
-
- spin_unlock_irqrestore(&pctl->lock, flags);
}
static void sunxi_pinctrl_irq_mask(struct irq_data *d)
@@ -619,19 +654,11 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d)
static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
{
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- struct sunxi_desc_function *func;
u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
unsigned long flags;
u32 val;
- func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
- pctl->irq_array[d->hwirq],
- "irq");
-
- /* Change muxing to INT mode */
- sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
-
spin_lock_irqsave(&pctl->lock, flags);
/* Unmask the IRQ */
@@ -641,28 +668,60 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
spin_unlock_irqrestore(&pctl->lock, flags);
}
-static struct irq_chip sunxi_pinctrl_irq_chip = {
+static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
+{
+ sunxi_pinctrl_irq_ack(d);
+ sunxi_pinctrl_irq_unmask(d);
+}
+
+static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
+ .irq_ack = sunxi_pinctrl_irq_ack,
+ .irq_mask = sunxi_pinctrl_irq_mask,
+ .irq_unmask = sunxi_pinctrl_irq_unmask,
+ .irq_request_resources = sunxi_pinctrl_irq_request_resources,
+ .irq_release_resources = sunxi_pinctrl_irq_release_resources,
+ .irq_set_type = sunxi_pinctrl_irq_set_type,
+ .flags = IRQCHIP_SKIP_SET_WAKE,
+};
+
+static struct irq_chip sunxi_pinctrl_level_irq_chip = {
+ .irq_eoi = sunxi_pinctrl_irq_ack,
.irq_mask = sunxi_pinctrl_irq_mask,
- .irq_mask_ack = sunxi_pinctrl_irq_mask_ack,
.irq_unmask = sunxi_pinctrl_irq_unmask,
+ /* Define irq_enable / disable to avoid spurious irqs for drivers
+ * using these to suppress irqs while they clear the irq source */
+ .irq_enable = sunxi_pinctrl_irq_ack_unmask,
+ .irq_disable = sunxi_pinctrl_irq_mask,
+ .irq_request_resources = sunxi_pinctrl_irq_request_resources,
+ .irq_release_resources = sunxi_pinctrl_irq_release_resources,
.irq_set_type = sunxi_pinctrl_irq_set_type,
+ .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED |
+ IRQCHIP_EOI_IF_HANDLED,
};
static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct irq_chip *chip = irq_get_chip(irq);
struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
- const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
+ unsigned long bank, reg, val;
+
+ for (bank = 0; bank < pctl->desc->irq_banks; bank++)
+ if (irq == pctl->irq[bank])
+ break;
+
+ if (bank == pctl->desc->irq_banks)
+ return;
- /* Clear all interrupts */
- writel(reg, pctl->membase + IRQ_STATUS_REG);
+ reg = sunxi_irq_status_reg_from_bank(bank);
+ val = readl(pctl->membase + reg);
- if (reg) {
+ if (val) {
int irqoffset;
chained_irq_enter(chip, desc);
- for_each_set_bit(irqoffset, &reg, SUNXI_IRQ_NUMBER) {
- int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
+ for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
+ int pin_irq = irq_find_mapping(pctl->domain,
+ bank * IRQ_PER_BANK + irqoffset);
generic_handle_irq(pin_irq);
}
chained_irq_exit(chip, desc);
@@ -730,8 +789,11 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
while (func->name) {
/* Create interrupt mapping while we're at it */
- if (!strcmp(func->name, "irq"))
- pctl->irq_array[func->irqnum] = pin->pin.number;
+ if (!strcmp(func->name, "irq")) {
+ int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK;
+ pctl->irq_array[irqnum] = pin->pin.number;
+ }
+
sunxi_pinctrl_add_function(pctl, func->name);
func++;
}
@@ -801,6 +863,13 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
pctl->dev = &pdev->dev;
pctl->desc = desc;
+ pctl->irq_array = devm_kcalloc(&pdev->dev,
+ IRQ_PER_BANK * pctl->desc->irq_banks,
+ sizeof(*pctl->irq_array),
+ GFP_KERNEL);
+ if (!pctl->irq_array)
+ return -ENOMEM;
+
ret = sunxi_pinctrl_build_state(pdev);
if (ret) {
dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
@@ -869,7 +938,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
- pin->pin.number,
+ pin->pin.number - pctl->desc->pin_base,
pin->pin.number, 1);
if (ret)
goto gpiochip_error;
@@ -885,30 +954,51 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
if (ret)
goto gpiochip_error;
- pctl->irq = irq_of_parse_and_map(node, 0);
+ pctl->irq = devm_kcalloc(&pdev->dev,
+ pctl->desc->irq_banks,
+ sizeof(*pctl->irq),
+ GFP_KERNEL);
if (!pctl->irq) {
- ret = -EINVAL;
+ ret = -ENOMEM;
goto clk_error;
}
- pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER,
- &irq_domain_simple_ops, NULL);
+ for (i = 0; i < pctl->desc->irq_banks; i++) {
+ pctl->irq[i] = platform_get_irq(pdev, i);
+ if (pctl->irq[i] < 0) {
+ ret = pctl->irq[i];
+ goto clk_error;
+ }
+ }
+
+ pctl->domain = irq_domain_add_linear(node,
+ pctl->desc->irq_banks * IRQ_PER_BANK,
+ &irq_domain_simple_ops,
+ NULL);
if (!pctl->domain) {
dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
ret = -ENOMEM;
goto clk_error;
}
- for (i = 0; i < SUNXI_IRQ_NUMBER; i++) {
+ for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
int irqno = irq_create_mapping(pctl->domain, i);
- irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip,
- handle_simple_irq);
+ irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
+ handle_edge_irq);
irq_set_chip_data(irqno, pctl);
};
- irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler);
- irq_set_handler_data(pctl->irq, pctl);
+ for (i = 0; i < pctl->desc->irq_banks; i++) {
+ /* Mask and clear all IRQs before registering a handler */
+ writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i));
+ writel(0xffffffff,
+ pctl->membase + sunxi_irq_status_reg_from_bank(i));
+
+ irq_set_chained_handler(pctl->irq[i],
+ sunxi_pinctrl_irq_handler);
+ irq_set_handler_data(pctl->irq[i], pctl);
+ }
dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
@@ -917,8 +1007,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
clk_error:
clk_disable_unprepare(clk);
gpiochip_error:
- if (gpiochip_remove(pctl->chip))
- dev_err(&pdev->dev, "failed to remove gpio chip\n");
+ gpiochip_remove(pctl->chip);
pinctrl_error:
pinctrl_unregister(pctl->pctl_dev);
return ret;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index 8169ba598876..4245b96c7996 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -53,7 +53,7 @@
#define PULL_PINS_BITS 2
#define PULL_PINS_MASK 0x03
-#define SUNXI_IRQ_NUMBER 32
+#define IRQ_PER_BANK 32
#define IRQ_CFG_REG 0x200
#define IRQ_CFG_IRQ_PER_REG 8
@@ -68,6 +68,8 @@
#define IRQ_STATUS_IRQ_BITS 1
#define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
+#define IRQ_MEM_SIZE 0x20
+
#define IRQ_EDGE_RISING 0x00
#define IRQ_EDGE_FALLING 0x01
#define IRQ_LEVEL_HIGH 0x02
@@ -77,6 +79,7 @@
struct sunxi_desc_function {
const char *name;
u8 muxval;
+ u8 irqbank;
u8 irqnum;
};
@@ -89,6 +92,7 @@ struct sunxi_pinctrl_desc {
const struct sunxi_desc_pin *pins;
int npins;
unsigned pin_base;
+ unsigned irq_banks;
};
struct sunxi_pinctrl_function {
@@ -113,8 +117,8 @@ struct sunxi_pinctrl {
unsigned nfunctions;
struct sunxi_pinctrl_group *groups;
unsigned ngroups;
- int irq;
- int irq_array[SUNXI_IRQ_NUMBER];
+ int *irq;
+ unsigned *irq_array;
spinlock_t lock;
struct pinctrl_dev *pctl_dev;
};
@@ -139,6 +143,14 @@ struct sunxi_pinctrl {
.irqnum = _irq, \
}
+#define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq) \
+ { \
+ .name = "irq", \
+ .muxval = _val, \
+ .irqbank = _bank, \
+ .irqnum = _irq, \
+ }
+
/*
* The sunXi PIO registers are organized as is:
* 0x00 - 0x0c Muxing values.
@@ -218,8 +230,10 @@ static inline u32 sunxi_pull_offset(u16 pin)
static inline u32 sunxi_irq_cfg_reg(u16 irq)
{
- u8 reg = irq / IRQ_CFG_IRQ_PER_REG * 0x04;
- return reg + IRQ_CFG_REG;
+ u8 bank = irq / IRQ_PER_BANK;
+ u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
+
+ return IRQ_CFG_REG + bank * IRQ_MEM_SIZE + reg;
}
static inline u32 sunxi_irq_cfg_offset(u16 irq)
@@ -228,10 +242,16 @@ static inline u32 sunxi_irq_cfg_offset(u16 irq)
return irq_num * IRQ_CFG_IRQ_BITS;
}
+static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank)
+{
+ return IRQ_CTRL_REG + bank * IRQ_MEM_SIZE;
+}
+
static inline u32 sunxi_irq_ctrl_reg(u16 irq)
{
- u8 reg = irq / IRQ_CTRL_IRQ_PER_REG * 0x04;
- return reg + IRQ_CTRL_REG;
+ u8 bank = irq / IRQ_PER_BANK;
+
+ return sunxi_irq_ctrl_reg_from_bank(bank);
}
static inline u32 sunxi_irq_ctrl_offset(u16 irq)
@@ -240,10 +260,16 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq)
return irq_num * IRQ_CTRL_IRQ_BITS;
}
+static inline u32 sunxi_irq_status_reg_from_bank(u8 bank)
+{
+ return IRQ_STATUS_REG + bank * IRQ_MEM_SIZE;
+}
+
static inline u32 sunxi_irq_status_reg(u16 irq)
{
- u8 reg = irq / IRQ_STATUS_IRQ_PER_REG * 0x04;
- return reg + IRQ_STATUS_REG;
+ u8 bank = irq / IRQ_PER_BANK;
+
+ return sunxi_irq_status_reg_from_bank(bank);
}
static inline u32 sunxi_irq_status_offset(u16 irq)
diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c
index 2c61281bebd7..8cea355f9a81 100644
--- a/drivers/pinctrl/vt8500/pinctrl-wmt.c
+++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c
@@ -141,17 +141,6 @@ static int wmt_pmx_enable(struct pinctrl_dev *pctldev,
return wmt_set_pinmux(data, func_selector, pinnum);
}
-static void wmt_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned func_selector,
- unsigned group_selector)
-{
- struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);
- u32 pinnum = data->pins[group_selector].number;
-
- /* disable by setting GPIO_IN */
- wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, pinnum);
-}
-
static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -180,7 +169,6 @@ static struct pinmux_ops wmt_pinmux_ops = {
.get_function_name = wmt_pmx_get_function_name,
.get_function_groups = wmt_pmx_get_function_groups,
.enable = wmt_pmx_enable,
- .disable = wmt_pmx_disable,
.gpio_disable_free = wmt_pmx_gpio_disable_free,
.gpio_set_direction = wmt_pmx_gpio_set_direction,
};
@@ -627,8 +615,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev,
return 0;
fail_range:
- if (gpiochip_remove(&data->gpio_chip))
- dev_err(&pdev->dev, "failed to remove gpio chip\n");
+ gpiochip_remove(&data->gpio_chip);
fail_gpio:
pinctrl_unregister(data->pctl_dev);
return err;
@@ -637,12 +624,8 @@ fail_gpio:
int wmt_pinctrl_remove(struct platform_device *pdev)
{
struct wmt_pinctrl_data *data = platform_get_drvdata(pdev);
- int err;
-
- err = gpiochip_remove(&data->gpio_chip);
- if (err)
- dev_err(&pdev->dev, "failed to remove gpio chip\n");
+ gpiochip_remove(&data->gpio_chip);
pinctrl_unregister(data->pctl_dev);
return 0;