提交 e0b8b786 编写于 作者: L Linus Torvalds

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
  ...
...@@ -13,6 +13,8 @@ Required properties: ...@@ -13,6 +13,8 @@ Required properties:
"allwinner,sun6i-a31-pinctrl" "allwinner,sun6i-a31-pinctrl"
"allwinner,sun6i-a31-r-pinctrl" "allwinner,sun6i-a31-r-pinctrl"
"allwinner,sun7i-a20-pinctrl" "allwinner,sun7i-a20-pinctrl"
"allwinner,sun8i-a23-pinctrl"
"allwinner,sun8i-a23-r-pinctrl"
- reg: Should contain the register physical address and length for the - reg: Should contain the register physical address and length for the
pin controller. pin controller.
......
...@@ -46,7 +46,7 @@ Valid values for pins are: ...@@ -46,7 +46,7 @@ Valid values for pins are:
gpio0-gpio89 gpio0-gpio89
Valid values for function are: Valid values for function are:
cam_mclk, codec_mic_i2s, codec_spkr_i2s, gsbi1, gsbi2, gsbi3, gsbi4, cam_mclk, codec_mic_i2s, codec_spkr_i2s, gpio, gsbi1, gsbi2, gsbi3, gsbi4,
gsbi4_cam_i2c, gsbi5, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi4_cam_i2c, gsbi5, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6,
gsbi6_spi_cs1, gsbi6_spi_cs2, gsbi6_spi_cs3, gsbi7, gsbi7_spi_cs1, gsbi6_spi_cs1, gsbi6_spi_cs2, gsbi6_spi_cs3, gsbi7, gsbi7_spi_cs1,
gsbi7_spi_cs2, gsbi7_spi_cs3, gsbi_cam_i2c, hdmi, mi2s, riva_bt, riva_fm, gsbi7_spi_cs2, gsbi7_spi_cs3, gsbi_cam_i2c, hdmi, mi2s, riva_bt, riva_fm,
......
...@@ -51,7 +51,7 @@ Valid values for qcom,pins are: ...@@ -51,7 +51,7 @@ Valid values for qcom,pins are:
Valid values for function are: Valid values for function are:
mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gsbi1, gsbi2, gsbi4, gsbi5, mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gpio, gsbi1, gsbi2, gsbi4, gsbi5,
gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi7, nss_spi, sdc1, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi7, nss_spi, sdc1,
spdif, nand, tsif1, tsif2, usb_fs_n, usb_fs, usb2_hsic, rgmii2, sata, spdif, nand, tsif1, tsif2, usb_fs_n, usb_fs, usb2_hsic, rgmii2, sata,
pcie1_rst, pcie1_prsnt, pcie1_pwren_n, pcie1_pwren, pcie1_pwrflt, pcie1_rst, pcie1_prsnt, pcie1_pwren_n, pcie1_pwren, pcie1_pwrflt,
......
Qualcomm MSM8960 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
MSM8960 platform.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,msm8960-pinctrl"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the TLMM register space.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the TLMM summary IRQ.
- interrupt-controller:
Usage: required
Value type: <none>
Definition: identifies this node as an interrupt controller
- #interrupt-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/interrupt-controller/irq.h>
- gpio-controller:
Usage: required
Value type: <none>
Definition: identifies this node as a gpio controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an abitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
PIN CONFIGURATION NODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode. Valid pins are:
gpio0-gpio151,
sdc1_clk,
sdc1_cmd,
sdc1_data
sdc3_clk,
sdc3_cmd,
sdc3_data
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Functions are only valid for gpio pins.
Valid values are:
audio_pcm, bt, cam_mclk0, cam_mclk1, cam_mclk2,
codec_mic_i2s, codec_spkr_i2s, ext_gps, fm, gps_blanking,
gps_pps_in, gps_pps_out, gp_clk_0a, gp_clk_0b, gp_clk_1a,
gp_clk_1b, gp_clk_2a, gp_clk_2b, gp_mn, gp_pdm_0a,
gp_pdm_0b, gp_pdm_1a, gp_pdm_1b, gp_pdm_2a, gp_pdm_2b, gpio,
gsbi1, gsbi1_spi_cs1_n, gsbi1_spi_cs2a_n, gsbi1_spi_cs2b_n,
gsbi1_spi_cs3_n, gsbi2, gsbi2_spi_cs1_n, gsbi2_spi_cs2_n,
gsbi2_spi_cs3_n, gsbi3, gsbi4, gsbi4_3d_cam_i2c_l,
gsbi4_3d_cam_i2c_r, gsbi5, gsbi5_3d_cam_i2c_l,
gsbi5_3d_cam_i2c_r, gsbi6, gsbi7, gsbi8, gsbi9, gsbi10,
gsbi11, gsbi11_spi_cs1a_n, gsbi11_spi_cs1b_n,
gsbi11_spi_cs2a_n, gsbi11_spi_cs2b_n, gsbi11_spi_cs3_n,
gsbi12, hdmi_cec, hdmi_ddc_clock, hdmi_ddc_data,
hdmi_hot_plug_detect, hsic, mdp_vsync, mi2s, mic_i2s,
pmb_clk, pmb_ext_ctrl, ps_hold, rpm_wdog, sdc2, sdc4, sdc5,
slimbus1, slimbus2, spkr_i2s, ssbi1, ssbi2, ssbi_ext_gps,
ssbi_pmic2, ssbi_qpa1, ssbi_ts, tsif1, tsif2, ts_eoc,
usb_fs1, usb_fs1_oe, usb_fs1_oe_n, usb_fs2, usb_fs2_oe,
usb_fs2_oe_n, vfe_camif_timer1_a, vfe_camif_timer1_b,
vfe_camif_timer2, vfe_camif_timer3_a, vfe_camif_timer3_b,
vfe_camif_timer4_a, vfe_camif_timer4_b, vfe_camif_timer4_c,
vfe_camif_timer5_a, vfe_camif_timer5_b, vfe_camif_timer6_a,
vfe_camif_timer6_b, vfe_camif_timer6_c, vfe_camif_timer7_a,
vfe_camif_timer7_b, vfe_camif_timer7_c, wlan
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull down.
- bias-pull-up:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull up.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
Not valid for sdc pins.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
Not valid for sdc pins.
- drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins, in mA.
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
Example:
msmgpio: pinctrl@800000 {
compatible = "qcom,msm8960-pinctrl";
reg = <0x800000 0x4000>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <0 16 0x4>;
gsbi8_uart: gsbi8-uart {
mux {
pins = "gpio34", "gpio35";
function = "gsbi8";
};
tx {
pins = "gpio34";
drive-strength = <4>;
bias-disable;
};
rx {
pins = "gpio35";
drive-strength = <2>;
bias-pull-up;
};
};
};
...@@ -70,7 +70,7 @@ Valid values for function are: ...@@ -70,7 +70,7 @@ Valid values for function are:
cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc, cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc,
hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk, hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk,
gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s, gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s,
ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, gpio
(Note that this is not yet the complete list of functions) (Note that this is not yet the complete list of functions)
......
...@@ -15,6 +15,7 @@ Required Properties: ...@@ -15,6 +15,7 @@ Required Properties:
- "renesas,pfc-r8a7778": for R8A7778 (R-Mobile M1) compatible pin-controller. - "renesas,pfc-r8a7778": for R8A7778 (R-Mobile M1) compatible pin-controller.
- "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller. - "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller.
- "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller. - "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller.
- "renesas,pfc-r8a7791": for R8A7791 (R-Car M2) compatible pin-controller.
- "renesas,pfc-sh7372": for SH7372 (SH-Mobile AP4) compatible pin-controller. - "renesas,pfc-sh7372": for SH7372 (SH-Mobile AP4) compatible pin-controller.
- "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller. - "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller.
......
...@@ -21,6 +21,7 @@ defined as gpio sub-nodes of the pinmux controller. ...@@ -21,6 +21,7 @@ defined as gpio sub-nodes of the pinmux controller.
Required properties for iomux controller: Required properties for iomux controller:
- compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl" - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
"rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl" "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
"rockchip,rk3288-pinctrl"
- rockchip,grf: phandle referencing a syscon providing the - rockchip,grf: phandle referencing a syscon providing the
"general register files" "general register files"
...@@ -36,7 +37,7 @@ Deprecated properties for iomux controller: ...@@ -36,7 +37,7 @@ Deprecated properties for iomux controller:
Use rockchip,grf and rockchip,pmu described above instead. Use rockchip,grf and rockchip,pmu described above instead.
Required properties for gpio sub nodes: Required properties for gpio sub nodes:
- compatible: "rockchip,gpio-bank", "rockchip,rk3188-gpio-bank0" - compatible: "rockchip,gpio-bank"
- reg: register of the gpio bank (different than the iomux registerset) - reg: register of the gpio bank (different than the iomux registerset)
- interrupts: base interrupt of the gpio bank in the interrupt controller - interrupts: base interrupt of the gpio bank in the interrupt controller
- clocks: clock that drives this bank - clocks: clock that drives this bank
...@@ -50,6 +51,7 @@ Required properties for gpio sub nodes: ...@@ -50,6 +51,7 @@ Required properties for gpio sub nodes:
bindings/interrupt-controller/interrupts.txt bindings/interrupt-controller/interrupts.txt
Deprecated properties for gpio sub nodes: Deprecated properties for gpio sub nodes:
- compatible: "rockchip,rk3188-gpio-bank0"
- reg: second element: separate pull register for rk3188 bank0, use - reg: second element: separate pull register for rk3188 bank0, use
rockchip,pmu described above instead rockchip,pmu described above instead
......
...@@ -44,7 +44,11 @@ Required Properties: ...@@ -44,7 +44,11 @@ Required Properties:
- Pin mux/config groups as child nodes: The pin mux (selecting pin function - Pin mux/config groups as child nodes: The pin mux (selecting pin function
mode) and pin config (pull up/down, driver strength) settings are represented mode) and pin config (pull up/down, driver strength) settings are represented
as child nodes of the pin-controller node. There should be atleast one as child nodes of the pin-controller node. There should be atleast one
child node and there is no limit on the count of these child nodes. child node and there is no limit on the count of these child nodes. It is
also possible for a child node to consist of several further child nodes
to allow grouping multiple pinctrl groups into one. The format of second
level child nodes is exactly the same as for first level ones and is
described below.
The child node should contain a list of pin(s) on which a particular pin The child node should contain a list of pin(s) on which a particular pin
function selection or pin configuration (or both) have to applied. This function selection or pin configuration (or both) have to applied. This
...@@ -71,6 +75,7 @@ Required Properties: ...@@ -71,6 +75,7 @@ Required Properties:
"samsung,pins" property of the child node. The following pin configuration "samsung,pins" property of the child node. The following pin configuration
properties are supported. properties are supported.
- samsung,pin-val: Initial value of pin output buffer.
- samsung,pin-pud: Pull up/down configuration. - samsung,pin-pud: Pull up/down configuration.
- samsung,pin-drv: Drive strength configuration. - samsung,pin-drv: Drive strength configuration.
- samsung,pin-pud-pdn: Pull up/down configuration in power down mode. - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
...@@ -249,6 +254,23 @@ Example 1: A pin-controller node with pin groups. ...@@ -249,6 +254,23 @@ Example 1: A pin-controller node with pin groups.
samsung,pin-pud = <3>; samsung,pin-pud = <3>;
samsung,pin-drv = <0>; samsung,pin-drv = <0>;
}; };
sd4_bus8: sd4-bus-width8 {
part-1 {
samsung,pins = "gpk0-3", "gpk0-4",
"gpk0-5", "gpk0-6";
samsung,pin-function = <3>;
samsung,pin-pud = <3>;
samsung,pin-drv = <3>;
};
part-2 {
samsung,pins = "gpk1-3", "gpk1-4",
"gpk1-5", "gpk1-6";
samsung,pin-function = <4>;
samsung,pin-pud = <4>;
samsung,pin-drv = <3>;
};
};
}; };
Example 2: A pin-controller node with external wakeup interrupt controller node. Example 2: A pin-controller node with external wakeup interrupt controller node.
......
...@@ -101,14 +101,6 @@ ...@@ -101,14 +101,6 @@
#define MX27_PAD_CONTRAST__GPIO1_30 0x1e 0x032 #define MX27_PAD_CONTRAST__GPIO1_30 0x1e 0x032
#define MX27_PAD_OE_ACD__OE_ACD 0x1f 0x004 #define MX27_PAD_OE_ACD__OE_ACD 0x1f 0x004
#define MX27_PAD_OE_ACD__GPIO1_31 0x1f 0x032 #define MX27_PAD_OE_ACD__GPIO1_31 0x1f 0x032
#define MX27_PAD_UNUSED0__UNUSED0 0x20 0x004
#define MX27_PAD_UNUSED0__GPIO2_0 0x20 0x032
#define MX27_PAD_UNUSED1__UNUSED1 0x21 0x004
#define MX27_PAD_UNUSED1__GPIO2_1 0x21 0x032
#define MX27_PAD_UNUSED2__UNUSED2 0x22 0x004
#define MX27_PAD_UNUSED2__GPIO2_2 0x22 0x032
#define MX27_PAD_UNUSED3__UNUSED3 0x23 0x004
#define MX27_PAD_UNUSED3__GPIO2_3 0x23 0x032
#define MX27_PAD_SD2_D0__SD2_D0 0x24 0x004 #define MX27_PAD_SD2_D0__SD2_D0 0x24 0x004
#define MX27_PAD_SD2_D0__MSHC_DATA0 0x24 0x005 #define MX27_PAD_SD2_D0__MSHC_DATA0 0x24 0x005
#define MX27_PAD_SD2_D0__GPIO2_4 0x24 0x032 #define MX27_PAD_SD2_D0__GPIO2_4 0x24 0x032
...@@ -183,16 +175,6 @@ ...@@ -183,16 +175,6 @@
#define MX27_PAD_USBH1_RXDP__USBH1_RXDP 0x3f 0x004 #define MX27_PAD_USBH1_RXDP__USBH1_RXDP 0x3f 0x004
#define MX27_PAD_USBH1_RXDP__UART4_RXD 0x3f 0x001 #define MX27_PAD_USBH1_RXDP__UART4_RXD 0x3f 0x001
#define MX27_PAD_USBH1_RXDP__GPIO2_31 0x3f 0x032 #define MX27_PAD_USBH1_RXDP__GPIO2_31 0x3f 0x032
#define MX27_PAD_UNUSED4__UNUSED4 0x40 0x004
#define MX27_PAD_UNUSED4__GPIO3_0 0x40 0x032
#define MX27_PAD_UNUSED5__UNUSED5 0x41 0x004
#define MX27_PAD_UNUSED5__GPIO3_1 0x41 0x032
#define MX27_PAD_UNUSED6__UNUSED6 0x42 0x004
#define MX27_PAD_UNUSED6__GPIO3_2 0x42 0x032
#define MX27_PAD_UNUSED7__UNUSED7 0x43 0x004
#define MX27_PAD_UNUSED7__GPIO3_3 0x43 0x032
#define MX27_PAD_UNUSED8__UNUSED8 0x44 0x004
#define MX27_PAD_UNUSED8__GPIO3_4 0x44 0x032
#define MX27_PAD_I2C2_SDA__I2C2_SDA 0x45 0x004 #define MX27_PAD_I2C2_SDA__I2C2_SDA 0x45 0x004
#define MX27_PAD_I2C2_SDA__GPIO3_5 0x45 0x032 #define MX27_PAD_I2C2_SDA__GPIO3_5 0x45 0x032
#define MX27_PAD_I2C2_SCL__I2C2_SCL 0x46 0x004 #define MX27_PAD_I2C2_SCL__I2C2_SCL 0x46 0x004
...@@ -422,18 +404,6 @@ ...@@ -422,18 +404,6 @@
#define MX27_PAD_USBOTG_CLK__GPIO5_24 0x98 0x032 #define MX27_PAD_USBOTG_CLK__GPIO5_24 0x98 0x032
#define MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x99 0x004 #define MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x99 0x004
#define MX27_PAD_USBOTG_DATA7__GPIO5_25 0x99 0x032 #define MX27_PAD_USBOTG_DATA7__GPIO5_25 0x99 0x032
#define MX27_PAD_UNUSED9__UNUSED9 0x9a 0x004
#define MX27_PAD_UNUSED9__GPIO5_26 0x9a 0x032
#define MX27_PAD_UNUSED10__UNUSED10 0x9b 0x004
#define MX27_PAD_UNUSED10__GPIO5_27 0x9b 0x032
#define MX27_PAD_UNUSED11__UNUSED11 0x9c 0x004
#define MX27_PAD_UNUSED11__GPIO5_28 0x9c 0x032
#define MX27_PAD_UNUSED12__UNUSED12 0x9d 0x004
#define MX27_PAD_UNUSED12__GPIO5_29 0x9d 0x032
#define MX27_PAD_UNUSED13__UNUSED13 0x9e 0x004
#define MX27_PAD_UNUSED13__GPIO5_30 0x9e 0x032
#define MX27_PAD_UNUSED14__UNUSED14 0x9f 0x004
#define MX27_PAD_UNUSED14__GPIO5_31 0x9f 0x032
#define MX27_PAD_NFRB__NFRB 0xa0 0x000 #define MX27_PAD_NFRB__NFRB 0xa0 0x000
#define MX27_PAD_NFRB__ETMTRACEPKT3 0xa0 0x005 #define MX27_PAD_NFRB__ETMTRACEPKT3 0xa0 0x005
#define MX27_PAD_NFRB__GPIO6_0 0xa0 0x032 #define MX27_PAD_NFRB__GPIO6_0 0xa0 0x032
...@@ -506,21 +476,5 @@ ...@@ -506,21 +476,5 @@
#define MX27_PAD_ATA_DATA15__ETMTRACEPKT4 0xb7 0x005 #define MX27_PAD_ATA_DATA15__ETMTRACEPKT4 0xb7 0x005
#define MX27_PAD_ATA_DATA15__FEC_TX_EN 0xb7 0x006 #define MX27_PAD_ATA_DATA15__FEC_TX_EN 0xb7 0x006
#define MX27_PAD_ATA_DATA15__GPIO6_23 0xb7 0x032 #define MX27_PAD_ATA_DATA15__GPIO6_23 0xb7 0x032
#define MX27_PAD_UNUSED15__UNUSED15 0xb8 0x004
#define MX27_PAD_UNUSED15__GPIO6_24 0xb8 0x032
#define MX27_PAD_UNUSED16__UNUSED16 0xb9 0x004
#define MX27_PAD_UNUSED16__GPIO6_25 0xb9 0x032
#define MX27_PAD_UNUSED17__UNUSED17 0xba 0x004
#define MX27_PAD_UNUSED17__GPIO6_26 0xba 0x032
#define MX27_PAD_UNUSED18__UNUSED18 0xbb 0x004
#define MX27_PAD_UNUSED18__GPIO6_27 0xbb 0x032
#define MX27_PAD_UNUSED19__UNUSED19 0xbc 0x004
#define MX27_PAD_UNUSED19__GPIO6_28 0xbc 0x032
#define MX27_PAD_UNUSED20__UNUSED20 0xbd 0x004
#define MX27_PAD_UNUSED20__GPIO6_29 0xbd 0x032
#define MX27_PAD_UNUSED21__UNUSED21 0xbe 0x004
#define MX27_PAD_UNUSED21__GPIO6_30 0xbe 0x032
#define MX27_PAD_UNUSED22__UNUSED22 0xbf 0x004
#define MX27_PAD_UNUSED22__GPIO6_31 0xbf 0x032
#endif /* __DTS_IMX27_PINFUNC_H */ #endif /* __DTS_IMX27_PINFUNC_H */
...@@ -4,7 +4,6 @@ menuconfig ARCH_SUNXI ...@@ -4,7 +4,6 @@ menuconfig ARCH_SUNXI
select CLKSRC_MMIO select CLKSRC_MMIO
select GENERIC_IRQ_CHIP select GENERIC_IRQ_CHIP
select PINCTRL select PINCTRL
select PINCTRL_SUNXI
select SUN4I_TIMER select SUN4I_TIMER
if ARCH_SUNXI if ARCH_SUNXI
......
...@@ -11,10 +11,10 @@ menu "Pin controllers" ...@@ -11,10 +11,10 @@ menu "Pin controllers"
depends on PINCTRL depends on PINCTRL
config PINMUX config PINMUX
bool "Support pin multiplexing controllers" bool "Support pin multiplexing controllers" if COMPILE_TEST
config PINCONF config PINCONF
bool "Support pin configuration controllers" bool "Support pin configuration controllers" if COMPILE_TEST
config GENERIC_PINCONF config GENERIC_PINCONF
bool bool
...@@ -26,29 +26,6 @@ config DEBUG_PINCTRL ...@@ -26,29 +26,6 @@ config DEBUG_PINCTRL
help help
Say Y here to add some extra checks and diagnostics to PINCTRL calls. 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 config PINCTRL_ADI2
bool "ADI pin controller driver" bool "ADI pin controller driver"
depends on BLACKFIN depends on BLACKFIN
...@@ -93,7 +70,7 @@ config PINCTRL_AT91 ...@@ -93,7 +70,7 @@ config PINCTRL_AT91
config PINCTRL_BAYTRAIL config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control" bool "Intel Baytrail GPIO pin control"
depends on GPIOLIB && ACPI && X86 depends on GPIOLIB && ACPI && X86
select IRQ_DOMAIN select GPIOLIB_IRQCHIP
help help
driver for memory mapped GPIO functionality on Intel Baytrail driver for memory mapped GPIO functionality on Intel Baytrail
platforms. Supports 3 banks with 102, 28 and 44 gpios. platforms. Supports 3 banks with 102, 28 and 44 gpios.
...@@ -130,6 +107,13 @@ config PINCTRL_IMX1_CORE ...@@ -130,6 +107,13 @@ config PINCTRL_IMX1_CORE
select PINMUX select PINMUX
select PINCONF 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 config PINCTRL_IMX27
bool "IMX27 pinctrl driver" bool "IMX27 pinctrl driver"
depends on SOC_IMX27 depends on SOC_IMX27
...@@ -226,58 +210,6 @@ config PINCTRL_IMX28 ...@@ -226,58 +210,6 @@ config PINCTRL_IMX28
bool bool
select PINCTRL_MXS 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 config PINCTRL_ROCKCHIP
bool bool
select PINMUX select PINMUX
...@@ -356,22 +288,6 @@ config PINCTRL_COH901 ...@@ -356,22 +288,6 @@ config PINCTRL_COH901
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
ports of 8 GPIO pins each. 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 config PINCTRL_PALMAS
bool "Pinctrl driver for the PALMAS Series MFD devices" bool "Pinctrl driver for the PALMAS Series MFD devices"
depends on OF && MFD_PALMAS depends on OF && MFD_PALMAS
...@@ -383,18 +299,11 @@ config PINCTRL_PALMAS ...@@ -383,18 +299,11 @@ config PINCTRL_PALMAS
open drain configuration for the Palmas series devices like open drain configuration for the Palmas series devices like
TPS65913, TPS80036 etc. 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/berlin/Kconfig"
source "drivers/pinctrl/mvebu/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/sh-pfc/Kconfig"
source "drivers/pinctrl/spear/Kconfig" source "drivers/pinctrl/spear/Kconfig"
source "drivers/pinctrl/sunxi/Kconfig" source "drivers/pinctrl/sunxi/Kconfig"
......
...@@ -9,11 +9,6 @@ ifeq ($(CONFIG_OF),y) ...@@ -9,11 +9,6 @@ ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_PINCTRL) += devicetree.o obj-$(CONFIG_PINCTRL) += devicetree.o
endif endif
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o 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_ADI2) += pinctrl-adi2.o
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
...@@ -24,6 +19,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o ...@@ -24,6 +19,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.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_IMX27) += pinctrl-imx27.o
obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o
obj-$(CONFIG_PINCTRL_IMX50) += pinctrl-imx50.o obj-$(CONFIG_PINCTRL_IMX50) += pinctrl-imx50.o
...@@ -38,14 +34,6 @@ obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o ...@@ -38,14 +34,6 @@ obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.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_PALMAS) += pinctrl-palmas.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
...@@ -59,11 +47,6 @@ obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o ...@@ -59,11 +47,6 @@ obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o
obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.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_XWAY) += pinctrl-xway.o
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
...@@ -72,8 +55,11 @@ obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o ...@@ -72,8 +55,11 @@ obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-$(CONFIG_PLAT_ORION) += mvebu/ 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_ARCH_SHMOBILE) += sh-pfc/
obj-$(CONFIG_SUPERH) += sh-pfc/ obj-$(CONFIG_SUPERH) += sh-pfc/
obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
...@@ -992,28 +992,14 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) ...@@ -992,28 +992,14 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
if (p->state) { if (p->state) {
/* /*
* The set of groups with a mux configuration in the old state * For each pinmux setting in the old state, forget SW's record
* may not be identical to the set of groups with a mux setting * of mux owner for that pingroup. Any pingroups which are
* in the new state. While this might be unusual, it's entirely * still owned by the new state will be re-acquired by the call
* possible for the "user"-supplied mapping table to be written * to pinmux_enable_setting() in the loop below.
* 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.
*/ */
list_for_each_entry(setting, &p->state->settings, node) { list_for_each_entry(setting, &p->state->settings, node) {
bool found = false;
if (setting->type != PIN_MAP_TYPE_MUX_GROUP) if (setting->type != PIN_MAP_TYPE_MUX_GROUP)
continue; 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);
} }
} }
......
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
# 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
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
#include <linux/pinctrl/machine.h> #include <linux/pinctrl/machine.h>
#include "pinctrl-abx500.h" #include "pinctrl-abx500.h"
#include "core.h" #include "../core.h"
#include "pinconf.h" #include "../pinconf.h"
/* /*
* The AB9540 and AB8540 GPIO support are extended versions * The AB9540 and AB8540 GPIO support are extended versions
...@@ -737,20 +737,6 @@ static int abx500_pmx_enable(struct pinctrl_dev *pctldev, unsigned function, ...@@ -737,20 +737,6 @@ static int abx500_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
return ret; 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, static int abx500_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned offset) unsigned offset)
...@@ -799,7 +785,6 @@ static const struct pinmux_ops abx500_pinmux_ops = { ...@@ -799,7 +785,6 @@ static const struct pinmux_ops abx500_pinmux_ops = {
.get_function_name = abx500_pmx_get_func_name, .get_function_name = abx500_pmx_get_func_name,
.get_function_groups = abx500_pmx_get_func_groups, .get_function_groups = abx500_pmx_get_func_groups,
.enable = abx500_pmx_enable, .enable = abx500_pmx_enable,
.disable = abx500_pmx_disable,
.gpio_request_enable = abx500_gpio_request_enable, .gpio_request_enable = abx500_gpio_request_enable,
.gpio_disable_free = abx500_gpio_disable_free, .gpio_disable_free = abx500_gpio_disable_free,
}; };
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
/* Since we request GPIOs from ourself */ /* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include "pinctrl-nomadik.h" #include "pinctrl-nomadik.h"
#include "core.h" #include "../core.h"
/* /*
* The GPIO module in the Nomadik family of Systems-on-Chip is an * The GPIO module in the Nomadik family of Systems-on-Chip is an
...@@ -1765,21 +1765,6 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function, ...@@ -1765,21 +1765,6 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
return ret; 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, static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned offset) unsigned offset)
...@@ -1826,7 +1811,6 @@ static const struct pinmux_ops nmk_pinmux_ops = { ...@@ -1826,7 +1811,6 @@ static const struct pinmux_ops nmk_pinmux_ops = {
.get_function_name = nmk_pmx_get_func_name, .get_function_name = nmk_pmx_get_func_name,
.get_function_groups = nmk_pmx_get_func_groups, .get_function_groups = nmk_pmx_get_func_groups,
.enable = nmk_pmx_enable, .enable = nmk_pmx_enable,
.disable = nmk_pmx_disable,
.gpio_request_enable = nmk_gpio_request_enable, .gpio_request_enable = nmk_gpio_request_enable,
.gpio_disable_free = nmk_gpio_disable_free, .gpio_disable_free = nmk_gpio_disable_free,
}; };
......
...@@ -401,7 +401,7 @@ static int adi_gpio_irq_type(struct irq_data *d, unsigned int type) ...@@ -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 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 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); port_setup(port, d->hwirq, true);
} else } else
goto out; goto out;
...@@ -652,35 +652,6 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id, ...@@ -652,35 +652,6 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id,
return 0; 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) static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
{ {
struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
...@@ -728,7 +699,6 @@ static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev, ...@@ -728,7 +699,6 @@ static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev,
static struct pinmux_ops adi_pinmux_ops = { static struct pinmux_ops adi_pinmux_ops = {
.enable = adi_pinmux_enable, .enable = adi_pinmux_enable,
.disable = adi_pinmux_disable,
.get_functions_count = adi_pinmux_get_funcs_count, .get_functions_count = adi_pinmux_get_funcs_count,
.get_function_name = adi_pinmux_get_func_name, .get_function_name = adi_pinmux_get_func_name,
.get_function_groups = adi_pinmux_get_groups, .get_function_groups = adi_pinmux_get_groups,
...@@ -979,7 +949,7 @@ static int adi_gpio_probe(struct platform_device *pdev) ...@@ -979,7 +949,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
struct gpio_port *port; struct gpio_port *port;
char pinctrl_devname[DEVNAME_SIZE]; char pinctrl_devname[DEVNAME_SIZE];
static int gpio; static int gpio;
int ret = 0, ret1; int ret = 0;
pdata = dev->platform_data; pdata = dev->platform_data;
if (!pdata) if (!pdata)
...@@ -1057,7 +1027,7 @@ static int adi_gpio_probe(struct platform_device *pdev) ...@@ -1057,7 +1027,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
return 0; return 0;
out_remove_gpiochip: out_remove_gpiochip:
ret1 = gpiochip_remove(&port->chip); gpiochip_remove(&port->chip);
out_remove_domain: out_remove_domain:
if (port->pint) if (port->pint)
irq_domain_remove(port->domain); irq_domain_remove(port->domain);
...@@ -1068,12 +1038,11 @@ static int adi_gpio_probe(struct platform_device *pdev) ...@@ -1068,12 +1038,11 @@ static int adi_gpio_probe(struct platform_device *pdev)
static int adi_gpio_remove(struct platform_device *pdev) static int adi_gpio_remove(struct platform_device *pdev)
{ {
struct gpio_port *port = platform_get_drvdata(pdev); struct gpio_port *port = platform_get_drvdata(pdev);
int ret;
u8 offset; u8 offset;
list_del(&port->node); list_del(&port->node);
gpiochip_remove_pin_ranges(&port->chip); gpiochip_remove_pin_ranges(&port->chip);
ret = gpiochip_remove(&port->chip); gpiochip_remove(&port->chip);
if (port->pint) { if (port->pint) {
for (offset = 0; offset < port->width; offset++) for (offset = 0; offset < port->width; offset++)
irq_dispose_mapping(irq_find_mapping(port->domain, irq_dispose_mapping(irq_find_mapping(port->domain,
...@@ -1081,7 +1050,7 @@ static int adi_gpio_remove(struct platform_device *pdev) ...@@ -1081,7 +1050,7 @@ static int adi_gpio_remove(struct platform_device *pdev)
irq_domain_remove(port->domain); irq_domain_remove(port->domain);
} }
return ret; return 0;
} }
static int adi_pinctrl_probe(struct platform_device *pdev) static int adi_pinctrl_probe(struct platform_device *pdev)
......
...@@ -565,7 +565,6 @@ static int as3722_pinctrl_probe(struct platform_device *pdev) ...@@ -565,7 +565,6 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
{ {
struct as3722_pctrl_info *as_pci; struct as3722_pctrl_info *as_pci;
int ret; int ret;
int tret;
as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL); as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
if (!as_pci) if (!as_pci)
...@@ -611,10 +610,7 @@ static int as3722_pinctrl_probe(struct platform_device *pdev) ...@@ -611,10 +610,7 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
return 0; return 0;
fail_range_add: fail_range_add:
tret = gpiochip_remove(&as_pci->gpio_chip); gpiochip_remove(&as_pci->gpio_chip);
if (tret < 0)
dev_warn(&pdev->dev, "Couldn't remove gpio chip, %d\n", tret);
fail_chip_add: fail_chip_add:
pinctrl_unregister(as_pci->pctl); pinctrl_unregister(as_pci->pctl);
return ret; return ret;
...@@ -623,11 +619,8 @@ static int as3722_pinctrl_probe(struct platform_device *pdev) ...@@ -623,11 +619,8 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
static int as3722_pinctrl_remove(struct platform_device *pdev) static int as3722_pinctrl_remove(struct platform_device *pdev)
{ {
struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev); struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
int ret;
ret = gpiochip_remove(&as_pci->gpio_chip); gpiochip_remove(&as_pci->gpio_chip);
if (ret < 0)
return ret;
pinctrl_unregister(as_pci->pctl); pinctrl_unregister(as_pci->pctl);
return 0; return 0;
} }
......
...@@ -611,26 +611,6 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -611,26 +611,6 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0; 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) static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
{ {
struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
...@@ -705,7 +685,6 @@ static const struct pinmux_ops at91_pmx_ops = { ...@@ -705,7 +685,6 @@ static const struct pinmux_ops at91_pmx_ops = {
.get_function_name = at91_pmx_get_func_name, .get_function_name = at91_pmx_get_func_name,
.get_function_groups = at91_pmx_get_groups, .get_function_groups = at91_pmx_get_groups,
.enable = at91_pmx_enable, .enable = at91_pmx_enable,
.disable = at91_pmx_disable,
.gpio_request_enable = at91_gpio_request_enable, .gpio_request_enable = at91_gpio_request_enable,
.gpio_disable_free = at91_gpio_disable_free, .gpio_disable_free = at91_gpio_disable_free,
}; };
...@@ -793,9 +772,9 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev, ...@@ -793,9 +772,9 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin_id) struct seq_file *s, unsigned pin_id)
{ {
unsigned long config; 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(MULTI_DRIVE);
DBG_SHOW_FLAG(PULL_UP); DBG_SHOW_FLAG(PULL_UP);
...@@ -945,7 +924,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np, ...@@ -945,7 +924,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */ /* Initialise function */
func->name = np->name; func->name = np->name;
func->ngroups = of_get_child_count(np); func->ngroups = of_get_child_count(np);
if (func->ngroups <= 0) { if (func->ngroups == 0) {
dev_err(info->dev, "no groups defined\n"); dev_err(info->dev, "no groups defined\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -25,9 +25,7 @@ ...@@ -25,9 +25,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/irqdomain.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
...@@ -44,6 +42,7 @@ ...@@ -44,6 +42,7 @@
/* BYT_CONF0_REG register bits */ /* BYT_CONF0_REG register bits */
#define BYT_IODEN BIT(31) #define BYT_IODEN BIT(31)
#define BYT_DIRECT_IRQ_EN BIT(27)
#define BYT_TRIG_NEG BIT(26) #define BYT_TRIG_NEG BIT(26)
#define BYT_TRIG_POS BIT(25) #define BYT_TRIG_POS BIT(25)
#define BYT_TRIG_LVL BIT(24) #define BYT_TRIG_LVL BIT(24)
...@@ -137,7 +136,6 @@ static struct pinctrl_gpio_range byt_ranges[] = { ...@@ -137,7 +136,6 @@ static struct pinctrl_gpio_range byt_ranges[] = {
struct byt_gpio { struct byt_gpio {
struct gpio_chip chip; struct gpio_chip chip;
struct irq_domain *domain;
struct platform_device *pdev; struct platform_device *pdev;
spinlock_t lock; spinlock_t lock;
void __iomem *reg_base; void __iomem *reg_base;
...@@ -217,7 +215,7 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) ...@@ -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) 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 offset = irqd_to_hwirq(d);
u32 value; u32 value;
unsigned long flags; unsigned long flags;
...@@ -303,12 +301,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip, ...@@ -303,12 +301,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value) unsigned gpio, int value)
{ {
struct byt_gpio *vg = to_byt_gpio(chip); 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); void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
unsigned long flags; unsigned long flags;
u32 reg_val; u32 reg_val;
spin_lock_irqsave(&vg->lock, flags); 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 = readl(reg) | BYT_DIR_MASK;
reg_val &= ~BYT_OUTPUT_EN; reg_val &= ~BYT_OUTPUT_EN;
...@@ -393,16 +401,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) ...@@ -393,16 +401,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
spin_unlock_irqrestore(&vg->lock, flags); 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) static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{ {
struct irq_data *data = irq_desc_get_irq_data(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); struct irq_chip *chip = irq_data_get_irq_chip(data);
u32 base, pin, mask; u32 base, pin, mask;
void __iomem *reg; void __iomem *reg;
...@@ -421,7 +423,7 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc) ...@@ -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 */ /* Clear before handling so we can't lose an edge */
writel(mask, reg); writel(mask, reg);
virq = irq_find_mapping(vg->domain, base + pin); virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
generic_handle_irq(virq); generic_handle_irq(virq);
/* In case bios or user sets triggering incorretly a pin /* In case bios or user sets triggering incorretly a pin
...@@ -454,33 +456,11 @@ static void byt_irq_mask(struct irq_data *d) ...@@ -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 = { static struct irq_chip byt_irqchip = {
.name = "BYT-GPIO", .name = "BYT-GPIO",
.irq_mask = byt_irq_mask, .irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask, .irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type, .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) 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) ...@@ -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) static int byt_gpio_probe(struct platform_device *pdev)
{ {
struct byt_gpio *vg; struct byt_gpio *vg;
...@@ -527,7 +490,6 @@ static int byt_gpio_probe(struct platform_device *pdev) ...@@ -527,7 +490,6 @@ static int byt_gpio_probe(struct platform_device *pdev)
struct acpi_device *acpi_dev; struct acpi_device *acpi_dev;
struct pinctrl_gpio_range *range; struct pinctrl_gpio_range *range;
acpi_handle handle = ACPI_HANDLE(dev); acpi_handle handle = ACPI_HANDLE(dev);
unsigned hwirq;
int ret; int ret;
if (acpi_bus_get_device(handle, &acpi_dev)) if (acpi_bus_get_device(handle, &acpi_dev))
...@@ -574,29 +536,29 @@ static int byt_gpio_probe(struct platform_device *pdev) ...@@ -574,29 +536,29 @@ static int byt_gpio_probe(struct platform_device *pdev)
gc->can_sleep = false; gc->can_sleep = false;
gc->dev = dev; gc->dev = dev;
ret = gpiochip_add(gc);
if (ret) {
dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
return ret;
}
/* set up interrupts */ /* set up interrupts */
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq_rc && irq_rc->start) { 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); byt_gpio_irq_init_hw(vg);
ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
irq_set_handler_data(hwirq, vg); handle_simple_irq, IRQ_TYPE_NONE);
irq_set_chained_handler(hwirq, byt_gpio_irq_handler);
}
ret = gpiochip_add(gc);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed adding byt-gpio chip\n"); dev_err(dev, "failed to add irqchip\n");
gpiochip_remove(gc);
return ret; return ret;
} }
gpiochip_set_chained_irqchip(gc, &byt_irqchip,
(unsigned)irq_rc->start,
byt_gpio_irq_handler);
}
pm_runtime_enable(dev); pm_runtime_enable(dev);
return 0; return 0;
...@@ -627,12 +589,9 @@ MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); ...@@ -627,12 +589,9 @@ MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
static int byt_gpio_remove(struct platform_device *pdev) static int byt_gpio_remove(struct platform_device *pdev)
{ {
struct byt_gpio *vg = platform_get_drvdata(pdev); struct byt_gpio *vg = platform_get_drvdata(pdev);
int err;
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
err = gpiochip_remove(&vg->chip); gpiochip_remove(&vg->chip);
if (err)
dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
return 0; return 0;
} }
......
...@@ -1396,7 +1396,7 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = { ...@@ -1396,7 +1396,7 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = {
.owner = THIS_MODULE, .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 bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
struct resource *res; struct resource *res;
......
...@@ -841,16 +841,6 @@ static int bcm2835_pmx_enable(struct pinctrl_dev *pctldev, ...@@ -841,16 +841,6 @@ static int bcm2835_pmx_enable(struct pinctrl_dev *pctldev,
return 0; 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, static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned offset) unsigned offset)
...@@ -880,7 +870,6 @@ static const struct pinmux_ops bcm2835_pmx_ops = { ...@@ -880,7 +870,6 @@ static const struct pinmux_ops bcm2835_pmx_ops = {
.get_function_name = bcm2835_pmx_get_function_name, .get_function_name = bcm2835_pmx_get_function_name,
.get_function_groups = bcm2835_pmx_get_function_groups, .get_function_groups = bcm2835_pmx_get_function_groups,
.enable = bcm2835_pmx_enable, .enable = bcm2835_pmx_enable,
.disable = bcm2835_pmx_disable,
.gpio_disable_free = bcm2835_pmx_gpio_disable_free, .gpio_disable_free = bcm2835_pmx_gpio_disable_free,
.gpio_set_direction = bcm2835_pmx_gpio_set_direction, .gpio_set_direction = bcm2835_pmx_gpio_set_direction,
}; };
......
...@@ -756,8 +756,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev) ...@@ -756,8 +756,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
err_no_range: err_no_range:
err_no_irqchip: err_no_irqchip:
if (gpiochip_remove(&gpio->chip)) gpiochip_remove(&gpio->chip);
dev_err(&pdev->dev, "failed to remove gpio chip\n");
err_no_chip: err_no_chip:
clk_disable_unprepare(gpio->clk); clk_disable_unprepare(gpio->clk);
dev_err(&pdev->dev, "module ERROR:%d\n", err); dev_err(&pdev->dev, "module ERROR:%d\n", err);
...@@ -767,16 +766,11 @@ static int __init u300_gpio_probe(struct platform_device *pdev) ...@@ -767,16 +766,11 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
static int __exit u300_gpio_remove(struct platform_device *pdev) static int __exit u300_gpio_remove(struct platform_device *pdev)
{ {
struct u300_gpio *gpio = platform_get_drvdata(pdev); struct u300_gpio *gpio = platform_get_drvdata(pdev);
int err;
/* Turn off the GPIO block */ /* Turn off the GPIO block */
writel(0x00000000U, gpio->base + U300_GPIO_CR); writel(0x00000000U, gpio->base + U300_GPIO_CR);
err = gpiochip_remove(&gpio->chip); gpiochip_remove(&gpio->chip);
if (err < 0) {
dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err);
return err;
}
clk_disable_unprepare(gpio->clk); clk_disable_unprepare(gpio->clk);
return 0; return 0;
} }
......
...@@ -515,7 +515,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np, ...@@ -515,7 +515,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */ /* Initialise function */
func->name = np->name; func->name = np->name;
func->num_groups = of_get_child_count(np); 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); dev_err(info->dev, "no groups defined in %s\n", np->full_name);
return -EINVAL; return -EINVAL;
} }
......
...@@ -526,7 +526,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np, ...@@ -526,7 +526,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */ /* Initialise function */
func->name = np->name; func->name = np->name;
func->num_groups = of_get_child_count(np); func->num_groups = of_get_child_count(np);
if (func->num_groups <= 0) if (func->num_groups == 0)
return -EINVAL; return -EINVAL;
func->groups = devm_kzalloc(info->dev, func->groups = devm_kzalloc(info->dev,
......
/*
* 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");
...@@ -63,10 +63,6 @@ enum imx27_pads { ...@@ -63,10 +63,6 @@ enum imx27_pads {
MX27_PAD_CONTRAST = PAD_ID(PA, 30), MX27_PAD_CONTRAST = PAD_ID(PA, 30),
MX27_PAD_OE_ACD = PAD_ID(PA, 31), 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_D0 = PAD_ID(PB, 4),
MX27_PAD_SD2_D1 = PAD_ID(PB, 5), MX27_PAD_SD2_D1 = PAD_ID(PB, 5),
MX27_PAD_SD2_D2 = PAD_ID(PB, 6), MX27_PAD_SD2_D2 = PAD_ID(PB, 6),
...@@ -96,11 +92,6 @@ enum imx27_pads { ...@@ -96,11 +92,6 @@ enum imx27_pads {
MX27_PAD_USBH1_RXDM = PAD_ID(PB, 30), MX27_PAD_USBH1_RXDM = PAD_ID(PB, 30),
MX27_PAD_USBH1_RXDP = PAD_ID(PB, 31), 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_SDA = PAD_ID(PC, 5),
MX27_PAD_I2C2_SCL = PAD_ID(PC, 6), MX27_PAD_I2C2_SCL = PAD_ID(PC, 6),
MX27_PAD_USBOTG_DATA5 = PAD_ID(PC, 7), MX27_PAD_USBOTG_DATA5 = PAD_ID(PC, 7),
...@@ -188,12 +179,6 @@ enum imx27_pads { ...@@ -188,12 +179,6 @@ enum imx27_pads {
MX27_PAD_SD1_CLK = PAD_ID(PE, 23), MX27_PAD_SD1_CLK = PAD_ID(PE, 23),
MX27_PAD_USBOTG_CLK = PAD_ID(PE, 24), MX27_PAD_USBOTG_CLK = PAD_ID(PE, 24),
MX27_PAD_USBOTG_DATA7 = PAD_ID(PE, 25), 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_NFRB = PAD_ID(PF, 0),
MX27_PAD_NFCLE = PAD_ID(PF, 1), MX27_PAD_NFCLE = PAD_ID(PF, 1),
...@@ -219,14 +204,6 @@ enum imx27_pads { ...@@ -219,14 +204,6 @@ enum imx27_pads {
MX27_PAD_CS4_B = PAD_ID(PF, 21), MX27_PAD_CS4_B = PAD_ID(PF, 21),
MX27_PAD_CS5_B = PAD_ID(PF, 22), MX27_PAD_CS5_B = PAD_ID(PF, 22),
MX27_PAD_ATA_DATA15 = PAD_ID(PF, 23), 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 */ /* Pad names for the pinmux subsystem */
...@@ -264,10 +241,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = { ...@@ -264,10 +241,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_CONTRAST), IMX_PINCTRL_PIN(MX27_PAD_CONTRAST),
IMX_PINCTRL_PIN(MX27_PAD_OE_ACD), 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_D0),
IMX_PINCTRL_PIN(MX27_PAD_SD2_D1), IMX_PINCTRL_PIN(MX27_PAD_SD2_D1),
IMX_PINCTRL_PIN(MX27_PAD_SD2_D2), IMX_PINCTRL_PIN(MX27_PAD_SD2_D2),
...@@ -297,11 +270,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = { ...@@ -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_RXDM),
IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDP), 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_SDA),
IMX_PINCTRL_PIN(MX27_PAD_I2C2_SCL), IMX_PINCTRL_PIN(MX27_PAD_I2C2_SCL),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA5), IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA5),
...@@ -389,12 +357,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = { ...@@ -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_SD1_CLK),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_CLK), IMX_PINCTRL_PIN(MX27_PAD_USBOTG_CLK),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA7), 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_NFRB),
IMX_PINCTRL_PIN(MX27_PAD_NFCLE), IMX_PINCTRL_PIN(MX27_PAD_NFCLE),
...@@ -420,14 +382,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = { ...@@ -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_CS4_B),
IMX_PINCTRL_PIN(MX27_PAD_CS5_B), IMX_PINCTRL_PIN(MX27_PAD_CS5_B),
IMX_PINCTRL_PIN(MX27_PAD_ATA_DATA15), 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 = { static struct imx1_pinctrl_soc_info imx27_pinctrl_info = {
...@@ -440,12 +394,6 @@ static struct of_device_id imx27_pinctrl_of_match[] = { ...@@ -440,12 +394,6 @@ static struct of_device_id imx27_pinctrl_of_match[] = {
{ /* sentinel */ } { /* 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) static int imx27_pinctrl_probe(struct platform_device *pdev)
{ {
return imx1_pinctrl_core_probe(pdev, &imx27_pinctrl_info); return imx1_pinctrl_core_probe(pdev, &imx27_pinctrl_info);
......
...@@ -62,11 +62,26 @@ enum rockchip_pinctrl_type { ...@@ -62,11 +62,26 @@ enum rockchip_pinctrl_type {
RK2928, RK2928,
RK3066B, RK3066B,
RK3188, RK3188,
RK3288,
}; };
enum rockchip_pin_bank_type { /**
COMMON_BANK, * Encode variants of iomux registers into a type variable
RK3188_BANK0, */
#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 { ...@@ -78,6 +93,7 @@ enum rockchip_pin_bank_type {
* @nr_pins: number of pins in this bank * @nr_pins: number of pins in this bank
* @name: name of the bank * @name: name of the bank
* @bank_num: number of the bank, to account for holes * @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 * @valid: are all necessary informations present
* @of_node: dt node of this bank * @of_node: dt node of this bank
* @drvdata: common pinctrl basedata * @drvdata: common pinctrl basedata
...@@ -95,7 +111,7 @@ struct rockchip_pin_bank { ...@@ -95,7 +111,7 @@ struct rockchip_pin_bank {
u8 nr_pins; u8 nr_pins;
char *name; char *name;
u8 bank_num; u8 bank_num;
enum rockchip_pin_bank_type bank_type; struct rockchip_iomux iomux[4];
bool valid; bool valid;
struct device_node *of_node; struct device_node *of_node;
struct rockchip_pinctrl *drvdata; struct rockchip_pinctrl *drvdata;
...@@ -111,6 +127,25 @@ struct rockchip_pin_bank { ...@@ -111,6 +127,25 @@ struct rockchip_pin_bank {
.bank_num = id, \ .bank_num = id, \
.nr_pins = pins, \ .nr_pins = pins, \
.name = label, \ .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 { ...@@ -121,7 +156,8 @@ struct rockchip_pin_ctrl {
u32 nr_pins; u32 nr_pins;
char *label; char *label;
enum rockchip_pinctrl_type type; 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, void (*pull_calc_reg)(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap, int pin_num, struct regmap **regmap,
int *reg, u8 *bit); int *reg, u8 *bit);
...@@ -343,24 +379,42 @@ static const struct pinctrl_ops rockchip_pctrl_ops = { ...@@ -343,24 +379,42 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{ {
struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pinctrl *info = bank->drvdata;
int iomux_num = (pin / 8);
struct regmap *regmap;
unsigned int val; unsigned int val;
int reg, ret; int reg, ret, mask;
u8 bit; 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; 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 */ /* get basic quadrupel of mux registers and the correct reg inside */
reg = info->ctrl->mux_offset; mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
reg += bank->bank_num * 0x10; reg = bank->iomux[iomux_num].offset;
reg += (pin / 8) * 4; if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
if ((pin % 8) >= 4)
reg += 0x4;
bit = (pin % 4) * 4;
} else {
bit = (pin % 8) * 2; bit = (pin % 8) * 2;
}
ret = regmap_read(info->regmap_base, reg, &val); ret = regmap_read(regmap, reg, &val);
if (ret) if (ret)
return 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) ...@@ -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) static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{ {
struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pinctrl *info = bank->drvdata;
int reg, ret; int iomux_num = (pin / 8);
struct regmap *regmap;
int reg, ret, mask;
unsigned long flags; unsigned long flags;
u8 bit; u8 bit;
u32 data; u32 data;
/* if (iomux_num > 3)
* The first 16 pins of rk3188_bank0 are always gpios and do not have return -EINVAL;
* a mux register at all.
*/ if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
if (bank->bank_type == RK3188_BANK0 && pin < 16) { 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) { if (mux != RK_FUNC_GPIO) {
dev_err(info->dev, dev_err(info->dev,
"pin %d only supports a gpio mux\n", pin); "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) ...@@ -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", dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
bank->bank_num, pin, mux); 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 */ /* get basic quadrupel of mux registers and the correct reg inside */
reg = info->ctrl->mux_offset; mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
reg += bank->bank_num * 0x10; reg = bank->iomux[iomux_num].offset;
reg += (pin / 8) * 4; if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
if ((pin % 8) >= 4)
reg += 0x4;
bit = (pin % 4) * 4;
} else {
bit = (pin % 8) * 2; bit = (pin % 8) * 2;
}
spin_lock_irqsave(&bank->slock, flags); spin_lock_irqsave(&bank->slock, flags);
data = (3 << (bit + 16)); data = (mask << (bit + 16));
data |= (mux & 3) << bit; data |= (mux & mask) << bit;
ret = regmap_write(info->regmap_base, reg, data); ret = regmap_write(regmap, reg, data);
spin_unlock_irqrestore(&bank->slock, flags); spin_unlock_irqrestore(&bank->slock, flags);
...@@ -449,7 +517,7 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, ...@@ -449,7 +517,7 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pinctrl *info = bank->drvdata;
/* The first 12 pins of the first bank are located elsewhere */ /* 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 *regmap = info->regmap_pmu ? info->regmap_pmu
: bank->regmap_pull; : bank->regmap_pull;
*reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0; *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, ...@@ -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) static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
{ {
struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pinctrl *info = bank->drvdata;
...@@ -501,6 +690,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) ...@@ -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_PULL_PIN_DEFAULT
: PIN_CONFIG_BIAS_DISABLE; : PIN_CONFIG_BIAS_DISABLE;
case RK3188: case RK3188:
case RK3288:
data >>= bit; data >>= bit;
data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
...@@ -555,6 +745,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, ...@@ -555,6 +745,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
spin_unlock_irqrestore(&bank->slock, flags); spin_unlock_irqrestore(&bank->slock, flags);
break; break;
case RK3188: case RK3188:
case RK3288:
spin_lock_irqsave(&bank->slock, flags); spin_lock_irqsave(&bank->slock, flags);
/* enable the write to the equivalent lower bits */ /* enable the write to the equivalent lower bits */
...@@ -657,23 +848,6 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -657,23 +848,6 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0; 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() * The calls to gpio_direction_output() and gpio_direction_input()
* leads to this function call (via the pinctrl_gpio_direction_{input|output}() * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
...@@ -716,7 +890,6 @@ static const struct pinmux_ops rockchip_pmx_ops = { ...@@ -716,7 +890,6 @@ static const struct pinmux_ops rockchip_pmx_ops = {
.get_function_name = rockchip_pmx_get_func_name, .get_function_name = rockchip_pmx_get_func_name,
.get_function_groups = rockchip_pmx_get_groups, .get_function_groups = rockchip_pmx_get_groups,
.enable = rockchip_pmx_enable, .enable = rockchip_pmx_enable,
.disable = rockchip_pmx_disable,
.gpio_set_direction = rockchip_pmx_gpio_set_direction, .gpio_set_direction = rockchip_pmx_gpio_set_direction,
}; };
...@@ -734,6 +907,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, ...@@ -734,6 +907,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
case RK3066B: case RK3066B:
return pull ? false : true; return pull ? false : true;
case RK3188: case RK3188:
case RK3288:
return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
} }
...@@ -788,6 +962,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -788,6 +962,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
if (rc) if (rc)
return rc; return rc;
break; 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: default:
return -ENOTSUPP; return -ENOTSUPP;
break; break;
...@@ -837,6 +1020,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -837,6 +1020,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
arg = rc ? 1 : 0; arg = rc ? 1 : 0;
break; 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: default:
return -ENOTSUPP; return -ENOTSUPP;
break; break;
...@@ -850,6 +1044,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -850,6 +1044,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
static const struct pinconf_ops rockchip_pinconf_ops = { static const struct pinconf_ops rockchip_pinconf_ops = {
.pin_config_get = rockchip_pinconf_get, .pin_config_get = rockchip_pinconf_get,
.pin_config_set = rockchip_pinconf_set, .pin_config_set = rockchip_pinconf_set,
.is_generic = true,
}; };
static const struct of_device_id rockchip_bank_match[] = { static const struct of_device_id rockchip_bank_match[] = {
...@@ -1414,10 +1609,7 @@ static int rockchip_gpiolib_register(struct platform_device *pdev, ...@@ -1414,10 +1609,7 @@ static int rockchip_gpiolib_register(struct platform_device *pdev,
for (--i, --bank; i >= 0; --i, --bank) { for (--i, --bank; i >= 0; --i, --bank) {
if (!bank->valid) if (!bank->valid)
continue; continue;
gpiochip_remove(&bank->gpio_chip);
if (gpiochip_remove(&bank->gpio_chip))
dev_err(&pdev->dev, "gpio chip %s remove failed\n",
bank->gpio_chip.label);
} }
return ret; return ret;
} }
...@@ -1427,20 +1619,15 @@ static int rockchip_gpiolib_unregister(struct platform_device *pdev, ...@@ -1427,20 +1619,15 @@ static int rockchip_gpiolib_unregister(struct platform_device *pdev,
{ {
struct rockchip_pin_ctrl *ctrl = info->ctrl; struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct rockchip_pin_bank *bank = ctrl->pin_banks; struct rockchip_pin_bank *bank = ctrl->pin_banks;
int ret = 0;
int i; int i;
for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) { for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
if (!bank->valid) if (!bank->valid)
continue; continue;
gpiochip_remove(&bank->gpio_chip);
ret = gpiochip_remove(&bank->gpio_chip);
} }
if (ret) return 0;
dev_err(&pdev->dev, "gpio chip remove failed\n");
return ret;
} }
static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, 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, ...@@ -1466,8 +1653,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
"rockchip,rk3188-gpio-bank0")) { "rockchip,rk3188-gpio-bank0")) {
struct device_node *node; struct device_node *node;
bank->bank_type = RK3188_BANK0;
node = of_parse_phandle(bank->of_node->parent, node = of_parse_phandle(bank->of_node->parent,
"rockchip,pmu", 0); "rockchip,pmu", 0);
if (!node) { if (!node) {
...@@ -1487,9 +1672,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, ...@@ -1487,9 +1672,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
base, base,
&rockchip_regmap_config); &rockchip_regmap_config);
} }
} else {
bank->bank_type = COMMON_BANK;
} }
bank->irq = irq_of_parse_and_map(bank->of_node, 0); 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( ...@@ -1513,7 +1695,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
struct device_node *np; struct device_node *np;
struct rockchip_pin_ctrl *ctrl; struct rockchip_pin_ctrl *ctrl;
struct rockchip_pin_bank *bank; struct rockchip_pin_bank *bank;
int i; int grf_offs, pmu_offs, i, j;
match = of_match_node(rockchip_pinctrl_dt_match, node); match = of_match_node(rockchip_pinctrl_dt_match, node);
ctrl = (struct rockchip_pin_ctrl *)match->data; ctrl = (struct rockchip_pin_ctrl *)match->data;
...@@ -1535,12 +1717,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_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; bank = ctrl->pin_banks;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
int bank_pins = 0;
spin_lock_init(&bank->slock); spin_lock_init(&bank->slock);
bank->drvdata = d; bank->drvdata = d;
bank->pin_base = ctrl->nr_pins; bank->pin_base = ctrl->nr_pins;
ctrl->nr_pins += bank->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; return ctrl;
...@@ -1644,7 +1865,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = { ...@@ -1644,7 +1865,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk2928_pin_banks), .nr_banks = ARRAY_SIZE(rk2928_pin_banks),
.label = "RK2928-GPIO", .label = "RK2928-GPIO",
.type = RK2928, .type = RK2928,
.mux_offset = 0xa8, .grf_mux_offset = 0xa8,
.pull_calc_reg = rk2928_calc_pull_reg_and_bit, .pull_calc_reg = rk2928_calc_pull_reg_and_bit,
}; };
...@@ -1662,7 +1883,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { ...@@ -1662,7 +1883,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3066a_pin_banks), .nr_banks = ARRAY_SIZE(rk3066a_pin_banks),
.label = "RK3066a-GPIO", .label = "RK3066a-GPIO",
.type = RK2928, .type = RK2928,
.mux_offset = 0xa8, .grf_mux_offset = 0xa8,
.pull_calc_reg = rk2928_calc_pull_reg_and_bit, .pull_calc_reg = rk2928_calc_pull_reg_and_bit,
}; };
...@@ -1678,11 +1899,11 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { ...@@ -1678,11 +1899,11 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3066b_pin_banks), .nr_banks = ARRAY_SIZE(rk3066b_pin_banks),
.label = "RK3066b-GPIO", .label = "RK3066b-GPIO",
.type = RK3066B, .type = RK3066B,
.mux_offset = 0x60, .grf_mux_offset = 0x60,
}; };
static struct rockchip_pin_bank rk3188_pin_banks[] = { 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(1, 32, "gpio1"),
PIN_BANK(2, 32, "gpio2"), PIN_BANK(2, 32, "gpio2"),
PIN_BANK(3, 32, "gpio3"), PIN_BANK(3, 32, "gpio3"),
...@@ -1693,10 +1914,52 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = { ...@@ -1693,10 +1914,52 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3188_pin_banks), .nr_banks = ARRAY_SIZE(rk3188_pin_banks),
.label = "RK3188-GPIO", .label = "RK3188-GPIO",
.type = RK3188, .type = RK3188,
.mux_offset = 0x60, .grf_mux_offset = 0x60,
.pull_calc_reg = rk3188_calc_pull_reg_and_bit, .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[] = { static const struct of_device_id rockchip_pinctrl_dt_match[] = {
{ .compatible = "rockchip,rk2928-pinctrl", { .compatible = "rockchip,rk2928-pinctrl",
.data = (void *)&rk2928_pin_ctrl }, .data = (void *)&rk2928_pin_ctrl },
...@@ -1706,6 +1969,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { ...@@ -1706,6 +1969,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
.data = (void *)&rk3066b_pin_ctrl }, .data = (void *)&rk3066b_pin_ctrl },
{ .compatible = "rockchip,rk3188-pinctrl", { .compatible = "rockchip,rk3188-pinctrl",
.data = (void *)&rk3188_pin_ctrl }, .data = (void *)&rk3188_pin_ctrl },
{ .compatible = "rockchip,rk3288-pinctrl",
.data = (void *)&rk3288_pin_ctrl },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);
......
...@@ -488,61 +488,6 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector, ...@@ -488,61 +488,6 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
return 0; 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, static int pcs_request_gpio(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned pin) struct pinctrl_gpio_range *range, unsigned pin)
{ {
...@@ -575,7 +520,6 @@ static const struct pinmux_ops pcs_pinmux_ops = { ...@@ -575,7 +520,6 @@ static const struct pinmux_ops pcs_pinmux_ops = {
.get_function_name = pcs_get_function_name, .get_function_name = pcs_get_function_name,
.get_function_groups = pcs_get_function_groups, .get_function_groups = pcs_get_function_groups,
.enable = pcs_enable, .enable = pcs_enable,
.disable = pcs_disable,
.gpio_request_enable = pcs_request_gpio, .gpio_request_enable = pcs_request_gpio,
}; };
...@@ -836,7 +780,7 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, ...@@ -836,7 +780,7 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
pin = &pcs->pins.pa[i]; pin = &pcs->pins.pa[i];
pn = &pcs->names[i]; pn = &pcs->names[i];
sprintf(pn->name, "%lx.%d", sprintf(pn->name, "%lx.%u",
(unsigned long)pcs->res->start + offset, pin_pos); (unsigned long)pcs->res->start + offset, pin_pos);
pin->name = pn->name; pin->name = pn->name;
pin->number = i; pin->number = i;
...@@ -1739,11 +1683,10 @@ static void pcs_irq_chain_handler(unsigned int irq, struct irq_desc *desc) ...@@ -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 pcs_soc_data *pcs_soc = irq_desc_get_handler_data(desc);
struct irq_chip *chip; struct irq_chip *chip;
int res;
chip = irq_get_chip(irq); chip = irq_get_chip(irq);
chained_irq_enter(chip, desc); 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)? */ /* REVISIT: export and add handle_bad_irq(irq, desc)? */
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
......
...@@ -930,11 +930,6 @@ static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector, ...@@ -930,11 +930,6 @@ static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector,
return 0; 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, static int st_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned gpio, struct pinctrl_gpio_range *range, unsigned gpio,
bool input) bool input)
...@@ -957,7 +952,6 @@ static struct pinmux_ops st_pmxops = { ...@@ -957,7 +952,6 @@ static struct pinmux_ops st_pmxops = {
.get_function_name = st_pmx_get_fname, .get_function_name = st_pmx_get_fname,
.get_function_groups = st_pmx_get_groups, .get_function_groups = st_pmx_get_groups,
.enable = st_pmx_enable, .enable = st_pmx_enable,
.disable = st_pmx_disable,
.gpio_set_direction = st_pmx_set_gpio_direction, .gpio_set_direction = st_pmx_set_gpio_direction,
}; };
...@@ -1178,9 +1172,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np, ...@@ -1178,9 +1172,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
const __be32 *list; const __be32 *list;
struct property *pp; struct property *pp;
struct st_pinconf *conf; struct st_pinconf *conf;
phandle phandle;
struct device_node *pins; struct device_node *pins;
u32 pin;
int i = 0, npins = 0, nr_props; int i = 0, npins = 0, nr_props;
pins = of_get_child_by_name(np, "st,pins"); pins = of_get_child_by_name(np, "st,pins");
...@@ -1218,8 +1210,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np, ...@@ -1218,8 +1210,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
conf = &grp->pin_conf[i]; conf = &grp->pin_conf[i];
/* bank & offset */ /* bank & offset */
phandle = be32_to_cpup(list++); be32_to_cpup(list++);
pin = be32_to_cpup(list++); be32_to_cpup(list++);
conf->pin = of_get_named_gpio(pins, pp->name, 0); conf->pin = of_get_named_gpio(pins, pp->name, 0);
conf->name = pp->name; conf->name = pp->name;
grp->pins[i] = conf->pin; grp->pins[i] = conf->pin;
...@@ -1256,7 +1248,7 @@ static int st_pctl_parse_functions(struct device_node *np, ...@@ -1256,7 +1248,7 @@ static int st_pctl_parse_functions(struct device_node *np,
func = &info->functions[index]; func = &info->functions[index];
func->name = np->name; func->name = np->name;
func->ngroups = of_get_child_count(np); func->ngroups = of_get_child_count(np);
if (func->ngroups <= 0) { if (func->ngroups == 0) {
dev_err(info->dev, "No groups defined\n"); dev_err(info->dev, "No groups defined\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1454,6 +1446,7 @@ static struct irq_chip st_gpio_irqchip = { ...@@ -1454,6 +1446,7 @@ static struct irq_chip st_gpio_irqchip = {
.irq_mask = st_gpio_irq_mask, .irq_mask = st_gpio_irq_mask,
.irq_unmask = st_gpio_irq_unmask, .irq_unmask = st_gpio_irq_unmask,
.irq_set_type = st_gpio_irq_set_type, .irq_set_type = st_gpio_irq_set_type,
.flags = IRQCHIP_SKIP_SET_WAKE,
}; };
static int st_gpiolib_register_bank(struct st_pinctrl *info, static int st_gpiolib_register_bank(struct st_pinctrl *info,
......
...@@ -738,22 +738,6 @@ static int tb10x_pctl_enable(struct pinctrl_dev *pctl, ...@@ -738,22 +738,6 @@ static int tb10x_pctl_enable(struct pinctrl_dev *pctl,
return 0; 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 = { static struct pinmux_ops tb10x_pinmux_ops = {
.get_functions_count = tb10x_get_functions_count, .get_functions_count = tb10x_get_functions_count,
.get_function_name = tb10x_get_function_name, .get_function_name = tb10x_get_function_name,
...@@ -761,7 +745,6 @@ static struct pinmux_ops tb10x_pinmux_ops = { ...@@ -761,7 +745,6 @@ static struct pinmux_ops tb10x_pinmux_ops = {
.gpio_request_enable = tb10x_gpio_request_enable, .gpio_request_enable = tb10x_gpio_request_enable,
.gpio_disable_free = tb10x_gpio_disable_free, .gpio_disable_free = tb10x_gpio_disable_free,
.enable = tb10x_pctl_enable, .enable = tb10x_pctl_enable,
.disable = tb10x_pctl_disable,
}; };
static struct pinctrl_desc tb10x_pindesc = { static struct pinctrl_desc tb10x_pindesc = {
......
...@@ -290,24 +290,11 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function, ...@@ -290,24 +290,11 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
return 0; 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 = { static const struct pinmux_ops tegra_pinmux_ops = {
.get_functions_count = tegra_pinctrl_get_funcs_count, .get_functions_count = tegra_pinctrl_get_funcs_count,
.get_function_name = tegra_pinctrl_get_func_name, .get_function_name = tegra_pinctrl_get_func_name,
.get_function_groups = tegra_pinctrl_get_func_groups, .get_function_groups = tegra_pinctrl_get_func_groups,
.enable = tegra_pinctrl_enable, .enable = tegra_pinctrl_enable,
.disable = tegra_pinctrl_disable,
}; };
static int tegra_pinconf_reg(struct tegra_pmx *pmx, static int tegra_pinconf_reg(struct tegra_pmx *pmx,
......
...@@ -574,33 +574,6 @@ static int tz1090_pdc_pinctrl_enable(struct pinctrl_dev *pctldev, ...@@ -574,33 +574,6 @@ static int tz1090_pdc_pinctrl_enable(struct pinctrl_dev *pctldev,
return 0; 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( static const struct tz1090_pdc_pingroup *find_mux_group(
struct tz1090_pdc_pmx *pmx, struct tz1090_pdc_pmx *pmx,
unsigned int pin) unsigned int pin)
...@@ -662,7 +635,6 @@ static struct pinmux_ops tz1090_pdc_pinmux_ops = { ...@@ -662,7 +635,6 @@ static struct pinmux_ops tz1090_pdc_pinmux_ops = {
.get_function_name = tz1090_pdc_pinctrl_get_func_name, .get_function_name = tz1090_pdc_pinctrl_get_func_name,
.get_function_groups = tz1090_pdc_pinctrl_get_func_groups, .get_function_groups = tz1090_pdc_pinctrl_get_func_groups,
.enable = tz1090_pdc_pinctrl_enable, .enable = tz1090_pdc_pinctrl_enable,
.disable = tz1090_pdc_pinctrl_disable,
.gpio_request_enable = tz1090_pdc_pinctrl_gpio_request_enable, .gpio_request_enable = tz1090_pdc_pinctrl_gpio_request_enable,
.gpio_disable_free = tz1090_pdc_pinctrl_gpio_disable_free, .gpio_disable_free = tz1090_pdc_pinctrl_gpio_disable_free,
}; };
......
...@@ -1478,63 +1478,6 @@ static int tz1090_pinctrl_enable(struct pinctrl_dev *pctldev, ...@@ -1478,63 +1478,6 @@ static int tz1090_pinctrl_enable(struct pinctrl_dev *pctldev,
return 0; return 0;
} }
/**
* 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. * tz1090_pinctrl_gpio_request_enable() - Put pin in GPIO mode.
* @pctldev: Pin control data * @pctldev: Pin control data
...@@ -1575,7 +1518,6 @@ static struct pinmux_ops tz1090_pinmux_ops = { ...@@ -1575,7 +1518,6 @@ static struct pinmux_ops tz1090_pinmux_ops = {
.get_function_name = tz1090_pinctrl_get_func_name, .get_function_name = tz1090_pinctrl_get_func_name,
.get_function_groups = tz1090_pinctrl_get_func_groups, .get_function_groups = tz1090_pinctrl_get_func_groups,
.enable = tz1090_pinctrl_enable, .enable = tz1090_pinctrl_enable,
.disable = tz1090_pinctrl_disable,
.gpio_request_enable = tz1090_pinctrl_gpio_request_enable, .gpio_request_enable = tz1090_pinctrl_gpio_request_enable,
.gpio_disable_free = tz1090_pinctrl_gpio_disable_free, .gpio_disable_free = tz1090_pinctrl_gpio_disable_free,
}; };
......
...@@ -970,19 +970,6 @@ static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -970,19 +970,6 @@ static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0; 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) static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
{ {
return ARRAY_SIZE(u300_pmx_functions); return ARRAY_SIZE(u300_pmx_functions);
...@@ -1008,7 +995,6 @@ static const struct pinmux_ops u300_pmx_ops = { ...@@ -1008,7 +995,6 @@ static const struct pinmux_ops u300_pmx_ops = {
.get_function_name = u300_pmx_get_func_name, .get_function_name = u300_pmx_get_func_name,
.get_function_groups = u300_pmx_get_groups, .get_function_groups = u300_pmx_get_groups,
.enable = u300_pmx_enable, .enable = u300_pmx_enable,
.disable = u300_pmx_disable,
}; };
static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
......
...@@ -471,7 +471,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) ...@@ -471,7 +471,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
{ {
struct pinctrl_dev *pctldev = setting->pctldev; struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
const struct pinmux_ops *ops = pctldev->desc->pmxops;
int ret = 0; int ret = 0;
const unsigned *pins = NULL; const unsigned *pins = NULL;
unsigned num_pins = 0; unsigned num_pins = 0;
...@@ -518,9 +517,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) ...@@ -518,9 +517,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
pins[i], desc->name, gname); pins[i], desc->name, gname);
} }
} }
if (ops->disable)
ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
} }
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
......
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
# 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
...@@ -230,7 +230,7 @@ static const unsigned int sdc3_data_pins[] = { 95 }; ...@@ -230,7 +230,7 @@ static const unsigned int sdc3_data_pins[] = { 95 };
.pins = gpio##id##_pins, \ .pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \ .npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \ .funcs = (int[]){ \
APQ_MUX_NA, /* gpio mode */ \ APQ_MUX_gpio, \
APQ_MUX_##f1, \ APQ_MUX_##f1, \
APQ_MUX_##f2, \ APQ_MUX_##f2, \
APQ_MUX_##f3, \ APQ_MUX_##f3, \
...@@ -293,6 +293,7 @@ enum apq8064_functions { ...@@ -293,6 +293,7 @@ enum apq8064_functions {
APQ_MUX_cam_mclk, APQ_MUX_cam_mclk,
APQ_MUX_codec_mic_i2s, APQ_MUX_codec_mic_i2s,
APQ_MUX_codec_spkr_i2s, APQ_MUX_codec_spkr_i2s,
APQ_MUX_gpio,
APQ_MUX_gsbi1, APQ_MUX_gsbi1,
APQ_MUX_gsbi2, APQ_MUX_gsbi2,
APQ_MUX_gsbi3, APQ_MUX_gsbi3,
...@@ -335,6 +336,21 @@ static const char * const codec_mic_i2s_groups[] = { ...@@ -335,6 +336,21 @@ static const char * const codec_mic_i2s_groups[] = {
static const char * const codec_spkr_i2s_groups[] = { static const char * const codec_spkr_i2s_groups[] = {
"gpio39", "gpio40", "gpio41", "gpio42" "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[] = { static const char * const gsbi1_groups[] = {
"gpio18", "gpio19", "gpio20", "gpio21" "gpio18", "gpio19", "gpio20", "gpio21"
}; };
...@@ -430,6 +446,7 @@ static const struct msm_function apq8064_functions[] = { ...@@ -430,6 +446,7 @@ static const struct msm_function apq8064_functions[] = {
FUNCTION(cam_mclk), FUNCTION(cam_mclk),
FUNCTION(codec_mic_i2s), FUNCTION(codec_mic_i2s),
FUNCTION(codec_spkr_i2s), FUNCTION(codec_spkr_i2s),
FUNCTION(gpio),
FUNCTION(gsbi1), FUNCTION(gsbi1),
FUNCTION(gsbi2), FUNCTION(gsbi2),
FUNCTION(gsbi3), FUNCTION(gsbi3),
......
...@@ -183,7 +183,7 @@ static const unsigned int sdc3_data_pins[] = { 71 }; ...@@ -183,7 +183,7 @@ static const unsigned int sdc3_data_pins[] = { 71 };
.pins = gpio##id##_pins, \ .pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \ .npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \ .funcs = (int[]){ \
IPQ_MUX_NA, /* gpio mode */ \ IPQ_MUX_gpio, \
IPQ_MUX_##f1, \ IPQ_MUX_##f1, \
IPQ_MUX_##f2, \ IPQ_MUX_##f2, \
IPQ_MUX_##f3, \ IPQ_MUX_##f3, \
...@@ -243,6 +243,7 @@ static const unsigned int sdc3_data_pins[] = { 71 }; ...@@ -243,6 +243,7 @@ static const unsigned int sdc3_data_pins[] = { 71 };
} }
enum ipq8064_functions { enum ipq8064_functions {
IPQ_MUX_gpio,
IPQ_MUX_mdio, IPQ_MUX_mdio,
IPQ_MUX_mi2s, IPQ_MUX_mi2s,
IPQ_MUX_pdm, IPQ_MUX_pdm,
...@@ -291,6 +292,19 @@ enum ipq8064_functions { ...@@ -291,6 +292,19 @@ enum ipq8064_functions {
IPQ_MUX_NA, 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[] = { static const char * const mdio_groups[] = {
"gpio0", "gpio1", "gpio10", "gpio11", "gpio0", "gpio1", "gpio10", "gpio11",
}; };
...@@ -481,6 +495,7 @@ static const char * const ps_hold_groups[] = { ...@@ -481,6 +495,7 @@ static const char * const ps_hold_groups[] = {
}; };
static const struct msm_function ipq8064_functions[] = { static const struct msm_function ipq8064_functions[] = {
FUNCTION(gpio),
FUNCTION(mdio), FUNCTION(mdio),
FUNCTION(ssbi), FUNCTION(ssbi),
FUNCTION(spmi), FUNCTION(spmi),
......
...@@ -27,10 +27,10 @@ ...@@ -27,10 +27,10 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include "core.h" #include "../core.h"
#include "pinconf.h" #include "../pinconf.h"
#include "pinctrl-msm.h" #include "pinctrl-msm.h"
#include "pinctrl-utils.h" #include "../pinctrl-utils.h"
#define MAX_NR_GPIO 300 #define MAX_NR_GPIO 300
...@@ -142,9 +142,6 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev, ...@@ -142,9 +142,6 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
g = &pctrl->soc->groups[group]; g = &pctrl->soc->groups[group];
if (WARN_ON(g->mux_bit < 0))
return -EINVAL;
for (i = 0; i < g->nfuncs; i++) { for (i = 0; i < g->nfuncs; i++) {
if (g->funcs[i] == function) if (g->funcs[i] == function)
break; break;
...@@ -165,36 +162,11 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev, ...@@ -165,36 +162,11 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
return 0; 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 = { static const struct pinmux_ops msm_pinmux_ops = {
.get_functions_count = msm_get_functions_count, .get_functions_count = msm_get_functions_count,
.get_function_name = msm_get_function_name, .get_function_name = msm_get_function_name,
.get_function_groups = msm_get_function_groups, .get_function_groups = msm_get_function_groups,
.enable = msm_pinmux_enable, .enable = msm_pinmux_enable,
.disable = msm_pinmux_disable,
}; };
static int msm_config_reg(struct msm_pinctrl *pctrl, static int msm_config_reg(struct msm_pinctrl *pctrl,
...@@ -206,6 +178,7 @@ static int msm_config_reg(struct msm_pinctrl *pctrl, ...@@ -206,6 +178,7 @@ static int msm_config_reg(struct msm_pinctrl *pctrl,
switch (param) { switch (param) {
case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_DOWN:
case PIN_CONFIG_BIAS_BUS_HOLD:
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
*bit = g->pull_bit; *bit = g->pull_bit;
*mask = 3; *mask = 3;
...@@ -243,6 +216,7 @@ static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -243,6 +216,7 @@ static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
#define MSM_NO_PULL 0 #define MSM_NO_PULL 0
#define MSM_PULL_DOWN 1 #define MSM_PULL_DOWN 1
#define MSM_KEEPER 2
#define MSM_PULL_UP 3 #define MSM_PULL_UP 3
static unsigned msm_regval_to_drive(u32 val) static unsigned msm_regval_to_drive(u32 val)
...@@ -280,6 +254,9 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev, ...@@ -280,6 +254,9 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_DOWN:
arg = arg == MSM_PULL_DOWN; arg = arg == MSM_PULL_DOWN;
break; break;
case PIN_CONFIG_BIAS_BUS_HOLD:
arg = arg == MSM_KEEPER;
break;
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
arg = arg == MSM_PULL_UP; arg = arg == MSM_PULL_UP;
break; break;
...@@ -339,6 +316,9 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, ...@@ -339,6 +316,9 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_DOWN:
arg = MSM_PULL_DOWN; arg = MSM_PULL_DOWN;
break; break;
case PIN_CONFIG_BIAS_BUS_HOLD:
arg = MSM_KEEPER;
break;
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
arg = MSM_PULL_UP; arg = MSM_PULL_UP;
break; break;
......
/*
* 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);
...@@ -342,7 +342,7 @@ static const unsigned int sdc2_data_pins[] = { 151 }; ...@@ -342,7 +342,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
.pins = gpio##id##_pins, \ .pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \ .npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \ .funcs = (int[]){ \
MSM_MUX_NA, /* gpio mode */ \ MSM_MUX_gpio, \
MSM_MUX_##f1, \ MSM_MUX_##f1, \
MSM_MUX_##f2, \ MSM_MUX_##f2, \
MSM_MUX_##f3, \ MSM_MUX_##f3, \
...@@ -402,6 +402,7 @@ static const unsigned int sdc2_data_pins[] = { 151 }; ...@@ -402,6 +402,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
* the pingroup table below. * the pingroup table below.
*/ */
enum msm8x74_functions { enum msm8x74_functions {
MSM_MUX_gpio,
MSM_MUX_cci_i2c0, MSM_MUX_cci_i2c0,
MSM_MUX_cci_i2c1, MSM_MUX_cci_i2c1,
MSM_MUX_blsp_i2c1, MSM_MUX_blsp_i2c1,
...@@ -509,6 +510,31 @@ enum msm8x74_functions { ...@@ -509,6 +510,31 @@ enum msm8x74_functions {
MSM_MUX_NA, 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[] = { static const char * const blsp_uart1_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3" "gpio0", "gpio1", "gpio2", "gpio3"
}; };
...@@ -728,6 +754,7 @@ static const char * const wlan_groups[] = { ...@@ -728,6 +754,7 @@ static const char * const wlan_groups[] = {
static const char * const slimbus_groups[] = { "gpio70", "gpio71" }; static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
static const struct msm_function msm8x74_functions[] = { static const struct msm_function msm8x74_functions[] = {
FUNCTION(gpio),
FUNCTION(cci_i2c0), FUNCTION(cci_i2c0),
FUNCTION(cci_i2c1), FUNCTION(cci_i2c1),
FUNCTION(uim1), FUNCTION(uim1),
......
#
# 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
# 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
...@@ -33,6 +33,18 @@ ...@@ -33,6 +33,18 @@
#include "pinctrl-samsung.h" #include "pinctrl-samsung.h"
#include "pinctrl-exynos.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 = { static struct samsung_pin_bank_type bank_type_off = {
.fld_width = { 4, 1, 2, 2, 2, 2, }, .fld_width = { 4, 1, 2, 2, 2, 2, },
...@@ -50,11 +62,13 @@ static const struct of_device_id exynos_wkup_irq_ids[] = { ...@@ -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_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata; 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 mask;
unsigned long flags; unsigned long flags;
...@@ -67,20 +81,24 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd) ...@@ -67,20 +81,24 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd)
spin_unlock_irqrestore(&bank->slock, flags); 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_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata; 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); 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_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata; 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 mask;
unsigned long flags; unsigned long flags;
...@@ -93,7 +111,7 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd) ...@@ -93,7 +111,7 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
* masked. * masked.
*/ */
if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK) 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); spin_lock_irqsave(&bank->slock, flags);
...@@ -104,16 +122,17 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd) ...@@ -104,16 +122,17 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
spin_unlock_irqrestore(&bank->slock, flags); 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 *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pin_bank_type *bank_type = bank->type; struct samsung_pin_bank_type *bank_type = bank->type;
struct samsung_pinctrl_drv_data *d = bank->drvdata; struct samsung_pinctrl_drv_data *d = bank->drvdata;
struct samsung_pin_ctrl *ctrl = d->ctrl;
unsigned int pin = irqd->hwirq; unsigned int pin = irqd->hwirq;
unsigned int shift = EXYNOS_EINT_CON_LEN * pin; unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
unsigned int con, trig_type; 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 long flags;
unsigned int mask; unsigned int mask;
...@@ -167,12 +186,17 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) ...@@ -167,12 +186,17 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
/* /*
* irq_chip for gpio interrupts. * irq_chip for gpio interrupts.
*/ */
static struct irq_chip exynos_gpio_irq_chip = { static struct exynos_irq_chip exynos_gpio_irq_chip = {
.chip = {
.name = "exynos_gpio_irq_chip", .name = "exynos_gpio_irq_chip",
.irq_unmask = exynos_gpio_irq_unmask, .irq_unmask = exynos_irq_unmask,
.irq_mask = exynos_gpio_irq_mask, .irq_mask = exynos_irq_mask,
.irq_ack = exynos_gpio_irq_ack, .irq_ack = exynos_irq_ack,
.irq_set_type = exynos_gpio_irq_set_type, .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, 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, ...@@ -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; struct samsung_pin_bank *b = h->host_data;
irq_set_chip_data(virq, b); 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); handle_level_irq);
set_irq_flags(virq, IRQF_VALID); set_irq_flags(virq, IRQF_VALID);
return 0; return 0;
...@@ -202,7 +226,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) ...@@ -202,7 +226,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
struct samsung_pin_bank *bank = ctrl->pin_banks; struct samsung_pin_bank *bank = ctrl->pin_banks;
unsigned int svc, group, pin, virq; 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); group = EXYNOS_SVC_GROUP(svc);
pin = svc & EXYNOS_SVC_NUM_MASK; pin = svc & EXYNOS_SVC_NUM_MASK;
...@@ -279,119 +303,6 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) ...@@ -279,119 +303,6 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
return ret; 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; static u32 exynos_eint_wake_mask = 0xffffffff;
u32 exynos_get_eint_wake_mask(void) 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) ...@@ -417,13 +328,18 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
/* /*
* irq_chip for wakeup interrupts * irq_chip for wakeup interrupts
*/ */
static struct irq_chip exynos_wkup_irq_chip = { static struct exynos_irq_chip exynos_wkup_irq_chip = {
.chip = {
.name = "exynos_wkup_irq_chip", .name = "exynos_wkup_irq_chip",
.irq_unmask = exynos_wkup_irq_unmask, .irq_unmask = exynos_irq_unmask,
.irq_mask = exynos_wkup_irq_mask, .irq_mask = exynos_irq_mask,
.irq_ack = exynos_wkup_irq_ack, .irq_ack = exynos_irq_ack,
.irq_set_type = exynos_wkup_irq_set_type, .irq_set_type = exynos_irq_set_type,
.irq_set_wake = exynos_wkup_irq_set_wake, .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 */ /* 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) ...@@ -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 irq_chip *chip = irq_get_chip(irq);
struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq); struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata; struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
struct samsung_pin_ctrl *ctrl = d->ctrl;
unsigned long pend; unsigned long pend;
unsigned long mask; unsigned long mask;
int i; int i;
...@@ -473,8 +388,10 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) ...@@ -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) { for (i = 0; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i]; struct samsung_pin_bank *b = eintd->banks[i];
pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset); pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET
mask = readl(d->virt_base + ctrl->weint_mask + b->eint_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); 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) ...@@ -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, static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw) 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); irq_set_chip_data(virq, h->host_data);
set_irq_flags(virq, IRQF_VALID); set_irq_flags(virq, IRQF_VALID);
return 0; return 0;
...@@ -703,13 +621,6 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = { ...@@ -703,13 +621,6 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = {
/* pin-controller instance 0 data */ /* pin-controller instance 0 data */
.pin_banks = s5pv210_pin_bank, .pin_banks = s5pv210_pin_bank,
.nr_banks = ARRAY_SIZE(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_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init, .eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
...@@ -758,10 +669,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { ...@@ -758,10 +669,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
/* pin-controller instance 0 data */ /* pin-controller instance 0 data */
.pin_banks = exynos3250_pin_banks0, .pin_banks = exynos3250_pin_banks0,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume, .resume = exynos_pinctrl_resume,
...@@ -770,13 +677,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { ...@@ -770,13 +677,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
/* pin-controller instance 1 data */ /* pin-controller instance 1 data */
.pin_banks = exynos3250_pin_banks1, .pin_banks = exynos3250_pin_banks1,
.nr_banks = ARRAY_SIZE(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_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init, .eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
...@@ -843,10 +743,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { ...@@ -843,10 +743,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
/* pin-controller instance 0 data */ /* pin-controller instance 0 data */
.pin_banks = exynos4210_pin_banks0, .pin_banks = exynos4210_pin_banks0,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume, .resume = exynos_pinctrl_resume,
...@@ -855,13 +751,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { ...@@ -855,13 +751,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
/* pin-controller instance 1 data */ /* pin-controller instance 1 data */
.pin_banks = exynos4210_pin_banks1, .pin_banks = exynos4210_pin_banks1,
.nr_banks = ARRAY_SIZE(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_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init, .eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
...@@ -942,10 +831,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { ...@@ -942,10 +831,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 0 data */ /* pin-controller instance 0 data */
.pin_banks = exynos4x12_pin_banks0, .pin_banks = exynos4x12_pin_banks0,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume, .resume = exynos_pinctrl_resume,
...@@ -954,13 +839,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { ...@@ -954,13 +839,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 1 data */ /* pin-controller instance 1 data */
.pin_banks = exynos4x12_pin_banks1, .pin_banks = exynos4x12_pin_banks1,
.nr_banks = ARRAY_SIZE(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_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init, .eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
...@@ -970,10 +848,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { ...@@ -970,10 +848,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 2 data */ /* pin-controller instance 2 data */
.pin_banks = exynos4x12_pin_banks2, .pin_banks = exynos4x12_pin_banks2,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume, .resume = exynos_pinctrl_resume,
...@@ -982,10 +856,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { ...@@ -982,10 +856,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 3 data */ /* pin-controller instance 3 data */
.pin_banks = exynos4x12_pin_banks3, .pin_banks = exynos4x12_pin_banks3,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume, .resume = exynos_pinctrl_resume,
...@@ -1058,13 +928,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { ...@@ -1058,13 +928,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 0 data */ /* pin-controller instance 0 data */
.pin_banks = exynos5250_pin_banks0, .pin_banks = exynos5250_pin_banks0,
.nr_banks = ARRAY_SIZE(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_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init, .eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
...@@ -1074,10 +937,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { ...@@ -1074,10 +937,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 1 data */ /* pin-controller instance 1 data */
.pin_banks = exynos5250_pin_banks1, .pin_banks = exynos5250_pin_banks1,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume, .resume = exynos_pinctrl_resume,
...@@ -1086,10 +945,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { ...@@ -1086,10 +945,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 2 data */ /* pin-controller instance 2 data */
.pin_banks = exynos5250_pin_banks2, .pin_banks = exynos5250_pin_banks2,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume, .resume = exynos_pinctrl_resume,
...@@ -1098,10 +953,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { ...@@ -1098,10 +953,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 3 data */ /* pin-controller instance 3 data */
.pin_banks = exynos5250_pin_banks3, .pin_banks = exynos5250_pin_banks3,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend, .suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume, .resume = exynos_pinctrl_resume,
...@@ -1158,13 +1009,6 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = { ...@@ -1158,13 +1009,6 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
/* pin-controller instance 0 data */ /* pin-controller instance 0 data */
.pin_banks = exynos5260_pin_banks0, .pin_banks = exynos5260_pin_banks0,
.nr_banks = ARRAY_SIZE(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_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init, .eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5260-gpio-ctrl0", .label = "exynos5260-gpio-ctrl0",
...@@ -1172,20 +1016,12 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = { ...@@ -1172,20 +1016,12 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
/* pin-controller instance 1 data */ /* pin-controller instance 1 data */
.pin_banks = exynos5260_pin_banks1, .pin_banks = exynos5260_pin_banks1,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl1", .label = "exynos5260-gpio-ctrl1",
}, { }, {
/* pin-controller instance 2 data */ /* pin-controller instance 2 data */
.pin_banks = exynos5260_pin_banks2, .pin_banks = exynos5260_pin_banks2,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl2", .label = "exynos5260-gpio-ctrl2",
}, },
...@@ -1256,13 +1092,6 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = { ...@@ -1256,13 +1092,6 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
/* pin-controller instance 0 data */ /* pin-controller instance 0 data */
.pin_banks = exynos5420_pin_banks0, .pin_banks = exynos5420_pin_banks0,
.nr_banks = ARRAY_SIZE(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_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init, .eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5420-gpio-ctrl0", .label = "exynos5420-gpio-ctrl0",
...@@ -1270,40 +1099,24 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = { ...@@ -1270,40 +1099,24 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
/* pin-controller instance 1 data */ /* pin-controller instance 1 data */
.pin_banks = exynos5420_pin_banks1, .pin_banks = exynos5420_pin_banks1,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl1", .label = "exynos5420-gpio-ctrl1",
}, { }, {
/* pin-controller instance 2 data */ /* pin-controller instance 2 data */
.pin_banks = exynos5420_pin_banks2, .pin_banks = exynos5420_pin_banks2,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl2", .label = "exynos5420-gpio-ctrl2",
}, { }, {
/* pin-controller instance 3 data */ /* pin-controller instance 3 data */
.pin_banks = exynos5420_pin_banks3, .pin_banks = exynos5420_pin_banks3,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl3", .label = "exynos5420-gpio-ctrl3",
}, { }, {
/* pin-controller instance 4 data */ /* pin-controller instance 4 data */
.pin_banks = exynos5420_pin_banks4, .pin_banks = exynos5420_pin_banks4,
.nr_banks = ARRAY_SIZE(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, .eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl4", .label = "exynos5420-gpio-ctrl4",
}, },
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include "core.h" #include "../core.h"
/* EXYNOS5440 GPIO and Pinctrl register offsets */ /* EXYNOS5440 GPIO and Pinctrl register offsets */
#define GPIO_MUX 0x00 #define GPIO_MUX 0x00
...@@ -371,13 +371,6 @@ static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned select ...@@ -371,13 +371,6 @@ static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned select
return 0; 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() * The calls to gpio_direction_output() and gpio_direction_input()
* leads to this function call (via the pinctrl_gpio_direction_{input|output}() * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
...@@ -395,7 +388,6 @@ static const struct pinmux_ops exynos5440_pinmux_ops = { ...@@ -395,7 +388,6 @@ static const struct pinmux_ops exynos5440_pinmux_ops = {
.get_function_name = exynos5440_pinmux_get_fname, .get_function_name = exynos5440_pinmux_get_fname,
.get_function_groups = exynos5440_pinmux_get_groups, .get_function_groups = exynos5440_pinmux_get_groups,
.enable = exynos5440_pinmux_enable, .enable = exynos5440_pinmux_enable,
.disable = exynos5440_pinmux_disable,
.gpio_set_direction = exynos5440_pinmux_gpio_set_direction, .gpio_set_direction = exynos5440_pinmux_gpio_set_direction,
}; };
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include "core.h" #include "../core.h"
#include "pinctrl-samsung.h" #include "pinctrl-samsung.h"
#define GROUP_SUFFIX "-grp" #define GROUP_SUFFIX "-grp"
...@@ -40,13 +40,14 @@ ...@@ -40,13 +40,14 @@
/* list of all possible config options supported */ /* list of all possible config options supported */
static struct pin_config { static struct pin_config {
char *prop_cfg; const char *property;
unsigned int cfg_type; enum pincfg_type param;
} pcfgs[] = { } cfg_params[] = {
{ "samsung,pin-pud", PINCFG_TYPE_PUD }, { "samsung,pin-pud", PINCFG_TYPE_PUD },
{ "samsung,pin-drv", PINCFG_TYPE_DRV }, { "samsung,pin-drv", PINCFG_TYPE_DRV },
{ "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN }, { "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },
{ "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
{ "samsung,pin-val", PINCFG_TYPE_DAT },
}; };
/* Global list of devices (struct samsung_pinctrl_drv_data) */ /* 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) ...@@ -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); 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) 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 pmx->nr_groups;
return drvdata->nr_groups;
} }
/* return the name of the group selected by the group selector */
static const char *samsung_get_group_name(struct pinctrl_dev *pctldev, 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 pmx->pin_groups[group].name;
return drvdata->pin_groups[selector].name;
} }
/* return the pin numbers associated with the specified group */
static int samsung_get_group_pins(struct pinctrl_dev *pctldev, 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; return 0;
} }
/* create pinctrl_map entries by parsing device tree nodes */ static int reserve_map(struct device *dev, struct pinctrl_map **map,
static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev, unsigned *reserved_maps, unsigned *num_maps,
struct device_node *np, struct pinctrl_map **maps, unsigned reserve)
unsigned *nmaps)
{ {
struct device *dev = pctldev->dev; unsigned old_num = *reserved_maps;
struct pinctrl_map *map; unsigned new_num = *num_maps + reserve;
unsigned long *cfg = NULL; struct pinctrl_map *new_map;
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++;
}
/* if (old_num >= new_num)
* Find out the number of map entries to create. All the config options return 0;
* can be accomadated into a single config map entry.
*/ new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
if (cfg_cnt) if (!new_map) {
map_cnt = 1; dev_err(dev, "krealloc(map) failed\n");
if (of_find_property(np, "samsung,pin-function", NULL)) return -ENOMEM;
map_cnt++;
if (!map_cnt) {
dev_err(dev, "node %s does not have either config or function "
"configurations\n", np->name);
return -EINVAL;
} }
/* Allocate memory for pin-map entries */ memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
if (!map) { *map = new_map;
dev_err(dev, "could not alloc memory for pin-maps\n"); *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; return -ENOMEM;
} }
*nmaps = 0;
/* (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
* Allocate memory for pin group name. The pin group name is derived (*map)[*num_maps].data.configs.group_or_pin = group;
* from the node name from which these map entries are be created. (*map)[*num_maps].data.configs.configs = dup_configs;
*/ (*map)[*num_maps].data.configs.num_configs = num_configs;
gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL); (*num_maps)++;
if (!gname) {
dev_err(dev, "failed to alloc memory for group name\n"); return 0;
goto free_map; }
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;
} }
sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
/* new_configs[old_num] = config;
* don't have config options? then skip over to creating function
* map entries. *configs = new_configs;
*/ *num_configs = new_num;
if (!cfg_cnt)
goto skip_cfgs; return 0;
}
/* Allocate memory for config entries */
cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL); static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
if (!cfg) { struct pinctrl_map *map,
dev_err(dev, "failed to alloc memory for configs\n"); unsigned num_maps)
goto free_gname; {
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);
}
} }
/* Prepare a list of config settings */ reserve = 0;
for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) { if (has_func)
u32 value; reserve++;
if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value)) if (num_configs)
cfg[cfg_cnt++] = reserve++;
PINCFG_PACK(pcfgs[idx].cfg_type, value); 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;
/* create the config map entry */ of_property_for_each_string(np, "samsung,pins", prop, group) {
map[*nmaps].data.configs.group_or_pin = gname; if (has_func) {
map[*nmaps].data.configs.configs = cfg; ret = add_map_mux(map, reserved_maps,
map[*nmaps].data.configs.num_configs = cfg_cnt; num_maps, group, np->full_name);
map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP; if (ret < 0)
*nmaps += 1; goto exit;
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;
} }
sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
map[*nmaps].data.mux.group = gname; if (num_configs) {
map[*nmaps].data.mux.function = fname; ret = add_map_configs(dev, map, reserved_maps,
map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP; num_maps, group, configs,
*nmaps += 1; num_configs);
if (ret < 0)
goto exit;
}
} }
*maps = map; ret = 0;
return 0;
free_cfg: exit:
kfree(cfg); kfree(configs);
free_gname: return ret;
kfree(gname);
free_map:
kfree(map);
return -ENOMEM;
} }
/* free the memory allocated to hold the pin-map table */ static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
static void samsung_dt_free_map(struct pinctrl_dev *pctldev, struct device_node *np_config,
struct pinctrl_map *map, unsigned num_maps) struct pinctrl_map **map,
unsigned *num_maps)
{ {
int idx; struct samsung_pinctrl_drv_data *drvdata;
unsigned reserved_maps;
for (idx = 0; idx < num_maps; idx++) { struct device_node *np;
if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) { int ret;
kfree(map[idx].data.mux.function);
if (!idx) drvdata = pinctrl_dev_get_drvdata(pctldev);
kfree(map[idx].data.mux.group);
} else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) { reserved_maps = 0;
kfree(map[idx].data.configs.configs); *map = NULL;
if (!idx) *num_maps = 0;
kfree(map[idx].data.configs.group_or_pin);
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 */ /* list of pinctrl callbacks for the pinctrl core */
...@@ -286,23 +366,19 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -286,23 +366,19 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group, bool enable) unsigned group, bool enable)
{ {
struct samsung_pinctrl_drv_data *drvdata; struct samsung_pinctrl_drv_data *drvdata;
const unsigned int *pins; struct samsung_pin_bank_type *type;
struct samsung_pin_bank *bank; struct samsung_pin_bank *bank;
void __iomem *reg; void __iomem *reg;
u32 mask, shift, data, pin_offset, cnt; u32 mask, shift, data, pin_offset;
unsigned long flags; unsigned long flags;
const struct samsung_pmx_func *func;
const struct samsung_pin_group *grp;
drvdata = pinctrl_dev_get_drvdata(pctldev); drvdata = pinctrl_dev_get_drvdata(pctldev);
pins = drvdata->pin_groups[group].pins; func = &drvdata->pmx_functions[selector];
grp = &drvdata->pin_groups[group];
/*
* 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, pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base,
&reg, &pin_offset, &bank); &reg, &pin_offset, &bank);
type = bank->type; type = bank->type;
mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
...@@ -318,11 +394,10 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -318,11 +394,10 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
data &= ~(mask << shift); data &= ~(mask << shift);
if (enable) if (enable)
data |= drvdata->pin_groups[group].func << shift; data |= func->val << shift;
writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
spin_unlock_irqrestore(&bank->slock, flags); spin_unlock_irqrestore(&bank->slock, flags);
}
} }
/* enable a specified pinmux by writing to registers */ /* enable a specified pinmux by writing to registers */
...@@ -333,65 +408,12 @@ static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -333,65 +408,12 @@ static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0; 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;
unsigned long flags;
bank = gc_to_pin_bank(range->gc);
type = bank->type;
drvdata = pinctrl_dev_get_drvdata(pctldev);
pin_offset = offset - bank->pin_base;
reg = drvdata->virt_base + bank->pctl_offset +
type->reg_offset[PINCFG_TYPE_FUNC];
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);
data &= ~(mask << shift);
if (!input)
data |= FUNC_OUTPUT << shift;
writel(data, reg);
spin_unlock_irqrestore(&bank->slock, flags);
return 0;
}
/* list of pinmux callbacks for the pinmux vertical in pinctrl core */ /* list of pinmux callbacks for the pinmux vertical in pinctrl core */
static const struct pinmux_ops samsung_pinmux_ops = { static const struct pinmux_ops samsung_pinmux_ops = {
.get_functions_count = samsung_get_functions_count, .get_functions_count = samsung_get_functions_count,
.get_function_name = samsung_pinmux_get_fname, .get_function_name = samsung_pinmux_get_fname,
.get_function_groups = samsung_pinmux_get_groups, .get_function_groups = samsung_pinmux_get_groups,
.enable = samsung_pinmux_enable, .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 */ /* 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) ...@@ -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 * The calls to gpio_direction_output() and gpio_direction_input()
* mux function as 'gpio input' will be handled by the pinctrl susbsystem * leads to this function call.
* interface.
*/ */
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) 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. */
* gpiolib gpio_direction_output callback function. The setting of the pin
* mux function as 'gpio output' will be handled by the pinctrl susbsystem
* interface.
*/
static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
int value) int value)
{ {
samsung_gpio_set(gc, offset, 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) ...@@ -578,87 +634,115 @@ static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
return (virq) ? : -ENXIO; return (virq) ? : -ENXIO;
} }
/* static struct samsung_pin_group *samsung_pinctrl_create_groups(
* Parse the pin names listed in the 'samsung,pins' property and convert it struct device *dev,
* into a list of gpio numbers are create a pin group from it. struct samsung_pinctrl_drv_data *drvdata,
*/ unsigned int *cnt)
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)
{ {
struct device *dev = &pdev->dev; struct pinctrl_desc *ctrldesc = &drvdata->pctl;
struct property *prop; struct samsung_pin_group *groups, *grp;
struct pinctrl_pin_desc const *pdesc = pctl->pins; const struct pinctrl_pin_desc *pdesc;
unsigned int idx = 0, cnt; int i;
const char *pin_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;
}
*npins = of_property_count_strings(cfg_np, "samsung,pins"); *cnt = ctrldesc->npins;
if (IS_ERR_VALUE(*npins)) { return groups;
dev_err(dev, "invalid pin list in %s node", cfg_np->name); }
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; return -EINVAL;
} }
*pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL); func->name = func_np->full_name;
if (!*pin_list) {
dev_err(dev, "failed to allocate memory for pin list\n"); func->groups = devm_kzalloc(dev, npins * sizeof(char *), GFP_KERNEL);
if (!func->groups)
return -ENOMEM; return -ENOMEM;
}
of_property_for_each_string(cfg_np, "samsung,pins", prop, pin_name) { for (i = 0; i < npins; ++i) {
for (cnt = 0; cnt < pctl->npins; cnt++) { const char *gname;
if (pdesc[cnt].name) {
if (!strcmp(pin_name, pdesc[cnt].name)) { ret = of_property_read_string_index(func_np, "samsung,pins",
(*pin_list)[idx++] = pdesc[cnt].number; i, &gname);
break; if (ret) {
} dev_err(dev,
} "failed to read pin name %d from %s node\n",
} i, func_np->name);
if (cnt == pctl->npins) { return ret;
dev_err(dev, "pin %s not valid in %s node\n",
pin_name, cfg_np->name);
devm_kfree(dev, *pin_list);
return -EINVAL;
} }
func->groups[i] = gname;
} }
return 0; func->num_groups = npins;
return 1;
} }
/* static struct samsung_pmx_func *samsung_pinctrl_create_functions(
* Parse the information about all the available pin groups and pin functions struct device *dev,
* from device node of the pin-controller. A pin group is formed with all struct samsung_pinctrl_drv_data *drvdata,
* the pins listed in the "samsung,pins" property. unsigned int *cnt)
*/
static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{ {
struct device *dev = &pdev->dev; struct samsung_pmx_func *functions, *func;
struct device_node *dev_np = dev->of_node; struct device_node *dev_np = dev->of_node;
struct device_node *cfg_np; struct device_node *cfg_np;
struct samsung_pin_group *groups, *grp; unsigned int func_cnt = 0;
struct samsung_pmx_func *functions, *func;
unsigned *pin_list;
unsigned int npins, grp_cnt, func_idx = 0;
char *gname, *fname;
int ret; int ret;
grp_cnt = of_get_child_count(dev_np); /*
if (!grp_cnt) * Iterate over all the child nodes of the pin controller node
return -EINVAL; * 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 (!of_get_child_count(cfg_np)) {
if (!groups) { if (!of_find_property(cfg_np,
dev_err(dev, "failed allocate memory for ping group list\n"); "samsung,pin-function", NULL))
return -EINVAL; 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) { if (!functions) {
dev_err(dev, "failed to allocate memory for function list\n"); dev_err(dev, "failed to allocate memory for function list\n");
return -EINVAL; return ERR_PTR(-EINVAL);
} }
func = functions; func = functions;
...@@ -666,61 +750,68 @@ static int samsung_pinctrl_parse_dt(struct platform_device *pdev, ...@@ -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 * Iterate over all the child nodes of the pin controller node
* and create pin groups and pin function lists. * and create pin groups and pin function lists.
*/ */
func_cnt = 0;
for_each_child_of_node(dev_np, cfg_np) { for_each_child_of_node(dev_np, cfg_np) {
u32 function; struct device_node *func_np;
if (!of_find_property(cfg_np, "samsung,pins", NULL))
continue;
ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np, if (!of_get_child_count(cfg_np)) {
&drvdata->pctl, &pin_list, &npins); ret = samsung_pinctrl_create_function(dev, drvdata,
if (ret) cfg_np, func);
return ret; if (ret < 0)
return ERR_PTR(ret);
if (ret > 0) {
++func;
++func_cnt;
}
continue;
}
/* derive pin group name from the node name */ for_each_child_of_node(cfg_np, func_np) {
gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN, ret = samsung_pinctrl_create_function(dev, drvdata,
GFP_KERNEL); func_np, func);
if (!gname) { if (ret < 0)
dev_err(dev, "failed to alloc memory for group name\n"); return ERR_PTR(ret);
return -ENOMEM; if (ret > 0) {
++func;
++func_cnt;
}
}
} }
sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
grp->name = gname; *cnt = func_cnt;
grp->pins = pin_list; return functions;
grp->num_pins = npins; }
of_property_read_u32(cfg_np, "samsung,pin-function", &function);
grp->func = function;
grp++;
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 */ static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN, struct samsung_pinctrl_drv_data *drvdata)
GFP_KERNEL); {
if (!fname) { struct device *dev = &pdev->dev;
dev_err(dev, "failed to alloc memory for func name\n"); struct samsung_pin_group *groups;
return -ENOMEM; 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);
} }
sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
func->name = fname; functions = samsung_pinctrl_create_functions(dev, drvdata, &func_cnt);
func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL); if (IS_ERR(functions)) {
if (!func->groups) { dev_err(dev, "failed to parse pin functions\n");
dev_err(dev, "failed to alloc memory for group list " return PTR_ERR(groups);
"in pin function");
return -ENOMEM;
}
func->groups[0] = gname;
func->num_groups = 1;
func++;
func_idx++;
} }
drvdata->pin_groups = groups; drvdata->pin_groups = groups;
drvdata->nr_groups = grp_cnt; drvdata->nr_groups = grp_cnt;
drvdata->pmx_functions = functions; drvdata->pmx_functions = functions;
drvdata->nr_functions = func_idx; drvdata->nr_functions = func_cnt;
return 0; return 0;
} }
...@@ -790,7 +881,8 @@ static int samsung_pinctrl_register(struct platform_device *pdev, ...@@ -790,7 +881,8 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
pin_bank = &drvdata->ctrl->pin_banks[bank]; pin_bank = &drvdata->ctrl->pin_banks[bank];
pin_bank->grange.name = pin_bank->name; pin_bank->grange.name = pin_bank->name;
pin_bank->grange.id = bank; 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.base = pin_bank->gpio_chip.base;
pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
pin_bank->grange.gc = &pin_bank->gpio_chip; pin_bank->grange.gc = &pin_bank->gpio_chip;
...@@ -800,7 +892,19 @@ static int samsung_pinctrl_register(struct platform_device *pdev, ...@@ -800,7 +892,19 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
return 0; 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 = { static const struct gpio_chip samsung_gpiolib_chip = {
.request = samsung_gpio_request,
.free = samsung_gpio_free,
.set = samsung_gpio_set, .set = samsung_gpio_set,
.get = samsung_gpio_get, .get = samsung_gpio_get,
.direction_input = samsung_gpio_direction_input, .direction_input = samsung_gpio_direction_input,
......
...@@ -156,13 +156,6 @@ struct samsung_pin_bank { ...@@ -156,13 +156,6 @@ struct samsung_pin_bank {
* @nr_banks: number of pin banks. * @nr_banks: number of pin banks.
* @base: starting system wide pin number. * @base: starting system wide pin number.
* @nr_pins: number of pins supported by the controller. * @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 * @eint_gpio_init: platform specific callback to setup the external gpio
* interrupts for the controller. * interrupts for the controller.
* @eint_wkup_init: platform specific callback to setup the external wakeup * @eint_wkup_init: platform specific callback to setup the external wakeup
...@@ -176,16 +169,6 @@ struct samsung_pin_ctrl { ...@@ -176,16 +169,6 @@ struct samsung_pin_ctrl {
u32 base; u32 base;
u32 nr_pins; 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_gpio_init)(struct samsung_pinctrl_drv_data *);
int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
void (*suspend)(struct samsung_pinctrl_drv_data *); void (*suspend)(struct samsung_pinctrl_drv_data *);
...@@ -248,6 +231,7 @@ struct samsung_pmx_func { ...@@ -248,6 +231,7 @@ struct samsung_pmx_func {
const char *name; const char *name;
const char **groups; const char **groups;
u8 num_groups; u8 num_groups;
u32 val;
}; };
/* list of all exported SoC specific data */ /* list of all exported SoC specific data */
......
...@@ -409,11 +409,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) ...@@ -409,11 +409,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc) int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
{ {
int err; gpiochip_remove(&pfc->gpio->gpio_chip);
int ret; gpiochip_remove(&pfc->func->gpio_chip);
ret = gpiochip_remove(&pfc->gpio->gpio_chip);
err = gpiochip_remove(&pfc->func->gpio_chip);
return ret < 0 ? ret : err; return 0;
} }
...@@ -1726,6 +1726,133 @@ static const unsigned int audio_clkout_mux[] = { ...@@ -1726,6 +1726,133 @@ static const unsigned int audio_clkout_mux[] = {
AUDIO_CLKOUT_MARK, 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 --------------------------------------------------------------------- */ /* - DU --------------------------------------------------------------------- */
static const unsigned int du_rgb666_pins[] = { static const unsigned int du_rgb666_pins[] = {
...@@ -1867,6 +1994,192 @@ static const unsigned int eth_rmii_mux[] = { ...@@ -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_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, 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 ------------------------------------------------------------------- */ /* - I2C0 ------------------------------------------------------------------- */
static const unsigned int i2c0_pins[] = { static const unsigned int i2c0_pins[] = {
/* SCL, SDA */ /* SCL, SDA */
...@@ -3869,6 +4182,20 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { ...@@ -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_b_b),
SH_PFC_PIN_GROUP(audio_clk_c), SH_PFC_PIN_GROUP(audio_clk_c),
SH_PFC_PIN_GROUP(audio_clkout), 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_rgb666),
SH_PFC_PIN_GROUP(du_rgb888), SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0), SH_PFC_PIN_GROUP(du_clk_out_0),
...@@ -3885,6 +4212,32 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { ...@@ -3885,6 +4212,32 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(eth_magic), SH_PFC_PIN_GROUP(eth_magic),
SH_PFC_PIN_GROUP(eth_mdio), SH_PFC_PIN_GROUP(eth_mdio),
SH_PFC_PIN_GROUP(eth_rmii), 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),
SH_PFC_PIN_GROUP(i2c0_b), SH_PFC_PIN_GROUP(i2c0_b),
SH_PFC_PIN_GROUP(i2c0_c), SH_PFC_PIN_GROUP(i2c0_c),
...@@ -4155,6 +4508,30 @@ static const char * const audio_clk_groups[] = { ...@@ -4155,6 +4508,30 @@ static const char * const audio_clk_groups[] = {
"audio_clkout", "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[] = { static const char * const du_groups[] = {
"du_rgb666", "du_rgb666",
"du_rgb888", "du_rgb888",
...@@ -4183,6 +4560,41 @@ static const char * const eth_groups[] = { ...@@ -4183,6 +4560,41 @@ static const char * const eth_groups[] = {
"eth_rmii", "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[] = { static const char * const i2c0_groups[] = {
"i2c0", "i2c0",
"i2c0_b", "i2c0_b",
...@@ -4543,10 +4955,15 @@ static const char * const vin2_groups[] = { ...@@ -4543,10 +4955,15 @@ static const char * const vin2_groups[] = {
static const struct sh_pfc_function pinmux_functions[] = { static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(audio_clk), SH_PFC_FUNCTION(audio_clk),
SH_PFC_FUNCTION(can0),
SH_PFC_FUNCTION(can1),
SH_PFC_FUNCTION(du), SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(du0), SH_PFC_FUNCTION(du0),
SH_PFC_FUNCTION(du1), SH_PFC_FUNCTION(du1),
SH_PFC_FUNCTION(eth), SH_PFC_FUNCTION(eth),
SH_PFC_FUNCTION(hscif0),
SH_PFC_FUNCTION(hscif1),
SH_PFC_FUNCTION(hscif2),
SH_PFC_FUNCTION(i2c0), SH_PFC_FUNCTION(i2c0),
SH_PFC_FUNCTION(i2c1), SH_PFC_FUNCTION(i2c1),
SH_PFC_FUNCTION(i2c2), SH_PFC_FUNCTION(i2c2),
......
...@@ -3842,7 +3842,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc) ...@@ -3842,7 +3842,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
cfg.init_data = &sh73a0_vccq_mc0_init_data; cfg.init_data = &sh73a0_vccq_mc0_init_data;
cfg.driver_data = pfc; 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)) { if (IS_ERR(data->vccq_mc0)) {
ret = PTR_ERR(data->vccq_mc0); ret = PTR_ERR(data->vccq_mc0);
dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n", 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) ...@@ -3855,16 +3856,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
return 0; 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 = { static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
.init = sh73a0_pinmux_soc_init, .init = sh73a0_pinmux_soc_init,
.exit = sh73a0_pinmux_soc_exit,
.get_bias = sh73a0_pinmux_get_bias, .get_bias = sh73a0_pinmux_get_bias,
.set_bias = sh73a0_pinmux_set_bias, .set_bias = sh73a0_pinmux_set_bias,
}; };
......
...@@ -345,27 +345,6 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -345,27 +345,6 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector,
return ret; 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, static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned offset) unsigned offset)
...@@ -464,7 +443,6 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = { ...@@ -464,7 +443,6 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = {
.get_function_name = sh_pfc_get_function_name, .get_function_name = sh_pfc_get_function_name,
.get_function_groups = sh_pfc_get_function_groups, .get_function_groups = sh_pfc_get_function_groups,
.enable = sh_pfc_func_enable, .enable = sh_pfc_func_enable,
.disable = sh_pfc_func_disable,
.gpio_request_enable = sh_pfc_gpio_request_enable, .gpio_request_enable = sh_pfc_gpio_request_enable,
.gpio_disable_free = sh_pfc_gpio_disable_free, .gpio_disable_free = sh_pfc_gpio_disable_free,
.gpio_set_direction = sh_pfc_gpio_set_direction, .gpio_set_direction = sh_pfc_gpio_set_direction,
......
...@@ -186,15 +186,6 @@ static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector, ...@@ -186,15 +186,6 @@ static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector,
return 0; 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) static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
{ {
return sirfsoc_pmxfunc_cnt; return sirfsoc_pmxfunc_cnt;
...@@ -240,7 +231,6 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, ...@@ -240,7 +231,6 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
static struct pinmux_ops sirfsoc_pinmux_ops = { static struct pinmux_ops sirfsoc_pinmux_ops = {
.enable = sirfsoc_pinmux_enable, .enable = sirfsoc_pinmux_enable,
.disable = sirfsoc_pinmux_disable,
.get_functions_count = sirfsoc_pinmux_get_funcs_count, .get_functions_count = sirfsoc_pinmux_get_funcs_count,
.get_function_name = sirfsoc_pinmux_get_func_name, .get_function_name = sirfsoc_pinmux_get_func_name,
.get_function_groups = sirfsoc_pinmux_get_groups, .get_function_groups = sirfsoc_pinmux_get_groups,
......
...@@ -48,6 +48,7 @@ config PINCTRL_SPEAR1340 ...@@ -48,6 +48,7 @@ config PINCTRL_SPEAR1340
config PINCTRL_SPEAR_PLGPIO config PINCTRL_SPEAR_PLGPIO
bool "SPEAr SoC PLGPIO Controller" bool "SPEAr SoC PLGPIO Controller"
depends on GPIOLIB && PINCTRL_SPEAR depends on GPIOLIB && PINCTRL_SPEAR
select GPIOLIB_IRQCHIP
help help
Say yes here to support PLGPIO controller on ST Microelectronics SPEAr Say yes here to support PLGPIO controller on ST Microelectronics SPEAr
SoCs. SoCs.
......
...@@ -11,12 +11,11 @@ ...@@ -11,12 +11,11 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h> #include <linux/gpio/driver.h>
#include <linux/io.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/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm.h> #include <linux/pm.h>
...@@ -54,7 +53,6 @@ struct plgpio_regs { ...@@ -54,7 +53,6 @@ struct plgpio_regs {
* *
* lock: lock for guarding gpio registers * lock: lock for guarding gpio registers
* base: base address of plgpio block * base: base address of plgpio block
* irq_base: irq number of plgpio0
* chip: gpio framework specific chip information structure * chip: gpio framework specific chip information structure
* p2o: function ptr for pin to offset conversion. This is required only for * 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. * machines where mapping b/w pin and offset is not 1-to-1.
...@@ -68,8 +66,6 @@ struct plgpio { ...@@ -68,8 +66,6 @@ struct plgpio {
spinlock_t lock; spinlock_t lock;
void __iomem *base; void __iomem *base;
struct clk *clk; struct clk *clk;
unsigned irq_base;
struct irq_domain *irq_domain;
struct gpio_chip chip; struct gpio_chip chip;
int (*p2o)(int pin); /* pin_to_offset */ int (*p2o)(int pin); /* pin_to_offset */
int (*o2p)(int offset); /* offset_to_pin */ int (*o2p)(int offset); /* offset_to_pin */
...@@ -280,21 +276,12 @@ static void plgpio_free(struct gpio_chip *chip, unsigned offset) ...@@ -280,21 +276,12 @@ static void plgpio_free(struct gpio_chip *chip, unsigned offset)
pinctrl_free_gpio(gpio); 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 */ /* PLGPIO IRQ */
static void plgpio_irq_disable(struct irq_data *d) static void plgpio_irq_disable(struct irq_data *d)
{ {
struct plgpio *plgpio = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
int offset = d->irq - plgpio->irq_base; struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
int offset = d->hwirq;
unsigned long flags; unsigned long flags;
/* get correct offset for "offset" pin */ /* get correct offset for "offset" pin */
...@@ -311,8 +298,9 @@ static void plgpio_irq_disable(struct irq_data *d) ...@@ -311,8 +298,9 @@ static void plgpio_irq_disable(struct irq_data *d)
static void plgpio_irq_enable(struct irq_data *d) static void plgpio_irq_enable(struct irq_data *d)
{ {
struct plgpio *plgpio = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
int offset = d->irq - plgpio->irq_base; struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
int offset = d->hwirq;
unsigned long flags; unsigned long flags;
/* get correct offset for "offset" pin */ /* get correct offset for "offset" pin */
...@@ -329,8 +317,9 @@ static void plgpio_irq_enable(struct irq_data *d) ...@@ -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) static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
{ {
struct plgpio *plgpio = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
int offset = d->irq - plgpio->irq_base; struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
int offset = d->hwirq;
void __iomem *reg_off; void __iomem *reg_off;
unsigned int supported_type = 0, val; unsigned int supported_type = 0, val;
...@@ -369,7 +358,8 @@ static struct irq_chip plgpio_irqchip = { ...@@ -369,7 +358,8 @@ static struct irq_chip plgpio_irqchip = {
static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) 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); struct irq_chip *irqchip = irq_desc_get_chip(desc);
int regs_count, count, pin, offset, i = 0; int regs_count, count, pin, offset, i = 0;
unsigned long pending; unsigned long pending;
...@@ -410,7 +400,8 @@ static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) ...@@ -410,7 +400,8 @@ static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
/* get correct irq line number */ /* get correct irq line number */
pin = i * MAX_GPIO_PER_REG + pin; 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); chained_irq_exit(irqchip, desc);
...@@ -523,10 +514,9 @@ static int plgpio_probe_dt(struct platform_device *pdev, struct plgpio *plgpio) ...@@ -523,10 +514,9 @@ static int plgpio_probe_dt(struct platform_device *pdev, struct plgpio *plgpio)
} }
static int plgpio_probe(struct platform_device *pdev) static int plgpio_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node;
struct plgpio *plgpio; struct plgpio *plgpio;
struct resource *res; struct resource *res;
int ret, irq, i; int ret, irq;
plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL); plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
if (!plgpio) { if (!plgpio) {
...@@ -563,7 +553,6 @@ static int plgpio_probe(struct platform_device *pdev) ...@@ -563,7 +553,6 @@ static int plgpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, plgpio); platform_set_drvdata(pdev, plgpio);
spin_lock_init(&plgpio->lock); spin_lock_init(&plgpio->lock);
plgpio->irq_base = -1;
plgpio->chip.base = -1; plgpio->chip.base = -1;
plgpio->chip.request = plgpio_request; plgpio->chip.request = plgpio_request;
plgpio->chip.free = plgpio_free; plgpio->chip.free = plgpio_free;
...@@ -571,10 +560,10 @@ static int plgpio_probe(struct platform_device *pdev) ...@@ -571,10 +560,10 @@ static int plgpio_probe(struct platform_device *pdev)
plgpio->chip.direction_output = plgpio_direction_output; plgpio->chip.direction_output = plgpio_direction_output;
plgpio->chip.get = plgpio_get_value; plgpio->chip.get = plgpio_get_value;
plgpio->chip.set = plgpio_set_value; plgpio->chip.set = plgpio_set_value;
plgpio->chip.to_irq = plgpio_to_irq;
plgpio->chip.label = dev_name(&pdev->dev); plgpio->chip.label = dev_name(&pdev->dev);
plgpio->chip.dev = &pdev->dev; plgpio->chip.dev = &pdev->dev;
plgpio->chip.owner = THIS_MODULE; plgpio->chip.owner = THIS_MODULE;
plgpio->chip.of_node = pdev->dev.of_node;
if (!IS_ERR(plgpio->clk)) { if (!IS_ERR(plgpio->clk)) {
ret = clk_prepare(plgpio->clk); ret = clk_prepare(plgpio->clk);
...@@ -592,43 +581,32 @@ static int plgpio_probe(struct platform_device *pdev) ...@@ -592,43 +581,32 @@ static int plgpio_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_info(&pdev->dev, "irqs not supported\n"); dev_info(&pdev->dev, "PLGPIO registered without IRQs\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");
return 0; return 0;
} }
plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio, ret = gpiochip_irqchip_add(&plgpio->chip,
plgpio->irq_base, 0, &irq_domain_simple_ops, NULL); &plgpio_irqchip,
if (WARN_ON(!plgpio->irq_domain)) { 0,
dev_err(&pdev->dev, "irq domain init failed\n"); handle_simple_irq,
irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio); IRQ_TYPE_NONE);
ret = -ENXIO; if (ret) {
dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n");
goto remove_gpiochip; goto remove_gpiochip;
} }
irq_set_chained_handler(irq, plgpio_irq_handler); gpiochip_set_chained_irqchip(&plgpio->chip,
for (i = 0; i < plgpio->chip.ngpio; i++) { &plgpio_irqchip,
irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip, irq,
handle_simple_irq); plgpio_irq_handler);
set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
irq_set_chip_data(i + plgpio->irq_base, plgpio);
}
irq_set_handler_data(irq, plgpio);
dev_info(&pdev->dev, "PLGPIO registered with IRQs\n"); dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
return 0; return 0;
remove_gpiochip: remove_gpiochip:
dev_info(&pdev->dev, "Remove gpiochip\n"); dev_info(&pdev->dev, "Remove gpiochip\n");
if (gpiochip_remove(&plgpio->chip)) gpiochip_remove(&plgpio->chip);
dev_err(&pdev->dev, "unable to remove gpiochip\n");
unprepare_clk: unprepare_clk:
if (!IS_ERR(plgpio->clk)) if (!IS_ERR(plgpio->clk))
clk_unprepare(plgpio->clk); clk_unprepare(plgpio->clk);
......
...@@ -274,12 +274,6 @@ static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function, ...@@ -274,12 +274,6 @@ static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
return spear_pinctrl_endisable(pctldev, function, group, true); 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 */ /* gpio with pinmux */
static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx, static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
unsigned pin) unsigned pin)
...@@ -345,7 +339,6 @@ static const struct pinmux_ops spear_pinmux_ops = { ...@@ -345,7 +339,6 @@ static const struct pinmux_ops spear_pinmux_ops = {
.get_function_name = spear_pinctrl_get_func_name, .get_function_name = spear_pinctrl_get_func_name,
.get_function_groups = spear_pinctrl_get_func_groups, .get_function_groups = spear_pinctrl_get_func_groups,
.enable = spear_pinctrl_enable, .enable = spear_pinctrl_enable,
.disable = spear_pinctrl_disable,
.gpio_request_enable = gpio_request_enable, .gpio_request_enable = gpio_request_enable,
.gpio_disable_free = gpio_disable_free, .gpio_disable_free = gpio_disable_free,
}; };
......
if ARCH_SUNXI if ARCH_SUNXI
config PINCTRL_SUNXI
bool
config PINCTRL_SUNXI_COMMON config PINCTRL_SUNXI_COMMON
bool bool
select PINMUX select PINMUX
select GENERIC_PINCONF select GENERIC_PINCONF
config PINCTRL_SUN4I_A10 config PINCTRL_SUN4I_A10
def_bool PINCTRL_SUNXI || MACH_SUN4I def_bool MACH_SUN4I
select PINCTRL_SUNXI_COMMON select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN5I_A10S config PINCTRL_SUN5I_A10S
def_bool PINCTRL_SUNXI || MACH_SUN5I def_bool MACH_SUN5I
select PINCTRL_SUNXI_COMMON select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN5I_A13 config PINCTRL_SUN5I_A13
def_bool PINCTRL_SUNXI || MACH_SUN5I def_bool MACH_SUN5I
select PINCTRL_SUNXI_COMMON select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN6I_A31 config PINCTRL_SUN6I_A31
def_bool PINCTRL_SUNXI || MACH_SUN6I def_bool MACH_SUN6I
select PINCTRL_SUNXI_COMMON select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN6I_A31_R config PINCTRL_SUN6I_A31_R
def_bool PINCTRL_SUNXI || MACH_SUN6I def_bool MACH_SUN6I
depends on RESET_CONTROLLER depends on RESET_CONTROLLER
select PINCTRL_SUNXI_COMMON select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN7I_A20 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 select PINCTRL_SUNXI_COMMON
endif endif
...@@ -8,3 +8,5 @@ obj-$(CONFIG_PINCTRL_SUN5I_A13) += pinctrl-sun5i-a13.o ...@@ -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) += pinctrl-sun6i-a31.o
obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o
obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.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
...@@ -1010,6 +1010,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = { ...@@ -1010,6 +1010,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = { static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = {
.pins = sun4i_a10_pins, .pins = sun4i_a10_pins,
.npins = ARRAY_SIZE(sun4i_a10_pins), .npins = ARRAY_SIZE(sun4i_a10_pins),
.irq_banks = 1,
}; };
static int sun4i_a10_pinctrl_probe(struct platform_device *pdev) static int sun4i_a10_pinctrl_probe(struct platform_device *pdev)
......
...@@ -661,6 +661,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = { ...@@ -661,6 +661,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = {
static const struct sunxi_pinctrl_desc sun5i_a10s_pinctrl_data = { static const struct sunxi_pinctrl_desc sun5i_a10s_pinctrl_data = {
.pins = sun5i_a10s_pins, .pins = sun5i_a10s_pins,
.npins = ARRAY_SIZE(sun5i_a10s_pins), .npins = ARRAY_SIZE(sun5i_a10s_pins),
.irq_banks = 1,
}; };
static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev) static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev)
......
...@@ -330,15 +330,12 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = { ...@@ -330,15 +330,12 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
/* Hole */ /* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 0)), /* EINT0 */ SUNXI_FUNCTION_IRQ(0x6, 0)), /* EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1), SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 1)), /* EINT1 */ SUNXI_FUNCTION_IRQ(0x6, 1)), /* EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2), SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 2)), /* EINT2 */ SUNXI_FUNCTION_IRQ(0x6, 2)), /* EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3), SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
...@@ -382,6 +379,7 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = { ...@@ -382,6 +379,7 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = { static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
.pins = sun5i_a13_pins, .pins = sun5i_a13_pins,
.npins = ARRAY_SIZE(sun5i_a13_pins), .npins = ARRAY_SIZE(sun5i_a13_pins),
.irq_banks = 1,
}; };
static int sun5i_a13_pinctrl_probe(struct platform_device *pdev) static int sun5i_a13_pinctrl_probe(struct platform_device *pdev)
......
...@@ -93,6 +93,7 @@ static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = { ...@@ -93,6 +93,7 @@ static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = {
.pins = sun6i_a31_r_pins, .pins = sun6i_a31_r_pins,
.npins = ARRAY_SIZE(sun6i_a31_r_pins), .npins = ARRAY_SIZE(sun6i_a31_r_pins),
.pin_base = PL_BASE, .pin_base = PL_BASE,
.irq_banks = 2,
}; };
static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev) static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev)
......
...@@ -24,208 +24,244 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = { ...@@ -24,208 +24,244 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */ SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D0 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 1),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD1 */ SUNXI_FUNCTION(0x2, "gmac"), /* TXD1 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D1 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 2),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */ SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D2 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 3),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */ SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D3 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 4),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD4 */ SUNXI_FUNCTION(0x2, "gmac"), /* TXD4 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D4 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 5),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD5 */ SUNXI_FUNCTION(0x2, "gmac"), /* TXD5 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D5 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 6),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD6 */ SUNXI_FUNCTION(0x2, "gmac"), /* TXD6 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D6 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 7),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD7 */ SUNXI_FUNCTION(0x2, "gmac"), /* TXD7 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D7 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 8),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXCLK */ 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_PIN(SUNXI_PINCTRL_PIN(A, 9),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */ SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */
SUNXI_FUNCTION(0x3, "lcd1"), /* D9 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D9 */
SUNXI_FUNCTION(0x4, "mmc3"), /* CMD */ 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_PIN(SUNXI_PINCTRL_PIN(A, 10),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* GTXCLK */ SUNXI_FUNCTION(0x2, "gmac"), /* GTXCLK */
SUNXI_FUNCTION(0x3, "lcd1"), /* D10 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D10 */
SUNXI_FUNCTION(0x4, "mmc3"), /* CLK */ 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_PIN(SUNXI_PINCTRL_PIN(A, 11),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */ SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D11 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D11 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D0 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 12),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */ SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D12 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D12 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D1 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 13),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */ SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D13 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D13 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D2 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 14),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */ SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D14 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D14 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D3 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 15),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD4 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 16),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD5 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 17),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD6 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 18),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD7 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 19),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXDV */ SUNXI_FUNCTION(0x2, "gmac"), /* RXDV */
SUNXI_FUNCTION(0x3, "lcd1"), /* D19 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 20),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXCLK */ SUNXI_FUNCTION(0x2, "gmac"), /* RXCLK */
SUNXI_FUNCTION(0x3, "lcd1"), /* D20 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 21),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXERR */ SUNXI_FUNCTION(0x2, "gmac"), /* TXERR */
SUNXI_FUNCTION(0x3, "lcd1"), /* D21 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 22),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */ SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */
SUNXI_FUNCTION(0x3, "lcd1"), /* D22 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 23),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* COL */ SUNXI_FUNCTION(0x2, "gmac"), /* COL */
SUNXI_FUNCTION(0x3, "lcd1"), /* D23 */ 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_PIN(SUNXI_PINCTRL_PIN(A, 24),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* CRS */ SUNXI_FUNCTION(0x2, "gmac"), /* CRS */
SUNXI_FUNCTION(0x3, "lcd1"), /* CLK */ 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_PIN(SUNXI_PINCTRL_PIN(A, 25),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* CLKIN */ SUNXI_FUNCTION(0x2, "gmac"), /* CLKIN */
SUNXI_FUNCTION(0x3, "lcd1"), /* DE */ 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_PIN(SUNXI_PINCTRL_PIN(A, 26),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* MDC */ 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_PIN(SUNXI_PINCTRL_PIN(A, 27),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* MDIO */ 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 */ /* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0), SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* MCLK */ SUNXI_FUNCTION(0x2, "i2s0"), /* MCLK */
SUNXI_FUNCTION(0x3, "uart3"), /* CTS */ 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_PIN(SUNXI_PINCTRL_PIN(B, 1),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(B, 2),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(B, 3),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(B, 4),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO1 */ 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_PIN(SUNXI_PINCTRL_PIN(B, 5),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO2 */ SUNXI_FUNCTION(0x2, "i2s0"), /* DO2 */
SUNXI_FUNCTION(0x3, "uart3"), /* TX */ 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_PIN(SUNXI_PINCTRL_PIN(B, 6),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO3 */ SUNXI_FUNCTION(0x2, "i2s0"), /* DO3 */
SUNXI_FUNCTION(0x3, "uart3"), /* RX */ 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_PIN(SUNXI_PINCTRL_PIN(B, 7),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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 */ /* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0), SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
...@@ -510,86 +546,103 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = { ...@@ -510,86 +546,103 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* PCLK */ 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_PIN(SUNXI_PINCTRL_PIN(E, 1),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* MCLK */ 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_PIN(SUNXI_PINCTRL_PIN(E, 2),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */ 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_PIN(SUNXI_PINCTRL_PIN(E, 3),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */ 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_PIN(SUNXI_PINCTRL_PIN(E, 4),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D0 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 5),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D1 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 6),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D2 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 7),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D3 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 8),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D4 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 9),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D5 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 10),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D6 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 11),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D7 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 12),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D8 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 13),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D9 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 14),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D10 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 15),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D11 */ 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_PIN(SUNXI_PINCTRL_PIN(E, 16),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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 */ /* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0), SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
...@@ -625,86 +678,105 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = { ...@@ -625,86 +678,105 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 1),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 2),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 3),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 4),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 5),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 6),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 7),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 8),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 9),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 10),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c3"), /* SCK */ 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_PIN(SUNXI_PINCTRL_PIN(G, 11),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c3"), /* SDA */ 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_PIN(SUNXI_PINCTRL_PIN(G, 12),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CS1 */ 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_PIN(SUNXI_PINCTRL_PIN(G, 13),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */ 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_PIN(SUNXI_PINCTRL_PIN(G, 14),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CLK */ 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_PIN(SUNXI_PINCTRL_PIN(G, 15),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */ 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_PIN(SUNXI_PINCTRL_PIN(G, 16),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* MISO */ 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_PIN(SUNXI_PINCTRL_PIN(G, 17),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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_PIN(SUNXI_PINCTRL_PIN(G, 18),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"), 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 */ /* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0), SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x0, "gpio_in"),
...@@ -836,6 +908,7 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = { ...@@ -836,6 +908,7 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
static const struct sunxi_pinctrl_desc sun6i_a31_pinctrl_data = { static const struct sunxi_pinctrl_desc sun6i_a31_pinctrl_data = {
.pins = sun6i_a31_pins, .pins = sun6i_a31_pins,
.npins = ARRAY_SIZE(sun6i_a31_pins), .npins = ARRAY_SIZE(sun6i_a31_pins),
.irq_banks = 4,
}; };
static int sun6i_a31_pinctrl_probe(struct platform_device *pdev) static int sun6i_a31_pinctrl_probe(struct platform_device *pdev)
......
...@@ -1036,6 +1036,7 @@ static const struct sunxi_desc_pin sun7i_a20_pins[] = { ...@@ -1036,6 +1036,7 @@ static const struct sunxi_desc_pin sun7i_a20_pins[] = {
static const struct sunxi_pinctrl_desc sun7i_a20_pinctrl_data = { static const struct sunxi_pinctrl_desc sun7i_a20_pinctrl_data = {
.pins = sun7i_a20_pins, .pins = sun7i_a20_pins,
.npins = ARRAY_SIZE(sun7i_a20_pins), .npins = ARRAY_SIZE(sun7i_a20_pins),
.irq_banks = 1,
}; };
static int sun7i_a20_pinctrl_probe(struct platform_device *pdev) static int sun7i_a20_pinctrl_probe(struct platform_device *pdev)
......
/*
* 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");
/*
* 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");
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#include "../core.h" #include "../core.h"
#include "pinctrl-sunxi.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 * static struct sunxi_pinctrl_group *
sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *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, ...@@ -508,7 +511,7 @@ static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
base = PINS_PER_BANK * gpiospec->args[0]; base = PINS_PER_BANK * gpiospec->args[0];
pin = base + gpiospec->args[1]; pin = base + gpiospec->args[1];
if (pin > (gc->base + gc->ngpio)) if (pin > gc->ngpio)
return -EINVAL; return -EINVAL;
if (flags) if (flags)
...@@ -521,25 +524,61 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset) ...@@ -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_pinctrl *pctl = dev_get_drvdata(chip->dev);
struct sunxi_desc_function *desc; struct sunxi_desc_function *desc;
unsigned pinnum = pctl->desc->pin_base + offset;
unsigned irqnum;
if (offset >= chip->ngpio) if (offset >= chip->ngpio)
return -ENXIO; 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) if (!desc)
return -EINVAL; return -EINVAL;
irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum;
dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", 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, 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);
return irq_find_mapping(pctl->domain, desc->irqnum); 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, static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
unsigned int type)
{ {
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); 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); u32 reg = sunxi_irq_cfg_reg(d->hwirq);
u8 index = sunxi_irq_cfg_offset(d->hwirq); u8 index = sunxi_irq_cfg_offset(d->hwirq);
unsigned long flags; unsigned long flags;
...@@ -566,6 +605,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, ...@@ -566,6 +605,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
return -EINVAL; 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); spin_lock_irqsave(&pctl->lock, flags);
regval = readl(pctl->membase + reg); regval = readl(pctl->membase + reg);
...@@ -577,26 +624,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, ...@@ -577,26 +624,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
return 0; 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); 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); u32 status_reg = sunxi_irq_status_reg(d->hwirq);
u8 status_idx = sunxi_irq_status_offset(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 */ /* Clear the IRQ */
writel(1 << status_idx, pctl->membase + status_reg); writel(1 << status_idx, pctl->membase + status_reg);
spin_unlock_irqrestore(&pctl->lock, flags);
} }
static void sunxi_pinctrl_irq_mask(struct irq_data *d) static void sunxi_pinctrl_irq_mask(struct irq_data *d)
...@@ -619,19 +654,11 @@ 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) static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
{ {
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_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); u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
u8 idx = sunxi_irq_ctrl_offset(d->hwirq); u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
unsigned long flags; unsigned long flags;
u32 val; 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); spin_lock_irqsave(&pctl->lock, flags);
/* Unmask the IRQ */ /* Unmask the IRQ */
...@@ -641,28 +668,60 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d) ...@@ -641,28 +668,60 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
spin_unlock_irqrestore(&pctl->lock, flags); 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 = sunxi_pinctrl_irq_mask,
.irq_mask_ack = sunxi_pinctrl_irq_mask_ack,
.irq_unmask = sunxi_pinctrl_irq_unmask, .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, .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) static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
{ {
struct irq_chip *chip = irq_get_chip(irq); struct irq_chip *chip = irq_get_chip(irq);
struct sunxi_pinctrl *pctl = irq_get_handler_data(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 */ reg = sunxi_irq_status_reg_from_bank(bank);
writel(reg, pctl->membase + IRQ_STATUS_REG); val = readl(pctl->membase + reg);
if (reg) { if (val) {
int irqoffset; int irqoffset;
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
for_each_set_bit(irqoffset, &reg, SUNXI_IRQ_NUMBER) { for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
int pin_irq = irq_find_mapping(pctl->domain, irqoffset); int pin_irq = irq_find_mapping(pctl->domain,
bank * IRQ_PER_BANK + irqoffset);
generic_handle_irq(pin_irq); generic_handle_irq(pin_irq);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
...@@ -730,8 +789,11 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev) ...@@ -730,8 +789,11 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
while (func->name) { while (func->name) {
/* Create interrupt mapping while we're at it */ /* Create interrupt mapping while we're at it */
if (!strcmp(func->name, "irq")) if (!strcmp(func->name, "irq")) {
pctl->irq_array[func->irqnum] = pin->pin.number; int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK;
pctl->irq_array[irqnum] = pin->pin.number;
}
sunxi_pinctrl_add_function(pctl, func->name); sunxi_pinctrl_add_function(pctl, func->name);
func++; func++;
} }
...@@ -801,6 +863,13 @@ int sunxi_pinctrl_init(struct platform_device *pdev, ...@@ -801,6 +863,13 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
pctl->dev = &pdev->dev; pctl->dev = &pdev->dev;
pctl->desc = desc; 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); ret = sunxi_pinctrl_build_state(pdev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "dt probe failed: %d\n", ret); dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
...@@ -869,7 +938,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev, ...@@ -869,7 +938,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
const struct sunxi_desc_pin *pin = pctl->desc->pins + i; const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev), 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); pin->pin.number, 1);
if (ret) if (ret)
goto gpiochip_error; goto gpiochip_error;
...@@ -885,30 +954,51 @@ int sunxi_pinctrl_init(struct platform_device *pdev, ...@@ -885,30 +954,51 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
if (ret) if (ret)
goto gpiochip_error; 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) { if (!pctl->irq) {
ret = -EINVAL; ret = -ENOMEM;
goto clk_error;
}
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; goto clk_error;
} }
}
pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER, pctl->domain = irq_domain_add_linear(node,
&irq_domain_simple_ops, NULL); pctl->desc->irq_banks * IRQ_PER_BANK,
&irq_domain_simple_ops,
NULL);
if (!pctl->domain) { if (!pctl->domain) {
dev_err(&pdev->dev, "Couldn't register IRQ domain\n"); dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
ret = -ENOMEM; ret = -ENOMEM;
goto clk_error; 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); int irqno = irq_create_mapping(pctl->domain, i);
irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip, irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
handle_simple_irq); handle_edge_irq);
irq_set_chip_data(irqno, pctl); irq_set_chip_data(irqno, pctl);
}; };
irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler); for (i = 0; i < pctl->desc->irq_banks; i++) {
irq_set_handler_data(pctl->irq, pctl); /* 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"); dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
...@@ -917,8 +1007,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev, ...@@ -917,8 +1007,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
clk_error: clk_error:
clk_disable_unprepare(clk); clk_disable_unprepare(clk);
gpiochip_error: gpiochip_error:
if (gpiochip_remove(pctl->chip)) gpiochip_remove(pctl->chip);
dev_err(&pdev->dev, "failed to remove gpio chip\n");
pinctrl_error: pinctrl_error:
pinctrl_unregister(pctl->pctl_dev); pinctrl_unregister(pctl->pctl_dev);
return ret; return ret;
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#define PULL_PINS_BITS 2 #define PULL_PINS_BITS 2
#define PULL_PINS_MASK 0x03 #define PULL_PINS_MASK 0x03
#define SUNXI_IRQ_NUMBER 32 #define IRQ_PER_BANK 32
#define IRQ_CFG_REG 0x200 #define IRQ_CFG_REG 0x200
#define IRQ_CFG_IRQ_PER_REG 8 #define IRQ_CFG_IRQ_PER_REG 8
...@@ -68,6 +68,8 @@ ...@@ -68,6 +68,8 @@
#define IRQ_STATUS_IRQ_BITS 1 #define IRQ_STATUS_IRQ_BITS 1
#define IRQ_STATUS_IRQ_MASK ((1 << 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_RISING 0x00
#define IRQ_EDGE_FALLING 0x01 #define IRQ_EDGE_FALLING 0x01
#define IRQ_LEVEL_HIGH 0x02 #define IRQ_LEVEL_HIGH 0x02
...@@ -77,6 +79,7 @@ ...@@ -77,6 +79,7 @@
struct sunxi_desc_function { struct sunxi_desc_function {
const char *name; const char *name;
u8 muxval; u8 muxval;
u8 irqbank;
u8 irqnum; u8 irqnum;
}; };
...@@ -89,6 +92,7 @@ struct sunxi_pinctrl_desc { ...@@ -89,6 +92,7 @@ struct sunxi_pinctrl_desc {
const struct sunxi_desc_pin *pins; const struct sunxi_desc_pin *pins;
int npins; int npins;
unsigned pin_base; unsigned pin_base;
unsigned irq_banks;
}; };
struct sunxi_pinctrl_function { struct sunxi_pinctrl_function {
...@@ -113,8 +117,8 @@ struct sunxi_pinctrl { ...@@ -113,8 +117,8 @@ struct sunxi_pinctrl {
unsigned nfunctions; unsigned nfunctions;
struct sunxi_pinctrl_group *groups; struct sunxi_pinctrl_group *groups;
unsigned ngroups; unsigned ngroups;
int irq; int *irq;
int irq_array[SUNXI_IRQ_NUMBER]; unsigned *irq_array;
spinlock_t lock; spinlock_t lock;
struct pinctrl_dev *pctl_dev; struct pinctrl_dev *pctl_dev;
}; };
...@@ -139,6 +143,14 @@ struct sunxi_pinctrl { ...@@ -139,6 +143,14 @@ struct sunxi_pinctrl {
.irqnum = _irq, \ .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: * The sunXi PIO registers are organized as is:
* 0x00 - 0x0c Muxing values. * 0x00 - 0x0c Muxing values.
...@@ -218,8 +230,10 @@ static inline u32 sunxi_pull_offset(u16 pin) ...@@ -218,8 +230,10 @@ static inline u32 sunxi_pull_offset(u16 pin)
static inline u32 sunxi_irq_cfg_reg(u16 irq) static inline u32 sunxi_irq_cfg_reg(u16 irq)
{ {
u8 reg = irq / IRQ_CFG_IRQ_PER_REG * 0x04; u8 bank = irq / IRQ_PER_BANK;
return reg + IRQ_CFG_REG; 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) static inline u32 sunxi_irq_cfg_offset(u16 irq)
...@@ -228,10 +242,16 @@ 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; 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) static inline u32 sunxi_irq_ctrl_reg(u16 irq)
{ {
u8 reg = irq / IRQ_CTRL_IRQ_PER_REG * 0x04; u8 bank = irq / IRQ_PER_BANK;
return reg + IRQ_CTRL_REG;
return sunxi_irq_ctrl_reg_from_bank(bank);
} }
static inline u32 sunxi_irq_ctrl_offset(u16 irq) static inline u32 sunxi_irq_ctrl_offset(u16 irq)
...@@ -240,10 +260,16 @@ 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; 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) static inline u32 sunxi_irq_status_reg(u16 irq)
{ {
u8 reg = irq / IRQ_STATUS_IRQ_PER_REG * 0x04; u8 bank = irq / IRQ_PER_BANK;
return reg + IRQ_STATUS_REG;
return sunxi_irq_status_reg_from_bank(bank);
} }
static inline u32 sunxi_irq_status_offset(u16 irq) static inline u32 sunxi_irq_status_offset(u16 irq)
......
...@@ -141,17 +141,6 @@ static int wmt_pmx_enable(struct pinctrl_dev *pctldev, ...@@ -141,17 +141,6 @@ static int wmt_pmx_enable(struct pinctrl_dev *pctldev,
return wmt_set_pinmux(data, func_selector, pinnum); 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, static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned offset) unsigned offset)
...@@ -180,7 +169,6 @@ static struct pinmux_ops wmt_pinmux_ops = { ...@@ -180,7 +169,6 @@ static struct pinmux_ops wmt_pinmux_ops = {
.get_function_name = wmt_pmx_get_function_name, .get_function_name = wmt_pmx_get_function_name,
.get_function_groups = wmt_pmx_get_function_groups, .get_function_groups = wmt_pmx_get_function_groups,
.enable = wmt_pmx_enable, .enable = wmt_pmx_enable,
.disable = wmt_pmx_disable,
.gpio_disable_free = wmt_pmx_gpio_disable_free, .gpio_disable_free = wmt_pmx_gpio_disable_free,
.gpio_set_direction = wmt_pmx_gpio_set_direction, .gpio_set_direction = wmt_pmx_gpio_set_direction,
}; };
...@@ -627,8 +615,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev, ...@@ -627,8 +615,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev,
return 0; return 0;
fail_range: fail_range:
if (gpiochip_remove(&data->gpio_chip)) gpiochip_remove(&data->gpio_chip);
dev_err(&pdev->dev, "failed to remove gpio chip\n");
fail_gpio: fail_gpio:
pinctrl_unregister(data->pctl_dev); pinctrl_unregister(data->pctl_dev);
return err; return err;
...@@ -637,12 +624,8 @@ int wmt_pinctrl_probe(struct platform_device *pdev, ...@@ -637,12 +624,8 @@ int wmt_pinctrl_probe(struct platform_device *pdev,
int wmt_pinctrl_remove(struct platform_device *pdev) int wmt_pinctrl_remove(struct platform_device *pdev)
{ {
struct wmt_pinctrl_data *data = platform_get_drvdata(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); pinctrl_unregister(data->pctl_dev);
return 0; return 0;
......
...@@ -70,8 +70,6 @@ struct pinmux_ops { ...@@ -70,8 +70,6 @@ struct pinmux_ops {
unsigned * const num_groups); unsigned * const num_groups);
int (*enable) (struct pinctrl_dev *pctldev, unsigned func_selector, int (*enable) (struct pinctrl_dev *pctldev, unsigned func_selector,
unsigned group_selector); unsigned group_selector);
void (*disable) (struct pinctrl_dev *pctldev, unsigned func_selector,
unsigned group_selector);
int (*gpio_request_enable) (struct pinctrl_dev *pctldev, int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned offset); unsigned offset);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册