]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge tag 'pinctrl-v4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 15:59:10 +0000 (07:59 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 15:59:10 +0000 (07:59 -0800)
Pull pinctrl updates from Linus Walleij:
 "Bulk pin control changes for the v4.10 kernel cycle:

  No core changes this time. Mainly gradual improvement and
  feature growth in the drivers.

  New drivers:

   - New driver for TI DA850/OMAP-L138/AM18XX pinconf

   - The SX150x was moved over from the GPIO subsystem and reimagined as
     a pin control driver with GPIO support in a joint effort by three
     independent users of this hardware. The result was amazingly good!

   - New subdriver for the Oxnas OX820

  Improvements:

   - The sunxi driver now supports the generic pin control bindings
     rather than the sunxi-specific. Add debouncing support to the
     driver.

   - Simplifications in pinctrl-single adding a generic parser.

   - Two downstream fixes and move the Raspberry Pi BCM2835 over to use
     the generic GPIOLIB_IRQCHIP"

* tag 'pinctrl-v4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (92 commits)
  pinctrl: sx150x: use new nested IRQ infrastructure
  pinctrl: sx150x: handle missing 'advanced' reg in sx1504 and sx1505
  pinctrl: sx150x: rename 'reg_advance' to 'reg_advanced'
  pinctrl: sx150x: access the correct bits in the 4-bit regs of sx150[147]
  pinctrl: mt8173: set GPIO16 to usb iddig mode
  pinctrl: bcm2835: switch to GPIOLIB_IRQCHIP
  pinctrl: New driver for TI DA850/OMAP-L138/AM18XX pinconf
  devicetree: bindings: pinctrl: Add binding for ti,da850-pupd
  Documentation: pinctrl: palmas: Add ti,palmas-powerhold-override property definition
  pinctrl: intel: set default handler to be handle_bad_irq()
  pinctrl: sx150x: add support for sx1501, sx1504, sx1505 and sx1507
  pinctrl: sx150x: sort chips by part number
  pinctrl: sx150x: use correct registers for reg_sense (sx1502 and sx1508)
  pinctrl: imx: fix imx_pinctrl_desc initialization
  pinctrl: sx150x: support setting multiple pins at once
  pinctrl: sx150x: various spelling fixes and some white-space cleanup
  pinctrl: mediatek: use builtin_platform_driver
  pinctrl: stm32: use builtin_platform_driver
  pinctrl: sunxi: Testing the wrong variable
  pinctrl: nomadik: split up and comments MC0 pins
  ...

80 files changed:
Documentation/devicetree/bindings/gpio/gpio_oxnas.txt
Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt
Documentation/devicetree/bindings/pinctrl/pinctrl-sx150x.txt
Documentation/devicetree/bindings/pinctrl/qcom,msm8994-pinctrl.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt [new file with mode: 0644]
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/bcm/Kconfig
drivers/pinctrl/bcm/pinctrl-bcm2835.c
drivers/pinctrl/devicetree.c
drivers/pinctrl/devicetree.h
drivers/pinctrl/freescale/pinctrl-imx.c
drivers/pinctrl/intel/pinctrl-baytrail.c
drivers/pinctrl/intel/pinctrl-cherryview.c
drivers/pinctrl/intel/pinctrl-intel.c
drivers/pinctrl/intel/pinctrl-merrifield.c
drivers/pinctrl/mediatek/pinctrl-mt6397.c
drivers/pinctrl/mediatek/pinctrl-mtk-mt8173.h
drivers/pinctrl/meson/Makefile
drivers/pinctrl/meson/pinctrl-meson-gxl.c [new file with mode: 0644]
drivers/pinctrl/meson/pinctrl-meson.c
drivers/pinctrl/meson/pinctrl-meson.h
drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
drivers/pinctrl/pinconf-generic.c
drivers/pinctrl/pinctrl-at91.c
drivers/pinctrl/pinctrl-da850-pupd.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-oxnas.c
drivers/pinctrl/pinctrl-rockchip.c
drivers/pinctrl/pinctrl-single.c
drivers/pinctrl/pinctrl-st.c
drivers/pinctrl/pinctrl-sx150x.c
drivers/pinctrl/pinctrl-zynq.c
drivers/pinctrl/qcom/Kconfig
drivers/pinctrl/qcom/Makefile
drivers/pinctrl/qcom/pinctrl-msm8994.c [new file with mode: 0644]
drivers/pinctrl/samsung/pinctrl-exynos.c
drivers/pinctrl/samsung/pinctrl-exynos.h
drivers/pinctrl/samsung/pinctrl-s3c24xx.c
drivers/pinctrl/samsung/pinctrl-s3c64xx.c
drivers/pinctrl/samsung/pinctrl-samsung.c
drivers/pinctrl/samsung/pinctrl-samsung.h
drivers/pinctrl/sh-pfc/core.c
drivers/pinctrl/sh-pfc/core.h
drivers/pinctrl/sh-pfc/pfc-r8a7778.c
drivers/pinctrl/sh-pfc/pfc-r8a7795.c
drivers/pinctrl/sh-pfc/pfc-r8a7796.c
drivers/pinctrl/sh-pfc/pinctrl.c
drivers/pinctrl/sh-pfc/sh_pfc.h
drivers/pinctrl/stm32/pinctrl-stm32f429.c
drivers/pinctrl/sunxi/pinctrl-gr8.c
drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c
drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c
drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c
drivers/pinctrl/sunxi/pinctrl-sun6i-a31s.c
drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c
drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c
drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c
drivers/pinctrl/sunxi/pinctrl-sunxi.c
drivers/pinctrl/sunxi/pinctrl-sunxi.h
drivers/pinctrl/vt8500/pinctrl-vt8500.c
drivers/pinctrl/vt8500/pinctrl-wm8505.c
drivers/pinctrl/vt8500/pinctrl-wm8650.c
drivers/pinctrl/vt8500/pinctrl-wm8750.c
drivers/pinctrl/vt8500/pinctrl-wm8850.c
drivers/pinctrl/vt8500/pinctrl-wmt.c
drivers/pinctrl/vt8500/pinctrl-wmt.h
include/dt-bindings/gpio/meson-gxl-gpio.h [new file with mode: 0644]
include/dt-bindings/pinctrl/at91.h

index 928ed4f43907cbea4c67f6301e0c04fe01f17b81..966514744df484d5be1af84619199bbc8d199108 100644 (file)
@@ -3,7 +3,7 @@
 Please refer to gpio.txt for generic information regarding GPIO bindings.
 
 Required properties:
- - compatible: "oxsemi,ox810se-gpio"
+ - compatible: "oxsemi,ox810se-gpio" or "oxsemi,ox820-gpio"
  - reg: Base address and length for the device.
  - interrupts: The port interrupt shared by all pins.
  - gpio-controller: Marks the port as GPIO controller.
index 1685821eea41d2094978b1919d12a9216f9ec790..de1378b4efadca8bc6b39c428f486a1c77c3aad0 100644 (file)
@@ -28,6 +28,20 @@ Required properties:
 - reg: Should contain the register physical address and length for the
   pin controller.
 
+- clocks: phandle to the clocks feeding the pin controller:
+  - "apb": the gated APB parent clock
+  - "hosc": the high frequency oscillator in the system
+  - "losc": the low frequency oscillator in the system
+
+Note: For backward compatibility reasons, the hosc and losc clocks are only
+required if you need to use the optional input-debounce property. Any new
+device tree should set them.
+
+Optional properties:
+  - input-debounce: Array of debouncing periods in microseconds. One period per
+    irq bank found in the controller. 0 if no setup required.
+
+
 Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices.
 
@@ -37,6 +51,22 @@ pins it needs, and how they should be configured, with regard to muxer
 configuration, drive strength and pullups. If one of these options is
 not set, its actual value will be unspecified.
 
+This driver supports the generic pin multiplexing and configuration
+bindings. For details on each properties, you can refer to
+./pinctrl-bindings.txt.
+
+Required sub-node properties:
+  - pins
+  - function
+
+Optional sub-node properties:
+  - bias-disable
+  - bias-pull-up
+  - bias-pull-down
+  - drive-strength
+
+*** Deprecated pin configuration and multiplexing binding
+
 Required subnode-properties:
 
 - allwinner,pins: List of strings containing the pin name.
index b7a93e80a3026e75727fe5a1a17fc2611a72cc26..9a8a45d9d8abc284c3108adb4ef6d1355208c415 100644 (file)
@@ -98,6 +98,8 @@ DRIVE_STRENGTH (3 << 5): indicate the drive strength of the pin using the
                                01 - Low
                                10 - Medium
                                11 - High
+OUTPUT         (1 << 7): indicate this pin need to be configured as an output.
+OUTPUT_VAL     (1 << 8): output val (1 = high, 0 = low)
 DEBOUNCE       (1 << 16): indicate this pin needs debounce.
 DEBOUNCE_VAL   (0x3fff << 17): debounce value.
 
index fe7fe0b03cfb06def2242de87fa37e8f2ed990fb..2392557ede2777a2463e76f77e78be4ddadbd607 100644 (file)
@@ -7,6 +7,8 @@ Required properties for the root node:
                      "amlogic,meson8b-aobus-pinctrl"
                      "amlogic,meson-gxbb-periphs-pinctrl"
                      "amlogic,meson-gxbb-aobus-pinctrl"
+                     "amlogic,meson-gxl-periphs-pinctrl"
+                     "amlogic,meson-gxl-aobus-pinctrl"
  - reg: address and size of registers controlling irq functionality
 
 === GPIO sub-nodes ===
index d6074321f730e0ba1efd862ee2df0e0a409eac59..09e81a95bbfd34a48b381830b34b8cfa154dba3c 100644 (file)
@@ -9,7 +9,7 @@ used for a specific device or function. This node represents configurations of
 pins, optional function, and optional mux related configuration.
 
 Required properties for pin controller node:
- - compatible: "oxsemi,ox810se-pinctrl"
+ - compatible: "oxsemi,ox810se-pinctrl" or "oxsemi,ox820-pinctrl"
  - oxsemi,sys-ctrl: a phandle to the system controller syscon node
 
 Required properties for pin configuration sub-nodes:
index b73c96d24f59247da9d0ecbe51225e6f54271619..bf3f7b014724676471a83ef06d3f75a6fb3e54fc 100644 (file)
@@ -97,6 +97,11 @@ For example:
        };
 
 == Pin controller devices ==
+Required properties: See the pin controller driver specific documentation
+
+Optional properties:
+#pinctrl-cells:        Number of pin control cells in addition to the index within the
+               pin controller device instance
 
 Pin controller devices should contain the pin configuration nodes that client
 devices reference.
@@ -119,7 +124,8 @@ For example:
 
 The contents of each of those pin configuration child nodes is defined
 entirely by the binding for the individual pin controller device. There
-exists no common standard for this content.
+exists no common standard for this content. The pinctrl framework only
+provides generic helper bindings that the pin controller driver can use.
 
 The pin configuration nodes need not be direct children of the pin controller
 device; they may be grandchildren, for example. Whether this is legal, and
@@ -156,6 +162,42 @@ state_2_node_a {
        pins = "mfio29", "mfio30";
 };
 
+Optionally an altenative binding can be used if more suitable depending on the
+pin controller hardware. For hardaware where there is a large number of identical
+pin controller instances, naming each pin and function can easily become
+unmaintainable. This is especially the case if the same controller is used for
+different pins and functions depending on the SoC revision and packaging.
+
+For cases like this, the pin controller driver may use pinctrl-pin-array helper
+binding with a hardware based index and a number of pin configuration values:
+
+pincontroller {
+       ... /* Standard DT properties for the device itself elided */
+       #pinctrl-cells = <2>;
+
+       state_0_node_a {
+               pinctrl-pin-array = <
+                       0 A_DELAY_PS(0) G_DELAY_PS(120)
+                       4 A_DELAY_PS(0) G_DELAY_PS(360)
+                       ...
+               >;
+       };
+       ...
+};
+
+Above #pinctrl-cells specifies the number of value cells in addition to the
+index of the registers. This is similar to the interrupts-extended binding with
+one exception. There is no need to specify the phandle for each entry as that
+is already known as the defined pins are always children of the pin controller
+node. Further having the phandle pointing to another pin controller would not
+currently work as the pinctrl framework uses named modes to group pins for each
+pin control device.
+
+The index for pinctrl-pin-array must relate to the hardware for the pinctrl
+registers, and must not be a virtual index of pin instances. The reason for
+this is to avoid mapping of the index in the dts files and the pin controller
+driver as it can change.
+
 == Generic pin configuration node content ==
 
 Many data items that are represented in a pin configuration node are common
index caf297bee1fb4c34ef5151912656f9636fe1565e..c28d4eb83b7687fbb630af467c7b49fb5e7e25f7 100644 (file)
@@ -35,6 +35,15 @@ Optional properties:
 - ti,palmas-enable-dvfs2: Enable DVFS2. Configure pins for DVFS2 mode.
        Selection primary or secondary function associated to GPADC_START
        and SYSEN2 pin/pad for DVFS2 interface
+- ti,palmas-override-powerhold: This is applicable for PMICs for which
+       GPIO7 is configured in POWERHOLD mode which has higher priority
+       over DEV_ON bit and keeps the PMIC supplies on even after the DEV_ON
+       bit is turned off. This property enables driver to over ride the
+       POWERHOLD value to GPIO7 so as to turn off the PMIC in power off
+       scenarios. So for GPIO7 if ti,palmas-override-powerhold is set
+       then the GPIO_7 field should never be muxed to anything else.
+       It should be set to POWERHOLD by default and only in case of
+       power off scenarios the driver will over ride the mux value.
 
 This binding uses the following generic properties as defined in
 pinctrl-bindings.txt:
index c293c8aaac732014c813c5037c3db645d6c7c0ae..bf76867168e9fd39461f07468c5a782a4bdef9ef 100644 (file)
@@ -6,10 +6,15 @@ pin controller, GPIO, and interrupt bindings.
 
 Required properties:
 - compatible: should be one of :
+                       "semtech,sx1501q",
+                       "semtech,sx1502q",
+                       "semtech,sx1503q",
+                       "semtech,sx1504q",
+                       "semtech,sx1505q",
                        "semtech,sx1506q",
+                       "semtech,sx1507q",
                        "semtech,sx1508q",
-                       "semtech,sx1509q",
-                       "semtech,sx1502q".
+                       "semtech,sx1509q".
 
 - reg: The I2C slave address for this device.
 
@@ -27,7 +32,7 @@ Optional properties :
 - interrupt-controller: Marks the device as a interrupt controller.
 
 - semtech,probe-reset: Will trigger a reset of the GPIO expander on probe,
-               only for sx1508q and sx1509q
+               only for sx1507q, sx1508q and sx1509q
 
 The GPIO expander can optionally be used as an interrupt controller, in
 which case it uses the default two cell specifier.
@@ -42,7 +47,7 @@ Optional properties for pin configuration sub-nodes:
  - bias-pull-down: pull down the pin, except the OSCIO pin
  - bias-pull-pin-default: use pin-default pull state, except the OSCIO pin
  - drive-push-pull: drive actively high and low
- - drive-open-drain: drive with open drain only for sx1508q and sx1509q and except the OSCIO pin
+ - drive-open-drain: drive with open drain only for sx1507q, sx1508q and sx1509q and except the OSCIO pin
  - output-low: set the pin to output mode with low level
  - output-high: set the pin to output mode with high level
 
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8994-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8994-pinctrl.txt
new file mode 100644 (file)
index 0000000..13cd629
--- /dev/null
@@ -0,0 +1,177 @@
+Qualcomm MSM8994 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+MSM8994 platform.
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: Should contain one of:
+                   "qcom,msm8992-pinctrl",
+                   "qcom,msm8994-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 arbitrary 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-gpio145
+                       Supports mux, bias and drive-strength
+
+                     sdc1_clk, sdc1_cmd, sdc1_data sdc1_rclk, sdc2_clk,
+                     sdc2_cmd, sdc2_data
+                       Supports bias and drive-strength
+
+- 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_ref_clk,  blsp_i2c1, blsp_i2c2, blsp_i2c3, blsp_i2c4, blsp_i2c5,
+                   blsp_i2c6, blsp_i2c7, blsp_i2c8, blsp_i2c9, blsp_i2c10, blsp_i2c11,
+                   blsp_i2c12, blsp_spi1, blsp_spi1_cs1, blsp_spi1_cs2, blsp_spi1_cs3,
+                   blsp_spi2, blsp_spi2_cs1, blsp_spi2_cs2, blsp_spi2_cs3, blsp_spi3,
+                   blsp_spi4, blsp_spi5, blsp_spi6, blsp_spi7, blsp_spi8, blsp_spi9,
+                   blsp_spi10, blsp_spi10_cs1, blsp_spi10_cs2, blsp_spi10_cs3, blsp_spi11,
+                   blsp_spi12, blsp_uart1, blsp_uart2, blsp_uart3, blsp_uart4, blsp_uart5,
+                   blsp_uart6, blsp_uart7, blsp_uart8, blsp_uart9, blsp_uart10, blsp_uart11,
+                   blsp_uart12, blsp_uim1, blsp_uim2, blsp_uim3, blsp_uim4, blsp_uim5,
+                   blsp_uim6, blsp_uim7, blsp_uim8, blsp_uim9, blsp_uim10, blsp_uim11,
+                   blsp_uim12, blsp11_i2c_scl_b, blsp11_i2c_sda_b, blsp11_uart_rx_b,
+                   blsp11_uart_tx_b, cam_mclk0, cam_mclk1, cam_mclk2, cam_mclk3,
+                   cci_async_in0, cci_async_in1, cci_async_in2, cci_i2c0, cci_i2c1,
+                   cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4,
+                   gcc_gp1_clk_a, gcc_gp1_clk_b, gcc_gp2_clk_a, gcc_gp2_clk_b, gcc_gp3_clk_a,
+                   gcc_gp3_clk_b, gp_mn, gp_pdm0, gp_pdm1, gp_pdm2, gp0_clk,
+                   gp1_clk, gps_tx, gsm_tx, hdmi_cec, hdmi_ddc, hdmi_hpd, hdmi_rcv,
+                   mdp_vsync, mss_lte, nav_pps, nav_tsync, qdss_cti_trig_in_a,
+                   qdss_cti_trig_in_b, qdss_cti_trig_in_c, qdss_cti_trig_in_d,
+                   qdss_cti_trig_out_a, qdss_cti_trig_out_b, qdss_cti_trig_out_c,
+                   qdss_cti_trig_out_d, qdss_traceclk_a, qdss_traceclk_b, qdss_tracectl_a,
+                   qdss_tracectl_b, qdss_tracedata_a, qdss_tracedata_b, qua_mi2s, pci_e0,
+                   pci_e1, pri_mi2s, sdc4, sec_mi2s, slimbus, spkr_i2s, ter_mi2s, tsif1,
+                   tsif2, uim_batt_alarm, uim1, uim2, uim3, uim4, gpio
+
+- 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@fd510000 {
+               compatible = "qcom,msm8994-pinctrl";
+               reg = <0xfd510000 0x4000>;
+               interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+
+               blsp1_uart2_default: blsp1_uart2_default {
+                       pinmux {
+                               pins = "gpio4", "gpio5";
+                               function = "blsp_uart2";
+                       };
+                       pinconf {
+                               pins = "gpio4", "gpio5";
+                               drive-strength = <16>;
+                               bias-disable;
+                       };
+               };
+       };
index c68b9554561f07e47ddebaa2a5f4c068313f6193..4722bc61a1a29c62a909ed581b9727d94cf51f82 100644 (file)
@@ -19,10 +19,11 @@ The pins are grouped into up to 5 individual pin banks which need to be
 defined as gpio sub-nodes of the pinmux controller.
 
 Required properties for iomux controller:
-  - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
-                      "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
-                      "rockchip,rk3228-pinctrl", "rockchip,rk3288-pinctrl"
-                      "rockchip,rk3368-pinctrl", "rockchip,rk3399-pinctrl"
+  - compatible: one of "rockchip,rk1108-pinctrl", "rockchip,rk2928-pinctrl"
+                      "rockchip,rk3066a-pinctrl", "rockchip,rk3066b-pinctrl"
+                      "rockchip,rk3188-pinctrl", "rockchip,rk3228-pinctrl"
+                      "rockchip,rk3288-pinctrl", "rockchip,rk3368-pinctrl"
+                      "rockchip,rk3399-pinctrl"
   - rockchip,grf: phandle referencing a syscon providing the
         "general register files"
 
index d49e22d2a8b5ffa4f3d13b02ce8965d7d70b49b4..1baf19eecabf982d62be1458ea26af8dd7ef8148 100644 (file)
@@ -19,11 +19,30 @@ Required Properties:
   - "samsung,exynos5260-pinctrl": for Exynos5260 compatible pin-controller.
   - "samsung,exynos5410-pinctrl": for Exynos5410 compatible pin-controller.
   - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
+  - "samsung,exynos5433-pinctrl": for Exynos5433 compatible pin-controller.
   - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
 
+  - reg: Second base address of the pin controller if the specific registers
+  of the pin controller are separated into the different base address.
+
+       Eg: GPF[1-5] of Exynos5433 are separated into the two base address.
+       - First base address is for GPAx and GPF[1-5] external interrupt
+         registers.
+       - Second base address is for GPF[1-5] pinctrl registers.
+
+       pinctrl_0: pinctrl@10580000 {
+               compatible = "samsung,exynos5433-pinctrl";
+               reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
+
+               wakeup-interrupt-controller {
+                       compatible = "samsung,exynos7-wakeup-eint";
+                       interrupts = <0 16 0>;
+               };
+       };
+
 - Pin banks as child nodes: Pin banks of the controller are represented by child
   nodes of the controller node. Bank name is taken from name of the node. Each
   bank node must contain following properties:
diff --git a/Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt b/Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
new file mode 100644 (file)
index 0000000..7f29805
--- /dev/null
@@ -0,0 +1,55 @@
+* Pin configuration for TI DA850/OMAP-L138/AM18x
+
+These SoCs have a separate controller for setting bias (internal pullup/down).
+Bias can only be selected for groups rather than individual pins.
+
+Required Properties:
+
+  - compatible: Must be "ti,da850-pupd"
+  - reg: Base address and length of the memory resource used by the pullup/down
+    controller hardware module.
+
+The controller node also acts as a container for pin group configuration nodes.
+The names of these groups are ignored.
+
+Pin Group Node Properties:
+
+- groups: An array of strings, each string containing the name of a pin group.
+          Valid names are "cp0".."cp31".
+
+The pin configuration parameters use the generic pinconf bindings defined in
+pinctrl-bindings.txt in this directory. The supported parameters are
+bias-disable, bias-pull-up, bias-pull-down.
+
+
+Example
+-------
+
+In common dtsi file:
+
+       pinconf: pin-controller@22c00c {
+               compatible = "ti,da850-pupd";
+               reg = <0x22c00c 0x8>;
+       };
+
+In board-specific file:
+
+       &pinconf {
+               pinctrl-0 = <&pinconf_bias_groups>;
+               pinctrl-names = "default";
+
+               pinconf_bias_groups: bias-groups {
+                       pull-up {
+                               groups = "cp30", "cp31";
+                               bias-pull-up;
+                       };
+                       pull-down {
+                               groups = "cp29", "cp28";
+                               bias-pull-down;
+                       };
+                       disable {
+                               groups = "cp27", "cp26";
+                               bias-disable;
+                       };
+               };
+       };
index 801fa8bb05e147cd382211d5e92f37e16bd558e5..54044a8ecbd7f7e923cb44634bf97f4bf97afa38 100644 (file)
@@ -93,6 +93,15 @@ config PINCTRL_AMD
          Requires ACPI/FDT device enumeration code to set up a platform
          device.
 
+config PINCTRL_DA850_PUPD
+       tristate "TI DA850/OMAP-L138/AM18XX pullup/pulldown groups"
+       depends on OF && (ARCH_DAVINCI_DA850 || COMPILE_TEST)
+       select PINCONF
+       select GENERIC_PINCONF
+       help
+         Driver for TI DA850/OMAP-L138/AM18XX pinconf. Used to control
+         pullup/pulldown pin groups.
+
 config PINCTRL_DIGICOLOR
        bool
        depends on OF && (ARCH_DIGICOLOR || COMPILE_TEST)
@@ -171,6 +180,7 @@ config PINCTRL_SX150X
        select PINCONF
        select GENERIC_PINCONF
        select GPIOLIB_IRQCHIP
+       select REGMAP
        help
          Say yes here to provide support for Semtech SX150x-series I2C
          GPIO expanders as pinctrl module.
@@ -223,7 +233,7 @@ config PINCTRL_COH901
 
 config PINCTRL_MAX77620
        tristate "MAX77620/MAX20024 Pincontrol support"
-       depends on MFD_MAX77620
+       depends on MFD_MAX77620 && OF
        select PINMUX
        select GENERIC_PINCONF
        help
index 3b8e6f726acbcecb8dca7c367a57a6e5fbed6de3..25d50a86981d360ad805a3c13a1453e87d7d25cd 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_BF60x)   += pinctrl-adi2-bf60x.o
 obj-$(CONFIG_PINCTRL_AT91)     += pinctrl-at91.o
 obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
 obj-$(CONFIG_PINCTRL_AMD)      += pinctrl-amd.o
+obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
 obj-$(CONFIG_PINCTRL_DIGICOLOR)        += pinctrl-digicolor.o
 obj-$(CONFIG_PINCTRL_FALCON)   += pinctrl-falcon.o
 obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o
index 63246770bd74b9dcd3804cee66a960f2404b7092..8968dd7aebed2133b0103b39d7b752916dbfaab0 100644 (file)
@@ -20,6 +20,7 @@ config PINCTRL_BCM2835
        bool
        select PINMUX
        select PINCONF
+       select GPIOLIB_IRQCHIP
 
 config PINCTRL_IPROC_GPIO
        bool "Broadcom iProc GPIO (with PINCONF) driver"
index fa77165fab2c1348163979da507df17e7168c49b..1bb38d0493eb600fd3ada16aaba46ade8b8c3861 100644 (file)
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
-#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/irqdesc.h>
-#include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of.h>
@@ -47,6 +45,7 @@
 #define MODULE_NAME "pinctrl-bcm2835"
 #define BCM2835_NUM_GPIOS 54
 #define BCM2835_NUM_BANKS 2
+#define BCM2835_NUM_IRQS  3
 
 #define BCM2835_PIN_BITMAP_SZ \
        DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8)
@@ -86,31 +85,23 @@ enum bcm2835_pinconf_pull {
 #define BCM2835_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16)
 #define BCM2835_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff)
 
-struct bcm2835_gpio_irqdata {
-       struct bcm2835_pinctrl *pc;
-       int bank;
-};
-
 struct bcm2835_pinctrl {
        struct device *dev;
        void __iomem *base;
-       int irq[BCM2835_NUM_BANKS];
+       int irq[BCM2835_NUM_IRQS];
 
        /* note: locking assumes each bank will have its own unsigned long */
        unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
        unsigned int irq_type[BCM2835_NUM_GPIOS];
 
        struct pinctrl_dev *pctl_dev;
-       struct irq_domain *irq_domain;
        struct gpio_chip gpio_chip;
        struct pinctrl_gpio_range gpio_range;
 
-       struct bcm2835_gpio_irqdata irq_data[BCM2835_NUM_BANKS];
+       int irq_group[BCM2835_NUM_IRQS];
        spinlock_t irq_lock[BCM2835_NUM_BANKS];
 };
 
-static struct lock_class_key gpio_lock_class;
-
 /* pins are just named GPIO0..GPIO53 */
 #define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a)
 static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
@@ -368,13 +359,6 @@ static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
        return pinctrl_gpio_direction_output(chip->base + offset);
 }
 
-static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-       struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
-
-       return irq_linear_revmap(pc->irq_domain, offset);
-}
-
 static struct gpio_chip bcm2835_gpio_chip = {
        .label = MODULE_NAME,
        .owner = THIS_MODULE,
@@ -385,31 +369,67 @@ static struct gpio_chip bcm2835_gpio_chip = {
        .get_direction = bcm2835_gpio_get_direction,
        .get = bcm2835_gpio_get,
        .set = bcm2835_gpio_set,
-       .to_irq = bcm2835_gpio_to_irq,
        .base = -1,
        .ngpio = BCM2835_NUM_GPIOS,
        .can_sleep = false,
 };
 
-static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id)
+static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
+                                        unsigned int bank, u32 mask)
 {
-       struct bcm2835_gpio_irqdata *irqdata = dev_id;
-       struct bcm2835_pinctrl *pc = irqdata->pc;
-       int bank = irqdata->bank;
        unsigned long events;
        unsigned offset;
        unsigned gpio;
        unsigned int type;
 
        events = bcm2835_gpio_rd(pc, GPEDS0 + bank * 4);
+       events &= mask;
        events &= pc->enabled_irq_map[bank];
        for_each_set_bit(offset, &events, 32) {
                gpio = (32 * bank) + offset;
+               /* FIXME: no clue why the code looks up the type here */
                type = pc->irq_type[gpio];
 
-               generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio));
+               generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irqdomain,
+                                                    gpio));
        }
-       return events ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
+{
+       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+       struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
+       struct irq_chip *host_chip = irq_desc_get_chip(desc);
+       int irq = irq_desc_get_irq(desc);
+       int group;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(pc->irq); i++) {
+               if (pc->irq[i] == irq) {
+                       group = pc->irq_group[i];
+                       break;
+               }
+       }
+       /* This should not happen, every IRQ has a bank */
+       if (i == ARRAY_SIZE(pc->irq))
+               BUG();
+
+       chained_irq_enter(host_chip, desc);
+
+       switch (group) {
+       case 0: /* IRQ0 covers GPIOs 0-27 */
+               bcm2835_gpio_irq_handle_bank(pc, 0, 0x0fffffff);
+               break;
+       case 1: /* IRQ1 covers GPIOs 28-45 */
+               bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
+               bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
+               break;
+       case 2: /* IRQ2 covers GPIOs 46-53 */
+               bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
+               break;
+       }
+
+       chained_irq_exit(host_chip, desc);
 }
 
 static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
@@ -455,7 +475,8 @@ static void bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
 
 static void bcm2835_gpio_irq_enable(struct irq_data *data)
 {
-       struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+       struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
        unsigned gpio = irqd_to_hwirq(data);
        unsigned offset = GPIO_REG_SHIFT(gpio);
        unsigned bank = GPIO_REG_OFFSET(gpio);
@@ -469,7 +490,8 @@ static void bcm2835_gpio_irq_enable(struct irq_data *data)
 
 static void bcm2835_gpio_irq_disable(struct irq_data *data)
 {
-       struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+       struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
        unsigned gpio = irqd_to_hwirq(data);
        unsigned offset = GPIO_REG_SHIFT(gpio);
        unsigned bank = GPIO_REG_OFFSET(gpio);
@@ -575,7 +597,8 @@ static int __bcm2835_gpio_irq_set_type_enabled(struct bcm2835_pinctrl *pc,
 
 static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
 {
-       struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+       struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
        unsigned gpio = irqd_to_hwirq(data);
        unsigned offset = GPIO_REG_SHIFT(gpio);
        unsigned bank = GPIO_REG_OFFSET(gpio);
@@ -601,7 +624,8 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
 
 static void bcm2835_gpio_irq_ack(struct irq_data *data)
 {
-       struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+       struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
        unsigned gpio = irqd_to_hwirq(data);
 
        bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
@@ -644,10 +668,11 @@ static void bcm2835_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
                unsigned offset)
 {
        struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+       struct gpio_chip *chip = &pc->gpio_chip;
        enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
        const char *fname = bcm2835_functions[fsel];
        int value = bcm2835_gpio_get_bit(pc, GPLEV0, offset);
-       int irq = irq_find_mapping(pc->irq_domain, offset);
+       int irq = irq_find_mapping(chip->irqdomain, offset);
 
        seq_printf(s, "function %s in %s; irq %d (%s)",
                fname, value ? "hi" : "lo",
@@ -821,6 +846,16 @@ static const struct pinctrl_ops bcm2835_pctl_ops = {
        .dt_free_map = bcm2835_pctl_dt_free_map,
 };
 
+static int bcm2835_pmx_free(struct pinctrl_dev *pctldev,
+               unsigned offset)
+{
+       struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+       /* disable by setting to GPIO_IN */
+       bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
+       return 0;
+}
+
 static int bcm2835_pmx_get_functions_count(struct pinctrl_dev *pctldev)
 {
        return BCM2835_FSEL_COUNT;
@@ -880,6 +915,7 @@ static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
 }
 
 static const struct pinmux_ops bcm2835_pmx_ops = {
+       .free = bcm2835_pmx_free,
        .get_functions_count = bcm2835_pmx_get_functions_count,
        .get_function_name = bcm2835_pmx_get_function_name,
        .get_function_groups = bcm2835_pmx_get_function_groups,
@@ -917,12 +953,14 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,
 
                bcm2835_gpio_wr(pc, GPPUD, arg & 3);
                /*
-                * Docs say to wait 150 cycles, but not of what. We assume a
-                * 1 MHz clock here, which is pretty slow...
+                * BCM2835 datasheet say to wait 150 cycles, but not of what.
+                * But the VideoCore firmware delay for this operation
+                * based nearly on the same amount of VPU cycles and this clock
+                * runs at 250 MHz.
                 */
-               udelay(150);
+               udelay(1);
                bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit));
-               udelay(150);
+               udelay(1);
                bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0);
        } /* for each config */
 
@@ -980,26 +1018,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
        pc->gpio_chip.parent = dev;
        pc->gpio_chip.of_node = np;
 
-       pc->irq_domain = irq_domain_add_linear(np, BCM2835_NUM_GPIOS,
-                       &irq_domain_simple_ops, NULL);
-       if (!pc->irq_domain) {
-               dev_err(dev, "could not create IRQ domain\n");
-               return -ENOMEM;
-       }
-
-       for (i = 0; i < BCM2835_NUM_GPIOS; i++) {
-               int irq = irq_create_mapping(pc->irq_domain, i);
-               irq_set_lockdep_class(irq, &gpio_lock_class);
-               irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip,
-                               handle_level_irq);
-               irq_set_chip_data(irq, pc);
-       }
-
        for (i = 0; i < BCM2835_NUM_BANKS; i++) {
                unsigned long events;
                unsigned offset;
-               int len;
-               char *name;
 
                /* clear event detection flags */
                bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0);
@@ -1014,24 +1035,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
                for_each_set_bit(offset, &events, 32)
                        bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset));
 
-               pc->irq[i] = irq_of_parse_and_map(np, i);
-               pc->irq_data[i].pc = pc;
-               pc->irq_data[i].bank = i;
                spin_lock_init(&pc->irq_lock[i]);
-
-               len = strlen(dev_name(pc->dev)) + 16;
-               name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
-               if (!name)
-                       return -ENOMEM;
-               snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
-
-               err = devm_request_irq(dev, pc->irq[i],
-                       bcm2835_gpio_irq_handler, IRQF_SHARED,
-                       name, &pc->irq_data[i]);
-               if (err) {
-                       dev_err(dev, "unable to request IRQ %d\n", pc->irq[i]);
-                       return err;
-               }
        }
 
        err = gpiochip_add_data(&pc->gpio_chip, pc);
@@ -1040,6 +1044,29 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
                return err;
        }
 
+       err = gpiochip_irqchip_add(&pc->gpio_chip, &bcm2835_gpio_irq_chip,
+                                  0, handle_level_irq, IRQ_TYPE_NONE);
+       if (err) {
+               dev_info(dev, "could not add irqchip\n");
+               return err;
+       }
+
+       for (i = 0; i < BCM2835_NUM_IRQS; i++) {
+               pc->irq[i] = irq_of_parse_and_map(np, i);
+               pc->irq_group[i] = i;
+               /*
+                * Use the same handler for all groups: this is necessary
+                * since we use one gpiochip to cover all lines - the
+                * irq handler then needs to figure out which group and
+                * bank that was firing the IRQ and look up the per-group
+                * and bank data.
+                */
+               gpiochip_set_chained_irqchip(&pc->gpio_chip,
+                                            &bcm2835_gpio_irq_chip,
+                                            pc->irq[i],
+                                            bcm2835_gpio_irq_handler);
+       }
+
        pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
        if (IS_ERR(pc->pctl_dev)) {
                gpiochip_remove(&pc->gpio_chip);
index 54dad89fc9bfe60b23938cc21f1f198311b7f28a..260908480075a246bf6d311ab83566a9c706486c 100644 (file)
@@ -253,3 +253,147 @@ err:
        pinctrl_dt_free_maps(p);
        return ret;
 }
+
+/*
+ * For pinctrl binding, typically #pinctrl-cells is for the pin controller
+ * device, so either parent or grandparent. See pinctrl-bindings.txt.
+ */
+static int pinctrl_find_cells_size(const struct device_node *np)
+{
+       const char *cells_name = "#pinctrl-cells";
+       int cells_size, error;
+
+       error = of_property_read_u32(np->parent, cells_name, &cells_size);
+       if (error) {
+               error = of_property_read_u32(np->parent->parent,
+                                            cells_name, &cells_size);
+               if (error)
+                       return -ENOENT;
+       }
+
+       return cells_size;
+}
+
+/**
+ * pinctrl_get_list_and_count - Gets the list and it's cell size and number
+ * @np: pointer to device node with the property
+ * @list_name: property that contains the list
+ * @list: pointer for the list found
+ * @cells_size: pointer for the cell size found
+ * @nr_elements: pointer for the number of elements found
+ *
+ * Typically np is a single pinctrl entry containing the list.
+ */
+static int pinctrl_get_list_and_count(const struct device_node *np,
+                                     const char *list_name,
+                                     const __be32 **list,
+                                     int *cells_size,
+                                     int *nr_elements)
+{
+       int size;
+
+       *cells_size = 0;
+       *nr_elements = 0;
+
+       *list = of_get_property(np, list_name, &size);
+       if (!*list)
+               return -ENOENT;
+
+       *cells_size = pinctrl_find_cells_size(np);
+       if (*cells_size < 0)
+               return -ENOENT;
+
+       /* First element is always the index within the pinctrl device */
+       *nr_elements = (size / sizeof(**list)) / (*cells_size + 1);
+
+       return 0;
+}
+
+/**
+ * pinctrl_count_index_with_args - Count number of elements in a pinctrl entry
+ * @np: pointer to device node with the property
+ * @list_name: property that contains the list
+ *
+ * Counts the number of elements in a pinctrl array consisting of an index
+ * within the controller and a number of u32 entries specified for each
+ * entry. Note that device_node is always for the parent pin controller device.
+ */
+int pinctrl_count_index_with_args(const struct device_node *np,
+                                 const char *list_name)
+{
+       const __be32 *list;
+       int size, nr_cells, error;
+
+       error = pinctrl_get_list_and_count(np, list_name, &list,
+                                          &nr_cells, &size);
+       if (error)
+               return error;
+
+       return size;
+}
+EXPORT_SYMBOL_GPL(pinctrl_count_index_with_args);
+
+/**
+ * pinctrl_copy_args - Populates of_phandle_args based on index
+ * @np: pointer to device node with the property
+ * @list: pointer to a list with the elements
+ * @index: entry within the list of elements
+ * @nr_cells: number of cells in the list
+ * @nr_elem: number of elements for each entry in the list
+ * @out_args: returned values
+ *
+ * Populates the of_phandle_args based on the index in the list.
+ */
+static int pinctrl_copy_args(const struct device_node *np,
+                            const __be32 *list,
+                            int index, int nr_cells, int nr_elem,
+                            struct of_phandle_args *out_args)
+{
+       int i;
+
+       memset(out_args, 0, sizeof(*out_args));
+       out_args->np = (struct device_node *)np;
+       out_args->args_count = nr_cells + 1;
+
+       if (index >= nr_elem)
+               return -EINVAL;
+
+       list += index * (nr_cells + 1);
+
+       for (i = 0; i < nr_cells + 1; i++)
+               out_args->args[i] = be32_to_cpup(list++);
+
+       return 0;
+}
+
+/**
+ * pinctrl_parse_index_with_args - Find a node pointed by index in a list
+ * @np: pointer to device node with the property
+ * @list_name: property that contains the list
+ * @index: index within the list
+ * @out_arts: entries in the list pointed by index
+ *
+ * Finds the selected element in a pinctrl array consisting of an index
+ * within the controller and a number of u32 entries specified for each
+ * entry. Note that device_node is always for the parent pin controller device.
+ */
+int pinctrl_parse_index_with_args(const struct device_node *np,
+                                 const char *list_name, int index,
+                                 struct of_phandle_args *out_args)
+{
+       const __be32 *list;
+       int nr_elem, nr_cells, error;
+
+       error = pinctrl_get_list_and_count(np, list_name, &list,
+                                          &nr_cells, &nr_elem);
+       if (error || !nr_cells)
+               return error;
+
+       error = pinctrl_copy_args(np, list, index, nr_cells, nr_elem,
+                                 out_args);
+       if (error)
+               return error;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_parse_index_with_args);
index 760bc4960f586a549eeeb2a1e99a8168864e49dd..c2d1a550585070524a50465b388af4393c7e8d15 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+struct of_phandle_args;
+
 #ifdef CONFIG_OF
 
 void pinctrl_dt_free_maps(struct pinctrl *p);
 int pinctrl_dt_to_map(struct pinctrl *p);
 
+int pinctrl_count_index_with_args(const struct device_node *np,
+                                 const char *list_name);
+
+int pinctrl_parse_index_with_args(const struct device_node *np,
+                                 const char *list_name, int index,
+                                 struct of_phandle_args *out_args);
+
 #else
 
 static inline int pinctrl_dt_to_map(struct pinctrl *p)
@@ -32,4 +41,18 @@ static inline void pinctrl_dt_free_maps(struct pinctrl *p)
 {
 }
 
+static inline int pinctrl_count_index_with_args(const struct device_node *np,
+                                               const char *list_name)
+{
+       return -ENODEV;
+}
+
+static inline int
+pinctrl_parse_index_with_args(const struct device_node *np,
+                             const char *list_name, int index,
+                             struct of_phandle_args *out_args)
+{
+       return -ENODEV;
+}
+
 #endif
index 79c4e14a5a75e94fec9315588896bcfe9a104c11..5ef7e875b50e89a9d39dcfbd67e927b42ff9d087 100644 (file)
@@ -778,10 +778,10 @@ int imx_pinctrl_probe(struct platform_device *pdev,
        imx_pinctrl_desc->name = dev_name(&pdev->dev);
        imx_pinctrl_desc->pins = info->pins;
        imx_pinctrl_desc->npins = info->npins;
-       imx_pinctrl_desc->pctlops = &imx_pctrl_ops,
-       imx_pinctrl_desc->pmxops = &imx_pmx_ops,
-       imx_pinctrl_desc->confops = &imx_pinconf_ops,
-       imx_pinctrl_desc->owner = THIS_MODULE,
+       imx_pinctrl_desc->pctlops = &imx_pctrl_ops;
+       imx_pinctrl_desc->pmxops = &imx_pmx_ops;
+       imx_pinctrl_desc->confops = &imx_pinconf_ops;
+       imx_pinctrl_desc->owner = THIS_MODULE;
 
        ret = imx_pinctrl_probe_dt(pdev, info);
        if (ret) {
index 71bbeb9321bad587504bf5ca4f4c889019b4b9f4..37300634b7d2c853a05f5dcecce6b9d46d187b59 100644 (file)
@@ -1703,7 +1703,7 @@ static int byt_gpio_probe(struct byt_gpio *vg)
        if (irq_rc && irq_rc->start) {
                byt_gpio_irq_init_hw(vg);
                ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
-                                          handle_simple_irq, IRQ_TYPE_NONE);
+                                          handle_bad_irq, IRQ_TYPE_NONE);
                if (ret) {
                        dev_err(&vg->pdev->dev, "failed to add irqchip\n");
                        goto fail;
index c43b1e9a06aff0ba3fa94f49967ca4259ed77ced..5e66860a5e677290a0c649728cc48f852cc408b9 100644 (file)
@@ -762,7 +762,7 @@ static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
                seq_printf(s, "mode %d ", mode);
        }
 
-       seq_printf(s, "ctrl0 0x%08x ctrl1 0x%08x", ctrl0, ctrl1);
+       seq_printf(s, "0x%08x 0x%08x", ctrl0, ctrl1);
 
        if (locked)
                seq_puts(s, " [LOCKED]");
index 01443762e57055b88ea9f1accb0cf6e10eda2978..1e139672f1af9da0fa7ff4af1a919395e2ea6957 100644 (file)
@@ -911,7 +911,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
        }
 
        ret = gpiochip_irqchip_add(&pctrl->chip, &intel_gpio_irqchip, 0,
-                                  handle_simple_irq, IRQ_TYPE_NONE);
+                                  handle_bad_irq, IRQ_TYPE_NONE);
        if (ret) {
                dev_err(pctrl->dev, "failed to add irqchip\n");
                goto fail;
index 7826c7f0cb7cac1959e0c8efb27a0c546f09b060..b21896126f760a5cbae044ab13cba527e9dbfeff 100644 (file)
@@ -814,10 +814,51 @@ static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
        return 0;
 }
 
+static int mrfld_config_group_get(struct pinctrl_dev *pctldev,
+                                 unsigned int group, unsigned long *config)
+{
+       const unsigned int *pins;
+       unsigned int npins;
+       int ret;
+
+       ret = mrfld_get_group_pins(pctldev, group, &pins, &npins);
+       if (ret)
+               return ret;
+
+       ret = mrfld_config_get(pctldev, pins[0], config);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int mrfld_config_group_set(struct pinctrl_dev *pctldev,
+                                 unsigned int group, unsigned long *configs,
+                                 unsigned int num_configs)
+{
+       const unsigned int *pins;
+       unsigned int npins;
+       int i, ret;
+
+       ret = mrfld_get_group_pins(pctldev, group, &pins, &npins);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < npins; i++) {
+               ret = mrfld_config_set(pctldev, pins[i], configs, num_configs);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static const struct pinconf_ops mrfld_pinconf_ops = {
        .is_generic = true,
        .pin_config_get = mrfld_config_get,
        .pin_config_set = mrfld_config_set,
+       .pin_config_group_get = mrfld_config_group_get,
+       .pin_config_group_set = mrfld_config_group_set,
 };
 
 static const struct pinctrl_desc mrfld_pinctrl_desc = {
index 6eccb85c02cd2f764ba43843649c5e6629426225..afcede7e2222161a7f748964f6bd0e6e9ae9572b 100644 (file)
@@ -64,8 +64,4 @@ static struct platform_driver mtk_pinctrl_driver = {
        },
 };
 
-static int __init mtk_pinctrl_init(void)
-{
-       return platform_driver_register(&mtk_pinctrl_driver);
-}
-device_initcall(mtk_pinctrl_init);
+builtin_platform_driver(mtk_pinctrl_driver);
index 13e5b68bfe1b49716bddaa174467ea8bb686da32..9b018fdbeb51f4c4be4dfef9f06f56c4ef08338f 100644 (file)
@@ -201,7 +201,7 @@ static const struct mtk_desc_pin mtk_pins_mt8173[] = {
        MTK_PIN(
                PINCTRL_PIN(16, "IDDIG"),
                NULL, "mt8173",
-               MTK_EINT_FUNCTION(0, 16),
+               MTK_EINT_FUNCTION(1, 16),
                MTK_FUNCTION(0, "GPIO16"),
                MTK_FUNCTION(1, "IDDIG"),
                MTK_FUNCTION(2, "CMFLASH"),
index 24434f139947c045800ea3fd10e3e75869d81692..27c5b5126008b4336175417e1e075f63a6beb957 100644 (file)
@@ -1,2 +1,3 @@
-obj-y  += pinctrl-meson8.o pinctrl-meson8b.o pinctrl-meson-gxbb.o
+obj-y  += pinctrl-meson8.o pinctrl-meson8b.o
+obj-y  += pinctrl-meson-gxbb.o pinctrl-meson-gxl.o
 obj-y  += pinctrl-meson.o
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
new file mode 100644 (file)
index 0000000..25694f7
--- /dev/null
@@ -0,0 +1,589 @@
+/*
+ * Pin controller and GPIO driver for Amlogic Meson GXL.
+ *
+ * Copyright (C) 2016 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dt-bindings/gpio/meson-gxl-gpio.h>
+#include "pinctrl-meson.h"
+
+#define EE_OFF 10
+
+static const struct pinctrl_pin_desc meson_gxl_periphs_pins[] = {
+       MESON_PIN(GPIOZ_0, EE_OFF),
+       MESON_PIN(GPIOZ_1, EE_OFF),
+       MESON_PIN(GPIOZ_2, EE_OFF),
+       MESON_PIN(GPIOZ_3, EE_OFF),
+       MESON_PIN(GPIOZ_4, EE_OFF),
+       MESON_PIN(GPIOZ_5, EE_OFF),
+       MESON_PIN(GPIOZ_6, EE_OFF),
+       MESON_PIN(GPIOZ_7, EE_OFF),
+       MESON_PIN(GPIOZ_8, EE_OFF),
+       MESON_PIN(GPIOZ_9, EE_OFF),
+       MESON_PIN(GPIOZ_10, EE_OFF),
+       MESON_PIN(GPIOZ_11, EE_OFF),
+       MESON_PIN(GPIOZ_12, EE_OFF),
+       MESON_PIN(GPIOZ_13, EE_OFF),
+       MESON_PIN(GPIOZ_14, EE_OFF),
+       MESON_PIN(GPIOZ_15, EE_OFF),
+
+       MESON_PIN(GPIOH_0, EE_OFF),
+       MESON_PIN(GPIOH_1, EE_OFF),
+       MESON_PIN(GPIOH_2, EE_OFF),
+       MESON_PIN(GPIOH_3, EE_OFF),
+       MESON_PIN(GPIOH_4, EE_OFF),
+       MESON_PIN(GPIOH_5, EE_OFF),
+       MESON_PIN(GPIOH_6, EE_OFF),
+       MESON_PIN(GPIOH_7, EE_OFF),
+       MESON_PIN(GPIOH_8, EE_OFF),
+       MESON_PIN(GPIOH_9, EE_OFF),
+
+       MESON_PIN(BOOT_0, EE_OFF),
+       MESON_PIN(BOOT_1, EE_OFF),
+       MESON_PIN(BOOT_2, EE_OFF),
+       MESON_PIN(BOOT_3, EE_OFF),
+       MESON_PIN(BOOT_4, EE_OFF),
+       MESON_PIN(BOOT_5, EE_OFF),
+       MESON_PIN(BOOT_6, EE_OFF),
+       MESON_PIN(BOOT_7, EE_OFF),
+       MESON_PIN(BOOT_8, EE_OFF),
+       MESON_PIN(BOOT_9, EE_OFF),
+       MESON_PIN(BOOT_10, EE_OFF),
+       MESON_PIN(BOOT_11, EE_OFF),
+       MESON_PIN(BOOT_12, EE_OFF),
+       MESON_PIN(BOOT_13, EE_OFF),
+       MESON_PIN(BOOT_14, EE_OFF),
+       MESON_PIN(BOOT_15, EE_OFF),
+
+       MESON_PIN(CARD_0, EE_OFF),
+       MESON_PIN(CARD_1, EE_OFF),
+       MESON_PIN(CARD_2, EE_OFF),
+       MESON_PIN(CARD_3, EE_OFF),
+       MESON_PIN(CARD_4, EE_OFF),
+       MESON_PIN(CARD_5, EE_OFF),
+       MESON_PIN(CARD_6, EE_OFF),
+
+       MESON_PIN(GPIODV_0, EE_OFF),
+       MESON_PIN(GPIODV_1, EE_OFF),
+       MESON_PIN(GPIODV_2, EE_OFF),
+       MESON_PIN(GPIODV_3, EE_OFF),
+       MESON_PIN(GPIODV_4, EE_OFF),
+       MESON_PIN(GPIODV_5, EE_OFF),
+       MESON_PIN(GPIODV_6, EE_OFF),
+       MESON_PIN(GPIODV_7, EE_OFF),
+       MESON_PIN(GPIODV_8, EE_OFF),
+       MESON_PIN(GPIODV_9, EE_OFF),
+       MESON_PIN(GPIODV_10, EE_OFF),
+       MESON_PIN(GPIODV_11, EE_OFF),
+       MESON_PIN(GPIODV_12, EE_OFF),
+       MESON_PIN(GPIODV_13, EE_OFF),
+       MESON_PIN(GPIODV_14, EE_OFF),
+       MESON_PIN(GPIODV_15, EE_OFF),
+       MESON_PIN(GPIODV_16, EE_OFF),
+       MESON_PIN(GPIODV_17, EE_OFF),
+       MESON_PIN(GPIODV_19, EE_OFF),
+       MESON_PIN(GPIODV_20, EE_OFF),
+       MESON_PIN(GPIODV_21, EE_OFF),
+       MESON_PIN(GPIODV_22, EE_OFF),
+       MESON_PIN(GPIODV_23, EE_OFF),
+       MESON_PIN(GPIODV_24, EE_OFF),
+       MESON_PIN(GPIODV_25, EE_OFF),
+       MESON_PIN(GPIODV_26, EE_OFF),
+       MESON_PIN(GPIODV_27, EE_OFF),
+       MESON_PIN(GPIODV_28, EE_OFF),
+       MESON_PIN(GPIODV_29, EE_OFF),
+
+       MESON_PIN(GPIOX_0, EE_OFF),
+       MESON_PIN(GPIOX_1, EE_OFF),
+       MESON_PIN(GPIOX_2, EE_OFF),
+       MESON_PIN(GPIOX_3, EE_OFF),
+       MESON_PIN(GPIOX_4, EE_OFF),
+       MESON_PIN(GPIOX_5, EE_OFF),
+       MESON_PIN(GPIOX_6, EE_OFF),
+       MESON_PIN(GPIOX_7, EE_OFF),
+       MESON_PIN(GPIOX_8, EE_OFF),
+       MESON_PIN(GPIOX_9, EE_OFF),
+       MESON_PIN(GPIOX_10, EE_OFF),
+       MESON_PIN(GPIOX_11, EE_OFF),
+       MESON_PIN(GPIOX_12, EE_OFF),
+       MESON_PIN(GPIOX_13, EE_OFF),
+       MESON_PIN(GPIOX_14, EE_OFF),
+       MESON_PIN(GPIOX_15, EE_OFF),
+       MESON_PIN(GPIOX_16, EE_OFF),
+       MESON_PIN(GPIOX_17, EE_OFF),
+       MESON_PIN(GPIOX_18, EE_OFF),
+
+       MESON_PIN(GPIOCLK_0, EE_OFF),
+       MESON_PIN(GPIOCLK_1, EE_OFF),
+
+       MESON_PIN(GPIO_TEST_N, EE_OFF),
+};
+
+static const unsigned int emmc_nand_d07_pins[] = {
+       PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF),
+       PIN(BOOT_3, EE_OFF), PIN(BOOT_4, EE_OFF), PIN(BOOT_5, EE_OFF),
+       PIN(BOOT_6, EE_OFF), PIN(BOOT_7, EE_OFF),
+};
+static const unsigned int emmc_clk_pins[] = { PIN(BOOT_8, EE_OFF) };
+static const unsigned int emmc_cmd_pins[] = { PIN(BOOT_10, EE_OFF) };
+static const unsigned int emmc_ds_pins[] = { PIN(BOOT_15, EE_OFF) };
+
+static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) };
+static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) };
+static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) };
+static const unsigned int sdcard_d3_pins[] = { PIN(CARD_4, EE_OFF) };
+static const unsigned int sdcard_cmd_pins[] = { PIN(CARD_3, EE_OFF) };
+static const unsigned int sdcard_clk_pins[] = { PIN(CARD_2, EE_OFF) };
+
+static const unsigned int sdio_d0_pins[] = { PIN(GPIOX_0, EE_OFF) };
+static const unsigned int sdio_d1_pins[] = { PIN(GPIOX_1, EE_OFF) };
+static const unsigned int sdio_d2_pins[] = { PIN(GPIOX_2, EE_OFF) };
+static const unsigned int sdio_d3_pins[] = { PIN(GPIOX_3, EE_OFF) };
+static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_4, EE_OFF) };
+static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_5, EE_OFF) };
+static const unsigned int sdio_irq_pins[] = { PIN(GPIOX_7, EE_OFF) };
+
+static const unsigned int nand_ce0_pins[]      = { PIN(BOOT_8, EE_OFF) };
+static const unsigned int nand_ce1_pins[]      = { PIN(BOOT_9, EE_OFF) };
+static const unsigned int nand_rb0_pins[]      = { PIN(BOOT_10, EE_OFF) };
+static const unsigned int nand_ale_pins[]      = { PIN(BOOT_11, EE_OFF) };
+static const unsigned int nand_cle_pins[]      = { PIN(BOOT_12, EE_OFF) };
+static const unsigned int nand_wen_clk_pins[]  = { PIN(BOOT_13, EE_OFF) };
+static const unsigned int nand_ren_wr_pins[]   = { PIN(BOOT_14, EE_OFF) };
+static const unsigned int nand_dqs_pins[]      = { PIN(BOOT_15, EE_OFF) };
+
+static const unsigned int uart_tx_a_pins[]     = { PIN(GPIOX_12, EE_OFF) };
+static const unsigned int uart_rx_a_pins[]     = { PIN(GPIOX_13, EE_OFF) };
+static const unsigned int uart_cts_a_pins[]    = { PIN(GPIOX_14, EE_OFF) };
+static const unsigned int uart_rts_a_pins[]    = { PIN(GPIOX_15, EE_OFF) };
+
+static const unsigned int uart_tx_b_pins[]     = { PIN(GPIODV_24, EE_OFF) };
+static const unsigned int uart_rx_b_pins[]     = { PIN(GPIODV_25, EE_OFF) };
+
+static const unsigned int uart_tx_c_pins[]     = { PIN(GPIOX_8, EE_OFF) };
+static const unsigned int uart_rx_c_pins[]     = { PIN(GPIOX_9, EE_OFF) };
+
+static const unsigned int i2c_sck_a_pins[]     = { PIN(GPIODV_25, EE_OFF) };
+static const unsigned int i2c_sda_a_pins[]     = { PIN(GPIODV_24, EE_OFF) };
+
+static const unsigned int i2c_sck_b_pins[]     = { PIN(GPIODV_27, EE_OFF) };
+static const unsigned int i2c_sda_b_pins[]     = { PIN(GPIODV_26, EE_OFF) };
+
+static const unsigned int i2c_sck_c_pins[]     = { PIN(GPIODV_29, EE_OFF) };
+static const unsigned int i2c_sda_c_pins[]     = { PIN(GPIODV_28, EE_OFF) };
+
+static const unsigned int eth_mdio_pins[]      = { PIN(GPIOZ_0, EE_OFF) };
+static const unsigned int eth_mdc_pins[]       = { PIN(GPIOZ_1, EE_OFF) };
+static const unsigned int eth_clk_rx_clk_pins[]        = { PIN(GPIOZ_2, EE_OFF) };
+static const unsigned int eth_rx_dv_pins[]     = { PIN(GPIOZ_3, EE_OFF) };
+static const unsigned int eth_rxd0_pins[]      = { PIN(GPIOZ_4, EE_OFF) };
+static const unsigned int eth_rxd1_pins[]      = { PIN(GPIOZ_5, EE_OFF) };
+static const unsigned int eth_rxd2_pins[]      = { PIN(GPIOZ_6, EE_OFF) };
+static const unsigned int eth_rxd3_pins[]      = { PIN(GPIOZ_7, EE_OFF) };
+static const unsigned int eth_rgmii_tx_clk_pins[] = { PIN(GPIOZ_8, EE_OFF) };
+static const unsigned int eth_tx_en_pins[]     = { PIN(GPIOZ_9, EE_OFF) };
+static const unsigned int eth_txd0_pins[]      = { PIN(GPIOZ_10, EE_OFF) };
+static const unsigned int eth_txd1_pins[]      = { PIN(GPIOZ_11, EE_OFF) };
+static const unsigned int eth_txd2_pins[]      = { PIN(GPIOZ_12, EE_OFF) };
+static const unsigned int eth_txd3_pins[]      = { PIN(GPIOZ_13, EE_OFF) };
+
+static const unsigned int pwm_e_pins[]         = { PIN(GPIOX_16, EE_OFF) };
+
+static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = {
+       MESON_PIN(GPIOAO_0, 0),
+       MESON_PIN(GPIOAO_1, 0),
+       MESON_PIN(GPIOAO_2, 0),
+       MESON_PIN(GPIOAO_3, 0),
+       MESON_PIN(GPIOAO_4, 0),
+       MESON_PIN(GPIOAO_5, 0),
+       MESON_PIN(GPIOAO_6, 0),
+       MESON_PIN(GPIOAO_7, 0),
+       MESON_PIN(GPIOAO_8, 0),
+       MESON_PIN(GPIOAO_9, 0),
+};
+
+static const unsigned int uart_tx_ao_a_pins[]  = { PIN(GPIOAO_0, 0) };
+static const unsigned int uart_rx_ao_a_pins[]  = { PIN(GPIOAO_1, 0) };
+static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, 0) };
+static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, 0) };
+static const unsigned int uart_tx_ao_b_pins[]  = { PIN(GPIOAO_0, 0) };
+static const unsigned int uart_rx_ao_b_pins[]  = { PIN(GPIOAO_1, 0),
+                                                   PIN(GPIOAO_5, 0) };
+static const unsigned int uart_cts_ao_b_pins[] = { PIN(GPIOAO_2, 0) };
+static const unsigned int uart_rts_ao_b_pins[] = { PIN(GPIOAO_3, 0) };
+
+static const unsigned int remote_input_ao_pins[] = {PIN(GPIOAO_7, 0) };
+
+static struct meson_pmx_group meson_gxl_periphs_groups[] = {
+       GPIO_GROUP(GPIOZ_0, EE_OFF),
+       GPIO_GROUP(GPIOZ_1, EE_OFF),
+       GPIO_GROUP(GPIOZ_2, EE_OFF),
+       GPIO_GROUP(GPIOZ_3, EE_OFF),
+       GPIO_GROUP(GPIOZ_4, EE_OFF),
+       GPIO_GROUP(GPIOZ_5, EE_OFF),
+       GPIO_GROUP(GPIOZ_6, EE_OFF),
+       GPIO_GROUP(GPIOZ_7, EE_OFF),
+       GPIO_GROUP(GPIOZ_8, EE_OFF),
+       GPIO_GROUP(GPIOZ_9, EE_OFF),
+       GPIO_GROUP(GPIOZ_10, EE_OFF),
+       GPIO_GROUP(GPIOZ_11, EE_OFF),
+       GPIO_GROUP(GPIOZ_12, EE_OFF),
+       GPIO_GROUP(GPIOZ_13, EE_OFF),
+       GPIO_GROUP(GPIOZ_14, EE_OFF),
+       GPIO_GROUP(GPIOZ_15, EE_OFF),
+
+       GPIO_GROUP(GPIOH_0, EE_OFF),
+       GPIO_GROUP(GPIOH_1, EE_OFF),
+       GPIO_GROUP(GPIOH_2, EE_OFF),
+       GPIO_GROUP(GPIOH_3, EE_OFF),
+       GPIO_GROUP(GPIOH_4, EE_OFF),
+       GPIO_GROUP(GPIOH_5, EE_OFF),
+       GPIO_GROUP(GPIOH_6, EE_OFF),
+       GPIO_GROUP(GPIOH_7, EE_OFF),
+       GPIO_GROUP(GPIOH_8, EE_OFF),
+       GPIO_GROUP(GPIOH_9, EE_OFF),
+
+       GPIO_GROUP(BOOT_0, EE_OFF),
+       GPIO_GROUP(BOOT_1, EE_OFF),
+       GPIO_GROUP(BOOT_2, EE_OFF),
+       GPIO_GROUP(BOOT_3, EE_OFF),
+       GPIO_GROUP(BOOT_4, EE_OFF),
+       GPIO_GROUP(BOOT_5, EE_OFF),
+       GPIO_GROUP(BOOT_6, EE_OFF),
+       GPIO_GROUP(BOOT_7, EE_OFF),
+       GPIO_GROUP(BOOT_8, EE_OFF),
+       GPIO_GROUP(BOOT_9, EE_OFF),
+       GPIO_GROUP(BOOT_10, EE_OFF),
+       GPIO_GROUP(BOOT_11, EE_OFF),
+       GPIO_GROUP(BOOT_12, EE_OFF),
+       GPIO_GROUP(BOOT_13, EE_OFF),
+       GPIO_GROUP(BOOT_14, EE_OFF),
+       GPIO_GROUP(BOOT_15, EE_OFF),
+
+       GPIO_GROUP(CARD_0, EE_OFF),
+       GPIO_GROUP(CARD_1, EE_OFF),
+       GPIO_GROUP(CARD_2, EE_OFF),
+       GPIO_GROUP(CARD_3, EE_OFF),
+       GPIO_GROUP(CARD_4, EE_OFF),
+       GPIO_GROUP(CARD_5, EE_OFF),
+       GPIO_GROUP(CARD_6, EE_OFF),
+
+       GPIO_GROUP(GPIODV_0, EE_OFF),
+       GPIO_GROUP(GPIODV_1, EE_OFF),
+       GPIO_GROUP(GPIODV_2, EE_OFF),
+       GPIO_GROUP(GPIODV_3, EE_OFF),
+       GPIO_GROUP(GPIODV_4, EE_OFF),
+       GPIO_GROUP(GPIODV_5, EE_OFF),
+       GPIO_GROUP(GPIODV_6, EE_OFF),
+       GPIO_GROUP(GPIODV_7, EE_OFF),
+       GPIO_GROUP(GPIODV_8, EE_OFF),
+       GPIO_GROUP(GPIODV_9, EE_OFF),
+       GPIO_GROUP(GPIODV_10, EE_OFF),
+       GPIO_GROUP(GPIODV_11, EE_OFF),
+       GPIO_GROUP(GPIODV_12, EE_OFF),
+       GPIO_GROUP(GPIODV_13, EE_OFF),
+       GPIO_GROUP(GPIODV_14, EE_OFF),
+       GPIO_GROUP(GPIODV_15, EE_OFF),
+       GPIO_GROUP(GPIODV_16, EE_OFF),
+       GPIO_GROUP(GPIODV_17, EE_OFF),
+       GPIO_GROUP(GPIODV_19, EE_OFF),
+       GPIO_GROUP(GPIODV_20, EE_OFF),
+       GPIO_GROUP(GPIODV_21, EE_OFF),
+       GPIO_GROUP(GPIODV_22, EE_OFF),
+       GPIO_GROUP(GPIODV_23, EE_OFF),
+       GPIO_GROUP(GPIODV_24, EE_OFF),
+       GPIO_GROUP(GPIODV_25, EE_OFF),
+       GPIO_GROUP(GPIODV_26, EE_OFF),
+       GPIO_GROUP(GPIODV_27, EE_OFF),
+       GPIO_GROUP(GPIODV_28, EE_OFF),
+       GPIO_GROUP(GPIODV_29, EE_OFF),
+
+       GPIO_GROUP(GPIOX_0, EE_OFF),
+       GPIO_GROUP(GPIOX_1, EE_OFF),
+       GPIO_GROUP(GPIOX_2, EE_OFF),
+       GPIO_GROUP(GPIOX_3, EE_OFF),
+       GPIO_GROUP(GPIOX_4, EE_OFF),
+       GPIO_GROUP(GPIOX_5, EE_OFF),
+       GPIO_GROUP(GPIOX_6, EE_OFF),
+       GPIO_GROUP(GPIOX_7, EE_OFF),
+       GPIO_GROUP(GPIOX_8, EE_OFF),
+       GPIO_GROUP(GPIOX_9, EE_OFF),
+       GPIO_GROUP(GPIOX_10, EE_OFF),
+       GPIO_GROUP(GPIOX_11, EE_OFF),
+       GPIO_GROUP(GPIOX_12, EE_OFF),
+       GPIO_GROUP(GPIOX_13, EE_OFF),
+       GPIO_GROUP(GPIOX_14, EE_OFF),
+       GPIO_GROUP(GPIOX_15, EE_OFF),
+       GPIO_GROUP(GPIOX_16, EE_OFF),
+       GPIO_GROUP(GPIOX_17, EE_OFF),
+       GPIO_GROUP(GPIOX_18, EE_OFF),
+
+       GPIO_GROUP(GPIOCLK_0, EE_OFF),
+       GPIO_GROUP(GPIOCLK_1, EE_OFF),
+
+       GPIO_GROUP(GPIO_TEST_N, EE_OFF),
+
+       /* Bank X */
+       GROUP(sdio_d0,          5,      31),
+       GROUP(sdio_d1,          5,      30),
+       GROUP(sdio_d2,          5,      29),
+       GROUP(sdio_d3,          5,      28),
+       GROUP(sdio_cmd,         5,      27),
+       GROUP(sdio_clk,         5,      26),
+       GROUP(sdio_irq,         5,      24),
+       GROUP(uart_tx_a,        5,      19),
+       GROUP(uart_rx_a,        5,      18),
+       GROUP(uart_cts_a,       5,      17),
+       GROUP(uart_rts_a,       5,      16),
+       GROUP(uart_tx_c,        5,      13),
+       GROUP(uart_rx_c,        5,      12),
+       GROUP(pwm_e,            5,      15),
+
+       /* Bank Z */
+       GROUP(eth_mdio,         4,      22),
+       GROUP(eth_mdc,          4,      23),
+       GROUP(eth_clk_rx_clk,   4,      21),
+       GROUP(eth_rx_dv,        4,      20),
+       GROUP(eth_rxd0,         4,      19),
+       GROUP(eth_rxd1,         4,      18),
+       GROUP(eth_rxd2,         4,      17),
+       GROUP(eth_rxd3,         4,      16),
+       GROUP(eth_rgmii_tx_clk, 4,      15),
+       GROUP(eth_tx_en,        4,      14),
+       GROUP(eth_txd0,         4,      13),
+       GROUP(eth_txd1,         4,      12),
+       GROUP(eth_txd2,         4,      11),
+       GROUP(eth_txd3,         4,      10),
+
+       /* Bank DV */
+       GROUP(uart_tx_b,        2,      16),
+       GROUP(uart_rx_b,        2,      15),
+       GROUP(i2c_sck_a,        1,      15),
+       GROUP(i2c_sda_a,        1,      14),
+       GROUP(i2c_sck_b,        1,      13),
+       GROUP(i2c_sda_b,        1,      12),
+       GROUP(i2c_sck_c,        1,      11),
+       GROUP(i2c_sda_c,        1,      10),
+
+       /* Bank BOOT */
+       GROUP(emmc_nand_d07,    7,      31),
+       GROUP(emmc_clk,         7,      30),
+       GROUP(emmc_cmd,         7,      29),
+       GROUP(emmc_ds,          7,      28),
+       GROUP(nand_ce0,         7,      7),
+       GROUP(nand_ce1,         7,      6),
+       GROUP(nand_rb0,         7,      5),
+       GROUP(nand_ale,         7,      4),
+       GROUP(nand_cle,         7,      3),
+       GROUP(nand_wen_clk,     7,      2),
+       GROUP(nand_ren_wr,      7,      1),
+       GROUP(nand_dqs,         7,      0),
+
+       /* Bank CARD */
+       GROUP(sdcard_d1,        6,      5),
+       GROUP(sdcard_d0,        6,      4),
+       GROUP(sdcard_d3,        6,      1),
+       GROUP(sdcard_d2,        6,      0),
+       GROUP(sdcard_cmd,       6,      2),
+       GROUP(sdcard_clk,       6,      3),
+};
+
+static struct meson_pmx_group meson_gxl_aobus_groups[] = {
+       GPIO_GROUP(GPIOAO_0, 0),
+       GPIO_GROUP(GPIOAO_1, 0),
+       GPIO_GROUP(GPIOAO_2, 0),
+       GPIO_GROUP(GPIOAO_3, 0),
+       GPIO_GROUP(GPIOAO_4, 0),
+       GPIO_GROUP(GPIOAO_5, 0),
+       GPIO_GROUP(GPIOAO_6, 0),
+       GPIO_GROUP(GPIOAO_7, 0),
+       GPIO_GROUP(GPIOAO_8, 0),
+       GPIO_GROUP(GPIOAO_9, 0),
+
+       /* bank AO */
+       GROUP(uart_tx_ao_b,     0,      26),
+       GROUP(uart_rx_ao_b,     0,      25),
+       GROUP(uart_tx_ao_a,     0,      12),
+       GROUP(uart_rx_ao_a,     0,      11),
+       GROUP(uart_cts_ao_a,    0,      10),
+       GROUP(uart_rts_ao_a,    0,      9),
+       GROUP(uart_cts_ao_b,    0,      8),
+       GROUP(uart_rts_ao_b,    0,      7),
+       GROUP(remote_input_ao,  0,      0),
+};
+
+static const char * const gpio_periphs_groups[] = {
+       "GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4",
+       "GPIOZ_5", "GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9",
+       "GPIOZ_10", "GPIOZ_11", "GPIOZ_12", "GPIOZ_13", "GPIOZ_14",
+       "GPIOZ_15",
+
+       "GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4",
+       "GPIOH_5", "GPIOH_6", "GPIOH_7", "GPIOH_8", "GPIOH_9",
+
+       "BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4",
+       "BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9",
+       "BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14",
+       "BOOT_15",
+
+       "CARD_0", "CARD_1", "CARD_2", "CARD_3", "CARD_4",
+       "CARD_5", "CARD_6",
+
+       "GPIODV_0", "GPIODV_1", "GPIODV_2", "GPIODV_3", "GPIODV_4",
+       "GPIODV_5", "GPIODV_6", "GPIODV_7", "GPIODV_8", "GPIODV_9",
+       "GPIODV_10", "GPIODV_11", "GPIODV_12", "GPIODV_13", "GPIODV_14",
+       "GPIODV_15", "GPIODV_16", "GPIODV_17", "GPIODV_18", "GPIODV_19",
+       "GPIODV_20", "GPIODV_21", "GPIODV_22", "GPIODV_23", "GPIODV_24",
+       "GPIODV_25", "GPIODV_26", "GPIODV_27", "GPIODV_28", "GPIODV_29",
+
+       "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
+       "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
+       "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
+       "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18",
+
+       "GPIO_TEST_N",
+};
+
+static const char * const emmc_groups[] = {
+       "emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
+};
+
+static const char * const sdcard_groups[] = {
+       "sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
+       "sdcard_cmd", "sdcard_clk",
+};
+
+static const char * const sdio_groups[] = {
+       "sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3",
+       "sdio_cmd", "sdio_clk", "sdio_irq",
+};
+
+static const char * const nand_groups[] = {
+       "nand_ce0", "nand_ce1", "nand_rb0", "nand_ale", "nand_cle",
+       "nand_wen_clk", "nand_ren_wr", "nand_dqs",
+};
+
+static const char * const uart_a_groups[] = {
+       "uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a",
+};
+
+static const char * const uart_b_groups[] = {
+       "uart_tx_b", "uart_rx_b",
+};
+
+static const char * const uart_c_groups[] = {
+       "uart_tx_c", "uart_rx_c",
+};
+
+static const char * const i2c_a_groups[] = {
+       "i2c_sck_a", "i2c_sda_a",
+};
+
+static const char * const i2c_b_groups[] = {
+       "i2c_sck_b", "i2c_sda_b",
+};
+
+static const char * const i2c_c_groups[] = {
+       "i2c_sck_c", "i2c_sda_c",
+};
+
+static const char * const eth_groups[] = {
+       "eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv",
+       "eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3",
+       "eth_rgmii_tx_clk", "eth_tx_en",
+       "eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3",
+};
+
+static const char * const pwm_e_groups[] = {
+       "pwm_e",
+};
+
+static const char * const gpio_aobus_groups[] = {
+       "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
+       "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
+};
+
+static const char * const uart_ao_groups[] = {
+       "uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a",
+};
+
+static const char * const uart_ao_b_groups[] = {
+       "uart_tx_ao_b", "uart_rx_ao_b", "uart_cts_ao_b", "uart_rts_ao_b",
+};
+
+static const char * const remote_input_ao_groups[] = {
+       "remote_input_ao",
+};
+
+static struct meson_pmx_func meson_gxl_periphs_functions[] = {
+       FUNCTION(gpio_periphs),
+       FUNCTION(emmc),
+       FUNCTION(sdcard),
+       FUNCTION(sdio),
+       FUNCTION(nand),
+       FUNCTION(uart_a),
+       FUNCTION(uart_b),
+       FUNCTION(uart_c),
+       FUNCTION(i2c_a),
+       FUNCTION(i2c_b),
+       FUNCTION(i2c_c),
+       FUNCTION(eth),
+       FUNCTION(pwm_e),
+};
+
+static struct meson_pmx_func meson_gxl_aobus_functions[] = {
+       FUNCTION(gpio_aobus),
+       FUNCTION(uart_ao),
+       FUNCTION(uart_ao_b),
+       FUNCTION(remote_input_ao),
+};
+
+static struct meson_bank meson_gxl_periphs_banks[] = {
+       /*   name    first                      last                    pullen  pull    dir     out     in  */
+       BANK("X",    PIN(GPIOX_0, EE_OFF),      PIN(GPIOX_18, EE_OFF),  4,  0,  4,  0,  12, 0,  13, 0,  14, 0),
+       BANK("DV",   PIN(GPIODV_0, EE_OFF),     PIN(GPIODV_29, EE_OFF), 0,  0,  0,  0,  0,  0,  1,  0,  2,  0),
+       BANK("H",    PIN(GPIOH_0, EE_OFF),      PIN(GPIOH_9, EE_OFF),   1, 20,  1, 20,  3, 20,  4, 20,  5, 20),
+       BANK("Z",    PIN(GPIOZ_0, EE_OFF),      PIN(GPIOZ_15, EE_OFF),  3,  0,  3,  0,  9,  0,  10, 0, 11,  0),
+       BANK("CARD", PIN(CARD_0, EE_OFF),       PIN(CARD_6, EE_OFF),    2, 20,  2, 20,  6, 20,  7, 20,  8, 20),
+       BANK("BOOT", PIN(BOOT_0, EE_OFF),       PIN(BOOT_15, EE_OFF),   2,  0,  2,  0,  6,  0,  7,  0,  8,  0),
+       BANK("CLK",  PIN(GPIOCLK_0, EE_OFF),    PIN(GPIOCLK_1, EE_OFF), 3, 28,  3, 28,  9, 28, 10, 28, 11, 28),
+};
+
+static struct meson_bank meson_gxl_aobus_banks[] = {
+       /*   name    first              last              pullen  pull    dir     out     in  */
+       BANK("AO",   PIN(GPIOAO_0, 0),  PIN(GPIOAO_9, 0), 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+};
+
+struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = {
+       .name           = "periphs-banks",
+       .pin_base       = 10,
+       .pins           = meson_gxl_periphs_pins,
+       .groups         = meson_gxl_periphs_groups,
+       .funcs          = meson_gxl_periphs_functions,
+       .banks          = meson_gxl_periphs_banks,
+       .num_pins       = ARRAY_SIZE(meson_gxl_periphs_pins),
+       .num_groups     = ARRAY_SIZE(meson_gxl_periphs_groups),
+       .num_funcs      = ARRAY_SIZE(meson_gxl_periphs_functions),
+       .num_banks      = ARRAY_SIZE(meson_gxl_periphs_banks),
+};
+
+struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = {
+       .name           = "aobus-banks",
+       .pin_base       = 0,
+       .pins           = meson_gxl_aobus_pins,
+       .groups         = meson_gxl_aobus_groups,
+       .funcs          = meson_gxl_aobus_functions,
+       .banks          = meson_gxl_aobus_banks,
+       .num_pins       = ARRAY_SIZE(meson_gxl_aobus_pins),
+       .num_groups     = ARRAY_SIZE(meson_gxl_aobus_groups),
+       .num_funcs      = ARRAY_SIZE(meson_gxl_aobus_functions),
+       .num_banks      = ARRAY_SIZE(meson_gxl_aobus_banks),
+};
index 57122eda155afdeba61202506e779ab320468017..a579126832afde2d758d629f58338af2d9e9378f 100644 (file)
@@ -524,6 +524,14 @@ static const struct of_device_id meson_pinctrl_dt_match[] = {
                .compatible = "amlogic,meson-gxbb-aobus-pinctrl",
                .data = &meson_gxbb_aobus_pinctrl_data,
        },
+       {
+               .compatible = "amlogic,meson-gxl-periphs-pinctrl",
+               .data = &meson_gxl_periphs_pinctrl_data,
+       },
+       {
+               .compatible = "amlogic,meson-gxl-aobus-pinctrl",
+               .data = &meson_gxl_aobus_pinctrl_data,
+       },
        { },
 };
 
index 98b5080650c1ac3c6ad1d16ea7298d5a0b2feb07..1aa871d5431ee8b9b1a3c2106909b7571aebb52a 100644 (file)
@@ -169,3 +169,5 @@ extern struct meson_pinctrl_data meson8b_cbus_pinctrl_data;
 extern struct meson_pinctrl_data meson8b_aobus_pinctrl_data;
 extern struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data;
 extern struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data;
+extern struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data;
+extern struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data;
index 8392083514fb63242a65927a4e51db0c27e030e3..af4814479eb02deaf703c90e6b317a378d55563a 100644 (file)
@@ -379,13 +379,24 @@ static const unsigned msp0txrx_a_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 };
 static const unsigned msp0tfstck_a_1_pins[] = { DB8500_PIN_AF3, DB8500_PIN_AE3 };
 static const unsigned msp0rfsrck_a_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
 /* Basic pins of the MMC/SD card 0 interface */
-static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1,
-       DB8500_PIN_AB4, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2,
-       DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, /* MC0_CMDDIR */
+                                        DB8500_PIN_AC1, /* MC0_DAT0DIR */
+                                        DB8500_PIN_AB4, /* MC0_DAT2DIR */
+                                        DB8500_PIN_AA3, /* MC0_FBCLK */
+                                        DB8500_PIN_AA4, /* MC0_CLK */
+                                        DB8500_PIN_AB2, /* MC0_CMD */
+                                        DB8500_PIN_Y4,  /* MC0_DAT0 */
+                                        DB8500_PIN_Y2,  /* MC0_DAT1 */
+                                        DB8500_PIN_AA2, /* MC0_DAT2 */
+                                        DB8500_PIN_AA1  /* MC0_DAT3 */
+};
 /* Often only 4 bits are used, then these are not needed (only used for MMC) */
-static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3,
-       DB8500_PIN_V3, DB8500_PIN_V2};
-static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 };
+static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, /* MC0_DAT4 */
+                                              DB8500_PIN_W3, /* MC0_DAT5 */
+                                              DB8500_PIN_V3, /* MC0_DAT6 */
+                                              DB8500_PIN_V2  /* MC0_DAT7 */
+};
+static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 }; /* MC0_DAT31DIR */
 /* MSP1 can only be on these pins, but TXD and RXD can be flipped */
 static const unsigned msp1txrx_a_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 };
 static const unsigned msp1_a_1_pins[] = { DB8500_PIN_AE1, DB8500_PIN_AE2 };
index 5020ae5344794da4a64c571bc72e46243c853749..ce3335accb5b1ccc2abb8549049944c413fefa04 100644 (file)
@@ -381,7 +381,7 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
        if (ret < 0)
                goto exit;
 
-       for_each_child_of_node(np_config, np) {
+       for_each_available_child_of_node(np_config, np) {
                ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
                                        &reserved_maps, num_maps, type);
                if (ret < 0)
index 9f09041859099134220b54c7aee691f8810ee09d..569bc28cb90972943bb0929127688b2a1e59ff91 100644 (file)
@@ -56,6 +56,9 @@ static int gpio_banks;
 #define DRIVE_STRENGTH_SHIFT   5
 #define DRIVE_STRENGTH_MASK            0x3
 #define DRIVE_STRENGTH   (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT)
+#define OUTPUT         (1 << 7)
+#define OUTPUT_VAL_SHIFT       8
+#define OUTPUT_VAL     (0x1 << OUTPUT_VAL_SHIFT)
 #define DEBOUNCE       (1 << 16)
 #define DEBOUNCE_VAL_SHIFT     17
 #define DEBOUNCE_VAL   (0x3fff << DEBOUNCE_VAL_SHIFT)
@@ -375,6 +378,19 @@ static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
        writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR));
 }
 
+static bool at91_mux_get_output(void __iomem *pio, unsigned int pin, bool *val)
+{
+       *val = (readl_relaxed(pio + PIO_ODSR) >> pin) & 0x1;
+       return (readl_relaxed(pio + PIO_OSR) >> pin) & 0x1;
+}
+
+static void at91_mux_set_output(void __iomem *pio, unsigned int mask,
+                               bool is_on, bool val)
+{
+       writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
+       writel_relaxed(mask, pio + (is_on ? PIO_OER : PIO_ODR));
+}
+
 static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin)
 {
        return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1;
@@ -848,6 +864,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
        void __iomem *pio;
        unsigned pin;
        int div;
+       bool out;
 
        *config = 0;
        dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id);
@@ -875,6 +892,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
        if (info->ops->get_drivestrength)
                *config |= (info->ops->get_drivestrength(pio, pin)
                                << DRIVE_STRENGTH_SHIFT);
+       if (at91_mux_get_output(pio, pin, &out))
+               *config |= OUTPUT | (out << OUTPUT_VAL_SHIFT);
 
        return 0;
 }
@@ -907,6 +926,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
                if (config & PULL_UP && config & PULL_DOWN)
                        return -EINVAL;
 
+               at91_mux_set_output(pio, mask, config & OUTPUT,
+                                   (config & OUTPUT_VAL) >> OUTPUT_VAL_SHIFT);
                at91_mux_set_pullup(pio, mask, config & PULL_UP);
                at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);
                if (info->ops->set_deglitch)
diff --git a/drivers/pinctrl/pinctrl-da850-pupd.c b/drivers/pinctrl/pinctrl-da850-pupd.c
new file mode 100644 (file)
index 0000000..b36a90a
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Pinconf driver for TI DA850/OMAP-L138/AM18XX pullup/pulldown groups
+ *
+ * Copyright (C) 2016  David Lechner
+ *
+ * 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; version 2 of the License.
+ *
+ * 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/bitops.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+
+#define DA850_PUPD_ENA         0x00
+#define DA850_PUPD_SEL         0x04
+
+struct da850_pupd_data {
+       void __iomem *base;
+       struct pinctrl_desc desc;
+       struct pinctrl_dev *pinctrl;
+};
+
+static const char * const da850_pupd_group_names[] = {
+       "cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7",
+       "cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15",
+       "cp16", "cp17", "cp18", "cp19", "cp20", "cp21", "cp22", "cp23",
+       "cp24", "cp25", "cp26", "cp27", "cp28", "cp29", "cp30", "cp31",
+};
+
+static int da850_pupd_get_groups_count(struct pinctrl_dev *pctldev)
+{
+       return ARRAY_SIZE(da850_pupd_group_names);
+}
+
+static const char *da850_pupd_get_group_name(struct pinctrl_dev *pctldev,
+                                            unsigned int selector)
+{
+       return da850_pupd_group_names[selector];
+}
+
+static int da850_pupd_get_group_pins(struct pinctrl_dev *pctldev,
+                                    unsigned int selector,
+                                    const unsigned int **pins,
+                                    unsigned int *num_pins)
+{
+       *num_pins = 0;
+
+       return 0;
+}
+
+static const struct pinctrl_ops da850_pupd_pctlops = {
+       .get_groups_count       = da850_pupd_get_groups_count,
+       .get_group_name         = da850_pupd_get_group_name,
+       .get_group_pins         = da850_pupd_get_group_pins,
+       .dt_node_to_map         = pinconf_generic_dt_node_to_map_group,
+       .dt_free_map            = pinconf_generic_dt_free_map,
+};
+
+static int da850_pupd_pin_config_group_get(struct pinctrl_dev *pctldev,
+                                          unsigned int selector,
+                                          unsigned long *config)
+{
+       struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
+       enum pin_config_param param = pinconf_to_config_param(*config);
+       u32 val;
+       u16 arg;
+
+       val = readl(data->base + DA850_PUPD_ENA);
+       arg = !!(~val & BIT(selector));
+
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+               if (arg) {
+                       /* bias is disabled */
+                       arg = 0;
+                       break;
+               }
+               val = readl(data->base + DA850_PUPD_SEL);
+               if (param == PIN_CONFIG_BIAS_PULL_DOWN)
+                       val = ~val;
+               arg = !!(val & BIT(selector));
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       *config = pinconf_to_config_packed(param, arg);
+
+       return 0;
+}
+
+static int da850_pupd_pin_config_group_set(struct pinctrl_dev *pctldev,
+                                          unsigned int selector,
+                                          unsigned long *configs,
+                                          unsigned int num_configs)
+{
+       struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
+       u32 ena, sel;
+       enum pin_config_param param;
+       u16 arg;
+       int i;
+
+       ena = readl(data->base + DA850_PUPD_ENA);
+       sel = readl(data->base + DA850_PUPD_SEL);
+
+       for (i = 0; i < num_configs; i++) {
+               param = pinconf_to_config_param(configs[i]);
+               arg = pinconf_to_config_argument(configs[i]);
+
+               switch (param) {
+               case PIN_CONFIG_BIAS_DISABLE:
+                       ena &= ~BIT(selector);
+                       break;
+               case PIN_CONFIG_BIAS_PULL_UP:
+                       ena |= BIT(selector);
+                       sel |= BIT(selector);
+                       break;
+               case PIN_CONFIG_BIAS_PULL_DOWN:
+                       ena |= BIT(selector);
+                       sel &= ~BIT(selector);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       writel(sel, data->base + DA850_PUPD_SEL);
+       writel(ena, data->base + DA850_PUPD_ENA);
+
+       return 0;
+}
+
+static const struct pinconf_ops da850_pupd_confops = {
+       .is_generic             = true,
+       .pin_config_group_get   = da850_pupd_pin_config_group_get,
+       .pin_config_group_set   = da850_pupd_pin_config_group_set,
+};
+
+static int da850_pupd_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct da850_pupd_data *data;
+       struct resource *res;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       data->base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(data->base)) {
+               dev_err(dev, "Could not map resource\n");
+               return PTR_ERR(data->base);
+       }
+
+       data->desc.name = dev_name(dev);
+       data->desc.pctlops = &da850_pupd_pctlops;
+       data->desc.confops = &da850_pupd_confops;
+       data->desc.owner = THIS_MODULE;
+
+       data->pinctrl = devm_pinctrl_register(dev, &data->desc, data);
+       if (IS_ERR(data->pinctrl)) {
+               dev_err(dev, "Failed to register pinctrl\n");
+               return PTR_ERR(data->pinctrl);
+       }
+
+       platform_set_drvdata(pdev, data);
+
+       return 0;
+}
+
+static int da850_pupd_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static const struct of_device_id da850_pupd_of_match[] = {
+       { .compatible = "ti,da850-pupd" },
+       { }
+};
+
+static struct platform_driver da850_pupd_driver = {
+       .driver = {
+               .name           = "ti-da850-pupd",
+               .of_match_table = da850_pupd_of_match,
+       },
+       .probe  = da850_pupd_probe,
+       .remove = da850_pupd_remove,
+};
+module_platform_driver(da850_pupd_driver);
+
+MODULE_AUTHOR("David Lechner <david@lechnology.com>");
+MODULE_DESCRIPTION("TI DA850/OMAP-L138/AM18XX pullup/pulldown configuration");
+MODULE_LICENSE("GPL");
index 917a7d2535d71c0e061848dc5627ef8c15d6bf22..494ec9a7573a5c2026386d7753e503d53fada9ab 100644 (file)
 
 #define GPIO_BANK_START(bank)          ((bank) * PINS_PER_BANK)
 
-/* Regmap Offsets */
-#define PINMUX_PRIMARY_SEL0    0x0c
-#define PINMUX_SECONDARY_SEL0  0x14
-#define PINMUX_TERTIARY_SEL0   0x8c
-#define PINMUX_PRIMARY_SEL1    0x10
-#define PINMUX_SECONDARY_SEL1  0x18
-#define PINMUX_TERTIARY_SEL1   0x90
-#define PINMUX_PULLUP_CTRL0    0xac
-#define PINMUX_PULLUP_CTRL1    0xb0
+/* OX810 Regmap Offsets */
+#define PINMUX_810_PRIMARY_SEL0                0x0c
+#define PINMUX_810_SECONDARY_SEL0      0x14
+#define PINMUX_810_TERTIARY_SEL0       0x8c
+#define PINMUX_810_PRIMARY_SEL1                0x10
+#define PINMUX_810_SECONDARY_SEL1      0x18
+#define PINMUX_810_TERTIARY_SEL1       0x90
+#define PINMUX_810_PULLUP_CTRL0                0xac
+#define PINMUX_810_PULLUP_CTRL1                0xb0
+
+/* OX820 Regmap Offsets */
+#define PINMUX_820_BANK_OFFSET         0x100000
+#define PINMUX_820_SECONDARY_SEL       0x14
+#define PINMUX_820_TERTIARY_SEL                0x8c
+#define PINMUX_820_QUATERNARY_SEL      0x94
+#define PINMUX_820_DEBUG_SEL           0x9c
+#define PINMUX_820_ALTERNATIVE_SEL     0xa4
+#define PINMUX_820_PULLUP_CTRL         0xac
 
 /* GPIO Registers */
 #define INPUT_VALUE    0x00
@@ -87,8 +96,6 @@ struct oxnas_pinctrl {
        struct regmap *regmap;
        struct device *dev;
        struct pinctrl_dev *pctldev;
-       const struct pinctrl_pin_desc *pins;
-       unsigned int npins;
        const struct oxnas_function *functions;
        unsigned int nfunctions;
        const struct oxnas_pin_group *groups;
@@ -97,7 +104,50 @@ struct oxnas_pinctrl {
        unsigned int nbanks;
 };
 
-static const struct pinctrl_pin_desc oxnas_pins[] = {
+struct oxnas_pinctrl_data {
+       struct pinctrl_desc *desc;
+       struct oxnas_pinctrl *pctl;
+};
+
+static const struct pinctrl_pin_desc oxnas_ox810se_pins[] = {
+       PINCTRL_PIN(0, "gpio0"),
+       PINCTRL_PIN(1, "gpio1"),
+       PINCTRL_PIN(2, "gpio2"),
+       PINCTRL_PIN(3, "gpio3"),
+       PINCTRL_PIN(4, "gpio4"),
+       PINCTRL_PIN(5, "gpio5"),
+       PINCTRL_PIN(6, "gpio6"),
+       PINCTRL_PIN(7, "gpio7"),
+       PINCTRL_PIN(8, "gpio8"),
+       PINCTRL_PIN(9, "gpio9"),
+       PINCTRL_PIN(10, "gpio10"),
+       PINCTRL_PIN(11, "gpio11"),
+       PINCTRL_PIN(12, "gpio12"),
+       PINCTRL_PIN(13, "gpio13"),
+       PINCTRL_PIN(14, "gpio14"),
+       PINCTRL_PIN(15, "gpio15"),
+       PINCTRL_PIN(16, "gpio16"),
+       PINCTRL_PIN(17, "gpio17"),
+       PINCTRL_PIN(18, "gpio18"),
+       PINCTRL_PIN(19, "gpio19"),
+       PINCTRL_PIN(20, "gpio20"),
+       PINCTRL_PIN(21, "gpio21"),
+       PINCTRL_PIN(22, "gpio22"),
+       PINCTRL_PIN(23, "gpio23"),
+       PINCTRL_PIN(24, "gpio24"),
+       PINCTRL_PIN(25, "gpio25"),
+       PINCTRL_PIN(26, "gpio26"),
+       PINCTRL_PIN(27, "gpio27"),
+       PINCTRL_PIN(28, "gpio28"),
+       PINCTRL_PIN(29, "gpio29"),
+       PINCTRL_PIN(30, "gpio30"),
+       PINCTRL_PIN(31, "gpio31"),
+       PINCTRL_PIN(32, "gpio32"),
+       PINCTRL_PIN(33, "gpio33"),
+       PINCTRL_PIN(34, "gpio34"),
+};
+
+static const struct pinctrl_pin_desc oxnas_ox820_pins[] = {
        PINCTRL_PIN(0, "gpio0"),
        PINCTRL_PIN(1, "gpio1"),
        PINCTRL_PIN(2, "gpio2"),
@@ -133,9 +183,24 @@ static const struct pinctrl_pin_desc oxnas_pins[] = {
        PINCTRL_PIN(32, "gpio32"),
        PINCTRL_PIN(33, "gpio33"),
        PINCTRL_PIN(34, "gpio34"),
+       PINCTRL_PIN(35, "gpio35"),
+       PINCTRL_PIN(36, "gpio36"),
+       PINCTRL_PIN(37, "gpio37"),
+       PINCTRL_PIN(38, "gpio38"),
+       PINCTRL_PIN(39, "gpio39"),
+       PINCTRL_PIN(40, "gpio40"),
+       PINCTRL_PIN(41, "gpio41"),
+       PINCTRL_PIN(42, "gpio42"),
+       PINCTRL_PIN(43, "gpio43"),
+       PINCTRL_PIN(44, "gpio44"),
+       PINCTRL_PIN(45, "gpio45"),
+       PINCTRL_PIN(46, "gpio46"),
+       PINCTRL_PIN(47, "gpio47"),
+       PINCTRL_PIN(48, "gpio48"),
+       PINCTRL_PIN(49, "gpio49"),
 };
 
-static const char * const oxnas_fct0_group[] = {
+static const char * const oxnas_ox810se_fct0_group[] = {
        "gpio0",  "gpio1",  "gpio2",  "gpio3",
        "gpio4",  "gpio5",  "gpio6",  "gpio7",
        "gpio8",  "gpio9",  "gpio10", "gpio11",
@@ -147,7 +212,7 @@ static const char * const oxnas_fct0_group[] = {
        "gpio32", "gpio33", "gpio34"
 };
 
-static const char * const oxnas_fct3_group[] = {
+static const char * const oxnas_ox810se_fct3_group[] = {
        "gpio0",  "gpio1",  "gpio2",  "gpio3",
        "gpio4",  "gpio5",  "gpio6",  "gpio7",
        "gpio8",  "gpio9",
@@ -158,6 +223,40 @@ static const char * const oxnas_fct3_group[] = {
        "gpio34"
 };
 
+static const char * const oxnas_ox820_fct0_group[] = {
+       "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"
+};
+
+static const char * const oxnas_ox820_fct1_group[] = {
+       "gpio3", "gpio4",
+       "gpio12", "gpio13", "gpio14", "gpio15",
+       "gpio16", "gpio17", "gpio18", "gpio19",
+       "gpio20", "gpio21", "gpio22", "gpio23",
+       "gpio24"
+};
+
+static const char * const oxnas_ox820_fct4_group[] = {
+       "gpio5", "gpio6", "gpio7", "gpio8",
+       "gpio24", "gpio25", "gpio26", "gpio27",
+       "gpio40", "gpio41", "gpio42", "gpio43"
+};
+
+static const char * const oxnas_ox820_fct5_group[] = {
+       "gpio28", "gpio29", "gpio30", "gpio31"
+};
+
 #define FUNCTION(_name, _gr)                                   \
        {                                                       \
                .name = #_name,                                 \
@@ -165,9 +264,16 @@ static const char * const oxnas_fct3_group[] = {
                .ngroups = ARRAY_SIZE(oxnas_##_gr##_group),     \
        }
 
-static const struct oxnas_function oxnas_functions[] = {
-       FUNCTION(gpio, fct0),
-       FUNCTION(fct3, fct3),
+static const struct oxnas_function oxnas_ox810se_functions[] = {
+       FUNCTION(gpio, ox810se_fct0),
+       FUNCTION(fct3, ox810se_fct3),
+};
+
+static const struct oxnas_function oxnas_ox820_functions[] = {
+       FUNCTION(gpio, ox820_fct0),
+       FUNCTION(fct1, ox820_fct1),
+       FUNCTION(fct4, ox820_fct4),
+       FUNCTION(fct5, ox820_fct5),
 };
 
 #define OXNAS_PINCTRL_GROUP(_pin, _name, ...)                          \
@@ -185,7 +291,7 @@ static const struct oxnas_function oxnas_functions[] = {
                .fct = _fct,                            \
        }
 
-static const struct oxnas_pin_group oxnas_groups[] = {
+static const struct oxnas_pin_group oxnas_ox810se_groups[] = {
        OXNAS_PINCTRL_GROUP(0, gpio0,
                        OXNAS_PINCTRL_FUNCTION(gpio, 0),
                        OXNAS_PINCTRL_FUNCTION(fct3, 3)),
@@ -282,6 +388,140 @@ static const struct oxnas_pin_group oxnas_groups[] = {
                        OXNAS_PINCTRL_FUNCTION(fct3, 3)),
 };
 
+static const struct oxnas_pin_group oxnas_ox820_groups[] = {
+       OXNAS_PINCTRL_GROUP(0, gpio0,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(1, gpio1,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(2, gpio2,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(3, gpio3,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(4, gpio4,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(5, gpio5,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(6, gpio6,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(7, gpio7,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(8, gpio8,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(9, gpio9,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(10, gpio10,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(11, gpio11,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(12, gpio12,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(13, gpio13,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(14, gpio14,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(15, gpio15,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(16, gpio16,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(17, gpio17,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(18, gpio18,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(19, gpio19,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(20, gpio20,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(21, gpio21,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(22, gpio22,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(23, gpio23,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1)),
+       OXNAS_PINCTRL_GROUP(24, gpio24,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct1, 1),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 5)),
+       OXNAS_PINCTRL_GROUP(25, gpio25,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(26, gpio26,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(27, gpio27,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(28, gpio28,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct5, 5)),
+       OXNAS_PINCTRL_GROUP(29, gpio29,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct5, 5)),
+       OXNAS_PINCTRL_GROUP(30, gpio30,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct5, 5)),
+       OXNAS_PINCTRL_GROUP(31, gpio31,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct5, 5)),
+       OXNAS_PINCTRL_GROUP(32, gpio32,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(33, gpio33,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(34, gpio34,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(35, gpio35,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(36, gpio36,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(37, gpio37,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(38, gpio38,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(39, gpio39,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(40, gpio40,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(41, gpio41,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(42, gpio42,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(43, gpio43,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0),
+                       OXNAS_PINCTRL_FUNCTION(fct4, 4)),
+       OXNAS_PINCTRL_GROUP(44, gpio44,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(45, gpio45,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(46, gpio46,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(47, gpio47,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(48, gpio48,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+       OXNAS_PINCTRL_GROUP(49, gpio49,
+                       OXNAS_PINCTRL_FUNCTION(gpio, 0)),
+};
+
 static inline struct oxnas_gpio_bank *pctl_to_bank(struct oxnas_pinctrl *pctl,
                                                   unsigned int pin)
 {
@@ -352,8 +592,8 @@ static int oxnas_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
        return 0;
 }
 
-static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev,
-                              unsigned int func, unsigned int group)
+static int oxnas_ox810se_pinmux_enable(struct pinctrl_dev *pctldev,
+                                      unsigned int func, unsigned int group)
 {
        struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
        const struct oxnas_pin_group *pg = &pctl->groups[group];
@@ -371,22 +611,22 @@ static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev,
 
                        regmap_write_bits(pctl->regmap,
                                          (pg->bank ?
-                                               PINMUX_PRIMARY_SEL1 :
-                                               PINMUX_PRIMARY_SEL0),
+                                               PINMUX_810_PRIMARY_SEL1 :
+                                               PINMUX_810_PRIMARY_SEL0),
                                          mask,
                                          (functions->fct == 1 ?
                                                mask : 0));
                        regmap_write_bits(pctl->regmap,
                                          (pg->bank ?
-                                               PINMUX_SECONDARY_SEL1 :
-                                               PINMUX_SECONDARY_SEL0),
+                                               PINMUX_810_SECONDARY_SEL1 :
+                                               PINMUX_810_SECONDARY_SEL0),
                                          mask,
                                          (functions->fct == 2 ?
                                                mask : 0));
                        regmap_write_bits(pctl->regmap,
                                          (pg->bank ?
-                                               PINMUX_TERTIARY_SEL1 :
-                                               PINMUX_TERTIARY_SEL0),
+                                               PINMUX_810_TERTIARY_SEL1 :
+                                               PINMUX_810_TERTIARY_SEL0),
                                          mask,
                                          (functions->fct == 3 ?
                                                mask : 0));
@@ -402,9 +642,64 @@ static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev,
        return -EINVAL;
 }
 
-static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev,
-                                    struct pinctrl_gpio_range *range,
-                                    unsigned int offset)
+static int oxnas_ox820_pinmux_enable(struct pinctrl_dev *pctldev,
+                                    unsigned int func, unsigned int group)
+{
+       struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+       const struct oxnas_pin_group *pg = &pctl->groups[group];
+       const struct oxnas_function *pf = &pctl->functions[func];
+       const char *fname = pf->name;
+       struct oxnas_desc_function *functions = pg->functions;
+       unsigned int offset = (pg->bank ? PINMUX_820_BANK_OFFSET : 0);
+       u32 mask = BIT(pg->pin);
+
+       while (functions->name) {
+               if (!strcmp(functions->name, fname)) {
+                       dev_dbg(pctl->dev,
+                               "setting function %s bank %d pin %d fct %d mask %x\n",
+                               fname, pg->bank, pg->pin,
+                               functions->fct, mask);
+
+                       regmap_write_bits(pctl->regmap,
+                                         offset + PINMUX_820_SECONDARY_SEL,
+                                         mask,
+                                         (functions->fct == 1 ?
+                                               mask : 0));
+                       regmap_write_bits(pctl->regmap,
+                                         offset + PINMUX_820_TERTIARY_SEL,
+                                         mask,
+                                         (functions->fct == 2 ?
+                                               mask : 0));
+                       regmap_write_bits(pctl->regmap,
+                                         offset + PINMUX_820_QUATERNARY_SEL,
+                                         mask,
+                                         (functions->fct == 3 ?
+                                               mask : 0));
+                       regmap_write_bits(pctl->regmap,
+                                         offset + PINMUX_820_DEBUG_SEL,
+                                         mask,
+                                         (functions->fct == 4 ?
+                                               mask : 0));
+                       regmap_write_bits(pctl->regmap,
+                                         offset + PINMUX_820_ALTERNATIVE_SEL,
+                                         mask,
+                                         (functions->fct == 5 ?
+                                               mask : 0));
+
+                       return 0;
+               }
+
+               functions++;
+       }
+
+       dev_err(pctl->dev, "cannot mux pin %u to function %u\n", group, func);
+
+       return -EINVAL;
+}
+
+static int oxnas_ox810se_gpio_request_enable(struct pinctrl_dev *pctldev,
+                                            struct pinctrl_gpio_range *range,
+                                            unsigned int offset)
 {
        struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
        struct oxnas_gpio_bank *bank = gpiochip_get_data(range->gc);
@@ -415,18 +710,49 @@ static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev,
 
        regmap_write_bits(pctl->regmap,
                          (bank->id ?
-                               PINMUX_PRIMARY_SEL1 :
-                               PINMUX_PRIMARY_SEL0),
+                               PINMUX_810_PRIMARY_SEL1 :
+                               PINMUX_810_PRIMARY_SEL0),
                          mask, 0);
        regmap_write_bits(pctl->regmap,
                          (bank->id ?
-                               PINMUX_SECONDARY_SEL1 :
-                               PINMUX_SECONDARY_SEL0),
+                               PINMUX_810_SECONDARY_SEL1 :
+                               PINMUX_810_SECONDARY_SEL0),
                          mask, 0);
        regmap_write_bits(pctl->regmap,
                          (bank->id ?
-                               PINMUX_TERTIARY_SEL1 :
-                               PINMUX_TERTIARY_SEL0),
+                               PINMUX_810_TERTIARY_SEL1 :
+                               PINMUX_810_TERTIARY_SEL0),
+                         mask, 0);
+
+       return 0;
+}
+
+static int oxnas_ox820_gpio_request_enable(struct pinctrl_dev *pctldev,
+                                          struct pinctrl_gpio_range *range,
+                                          unsigned int offset)
+{
+       struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+       struct oxnas_gpio_bank *bank = gpiochip_get_data(range->gc);
+       unsigned int bank_offset = (bank->id ? PINMUX_820_BANK_OFFSET : 0);
+       u32 mask = BIT(offset - bank->gpio_chip.base);
+
+       dev_dbg(pctl->dev, "requesting gpio %d in bank %d (id %d) with mask 0x%x\n",
+               offset, bank->gpio_chip.base, bank->id, mask);
+
+       regmap_write_bits(pctl->regmap,
+                         bank_offset + PINMUX_820_SECONDARY_SEL,
+                         mask, 0);
+       regmap_write_bits(pctl->regmap,
+                         bank_offset + PINMUX_820_TERTIARY_SEL,
+                         mask, 0);
+       regmap_write_bits(pctl->regmap,
+                         bank_offset + PINMUX_820_QUATERNARY_SEL,
+                         mask, 0);
+       regmap_write_bits(pctl->regmap,
+                         bank_offset + PINMUX_820_DEBUG_SEL,
+                         mask, 0);
+       regmap_write_bits(pctl->regmap,
+                         bank_offset + PINMUX_820_ALTERNATIVE_SEL,
                          mask, 0);
 
        return 0;
@@ -498,17 +824,26 @@ static int oxnas_gpio_set_direction(struct pinctrl_dev *pctldev,
        return 0;
 }
 
-static const struct pinmux_ops oxnas_pinmux_ops = {
+static const struct pinmux_ops oxnas_ox810se_pinmux_ops = {
        .get_functions_count = oxnas_pinmux_get_functions_count,
        .get_function_name = oxnas_pinmux_get_function_name,
        .get_function_groups = oxnas_pinmux_get_function_groups,
-       .set_mux = oxnas_pinmux_enable,
-       .gpio_request_enable = oxnas_gpio_request_enable,
+       .set_mux = oxnas_ox810se_pinmux_enable,
+       .gpio_request_enable = oxnas_ox810se_gpio_request_enable,
        .gpio_set_direction = oxnas_gpio_set_direction,
 };
 
-static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
-                            unsigned long *config)
+static const struct pinmux_ops oxnas_ox820_pinmux_ops = {
+       .get_functions_count = oxnas_pinmux_get_functions_count,
+       .get_function_name = oxnas_pinmux_get_function_name,
+       .get_function_groups = oxnas_pinmux_get_function_groups,
+       .set_mux = oxnas_ox820_pinmux_enable,
+       .gpio_request_enable = oxnas_ox820_gpio_request_enable,
+       .gpio_set_direction = oxnas_gpio_set_direction,
+};
+
+static int oxnas_ox810se_pinconf_get(struct pinctrl_dev *pctldev,
+                                    unsigned int pin, unsigned long *config)
 {
        struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
        struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
@@ -521,8 +856,38 @@ static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
        case PIN_CONFIG_BIAS_PULL_UP:
                ret = regmap_read(pctl->regmap,
                                  (bank->id ?
-                                       PINMUX_PULLUP_CTRL1 :
-                                       PINMUX_PULLUP_CTRL0),
+                                       PINMUX_810_PULLUP_CTRL1 :
+                                       PINMUX_810_PULLUP_CTRL0),
+                                 &arg);
+               if (ret)
+                       return ret;
+
+               arg = !!(arg & mask);
+               break;
+       default:
+               return -ENOTSUPP;
+       }
+
+       *config = pinconf_to_config_packed(param, arg);
+
+       return 0;
+}
+
+static int oxnas_ox820_pinconf_get(struct pinctrl_dev *pctldev,
+                                  unsigned int pin, unsigned long *config)
+{
+       struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+       struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
+       unsigned int param = pinconf_to_config_param(*config);
+       unsigned int bank_offset = (bank->id ? PINMUX_820_BANK_OFFSET : 0);
+       u32 mask = BIT(pin - bank->gpio_chip.base);
+       int ret;
+       u32 arg;
+
+       switch (param) {
+       case PIN_CONFIG_BIAS_PULL_UP:
+               ret = regmap_read(pctl->regmap,
+                                 bank_offset + PINMUX_820_PULLUP_CTRL,
                                  &arg);
                if (ret)
                        return ret;
@@ -538,8 +903,9 @@ static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
        return 0;
 }
 
-static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-                            unsigned long *configs, unsigned int num_configs)
+static int oxnas_ox810se_pinconf_set(struct pinctrl_dev *pctldev,
+                                    unsigned int pin, unsigned long *configs,
+                                    unsigned int num_configs)
 {
        struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
        struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
@@ -561,8 +927,8 @@ static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                        dev_dbg(pctl->dev, "   pullup\n");
                        regmap_write_bits(pctl->regmap,
                                          (bank->id ?
-                                               PINMUX_PULLUP_CTRL1 :
-                                               PINMUX_PULLUP_CTRL0),
+                                               PINMUX_810_PULLUP_CTRL1 :
+                                               PINMUX_810_PULLUP_CTRL0),
                                          mask, mask);
                        break;
                default:
@@ -575,18 +941,53 @@ static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
        return 0;
 }
 
-static const struct pinconf_ops oxnas_pinconf_ops = {
-       .pin_config_get = oxnas_pinconf_get,
-       .pin_config_set = oxnas_pinconf_set,
+static int oxnas_ox820_pinconf_set(struct pinctrl_dev *pctldev,
+                                  unsigned int pin, unsigned long *configs,
+                                  unsigned int num_configs)
+{
+       struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+       struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
+       unsigned int bank_offset = (bank->id ? PINMUX_820_BANK_OFFSET : 0);
+       unsigned int param;
+       u32 arg;
+       unsigned int i;
+       u32 offset = pin - bank->gpio_chip.base;
+       u32 mask = BIT(offset);
+
+       dev_dbg(pctl->dev, "setting pin %d bank %d mask 0x%x\n",
+               pin, bank->gpio_chip.base, mask);
+
+       for (i = 0; i < num_configs; i++) {
+               param = pinconf_to_config_param(configs[i]);
+               arg = pinconf_to_config_argument(configs[i]);
+
+               switch (param) {
+               case PIN_CONFIG_BIAS_PULL_UP:
+                       dev_dbg(pctl->dev, "   pullup\n");
+                       regmap_write_bits(pctl->regmap,
+                                         bank_offset + PINMUX_820_PULLUP_CTRL,
+                                         mask, mask);
+                       break;
+               default:
+                       dev_err(pctl->dev, "Property %u not supported\n",
+                               param);
+                       return -ENOTSUPP;
+               }
+       }
+
+       return 0;
+}
+
+static const struct pinconf_ops oxnas_ox810se_pinconf_ops = {
+       .pin_config_get = oxnas_ox810se_pinconf_get,
+       .pin_config_set = oxnas_ox810se_pinconf_set,
        .is_generic = true,
 };
 
-static struct pinctrl_desc oxnas_pinctrl_desc = {
-       .name = "oxnas-pinctrl",
-       .pctlops = &oxnas_pinctrl_ops,
-       .pmxops = &oxnas_pinmux_ops,
-       .confops = &oxnas_pinconf_ops,
-       .owner = THIS_MODULE,
+static const struct pinconf_ops oxnas_ox820_pinconf_ops = {
+       .pin_config_get = oxnas_ox820_pinconf_get,
+       .pin_config_set = oxnas_ox820_pinconf_set,
+       .is_generic = true,
 };
 
 static void oxnas_gpio_irq_ack(struct irq_data *data)
@@ -699,10 +1100,78 @@ static struct oxnas_gpio_bank oxnas_gpio_banks[] = {
        GPIO_BANK(1),
 };
 
+static struct oxnas_pinctrl ox810se_pinctrl = {
+       .functions = oxnas_ox810se_functions,
+       .nfunctions = ARRAY_SIZE(oxnas_ox810se_functions),
+       .groups = oxnas_ox810se_groups,
+       .ngroups = ARRAY_SIZE(oxnas_ox810se_groups),
+       .gpio_banks = oxnas_gpio_banks,
+       .nbanks = ARRAY_SIZE(oxnas_gpio_banks),
+};
+
+static struct pinctrl_desc oxnas_ox810se_pinctrl_desc = {
+       .name = "oxnas-pinctrl",
+       .pins = oxnas_ox810se_pins,
+       .npins = ARRAY_SIZE(oxnas_ox810se_pins),
+       .pctlops = &oxnas_pinctrl_ops,
+       .pmxops = &oxnas_ox810se_pinmux_ops,
+       .confops = &oxnas_ox810se_pinconf_ops,
+       .owner = THIS_MODULE,
+};
+
+static struct oxnas_pinctrl ox820_pinctrl = {
+       .functions = oxnas_ox820_functions,
+       .nfunctions = ARRAY_SIZE(oxnas_ox820_functions),
+       .groups = oxnas_ox820_groups,
+       .ngroups = ARRAY_SIZE(oxnas_ox820_groups),
+       .gpio_banks = oxnas_gpio_banks,
+       .nbanks = ARRAY_SIZE(oxnas_gpio_banks),
+};
+
+static struct pinctrl_desc oxnas_ox820_pinctrl_desc = {
+       .name = "oxnas-pinctrl",
+       .pins = oxnas_ox820_pins,
+       .npins = ARRAY_SIZE(oxnas_ox820_pins),
+       .pctlops = &oxnas_pinctrl_ops,
+       .pmxops = &oxnas_ox820_pinmux_ops,
+       .confops = &oxnas_ox820_pinconf_ops,
+       .owner = THIS_MODULE,
+};
+
+static struct oxnas_pinctrl_data oxnas_ox810se_pinctrl_data = {
+       .desc = &oxnas_ox810se_pinctrl_desc,
+       .pctl = &ox810se_pinctrl,
+};
+
+static struct oxnas_pinctrl_data oxnas_ox820_pinctrl_data = {
+       .desc = &oxnas_ox820_pinctrl_desc,
+       .pctl = &ox820_pinctrl,
+};
+
+static const struct of_device_id oxnas_pinctrl_of_match[] = {
+       { .compatible = "oxsemi,ox810se-pinctrl",
+         .data = &oxnas_ox810se_pinctrl_data
+       },
+       { .compatible = "oxsemi,ox820-pinctrl",
+         .data = &oxnas_ox820_pinctrl_data,
+       },
+       { },
+};
+
 static int oxnas_pinctrl_probe(struct platform_device *pdev)
 {
+       const struct of_device_id *id;
+       const struct oxnas_pinctrl_data *data;
        struct oxnas_pinctrl *pctl;
 
+       id = of_match_node(oxnas_pinctrl_of_match, pdev->dev.of_node);
+       if (!id)
+               return -ENODEV;
+
+       data = id->data;
+       if (!data || !data->pctl || !data->desc)
+               return -EINVAL;
+
        pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
        if (!pctl)
                return -ENOMEM;
@@ -716,20 +1185,14 @@ static int oxnas_pinctrl_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       pctl->pins = oxnas_pins;
-       pctl->npins = ARRAY_SIZE(oxnas_pins);
-       pctl->functions = oxnas_functions;
-       pctl->nfunctions = ARRAY_SIZE(oxnas_functions);
-       pctl->groups = oxnas_groups;
-       pctl->ngroups = ARRAY_SIZE(oxnas_groups);
-       pctl->gpio_banks = oxnas_gpio_banks;
-       pctl->nbanks = ARRAY_SIZE(oxnas_gpio_banks);
-
-       oxnas_pinctrl_desc.pins = pctl->pins;
-       oxnas_pinctrl_desc.npins = pctl->npins;
+       pctl->functions = data->pctl->functions;
+       pctl->nfunctions = data->pctl->nfunctions;
+       pctl->groups = data->pctl->groups;
+       pctl->ngroups = data->pctl->ngroups;
+       pctl->gpio_banks = data->pctl->gpio_banks;
+       pctl->nbanks = data->pctl->nbanks;
 
-       pctl->pctldev = pinctrl_register(&oxnas_pinctrl_desc,
-                                        &pdev->dev, pctl);
+       pctl->pctldev = pinctrl_register(data->desc, &pdev->dev, pctl);
        if (IS_ERR(pctl->pctldev)) {
                dev_err(&pdev->dev, "Failed to register pinctrl device\n");
                return PTR_ERR(pctl->pctldev);
@@ -805,11 +1268,6 @@ static int oxnas_gpio_probe(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id oxnas_pinctrl_of_match[] = {
-       { .compatible = "oxsemi,ox810se-pinctrl", },
-       { },
-};
-
 static struct platform_driver oxnas_pinctrl_driver = {
        .driver = {
                .name = "oxnas-pinctrl",
@@ -821,6 +1279,7 @@ static struct platform_driver oxnas_pinctrl_driver = {
 
 static const struct of_device_id oxnas_gpio_of_match[] = {
        { .compatible = "oxsemi,ox810se-gpio", },
+       { .compatible = "oxsemi,ox820-gpio", },
        { },
 };
 
index 49bf7dcb7ed82c082df8c24011fe69dec1ecada7..08765f58253c206b2c3d6692d19a504a7de4fbfa 100644 (file)
@@ -59,6 +59,7 @@
 #define GPIO_LS_SYNC           0x60
 
 enum rockchip_pinctrl_type {
+       RK1108,
        RK2928,
        RK3066B,
        RK3188,
@@ -624,6 +625,65 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
        return ret;
 }
 
+#define RK1108_PULL_PMU_OFFSET         0x10
+#define RK1108_PULL_OFFSET             0x110
+#define RK1108_PULL_PINS_PER_REG       8
+#define RK1108_PULL_BITS_PER_PIN       2
+#define RK1108_PULL_BANK_STRIDE                16
+
+static void rk1108_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 = RK1108_PULL_PMU_OFFSET;
+       } else {
+               *reg = RK1108_PULL_OFFSET;
+               *regmap = info->regmap_base;
+               /* correct the offset, as we're starting with the 2nd bank */
+               *reg -= 0x10;
+               *reg += bank->bank_num * RK1108_PULL_BANK_STRIDE;
+       }
+
+       *reg += ((pin_num / RK1108_PULL_PINS_PER_REG) * 4);
+       *bit = (pin_num % RK1108_PULL_PINS_PER_REG);
+       *bit *= RK1108_PULL_BITS_PER_PIN;
+}
+
+#define RK1108_DRV_PMU_OFFSET          0x20
+#define RK1108_DRV_GRF_OFFSET          0x210
+#define RK1108_DRV_BITS_PER_PIN                2
+#define RK1108_DRV_PINS_PER_REG                8
+#define RK1108_DRV_BANK_STRIDE         16
+
+static void rk1108_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 = RK1108_DRV_PMU_OFFSET;
+       } else {
+               *regmap = info->regmap_base;
+               *reg = RK1108_DRV_GRF_OFFSET;
+
+               /* correct the offset, as we're starting with the 2nd bank */
+               *reg -= 0x10;
+               *reg += bank->bank_num * RK1108_DRV_BANK_STRIDE;
+       }
+
+       *reg += ((pin_num / RK1108_DRV_PINS_PER_REG) * 4);
+       *bit = pin_num % RK1108_DRV_PINS_PER_REG;
+       *bit *= RK1108_DRV_BITS_PER_PIN;
+}
+
 #define RK2928_PULL_OFFSET             0x118
 #define RK2928_PULL_PINS_PER_REG       16
 #define RK2928_PULL_BANK_STRIDE                8
@@ -1123,6 +1183,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
                return !(data & BIT(bit))
                                ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
                                : PIN_CONFIG_BIAS_DISABLE;
+       case RK1108:
        case RK3188:
        case RK3288:
        case RK3368:
@@ -1169,6 +1230,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
 
                spin_unlock_irqrestore(&bank->slock, flags);
                break;
+       case RK1108:
        case RK3188:
        case RK3288:
        case RK3368:
@@ -1358,6 +1420,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
                                        pull == PIN_CONFIG_BIAS_DISABLE);
        case RK3066B:
                return pull ? false : true;
+       case RK1108:
        case RK3188:
        case RK3288:
        case RK3368:
@@ -2455,6 +2518,27 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
        return 0;
 }
 
+static struct rockchip_pin_bank rk1108_pin_banks[] = {
+       PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
+                                            IOMUX_SOURCE_PMU,
+                                            IOMUX_SOURCE_PMU,
+                                            IOMUX_SOURCE_PMU),
+       PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
+       PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0),
+       PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0),
+};
+
+static struct rockchip_pin_ctrl rk1108_pin_ctrl = {
+       .pin_banks              = rk1108_pin_banks,
+       .nr_banks               = ARRAY_SIZE(rk1108_pin_banks),
+       .label                  = "RK1108-GPIO",
+       .type                   = RK1108,
+       .grf_mux_offset         = 0x10,
+       .pmu_mux_offset         = 0x0,
+       .pull_calc_reg          = rk1108_calc_pull_reg_and_bit,
+       .drv_calc_reg           = rk1108_calc_drv_reg_and_bit,
+};
+
 static struct rockchip_pin_bank rk2928_pin_banks[] = {
        PIN_BANK(0, 32, "gpio0"),
        PIN_BANK(1, 32, "gpio1"),
@@ -2684,6 +2768,8 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
 };
 
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
+       { .compatible = "rockchip,rk1108-pinctrl",
+               .data = (void *)&rk1108_pin_ctrl },
        { .compatible = "rockchip,rk2928-pinctrl",
                .data = (void *)&rk2928_pin_ctrl },
        { .compatible = "rockchip,rk3036-pinctrl",
index bfdf720db270d8b2c47007455406d9887ed028c6..a5a0392ab8175da62001816e3f7eb7a2600f1b08 100644 (file)
 #include <linux/platform_data/pinctrl-single.h>
 
 #include "core.h"
+#include "devicetree.h"
 #include "pinconf.h"
 
 #define DRIVER_NAME                    "pinctrl-single"
-#define PCS_MUX_PINS_NAME              "pinctrl-single,pins"
-#define PCS_MUX_BITS_NAME              "pinctrl-single,bits"
-#define PCS_REG_NAME_LEN               ((sizeof(unsigned long) * 2) + 3)
 #define PCS_OFF_DISABLED               ~0U
 
 /**
@@ -141,20 +139,6 @@ struct pcs_data {
        int cur;
 };
 
-/**
- * struct pcs_name - register name for a pin
- * @name:      name of the pinctrl register
- *
- * REVISIT: We may want to make names optional in the pinctrl
- * framework as some drivers may not care about pin names to
- * avoid kernel bloat. The pin names can be deciphered by user
- * space tools using debugfs based on the register address and
- * SoC packaging information.
- */
-struct pcs_name {
-       char name[PCS_REG_NAME_LEN];
-};
-
 /**
  * struct pcs_soc_data - SoC specific settings
  * @flags:     initial SoC specific PCS_FEAT_xxx values
@@ -177,8 +161,11 @@ struct pcs_soc_data {
  * @base:      virtual address of the controller
  * @size:      size of the ioremapped area
  * @dev:       device entry
+ * @np:                device tree node
  * @pctl:      pin controller device
  * @flags:     mask of PCS_FEAT_xxx values
+ * @missing_nr_pinctrl_cells: for legacy binding, may go away
+ * @socdata:   soc specific data
  * @lock:      spinlock for register access
  * @mutex:     mutex protecting the lists
  * @width:     bits per mux register
@@ -186,8 +173,8 @@ struct pcs_soc_data {
  * @fshift:    function register shift
  * @foff:      value to turn mux off
  * @fmax:      max number of functions in fmask
- * @bits_per_pin:number of bits per pin
- * @names:     array of register names for pins
+ * @bits_per_mux: number of bits per mux
+ * @bits_per_pin: number of bits per pin
  * @pins:      physical pins on the SoC
  * @pgtree:    pingroup index radix tree
  * @ftree:     function index radix tree
@@ -208,11 +195,13 @@ struct pcs_device {
        void __iomem *base;
        unsigned size;
        struct device *dev;
+       struct device_node *np;
        struct pinctrl_dev *pctl;
        unsigned flags;
 #define PCS_QUIRK_SHARED_IRQ   (1 << 2)
 #define PCS_FEAT_IRQ           (1 << 1)
 #define PCS_FEAT_PINCONF       (1 << 0)
+       struct property *missing_nr_pinctrl_cells;
        struct pcs_soc_data socdata;
        raw_spinlock_t lock;
        struct mutex mutex;
@@ -223,7 +212,6 @@ struct pcs_device {
        unsigned fmax;
        bool bits_per_mux;
        unsigned bits_per_pin;
-       struct pcs_name *names;
        struct pcs_data pins;
        struct radix_tree_root pgtree;
        struct radix_tree_root ftree;
@@ -354,13 +342,17 @@ static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
 {
        struct pcs_device *pcs;
        unsigned val, mux_bytes;
+       unsigned long offset;
+       size_t pa;
 
        pcs = pinctrl_dev_get_drvdata(pctldev);
 
        mux_bytes = pcs->width / BITS_PER_BYTE;
-       val = pcs->read(pcs->base + pin * mux_bytes);
+       offset = pin * mux_bytes;
+       val = pcs->read(pcs->base + offset);
+       pa = pcs->res->start + offset;
 
-       seq_printf(s, "%08x %s " , val, DRIVER_NAME);
+       seq_printf(s, "%zx %08x %s ", pa, val, DRIVER_NAME);
 }
 
 static void pcs_dt_free_map(struct pinctrl_dev *pctldev,
@@ -763,7 +755,6 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
 {
        struct pcs_soc_data *pcs_soc = &pcs->socdata;
        struct pinctrl_pin_desc *pin;
-       struct pcs_name *pn;
        int i;
 
        i = pcs->pins.cur;
@@ -786,10 +777,6 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
        }
 
        pin = &pcs->pins.pa[i];
-       pn = &pcs->names[i];
-       sprintf(pn->name, "%lx.%u",
-               (unsigned long)pcs->res->start + offset, pin_pos);
-       pin->name = pn->name;
        pin->number = i;
        pcs->pins.cur++;
 
@@ -827,12 +814,6 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)
        if (!pcs->pins.pa)
                return -ENOMEM;
 
-       pcs->names = devm_kzalloc(pcs->dev,
-                               sizeof(struct pcs_name) * nr_pins,
-                               GFP_KERNEL);
-       if (!pcs->names)
-               return -ENOMEM;
-
        pcs->desc.pins = pcs->pins.pa;
        pcs->desc.npins = nr_pins;
 
@@ -1146,21 +1127,17 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
                                                unsigned *num_maps,
                                                const char **pgnames)
 {
+       const char *name = "pinctrl-single,pins";
        struct pcs_func_vals *vals;
-       const __be32 *mux;
-       int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
+       int rows, *pins, found = 0, res = -ENOMEM, i;
        struct pcs_function *function;
 
-       mux = of_get_property(np, PCS_MUX_PINS_NAME, &size);
-       if ((!mux) || (size < sizeof(*mux) * 2)) {
-               dev_err(pcs->dev, "bad data for mux %s\n",
-                       np->name);
+       rows = pinctrl_count_index_with_args(np, name);
+       if (rows <= 0) {
+               dev_err(pcs->dev, "Ivalid number of rows: %d\n", rows);
                return -EINVAL;
        }
 
-       size /= sizeof(*mux);   /* Number of elements in array */
-       rows = size / 2;
-
        vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL);
        if (!vals)
                return -ENOMEM;
@@ -1169,14 +1146,28 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
        if (!pins)
                goto free_vals;
 
-       while (index < size) {
-               unsigned offset, val;
+       for (i = 0; i < rows; i++) {
+               struct of_phandle_args pinctrl_spec;
+               unsigned int offset;
                int pin;
 
-               offset = be32_to_cpup(mux + index++);
-               val = be32_to_cpup(mux + index++);
+               res = pinctrl_parse_index_with_args(np, name, i, &pinctrl_spec);
+               if (res)
+                       return res;
+
+               if (pinctrl_spec.args_count < 2) {
+                       dev_err(pcs->dev, "invalid args_count for spec: %i\n",
+                               pinctrl_spec.args_count);
+                       break;
+               }
+
+               /* Index plus one value cell */
+               offset = pinctrl_spec.args[0];
                vals[found].reg = pcs->base + offset;
-               vals[found].val = val;
+               vals[found].val = pinctrl_spec.args[1];
+
+               dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x\n",
+                       pinctrl_spec.np->name, offset, pinctrl_spec.args[1]);
 
                pin = pcs_get_pin_by_offset(pcs, offset);
                if (pin < 0) {
@@ -1190,8 +1181,10 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
 
        pgnames[0] = np->name;
        function = pcs_add_function(pcs, np, np->name, vals, found, pgnames, 1);
-       if (!function)
+       if (!function) {
+               res = -ENOMEM;
                goto free_pins;
+       }
 
        res = pcs_add_pingroup(pcs, np, np->name, pins, found);
        if (res < 0)
@@ -1226,36 +1219,24 @@ free_vals:
        return res;
 }
 
-#define PARAMS_FOR_BITS_PER_MUX 3
-
 static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
                                                struct device_node *np,
                                                struct pinctrl_map **map,
                                                unsigned *num_maps,
                                                const char **pgnames)
 {
+       const char *name = "pinctrl-single,bits";
        struct pcs_func_vals *vals;
-       const __be32 *mux;
-       int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
+       int rows, *pins, found = 0, res = -ENOMEM, i;
        int npins_in_row;
        struct pcs_function *function;
 
-       mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
-
-       if (!mux) {
-               dev_err(pcs->dev, "no valid property for %s\n", np->name);
-               return -EINVAL;
-       }
-
-       if (size < (sizeof(*mux) * PARAMS_FOR_BITS_PER_MUX)) {
-               dev_err(pcs->dev, "bad data for %s\n", np->name);
+       rows = pinctrl_count_index_with_args(np, name);
+       if (rows <= 0) {
+               dev_err(pcs->dev, "Invalid number of rows: %d\n", rows);
                return -EINVAL;
        }
 
-       /* Number of elements in array */
-       size /= sizeof(*mux);
-
-       rows = size / PARAMS_FOR_BITS_PER_MUX;
        npins_in_row = pcs->width / pcs->bits_per_pin;
 
        vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows * npins_in_row,
@@ -1268,15 +1249,30 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
        if (!pins)
                goto free_vals;
 
-       while (index < size) {
+       for (i = 0; i < rows; i++) {
+               struct of_phandle_args pinctrl_spec;
                unsigned offset, val;
                unsigned mask, bit_pos, val_pos, mask_pos, submask;
                unsigned pin_num_from_lsb;
                int pin;
 
-               offset = be32_to_cpup(mux + index++);
-               val = be32_to_cpup(mux + index++);
-               mask = be32_to_cpup(mux + index++);
+               res = pinctrl_parse_index_with_args(np, name, i, &pinctrl_spec);
+               if (res)
+                       return res;
+
+               if (pinctrl_spec.args_count < 3) {
+                       dev_err(pcs->dev, "invalid args_count for spec: %i\n",
+                               pinctrl_spec.args_count);
+                       break;
+               }
+
+               /* Index plus two value cells */
+               offset = pinctrl_spec.args[0];
+               val = pinctrl_spec.args[1];
+               mask = pinctrl_spec.args[2];
+
+               dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x mask: 0x%x\n",
+                       pinctrl_spec.np->name, offset, val, mask);
 
                /* Parse pins in each row from LSB */
                while (mask) {
@@ -1319,8 +1315,10 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
 
        pgnames[0] = np->name;
        function = pcs_add_function(pcs, np, np->name, vals, found, pgnames, 1);
-       if (!function)
+       if (!function) {
+               res = -ENOMEM;
                goto free_pins;
+       }
 
        res = pcs_add_pingroup(pcs, np, np->name, pins, found);
        if (res < 0)
@@ -1494,17 +1492,12 @@ static void pcs_free_resources(struct pcs_device *pcs)
        pinctrl_unregister(pcs->pctl);
        pcs_free_funcs(pcs);
        pcs_free_pingroups(pcs);
+#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE)
+       if (pcs->missing_nr_pinctrl_cells)
+               of_remove_property(pcs->np, pcs->missing_nr_pinctrl_cells);
+#endif
 }
 
-#define PCS_GET_PROP_U32(name, reg, err)                               \
-       do {                                                            \
-               ret = of_property_read_u32(np, name, reg);              \
-               if (ret) {                                              \
-                       dev_err(pcs->dev, err);                         \
-                       return ret;                                     \
-               }                                                       \
-       } while (0);
-
 static const struct of_device_id pcs_of_match[];
 
 static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
@@ -1820,6 +1813,55 @@ static int pinctrl_single_resume(struct platform_device *pdev)
 }
 #endif
 
+/**
+ * pcs_quirk_missing_pinctrl_cells - handle legacy binding
+ * @pcs: pinctrl driver instance
+ * @np: device tree node
+ * @cells: number of cells
+ *
+ * Handle legacy binding with no #pinctrl-cells. This should be
+ * always two pinctrl-single,bit-per-mux and one for others.
+ * At some point we may want to consider removing this.
+ */
+static int pcs_quirk_missing_pinctrl_cells(struct pcs_device *pcs,
+                                          struct device_node *np,
+                                          int cells)
+{
+       struct property *p;
+       const char *name = "#pinctrl-cells";
+       int error;
+       u32 val;
+
+       error = of_property_read_u32(np, name, &val);
+       if (!error)
+               return 0;
+
+       dev_warn(pcs->dev, "please update dts to use %s = <%i>\n",
+                name, cells);
+
+       p = devm_kzalloc(pcs->dev, sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
+       p->length = sizeof(__be32);
+       p->value = devm_kzalloc(pcs->dev, sizeof(__be32), GFP_KERNEL);
+       if (!p->value)
+               return -ENOMEM;
+       *(__be32 *)p->value = cpu_to_be32(cells);
+
+       p->name = devm_kstrdup(pcs->dev, name, GFP_KERNEL);
+       if (!p->name)
+               return -ENOMEM;
+
+       pcs->missing_nr_pinctrl_cells = p;
+
+#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE)
+       error = of_add_property(np, pcs->missing_nr_pinctrl_cells);
+#endif
+
+       return error;
+}
+
 static int pcs_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -1840,6 +1882,7 @@ static int pcs_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
        pcs->dev = &pdev->dev;
+       pcs->np = np;
        raw_spin_lock_init(&pcs->lock);
        mutex_init(&pcs->mutex);
        INIT_LIST_HEAD(&pcs->pingroups);
@@ -1849,8 +1892,13 @@ static int pcs_probe(struct platform_device *pdev)
        pcs->flags = soc->flags;
        memcpy(&pcs->socdata, soc, sizeof(*soc));
 
-       PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width,
-                        "register width not specified\n");
+       ret = of_property_read_u32(np, "pinctrl-single,register-width",
+                                  &pcs->width);
+       if (ret) {
+               dev_err(pcs->dev, "register width not specified\n");
+
+               return ret;
+       }
 
        ret = of_property_read_u32(np, "pinctrl-single,function-mask",
                                   &pcs->fmask);
@@ -1871,6 +1919,13 @@ static int pcs_probe(struct platform_device *pdev)
 
        pcs->bits_per_mux = of_property_read_bool(np,
                                                  "pinctrl-single,bit-per-mux");
+       ret = pcs_quirk_missing_pinctrl_cells(pcs, np,
+                                             pcs->bits_per_mux ? 2 : 1);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to patch #pinctrl-cells\n");
+
+               return ret;
+       }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
index b7bb371679692e5dd76186be130ed4b4a6a86cb3..676efcc032d26178718c601116a1a387622760c5 100644 (file)
@@ -1006,7 +1006,7 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
 
        function = st_pctl_get_pin_function(pc, offset);
        if (function)
-               snprintf(f, 10, "Alt Fn %d", function);
+               snprintf(f, 10, "Alt Fn %u", function);
        else
                snprintf(f, 5, "GPIO");
 
@@ -1181,7 +1181,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
                if (!strcmp(pp->name, "name"))
                        continue;
 
-               if (pp  && (pp->length/sizeof(__be32)) >= OF_GPIO_ARGS_MIN) {
+               if (pp->length / sizeof(__be32) >= OF_GPIO_ARGS_MIN) {
                        npins++;
                } else {
                        pr_warn("Invalid st,pins in %s node\n", np->name);
index d2d4211e615e219cce338bf59063ecfc1ae6706e..29fb7403d24e1acd01eb3bb8bb9c8f40c17bf5d1 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  *
  * Driver for Semtech SX150X I2C GPIO Expanders
+ * The handling of the 4-bit chips (SX1501/SX1504/SX1507) is untested.
  *
  * Author: Gregory Bean <gbean@codeaurora.org>
  *
@@ -18,6 +19,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/regmap.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -25,8 +27,8 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/of.h>
-#include <linux/gpio.h>
-#include <linux/pinctrl/machine.h>
+#include <linux/of_device.h>
+#include <linux/gpio/driver.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
@@ -42,6 +44,14 @@ enum {
        SX150X_456,
        SX150X_789,
 };
+enum {
+       SX150X_789_REG_MISC_AUTOCLEAR_OFF = 1 << 0,
+       SX150X_MAX_REGISTER = 0xad,
+       SX150X_IRQ_TYPE_EDGE_RISING = 0x1,
+       SX150X_IRQ_TYPE_EDGE_FALLING = 0x2,
+       SX150X_789_RESET_KEY1 = 0x12,
+       SX150X_789_RESET_KEY2 = 0x34,
+};
 
 struct sx150x_123_pri {
        u8 reg_pld_mode;
@@ -50,7 +60,7 @@ struct sx150x_123_pri {
        u8 reg_pld_table2;
        u8 reg_pld_table3;
        u8 reg_pld_table4;
-       u8 reg_advance;
+       u8 reg_advanced;
 };
 
 struct sx150x_456_pri {
@@ -60,7 +70,7 @@ struct sx150x_456_pri {
        u8 reg_pld_table2;
        u8 reg_pld_table3;
        u8 reg_pld_table4;
-       u8 reg_advance;
+       u8 reg_advanced;
 };
 
 struct sx150x_789_pri {
@@ -98,17 +108,23 @@ struct sx150x_pinctrl {
        struct pinctrl_desc pinctrl_desc;
        struct gpio_chip gpio;
        struct irq_chip irq_chip;
+       struct regmap *regmap;
        struct {
-               int update;
                u32 sense;
                u32 masked;
-               u32 dev_sense;
-               u32 dev_masked;
        } irq;
        struct mutex lock;
        const struct sx150x_device_data *data;
 };
 
+static const struct pinctrl_pin_desc sx150x_4_pins[] = {
+       PINCTRL_PIN(0, "gpio0"),
+       PINCTRL_PIN(1, "gpio1"),
+       PINCTRL_PIN(2, "gpio2"),
+       PINCTRL_PIN(3, "gpio3"),
+       PINCTRL_PIN(4, "oscio"),
+};
+
 static const struct pinctrl_pin_desc sx150x_8_pins[] = {
        PINCTRL_PIN(0, "gpio0"),
        PINCTRL_PIN(1, "gpio1"),
@@ -141,179 +157,198 @@ static const struct pinctrl_pin_desc sx150x_16_pins[] = {
        PINCTRL_PIN(16, "oscio"),
 };
 
-static const struct sx150x_device_data sx1508q_device_data = {
-       .model = SX150X_789,
-       .reg_pullup     = 0x03,
-       .reg_pulldn     = 0x04,
-       .reg_dir        = 0x07,
-       .reg_data       = 0x08,
-       .reg_irq_mask   = 0x09,
-       .reg_irq_src    = 0x0c,
-       .reg_sense      = 0x0b,
-       .pri.x789 = {
-               .reg_drain      = 0x05,
-               .reg_polarity   = 0x06,
-               .reg_clock      = 0x0f,
-               .reg_misc       = 0x10,
-               .reg_reset      = 0x7d,
+static const struct sx150x_device_data sx1501q_device_data = {
+       .model = SX150X_123,
+       .reg_pullup     = 0x02,
+       .reg_pulldn     = 0x03,
+       .reg_dir        = 0x01,
+       .reg_data       = 0x00,
+       .reg_irq_mask   = 0x05,
+       .reg_irq_src    = 0x08,
+       .reg_sense      = 0x07,
+       .pri.x123 = {
+               .reg_pld_mode   = 0x10,
+               .reg_pld_table0 = 0x11,
+               .reg_pld_table2 = 0x13,
+               .reg_advanced   = 0xad,
        },
-       .ngpios = 8,
+       .ngpios = 4,
+       .pins = sx150x_4_pins,
+       .npins = 4, /* oscio not available */
+};
+
+static const struct sx150x_device_data sx1502q_device_data = {
+       .model = SX150X_123,
+       .reg_pullup     = 0x02,
+       .reg_pulldn     = 0x03,
+       .reg_dir        = 0x01,
+       .reg_data       = 0x00,
+       .reg_irq_mask   = 0x05,
+       .reg_irq_src    = 0x08,
+       .reg_sense      = 0x06,
+       .pri.x123 = {
+               .reg_pld_mode   = 0x10,
+               .reg_pld_table0 = 0x11,
+               .reg_pld_table1 = 0x12,
+               .reg_pld_table2 = 0x13,
+               .reg_pld_table3 = 0x14,
+               .reg_pld_table4 = 0x15,
+               .reg_advanced   = 0xad,
+       },
+       .ngpios = 8,
        .pins = sx150x_8_pins,
-       .npins = ARRAY_SIZE(sx150x_8_pins),
+       .npins = 8, /* oscio not available */
 };
 
-static const struct sx150x_device_data sx1509q_device_data = {
-       .model = SX150X_789,
-       .reg_pullup     = 0x07,
-       .reg_pulldn     = 0x09,
-       .reg_dir        = 0x0f,
-       .reg_data       = 0x11,
-       .reg_irq_mask   = 0x13,
-       .reg_irq_src    = 0x19,
-       .reg_sense      = 0x17,
-       .pri.x789 = {
-               .reg_drain      = 0x0b,
-               .reg_polarity   = 0x0d,
-               .reg_clock      = 0x1e,
-               .reg_misc       = 0x1f,
-               .reg_reset      = 0x7d,
+static const struct sx150x_device_data sx1503q_device_data = {
+       .model = SX150X_123,
+       .reg_pullup     = 0x04,
+       .reg_pulldn     = 0x06,
+       .reg_dir        = 0x02,
+       .reg_data       = 0x00,
+       .reg_irq_mask   = 0x08,
+       .reg_irq_src    = 0x0e,
+       .reg_sense      = 0x0a,
+       .pri.x123 = {
+               .reg_pld_mode   = 0x20,
+               .reg_pld_table0 = 0x22,
+               .reg_pld_table1 = 0x24,
+               .reg_pld_table2 = 0x26,
+               .reg_pld_table3 = 0x28,
+               .reg_pld_table4 = 0x2a,
+               .reg_advanced   = 0xad,
        },
        .ngpios = 16,
        .pins = sx150x_16_pins,
-       .npins = ARRAY_SIZE(sx150x_16_pins),
+       .npins  = 16, /* oscio not available */
 };
 
-static const struct sx150x_device_data sx1506q_device_data = {
+static const struct sx150x_device_data sx1504q_device_data = {
        .model = SX150X_456,
-       .reg_pullup     = 0x05,
-       .reg_pulldn     = 0x07,
-       .reg_dir        = 0x03,
-       .reg_data       = 0x01,
-       .reg_irq_mask   = 0x09,
-       .reg_irq_src    = 0x0f,
-       .reg_sense      = 0x0d,
+       .reg_pullup     = 0x02,
+       .reg_pulldn     = 0x03,
+       .reg_dir        = 0x01,
+       .reg_data       = 0x00,
+       .reg_irq_mask   = 0x05,
+       .reg_irq_src    = 0x08,
+       .reg_sense      = 0x07,
        .pri.x456 = {
-               .reg_pld_mode   = 0x21,
-               .reg_pld_table0 = 0x23,
-               .reg_pld_table1 = 0x25,
-               .reg_pld_table2 = 0x27,
-               .reg_pld_table3 = 0x29,
-               .reg_pld_table4 = 0x2b,
-               .reg_advance    = 0xad,
+               .reg_pld_mode   = 0x10,
+               .reg_pld_table0 = 0x11,
+               .reg_pld_table2 = 0x13,
        },
-       .ngpios = 16,
-       .pins = sx150x_16_pins,
-       .npins = 16, /* oscio not available */
+       .ngpios = 4,
+       .pins = sx150x_4_pins,
+       .npins = 4, /* oscio not available */
 };
 
-static const struct sx150x_device_data sx1502q_device_data = {
-       .model = SX150X_123,
+static const struct sx150x_device_data sx1505q_device_data = {
+       .model = SX150X_456,
        .reg_pullup     = 0x02,
        .reg_pulldn     = 0x03,
        .reg_dir        = 0x01,
        .reg_data       = 0x00,
        .reg_irq_mask   = 0x05,
        .reg_irq_src    = 0x08,
-       .reg_sense      = 0x07,
-       .pri.x123 = {
+       .reg_sense      = 0x06,
+       .pri.x456 = {
                .reg_pld_mode   = 0x10,
                .reg_pld_table0 = 0x11,
                .reg_pld_table1 = 0x12,
                .reg_pld_table2 = 0x13,
                .reg_pld_table3 = 0x14,
                .reg_pld_table4 = 0x15,
-               .reg_advance    = 0xad,
        },
        .ngpios = 8,
        .pins = sx150x_8_pins,
        .npins = 8, /* oscio not available */
 };
 
-static s32 sx150x_i2c_write(struct i2c_client *client, u8 reg, u8 val)
-{
-       s32 err = i2c_smbus_write_byte_data(client, reg, val);
-
-       if (err < 0)
-               dev_warn(&client->dev,
-                       "i2c write fail: can't write %02x to %02x: %d\n",
-                       val, reg, err);
-       return err;
-}
-
-static s32 sx150x_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
-{
-       s32 err = i2c_smbus_read_byte_data(client, reg);
-
-       if (err >= 0)
-               *val = err;
-       else
-               dev_warn(&client->dev,
-                       "i2c read fail: can't read from %02x: %d\n",
-                       reg, err);
-       return err;
-}
-
-/*
- * These utility functions solve the common problem of locating and setting
- * configuration bits.  Configuration bits are grouped into registers
- * whose indexes increase downwards.  For example, with eight-bit registers,
- * sixteen gpios would have their config bits grouped in the following order:
- * REGISTER N-1 [ f e d c b a 9 8 ]
- *          N   [ 7 6 5 4 3 2 1 0 ]
- *
- * For multi-bit configurations, the pattern gets wider:
- * REGISTER N-3 [ f f e e d d c c ]
- *          N-2 [ b b a a 9 9 8 8 ]
- *          N-1 [ 7 7 6 6 5 5 4 4 ]
- *          N   [ 3 3 2 2 1 1 0 0 ]
- *
- * Given the address of the starting register 'N', the index of the gpio
- * whose configuration we seek to change, and the width in bits of that
- * configuration, these functions allow us to locate the correct
- * register and mask the correct bits.
- */
-static inline void sx150x_find_cfg(u8 offset, u8 width,
-                                  u8 *reg, u8 *mask, u8 *shift)
-{
-       *reg   -= offset * width / 8;
-       *mask   = (1 << width) - 1;
-       *shift  = (offset * width) % 8;
-       *mask <<= *shift;
-}
-
-static int sx150x_write_cfg(struct i2c_client *client,
-                           u8 offset, u8 width, u8 reg, u8 val)
-{
-       u8  mask;
-       u8  data;
-       u8  shift;
-       int err;
-
-       sx150x_find_cfg(offset, width, &reg, &mask, &shift);
-       err = sx150x_i2c_read(client, reg, &data);
-       if (err < 0)
-               return err;
-
-       data &= ~mask;
-       data |= (val << shift) & mask;
-       return sx150x_i2c_write(client, reg, data);
-}
+static const struct sx150x_device_data sx1506q_device_data = {
+       .model = SX150X_456,
+       .reg_pullup     = 0x04,
+       .reg_pulldn     = 0x06,
+       .reg_dir        = 0x02,
+       .reg_data       = 0x00,
+       .reg_irq_mask   = 0x08,
+       .reg_irq_src    = 0x0e,
+       .reg_sense      = 0x0a,
+       .pri.x456 = {
+               .reg_pld_mode   = 0x20,
+               .reg_pld_table0 = 0x22,
+               .reg_pld_table1 = 0x24,
+               .reg_pld_table2 = 0x26,
+               .reg_pld_table3 = 0x28,
+               .reg_pld_table4 = 0x2a,
+               .reg_advanced   = 0xad,
+       },
+       .ngpios = 16,
+       .pins = sx150x_16_pins,
+       .npins = 16, /* oscio not available */
+};
 
-static int sx150x_read_cfg(struct i2c_client *client,
-                          u8 offset, u8 width, u8 reg)
-{
-       u8  mask;
-       u8  data;
-       u8  shift;
-       int err;
+static const struct sx150x_device_data sx1507q_device_data = {
+       .model = SX150X_789,
+       .reg_pullup     = 0x03,
+       .reg_pulldn     = 0x04,
+       .reg_dir        = 0x07,
+       .reg_data       = 0x08,
+       .reg_irq_mask   = 0x09,
+       .reg_irq_src    = 0x0b,
+       .reg_sense      = 0x0a,
+       .pri.x789 = {
+               .reg_drain      = 0x05,
+               .reg_polarity   = 0x06,
+               .reg_clock      = 0x0d,
+               .reg_misc       = 0x0e,
+               .reg_reset      = 0x7d,
+       },
+       .ngpios = 4,
+       .pins = sx150x_4_pins,
+       .npins = ARRAY_SIZE(sx150x_4_pins),
+};
 
-       sx150x_find_cfg(offset, width, &reg, &mask, &shift);
-       err = sx150x_i2c_read(client, reg, &data);
-       if (err < 0)
-               return err;
+static const struct sx150x_device_data sx1508q_device_data = {
+       .model = SX150X_789,
+       .reg_pullup     = 0x03,
+       .reg_pulldn     = 0x04,
+       .reg_dir        = 0x07,
+       .reg_data       = 0x08,
+       .reg_irq_mask   = 0x09,
+       .reg_irq_src    = 0x0c,
+       .reg_sense      = 0x0a,
+       .pri.x789 = {
+               .reg_drain      = 0x05,
+               .reg_polarity   = 0x06,
+               .reg_clock      = 0x0f,
+               .reg_misc       = 0x10,
+               .reg_reset      = 0x7d,
+       },
+       .ngpios = 8,
+       .pins = sx150x_8_pins,
+       .npins = ARRAY_SIZE(sx150x_8_pins),
+};
 
-       return (data & mask);
-}
+static const struct sx150x_device_data sx1509q_device_data = {
+       .model = SX150X_789,
+       .reg_pullup     = 0x06,
+       .reg_pulldn     = 0x08,
+       .reg_dir        = 0x0e,
+       .reg_data       = 0x10,
+       .reg_irq_mask   = 0x12,
+       .reg_irq_src    = 0x18,
+       .reg_sense      = 0x14,
+       .pri.x789 = {
+               .reg_drain      = 0x0a,
+               .reg_polarity   = 0x0c,
+               .reg_clock      = 0x1e,
+               .reg_misc       = 0x1f,
+               .reg_reset      = 0x7d,
+       },
+       .ngpios = 16,
+       .pins = sx150x_16_pins,
+       .npins = ARRAY_SIZE(sx150x_16_pins),
+};
 
 static int sx150x_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
 {
@@ -360,31 +395,33 @@ static int sx150x_gpio_get_direction(struct gpio_chip *chip,
                                      unsigned int offset)
 {
        struct sx150x_pinctrl *pctl = gpiochip_get_data(chip);
-       int status;
+       unsigned int value;
+       int ret;
 
        if (sx150x_pin_is_oscio(pctl, offset))
                return false;
 
-       status = sx150x_read_cfg(pctl->client, offset, 1, pctl->data->reg_dir);
-       if (status >= 0)
-               status = !!status;
+       ret = regmap_read(pctl->regmap, pctl->data->reg_dir, &value);
+       if (ret < 0)
+               return ret;
 
-       return status;
+       return !!(value & BIT(offset));
 }
 
 static int sx150x_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
        struct sx150x_pinctrl *pctl = gpiochip_get_data(chip);
-       int status;
+       unsigned int value;
+       int ret;
 
        if (sx150x_pin_is_oscio(pctl, offset))
                return -EINVAL;
 
-       status = sx150x_read_cfg(pctl->client, offset, 1, pctl->data->reg_data);
-       if (status >= 0)
-               status = !!status;
+       ret = regmap_read(pctl->regmap, pctl->data->reg_data, &value);
+       if (ret < 0)
+               return ret;
 
-       return status;
+       return !!(value & BIT(offset));
 }
 
 static int sx150x_gpio_set_single_ended(struct gpio_chip *chip,
@@ -400,13 +437,9 @@ static int sx150x_gpio_set_single_ended(struct gpio_chip *chip,
                    sx150x_pin_is_oscio(pctl, offset))
                        return 0;
 
-               mutex_lock(&pctl->lock);
-               ret = sx150x_write_cfg(pctl->client, offset, 1,
-                                      pctl->data->pri.x789.reg_drain,
-                                      0);
-               mutex_unlock(&pctl->lock);
-               if (ret < 0)
-                       return ret;
+               ret = regmap_write_bits(pctl->regmap,
+                                       pctl->data->pri.x789.reg_drain,
+                                       BIT(offset), 0);
                break;
 
        case LINE_MODE_OPEN_DRAIN:
@@ -414,81 +447,83 @@ static int sx150x_gpio_set_single_ended(struct gpio_chip *chip,
                    sx150x_pin_is_oscio(pctl, offset))
                        return -ENOTSUPP;
 
-               mutex_lock(&pctl->lock);
-               ret = sx150x_write_cfg(pctl->client, offset, 1,
-                                      pctl->data->pri.x789.reg_drain,
-                                      1);
-               mutex_unlock(&pctl->lock);
-               if (ret < 0)
-                       return ret;
+               ret = regmap_write_bits(pctl->regmap,
+                                       pctl->data->pri.x789.reg_drain,
+                                       BIT(offset), BIT(offset));
                break;
-
        default:
-               return -ENOTSUPP;
+               ret = -ENOTSUPP;
+               break;
        }
 
-       return 0;
+       return ret;
+}
+
+static int __sx150x_gpio_set(struct sx150x_pinctrl *pctl, unsigned int offset,
+                            int value)
+{
+       return regmap_write_bits(pctl->regmap, pctl->data->reg_data,
+                                BIT(offset), value ? BIT(offset) : 0);
+}
+
+static int sx150x_gpio_oscio_set(struct sx150x_pinctrl *pctl,
+                                int value)
+{
+       return regmap_write(pctl->regmap,
+                           pctl->data->pri.x789.reg_clock,
+                           (value ? 0x1f : 0x10));
 }
 
 static void sx150x_gpio_set(struct gpio_chip *chip, unsigned int offset,
-                              int value)
+                           int value)
 {
        struct sx150x_pinctrl *pctl = gpiochip_get_data(chip);
 
-       if (sx150x_pin_is_oscio(pctl, offset)) {
+       if (sx150x_pin_is_oscio(pctl, offset))
+               sx150x_gpio_oscio_set(pctl, value);
+       else
+               __sx150x_gpio_set(pctl, offset, value);
 
-               mutex_lock(&pctl->lock);
-               sx150x_i2c_write(pctl->client,
-                                      pctl->data->pri.x789.reg_clock,
-                                      (value ? 0x1f : 0x10));
-               mutex_unlock(&pctl->lock);
-       } else {
-               mutex_lock(&pctl->lock);
-               sx150x_write_cfg(pctl->client, offset, 1,
-                                      pctl->data->reg_data,
-                                      (value ? 1 : 0));
-               mutex_unlock(&pctl->lock);
-       }
+}
+
+static void sx150x_gpio_set_multiple(struct gpio_chip *chip,
+                                    unsigned long *mask,
+                                    unsigned long *bits)
+{
+       struct sx150x_pinctrl *pctl = gpiochip_get_data(chip);
+
+       regmap_write_bits(pctl->regmap, pctl->data->reg_data, *mask, *bits);
 }
 
 static int sx150x_gpio_direction_input(struct gpio_chip *chip,
-                                     unsigned int offset)
+                                      unsigned int offset)
 {
        struct sx150x_pinctrl *pctl = gpiochip_get_data(chip);
-       int ret;
 
        if (sx150x_pin_is_oscio(pctl, offset))
                return -EINVAL;
 
-       mutex_lock(&pctl->lock);
-       ret = sx150x_write_cfg(pctl->client, offset, 1,
-                               pctl->data->reg_dir, 1);
-       mutex_unlock(&pctl->lock);
-
-       return ret;
+       return regmap_write_bits(pctl->regmap,
+                                pctl->data->reg_dir,
+                                BIT(offset), BIT(offset));
 }
 
 static int sx150x_gpio_direction_output(struct gpio_chip *chip,
-                                      unsigned int offset, int value)
+                                       unsigned int offset, int value)
 {
        struct sx150x_pinctrl *pctl = gpiochip_get_data(chip);
-       int status;
+       int ret;
 
-       if (sx150x_pin_is_oscio(pctl, offset)) {
-               sx150x_gpio_set(chip, offset, value);
-               return 0;
-       }
+       if (sx150x_pin_is_oscio(pctl, offset))
+               return sx150x_gpio_oscio_set(pctl, value);
 
-       mutex_lock(&pctl->lock);
-       status = sx150x_write_cfg(pctl->client, offset, 1,
-                                 pctl->data->reg_data,
-                                 (value ? 1 : 0));
-       if (status >= 0)
-               status = sx150x_write_cfg(pctl->client, offset, 1,
-                                         pctl->data->reg_dir, 0);
-       mutex_unlock(&pctl->lock);
+       ret = __sx150x_gpio_set(pctl, offset, value);
+       if (ret < 0)
+               return ret;
 
-       return status;
+       return regmap_write_bits(pctl->regmap,
+                                pctl->data->reg_dir,
+                                BIT(offset), 0);
 }
 
 static void sx150x_irq_mask(struct irq_data *d)
@@ -497,8 +532,7 @@ static void sx150x_irq_mask(struct irq_data *d)
                        gpiochip_get_data(irq_data_get_irq_chip_data(d));
        unsigned int n = d->hwirq;
 
-       pctl->irq.masked |= (1 << n);
-       pctl->irq.update = n;
+       pctl->irq.masked |= BIT(n);
 }
 
 static void sx150x_irq_unmask(struct irq_data *d)
@@ -507,8 +541,22 @@ static void sx150x_irq_unmask(struct irq_data *d)
                        gpiochip_get_data(irq_data_get_irq_chip_data(d));
        unsigned int n = d->hwirq;
 
-       pctl->irq.masked &= ~(1 << n);
-       pctl->irq.update = n;
+       pctl->irq.masked &= ~BIT(n);
+}
+
+static void sx150x_irq_set_sense(struct sx150x_pinctrl *pctl,
+                                unsigned int line, unsigned int sense)
+{
+       /*
+        * Every interrupt line is represented by two bits shifted
+        * proportionally to the line number
+        */
+       const unsigned int n = line * 2;
+       const unsigned int mask = ~((SX150X_IRQ_TYPE_EDGE_RISING |
+                                    SX150X_IRQ_TYPE_EDGE_FALLING) << n);
+
+       pctl->irq.sense &= mask;
+       pctl->irq.sense |= sense << n;
 }
 
 static int sx150x_irq_set_type(struct irq_data *d, unsigned int flow_type)
@@ -523,51 +571,34 @@ static int sx150x_irq_set_type(struct irq_data *d, unsigned int flow_type)
        n = d->hwirq;
 
        if (flow_type & IRQ_TYPE_EDGE_RISING)
-               val |= 0x1;
+               val |= SX150X_IRQ_TYPE_EDGE_RISING;
        if (flow_type & IRQ_TYPE_EDGE_FALLING)
-               val |= 0x2;
+               val |= SX150X_IRQ_TYPE_EDGE_FALLING;
 
-       pctl->irq.sense &= ~(3UL << (n * 2));
-       pctl->irq.sense |= val << (n * 2);
-       pctl->irq.update = n;
+       sx150x_irq_set_sense(pctl, n, val);
        return 0;
 }
 
 static irqreturn_t sx150x_irq_thread_fn(int irq, void *dev_id)
 {
        struct sx150x_pinctrl *pctl = (struct sx150x_pinctrl *)dev_id;
-       unsigned int nhandled = 0;
-       unsigned int sub_irq;
-       unsigned int n;
-       s32 err;
-       u8 val;
-       int i;
+       unsigned long n, status;
+       unsigned int val;
+       int err;
 
-       for (i = (pctl->data->ngpios / 8) - 1; i >= 0; --i) {
-               err = sx150x_i2c_read(pctl->client,
-                                     pctl->data->reg_irq_src - i,
-                                     &val);
-               if (err < 0)
-                       continue;
+       err = regmap_read(pctl->regmap, pctl->data->reg_irq_src, &val);
+       if (err < 0)
+               return IRQ_NONE;
 
-               err = sx150x_i2c_write(pctl->client,
-                                      pctl->data->reg_irq_src - i,
-                                      val);
-               if (err < 0)
-                       continue;
-
-               for (n = 0; n < 8; ++n) {
-                       if (val & (1 << n)) {
-                               sub_irq = irq_find_mapping(
-                                               pctl->gpio.irqdomain,
-                                               (i * 8) + n);
-                               handle_nested_irq(sub_irq);
-                               ++nhandled;
-                       }
-               }
-       }
+       err = regmap_write(pctl->regmap, pctl->data->reg_irq_src, val);
+       if (err < 0)
+               return IRQ_NONE;
 
-       return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
+       status = val;
+       for_each_set_bit(n, &status, pctl->data->ngpios)
+               handle_nested_irq(irq_find_mapping(pctl->gpio.irqdomain, n));
+
+       return IRQ_HANDLED;
 }
 
 static void sx150x_irq_bus_lock(struct irq_data *d)
@@ -582,35 +613,9 @@ static void sx150x_irq_bus_sync_unlock(struct irq_data *d)
 {
        struct sx150x_pinctrl *pctl =
                        gpiochip_get_data(irq_data_get_irq_chip_data(d));
-       unsigned int n;
-
-       if (pctl->irq.update < 0)
-               goto out;
 
-       n = pctl->irq.update;
-       pctl->irq.update = -1;
-
-       /* Avoid updates if nothing changed */
-       if (pctl->irq.dev_sense == pctl->irq.sense &&
-           pctl->irq.dev_masked == pctl->irq.masked)
-               goto out;
-
-       pctl->irq.dev_sense = pctl->irq.sense;
-       pctl->irq.dev_masked = pctl->irq.masked;
-
-       if (pctl->irq.masked & (1 << n)) {
-               sx150x_write_cfg(pctl->client, n, 1,
-                                pctl->data->reg_irq_mask, 1);
-               sx150x_write_cfg(pctl->client, n, 2,
-                                pctl->data->reg_sense, 0);
-       } else {
-               sx150x_write_cfg(pctl->client, n, 1,
-                                pctl->data->reg_irq_mask, 0);
-               sx150x_write_cfg(pctl->client, n, 2,
-                                pctl->data->reg_sense,
-                                pctl->irq.sense >> (n * 2));
-       }
-out:
+       regmap_write(pctl->regmap, pctl->data->reg_irq_mask, pctl->irq.masked);
+       regmap_write(pctl->regmap, pctl->data->reg_sense, pctl->irq.sense);
        mutex_unlock(&pctl->lock);
 }
 
@@ -621,19 +626,15 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
        unsigned int param = pinconf_to_config_param(*config);
        int ret;
        u32 arg;
+       unsigned int data;
 
        if (sx150x_pin_is_oscio(pctl, pin)) {
-               u8 data;
-
                switch (param) {
                case PIN_CONFIG_DRIVE_PUSH_PULL:
                case PIN_CONFIG_OUTPUT:
-                       mutex_lock(&pctl->lock);
-                       ret = sx150x_i2c_read(pctl->client,
-                                       pctl->data->pri.x789.reg_clock,
-                                       &data);
-                       mutex_unlock(&pctl->lock);
-
+                       ret = regmap_read(pctl->regmap,
+                                         pctl->data->pri.x789.reg_clock,
+                                         &data);
                        if (ret < 0)
                                return ret;
 
@@ -658,10 +659,10 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 
        switch (param) {
        case PIN_CONFIG_BIAS_PULL_DOWN:
-               mutex_lock(&pctl->lock);
-               ret = sx150x_read_cfg(pctl->client, pin, 1,
-                                     pctl->data->reg_pulldn);
-               mutex_unlock(&pctl->lock);
+               ret = regmap_read(pctl->regmap,
+                                 pctl->data->reg_pulldn,
+                                 &data);
+               data &= BIT(pin);
 
                if (ret < 0)
                        return ret;
@@ -673,10 +674,10 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
                break;
 
        case PIN_CONFIG_BIAS_PULL_UP:
-               mutex_lock(&pctl->lock);
-               ret = sx150x_read_cfg(pctl->client, pin, 1,
-                                     pctl->data->reg_pullup);
-               mutex_unlock(&pctl->lock);
+               ret = regmap_read(pctl->regmap,
+                                 pctl->data->reg_pullup,
+                                 &data);
+               data &= BIT(pin);
 
                if (ret < 0)
                        return ret;
@@ -691,15 +692,15 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
                if (pctl->data->model != SX150X_789)
                        return -ENOTSUPP;
 
-               mutex_lock(&pctl->lock);
-               ret = sx150x_read_cfg(pctl->client, pin, 1,
-                                     pctl->data->pri.x789.reg_drain);
-               mutex_unlock(&pctl->lock);
+               ret = regmap_read(pctl->regmap,
+                                 pctl->data->pri.x789.reg_drain,
+                                 &data);
+               data &= BIT(pin);
 
                if (ret < 0)
                        return ret;
 
-               if (!ret)
+               if (!data)
                        return -EINVAL;
 
                arg = 1;
@@ -709,15 +710,15 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
                if (pctl->data->model != SX150X_789)
                        arg = true;
                else {
-                       mutex_lock(&pctl->lock);
-                       ret = sx150x_read_cfg(pctl->client, pin, 1,
-                                             pctl->data->pri.x789.reg_drain);
-                       mutex_unlock(&pctl->lock);
+                       ret = regmap_read(pctl->regmap,
+                                         pctl->data->pri.x789.reg_drain,
+                                         &data);
+                       data &= BIT(pin);
 
                        if (ret < 0)
                                return ret;
 
-                       if (ret)
+                       if (data)
                                return -EINVAL;
 
                        arg = 1;
@@ -777,39 +778,33 @@ static int sx150x_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                switch (param) {
                case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
                case PIN_CONFIG_BIAS_DISABLE:
-                       mutex_lock(&pctl->lock);
-                       ret = sx150x_write_cfg(pctl->client, pin, 1,
-                                              pctl->data->reg_pulldn, 0);
-                       mutex_unlock(&pctl->lock);
+                       ret = regmap_write_bits(pctl->regmap,
+                                               pctl->data->reg_pulldn,
+                                               BIT(pin), 0);
                        if (ret < 0)
                                return ret;
 
-                       mutex_lock(&pctl->lock);
-                       ret = sx150x_write_cfg(pctl->client, pin, 1,
-                                              pctl->data->reg_pullup, 0);
-                       mutex_unlock(&pctl->lock);
+                       ret = regmap_write_bits(pctl->regmap,
+                                               pctl->data->reg_pullup,
+                                               BIT(pin), 0);
                        if (ret < 0)
                                return ret;
 
                        break;
 
                case PIN_CONFIG_BIAS_PULL_UP:
-                       mutex_lock(&pctl->lock);
-                       ret = sx150x_write_cfg(pctl->client, pin, 1,
-                                              pctl->data->reg_pullup,
-                                              1);
-                       mutex_unlock(&pctl->lock);
+                       ret = regmap_write_bits(pctl->regmap,
+                                               pctl->data->reg_pullup,
+                                               BIT(pin), BIT(pin));
                        if (ret < 0)
                                return ret;
 
                        break;
 
                case PIN_CONFIG_BIAS_PULL_DOWN:
-                       mutex_lock(&pctl->lock);
-                       ret = sx150x_write_cfg(pctl->client, pin, 1,
-                                              pctl->data->reg_pulldn,
-                                              1);
-                       mutex_unlock(&pctl->lock);
+                       ret = regmap_write_bits(pctl->regmap,
+                                               pctl->data->reg_pulldn,
+                                               BIT(pin), BIT(pin));
                        if (ret < 0)
                                return ret;
 
@@ -854,49 +849,86 @@ static const struct pinconf_ops sx150x_pinconf_ops = {
 };
 
 static const struct i2c_device_id sx150x_id[] = {
+       {"sx1501q", (kernel_ulong_t) &sx1501q_device_data },
+       {"sx1502q", (kernel_ulong_t) &sx1502q_device_data },
+       {"sx1503q", (kernel_ulong_t) &sx1503q_device_data },
+       {"sx1504q", (kernel_ulong_t) &sx1504q_device_data },
+       {"sx1505q", (kernel_ulong_t) &sx1505q_device_data },
+       {"sx1506q", (kernel_ulong_t) &sx1506q_device_data },
+       {"sx1507q", (kernel_ulong_t) &sx1507q_device_data },
        {"sx1508q", (kernel_ulong_t) &sx1508q_device_data },
        {"sx1509q", (kernel_ulong_t) &sx1509q_device_data },
-       {"sx1506q", (kernel_ulong_t) &sx1506q_device_data },
-       {"sx1502q", (kernel_ulong_t) &sx1502q_device_data },
        {}
 };
 
 static const struct of_device_id sx150x_of_match[] = {
-       { .compatible = "semtech,sx1508q" },
-       { .compatible = "semtech,sx1509q" },
-       { .compatible = "semtech,sx1506q" },
-       { .compatible = "semtech,sx1502q" },
+       { .compatible = "semtech,sx1501q", .data = &sx1501q_device_data },
+       { .compatible = "semtech,sx1502q", .data = &sx1502q_device_data },
+       { .compatible = "semtech,sx1503q", .data = &sx1503q_device_data },
+       { .compatible = "semtech,sx1504q", .data = &sx1504q_device_data },
+       { .compatible = "semtech,sx1505q", .data = &sx1505q_device_data },
+       { .compatible = "semtech,sx1506q", .data = &sx1506q_device_data },
+       { .compatible = "semtech,sx1507q", .data = &sx1507q_device_data },
+       { .compatible = "semtech,sx1508q", .data = &sx1508q_device_data },
+       { .compatible = "semtech,sx1509q", .data = &sx1509q_device_data },
        {},
 };
 
-static int sx150x_init_io(struct sx150x_pinctrl *pctl, u8 base, u16 cfg)
-{
-       int err = 0;
-       unsigned int n;
-
-       for (n = 0; err >= 0 && n < (pctl->data->ngpios / 8); ++n)
-               err = sx150x_i2c_write(pctl->client, base - n, cfg >> (n * 8));
-       return err;
-}
-
 static int sx150x_reset(struct sx150x_pinctrl *pctl)
 {
        int err;
 
        err = i2c_smbus_write_byte_data(pctl->client,
                                        pctl->data->pri.x789.reg_reset,
-                                       0x12);
+                                       SX150X_789_RESET_KEY1);
        if (err < 0)
                return err;
 
        err = i2c_smbus_write_byte_data(pctl->client,
                                        pctl->data->pri.x789.reg_reset,
-                                       0x34);
+                                       SX150X_789_RESET_KEY2);
        return err;
 }
 
+static int sx150x_init_misc(struct sx150x_pinctrl *pctl)
+{
+       u8 reg, value;
+
+       switch (pctl->data->model) {
+       case SX150X_789:
+               reg   = pctl->data->pri.x789.reg_misc;
+               value = SX150X_789_REG_MISC_AUTOCLEAR_OFF;
+               break;
+       case SX150X_456:
+               reg   = pctl->data->pri.x456.reg_advanced;
+               value = 0x00;
+
+               /*
+                * Only SX1506 has RegAdvanced, SX1504/5 are expected
+                * to initialize this offset to zero
+                */
+               if (!reg)
+                       return 0;
+               break;
+       case SX150X_123:
+               reg   = pctl->data->pri.x123.reg_advanced;
+               value = 0x00;
+               break;
+       default:
+               WARN(1, "Unknown chip model %d\n", pctl->data->model);
+               return -EINVAL;
+       }
+
+       return regmap_write(pctl->regmap, reg, value);
+}
+
 static int sx150x_init_hw(struct sx150x_pinctrl *pctl)
 {
+       const u8 reg[] = {
+               [SX150X_789] = pctl->data->pri.x789.reg_polarity,
+               [SX150X_456] = pctl->data->pri.x456.reg_pld_mode,
+               [SX150X_123] = pctl->data->pri.x123.reg_pld_mode,
+       };
        int err;
 
        if (pctl->data->model == SX150X_789 &&
@@ -906,47 +938,193 @@ static int sx150x_init_hw(struct sx150x_pinctrl *pctl)
                        return err;
        }
 
-       if (pctl->data->model == SX150X_789)
-               err = sx150x_i2c_write(pctl->client,
-                               pctl->data->pri.x789.reg_misc,
-                               0x01);
-       else if (pctl->data->model == SX150X_456)
-               err = sx150x_i2c_write(pctl->client,
-                               pctl->data->pri.x456.reg_advance,
-                               0x04);
-       else
-               err = sx150x_i2c_write(pctl->client,
-                               pctl->data->pri.x123.reg_advance,
-                               0x00);
+       err = sx150x_init_misc(pctl);
        if (err < 0)
                return err;
 
        /* Set all pins to work in normal mode */
-       if (pctl->data->model == SX150X_789) {
-               err = sx150x_init_io(pctl,
-                               pctl->data->pri.x789.reg_polarity,
-                               0);
-               if (err < 0)
-                       return err;
-       } else if (pctl->data->model == SX150X_456) {
-               /* Set all pins to work in normal mode */
-               err = sx150x_init_io(pctl,
-                               pctl->data->pri.x456.reg_pld_mode,
-                               0);
-               if (err < 0)
-                       return err;
+       return regmap_write(pctl->regmap, reg[pctl->data->model], 0);
+}
+
+static int sx150x_regmap_reg_width(struct sx150x_pinctrl *pctl,
+                                  unsigned int reg)
+{
+       const struct sx150x_device_data *data = pctl->data;
+
+       if (reg == data->reg_sense) {
+               /*
+                * RegSense packs two bits of configuration per GPIO,
+                * so we'd need to read twice as many bits as there
+                * are GPIO in our chip
+                */
+               return 2 * data->ngpios;
+       } else if ((data->model == SX150X_789 &&
+                   (reg == data->pri.x789.reg_misc ||
+                    reg == data->pri.x789.reg_clock ||
+                    reg == data->pri.x789.reg_reset))
+                  ||
+                  (data->model == SX150X_123 &&
+                   reg == data->pri.x123.reg_advanced)
+                  ||
+                  (data->model == SX150X_456 &&
+                   data->pri.x456.reg_advanced &&
+                   reg == data->pri.x456.reg_advanced)) {
+               return 8;
        } else {
-               /* Set all pins to work in normal mode */
-               err = sx150x_init_io(pctl,
-                               pctl->data->pri.x123.reg_pld_mode,
-                               0);
-               if (err < 0)
-                       return err;
+               return data->ngpios;
+       }
+}
+
+static unsigned int sx150x_maybe_swizzle(struct sx150x_pinctrl *pctl,
+                                        unsigned int reg, unsigned int val)
+{
+       unsigned int a, b;
+       const struct sx150x_device_data *data = pctl->data;
+
+       /*
+        * Whereas SX1509 presents RegSense in a simple layout as such:
+        *      reg     [ f f e e d d c c ]
+        *      reg + 1 [ b b a a 9 9 8 8 ]
+        *      reg + 2 [ 7 7 6 6 5 5 4 4 ]
+        *      reg + 3 [ 3 3 2 2 1 1 0 0 ]
+        *
+        * SX1503 and SX1506 deviate from that data layout, instead storing
+        * their contents as follows:
+        *
+        *      reg     [ f f e e d d c c ]
+        *      reg + 1 [ 7 7 6 6 5 5 4 4 ]
+        *      reg + 2 [ b b a a 9 9 8 8 ]
+        *      reg + 3 [ 3 3 2 2 1 1 0 0 ]
+        *
+        * so, taking that into account, we swap two
+        * inner bytes of a 4-byte result
+        */
+
+       if (reg == data->reg_sense &&
+           data->ngpios == 16 &&
+           (data->model == SX150X_123 ||
+            data->model == SX150X_456)) {
+               a = val & 0x00ff0000;
+               b = val & 0x0000ff00;
+
+               val &= 0xff0000ff;
+               val |= b << 8;
+               val |= a >> 8;
+       }
+
+       return val;
+}
+
+/*
+ * In order to mask the differences between 16 and 8 bit expander
+ * devices we set up a sligthly ficticious regmap that pretends to be
+ * a set of 32-bit (to accomodate RegSenseLow/RegSenseHigh
+ * pair/quartet) registers and transparently reconstructs those
+ * registers via multiple I2C/SMBus reads
+ *
+ * This way the rest of the driver code, interfacing with the chip via
+ * regmap API, can work assuming that each GPIO pin is represented by
+ * a group of bits at an offset proportional to GPIO number within a
+ * given register.
+ */
+static int sx150x_regmap_reg_read(void *context, unsigned int reg,
+                                 unsigned int *result)
+{
+       int ret, n;
+       struct sx150x_pinctrl *pctl = context;
+       struct i2c_client *i2c = pctl->client;
+       const int width = sx150x_regmap_reg_width(pctl, reg);
+       unsigned int idx, val;
+
+       /*
+        * There are four potential cases covered by this function:
+        *
+        * 1) 8-pin chip, single configuration bit register
+        *
+        *      This is trivial the code below just needs to read:
+        *              reg  [ 7 6 5 4 3 2 1 0 ]
+        *
+        * 2) 8-pin chip, double configuration bit register (RegSense)
+        *
+        *      The read will be done as follows:
+        *              reg      [ 7 7 6 6 5 5 4 4 ]
+        *              reg + 1  [ 3 3 2 2 1 1 0 0 ]
+        *
+        * 3) 16-pin chip, single configuration bit register
+        *
+        *      The read will be done as follows:
+        *              reg     [ f e d c b a 9 8 ]
+        *              reg + 1 [ 7 6 5 4 3 2 1 0 ]
+        *
+        * 4) 16-pin chip, double configuration bit register (RegSense)
+        *
+        *      The read will be done as follows:
+        *              reg     [ f f e e d d c c ]
+        *              reg + 1 [ b b a a 9 9 8 8 ]
+        *              reg + 2 [ 7 7 6 6 5 5 4 4 ]
+        *              reg + 3 [ 3 3 2 2 1 1 0 0 ]
+        */
+
+       for (n = width, val = 0, idx = reg; n > 0; n -= 8, idx++) {
+               val <<= 8;
+
+               ret = i2c_smbus_read_byte_data(i2c, idx);
+               if (ret < 0)
+                       return ret;
+
+               val |= ret;
        }
 
+       *result = sx150x_maybe_swizzle(pctl, reg, val);
+
+       return 0;
+}
+
+static int sx150x_regmap_reg_write(void *context, unsigned int reg,
+                                  unsigned int val)
+{
+       int ret, n;
+       struct sx150x_pinctrl *pctl = context;
+       struct i2c_client *i2c = pctl->client;
+       const int width = sx150x_regmap_reg_width(pctl, reg);
+
+       val = sx150x_maybe_swizzle(pctl, reg, val);
+
+       n = (width - 1) & ~7;
+       do {
+               const u8 byte = (val >> n) & 0xff;
+
+               ret = i2c_smbus_write_byte_data(i2c, reg, byte);
+               if (ret < 0)
+                       return ret;
+
+               reg++;
+               n -= 8;
+       } while (n >= 0);
+
        return 0;
 }
 
+static bool sx150x_reg_volatile(struct device *dev, unsigned int reg)
+{
+       struct sx150x_pinctrl *pctl = i2c_get_clientdata(to_i2c_client(dev));
+
+       return reg == pctl->data->reg_irq_src || reg == pctl->data->reg_data;
+}
+
+const struct regmap_config sx150x_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 32,
+
+       .cache_type = REGCACHE_RBTREE,
+
+       .reg_read = sx150x_regmap_reg_read,
+       .reg_write = sx150x_regmap_reg_write,
+
+       .max_register = SX150X_MAX_REGISTER,
+       .volatile_reg = sx150x_reg_volatile,
+};
+
 static int sx150x_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
@@ -956,9 +1134,6 @@ static int sx150x_probe(struct i2c_client *client,
        struct sx150x_pinctrl *pctl;
        int ret;
 
-       if (!id->driver_data)
-               return -EINVAL;
-
        if (!i2c_check_functionality(client->adapter, i2c_funcs))
                return -ENOSYS;
 
@@ -966,9 +1141,27 @@ static int sx150x_probe(struct i2c_client *client,
        if (!pctl)
                return -ENOMEM;
 
+       i2c_set_clientdata(client, pctl);
+
        pctl->dev = dev;
        pctl->client = client;
-       pctl->data = (void *)id->driver_data;
+
+       if (dev->of_node)
+               pctl->data = of_device_get_match_data(dev);
+       else
+               pctl->data = (struct sx150x_device_data *)id->driver_data;
+
+       if (!pctl->data)
+               return -EINVAL;
+
+       pctl->regmap = devm_regmap_init(dev, NULL, pctl,
+                                       &sx150x_regmap_config);
+       if (IS_ERR(pctl->regmap)) {
+               ret = PTR_ERR(pctl->regmap);
+               dev_err(dev, "Failed to allocate register map: %d\n",
+                       ret);
+               return ret;
+       }
 
        mutex_init(&pctl->lock);
 
@@ -991,6 +1184,14 @@ static int sx150x_probe(struct i2c_client *client,
        pctl->gpio.of_node = dev->of_node;
 #endif
        pctl->gpio.can_sleep = true;
+       /*
+        * Setting multiple pins is not safe when all pins are not
+        * handled by the same regmap register. The oscio pin (present
+        * on the SX150X_789 chips) lives in its own register, so
+        * would require locking that is not in place at this time.
+        */
+       if (pctl->data->model != SX150X_789)
+               pctl->gpio.set_multiple = sx150x_gpio_set_multiple;
 
        ret = devm_gpiochip_add_data(dev, &pctl->gpio, pctl);
        if (ret)
@@ -1008,13 +1209,21 @@ static int sx150x_probe(struct i2c_client *client,
 
                pctl->irq.masked = ~0;
                pctl->irq.sense = 0;
-               pctl->irq.dev_masked = ~0;
-               pctl->irq.dev_sense = 0;
-               pctl->irq.update = -1;
 
-               ret = gpiochip_irqchip_add(&pctl->gpio,
-                                          &pctl->irq_chip, 0,
-                                          handle_edge_irq, IRQ_TYPE_NONE);
+               /*
+                * Because sx150x_irq_threaded_fn invokes all of the
+                * nested interrrupt handlers via handle_nested_irq,
+                * any "handler" passed to gpiochip_irqchip_add()
+                * below is going to be ignored, so the choice of the
+                * function does not matter that much.
+                *
+                * We set it to handle_bad_irq to avoid confusion,
+                * plus it will be instantly noticeable if it is ever
+                * called (should not happen)
+                */
+               ret = gpiochip_irqchip_add_nested(&pctl->gpio,
+                                       &pctl->irq_chip, 0,
+                                       handle_bad_irq, IRQ_TYPE_NONE);
                if (ret) {
                        dev_err(dev, "could not connect irqchip to gpiochip\n");
                        return ret;
@@ -1027,6 +1236,10 @@ static int sx150x_probe(struct i2c_client *client,
                                                pctl->irq_chip.name, pctl);
                if (ret < 0)
                        return ret;
+
+               gpiochip_set_nested_irqchip(&pctl->gpio,
+                                           &pctl->irq_chip,
+                                           client->irq);
        }
 
        /* Pinctrl_desc */
index e0ecffcbe11f6ec58026f59e63e66b69fc5be7c4..b51a46dfdcc35503a8168af56dbb28bace6c31e9 100644 (file)
@@ -247,6 +247,8 @@ static const unsigned int smc0_nor_addr25_pins[] = {1};
 static const unsigned int smc0_nand_pins[] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
                                              12, 13, 14, 16, 17, 18, 19, 20,
                                              21, 22, 23};
+static const unsigned int smc0_nand8_pins[] = {0, 2, 3,  4,  5,  6,  7,
+                                              8, 9, 10, 11, 12, 13, 14};
 /* Note: CAN MIO clock inputs are modeled in the clock framework */
 static const unsigned int can0_0_pins[] = {10, 11};
 static const unsigned int can0_1_pins[] = {14, 15};
@@ -445,6 +447,7 @@ static const struct zynq_pctrl_group zynq_pctrl_groups[] = {
        DEFINE_ZYNQ_PINCTRL_GRP(smc0_nor_cs1),
        DEFINE_ZYNQ_PINCTRL_GRP(smc0_nor_addr25),
        DEFINE_ZYNQ_PINCTRL_GRP(smc0_nand),
+       DEFINE_ZYNQ_PINCTRL_GRP(smc0_nand8),
        DEFINE_ZYNQ_PINCTRL_GRP(can0_0),
        DEFINE_ZYNQ_PINCTRL_GRP(can0_1),
        DEFINE_ZYNQ_PINCTRL_GRP(can0_2),
@@ -709,7 +712,8 @@ static const char * const sdio1_wp_groups[] = {"gpio0_0_grp",
 static const char * const smc0_nor_groups[] = {"smc0_nor_grp"};
 static const char * const smc0_nor_cs1_groups[] = {"smc0_nor_cs1_grp"};
 static const char * const smc0_nor_addr25_groups[] = {"smc0_nor_addr25_grp"};
-static const char * const smc0_nand_groups[] = {"smc0_nand_grp"};
+static const char * const smc0_nand_groups[] = {"smc0_nand_grp",
+               "smc0_nand8_grp"};
 static const char * const can0_groups[] = {"can0_0_grp", "can0_1_grp",
                "can0_2_grp", "can0_3_grp", "can0_4_grp", "can0_5_grp",
                "can0_6_grp", "can0_7_grp", "can0_8_grp", "can0_9_grp",
index 93ef268d5ccdbcab5a78a055dd9c4f87d133da95..3ebdc01f53c0072671c8f79afc9547d5839e5826 100644 (file)
@@ -79,6 +79,15 @@ config PINCTRL_MSM8916
          This is the pinctrl, pinmux, pinconf and gpiolib driver for the
          Qualcomm TLMM block found on the Qualcomm 8916 platform.
 
+config PINCTRL_MSM8994
+       tristate "Qualcomm 8994 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 8994 platform. The
+         Qualcomm 8992 platform is also supported by this driver.
+
 config PINCTRL_MSM8996
        tristate "Qualcomm MSM8996 pin controller driver"
        depends on GPIOLIB && OF
index 8319e11cecb57c75a84d18c7641fb729e9028cb6..ab47764dbc5c6d018661a3a035bed1082e58c3dc 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_MSM8660)   += pinctrl-msm8660.o
 obj-$(CONFIG_PINCTRL_MSM8960)  += pinctrl-msm8960.o
 obj-$(CONFIG_PINCTRL_MSM8X74)  += pinctrl-msm8x74.o
 obj-$(CONFIG_PINCTRL_MSM8916)  += pinctrl-msm8916.o
+obj-$(CONFIG_PINCTRL_MSM8994)   += pinctrl-msm8994.o
 obj-$(CONFIG_PINCTRL_MSM8996)   += pinctrl-msm8996.o
 obj-$(CONFIG_PINCTRL_QDF2XXX)  += pinctrl-qdf2xxx.o
 obj-$(CONFIG_PINCTRL_MDM9615)  += pinctrl-mdm9615.o
diff --git a/drivers/pinctrl/qcom/pinctrl-msm8994.c b/drivers/pinctrl/qcom/pinctrl-msm8994.c
new file mode 100644 (file)
index 0000000..8e16d9a
--- /dev/null
@@ -0,0 +1,1379 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * 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 "pinctrl-msm.h"
+
+#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 = 0x1008 + 0x10 * 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_target_bit = 5,                   \
+               .intr_target_kpss_val = 4,              \
+               .intr_raw_status_bit = 4,               \
+               .intr_polarity_bit = 1,                 \
+               .intr_detection_bit = 2,                \
+               .intr_detection_width = 2,              \
+       }
+
+#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_target_kpss_val = -1,             \
+               .intr_raw_status_bit = -1,              \
+               .intr_polarity_bit = -1,                \
+               .intr_detection_bit = -1,               \
+               .intr_detection_width = -1,             \
+       }
+static const struct pinctrl_pin_desc msm8994_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, "SDC1_RCLK"),
+       PINCTRL_PIN(147, "SDC1_CLK"),
+       PINCTRL_PIN(148, "SDC1_CMD"),
+       PINCTRL_PIN(149, "SDC1_DATA"),
+       PINCTRL_PIN(150, "SDC2_CLK"),
+       PINCTRL_PIN(151, "SDC2_CMD"),
+       PINCTRL_PIN(152, "SDC2_DATA"),
+       PINCTRL_PIN(153, "SDC3_CLK"),
+       PINCTRL_PIN(154, "SDC3_CMD"),
+       PINCTRL_PIN(155, "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);
+
+static const unsigned int sdc1_rclk_pins[] = { 146 };
+static const unsigned int sdc1_clk_pins[] = { 147 };
+static const unsigned int sdc1_cmd_pins[] = { 148 };
+static const unsigned int sdc1_data_pins[] = { 149 };
+static const unsigned int sdc2_clk_pins[] = { 150 };
+static const unsigned int sdc2_cmd_pins[] = { 151 };
+static const unsigned int sdc2_data_pins[] = { 152 };
+static const unsigned int sdc3_clk_pins[] = { 153 };
+static const unsigned int sdc3_cmd_pins[] = { 154 };
+static const unsigned int sdc3_data_pins[] = { 155 };
+
+enum msm8994_functions {
+       MSM_MUX_audio_ref_clk,
+       MSM_MUX_blsp_i2c1,
+       MSM_MUX_blsp_i2c2,
+       MSM_MUX_blsp_i2c3,
+       MSM_MUX_blsp_i2c4,
+       MSM_MUX_blsp_i2c5,
+       MSM_MUX_blsp_i2c6,
+       MSM_MUX_blsp_i2c7,
+       MSM_MUX_blsp_i2c8,
+       MSM_MUX_blsp_i2c9,
+       MSM_MUX_blsp_i2c10,
+       MSM_MUX_blsp_i2c11,
+       MSM_MUX_blsp_i2c12,
+       MSM_MUX_blsp_spi1,
+       MSM_MUX_blsp_spi1_cs1,
+       MSM_MUX_blsp_spi1_cs2,
+       MSM_MUX_blsp_spi1_cs3,
+       MSM_MUX_blsp_spi2,
+       MSM_MUX_blsp_spi2_cs1,
+       MSM_MUX_blsp_spi2_cs2,
+       MSM_MUX_blsp_spi2_cs3,
+       MSM_MUX_blsp_spi3,
+       MSM_MUX_blsp_spi4,
+       MSM_MUX_blsp_spi5,
+       MSM_MUX_blsp_spi6,
+       MSM_MUX_blsp_spi7,
+       MSM_MUX_blsp_spi8,
+       MSM_MUX_blsp_spi9,
+       MSM_MUX_blsp_spi10,
+       MSM_MUX_blsp_spi10_cs1,
+       MSM_MUX_blsp_spi10_cs2,
+       MSM_MUX_blsp_spi10_cs3,
+       MSM_MUX_blsp_spi11,
+       MSM_MUX_blsp_spi12,
+       MSM_MUX_blsp_uart1,
+       MSM_MUX_blsp_uart2,
+       MSM_MUX_blsp_uart3,
+       MSM_MUX_blsp_uart4,
+       MSM_MUX_blsp_uart5,
+       MSM_MUX_blsp_uart6,
+       MSM_MUX_blsp_uart7,
+       MSM_MUX_blsp_uart8,
+       MSM_MUX_blsp_uart9,
+       MSM_MUX_blsp_uart10,
+       MSM_MUX_blsp_uart11,
+       MSM_MUX_blsp_uart12,
+       MSM_MUX_blsp_uim1,
+       MSM_MUX_blsp_uim2,
+       MSM_MUX_blsp_uim3,
+       MSM_MUX_blsp_uim4,
+       MSM_MUX_blsp_uim5,
+       MSM_MUX_blsp_uim6,
+       MSM_MUX_blsp_uim7,
+       MSM_MUX_blsp_uim8,
+       MSM_MUX_blsp_uim9,
+       MSM_MUX_blsp_uim10,
+       MSM_MUX_blsp_uim11,
+       MSM_MUX_blsp_uim12,
+       MSM_MUX_blsp11_i2c_scl_b,
+       MSM_MUX_blsp11_i2c_sda_b,
+       MSM_MUX_blsp11_uart_rx_b,
+       MSM_MUX_blsp11_uart_tx_b,
+       MSM_MUX_cam_mclk0,
+       MSM_MUX_cam_mclk1,
+       MSM_MUX_cam_mclk2,
+       MSM_MUX_cam_mclk3,
+       MSM_MUX_cci_async_in0,
+       MSM_MUX_cci_async_in1,
+       MSM_MUX_cci_async_in2,
+       MSM_MUX_cci_i2c0,
+       MSM_MUX_cci_i2c1,
+       MSM_MUX_cci_timer0,
+       MSM_MUX_cci_timer1,
+       MSM_MUX_cci_timer2,
+       MSM_MUX_cci_timer3,
+       MSM_MUX_cci_timer4,
+       MSM_MUX_gcc_gp1_clk_a,
+       MSM_MUX_gcc_gp1_clk_b,
+       MSM_MUX_gcc_gp2_clk_a,
+       MSM_MUX_gcc_gp2_clk_b,
+       MSM_MUX_gcc_gp3_clk_a,
+       MSM_MUX_gcc_gp3_clk_b,
+       MSM_MUX_gp_mn,
+       MSM_MUX_gp_pdm0,
+       MSM_MUX_gp_pdm1,
+       MSM_MUX_gp_pdm2,
+       MSM_MUX_gp0_clk,
+       MSM_MUX_gp1_clk,
+       MSM_MUX_gps_tx,
+       MSM_MUX_gsm_tx,
+       MSM_MUX_hdmi_cec,
+       MSM_MUX_hdmi_ddc,
+       MSM_MUX_hdmi_hpd,
+       MSM_MUX_hdmi_rcv,
+       MSM_MUX_mdp_vsync,
+       MSM_MUX_mss_lte,
+       MSM_MUX_nav_pps,
+       MSM_MUX_nav_tsync,
+       MSM_MUX_qdss_cti_trig_in_a,
+       MSM_MUX_qdss_cti_trig_in_b,
+       MSM_MUX_qdss_cti_trig_in_c,
+       MSM_MUX_qdss_cti_trig_in_d,
+       MSM_MUX_qdss_cti_trig_out_a,
+       MSM_MUX_qdss_cti_trig_out_b,
+       MSM_MUX_qdss_cti_trig_out_c,
+       MSM_MUX_qdss_cti_trig_out_d,
+       MSM_MUX_qdss_traceclk_a,
+       MSM_MUX_qdss_traceclk_b,
+       MSM_MUX_qdss_tracectl_a,
+       MSM_MUX_qdss_tracectl_b,
+       MSM_MUX_qdss_tracedata_a,
+       MSM_MUX_qdss_tracedata_b,
+       MSM_MUX_qua_mi2s,
+       MSM_MUX_pci_e0,
+       MSM_MUX_pci_e1,
+       MSM_MUX_pri_mi2s,
+       MSM_MUX_sdc4,
+       MSM_MUX_sec_mi2s,
+       MSM_MUX_slimbus,
+       MSM_MUX_spkr_i2s,
+       MSM_MUX_ter_mi2s,
+       MSM_MUX_tsif1,
+       MSM_MUX_tsif2,
+       MSM_MUX_uim1,
+       MSM_MUX_uim2,
+       MSM_MUX_uim3,
+       MSM_MUX_uim4,
+       MSM_MUX_uim_batt_alarm,
+       MSM_MUX_gpio,
+       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_spi1_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3"
+};
+static const char * const blsp_uart1_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3"
+};
+static const char * const blsp_uim1_groups[] = {
+       "gpio0", "gpio1"
+};
+static const char * const hdmi_rcv_groups[] = {
+       "gpio0"
+};
+static const char * const blsp_i2c1_groups[] = {
+       "gpio2", "gpio3"
+};
+static const char * const blsp_spi2_groups[] = {
+       "gpio4", "gpio5", "gpio6", "gpio7"
+};
+static const char * const blsp_uart2_groups[] = {
+       "gpio4", "gpio5", "gpio6", "gpio7"
+};
+static const char * const blsp_uim2_groups[] = {
+       "gpio4", "gpio5"
+};
+static const char * const qdss_cti_trig_out_b_groups[] = {
+       "gpio4",
+};
+static const char * const qdss_cti_trig_in_b_groups[] = {
+       "gpio5",
+};
+static const char * const blsp_i2c2_groups[] = {
+       "gpio6", "gpio7"
+};
+static const char * const blsp_spi3_groups[] = {
+       "gpio8", "gpio9", "gpio10", "gpio11"
+};
+static const char * const blsp_uart3_groups[] = {
+       "gpio8", "gpio9", "gpio10", "gpio11"
+};
+static const char * const blsp_uim3_groups[] = {
+       "gpio8", "gpio9"
+};
+static const char * const blsp_spi1_cs1_groups[] = {
+       "gpio8"
+};
+static const char * const blsp_spi1_cs2_groups[] = {
+       "gpio9", "gpio11"
+};
+static const char * const mdp_vsync_groups[] = {
+       "gpio10", "gpio11", "gpio12"
+};
+static const char * const blsp_i2c3_groups[] = {
+       "gpio10", "gpio11"
+};
+static const char * const blsp_spi1_cs3_groups[] = {
+       "gpio10"
+};
+static const char * const qdss_tracedata_b_groups[] = {
+       "gpio13", "gpio14", "gpio15", "gpio16", "gpio17", "gpio18",
+       "gpio19", "gpio21", "gpio22", "gpio23", "gpio25", "gpio26",
+       "gpio57", "gpio58", "gpio92", "gpio93",
+};
+static const char * const cam_mclk0_groups[] = {
+       "gpio13"
+};
+static const char * const cam_mclk1_groups[] = {
+       "gpio14"
+};
+static const char * const cam_mclk2_groups[] = {
+       "gpio15"
+};
+static const char * const cam_mclk3_groups[] = {
+       "gpio16"
+};
+static const char * const cci_i2c0_groups[] = {
+       "gpio17", "gpio18"
+};
+static const char * const blsp_spi4_groups[] = {
+       "gpio17", "gpio18", "gpio19", "gpio20"
+};
+static const char * const blsp_uart4_groups[] = {
+       "gpio17", "gpio18", "gpio19", "gpio20"
+};
+static const char * const blsp_uim4_groups[] = {
+       "gpio17", "gpio18"
+};
+static const char * const cci_i2c1_groups[] = {
+       "gpio19", "gpio20"
+};
+static const char * const blsp_i2c4_groups[] = {
+       "gpio19", "gpio20"
+};
+static const char * const cci_timer0_groups[] = {
+       "gpio21"
+};
+static const char * const blsp_spi5_groups[] = {
+       "gpio21", "gpio22", "gpio23", "gpio24"
+};
+static const char * const blsp_uart5_groups[] = {
+       "gpio21", "gpio22", "gpio23", "gpio24"
+};
+static const char * const blsp_uim5_groups[] = {
+       "gpio21", "gpio22"
+};
+static const char * const cci_timer1_groups[] = {
+       "gpio22"
+};
+static const char * const cci_timer2_groups[] = {
+       "gpio23"
+};
+static const char * const blsp_i2c5_groups[] = {
+       "gpio23", "gpio24"
+};
+static const char * const cci_timer3_groups[] = {
+       "gpio24"
+};
+static const char * const cci_async_in1_groups[] = {
+       "gpio24"
+};
+static const char * const cci_timer4_groups[] = {
+       "gpio25"
+};
+static const char * const cci_async_in2_groups[] = {
+       "gpio25"
+};
+static const char * const blsp_spi6_groups[] = {
+       "gpio25", "gpio26", "gpio27", "gpio28"
+};
+static const char * const blsp_uart6_groups[] = {
+       "gpio25", "gpio26", "gpio27", "gpio28"
+};
+static const char * const blsp_uim6_groups[] = {
+       "gpio25", "gpio26"
+};
+static const char * const cci_async_in0_groups[] = {
+       "gpio26"
+};
+static const char * const gp0_clk_groups[] = {
+       "gpio26"
+};
+static const char * const gp1_clk_groups[] = {
+       "gpio27", "gpio57", "gpio78"
+};
+static const char * const blsp_i2c6_groups[] = {
+       "gpio27", "gpio28"
+};
+static const char * const qdss_tracectl_a_groups[] = {
+       "gpio27",
+};
+static const char * const qdss_traceclk_a_groups[] = {
+       "gpio28",
+};
+static const char * const gp_mn_groups[] = {
+       "gpio29"
+};
+static const char * const hdmi_cec_groups[] = {
+       "gpio31"
+};
+static const char * const hdmi_ddc_groups[] = {
+       "gpio32", "gpio33"
+};
+static const char * const hdmi_hpd_groups[] = {
+       "gpio34"
+};
+static const char * const uim3_groups[] = {
+       "gpio35", "gpio36", "gpio37", "gpio38"
+};
+static const char * const pci_e1_groups[] = {
+       "gpio35", "gpio36",
+};
+static const char * const blsp_spi7_groups[] = {
+       "gpio41", "gpio42", "gpio43", "gpio44"
+};
+static const char * const blsp_uart7_groups[] = {
+       "gpio41", "gpio42", "gpio43", "gpio44"
+};
+static const char * const blsp_uim7_groups[] = {
+       "gpio41", "gpio42"
+};
+static const char * const qdss_cti_trig_out_c_groups[] = {
+       "gpio41",
+};
+static const char * const qdss_cti_trig_in_c_groups[] = {
+       "gpio42",
+};
+static const char * const blsp_i2c7_groups[] = {
+       "gpio43", "gpio44"
+};
+static const char * const blsp_spi8_groups[] = {
+       "gpio45", "gpio46", "gpio47", "gpio48"
+};
+static const char * const blsp_uart8_groups[] = {
+       "gpio45", "gpio46", "gpio47", "gpio48"
+};
+static const char * const blsp_uim8_groups[] = {
+       "gpio45", "gpio46"
+};
+static const char * const blsp_i2c8_groups[] = {
+       "gpio47", "gpio48"
+};
+static const char * const blsp_spi10_cs1_groups[] = {
+       "gpio47", "gpio67"
+};
+static const char * const blsp_spi10_cs2_groups[] = {
+       "gpio48", "gpio68"
+};
+static const char * const uim2_groups[] = {
+       "gpio49", "gpio50", "gpio51", "gpio52"
+};
+static const char * const blsp_spi9_groups[] = {
+       "gpio49", "gpio50", "gpio51", "gpio52"
+};
+static const char * const blsp_uart9_groups[] = {
+       "gpio49", "gpio50", "gpio51", "gpio52"
+};
+static const char * const blsp_uim9_groups[] = {
+       "gpio49", "gpio50"
+};
+static const char * const blsp_i2c9_groups[] = {
+       "gpio51", "gpio52"
+};
+static const char * const pci_e0_groups[] = {
+       "gpio53", "gpio54",
+};
+static const char * const uim4_groups[] = {
+       "gpio53", "gpio54", "gpio55", "gpio56"
+};
+static const char * const blsp_spi10_groups[] = {
+       "gpio53", "gpio54", "gpio55", "gpio56"
+};
+static const char * const blsp_uart10_groups[] = {
+       "gpio53", "gpio54", "gpio55", "gpio56"
+};
+static const char * const blsp_uim10_groups[] = {
+       "gpio53", "gpio54"
+};
+static const char * const qdss_tracedata_a_groups[] = {
+       "gpio53", "gpio54", "gpio63", "gpio64", "gpio65",
+       "gpio66", "gpio67", "gpio74", "gpio75", "gpio76",
+       "gpio77", "gpio85", "gpio86", "gpio87", "gpio89",
+       "gpio90"
+};
+static const char * const gp_pdm0_groups[] = {
+       "gpio54", "gpio95"
+};
+static const char * const blsp_i2c10_groups[] = {
+       "gpio55", "gpio56"
+};
+static const char * const qdss_cti_trig_in_a_groups[] = {
+       "gpio55",
+};
+static const char * const qdss_cti_trig_out_a_groups[] = {
+       "gpio56",
+};
+static const char * const qua_mi2s_groups[] = {
+       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+};
+static const char * const gcc_gp1_clk_a_groups[] = {
+       "gpio57"
+};
+static const char * const gcc_gp2_clk_a_groups[] = {
+       "gpio58"
+};
+static const char * const gcc_gp3_clk_a_groups[] = {
+       "gpio59"
+};
+static const char * const blsp_spi2_cs1_groups[] = {
+       "gpio62"
+};
+static const char * const blsp_spi2_cs2_groups[] = {
+       "gpio63"
+};
+static const char * const gp_pdm2_groups[] = {
+       "gpio63", "gpio79"
+};
+static const char * const pri_mi2s_groups[] = {
+       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
+};
+static const char * const blsp_spi2_cs3_groups[] = {
+       "gpio66"
+};
+static const char * const spkr_i2s_groups[] = {
+       "gpio69", "gpio70", "gpio71", "gpio72"
+};
+static const char * const audio_ref_clk_groups[] = {
+       "gpio69"
+};
+static const char * const slimbus_groups[] = {
+       "gpio70", "gpio71"
+};
+static const char * const ter_mi2s_groups[] = {
+       "gpio73", "gpio74", "gpio75", "gpio76", "gpio77"
+};
+static const char * const gp_pdm1_groups[] = {
+       "gpio74", "gpio86"
+};
+static const char * const sec_mi2s_groups[] = {
+       "gpio78", "gpio79", "gpio80", "gpio81", "gpio82"
+};
+static const char * const gcc_gp1_clk_b_groups[] = {
+       "gpio78"
+};
+static const char * const blsp_spi11_groups[] = {
+       "gpio81", "gpio82", "gpio83", "gpio84"
+};
+static const char * const blsp_uart11_groups[] = {
+       "gpio81", "gpio82", "gpio83", "gpio84"
+};
+static const char * const blsp_uim11_groups[] = {
+       "gpio81", "gpio82"
+};
+static const char * const gcc_gp2_clk_b_groups[] = {
+       "gpio81"
+};
+static const char * const gcc_gp3_clk_b_groups[] = {
+       "gpio82"
+};
+static const char * const blsp_i2c11_groups[] = {
+       "gpio83", "gpio84"
+};
+static const char * const blsp_uart12_groups[] = {
+       "gpio85", "gpio86", "gpio87", "gpio88"
+};
+static const char * const blsp_uim12_groups[] = {
+       "gpio85", "gpio86"
+};
+static const char * const blsp_i2c12_groups[] = {
+       "gpio87", "gpio88"
+};
+static const char * const blsp_spi12_groups[] = {
+       "gpio85", "gpio86", "gpio87", "gpio88"
+};
+static const char * const tsif1_groups[] = {
+       "gpio89", "gpio90", "gpio91", "gpio110", "gpio111"
+};
+static const char * const blsp_spi10_cs3_groups[] = {
+       "gpio90"
+};
+static const char * const sdc4_groups[] = {
+       "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96"
+};
+static const char * const qdss_traceclk_b_groups[] = {
+       "gpio91",
+};
+static const char * const tsif2_groups[] = {
+       "gpio92", "gpio93", "gpio94", "gpio95", "gpio96"
+};
+static const char * const qdss_tracectl_b_groups[] = {
+       "gpio94",
+};
+static const char * const qdss_cti_trig_out_d_groups[] = {
+       "gpio95",
+};
+static const char * const qdss_cti_trig_in_d_groups[] = {
+       "gpio96",
+};
+static const char * const uim1_groups[] = {
+       "gpio97", "gpio98", "gpio99", "gpio100"
+};
+static const char * const uim_batt_alarm_groups[] = {
+       "gpio101"
+};
+static const char * const blsp11_uart_tx_b_groups[] = {
+       "gpio111"
+};
+static const char * const blsp11_uart_rx_b_groups[] = {
+       "gpio112"
+};
+static const char * const blsp11_i2c_sda_b_groups[] = {
+       "gpio113"
+};
+static const char * const blsp11_i2c_scl_b_groups[] = {
+       "gpio114"
+};
+static const char * const gsm_tx_groups[] = {
+       "gpio126", "gpio131", "gpio132", "gpio133"
+};
+static const char * const nav_tsync_groups[] = {
+       "gpio127"
+};
+static const char * const nav_pps_groups[] = {
+       "gpio127"
+};
+static const char * const gps_tx_groups[] = {
+       "gpio130"
+};
+static const char * const mss_lte_groups[] = {
+       "gpio134", "gpio135"
+};
+
+static const struct msm_function msm8994_functions[] = {
+       FUNCTION(audio_ref_clk),
+       FUNCTION(blsp_i2c1),
+       FUNCTION(blsp_i2c2),
+       FUNCTION(blsp_i2c3),
+       FUNCTION(blsp_i2c4),
+       FUNCTION(blsp_i2c5),
+       FUNCTION(blsp_i2c6),
+       FUNCTION(blsp_i2c7),
+       FUNCTION(blsp_i2c8),
+       FUNCTION(blsp_i2c9),
+       FUNCTION(blsp_i2c10),
+       FUNCTION(blsp_i2c11),
+       FUNCTION(blsp_i2c12),
+       FUNCTION(blsp_spi1),
+       FUNCTION(blsp_spi1_cs1),
+       FUNCTION(blsp_spi1_cs2),
+       FUNCTION(blsp_spi1_cs3),
+       FUNCTION(blsp_spi2),
+       FUNCTION(blsp_spi2_cs1),
+       FUNCTION(blsp_spi2_cs2),
+       FUNCTION(blsp_spi2_cs3),
+       FUNCTION(blsp_spi3),
+       FUNCTION(blsp_spi4),
+       FUNCTION(blsp_spi5),
+       FUNCTION(blsp_spi6),
+       FUNCTION(blsp_spi7),
+       FUNCTION(blsp_spi8),
+       FUNCTION(blsp_spi9),
+       FUNCTION(blsp_spi10),
+       FUNCTION(blsp_spi10_cs1),
+       FUNCTION(blsp_spi10_cs2),
+       FUNCTION(blsp_spi10_cs3),
+       FUNCTION(blsp_spi11),
+       FUNCTION(blsp_spi12),
+       FUNCTION(blsp_uart1),
+       FUNCTION(blsp_uart2),
+       FUNCTION(blsp_uart3),
+       FUNCTION(blsp_uart4),
+       FUNCTION(blsp_uart5),
+       FUNCTION(blsp_uart6),
+       FUNCTION(blsp_uart7),
+       FUNCTION(blsp_uart8),
+       FUNCTION(blsp_uart9),
+       FUNCTION(blsp_uart10),
+       FUNCTION(blsp_uart11),
+       FUNCTION(blsp_uart12),
+       FUNCTION(blsp_uim1),
+       FUNCTION(blsp_uim2),
+       FUNCTION(blsp_uim3),
+       FUNCTION(blsp_uim4),
+       FUNCTION(blsp_uim5),
+       FUNCTION(blsp_uim6),
+       FUNCTION(blsp_uim7),
+       FUNCTION(blsp_uim8),
+       FUNCTION(blsp_uim9),
+       FUNCTION(blsp_uim10),
+       FUNCTION(blsp_uim11),
+       FUNCTION(blsp_uim12),
+       FUNCTION(blsp11_i2c_scl_b),
+       FUNCTION(blsp11_i2c_sda_b),
+       FUNCTION(blsp11_uart_rx_b),
+       FUNCTION(blsp11_uart_tx_b),
+       FUNCTION(cam_mclk0),
+       FUNCTION(cam_mclk1),
+       FUNCTION(cam_mclk2),
+       FUNCTION(cam_mclk3),
+       FUNCTION(cci_async_in0),
+       FUNCTION(cci_async_in1),
+       FUNCTION(cci_async_in2),
+       FUNCTION(cci_i2c0),
+       FUNCTION(cci_i2c1),
+       FUNCTION(cci_timer0),
+       FUNCTION(cci_timer1),
+       FUNCTION(cci_timer2),
+       FUNCTION(cci_timer3),
+       FUNCTION(cci_timer4),
+       FUNCTION(gcc_gp1_clk_a),
+       FUNCTION(gcc_gp1_clk_b),
+       FUNCTION(gcc_gp2_clk_a),
+       FUNCTION(gcc_gp2_clk_b),
+       FUNCTION(gcc_gp3_clk_a),
+       FUNCTION(gcc_gp3_clk_b),
+       FUNCTION(gp_mn),
+       FUNCTION(gp_pdm0),
+       FUNCTION(gp_pdm1),
+       FUNCTION(gp_pdm2),
+       FUNCTION(gp0_clk),
+       FUNCTION(gp1_clk),
+       FUNCTION(gps_tx),
+       FUNCTION(gsm_tx),
+       FUNCTION(hdmi_cec),
+       FUNCTION(hdmi_ddc),
+       FUNCTION(hdmi_hpd),
+       FUNCTION(hdmi_rcv),
+       FUNCTION(mdp_vsync),
+       FUNCTION(mss_lte),
+       FUNCTION(nav_pps),
+       FUNCTION(nav_tsync),
+       FUNCTION(qdss_cti_trig_in_a),
+       FUNCTION(qdss_cti_trig_in_b),
+       FUNCTION(qdss_cti_trig_in_c),
+       FUNCTION(qdss_cti_trig_in_d),
+       FUNCTION(qdss_cti_trig_out_a),
+       FUNCTION(qdss_cti_trig_out_b),
+       FUNCTION(qdss_cti_trig_out_c),
+       FUNCTION(qdss_cti_trig_out_d),
+       FUNCTION(qdss_traceclk_a),
+       FUNCTION(qdss_traceclk_b),
+       FUNCTION(qdss_tracectl_a),
+       FUNCTION(qdss_tracectl_b),
+       FUNCTION(qdss_tracedata_a),
+       FUNCTION(qdss_tracedata_b),
+       FUNCTION(qua_mi2s),
+       FUNCTION(pci_e0),
+       FUNCTION(pci_e1),
+       FUNCTION(pri_mi2s),
+       FUNCTION(sdc4),
+       FUNCTION(sec_mi2s),
+       FUNCTION(slimbus),
+       FUNCTION(spkr_i2s),
+       FUNCTION(ter_mi2s),
+       FUNCTION(tsif1),
+       FUNCTION(tsif2),
+       FUNCTION(uim_batt_alarm),
+       FUNCTION(uim1),
+       FUNCTION(uim2),
+       FUNCTION(uim3),
+       FUNCTION(uim4),
+       FUNCTION(gpio),
+};
+
+static const struct msm_pingroup msm8994_groups[] = {
+       PINGROUP(0,   blsp_spi1, blsp_uart1, blsp_uim1, hdmi_rcv, NA, NA, NA,
+                NA, NA, NA, NA),
+       PINGROUP(1,   blsp_spi1, blsp_uart1, blsp_uim1, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(2,   blsp_spi1, blsp_uart1, blsp_i2c1, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(3,   blsp_spi1, blsp_uart1, blsp_i2c1, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(4,   blsp_spi2, blsp_uart2, blsp_uim2, NA, qdss_cti_trig_out_b,
+                NA, NA, NA, NA, NA, NA),
+       PINGROUP(5,   blsp_spi2, blsp_uart2, blsp_uim2, NA, qdss_cti_trig_in_b,
+                NA, NA, NA, NA, NA, NA),
+       PINGROUP(6,   blsp_spi2, blsp_uart2, blsp_i2c2, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(7,   blsp_spi2, blsp_uart2, blsp_i2c2, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(8,   blsp_spi3, blsp_uart3, blsp_uim3, blsp_spi1_cs1, NA, NA,
+                NA, NA, NA, NA, NA),
+       PINGROUP(9,   blsp_spi3, blsp_uart3, blsp_uim3, blsp_spi1_cs2, NA, NA,
+                NA, NA, NA, NA, NA),
+       PINGROUP(10,  mdp_vsync, blsp_spi3, blsp_uart3, blsp_i2c3,
+                blsp_spi1_cs3, NA, NA, NA, NA, NA, NA),
+       PINGROUP(11,  mdp_vsync, blsp_spi3, blsp_uart3, blsp_i2c3,
+                blsp_spi1_cs2, NA, NA, NA, NA, NA, NA),
+       PINGROUP(12,  mdp_vsync, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(13,  cam_mclk0, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(14,  cam_mclk1, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(15,  cam_mclk2, NA, qdss_tracedata_b, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(16,  cam_mclk3, NA, qdss_tracedata_b, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(17,  cci_i2c0, blsp_spi4, blsp_uart4, blsp_uim4, NA,
+                qdss_tracedata_b, NA, NA, NA, NA, NA),
+       PINGROUP(18,  cci_i2c0, blsp_spi4, blsp_uart4, blsp_uim4, NA,
+                qdss_tracedata_b, NA, NA, NA, NA, NA),
+       PINGROUP(19,  cci_i2c1, blsp_spi4, blsp_uart4, blsp_i2c4, NA,
+                qdss_tracedata_b, NA, NA, NA, NA, NA),
+       PINGROUP(20,  cci_i2c1, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA,
+                NA, NA, NA, NA),
+       PINGROUP(21,  cci_timer0, blsp_spi5, blsp_uart5, blsp_uim5, NA,
+                qdss_tracedata_b, NA, NA, NA, NA, NA),
+       PINGROUP(22,  cci_timer1, blsp_spi5, blsp_uart5, blsp_uim5, NA,
+                qdss_tracedata_b, NA, NA, NA, NA, NA),
+       PINGROUP(23,  cci_timer2, blsp_spi5, blsp_uart5, blsp_i2c5, NA, NA,
+                qdss_tracedata_b, NA, NA, NA, NA),
+       PINGROUP(24,  cci_timer3, cci_async_in1, blsp_spi5, blsp_uart5,
+                blsp_i2c5, NA, NA, NA, NA, NA, NA),
+       PINGROUP(25,  cci_timer4, cci_async_in2, blsp_spi6, blsp_uart6,
+                blsp_uim6, NA, NA, qdss_tracedata_b, NA, NA, NA),
+       PINGROUP(26,  cci_async_in0, blsp_spi6, blsp_uart6, blsp_uim6, gp0_clk,
+                NA, qdss_tracedata_b, NA, NA, NA, NA),
+       PINGROUP(27,  blsp_spi6, blsp_uart6, blsp_i2c6, gp1_clk,
+                qdss_tracectl_a, NA, NA, NA, NA, NA, NA),
+       PINGROUP(28,  blsp_spi6, blsp_uart6, blsp_i2c6, qdss_traceclk_a, NA,
+                NA, NA, NA, NA, NA, NA),
+       PINGROUP(29,  gp_mn, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(30,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(31,  hdmi_cec, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(32,  hdmi_ddc, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(33,  hdmi_ddc, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(34,  hdmi_hpd, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(35,  uim3, pci_e1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(36,  uim3, pci_e1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(37,  uim3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(38,  uim3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(39,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(40,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(41,  blsp_spi7, blsp_uart7, blsp_uim7, qdss_cti_trig_out_c,
+                NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(42,  blsp_spi7, blsp_uart7, blsp_uim7, qdss_cti_trig_in_c, NA,
+                NA, NA, NA, NA, NA, NA),
+       PINGROUP(43,  blsp_spi7, blsp_uart7, blsp_i2c7, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(44,  blsp_spi7, blsp_uart7, blsp_i2c7, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(45,  blsp_spi8, blsp_uart8, blsp_uim8, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(46,  blsp_spi8, blsp_uart8, blsp_uim8, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(47,  blsp_spi8, blsp_uart8, blsp_i2c8, blsp_spi10_cs1, NA, NA,
+                NA, NA, NA, NA, NA),
+       PINGROUP(48,  blsp_spi8, blsp_uart8, blsp_i2c8, blsp_spi10_cs2, NA, NA,
+                NA, NA, NA, NA, NA),
+       PINGROUP(49,  uim2, blsp_spi9, blsp_uart9, blsp_uim9, NA, NA, NA, NA,
+                NA, NA, NA),
+       PINGROUP(50,  uim2, blsp_spi9, blsp_uart9, blsp_uim9, NA, NA, NA, NA,
+                NA, NA, NA),
+       PINGROUP(51,  uim2, blsp_spi9, blsp_uart9, blsp_i2c9, NA, NA, NA, NA,
+                NA, NA, NA),
+       PINGROUP(52,  uim2, blsp_spi9, blsp_uart9, blsp_i2c9, NA, NA, NA, NA,
+                NA, NA, NA),
+       PINGROUP(53,  uim4, pci_e0, blsp_spi10, blsp_uart10, blsp_uim10, NA,
+                NA, qdss_tracedata_a, NA, NA, NA),
+       PINGROUP(54,  uim4, pci_e0, blsp_spi10, blsp_uart10, blsp_uim10,
+                gp_pdm0, NA, NA, qdss_tracedata_a, NA, NA),
+       PINGROUP(55,  uim4, blsp_spi10, blsp_uart10, blsp_i2c10, NA, NA, NA,
+                qdss_cti_trig_in_a, NA, NA, NA),
+       PINGROUP(56,  uim4, blsp_spi10, blsp_uart10, blsp_i2c10, NA, NA,
+                qdss_cti_trig_out_a, NA, NA, NA, NA),
+       PINGROUP(57,  qua_mi2s, gcc_gp1_clk_a, NA, NA, qdss_tracedata_b, NA, NA,
+                NA, NA, NA, NA),
+       PINGROUP(58,  qua_mi2s, gcc_gp2_clk_a, NA, NA, qdss_tracedata_b, NA, NA,
+                NA, NA, NA, NA),
+       PINGROUP(59,  qua_mi2s, gcc_gp3_clk_a, NA, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(60,  qua_mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(61,  qua_mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(62,  qua_mi2s, blsp_spi2_cs1, NA, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(63,  qua_mi2s, blsp_spi2_cs2, gp_pdm2, NA, NA, NA, NA, NA,
+                qdss_tracedata_a, NA, NA),
+       PINGROUP(64,  pri_mi2s, NA, NA, NA, qdss_tracedata_a, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(65,  pri_mi2s, NA, NA, NA, qdss_tracedata_a, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(66,  pri_mi2s, blsp_spi2_cs3, NA, NA, NA, qdss_tracedata_a,
+                NA, NA, NA, NA, NA),
+       PINGROUP(67,  pri_mi2s, blsp_spi10_cs1, NA, NA, NA, qdss_tracedata_a,
+                NA, NA, NA, NA, NA),
+       PINGROUP(68,  pri_mi2s, blsp_spi10_cs2, NA, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(69,  spkr_i2s, audio_ref_clk, NA, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(70,  slimbus, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(71,  slimbus, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(72,  spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(73,  ter_mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(74,  ter_mi2s, gp_pdm1, NA, NA, NA, qdss_tracedata_a, NA, NA,
+                NA, NA, NA),
+       PINGROUP(75,  ter_mi2s, NA, NA, qdss_tracedata_a, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(76,  ter_mi2s, NA, NA, qdss_tracedata_a, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(77,  ter_mi2s, NA, NA, qdss_tracedata_a, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(78,  sec_mi2s, gcc_gp1_clk_b, NA, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(79,  sec_mi2s, gp_pdm2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(80,  sec_mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(81,  sec_mi2s, blsp_spi11, blsp_uart11, blsp_uim11,
+                gcc_gp2_clk_b, NA, NA, NA, NA, NA, NA),
+       PINGROUP(82,  sec_mi2s, blsp_spi11, blsp_uart11, blsp_uim11,
+                gcc_gp3_clk_b, NA, NA, NA, NA, NA, NA),
+       PINGROUP(83,  blsp_spi11, blsp_uart11, blsp_i2c11, NA, NA, NA, NA, NA,
+                NA, NA, NA),
+       PINGROUP(84,  blsp_spi11, blsp_uart11, blsp_i2c11, NA, NA, NA, NA, NA,
+                NA, NA, NA),
+       PINGROUP(85,  blsp_spi12, blsp_uart12, blsp_uim12, NA, NA,
+                qdss_tracedata_a, NA, NA, NA, NA, NA),
+       PINGROUP(86,  blsp_spi12, blsp_uart12, blsp_uim12, gp_pdm1, NA,
+                qdss_tracedata_a, NA, NA, NA, NA, NA),
+       PINGROUP(87,  blsp_spi12, blsp_uart12, blsp_i2c12, NA,
+                qdss_tracedata_a, NA, NA, NA, NA, NA, NA),
+       PINGROUP(88,  blsp_spi12, blsp_uart12, blsp_i2c12, NA, NA, NA, NA, NA,
+                NA, NA, NA),
+       PINGROUP(89,  tsif1, NA, qdss_tracedata_a, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(90,  tsif1, blsp_spi10_cs3, qdss_tracedata_a, NA, NA, NA, NA,
+                NA, NA, NA, NA),
+       PINGROUP(91,  tsif1, sdc4, NA, NA, NA, NA, qdss_traceclk_b, NA, NA, NA,
+                NA),
+       PINGROUP(92,  tsif2, sdc4, NA, NA, qdss_tracedata_b, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(93,  tsif2, sdc4, NA, NA, NA, NA, qdss_tracedata_b, NA, NA,
+                NA, NA),
+       PINGROUP(94,  tsif2, sdc4, NA, NA, NA, NA, qdss_tracectl_b, NA, NA, NA,
+                NA),
+       PINGROUP(95,  tsif2, sdc4, gp_pdm0, NA, NA, NA, qdss_cti_trig_out_d,
+                NA, NA, NA, NA),
+       PINGROUP(96,  tsif2, sdc4, qdss_cti_trig_in_d, NA, NA, NA, NA, NA, NA,
+                NA, NA),
+       PINGROUP(97,  uim1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(98,  uim1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(99,  uim1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(100, uim1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(101, uim_batt_alarm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(102, NA, 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, NA, 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, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(111, tsif1, blsp11_uart_tx_b, NA, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(112, blsp11_uart_rx_b, NA, NA, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(113, blsp11_i2c_sda_b, NA, NA, NA, NA, NA, NA, NA, NA, NA,
+                NA),
+       PINGROUP(114, blsp11_i2c_scl_b, 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, gsm_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(127, NA, nav_tsync, nav_pps, 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, gps_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(131, gsm_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(132, gsm_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(133, gsm_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(134, mss_lte, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(135, mss_lte, 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, NA, 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, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(141, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(142, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(143, NA, 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),
+       SDC_PINGROUP(sdc1_rclk, 0x2044, 15, 0),
+       SDC_PINGROUP(sdc1_clk, 0x2044, 13, 6),
+       SDC_PINGROUP(sdc1_cmd, 0x2044, 11, 3),
+       SDC_PINGROUP(sdc1_data, 0x2044, 9, 0),
+       SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6),
+       SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3),
+       SDC_PINGROUP(sdc2_data, 0x2048, 9, 0),
+       SDC_PINGROUP(sdc3_clk, 0x206c, 14, 6),
+       SDC_PINGROUP(sdc3_cmd, 0x206c, 11, 3),
+       SDC_PINGROUP(sdc3_data, 0x206c, 9, 0),
+};
+
+#define NUM_GPIO_PINGROUPS 146
+
+static const struct msm_pinctrl_soc_data msm8994_pinctrl = {
+       .pins = msm8994_pins,
+       .npins = ARRAY_SIZE(msm8994_pins),
+       .functions = msm8994_functions,
+       .nfunctions = ARRAY_SIZE(msm8994_functions),
+       .groups = msm8994_groups,
+       .ngroups = ARRAY_SIZE(msm8994_groups),
+       .ngpios = NUM_GPIO_PINGROUPS,
+};
+
+static int msm8994_pinctrl_probe(struct platform_device *pdev)
+{
+       return msm_pinctrl_probe(pdev, &msm8994_pinctrl);
+}
+
+static const struct of_device_id msm8994_pinctrl_of_match[] = {
+       { .compatible = "qcom,msm8992-pinctrl", },
+       { .compatible = "qcom,msm8994-pinctrl", },
+       { }
+};
+
+static struct platform_driver msm8994_pinctrl_driver = {
+       .driver = {
+               .name = "msm8994-pinctrl",
+               .of_match_table = msm8994_pinctrl_of_match,
+       },
+       .probe = msm8994_pinctrl_probe,
+       .remove = msm_pinctrl_remove,
+};
+
+static int __init msm8994_pinctrl_init(void)
+{
+       return platform_driver_register(&msm8994_pinctrl_driver);
+}
+arch_initcall(msm8994_pinctrl_init);
+
+static void __exit msm8994_pinctrl_exit(void)
+{
+       platform_driver_unregister(&msm8994_pinctrl_driver);
+}
+module_exit(msm8994_pinctrl_exit);
+
+MODULE_DESCRIPTION("Qualcomm MSM8994 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, msm8994_pinctrl_of_match);
index d32fa2b5ff82ba6de5a586cc9ee6fdc29e7f71cd..12f7d1eb65bc71e891f3eb88a750953dbd1ce68b 100644 (file)
@@ -61,16 +61,15 @@ static void exynos_irq_mask(struct irq_data *irqd)
        struct irq_chip *chip = irq_data_get_irq_chip(irqd);
        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
        unsigned long mask;
        unsigned long flags;
 
        spin_lock_irqsave(&bank->slock, flags);
 
-       mask = readl(d->virt_base + reg_mask);
+       mask = readl(bank->eint_base + reg_mask);
        mask |= 1 << irqd->hwirq;
-       writel(mask, d->virt_base + reg_mask);
+       writel(mask, bank->eint_base + reg_mask);
 
        spin_unlock_irqrestore(&bank->slock, flags);
 }
@@ -80,10 +79,9 @@ static void exynos_irq_ack(struct irq_data *irqd)
        struct irq_chip *chip = irq_data_get_irq_chip(irqd);
        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
 
-       writel(1 << irqd->hwirq, d->virt_base + reg_pend);
+       writel(1 << irqd->hwirq, bank->eint_base + reg_pend);
 }
 
 static void exynos_irq_unmask(struct irq_data *irqd)
@@ -91,7 +89,6 @@ static void exynos_irq_unmask(struct irq_data *irqd)
        struct irq_chip *chip = irq_data_get_irq_chip(irqd);
        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
        unsigned long mask;
        unsigned long flags;
@@ -109,9 +106,9 @@ static void exynos_irq_unmask(struct irq_data *irqd)
 
        spin_lock_irqsave(&bank->slock, flags);
 
-       mask = readl(d->virt_base + reg_mask);
+       mask = readl(bank->eint_base + reg_mask);
        mask &= ~(1 << irqd->hwirq);
-       writel(mask, d->virt_base + reg_mask);
+       writel(mask, bank->eint_base + reg_mask);
 
        spin_unlock_irqrestore(&bank->slock, flags);
 }
@@ -121,7 +118,6 @@ 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_pinctrl_drv_data *d = bank->drvdata;
        unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
        unsigned int con, trig_type;
        unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
@@ -152,10 +148,10 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
        else
                irq_set_handler_locked(irqd, handle_level_irq);
 
-       con = readl(d->virt_base + reg_con);
+       con = readl(bank->eint_base + reg_con);
        con &= ~(EXYNOS_EINT_CON_MASK << shift);
        con |= trig_type << shift;
-       writel(con, d->virt_base + reg_con);
+       writel(con, bank->eint_base + reg_con);
 
        return 0;
 }
@@ -166,7 +162,6 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
        const struct samsung_pin_bank_type *bank_type = bank->type;
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
        unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
        unsigned long flags;
@@ -188,10 +183,10 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
 
        spin_lock_irqsave(&bank->slock, flags);
 
-       con = readl(d->virt_base + reg_con);
+       con = readl(bank->eint_base + reg_con);
        con &= ~(mask << shift);
        con |= EXYNOS_EINT_FUNC << shift;
-       writel(con, d->virt_base + reg_con);
+       writel(con, bank->eint_base + reg_con);
 
        spin_unlock_irqrestore(&bank->slock, flags);
 
@@ -206,7 +201,6 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
        const struct samsung_pin_bank_type *bank_type = bank->type;
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
        unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
        unsigned long flags;
@@ -221,10 +215,10 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
 
        spin_lock_irqsave(&bank->slock, flags);
 
-       con = readl(d->virt_base + reg_con);
+       con = readl(bank->eint_base + reg_con);
        con &= ~(mask << shift);
        con |= FUNC_INPUT << shift;
-       writel(con, d->virt_base + reg_con);
+       writel(con, bank->eint_base + reg_con);
 
        spin_unlock_irqrestore(&bank->slock, flags);
 
@@ -274,7 +268,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
        struct samsung_pin_bank *bank = d->pin_banks;
        unsigned int svc, group, pin, virq;
 
-       svc = readl(d->virt_base + EXYNOS_SVC_OFFSET);
+       svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
        group = EXYNOS_SVC_GROUP(svc);
        pin = svc & EXYNOS_SVC_NUM_MASK;
 
@@ -452,7 +446,6 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
 {
        struct irq_chip *chip = irq_desc_get_chip(desc);
        struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc);
-       struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
        unsigned long pend;
        unsigned long mask;
        int i;
@@ -461,9 +454,9 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
 
        for (i = 0; i < eintd->nr_banks; ++i) {
                struct samsung_pin_bank *b = eintd->banks[i];
-               pend = readl(d->virt_base + b->irq_chip->eint_pend
+               pend = readl(b->eint_base + b->irq_chip->eint_pend
                                + b->eint_offset);
-               mask = readl(d->virt_base + b->irq_chip->eint_mask
+               mask = readl(b->eint_base + b->irq_chip->eint_mask
                                + b->eint_offset);
                exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
        }
@@ -581,7 +574,7 @@ static void exynos_pinctrl_suspend_bank(
                                struct samsung_pin_bank *bank)
 {
        struct exynos_eint_gpio_save *save = bank->soc_priv;
-       void __iomem *regs = drvdata->virt_base;
+       void __iomem *regs = bank->eint_base;
 
        save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
                                                + bank->eint_offset);
@@ -610,7 +603,7 @@ static void exynos_pinctrl_resume_bank(
                                struct samsung_pin_bank *bank)
 {
        struct exynos_eint_gpio_save *save = bank->soc_priv;
-       void __iomem *regs = drvdata->virt_base;
+       void __iomem *regs = bank->eint_base;
 
        pr_debug("%s:     con %#010x => %#010x\n", bank->name,
                        readl(regs + EXYNOS_GPIO_ECON_OFFSET
@@ -1346,6 +1339,11 @@ static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = {
        EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
        EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
        EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
+       EXYNOS_PIN_BANK_EINTW_EXT(8, 0x020, "gpf1", 0x1004, 1),
+       EXYNOS_PIN_BANK_EINTW_EXT(4, 0x040, "gpf2", 0x1008, 1),
+       EXYNOS_PIN_BANK_EINTW_EXT(4, 0x060, "gpf3", 0x100c, 1),
+       EXYNOS_PIN_BANK_EINTW_EXT(8, 0x080, "gpf4", 0x1010, 1),
+       EXYNOS_PIN_BANK_EINTW_EXT(8, 0x0a0, "gpf5", 0x1014, 1),
 };
 
 /* pin banks of exynos5433 pin-controller - AUD */
@@ -1427,6 +1425,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] = {
                .eint_wkup_init = exynos_eint_wkup_init,
                .suspend        = exynos_pinctrl_suspend,
                .resume         = exynos_pinctrl_resume,
+               .nr_ext_resources = 1,
        }, {
                /* pin-controller instance 1 data */
                .pin_banks      = exynos5433_pin_banks1,
index 0f0f7cedb2dcc7c89d94cc481de9d29ab7dd613d..5821525a2c8473fa026b3dc84cd6eb999c243b2a 100644 (file)
                .name           = id                    \
        }
 
+#define EXYNOS_PIN_BANK_EINTW_EXT(pins, reg, id, offs, pctl_idx) \
+       {                                               \
+               .type           = &bank_type_alive,     \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_WKUP,       \
+               .eint_offset    = offs,                 \
+               .name           = id,                   \
+               .pctl_res_idx   = pctl_idx,             \
+       }                                               \
+
 /**
  * struct exynos_weint_data: irq specific data for all the wakeup interrupts
  * generated by the external wakeup interrupt controller.
index 3d92f827da7a83fc08a0d24e86347004ff01ba0b..b82a003546ae88f8c2f3e8cebad87b1547ff21d7 100644 (file)
@@ -151,7 +151,7 @@ static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
        u32 val;
 
        /* Make sure that pin is configured as interrupt */
-       reg = d->virt_base + bank->pctl_offset;
+       reg = bank->pctl_base + bank->pctl_offset;
        shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
        mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
 
@@ -184,7 +184,7 @@ static int s3c24xx_eint_type(struct irq_data *data, unsigned int type)
        s3c24xx_eint_set_handler(data, type);
 
        /* Set up interrupt trigger */
-       reg = d->virt_base + EINT_REG(index);
+       reg = bank->eint_base + EINT_REG(index);
        shift = EINT_OFFS(index);
 
        val = readl(reg);
@@ -259,32 +259,29 @@ static void s3c2410_demux_eint0_3(struct irq_desc *desc)
 static void s3c2412_eint0_3_ack(struct irq_data *data)
 {
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
 
        unsigned long bitval = 1UL << data->hwirq;
-       writel(bitval, d->virt_base + EINTPEND_REG);
+       writel(bitval, bank->eint_base + EINTPEND_REG);
 }
 
 static void s3c2412_eint0_3_mask(struct irq_data *data)
 {
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned long mask;
 
-       mask = readl(d->virt_base + EINTMASK_REG);
+       mask = readl(bank->eint_base + EINTMASK_REG);
        mask |= (1UL << data->hwirq);
-       writel(mask, d->virt_base + EINTMASK_REG);
+       writel(mask, bank->eint_base + EINTMASK_REG);
 }
 
 static void s3c2412_eint0_3_unmask(struct irq_data *data)
 {
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned long mask;
 
-       mask = readl(d->virt_base + EINTMASK_REG);
+       mask = readl(bank->eint_base + EINTMASK_REG);
        mask &= ~(1UL << data->hwirq);
-       writel(mask, d->virt_base + EINTMASK_REG);
+       writel(mask, bank->eint_base + EINTMASK_REG);
 }
 
 static struct irq_chip s3c2412_eint0_3_chip = {
@@ -319,34 +316,31 @@ static void s3c2412_demux_eint0_3(struct irq_desc *desc)
 static void s3c24xx_eint_ack(struct irq_data *data)
 {
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned char index = bank->eint_offset + data->hwirq;
 
-       writel(1UL << index, d->virt_base + EINTPEND_REG);
+       writel(1UL << index, bank->eint_base + EINTPEND_REG);
 }
 
 static void s3c24xx_eint_mask(struct irq_data *data)
 {
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned char index = bank->eint_offset + data->hwirq;
        unsigned long mask;
 
-       mask = readl(d->virt_base + EINTMASK_REG);
+       mask = readl(bank->eint_base + EINTMASK_REG);
        mask |= (1UL << index);
-       writel(mask, d->virt_base + EINTMASK_REG);
+       writel(mask, bank->eint_base + EINTMASK_REG);
 }
 
 static void s3c24xx_eint_unmask(struct irq_data *data)
 {
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned char index = bank->eint_offset + data->hwirq;
        unsigned long mask;
 
-       mask = readl(d->virt_base + EINTMASK_REG);
+       mask = readl(bank->eint_base + EINTMASK_REG);
        mask &= ~(1UL << index);
-       writel(mask, d->virt_base + EINTMASK_REG);
+       writel(mask, bank->eint_base + EINTMASK_REG);
 }
 
 static struct irq_chip s3c24xx_eint_chip = {
@@ -362,13 +356,14 @@ static inline void s3c24xx_demux_eint(struct irq_desc *desc,
 {
        struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc);
        struct irq_chip *chip = irq_desc_get_chip(desc);
-       struct samsung_pinctrl_drv_data *d = data->drvdata;
+       struct irq_data *irqd = irq_desc_get_irq_data(desc);
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
        unsigned int pend, mask;
 
        chained_irq_enter(chip, desc);
 
-       pend = readl(d->virt_base + EINTPEND_REG);
-       mask = readl(d->virt_base + EINTMASK_REG);
+       pend = readl(bank->eint_base + EINTPEND_REG);
+       mask = readl(bank->eint_base + EINTMASK_REG);
 
        pend &= ~mask;
        pend &= range;
index 43407ab248f5121d0ca5625112592a32a9f1a968..4c632812ccff2dbd8086b0640f58774edf23e0fb 100644 (file)
@@ -280,7 +280,7 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d,
        u32 val;
 
        /* Make sure that pin is configured as interrupt */
-       reg = d->virt_base + bank->pctl_offset;
+       reg = bank->pctl_base + bank->pctl_offset;
        shift = pin;
        if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) {
                /* 4-bit bank type with 2 con regs */
@@ -308,9 +308,8 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d,
 static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask)
 {
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
-       void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset);
+       void __iomem *reg = bank->eint_base + EINTMASK_REG(bank->eint_offset);
        u32 val;
 
        val = readl(reg);
@@ -334,9 +333,8 @@ static void s3c64xx_gpio_irq_mask(struct irq_data *irqd)
 static void s3c64xx_gpio_irq_ack(struct irq_data *irqd)
 {
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
        unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
-       void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset);
+       void __iomem *reg = bank->eint_base + EINTPEND_REG(bank->eint_offset);
 
        writel(1 << index, reg);
 }
@@ -359,7 +357,7 @@ static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
        s3c64xx_irq_set_handler(irqd, type);
 
        /* Set up interrupt trigger */
-       reg = d->virt_base + EINTCON_REG(bank->eint_offset);
+       reg = bank->eint_base + EINTCON_REG(bank->eint_offset);
        shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
        shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */
 
@@ -411,7 +409,8 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc)
 {
        struct irq_chip *chip = irq_desc_get_chip(desc);
        struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc);
-       struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
+       struct irq_data *irqd = irq_desc_get_irq_data(desc);
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 
        chained_irq_enter(chip, desc);
 
@@ -421,7 +420,7 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc)
                unsigned int pin;
                unsigned int virq;
 
-               svc = readl(drvdata->virt_base + SERVICE_REG);
+               svc = readl(bank->eint_base + SERVICE_REG);
                group = SVC_GROUP(svc);
                pin = svc & SVC_NUM_MASK;
 
@@ -518,15 +517,15 @@ static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask)
 {
        struct s3c64xx_eint0_domain_data *ddata =
                                        irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
+       struct samsung_pin_bank *bank = ddata->bank;
        u32 val;
 
-       val = readl(d->virt_base + EINT0MASK_REG);
+       val = readl(bank->eint_base + EINT0MASK_REG);
        if (mask)
                val |= 1 << ddata->eints[irqd->hwirq];
        else
                val &= ~(1 << ddata->eints[irqd->hwirq]);
-       writel(val, d->virt_base + EINT0MASK_REG);
+       writel(val, bank->eint_base + EINT0MASK_REG);
 }
 
 static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
@@ -543,10 +542,10 @@ static void s3c64xx_eint0_irq_ack(struct irq_data *irqd)
 {
        struct s3c64xx_eint0_domain_data *ddata =
                                        irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
+       struct samsung_pin_bank *bank = ddata->bank;
 
        writel(1 << ddata->eints[irqd->hwirq],
-                                       d->virt_base + EINT0PEND_REG);
+                                       bank->eint_base + EINT0PEND_REG);
 }
 
 static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
@@ -554,7 +553,7 @@ static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
        struct s3c64xx_eint0_domain_data *ddata =
                                        irq_data_get_irq_chip_data(irqd);
        struct samsung_pin_bank *bank = ddata->bank;
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
        void __iomem *reg;
        int trigger;
        u8 shift;
@@ -569,7 +568,7 @@ static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
        s3c64xx_irq_set_handler(irqd, type);
 
        /* Set up interrupt trigger */
-       reg = d->virt_base + EINT0CON0_REG;
+       reg = bank->eint_base + EINT0CON0_REG;
        shift = ddata->eints[irqd->hwirq];
        if (shift >= EINT_MAX_PER_REG) {
                reg += 4;
@@ -601,14 +600,19 @@ static struct irq_chip s3c64xx_eint0_irq_chip = {
 static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range)
 {
        struct irq_chip *chip = irq_desc_get_chip(desc);
+       struct irq_data *irqd = irq_desc_get_irq_data(desc);
+       struct s3c64xx_eint0_domain_data *ddata =
+                                       irq_data_get_irq_chip_data(irqd);
+       struct samsung_pin_bank *bank = ddata->bank;
+
        struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc);
-       struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
+
        unsigned int pend, mask;
 
        chained_irq_enter(chip, desc);
 
-       pend = readl(drvdata->virt_base + EINT0PEND_REG);
-       mask = readl(drvdata->virt_base + EINT0MASK_REG);
+       pend = readl(bank->eint_base + EINT0PEND_REG);
+       mask = readl(bank->eint_base + EINT0MASK_REG);
 
        pend = pend & range & ~mask;
        pend &= range;
index 620727fabe6437feb63f6d4b24f11949616131f4..41e62391c33ca10e34e9322780926fb7637ebe39 100644 (file)
@@ -33,6 +33,9 @@
 #include "../core.h"
 #include "pinctrl-samsung.h"
 
+/* maximum number of the memory resources */
+#define        SAMSUNG_PINCTRL_NUM_RESOURCES   2
+
 /* list of all possible config options supported */
 static struct pin_config {
        const char *property;
@@ -345,7 +348,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
                        ((b->pin_base + b->nr_pins - 1) < pin))
                b++;
 
-       *reg = drvdata->virt_base + b->pctl_offset;
+       *reg = b->pctl_base + b->pctl_offset;
        *offset = pin - b->pin_base;
        if (bank)
                *bank = b;
@@ -526,7 +529,7 @@ static void samsung_gpio_set_value(struct gpio_chip *gc,
        void __iomem *reg;
        u32 data;
 
-       reg = bank->drvdata->virt_base + bank->pctl_offset;
+       reg = bank->pctl_base + bank->pctl_offset;
 
        data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
        data &= ~(1 << offset);
@@ -554,7 +557,7 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
        struct samsung_pin_bank *bank = gpiochip_get_data(gc);
        const struct samsung_pin_bank_type *type = bank->type;
 
-       reg = bank->drvdata->virt_base + bank->pctl_offset;
+       reg = bank->pctl_base + bank->pctl_offset;
 
        data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
        data >>= offset;
@@ -581,8 +584,8 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc,
        type = bank->type;
        drvdata = bank->drvdata;
 
-       reg = drvdata->virt_base + bank->pctl_offset +
-                                       type->reg_offset[PINCFG_TYPE_FUNC];
+       reg = bank->pctl_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];
@@ -979,6 +982,8 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
        const struct samsung_pin_bank_data *bdata;
        const struct samsung_pin_ctrl *ctrl;
        struct samsung_pin_bank *bank;
+       struct resource *res;
+       void __iomem *virt_base[SAMSUNG_PINCTRL_NUM_RESOURCES];
        int i;
 
        id = of_alias_get_id(node, "pinctrl");
@@ -997,6 +1002,17 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
        if (!d->pin_banks)
                return ERR_PTR(-ENOMEM);
 
+       if (ctrl->nr_ext_resources + 1 > SAMSUNG_PINCTRL_NUM_RESOURCES)
+               return ERR_PTR(-EINVAL);
+
+       for (i = 0; i < ctrl->nr_ext_resources + 1; i++) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               virt_base[i] = devm_ioremap(&pdev->dev, res->start,
+                                               resource_size(res));
+               if (IS_ERR(virt_base[i]))
+                       return ERR_PTR(-EIO);
+       }
+
        bank = d->pin_banks;
        bdata = ctrl->pin_banks;
        for (i = 0; i < ctrl->nr_banks; ++i, ++bdata, ++bank) {
@@ -1013,6 +1029,9 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
                bank->drvdata = d;
                bank->pin_base = d->nr_pins;
                d->nr_pins += bank->nr_pins;
+
+               bank->eint_base = virt_base[0];
+               bank->pctl_base = virt_base[bdata->pctl_res_idx];
        }
 
        for_each_child_of_node(node, np) {
@@ -1052,11 +1071,6 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
        }
        drvdata->dev = dev;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       drvdata->virt_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(drvdata->virt_base))
-               return PTR_ERR(drvdata->virt_base);
-
        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (res)
                drvdata->irq = res->start;
@@ -1094,12 +1108,11 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
 static void samsung_pinctrl_suspend_dev(
        struct samsung_pinctrl_drv_data *drvdata)
 {
-       void __iomem *virt_base = drvdata->virt_base;
        int i;
 
        for (i = 0; i < drvdata->nr_banks; i++) {
                struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
-               void __iomem *reg = virt_base + bank->pctl_offset;
+               void __iomem *reg = bank->pctl_base + bank->pctl_offset;
                const u8 *offs = bank->type->reg_offset;
                const u8 *widths = bank->type->fld_width;
                enum pincfg_type type;
@@ -1140,7 +1153,6 @@ static void samsung_pinctrl_suspend_dev(
  */
 static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata)
 {
-       void __iomem *virt_base = drvdata->virt_base;
        int i;
 
        if (drvdata->resume)
@@ -1148,7 +1160,7 @@ static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata)
 
        for (i = 0; i < drvdata->nr_banks; i++) {
                struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
-               void __iomem *reg = virt_base + bank->pctl_offset;
+               void __iomem *reg = bank->pctl_base + bank->pctl_offset;
                const u8 *offs = bank->type->reg_offset;
                const u8 *widths = bank->type->fld_width;
                enum pincfg_type type;
index cd31bfaf62cb6e33d296e1ba9171933a64434ac4..043cb6c11180e5c8241d47feddbbd0f74fe4d31c 100644 (file)
@@ -116,6 +116,7 @@ struct samsung_pin_bank_type {
  * struct samsung_pin_bank_data: represent a controller pin-bank (init data).
  * @type: type of the bank (register offsets and bitfield widths)
  * @pctl_offset: starting offset of the pin-bank registers.
+ * @pctl_res_idx: index of base address for pin-bank registers.
  * @nr_pins: number of pins included in this bank.
  * @eint_func: function to set in CON register to configure pin as EINT.
  * @eint_type: type of the external interrupt supported by the bank.
@@ -126,6 +127,7 @@ struct samsung_pin_bank_type {
 struct samsung_pin_bank_data {
        const struct samsung_pin_bank_type *type;
        u32             pctl_offset;
+       u8              pctl_res_idx;
        u8              nr_pins;
        u8              eint_func;
        enum eint_type  eint_type;
@@ -137,8 +139,10 @@ struct samsung_pin_bank_data {
 /**
  * struct samsung_pin_bank: represent a controller pin-bank.
  * @type: type of the bank (register offsets and bitfield widths)
+ * @pctl_base: base address of the pin-bank registers
  * @pctl_offset: starting offset of the pin-bank registers.
  * @nr_pins: number of pins included in this bank.
+ * @eint_base: base address of the pin-bank EINT registers.
  * @eint_func: function to set in CON register to configure pin as EINT.
  * @eint_type: type of the external interrupt supported by the bank.
  * @eint_mask: bit mask of pins which support EINT function.
@@ -157,8 +161,10 @@ struct samsung_pin_bank_data {
  */
 struct samsung_pin_bank {
        const struct samsung_pin_bank_type *type;
+       void __iomem    *pctl_base;
        u32             pctl_offset;
        u8              nr_pins;
+       void __iomem    *eint_base;
        u8              eint_func;
        enum eint_type  eint_type;
        u32             eint_mask;
@@ -182,6 +188,7 @@ struct samsung_pin_bank {
  * struct samsung_pin_ctrl: represent a pin controller.
  * @pin_banks: list of pin banks included in this controller.
  * @nr_banks: number of pin banks.
+ * @nr_ext_resources: number of the extra base address for pin banks.
  * @eint_gpio_init: platform specific callback to setup the external gpio
  *     interrupts for the controller.
  * @eint_wkup_init: platform specific callback to setup the external wakeup
@@ -190,6 +197,7 @@ struct samsung_pin_bank {
 struct samsung_pin_ctrl {
        const struct samsung_pin_bank_data *pin_banks;
        u32             nr_banks;
+       int             nr_ext_resources;
 
        int             (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
        int             (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
@@ -200,7 +208,6 @@ struct samsung_pin_ctrl {
 /**
  * struct samsung_pinctrl_drv_data: wrapper for holding driver data together.
  * @node: global list node
- * @virt_base: register base address of the controller.
  * @dev: device instance representing the controller.
  * @irq: interrpt number used by the controller to notify gpio interrupts.
  * @ctrl: pin controller instance managed by the driver.
@@ -215,7 +222,6 @@ struct samsung_pin_ctrl {
  */
 struct samsung_pinctrl_drv_data {
        struct list_head                node;
-       void __iomem                    *virt_base;
        struct device                   *dev;
        int                             irq;
 
index f3a8897d4e8f407f04980c8c404b0e5c4643ec2e..cf80ce1dd7cea5a0fdd9c524a6c5a03e1d93e0f2 100644 (file)
@@ -389,6 +389,21 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
        return 0;
 }
 
+const struct sh_pfc_bias_info *
+sh_pfc_pin_to_bias_info(const struct sh_pfc_bias_info *info,
+                       unsigned int num, unsigned int pin)
+{
+       unsigned int i;
+
+       for (i = 0; i < num; i++)
+               if (info[i].pin == pin)
+                       return &info[i];
+
+       WARN_ONCE(1, "Pin %u is not in bias info list\n", pin);
+
+       return NULL;
+}
+
 static int sh_pfc_init_ranges(struct sh_pfc *pfc)
 {
        struct sh_pfc_pin_range *range;
index 0bbdea5849f41713a135b5dd3ae6bc810717e2b3..6d598dd63720856774c0f7b2267f631fc67204a0 100644 (file)
@@ -33,4 +33,8 @@ void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width,
 int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin);
 int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type);
 
+const struct sh_pfc_bias_info *
+sh_pfc_pin_to_bias_info(const struct sh_pfc_bias_info *info,
+                       unsigned int num, unsigned int pin);
+
 #endif /* __SH_PFC_CORE_H__ */
index 18ef7042b3d1b04761b2e194d11601a1f1d20fe6..c3af9ebee4afc7b0cc4d73a7aad0144cbcae8dc9 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/pinctrl/pinconf-generic.h>
 
+#include "core.h"
 #include "sh_pfc.h"
 
 #define PORT_GP_PUP_1(bank, pin, fn, sfx)      \
@@ -2918,183 +2919,182 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
 #define PUPR4  0x110
 #define PUPR5  0x114
 
-static const struct {
-       u16 reg : 11;
-       u16 bit : 5;
-} pullups[] = {
-       [RCAR_GP_PIN(0,  6)] = { PUPR0,  0 },   /* A0 */
-       [RCAR_GP_PIN(0,  7)] = { PUPR0,  1 },   /* A1 */
-       [RCAR_GP_PIN(0,  8)] = { PUPR0,  2 },   /* A2 */
-       [RCAR_GP_PIN(0,  9)] = { PUPR0,  3 },   /* A3 */
-       [RCAR_GP_PIN(0, 10)] = { PUPR0,  4 },   /* A4 */
-       [RCAR_GP_PIN(0, 11)] = { PUPR0,  5 },   /* A5 */
-       [RCAR_GP_PIN(0, 12)] = { PUPR0,  6 },   /* A6 */
-       [RCAR_GP_PIN(0, 13)] = { PUPR0,  7 },   /* A7 */
-       [RCAR_GP_PIN(0, 14)] = { PUPR0,  8 },   /* A8 */
-       [RCAR_GP_PIN(0, 15)] = { PUPR0,  9 },   /* A9 */
-       [RCAR_GP_PIN(0, 16)] = { PUPR0, 10 },   /* A10 */
-       [RCAR_GP_PIN(0, 17)] = { PUPR0, 11 },   /* A11 */
-       [RCAR_GP_PIN(0, 18)] = { PUPR0, 12 },   /* A12 */
-       [RCAR_GP_PIN(0, 19)] = { PUPR0, 13 },   /* A13 */
-       [RCAR_GP_PIN(0, 20)] = { PUPR0, 14 },   /* A14 */
-       [RCAR_GP_PIN(0, 21)] = { PUPR0, 15 },   /* A15 */
-       [RCAR_GP_PIN(0, 22)] = { PUPR0, 16 },   /* A16 */
-       [RCAR_GP_PIN(0, 23)] = { PUPR0, 17 },   /* A17 */
-       [RCAR_GP_PIN(0, 24)] = { PUPR0, 18 },   /* A18 */
-       [RCAR_GP_PIN(0, 25)] = { PUPR0, 19 },   /* A19 */
-       [RCAR_GP_PIN(0, 26)] = { PUPR0, 20 },   /* A20 */
-       [RCAR_GP_PIN(0, 27)] = { PUPR0, 21 },   /* A21 */
-       [RCAR_GP_PIN(0, 28)] = { PUPR0, 22 },   /* A22 */
-       [RCAR_GP_PIN(0, 29)] = { PUPR0, 23 },   /* A23 */
-       [RCAR_GP_PIN(0, 30)] = { PUPR0, 24 },   /* A24 */
-       [RCAR_GP_PIN(0, 31)] = { PUPR0, 25 },   /* A25 */
-       [RCAR_GP_PIN(1,  3)] = { PUPR0, 26 },   /* /EX_CS0 */
-       [RCAR_GP_PIN(1,  4)] = { PUPR0, 27 },   /* /EX_CS1 */
-       [RCAR_GP_PIN(1,  5)] = { PUPR0, 28 },   /* /EX_CS2 */
-       [RCAR_GP_PIN(1,  6)] = { PUPR0, 29 },   /* /EX_CS3 */
-       [RCAR_GP_PIN(1,  7)] = { PUPR0, 30 },   /* /EX_CS4 */
-       [RCAR_GP_PIN(1,  8)] = { PUPR0, 31 },   /* /EX_CS5 */
-
-       [RCAR_GP_PIN(0,  0)] = { PUPR1,  0 },   /* /PRESETOUT   */
-       [RCAR_GP_PIN(0,  5)] = { PUPR1,  1 },   /* /BS          */
-       [RCAR_GP_PIN(1,  0)] = { PUPR1,  2 },   /* RD//WR       */
-       [RCAR_GP_PIN(1,  1)] = { PUPR1,  3 },   /* /WE0         */
-       [RCAR_GP_PIN(1,  2)] = { PUPR1,  4 },   /* /WE1         */
-       [RCAR_GP_PIN(1, 11)] = { PUPR1,  5 },   /* EX_WAIT0     */
-       [RCAR_GP_PIN(1,  9)] = { PUPR1,  6 },   /* DREQ0        */
-       [RCAR_GP_PIN(1, 10)] = { PUPR1,  7 },   /* DACK0        */
-       [RCAR_GP_PIN(1, 12)] = { PUPR1,  8 },   /* IRQ0         */
-       [RCAR_GP_PIN(1, 13)] = { PUPR1,  9 },   /* IRQ1         */
-
-       [RCAR_GP_PIN(1, 22)] = { PUPR2,  0 },   /* DU0_DR0      */
-       [RCAR_GP_PIN(1, 23)] = { PUPR2,  1 },   /* DU0_DR1      */
-       [RCAR_GP_PIN(1, 24)] = { PUPR2,  2 },   /* DU0_DR2      */
-       [RCAR_GP_PIN(1, 25)] = { PUPR2,  3 },   /* DU0_DR3      */
-       [RCAR_GP_PIN(1, 26)] = { PUPR2,  4 },   /* DU0_DR4      */
-       [RCAR_GP_PIN(1, 27)] = { PUPR2,  5 },   /* DU0_DR5      */
-       [RCAR_GP_PIN(1, 28)] = { PUPR2,  6 },   /* DU0_DR6      */
-       [RCAR_GP_PIN(1, 29)] = { PUPR2,  7 },   /* DU0_DR7      */
-       [RCAR_GP_PIN(1, 30)] = { PUPR2,  8 },   /* DU0_DG0      */
-       [RCAR_GP_PIN(1, 31)] = { PUPR2,  9 },   /* DU0_DG1      */
-       [RCAR_GP_PIN(2,  0)] = { PUPR2, 10 },   /* DU0_DG2      */
-       [RCAR_GP_PIN(2,  1)] = { PUPR2, 11 },   /* DU0_DG3      */
-       [RCAR_GP_PIN(2,  2)] = { PUPR2, 12 },   /* DU0_DG4      */
-       [RCAR_GP_PIN(2,  3)] = { PUPR2, 13 },   /* DU0_DG5      */
-       [RCAR_GP_PIN(2,  4)] = { PUPR2, 14 },   /* DU0_DG6      */
-       [RCAR_GP_PIN(2,  5)] = { PUPR2, 15 },   /* DU0_DG7      */
-       [RCAR_GP_PIN(2,  6)] = { PUPR2, 16 },   /* DU0_DB0      */
-       [RCAR_GP_PIN(2,  7)] = { PUPR2, 17 },   /* DU0_DB1      */
-       [RCAR_GP_PIN(2,  8)] = { PUPR2, 18 },   /* DU0_DB2      */
-       [RCAR_GP_PIN(2,  9)] = { PUPR2, 19 },   /* DU0_DB3      */
-       [RCAR_GP_PIN(2, 10)] = { PUPR2, 20 },   /* DU0_DB4      */
-       [RCAR_GP_PIN(2, 11)] = { PUPR2, 21 },   /* DU0_DB5      */
-       [RCAR_GP_PIN(2, 12)] = { PUPR2, 22 },   /* DU0_DB6      */
-       [RCAR_GP_PIN(2, 13)] = { PUPR2, 23 },   /* DU0_DB7      */
-       [RCAR_GP_PIN(2, 14)] = { PUPR2, 24 },   /* DU0_DOTCLKIN */
-       [RCAR_GP_PIN(2, 15)] = { PUPR2, 25 },   /* DU0_DOTCLKOUT0 */
-       [RCAR_GP_PIN(2, 17)] = { PUPR2, 26 },   /* DU0_HSYNC    */
-       [RCAR_GP_PIN(2, 18)] = { PUPR2, 27 },   /* DU0_VSYNC    */
-       [RCAR_GP_PIN(2, 19)] = { PUPR2, 28 },   /* DU0_EXODDF   */
-       [RCAR_GP_PIN(2, 20)] = { PUPR2, 29 },   /* DU0_DISP     */
-       [RCAR_GP_PIN(2, 21)] = { PUPR2, 30 },   /* DU0_CDE      */
-       [RCAR_GP_PIN(2, 16)] = { PUPR2, 31 },   /* DU0_DOTCLKOUT1 */
-
-       [RCAR_GP_PIN(3, 24)] = { PUPR3,  0 },   /* VI0_CLK      */
-       [RCAR_GP_PIN(3, 25)] = { PUPR3,  1 },   /* VI0_CLKENB   */
-       [RCAR_GP_PIN(3, 26)] = { PUPR3,  2 },   /* VI0_FIELD    */
-       [RCAR_GP_PIN(3, 27)] = { PUPR3,  3 },   /* /VI0_HSYNC   */
-       [RCAR_GP_PIN(3, 28)] = { PUPR3,  4 },   /* /VI0_VSYNC   */
-       [RCAR_GP_PIN(3, 29)] = { PUPR3,  5 },   /* VI0_DATA0    */
-       [RCAR_GP_PIN(3, 30)] = { PUPR3,  6 },   /* VI0_DATA1    */
-       [RCAR_GP_PIN(3, 31)] = { PUPR3,  7 },   /* VI0_DATA2    */
-       [RCAR_GP_PIN(4,  0)] = { PUPR3,  8 },   /* VI0_DATA3    */
-       [RCAR_GP_PIN(4,  1)] = { PUPR3,  9 },   /* VI0_DATA4    */
-       [RCAR_GP_PIN(4,  2)] = { PUPR3, 10 },   /* VI0_DATA5    */
-       [RCAR_GP_PIN(4,  3)] = { PUPR3, 11 },   /* VI0_DATA6    */
-       [RCAR_GP_PIN(4,  4)] = { PUPR3, 12 },   /* VI0_DATA7    */
-       [RCAR_GP_PIN(4,  5)] = { PUPR3, 13 },   /* VI0_G2       */
-       [RCAR_GP_PIN(4,  6)] = { PUPR3, 14 },   /* VI0_G3       */
-       [RCAR_GP_PIN(4,  7)] = { PUPR3, 15 },   /* VI0_G4       */
-       [RCAR_GP_PIN(4,  8)] = { PUPR3, 16 },   /* VI0_G5       */
-       [RCAR_GP_PIN(4, 21)] = { PUPR3, 17 },   /* VI1_DATA12   */
-       [RCAR_GP_PIN(4, 22)] = { PUPR3, 18 },   /* VI1_DATA13   */
-       [RCAR_GP_PIN(4, 23)] = { PUPR3, 19 },   /* VI1_DATA14   */
-       [RCAR_GP_PIN(4, 24)] = { PUPR3, 20 },   /* VI1_DATA15   */
-       [RCAR_GP_PIN(4,  9)] = { PUPR3, 21 },   /* ETH_REF_CLK  */
-       [RCAR_GP_PIN(4, 10)] = { PUPR3, 22 },   /* ETH_TXD0     */
-       [RCAR_GP_PIN(4, 11)] = { PUPR3, 23 },   /* ETH_TXD1     */
-       [RCAR_GP_PIN(4, 12)] = { PUPR3, 24 },   /* ETH_CRS_DV   */
-       [RCAR_GP_PIN(4, 13)] = { PUPR3, 25 },   /* ETH_TX_EN    */
-       [RCAR_GP_PIN(4, 14)] = { PUPR3, 26 },   /* ETH_RX_ER    */
-       [RCAR_GP_PIN(4, 15)] = { PUPR3, 27 },   /* ETH_RXD0     */
-       [RCAR_GP_PIN(4, 16)] = { PUPR3, 28 },   /* ETH_RXD1     */
-       [RCAR_GP_PIN(4, 17)] = { PUPR3, 29 },   /* ETH_MDC      */
-       [RCAR_GP_PIN(4, 18)] = { PUPR3, 30 },   /* ETH_MDIO     */
-       [RCAR_GP_PIN(4, 19)] = { PUPR3, 31 },   /* ETH_LINK     */
-
-       [RCAR_GP_PIN(3,  6)] = { PUPR4,  0 },   /* SSI_SCK012   */
-       [RCAR_GP_PIN(3,  7)] = { PUPR4,  1 },   /* SSI_WS012    */
-       [RCAR_GP_PIN(3, 10)] = { PUPR4,  2 },   /* SSI_SDATA0   */
-       [RCAR_GP_PIN(3,  9)] = { PUPR4,  3 },   /* SSI_SDATA1   */
-       [RCAR_GP_PIN(3,  8)] = { PUPR4,  4 },   /* SSI_SDATA2   */
-       [RCAR_GP_PIN(3,  2)] = { PUPR4,  5 },   /* SSI_SCK34    */
-       [RCAR_GP_PIN(3,  3)] = { PUPR4,  6 },   /* SSI_WS34     */
-       [RCAR_GP_PIN(3,  5)] = { PUPR4,  7 },   /* SSI_SDATA3   */
-       [RCAR_GP_PIN(3,  4)] = { PUPR4,  8 },   /* SSI_SDATA4   */
-       [RCAR_GP_PIN(2, 31)] = { PUPR4,  9 },   /* SSI_SCK5     */
-       [RCAR_GP_PIN(3,  0)] = { PUPR4, 10 },   /* SSI_WS5      */
-       [RCAR_GP_PIN(3,  1)] = { PUPR4, 11 },   /* SSI_SDATA5   */
-       [RCAR_GP_PIN(2, 28)] = { PUPR4, 12 },   /* SSI_SCK6     */
-       [RCAR_GP_PIN(2, 29)] = { PUPR4, 13 },   /* SSI_WS6      */
-       [RCAR_GP_PIN(2, 30)] = { PUPR4, 14 },   /* SSI_SDATA6   */
-       [RCAR_GP_PIN(2, 24)] = { PUPR4, 15 },   /* SSI_SCK78    */
-       [RCAR_GP_PIN(2, 25)] = { PUPR4, 16 },   /* SSI_WS78     */
-       [RCAR_GP_PIN(2, 27)] = { PUPR4, 17 },   /* SSI_SDATA7   */
-       [RCAR_GP_PIN(2, 26)] = { PUPR4, 18 },   /* SSI_SDATA8   */
-       [RCAR_GP_PIN(3, 23)] = { PUPR4, 19 },   /* TCLK0        */
-       [RCAR_GP_PIN(3, 11)] = { PUPR4, 20 },   /* SD0_CLK      */
-       [RCAR_GP_PIN(3, 12)] = { PUPR4, 21 },   /* SD0_CMD      */
-       [RCAR_GP_PIN(3, 13)] = { PUPR4, 22 },   /* SD0_DAT0     */
-       [RCAR_GP_PIN(3, 14)] = { PUPR4, 23 },   /* SD0_DAT1     */
-       [RCAR_GP_PIN(3, 15)] = { PUPR4, 24 },   /* SD0_DAT2     */
-       [RCAR_GP_PIN(3, 16)] = { PUPR4, 25 },   /* SD0_DAT3     */
-       [RCAR_GP_PIN(3, 17)] = { PUPR4, 26 },   /* SD0_CD       */
-       [RCAR_GP_PIN(3, 18)] = { PUPR4, 27 },   /* SD0_WP       */
-       [RCAR_GP_PIN(2, 22)] = { PUPR4, 28 },   /* AUDIO_CLKA   */
-       [RCAR_GP_PIN(2, 23)] = { PUPR4, 29 },   /* AUDIO_CLKB   */
-       [RCAR_GP_PIN(1, 14)] = { PUPR4, 30 },   /* IRQ2         */
-       [RCAR_GP_PIN(1, 15)] = { PUPR4, 31 },   /* IRQ3         */
-
-       [RCAR_GP_PIN(0,  1)] = { PUPR5,  0 },   /* PENC0        */
-       [RCAR_GP_PIN(0,  2)] = { PUPR5,  1 },   /* PENC1        */
-       [RCAR_GP_PIN(0,  3)] = { PUPR5,  2 },   /* USB_OVC0     */
-       [RCAR_GP_PIN(0,  4)] = { PUPR5,  3 },   /* USB_OVC1     */
-       [RCAR_GP_PIN(1, 16)] = { PUPR5,  4 },   /* SCIF_CLK     */
-       [RCAR_GP_PIN(1, 17)] = { PUPR5,  5 },   /* TX0          */
-       [RCAR_GP_PIN(1, 18)] = { PUPR5,  6 },   /* RX0          */
-       [RCAR_GP_PIN(1, 19)] = { PUPR5,  7 },   /* SCK0         */
-       [RCAR_GP_PIN(1, 20)] = { PUPR5,  8 },   /* /CTS0        */
-       [RCAR_GP_PIN(1, 21)] = { PUPR5,  9 },   /* /RTS0        */
-       [RCAR_GP_PIN(3, 19)] = { PUPR5, 10 },   /* HSPI_CLK0    */
-       [RCAR_GP_PIN(3, 20)] = { PUPR5, 11 },   /* /HSPI_CS0    */
-       [RCAR_GP_PIN(3, 21)] = { PUPR5, 12 },   /* HSPI_RX0     */
-       [RCAR_GP_PIN(3, 22)] = { PUPR5, 13 },   /* HSPI_TX0     */
-       [RCAR_GP_PIN(4, 20)] = { PUPR5, 14 },   /* ETH_MAGIC    */
-       [RCAR_GP_PIN(4, 25)] = { PUPR5, 15 },   /* AVS1         */
-       [RCAR_GP_PIN(4, 26)] = { PUPR5, 16 },   /* AVS2         */
+static const struct sh_pfc_bias_info bias_info[] = {
+       { RCAR_GP_PIN(0,  6), PUPR0,  0 },      /* A0 */
+       { RCAR_GP_PIN(0,  7), PUPR0,  1 },      /* A1 */
+       { RCAR_GP_PIN(0,  8), PUPR0,  2 },      /* A2 */
+       { RCAR_GP_PIN(0,  9), PUPR0,  3 },      /* A3 */
+       { RCAR_GP_PIN(0, 10), PUPR0,  4 },      /* A4 */
+       { RCAR_GP_PIN(0, 11), PUPR0,  5 },      /* A5 */
+       { RCAR_GP_PIN(0, 12), PUPR0,  6 },      /* A6 */
+       { RCAR_GP_PIN(0, 13), PUPR0,  7 },      /* A7 */
+       { RCAR_GP_PIN(0, 14), PUPR0,  8 },      /* A8 */
+       { RCAR_GP_PIN(0, 15), PUPR0,  9 },      /* A9 */
+       { RCAR_GP_PIN(0, 16), PUPR0, 10 },      /* A10 */
+       { RCAR_GP_PIN(0, 17), PUPR0, 11 },      /* A11 */
+       { RCAR_GP_PIN(0, 18), PUPR0, 12 },      /* A12 */
+       { RCAR_GP_PIN(0, 19), PUPR0, 13 },      /* A13 */
+       { RCAR_GP_PIN(0, 20), PUPR0, 14 },      /* A14 */
+       { RCAR_GP_PIN(0, 21), PUPR0, 15 },      /* A15 */
+       { RCAR_GP_PIN(0, 22), PUPR0, 16 },      /* A16 */
+       { RCAR_GP_PIN(0, 23), PUPR0, 17 },      /* A17 */
+       { RCAR_GP_PIN(0, 24), PUPR0, 18 },      /* A18 */
+       { RCAR_GP_PIN(0, 25), PUPR0, 19 },      /* A19 */
+       { RCAR_GP_PIN(0, 26), PUPR0, 20 },      /* A20 */
+       { RCAR_GP_PIN(0, 27), PUPR0, 21 },      /* A21 */
+       { RCAR_GP_PIN(0, 28), PUPR0, 22 },      /* A22 */
+       { RCAR_GP_PIN(0, 29), PUPR0, 23 },      /* A23 */
+       { RCAR_GP_PIN(0, 30), PUPR0, 24 },      /* A24 */
+       { RCAR_GP_PIN(0, 31), PUPR0, 25 },      /* A25 */
+       { RCAR_GP_PIN(1,  3), PUPR0, 26 },      /* /EX_CS0 */
+       { RCAR_GP_PIN(1,  4), PUPR0, 27 },      /* /EX_CS1 */
+       { RCAR_GP_PIN(1,  5), PUPR0, 28 },      /* /EX_CS2 */
+       { RCAR_GP_PIN(1,  6), PUPR0, 29 },      /* /EX_CS3 */
+       { RCAR_GP_PIN(1,  7), PUPR0, 30 },      /* /EX_CS4 */
+       { RCAR_GP_PIN(1,  8), PUPR0, 31 },      /* /EX_CS5 */
+
+       { RCAR_GP_PIN(0,  0), PUPR1,  0 },      /* /PRESETOUT   */
+       { RCAR_GP_PIN(0,  5), PUPR1,  1 },      /* /BS          */
+       { RCAR_GP_PIN(1,  0), PUPR1,  2 },      /* RD//WR       */
+       { RCAR_GP_PIN(1,  1), PUPR1,  3 },      /* /WE0         */
+       { RCAR_GP_PIN(1,  2), PUPR1,  4 },      /* /WE1         */
+       { RCAR_GP_PIN(1, 11), PUPR1,  5 },      /* EX_WAIT0     */
+       { RCAR_GP_PIN(1,  9), PUPR1,  6 },      /* DREQ0        */
+       { RCAR_GP_PIN(1, 10), PUPR1,  7 },      /* DACK0        */
+       { RCAR_GP_PIN(1, 12), PUPR1,  8 },      /* IRQ0         */
+       { RCAR_GP_PIN(1, 13), PUPR1,  9 },      /* IRQ1         */
+
+       { RCAR_GP_PIN(1, 22), PUPR2,  0 },      /* DU0_DR0      */
+       { RCAR_GP_PIN(1, 23), PUPR2,  1 },      /* DU0_DR1      */
+       { RCAR_GP_PIN(1, 24), PUPR2,  2 },      /* DU0_DR2      */
+       { RCAR_GP_PIN(1, 25), PUPR2,  3 },      /* DU0_DR3      */
+       { RCAR_GP_PIN(1, 26), PUPR2,  4 },      /* DU0_DR4      */
+       { RCAR_GP_PIN(1, 27), PUPR2,  5 },      /* DU0_DR5      */
+       { RCAR_GP_PIN(1, 28), PUPR2,  6 },      /* DU0_DR6      */
+       { RCAR_GP_PIN(1, 29), PUPR2,  7 },      /* DU0_DR7      */
+       { RCAR_GP_PIN(1, 30), PUPR2,  8 },      /* DU0_DG0      */
+       { RCAR_GP_PIN(1, 31), PUPR2,  9 },      /* DU0_DG1      */
+       { RCAR_GP_PIN(2,  0), PUPR2, 10 },      /* DU0_DG2      */
+       { RCAR_GP_PIN(2,  1), PUPR2, 11 },      /* DU0_DG3      */
+       { RCAR_GP_PIN(2,  2), PUPR2, 12 },      /* DU0_DG4      */
+       { RCAR_GP_PIN(2,  3), PUPR2, 13 },      /* DU0_DG5      */
+       { RCAR_GP_PIN(2,  4), PUPR2, 14 },      /* DU0_DG6      */
+       { RCAR_GP_PIN(2,  5), PUPR2, 15 },      /* DU0_DG7      */
+       { RCAR_GP_PIN(2,  6), PUPR2, 16 },      /* DU0_DB0      */
+       { RCAR_GP_PIN(2,  7), PUPR2, 17 },      /* DU0_DB1      */
+       { RCAR_GP_PIN(2,  8), PUPR2, 18 },      /* DU0_DB2      */
+       { RCAR_GP_PIN(2,  9), PUPR2, 19 },      /* DU0_DB3      */
+       { RCAR_GP_PIN(2, 10), PUPR2, 20 },      /* DU0_DB4      */
+       { RCAR_GP_PIN(2, 11), PUPR2, 21 },      /* DU0_DB5      */
+       { RCAR_GP_PIN(2, 12), PUPR2, 22 },      /* DU0_DB6      */
+       { RCAR_GP_PIN(2, 13), PUPR2, 23 },      /* DU0_DB7      */
+       { RCAR_GP_PIN(2, 14), PUPR2, 24 },      /* DU0_DOTCLKIN */
+       { RCAR_GP_PIN(2, 15), PUPR2, 25 },      /* DU0_DOTCLKOUT0 */
+       { RCAR_GP_PIN(2, 17), PUPR2, 26 },      /* DU0_HSYNC    */
+       { RCAR_GP_PIN(2, 18), PUPR2, 27 },      /* DU0_VSYNC    */
+       { RCAR_GP_PIN(2, 19), PUPR2, 28 },      /* DU0_EXODDF   */
+       { RCAR_GP_PIN(2, 20), PUPR2, 29 },      /* DU0_DISP     */
+       { RCAR_GP_PIN(2, 21), PUPR2, 30 },      /* DU0_CDE      */
+       { RCAR_GP_PIN(2, 16), PUPR2, 31 },      /* DU0_DOTCLKOUT1 */
+
+       { RCAR_GP_PIN(3, 24), PUPR3,  0 },      /* VI0_CLK      */
+       { RCAR_GP_PIN(3, 25), PUPR3,  1 },      /* VI0_CLKENB   */
+       { RCAR_GP_PIN(3, 26), PUPR3,  2 },      /* VI0_FIELD    */
+       { RCAR_GP_PIN(3, 27), PUPR3,  3 },      /* /VI0_HSYNC   */
+       { RCAR_GP_PIN(3, 28), PUPR3,  4 },      /* /VI0_VSYNC   */
+       { RCAR_GP_PIN(3, 29), PUPR3,  5 },      /* VI0_DATA0    */
+       { RCAR_GP_PIN(3, 30), PUPR3,  6 },      /* VI0_DATA1    */
+       { RCAR_GP_PIN(3, 31), PUPR3,  7 },      /* VI0_DATA2    */
+       { RCAR_GP_PIN(4,  0), PUPR3,  8 },      /* VI0_DATA3    */
+       { RCAR_GP_PIN(4,  1), PUPR3,  9 },      /* VI0_DATA4    */
+       { RCAR_GP_PIN(4,  2), PUPR3, 10 },      /* VI0_DATA5    */
+       { RCAR_GP_PIN(4,  3), PUPR3, 11 },      /* VI0_DATA6    */
+       { RCAR_GP_PIN(4,  4), PUPR3, 12 },      /* VI0_DATA7    */
+       { RCAR_GP_PIN(4,  5), PUPR3, 13 },      /* VI0_G2       */
+       { RCAR_GP_PIN(4,  6), PUPR3, 14 },      /* VI0_G3       */
+       { RCAR_GP_PIN(4,  7), PUPR3, 15 },      /* VI0_G4       */
+       { RCAR_GP_PIN(4,  8), PUPR3, 16 },      /* VI0_G5       */
+       { RCAR_GP_PIN(4, 21), PUPR3, 17 },      /* VI1_DATA12   */
+       { RCAR_GP_PIN(4, 22), PUPR3, 18 },      /* VI1_DATA13   */
+       { RCAR_GP_PIN(4, 23), PUPR3, 19 },      /* VI1_DATA14   */
+       { RCAR_GP_PIN(4, 24), PUPR3, 20 },      /* VI1_DATA15   */
+       { RCAR_GP_PIN(4,  9), PUPR3, 21 },      /* ETH_REF_CLK  */
+       { RCAR_GP_PIN(4, 10), PUPR3, 22 },      /* ETH_TXD0     */
+       { RCAR_GP_PIN(4, 11), PUPR3, 23 },      /* ETH_TXD1     */
+       { RCAR_GP_PIN(4, 12), PUPR3, 24 },      /* ETH_CRS_DV   */
+       { RCAR_GP_PIN(4, 13), PUPR3, 25 },      /* ETH_TX_EN    */
+       { RCAR_GP_PIN(4, 14), PUPR3, 26 },      /* ETH_RX_ER    */
+       { RCAR_GP_PIN(4, 15), PUPR3, 27 },      /* ETH_RXD0     */
+       { RCAR_GP_PIN(4, 16), PUPR3, 28 },      /* ETH_RXD1     */
+       { RCAR_GP_PIN(4, 17), PUPR3, 29 },      /* ETH_MDC      */
+       { RCAR_GP_PIN(4, 18), PUPR3, 30 },      /* ETH_MDIO     */
+       { RCAR_GP_PIN(4, 19), PUPR3, 31 },      /* ETH_LINK     */
+
+       { RCAR_GP_PIN(3,  6), PUPR4,  0 },      /* SSI_SCK012   */
+       { RCAR_GP_PIN(3,  7), PUPR4,  1 },      /* SSI_WS012    */
+       { RCAR_GP_PIN(3, 10), PUPR4,  2 },      /* SSI_SDATA0   */
+       { RCAR_GP_PIN(3,  9), PUPR4,  3 },      /* SSI_SDATA1   */
+       { RCAR_GP_PIN(3,  8), PUPR4,  4 },      /* SSI_SDATA2   */
+       { RCAR_GP_PIN(3,  2), PUPR4,  5 },      /* SSI_SCK34    */
+       { RCAR_GP_PIN(3,  3), PUPR4,  6 },      /* SSI_WS34     */
+       { RCAR_GP_PIN(3,  5), PUPR4,  7 },      /* SSI_SDATA3   */
+       { RCAR_GP_PIN(3,  4), PUPR4,  8 },      /* SSI_SDATA4   */
+       { RCAR_GP_PIN(2, 31), PUPR4,  9 },      /* SSI_SCK5     */
+       { RCAR_GP_PIN(3,  0), PUPR4, 10 },      /* SSI_WS5      */
+       { RCAR_GP_PIN(3,  1), PUPR4, 11 },      /* SSI_SDATA5   */
+       { RCAR_GP_PIN(2, 28), PUPR4, 12 },      /* SSI_SCK6     */
+       { RCAR_GP_PIN(2, 29), PUPR4, 13 },      /* SSI_WS6      */
+       { RCAR_GP_PIN(2, 30), PUPR4, 14 },      /* SSI_SDATA6   */
+       { RCAR_GP_PIN(2, 24), PUPR4, 15 },      /* SSI_SCK78    */
+       { RCAR_GP_PIN(2, 25), PUPR4, 16 },      /* SSI_WS78     */
+       { RCAR_GP_PIN(2, 27), PUPR4, 17 },      /* SSI_SDATA7   */
+       { RCAR_GP_PIN(2, 26), PUPR4, 18 },      /* SSI_SDATA8   */
+       { RCAR_GP_PIN(3, 23), PUPR4, 19 },      /* TCLK0        */
+       { RCAR_GP_PIN(3, 11), PUPR4, 20 },      /* SD0_CLK      */
+       { RCAR_GP_PIN(3, 12), PUPR4, 21 },      /* SD0_CMD      */
+       { RCAR_GP_PIN(3, 13), PUPR4, 22 },      /* SD0_DAT0     */
+       { RCAR_GP_PIN(3, 14), PUPR4, 23 },      /* SD0_DAT1     */
+       { RCAR_GP_PIN(3, 15), PUPR4, 24 },      /* SD0_DAT2     */
+       { RCAR_GP_PIN(3, 16), PUPR4, 25 },      /* SD0_DAT3     */
+       { RCAR_GP_PIN(3, 17), PUPR4, 26 },      /* SD0_CD       */
+       { RCAR_GP_PIN(3, 18), PUPR4, 27 },      /* SD0_WP       */
+       { RCAR_GP_PIN(2, 22), PUPR4, 28 },      /* AUDIO_CLKA   */
+       { RCAR_GP_PIN(2, 23), PUPR4, 29 },      /* AUDIO_CLKB   */
+       { RCAR_GP_PIN(1, 14), PUPR4, 30 },      /* IRQ2         */
+       { RCAR_GP_PIN(1, 15), PUPR4, 31 },      /* IRQ3         */
+
+       { RCAR_GP_PIN(0,  1), PUPR5,  0 },      /* PENC0        */
+       { RCAR_GP_PIN(0,  2), PUPR5,  1 },      /* PENC1        */
+       { RCAR_GP_PIN(0,  3), PUPR5,  2 },      /* USB_OVC0     */
+       { RCAR_GP_PIN(0,  4), PUPR5,  3 },      /* USB_OVC1     */
+       { RCAR_GP_PIN(1, 16), PUPR5,  4 },      /* SCIF_CLK     */
+       { RCAR_GP_PIN(1, 17), PUPR5,  5 },      /* TX0          */
+       { RCAR_GP_PIN(1, 18), PUPR5,  6 },      /* RX0          */
+       { RCAR_GP_PIN(1, 19), PUPR5,  7 },      /* SCK0         */
+       { RCAR_GP_PIN(1, 20), PUPR5,  8 },      /* /CTS0        */
+       { RCAR_GP_PIN(1, 21), PUPR5,  9 },      /* /RTS0        */
+       { RCAR_GP_PIN(3, 19), PUPR5, 10 },      /* HSPI_CLK0    */
+       { RCAR_GP_PIN(3, 20), PUPR5, 11 },      /* /HSPI_CS0    */
+       { RCAR_GP_PIN(3, 21), PUPR5, 12 },      /* HSPI_RX0     */
+       { RCAR_GP_PIN(3, 22), PUPR5, 13 },      /* HSPI_TX0     */
+       { RCAR_GP_PIN(4, 20), PUPR5, 14 },      /* ETH_MAGIC    */
+       { RCAR_GP_PIN(4, 25), PUPR5, 15 },      /* AVS1         */
+       { RCAR_GP_PIN(4, 26), PUPR5, 16 },      /* AVS2         */
 };
 
 static unsigned int r8a7778_pinmux_get_bias(struct sh_pfc *pfc,
                                            unsigned int pin)
 {
+       const struct sh_pfc_bias_info *info;
        void __iomem *addr;
 
-       if (WARN_ON_ONCE(!pullups[pin].reg))
+       info = sh_pfc_pin_to_bias_info(bias_info, ARRAY_SIZE(bias_info), pin);
+       if (!info)
                return PIN_CONFIG_BIAS_DISABLE;
 
-       addr = pfc->windows->virt + pullups[pin].reg;
+       addr = pfc->windows->virt + info->reg;
 
-       if (ioread32(addr) & BIT(pullups[pin].bit))
+       if (ioread32(addr) & BIT(info->bit))
                return PIN_CONFIG_BIAS_PULL_UP;
        else
                return PIN_CONFIG_BIAS_DISABLE;
@@ -3103,15 +3103,17 @@ static unsigned int r8a7778_pinmux_get_bias(struct sh_pfc *pfc,
 static void r8a7778_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
                                   unsigned int bias)
 {
+       const struct sh_pfc_bias_info *info;
        void __iomem *addr;
        u32 value;
        u32 bit;
 
-       if (WARN_ON_ONCE(!pullups[pin].reg))
+       info = sh_pfc_pin_to_bias_info(bias_info, ARRAY_SIZE(bias_info), pin);
+       if (!info)
                return;
 
-       addr = pfc->windows->virt + pullups[pin].reg;
-       bit = BIT(pullups[pin].bit);
+       addr = pfc->windows->virt + info->reg;
+       bit = BIT(info->bit);
 
        value = ioread32(addr) & ~bit;
        if (bias == PIN_CONFIG_BIAS_PULL_UP)
index 2e8cc2adbed7e2514096b9b75c4a9012d90066a4..135ed5cbeb44c5e6aaf76ca30a96e5c52751f7b3 100644 (file)
@@ -523,6 +523,22 @@ MOD_SEL0_2_1               MOD_SEL1_2 \
                        MOD_SEL1_1 \
                        MOD_SEL1_0              MOD_SEL2_0
 
+/*
+ * These pins are not able to be muxed but have other properties
+ * that can be set, such as drive-strength or pull-up/pull-down enable.
+ */
+#define PINMUX_STATIC \
+       FM(QSPI0_SPCLK) FM(QSPI0_SSL) FM(QSPI0_MOSI_IO0) FM(QSPI0_MISO_IO1) \
+       FM(QSPI0_IO2) FM(QSPI0_IO3) \
+       FM(QSPI1_SPCLK) FM(QSPI1_SSL) FM(QSPI1_MOSI_IO0) FM(QSPI1_MISO_IO1) \
+       FM(QSPI1_IO2) FM(QSPI1_IO3) \
+       FM(RPC_INT) FM(RPC_WP) FM(RPC_RESET) \
+       FM(AVB_TX_CTL) FM(AVB_TXC) FM(AVB_TD0) FM(AVB_TD1) FM(AVB_TD2) FM(AVB_TD3) \
+       FM(AVB_RX_CTL) FM(AVB_RXC) FM(AVB_RD0) FM(AVB_RD1) FM(AVB_RD2) FM(AVB_RD3) \
+       FM(AVB_TXCREFCLK) FM(AVB_MDIO) \
+       FM(CLKOUT) FM(PRESETOUT) \
+       FM(DU_DOTCLKIN0) FM(DU_DOTCLKIN1) FM(DU_DOTCLKIN2) FM(DU_DOTCLKIN3) \
+       FM(TMS) FM(TDO) FM(ASEBRK) FM(MLB_REF)
 
 enum {
        PINMUX_RESERVED = 0,
@@ -548,6 +564,7 @@ enum {
        PINMUX_GPSR
        PINMUX_IPSR
        PINMUX_MOD_SELS
+       PINMUX_STATIC
        PINMUX_MARK_END,
 #undef F_
 #undef FM
@@ -1412,10 +1429,78 @@ static const u16 pinmux_data[] = {
        PINMUX_IPSR_MSEL(IP17_7_4,      STP_ISSYNC_0_E,         SEL_SSP1_0_4),
        PINMUX_IPSR_MSEL(IP17_7_4,      RIF2_D1_B,              SEL_DRIF2_1),
        PINMUX_IPSR_GPSR(IP17_7_4,      TPU0TO3),
+
+/*
+ * Static pins can not be muxed between different functions but
+ * still needs a mark entry in the pinmux list. Add each static
+ * pin to the list without an associated function. The sh-pfc
+ * core will do the right thing and skip trying to mux then pin
+ * while still applying configuration to it
+ */
+#define FM(x)  PINMUX_DATA(x##_MARK, 0),
+       PINMUX_STATIC
+#undef FM
 };
 
+/*
+ * R8A7795 has 8 banks with 32 PGIOS in each => 256 GPIOs.
+ * Physical layout rows: A - AW, cols: 1 - 39.
+ */
+#define ROW_GROUP_A(r) ('Z' - 'A' + 1 + (r))
+#define PIN_NUMBER(r, c) (((r) - 'A') * 39 + (c) + 300)
+#define PIN_A_NUMBER(r, c) PIN_NUMBER(ROW_GROUP_A(r), c)
+
 static const struct sh_pfc_pin pinmux_pins[] = {
        PINMUX_GPIO_GP_ALL(),
+
+       /*
+        * Pins not associated with a GPIO port.
+        *
+        * The pin positions are different between different r8a7795
+        * packages, all that is needed for the pfc driver is a unique
+        * number for each pin. To this end use the pin layout from
+        * R-Car H3SiP to calculate a unique number for each pin.
+        */
+       SH_PFC_PIN_NAMED_CFG('A',  8, AVB_TX_CTL, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('A',  9, AVB_MDIO, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('A', 12, AVB_TXCREFCLK, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('A', 13, AVB_RD0, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('A', 14, AVB_RD2, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('A', 16, AVB_RX_CTL, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('A', 17, AVB_TD2, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('A', 18, AVB_TD0, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('A', 19, AVB_TXC, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('B', 13, AVB_RD1, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('B', 14, AVB_RD3, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('B', 17, AVB_TD3, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('B', 18, AVB_TD1, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('B', 19, AVB_RXC, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('C',  1, PRESETOUT#, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('F',  1, CLKOUT, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('H', 37, MLB_REF, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('V',  3, QSPI1_SPCLK, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('V',  5, QSPI1_SSL, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('V',  6, RPC_WP#, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('V',  7, RPC_RESET#, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('W',  3, QSPI0_SPCLK, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('Y',  3, QSPI0_SSL, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('Y',  6, QSPI0_IO2, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG('Y',  7, RPC_INT#, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('B'),  4, QSPI0_MISO_IO1, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('B'),  6, QSPI0_IO3, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('C'),  3, QSPI1_IO3, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('C'),  5, QSPI0_MOSI_IO0, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('C'),  7, QSPI1_MOSI_IO0, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('D'), 38, FSCLKST#, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('E'),  4, QSPI1_IO2, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('E'),  5, QSPI1_MISO_IO1, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('P'),  7, DU_DOTCLKIN0, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('P'),  8, DU_DOTCLKIN1, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('R'),  7, DU_DOTCLKIN2, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('R'),  8, DU_DOTCLKIN3, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('R'), 30, TMS, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('T'), 28, TDO, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
+       SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('T'), 30, ASEBRK, SH_PFC_PIN_CFG_DRIVE_STRENGTH),
 };
 
 /* - AUDIO CLOCK ------------------------------------------------------------ */
@@ -1563,11 +1648,33 @@ static const unsigned int avb_phy_int_mux[] = {
        AVB_PHY_INT_MARK,
 };
 static const unsigned int avb_mdc_pins[] = {
-       /* AVB_MDC */
-       RCAR_GP_PIN(2, 9),
+       /* AVB_MDC, AVB_MDIO */
+       RCAR_GP_PIN(2, 9), PIN_NUMBER('A', 9),
 };
 static const unsigned int avb_mdc_mux[] = {
-       AVB_MDC_MARK,
+       AVB_MDC_MARK, AVB_MDIO_MARK,
+};
+static const unsigned int avb_mii_pins[] = {
+       /*
+        * AVB_TX_CTL, AVB_TXC, AVB_TD0,
+        * AVB_TD1, AVB_TD2, AVB_TD3,
+        * AVB_RX_CTL, AVB_RXC, AVB_RD0,
+        * AVB_RD1, AVB_RD2, AVB_RD3,
+        * AVB_TXCREFCLK
+        */
+       PIN_NUMBER('A', 8), PIN_NUMBER('A', 19), PIN_NUMBER('A', 18),
+       PIN_NUMBER('B', 18), PIN_NUMBER('A', 17), PIN_NUMBER('B', 17),
+       PIN_NUMBER('A', 16), PIN_NUMBER('B', 19), PIN_NUMBER('A', 13),
+       PIN_NUMBER('B', 13), PIN_NUMBER('A', 14), PIN_NUMBER('B', 14),
+       PIN_NUMBER('A', 12),
+
+};
+static const unsigned int avb_mii_mux[] = {
+       AVB_TX_CTL_MARK, AVB_TXC_MARK, AVB_TD0_MARK,
+       AVB_TD1_MARK, AVB_TD2_MARK, AVB_TD3_MARK,
+       AVB_RX_CTL_MARK, AVB_RXC_MARK, AVB_RD0_MARK,
+       AVB_RD1_MARK, AVB_RD2_MARK, AVB_RD3_MARK,
+       AVB_TXCREFCLK_MARK,
 };
 static const unsigned int avb_avtp_pps_pins[] = {
        /* AVB_AVTP_PPS */
@@ -3613,6 +3720,55 @@ static const unsigned int usb2_mux[] = {
        USB2_PWEN_MARK, USB2_OVC_MARK,
 };
 
+/* - QSPI0 ------------------------------------------------------------------ */
+static const unsigned int qspi0_ctrl_pins[] = {
+       /* QSPI0_SPCLK, QSPI0_SSL */
+       PIN_NUMBER('W', 3), PIN_NUMBER('Y', 3),
+};
+static const unsigned int qspi0_ctrl_mux[] = {
+       QSPI0_SPCLK_MARK, QSPI0_SSL_MARK,
+};
+static const unsigned int qspi0_data2_pins[] = {
+       /* QSPI0_MOSI_IO0, QSPI0_MISO_IO1 */
+       PIN_A_NUMBER('C', 5), PIN_A_NUMBER('B', 4),
+};
+static const unsigned int qspi0_data2_mux[] = {
+       QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK,
+};
+static const unsigned int qspi0_data4_pins[] = {
+       /* QSPI0_MOSI_IO0, QSPI0_MISO_IO1, QSPI0_IO2, QSPI0_IO3 */
+       PIN_A_NUMBER('C', 5), PIN_A_NUMBER('B', 4),
+       PIN_NUMBER('Y', 6), PIN_A_NUMBER('B', 6),
+};
+static const unsigned int qspi0_data4_mux[] = {
+       QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK,
+       QSPI0_IO2_MARK, QSPI0_IO3_MARK,
+};
+/* - QSPI1 ------------------------------------------------------------------ */
+static const unsigned int qspi1_ctrl_pins[] = {
+       /* QSPI1_SPCLK, QSPI1_SSL */
+       PIN_NUMBER('V', 3), PIN_NUMBER('V', 5),
+};
+static const unsigned int qspi1_ctrl_mux[] = {
+       QSPI1_SPCLK_MARK, QSPI1_SSL_MARK,
+};
+static const unsigned int qspi1_data2_pins[] = {
+       /* QSPI1_MOSI_IO0, QSPI1_MISO_IO1 */
+       PIN_A_NUMBER('C', 7), PIN_A_NUMBER('E', 5),
+};
+static const unsigned int qspi1_data2_mux[] = {
+       QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK,
+};
+static const unsigned int qspi1_data4_pins[] = {
+       /* QSPI1_MOSI_IO0, QSPI1_MISO_IO1, QSPI1_IO2, QSPI1_IO3 */
+       PIN_A_NUMBER('C', 7), PIN_A_NUMBER('E', 5),
+       PIN_A_NUMBER('E', 4), PIN_A_NUMBER('C', 3),
+};
+static const unsigned int qspi1_data4_mux[] = {
+       QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK,
+       QSPI1_IO2_MARK, QSPI1_IO3_MARK,
+};
+
 static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(audio_clk_a_a),
        SH_PFC_PIN_GROUP(audio_clk_a_b),
@@ -3635,6 +3791,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(avb_magic),
        SH_PFC_PIN_GROUP(avb_phy_int),
        SH_PFC_PIN_GROUP(avb_mdc),
+       SH_PFC_PIN_GROUP(avb_mii),
        SH_PFC_PIN_GROUP(avb_avtp_pps),
        SH_PFC_PIN_GROUP(avb_avtp_match_a),
        SH_PFC_PIN_GROUP(avb_avtp_capture_a),
@@ -3912,6 +4069,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(usb0),
        SH_PFC_PIN_GROUP(usb1),
        SH_PFC_PIN_GROUP(usb2),
+       SH_PFC_PIN_GROUP(qspi0_ctrl),
+       SH_PFC_PIN_GROUP(qspi0_data2),
+       SH_PFC_PIN_GROUP(qspi0_data4),
+       SH_PFC_PIN_GROUP(qspi1_ctrl),
+       SH_PFC_PIN_GROUP(qspi1_data2),
+       SH_PFC_PIN_GROUP(qspi1_data4),
 };
 
 static const char * const audio_clk_groups[] = {
@@ -3939,6 +4102,7 @@ static const char * const avb_groups[] = {
        "avb_magic",
        "avb_phy_int",
        "avb_mdc",
+       "avb_mii",
        "avb_avtp_pps",
        "avb_avtp_match_a",
        "avb_avtp_capture_a",
@@ -4356,6 +4520,18 @@ static const char * const usb2_groups[] = {
        "usb2",
 };
 
+static const char * const qspi0_groups[] = {
+       "qspi0_ctrl",
+       "qspi0_data2",
+       "qspi0_data4",
+};
+
+static const char * const qspi1_groups[] = {
+       "qspi1_ctrl",
+       "qspi1_data2",
+       "qspi1_data4",
+};
+
 static const struct sh_pfc_function pinmux_functions[] = {
        SH_PFC_FUNCTION(audio_clk),
        SH_PFC_FUNCTION(avb),
@@ -4405,6 +4581,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
        SH_PFC_FUNCTION(usb0),
        SH_PFC_FUNCTION(usb1),
        SH_PFC_FUNCTION(usb2),
+       SH_PFC_FUNCTION(qspi0),
+       SH_PFC_FUNCTION(qspi1),
 };
 
 static const struct pinmux_cfg_reg pinmux_config_regs[] = {
@@ -4962,10 +5140,45 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
 };
 
 static const struct pinmux_drive_reg pinmux_drive_regs[] = {
+       { PINMUX_DRIVE_REG("DRVCTRL0", 0xe6060300) {
+               { PIN_NUMBER('W', 3),   28, 2 },        /* QSPI0_SPCLK */
+               { PIN_A_NUMBER('C', 5), 24, 2 },        /* QSPI0_MOSI_IO0 */
+               { PIN_A_NUMBER('B', 4), 20, 2 },        /* QSPI0_MISO_IO1 */
+               { PIN_NUMBER('Y', 6),   16, 2 },        /* QSPI0_IO2 */
+               { PIN_A_NUMBER('B', 6), 12, 2 },        /* QSPI0_IO3 */
+               { PIN_NUMBER('Y', 3),    8, 2 },        /* QSPI0_SSL */
+               { PIN_NUMBER('V', 3),    4, 2 },        /* QSPI1_SPCLK */
+               { PIN_A_NUMBER('C', 7),  0, 2 },        /* QSPI1_MOSI_IO0 */
+       } },
+       { PINMUX_DRIVE_REG("DRVCTRL1", 0xe6060304) {
+               { PIN_A_NUMBER('E', 5), 28, 2 },        /* QSPI1_MISO_IO1 */
+               { PIN_A_NUMBER('E', 4), 24, 2 },        /* QSPI1_IO2 */
+               { PIN_A_NUMBER('C', 3), 20, 2 },        /* QSPI1_IO3 */
+               { PIN_NUMBER('V', 5),   16, 2 },        /* QSPI1_SSL */
+               { PIN_NUMBER('Y', 7),   12, 2 },        /* RPC_INT# */
+               { PIN_NUMBER('V', 6),    8, 2 },        /* RPC_WP# */
+               { PIN_NUMBER('V', 7),    4, 2 },        /* RPC_RESET# */
+               { PIN_NUMBER('A', 16),   0, 3 },        /* AVB_RX_CTL */
+       } },
+       { PINMUX_DRIVE_REG("DRVCTRL2", 0xe6060308) {
+               { PIN_NUMBER('B', 19),  28, 3 },        /* AVB_RXC */
+               { PIN_NUMBER('A', 13),  24, 3 },        /* AVB_RD0 */
+               { PIN_NUMBER('B', 13),  20, 3 },        /* AVB_RD1 */
+               { PIN_NUMBER('A', 14),  16, 3 },        /* AVB_RD2 */
+               { PIN_NUMBER('B', 14),  12, 3 },        /* AVB_RD3 */
+               { PIN_NUMBER('A', 8),    8, 3 },        /* AVB_TX_CTL */
+               { PIN_NUMBER('A', 19),   4, 3 },        /* AVB_TXC */
+               { PIN_NUMBER('A', 18),   0, 3 },        /* AVB_TD0 */
+       } },
        { PINMUX_DRIVE_REG("DRVCTRL3", 0xe606030c) {
-               { RCAR_GP_PIN(2,  9),  8, 3 },  /* AVB_MDC */
-               { RCAR_GP_PIN(2, 10),  4, 3 },  /* AVB_MAGIC */
-               { RCAR_GP_PIN(2, 11),  0, 3 },  /* AVB_PHY_INT */
+               { PIN_NUMBER('B', 18),  28, 3 },        /* AVB_TD1 */
+               { PIN_NUMBER('A', 17),  24, 3 },        /* AVB_TD2 */
+               { PIN_NUMBER('B', 17),  20, 3 },        /* AVB_TD3 */
+               { PIN_NUMBER('A', 12),  16, 3 },        /* AVB_TXCREFCLK */
+               { PIN_NUMBER('A', 9),   12, 3 },        /* AVB_MDIO */
+               { RCAR_GP_PIN(2,  9),    8, 3 },        /* AVB_MDC */
+               { RCAR_GP_PIN(2, 10),    4, 3 },        /* AVB_MAGIC */
+               { RCAR_GP_PIN(2, 11),    0, 3 },        /* AVB_PHY_INT */
        } },
        { PINMUX_DRIVE_REG("DRVCTRL4", 0xe6060310) {
                { RCAR_GP_PIN(2, 12), 28, 3 },  /* AVB_LINK */
@@ -5008,6 +5221,7 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
                { RCAR_GP_PIN(1, 19),  0, 3 },  /* A19 */
        } },
        { PINMUX_DRIVE_REG("DRVCTRL8", 0xe6060320) {
+               { PIN_NUMBER('F', 1), 28, 3 },  /* CLKOUT */
                { RCAR_GP_PIN(1, 20), 24, 3 },  /* CS0 */
                { RCAR_GP_PIN(1, 21), 20, 3 },  /* CS1_A26 */
                { RCAR_GP_PIN(1, 22), 16, 3 },  /* BS */
@@ -5018,6 +5232,7 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
        } },
        { PINMUX_DRIVE_REG("DRVCTRL9", 0xe6060324) {
                { RCAR_GP_PIN(1, 27), 28, 3 },  /* EX_WAIT0 */
+               { PIN_NUMBER('C', 1), 24, 3 },  /* PRESETOUT# */
                { RCAR_GP_PIN(0,  0), 20, 3 },  /* D0 */
                { RCAR_GP_PIN(0,  1), 16, 3 },  /* D1 */
                { RCAR_GP_PIN(0,  2), 12, 3 },  /* D2 */
@@ -5036,20 +5251,30 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
                { RCAR_GP_PIN(0, 13),  0, 3 },  /* D13 */
        } },
        { PINMUX_DRIVE_REG("DRVCTRL11", 0xe606032c) {
-               { RCAR_GP_PIN(0, 14), 28, 3 },  /* D14 */
-               { RCAR_GP_PIN(0, 15), 24, 3 },  /* D15 */
-               { RCAR_GP_PIN(7,  0), 20, 3 },  /* AVS1 */
-               { RCAR_GP_PIN(7,  1), 16, 3 },  /* AVS2 */
-               { RCAR_GP_PIN(7,  2), 12, 3 },  /* HDMI0_CEC */
-               { RCAR_GP_PIN(7,  3),  8, 3 },  /* HDMI1_CEC */
+               { RCAR_GP_PIN(0, 14),   28, 3 },        /* D14 */
+               { RCAR_GP_PIN(0, 15),   24, 3 },        /* D15 */
+               { RCAR_GP_PIN(7,  0),   20, 3 },        /* AVS1 */
+               { RCAR_GP_PIN(7,  1),   16, 3 },        /* AVS2 */
+               { RCAR_GP_PIN(7,  2),   12, 3 },        /* HDMI0_CEC */
+               { RCAR_GP_PIN(7,  3),    8, 3 },        /* HDMI1_CEC */
+               { PIN_A_NUMBER('P', 7),  4, 2 },        /* DU_DOTCLKIN0 */
+               { PIN_A_NUMBER('P', 8),  0, 2 },        /* DU_DOTCLKIN1 */
+       } },
+       { PINMUX_DRIVE_REG("DRVCTRL12", 0xe6060330) {
+               { PIN_A_NUMBER('R', 7),  28, 2 },       /* DU_DOTCLKIN2 */
+               { PIN_A_NUMBER('R', 8),  24, 2 },       /* DU_DOTCLKIN3 */
+               { PIN_A_NUMBER('D', 38), 20, 2 },       /* FSCLKST# */
+               { PIN_A_NUMBER('R', 30),  4, 2 },       /* TMS */
        } },
        { PINMUX_DRIVE_REG("DRVCTRL13", 0xe6060334) {
-               { RCAR_GP_PIN(3,  0), 20, 3 },  /* SD0_CLK */
-               { RCAR_GP_PIN(3,  1), 16, 3 },  /* SD0_CMD */
-               { RCAR_GP_PIN(3,  2), 12, 3 },  /* SD0_DAT0 */
-               { RCAR_GP_PIN(3,  3),  8, 3 },  /* SD0_DAT1 */
-               { RCAR_GP_PIN(3,  4),  4, 3 },  /* SD0_DAT2 */
-               { RCAR_GP_PIN(3,  5),  0, 3 },  /* SD0_DAT3 */
+               { PIN_A_NUMBER('T', 28), 28, 2 },       /* TDO */
+               { PIN_A_NUMBER('T', 30), 24, 2 },       /* ASEBRK */
+               { RCAR_GP_PIN(3,  0),    20, 3 },       /* SD0_CLK */
+               { RCAR_GP_PIN(3,  1),    16, 3 },       /* SD0_CMD */
+               { RCAR_GP_PIN(3,  2),    12, 3 },       /* SD0_DAT0 */
+               { RCAR_GP_PIN(3,  3),     8, 3 },       /* SD0_DAT1 */
+               { RCAR_GP_PIN(3,  4),     4, 3 },       /* SD0_DAT2 */
+               { RCAR_GP_PIN(3,  5),     0, 3 },       /* SD0_DAT3 */
        } },
        { PINMUX_DRIVE_REG("DRVCTRL14", 0xe6060338) {
                { RCAR_GP_PIN(3,  6), 28, 3 },  /* SD1_CLK */
@@ -5118,6 +5343,7 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
                { RCAR_GP_PIN(5, 23), 16, 3 },  /* MLB_CLK */
                { RCAR_GP_PIN(5, 24), 12, 3 },  /* MLB_SIG */
                { RCAR_GP_PIN(5, 25),  8, 3 },  /* MLB_DAT */
+               { PIN_NUMBER('H', 37),  4, 3 }, /* MLB_REF */
                { RCAR_GP_PIN(6,  0),  0, 3 },  /* SSI_SCK01239 */
        } },
        { PINMUX_DRIVE_REG("DRVCTRL21", 0xe6060354) {
@@ -5188,206 +5414,206 @@ static int r8a7795_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *poc
 #define PU5    0x14
 #define PU6    0x18
 
-static const struct {
-       u16 reg : 11;
-       u16 bit : 5;
-} pullups[] = {
-       [RCAR_GP_PIN(2, 11)] = { PU0, 31 },     /* AVB_PHY_INT */
-       [RCAR_GP_PIN(2, 10)] = { PU0, 30 },     /* AVB_MAGIC */
-       [RCAR_GP_PIN(2,  9)] = { PU0, 29 },     /* AVB_MDC */
-
-       [RCAR_GP_PIN(1, 19)] = { PU1, 31 },     /* A19 */
-       [RCAR_GP_PIN(1, 18)] = { PU1, 30 },     /* A18 */
-       [RCAR_GP_PIN(1, 17)] = { PU1, 29 },     /* A17 */
-       [RCAR_GP_PIN(1, 16)] = { PU1, 28 },     /* A16 */
-       [RCAR_GP_PIN(1, 15)] = { PU1, 27 },     /* A15 */
-       [RCAR_GP_PIN(1, 14)] = { PU1, 26 },     /* A14 */
-       [RCAR_GP_PIN(1, 13)] = { PU1, 25 },     /* A13 */
-       [RCAR_GP_PIN(1, 12)] = { PU1, 24 },     /* A12 */
-       [RCAR_GP_PIN(1, 11)] = { PU1, 23 },     /* A11 */
-       [RCAR_GP_PIN(1, 10)] = { PU1, 22 },     /* A10 */
-       [RCAR_GP_PIN(1,  9)] = { PU1, 21 },     /* A9 */
-       [RCAR_GP_PIN(1,  8)] = { PU1, 20 },     /* A8 */
-       [RCAR_GP_PIN(1,  7)] = { PU1, 19 },     /* A7 */
-       [RCAR_GP_PIN(1,  6)] = { PU1, 18 },     /* A6 */
-       [RCAR_GP_PIN(1,  5)] = { PU1, 17 },     /* A5 */
-       [RCAR_GP_PIN(1,  4)] = { PU1, 16 },     /* A4 */
-       [RCAR_GP_PIN(1,  3)] = { PU1, 15 },     /* A3 */
-       [RCAR_GP_PIN(1,  2)] = { PU1, 14 },     /* A2 */
-       [RCAR_GP_PIN(1,  1)] = { PU1, 13 },     /* A1 */
-       [RCAR_GP_PIN(1,  0)] = { PU1, 12 },     /* A0 */
-       [RCAR_GP_PIN(2,  8)] = { PU1, 11 },     /* PWM2_A */
-       [RCAR_GP_PIN(2,  7)] = { PU1, 10 },     /* PWM1_A */
-       [RCAR_GP_PIN(2,  6)] = { PU1,  9 },     /* PWM0 */
-       [RCAR_GP_PIN(2,  5)] = { PU1,  8 },     /* IRQ5 */
-       [RCAR_GP_PIN(2,  4)] = { PU1,  7 },     /* IRQ4 */
-       [RCAR_GP_PIN(2,  3)] = { PU1,  6 },     /* IRQ3 */
-       [RCAR_GP_PIN(2,  2)] = { PU1,  5 },     /* IRQ2 */
-       [RCAR_GP_PIN(2,  1)] = { PU1,  4 },     /* IRQ1 */
-       [RCAR_GP_PIN(2,  0)] = { PU1,  3 },     /* IRQ0 */
-       [RCAR_GP_PIN(2, 14)] = { PU1,  2 },     /* AVB_AVTP_CAPTURE_A */
-       [RCAR_GP_PIN(2, 13)] = { PU1,  1 },     /* AVB_AVTP_MATCH_A */
-       [RCAR_GP_PIN(2, 12)] = { PU1,  0 },     /* AVB_LINK */
-
-       [RCAR_GP_PIN(7,  3)] = { PU2, 29 },     /* HDMI1_CEC */
-       [RCAR_GP_PIN(7,  2)] = { PU2, 28 },     /* HDMI0_CEC */
-       [RCAR_GP_PIN(7,  1)] = { PU2, 27 },     /* AVS2 */
-       [RCAR_GP_PIN(7,  0)] = { PU2, 26 },     /* AVS1 */
-       [RCAR_GP_PIN(0, 15)] = { PU2, 25 },     /* D15 */
-       [RCAR_GP_PIN(0, 14)] = { PU2, 24 },     /* D14 */
-       [RCAR_GP_PIN(0, 13)] = { PU2, 23 },     /* D13 */
-       [RCAR_GP_PIN(0, 12)] = { PU2, 22 },     /* D12 */
-       [RCAR_GP_PIN(0, 11)] = { PU2, 21 },     /* D11 */
-       [RCAR_GP_PIN(0, 10)] = { PU2, 20 },     /* D10 */
-       [RCAR_GP_PIN(0,  9)] = { PU2, 19 },     /* D9 */
-       [RCAR_GP_PIN(0,  8)] = { PU2, 18 },     /* D8 */
-       [RCAR_GP_PIN(0,  7)] = { PU2, 17 },     /* D7 */
-       [RCAR_GP_PIN(0,  6)] = { PU2, 16 },     /* D6 */
-       [RCAR_GP_PIN(0,  5)] = { PU2, 15 },     /* D5 */
-       [RCAR_GP_PIN(0,  4)] = { PU2, 14 },     /* D4 */
-       [RCAR_GP_PIN(0,  3)] = { PU2, 13 },     /* D3 */
-       [RCAR_GP_PIN(0,  2)] = { PU2, 12 },     /* D2 */
-       [RCAR_GP_PIN(0,  1)] = { PU2, 11 },     /* D1 */
-       [RCAR_GP_PIN(0,  0)] = { PU2, 10 },     /* D0 */
-       [RCAR_GP_PIN(1, 27)] = { PU2,  8 },     /* EX_WAIT0_A */
-       [RCAR_GP_PIN(1, 26)] = { PU2,  7 },     /* WE1_N */
-       [RCAR_GP_PIN(1, 25)] = { PU2,  6 },     /* WE0_N */
-       [RCAR_GP_PIN(1, 24)] = { PU2,  5 },     /* RD_WR_N */
-       [RCAR_GP_PIN(1, 23)] = { PU2,  4 },     /* RD_N */
-       [RCAR_GP_PIN(1, 22)] = { PU2,  3 },     /* BS_N */
-       [RCAR_GP_PIN(1, 21)] = { PU2,  2 },     /* CS1_N_A26 */
-       [RCAR_GP_PIN(1, 20)] = { PU2,  1 },     /* CS0_N */
-
-       [RCAR_GP_PIN(4,  9)] = { PU3, 31 },     /* SD3_DAT0 */
-       [RCAR_GP_PIN(4,  8)] = { PU3, 30 },     /* SD3_CMD */
-       [RCAR_GP_PIN(4,  7)] = { PU3, 29 },     /* SD3_CLK */
-       [RCAR_GP_PIN(4,  6)] = { PU3, 28 },     /* SD2_DS */
-       [RCAR_GP_PIN(4,  5)] = { PU3, 27 },     /* SD2_DAT3 */
-       [RCAR_GP_PIN(4,  4)] = { PU3, 26 },     /* SD2_DAT2 */
-       [RCAR_GP_PIN(4,  3)] = { PU3, 25 },     /* SD2_DAT1 */
-       [RCAR_GP_PIN(4,  2)] = { PU3, 24 },     /* SD2_DAT0 */
-       [RCAR_GP_PIN(4,  1)] = { PU3, 23 },     /* SD2_CMD */
-       [RCAR_GP_PIN(4,  0)] = { PU3, 22 },     /* SD2_CLK */
-       [RCAR_GP_PIN(3, 11)] = { PU3, 21 },     /* SD1_DAT3 */
-       [RCAR_GP_PIN(3, 10)] = { PU3, 20 },     /* SD1_DAT2 */
-       [RCAR_GP_PIN(3,  9)] = { PU3, 19 },     /* SD1_DAT1 */
-       [RCAR_GP_PIN(3,  8)] = { PU3, 18 },     /* SD1_DAT0 */
-       [RCAR_GP_PIN(3,  7)] = { PU3, 17 },     /* SD1_CMD */
-       [RCAR_GP_PIN(3,  6)] = { PU3, 16 },     /* SD1_CLK */
-       [RCAR_GP_PIN(3,  5)] = { PU3, 15 },     /* SD0_DAT3 */
-       [RCAR_GP_PIN(3,  4)] = { PU3, 14 },     /* SD0_DAT2 */
-       [RCAR_GP_PIN(3,  3)] = { PU3, 13 },     /* SD0_DAT1 */
-       [RCAR_GP_PIN(3,  2)] = { PU3, 12 },     /* SD0_DAT0 */
-       [RCAR_GP_PIN(3,  1)] = { PU3, 11 },     /* SD0_CMD */
-       [RCAR_GP_PIN(3,  0)] = { PU3, 10 },     /* SD0_CLK */
-
-       [RCAR_GP_PIN(5, 19)] = { PU4, 31 },     /* MSIOF0_SS1 */
-       [RCAR_GP_PIN(5, 18)] = { PU4, 30 },     /* MSIOF0_SYNC */
-       [RCAR_GP_PIN(5, 17)] = { PU4, 29 },     /* MSIOF0_SCK */
-       [RCAR_GP_PIN(5, 16)] = { PU4, 28 },     /* HRTS0_N */
-       [RCAR_GP_PIN(5, 15)] = { PU4, 27 },     /* HCTS0_N */
-       [RCAR_GP_PIN(5, 14)] = { PU4, 26 },     /* HTX0 */
-       [RCAR_GP_PIN(5, 13)] = { PU4, 25 },     /* HRX0 */
-       [RCAR_GP_PIN(5, 12)] = { PU4, 24 },     /* HSCK0 */
-       [RCAR_GP_PIN(5, 11)] = { PU4, 23 },     /* RX2_A */
-       [RCAR_GP_PIN(5, 10)] = { PU4, 22 },     /* TX2_A */
-       [RCAR_GP_PIN(5,  9)] = { PU4, 21 },     /* SCK2 */
-       [RCAR_GP_PIN(5,  8)] = { PU4, 20 },     /* RTS1_N_TANS */
-       [RCAR_GP_PIN(5,  7)] = { PU4, 19 },     /* CTS1_N */
-       [RCAR_GP_PIN(5,  6)] = { PU4, 18 },     /* TX1_A */
-       [RCAR_GP_PIN(5,  5)] = { PU4, 17 },     /* RX1_A */
-       [RCAR_GP_PIN(5,  4)] = { PU4, 16 },     /* RTS0_N_TANS */
-       [RCAR_GP_PIN(5,  3)] = { PU4, 15 },     /* CTS0_N */
-       [RCAR_GP_PIN(5,  2)] = { PU4, 14 },     /* TX0 */
-       [RCAR_GP_PIN(5,  1)] = { PU4, 13 },     /* RX0 */
-       [RCAR_GP_PIN(5,  0)] = { PU4, 12 },     /* SCK0 */
-       [RCAR_GP_PIN(3, 15)] = { PU4, 11 },     /* SD1_WP */
-       [RCAR_GP_PIN(3, 14)] = { PU4, 10 },     /* SD1_CD */
-       [RCAR_GP_PIN(3, 13)] = { PU4,  9 },     /* SD0_WP */
-       [RCAR_GP_PIN(3, 12)] = { PU4,  8 },     /* SD0_CD */
-       [RCAR_GP_PIN(4, 17)] = { PU4,  7 },     /* SD3_DS */
-       [RCAR_GP_PIN(4, 16)] = { PU4,  6 },     /* SD3_DAT7 */
-       [RCAR_GP_PIN(4, 15)] = { PU4,  5 },     /* SD3_DAT6 */
-       [RCAR_GP_PIN(4, 14)] = { PU4,  4 },     /* SD3_DAT5 */
-       [RCAR_GP_PIN(4, 13)] = { PU4,  3 },     /* SD3_DAT4 */
-       [RCAR_GP_PIN(4, 12)] = { PU4,  2 },     /* SD3_DAT3 */
-       [RCAR_GP_PIN(4, 11)] = { PU4,  1 },     /* SD3_DAT2 */
-       [RCAR_GP_PIN(4, 10)] = { PU4,  0 },     /* SD3_DAT1 */
-
-       [RCAR_GP_PIN(6, 24)] = { PU5, 31 },     /* USB0_PWEN */
-       [RCAR_GP_PIN(6, 23)] = { PU5, 30 },     /* AUDIO_CLKB_B */
-       [RCAR_GP_PIN(6, 22)] = { PU5, 29 },     /* AUDIO_CLKA_A */
-       [RCAR_GP_PIN(6, 21)] = { PU5, 28 },     /* SSI_SDATA9_A */
-       [RCAR_GP_PIN(6, 20)] = { PU5, 27 },     /* SSI_SDATA8 */
-       [RCAR_GP_PIN(6, 19)] = { PU5, 26 },     /* SSI_SDATA7 */
-       [RCAR_GP_PIN(6, 18)] = { PU5, 25 },     /* SSI_WS78 */
-       [RCAR_GP_PIN(6, 17)] = { PU5, 24 },     /* SSI_SCK78 */
-       [RCAR_GP_PIN(6, 16)] = { PU5, 23 },     /* SSI_SDATA6 */
-       [RCAR_GP_PIN(6, 15)] = { PU5, 22 },     /* SSI_WS6 */
-       [RCAR_GP_PIN(6, 14)] = { PU5, 21 },     /* SSI_SCK6 */
-       [RCAR_GP_PIN(6, 13)] = { PU5, 20 },     /* SSI_SDATA5 */
-       [RCAR_GP_PIN(6, 12)] = { PU5, 19 },     /* SSI_WS5 */
-       [RCAR_GP_PIN(6, 11)] = { PU5, 18 },     /* SSI_SCK5 */
-       [RCAR_GP_PIN(6, 10)] = { PU5, 17 },     /* SSI_SDATA4 */
-       [RCAR_GP_PIN(6,  9)] = { PU5, 16 },     /* SSI_WS4 */
-       [RCAR_GP_PIN(6,  8)] = { PU5, 15 },     /* SSI_SCK4 */
-       [RCAR_GP_PIN(6,  7)] = { PU5, 14 },     /* SSI_SDATA3 */
-       [RCAR_GP_PIN(6,  6)] = { PU5, 13 },     /* SSI_WS34 */
-       [RCAR_GP_PIN(6,  5)] = { PU5, 12 },     /* SSI_SCK34 */
-       [RCAR_GP_PIN(6,  4)] = { PU5, 11 },     /* SSI_SDATA2_A */
-       [RCAR_GP_PIN(6,  3)] = { PU5, 10 },     /* SSI_SDATA1_A */
-       [RCAR_GP_PIN(6,  2)] = { PU5,  9 },     /* SSI_SDATA0 */
-       [RCAR_GP_PIN(6,  1)] = { PU5,  8 },     /* SSI_WS01239 */
-       [RCAR_GP_PIN(6,  0)] = { PU5,  7 },     /* SSI_SCK01239 */
-       [RCAR_GP_PIN(5, 25)] = { PU5,  5 },     /* MLB_DAT */
-       [RCAR_GP_PIN(5, 24)] = { PU5,  4 },     /* MLB_SIG */
-       [RCAR_GP_PIN(5, 23)] = { PU5,  3 },     /* MLB_CLK */
-       [RCAR_GP_PIN(5, 22)] = { PU5,  2 },     /* MSIOF0_RXD */
-       [RCAR_GP_PIN(5, 21)] = { PU5,  1 },     /* MSIOF0_SS2 */
-       [RCAR_GP_PIN(5, 20)] = { PU5,  0 },     /* MSIOF0_TXD */
-
-       [RCAR_GP_PIN(6, 31)] = { PU6,  6 },     /* USB31_OVC */
-       [RCAR_GP_PIN(6, 30)] = { PU6,  5 },     /* USB31_PWEN */
-       [RCAR_GP_PIN(6, 29)] = { PU6,  4 },     /* USB30_OVC */
-       [RCAR_GP_PIN(6, 28)] = { PU6,  3 },     /* USB30_PWEN */
-       [RCAR_GP_PIN(6, 27)] = { PU6,  2 },     /* USB1_OVC */
-       [RCAR_GP_PIN(6, 26)] = { PU6,  1 },     /* USB1_PWEN */
-       [RCAR_GP_PIN(6, 25)] = { PU6,  0 },     /* USB0_OVC */
+static const struct sh_pfc_bias_info bias_info[] = {
+       { RCAR_GP_PIN(2, 11), PU0, 31 },        /* AVB_PHY_INT */
+       { RCAR_GP_PIN(2, 10), PU0, 30 },        /* AVB_MAGIC */
+       { RCAR_GP_PIN(2,  9), PU0, 29 },        /* AVB_MDC */
+
+       { RCAR_GP_PIN(1, 19), PU1, 31 },        /* A19 */
+       { RCAR_GP_PIN(1, 18), PU1, 30 },        /* A18 */
+       { RCAR_GP_PIN(1, 17), PU1, 29 },        /* A17 */
+       { RCAR_GP_PIN(1, 16), PU1, 28 },        /* A16 */
+       { RCAR_GP_PIN(1, 15), PU1, 27 },        /* A15 */
+       { RCAR_GP_PIN(1, 14), PU1, 26 },        /* A14 */
+       { RCAR_GP_PIN(1, 13), PU1, 25 },        /* A13 */
+       { RCAR_GP_PIN(1, 12), PU1, 24 },        /* A12 */
+       { RCAR_GP_PIN(1, 11), PU1, 23 },        /* A11 */
+       { RCAR_GP_PIN(1, 10), PU1, 22 },        /* A10 */
+       { RCAR_GP_PIN(1,  9), PU1, 21 },        /* A9 */
+       { RCAR_GP_PIN(1,  8), PU1, 20 },        /* A8 */
+       { RCAR_GP_PIN(1,  7), PU1, 19 },        /* A7 */
+       { RCAR_GP_PIN(1,  6), PU1, 18 },        /* A6 */
+       { RCAR_GP_PIN(1,  5), PU1, 17 },        /* A5 */
+       { RCAR_GP_PIN(1,  4), PU1, 16 },        /* A4 */
+       { RCAR_GP_PIN(1,  3), PU1, 15 },        /* A3 */
+       { RCAR_GP_PIN(1,  2), PU1, 14 },        /* A2 */
+       { RCAR_GP_PIN(1,  1), PU1, 13 },        /* A1 */
+       { RCAR_GP_PIN(1,  0), PU1, 12 },        /* A0 */
+       { RCAR_GP_PIN(2,  8), PU1, 11 },        /* PWM2_A */
+       { RCAR_GP_PIN(2,  7), PU1, 10 },        /* PWM1_A */
+       { RCAR_GP_PIN(2,  6), PU1,  9 },        /* PWM0 */
+       { RCAR_GP_PIN(2,  5), PU1,  8 },        /* IRQ5 */
+       { RCAR_GP_PIN(2,  4), PU1,  7 },        /* IRQ4 */
+       { RCAR_GP_PIN(2,  3), PU1,  6 },        /* IRQ3 */
+       { RCAR_GP_PIN(2,  2), PU1,  5 },        /* IRQ2 */
+       { RCAR_GP_PIN(2,  1), PU1,  4 },        /* IRQ1 */
+       { RCAR_GP_PIN(2,  0), PU1,  3 },        /* IRQ0 */
+       { RCAR_GP_PIN(2, 14), PU1,  2 },        /* AVB_AVTP_CAPTURE_A */
+       { RCAR_GP_PIN(2, 13), PU1,  1 },        /* AVB_AVTP_MATCH_A */
+       { RCAR_GP_PIN(2, 12), PU1,  0 },        /* AVB_LINK */
+
+       { RCAR_GP_PIN(7,  3), PU2, 29 },        /* HDMI1_CEC */
+       { RCAR_GP_PIN(7,  2), PU2, 28 },        /* HDMI0_CEC */
+       { RCAR_GP_PIN(7,  1), PU2, 27 },        /* AVS2 */
+       { RCAR_GP_PIN(7,  0), PU2, 26 },        /* AVS1 */
+       { RCAR_GP_PIN(0, 15), PU2, 25 },        /* D15 */
+       { RCAR_GP_PIN(0, 14), PU2, 24 },        /* D14 */
+       { RCAR_GP_PIN(0, 13), PU2, 23 },        /* D13 */
+       { RCAR_GP_PIN(0, 12), PU2, 22 },        /* D12 */
+       { RCAR_GP_PIN(0, 11), PU2, 21 },        /* D11 */
+       { RCAR_GP_PIN(0, 10), PU2, 20 },        /* D10 */
+       { RCAR_GP_PIN(0,  9), PU2, 19 },        /* D9 */
+       { RCAR_GP_PIN(0,  8), PU2, 18 },        /* D8 */
+       { RCAR_GP_PIN(0,  7), PU2, 17 },        /* D7 */
+       { RCAR_GP_PIN(0,  6), PU2, 16 },        /* D6 */
+       { RCAR_GP_PIN(0,  5), PU2, 15 },        /* D5 */
+       { RCAR_GP_PIN(0,  4), PU2, 14 },        /* D4 */
+       { RCAR_GP_PIN(0,  3), PU2, 13 },        /* D3 */
+       { RCAR_GP_PIN(0,  2), PU2, 12 },        /* D2 */
+       { RCAR_GP_PIN(0,  1), PU2, 11 },        /* D1 */
+       { RCAR_GP_PIN(0,  0), PU2, 10 },        /* D0 */
+       { RCAR_GP_PIN(1, 27), PU2,  8 },        /* EX_WAIT0_A */
+       { RCAR_GP_PIN(1, 26), PU2,  7 },        /* WE1_N */
+       { RCAR_GP_PIN(1, 25), PU2,  6 },        /* WE0_N */
+       { RCAR_GP_PIN(1, 24), PU2,  5 },        /* RD_WR_N */
+       { RCAR_GP_PIN(1, 23), PU2,  4 },        /* RD_N */
+       { RCAR_GP_PIN(1, 22), PU2,  3 },        /* BS_N */
+       { RCAR_GP_PIN(1, 21), PU2,  2 },        /* CS1_N_A26 */
+       { RCAR_GP_PIN(1, 20), PU2,  1 },        /* CS0_N */
+
+       { RCAR_GP_PIN(4,  9), PU3, 31 },        /* SD3_DAT0 */
+       { RCAR_GP_PIN(4,  8), PU3, 30 },        /* SD3_CMD */
+       { RCAR_GP_PIN(4,  7), PU3, 29 },        /* SD3_CLK */
+       { RCAR_GP_PIN(4,  6), PU3, 28 },        /* SD2_DS */
+       { RCAR_GP_PIN(4,  5), PU3, 27 },        /* SD2_DAT3 */
+       { RCAR_GP_PIN(4,  4), PU3, 26 },        /* SD2_DAT2 */
+       { RCAR_GP_PIN(4,  3), PU3, 25 },        /* SD2_DAT1 */
+       { RCAR_GP_PIN(4,  2), PU3, 24 },        /* SD2_DAT0 */
+       { RCAR_GP_PIN(4,  1), PU3, 23 },        /* SD2_CMD */
+       { RCAR_GP_PIN(4,  0), PU3, 22 },        /* SD2_CLK */
+       { RCAR_GP_PIN(3, 11), PU3, 21 },        /* SD1_DAT3 */
+       { RCAR_GP_PIN(3, 10), PU3, 20 },        /* SD1_DAT2 */
+       { RCAR_GP_PIN(3,  9), PU3, 19 },        /* SD1_DAT1 */
+       { RCAR_GP_PIN(3,  8), PU3, 18 },        /* SD1_DAT0 */
+       { RCAR_GP_PIN(3,  7), PU3, 17 },        /* SD1_CMD */
+       { RCAR_GP_PIN(3,  6), PU3, 16 },        /* SD1_CLK */
+       { RCAR_GP_PIN(3,  5), PU3, 15 },        /* SD0_DAT3 */
+       { RCAR_GP_PIN(3,  4), PU3, 14 },        /* SD0_DAT2 */
+       { RCAR_GP_PIN(3,  3), PU3, 13 },        /* SD0_DAT1 */
+       { RCAR_GP_PIN(3,  2), PU3, 12 },        /* SD0_DAT0 */
+       { RCAR_GP_PIN(3,  1), PU3, 11 },        /* SD0_CMD */
+       { RCAR_GP_PIN(3,  0), PU3, 10 },        /* SD0_CLK */
+
+       { RCAR_GP_PIN(5, 19), PU4, 31 },        /* MSIOF0_SS1 */
+       { RCAR_GP_PIN(5, 18), PU4, 30 },        /* MSIOF0_SYNC */
+       { RCAR_GP_PIN(5, 17), PU4, 29 },        /* MSIOF0_SCK */
+       { RCAR_GP_PIN(5, 16), PU4, 28 },        /* HRTS0_N */
+       { RCAR_GP_PIN(5, 15), PU4, 27 },        /* HCTS0_N */
+       { RCAR_GP_PIN(5, 14), PU4, 26 },        /* HTX0 */
+       { RCAR_GP_PIN(5, 13), PU4, 25 },        /* HRX0 */
+       { RCAR_GP_PIN(5, 12), PU4, 24 },        /* HSCK0 */
+       { RCAR_GP_PIN(5, 11), PU4, 23 },        /* RX2_A */
+       { RCAR_GP_PIN(5, 10), PU4, 22 },        /* TX2_A */
+       { RCAR_GP_PIN(5,  9), PU4, 21 },        /* SCK2 */
+       { RCAR_GP_PIN(5,  8), PU4, 20 },        /* RTS1_N_TANS */
+       { RCAR_GP_PIN(5,  7), PU4, 19 },        /* CTS1_N */
+       { RCAR_GP_PIN(5,  6), PU4, 18 },        /* TX1_A */
+       { RCAR_GP_PIN(5,  5), PU4, 17 },        /* RX1_A */
+       { RCAR_GP_PIN(5,  4), PU4, 16 },        /* RTS0_N_TANS */
+       { RCAR_GP_PIN(5,  3), PU4, 15 },        /* CTS0_N */
+       { RCAR_GP_PIN(5,  2), PU4, 14 },        /* TX0 */
+       { RCAR_GP_PIN(5,  1), PU4, 13 },        /* RX0 */
+       { RCAR_GP_PIN(5,  0), PU4, 12 },        /* SCK0 */
+       { RCAR_GP_PIN(3, 15), PU4, 11 },        /* SD1_WP */
+       { RCAR_GP_PIN(3, 14), PU4, 10 },        /* SD1_CD */
+       { RCAR_GP_PIN(3, 13), PU4,  9 },        /* SD0_WP */
+       { RCAR_GP_PIN(3, 12), PU4,  8 },        /* SD0_CD */
+       { RCAR_GP_PIN(4, 17), PU4,  7 },        /* SD3_DS */
+       { RCAR_GP_PIN(4, 16), PU4,  6 },        /* SD3_DAT7 */
+       { RCAR_GP_PIN(4, 15), PU4,  5 },        /* SD3_DAT6 */
+       { RCAR_GP_PIN(4, 14), PU4,  4 },        /* SD3_DAT5 */
+       { RCAR_GP_PIN(4, 13), PU4,  3 },        /* SD3_DAT4 */
+       { RCAR_GP_PIN(4, 12), PU4,  2 },        /* SD3_DAT3 */
+       { RCAR_GP_PIN(4, 11), PU4,  1 },        /* SD3_DAT2 */
+       { RCAR_GP_PIN(4, 10), PU4,  0 },        /* SD3_DAT1 */
+
+       { RCAR_GP_PIN(6, 24), PU5, 31 },        /* USB0_PWEN */
+       { RCAR_GP_PIN(6, 23), PU5, 30 },        /* AUDIO_CLKB_B */
+       { RCAR_GP_PIN(6, 22), PU5, 29 },        /* AUDIO_CLKA_A */
+       { RCAR_GP_PIN(6, 21), PU5, 28 },        /* SSI_SDATA9_A */
+       { RCAR_GP_PIN(6, 20), PU5, 27 },        /* SSI_SDATA8 */
+       { RCAR_GP_PIN(6, 19), PU5, 26 },        /* SSI_SDATA7 */
+       { RCAR_GP_PIN(6, 18), PU5, 25 },        /* SSI_WS78 */
+       { RCAR_GP_PIN(6, 17), PU5, 24 },        /* SSI_SCK78 */
+       { RCAR_GP_PIN(6, 16), PU5, 23 },        /* SSI_SDATA6 */
+       { RCAR_GP_PIN(6, 15), PU5, 22 },        /* SSI_WS6 */
+       { RCAR_GP_PIN(6, 14), PU5, 21 },        /* SSI_SCK6 */
+       { RCAR_GP_PIN(6, 13), PU5, 20 },        /* SSI_SDATA5 */
+       { RCAR_GP_PIN(6, 12), PU5, 19 },        /* SSI_WS5 */
+       { RCAR_GP_PIN(6, 11), PU5, 18 },        /* SSI_SCK5 */
+       { RCAR_GP_PIN(6, 10), PU5, 17 },        /* SSI_SDATA4 */
+       { RCAR_GP_PIN(6,  9), PU5, 16 },        /* SSI_WS4 */
+       { RCAR_GP_PIN(6,  8), PU5, 15 },        /* SSI_SCK4 */
+       { RCAR_GP_PIN(6,  7), PU5, 14 },        /* SSI_SDATA3 */
+       { RCAR_GP_PIN(6,  6), PU5, 13 },        /* SSI_WS34 */
+       { RCAR_GP_PIN(6,  5), PU5, 12 },        /* SSI_SCK34 */
+       { RCAR_GP_PIN(6,  4), PU5, 11 },        /* SSI_SDATA2_A */
+       { RCAR_GP_PIN(6,  3), PU5, 10 },        /* SSI_SDATA1_A */
+       { RCAR_GP_PIN(6,  2), PU5,  9 },        /* SSI_SDATA0 */
+       { RCAR_GP_PIN(6,  1), PU5,  8 },        /* SSI_WS01239 */
+       { RCAR_GP_PIN(6,  0), PU5,  7 },        /* SSI_SCK01239 */
+       { RCAR_GP_PIN(5, 25), PU5,  5 },        /* MLB_DAT */
+       { RCAR_GP_PIN(5, 24), PU5,  4 },        /* MLB_SIG */
+       { RCAR_GP_PIN(5, 23), PU5,  3 },        /* MLB_CLK */
+       { RCAR_GP_PIN(5, 22), PU5,  2 },        /* MSIOF0_RXD */
+       { RCAR_GP_PIN(5, 21), PU5,  1 },        /* MSIOF0_SS2 */
+       { RCAR_GP_PIN(5, 20), PU5,  0 },        /* MSIOF0_TXD */
+
+       { RCAR_GP_PIN(6, 31), PU6,  6 },        /* USB31_OVC */
+       { RCAR_GP_PIN(6, 30), PU6,  5 },        /* USB31_PWEN */
+       { RCAR_GP_PIN(6, 29), PU6,  4 },        /* USB30_OVC */
+       { RCAR_GP_PIN(6, 28), PU6,  3 },        /* USB30_PWEN */
+       { RCAR_GP_PIN(6, 27), PU6,  2 },        /* USB1_OVC */
+       { RCAR_GP_PIN(6, 26), PU6,  1 },        /* USB1_PWEN */
+       { RCAR_GP_PIN(6, 25), PU6,  0 },        /* USB0_OVC */
 };
 
 static unsigned int r8a7795_pinmux_get_bias(struct sh_pfc *pfc,
                                            unsigned int pin)
 {
+       const struct sh_pfc_bias_info *info;
        u32 reg;
        u32 bit;
 
-       if (WARN_ON_ONCE(!pullups[pin].reg))
+       info = sh_pfc_pin_to_bias_info(bias_info, ARRAY_SIZE(bias_info), pin);
+       if (!info)
                return PIN_CONFIG_BIAS_DISABLE;
 
-       reg = pullups[pin].reg;
-       bit = BIT(pullups[pin].bit);
+       reg = info->reg;
+       bit = BIT(info->bit);
 
-       if (sh_pfc_read_reg(pfc, PUEN + reg, 32) & bit) {
-               if (sh_pfc_read_reg(pfc, PUD + reg, 32) & bit)
-                       return PIN_CONFIG_BIAS_PULL_UP;
-               else
-                       return PIN_CONFIG_BIAS_PULL_DOWN;
-       } else
+       if (!(sh_pfc_read_reg(pfc, PUEN + reg, 32) & bit))
                return PIN_CONFIG_BIAS_DISABLE;
+       else if (sh_pfc_read_reg(pfc, PUD + reg, 32) & bit)
+               return PIN_CONFIG_BIAS_PULL_UP;
+       else
+               return PIN_CONFIG_BIAS_PULL_DOWN;
 }
 
 static void r8a7795_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
                                   unsigned int bias)
 {
+       const struct sh_pfc_bias_info *info;
        u32 enable, updown;
        u32 reg;
        u32 bit;
 
-       if (WARN_ON_ONCE(!pullups[pin].reg))
+       info = sh_pfc_pin_to_bias_info(bias_info, ARRAY_SIZE(bias_info), pin);
+       if (!info)
                return;
 
-       reg = pullups[pin].reg;
-       bit = BIT(pullups[pin].bit);
+       reg = info->reg;
+       bit = BIT(info->bit);
 
        enable = sh_pfc_read_reg(pfc, PUEN + reg, 32) & ~bit;
        if (bias != PIN_CONFIG_BIAS_DISABLE)
index dc9b671ccf2e51261d26becbbe32572de67b6b2e..7e16545a2c3c9db82d4f8777ecca5b733af9a21f 100644 (file)
 #define GPSR3_0                F_(SD0_CLK,             IP7_19_16)
 
 /* GPSR4 */
-#define GPSR4_17       F_(SD3_DS,              IP11_11_8)
-#define GPSR4_16       F_(SD3_DAT7,            IP10_7_4)
-#define GPSR4_15       F_(SD3_DAT6,            IP10_3_0)
-#define GPSR4_14       F_(SD3_DAT5,            IP9_31_28)
-#define GPSR4_13       F_(SD3_DAT4,            IP9_27_24)
+#define GPSR4_17       F_(SD3_DS,              IP11_7_4)
+#define GPSR4_16       F_(SD3_DAT7,            IP11_3_0)
+#define GPSR4_15       F_(SD3_DAT6,            IP10_31_28)
+#define GPSR4_14       F_(SD3_DAT5,            IP10_27_24)
+#define GPSR4_13       F_(SD3_DAT4,            IP10_23_20)
 #define GPSR4_12       F_(SD3_DAT3,            IP10_19_16)
 #define GPSR4_11       F_(SD3_DAT2,            IP10_15_12)
 #define GPSR4_10       F_(SD3_DAT1,            IP10_11_8)
 #define GPSR4_9                F_(SD3_DAT0,            IP10_7_4)
 #define GPSR4_8                F_(SD3_CMD,             IP10_3_0)
 #define GPSR4_7                F_(SD3_CLK,             IP9_31_28)
-#define GPSR4_6                F_(SD2_DS,              IP9_23_20)
-#define GPSR4_5                F_(SD2_DAT3,            IP9_19_16)
-#define GPSR4_4                F_(SD2_DAT2,            IP9_15_12)
-#define GPSR4_3                F_(SD2_DAT1,            IP9_11_8)
-#define GPSR4_2                F_(SD2_DAT0,            IP9_7_4)
+#define GPSR4_6                F_(SD2_DS,              IP9_27_24)
+#define GPSR4_5                F_(SD2_DAT3,            IP9_23_20)
+#define GPSR4_4                F_(SD2_DAT2,            IP9_19_16)
+#define GPSR4_3                F_(SD2_DAT1,            IP9_15_12)
+#define GPSR4_2                F_(SD2_DAT0,            IP9_11_8)
 #define GPSR4_1                F_(SD2_CMD,             IP9_7_4)
 #define GPSR4_0                F_(SD2_CLK,             IP9_3_0)
 
@@ -1490,6 +1490,418 @@ static const struct sh_pfc_pin pinmux_pins[] = {
        PINMUX_GPIO_GP_ALL(),
 };
 
+/* - EtherAVB --------------------------------------------------------------- */
+static const unsigned int avb_link_pins[] = {
+       /* AVB_LINK */
+       RCAR_GP_PIN(2, 12),
+};
+static const unsigned int avb_link_mux[] = {
+       AVB_LINK_MARK,
+};
+static const unsigned int avb_magic_pins[] = {
+       /* AVB_MAGIC_ */
+       RCAR_GP_PIN(2, 10),
+};
+static const unsigned int avb_magic_mux[] = {
+       AVB_MAGIC_MARK,
+};
+static const unsigned int avb_phy_int_pins[] = {
+       /* AVB_PHY_INT */
+       RCAR_GP_PIN(2, 11),
+};
+static const unsigned int avb_phy_int_mux[] = {
+       AVB_PHY_INT_MARK,
+};
+static const unsigned int avb_mdc_pins[] = {
+       /* AVB_MDC */
+       RCAR_GP_PIN(2, 9),
+};
+static const unsigned int avb_mdc_mux[] = {
+       AVB_MDC_MARK,
+};
+static const unsigned int avb_avtp_pps_pins[] = {
+       /* AVB_AVTP_PPS */
+       RCAR_GP_PIN(2, 6),
+};
+static const unsigned int avb_avtp_pps_mux[] = {
+       AVB_AVTP_PPS_MARK,
+};
+static const unsigned int avb_avtp_match_a_pins[] = {
+       /* AVB_AVTP_MATCH_A */
+       RCAR_GP_PIN(2, 13),
+};
+static const unsigned int avb_avtp_match_a_mux[] = {
+       AVB_AVTP_MATCH_A_MARK,
+};
+static const unsigned int avb_avtp_capture_a_pins[] = {
+       /* AVB_AVTP_CAPTURE_A */
+       RCAR_GP_PIN(2, 14),
+};
+static const unsigned int avb_avtp_capture_a_mux[] = {
+       AVB_AVTP_CAPTURE_A_MARK,
+};
+static const unsigned int avb_avtp_match_b_pins[] = {
+       /*  AVB_AVTP_MATCH_B */
+       RCAR_GP_PIN(1, 8),
+};
+static const unsigned int avb_avtp_match_b_mux[] = {
+       AVB_AVTP_MATCH_B_MARK,
+};
+static const unsigned int avb_avtp_capture_b_pins[] = {
+       /* AVB_AVTP_CAPTURE_B */
+       RCAR_GP_PIN(1, 11),
+};
+static const unsigned int avb_avtp_capture_b_mux[] = {
+       AVB_AVTP_CAPTURE_B_MARK,
+};
+
+/* - DRIF0 --------------------------------------------------------------- */
+static const unsigned int drif0_ctrl_a_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9),
+};
+static const unsigned int drif0_ctrl_a_mux[] = {
+       RIF0_CLK_A_MARK, RIF0_SYNC_A_MARK,
+};
+static const unsigned int drif0_data0_a_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(6, 10),
+};
+static const unsigned int drif0_data0_a_mux[] = {
+       RIF0_D0_A_MARK,
+};
+static const unsigned int drif0_data1_a_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(6, 7),
+};
+static const unsigned int drif0_data1_a_mux[] = {
+       RIF0_D1_A_MARK,
+};
+static const unsigned int drif0_ctrl_b_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 4),
+};
+static const unsigned int drif0_ctrl_b_mux[] = {
+       RIF0_CLK_B_MARK, RIF0_SYNC_B_MARK,
+};
+static const unsigned int drif0_data0_b_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(5, 1),
+};
+static const unsigned int drif0_data0_b_mux[] = {
+       RIF0_D0_B_MARK,
+};
+static const unsigned int drif0_data1_b_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(5, 2),
+};
+static const unsigned int drif0_data1_b_mux[] = {
+       RIF0_D1_B_MARK,
+};
+static const unsigned int drif0_ctrl_c_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(5, 12), RCAR_GP_PIN(5, 15),
+};
+static const unsigned int drif0_ctrl_c_mux[] = {
+       RIF0_CLK_C_MARK, RIF0_SYNC_C_MARK,
+};
+static const unsigned int drif0_data0_c_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(5, 13),
+};
+static const unsigned int drif0_data0_c_mux[] = {
+       RIF0_D0_C_MARK,
+};
+static const unsigned int drif0_data1_c_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(5, 14),
+};
+static const unsigned int drif0_data1_c_mux[] = {
+       RIF0_D1_C_MARK,
+};
+/* - DRIF1 --------------------------------------------------------------- */
+static const unsigned int drif1_ctrl_a_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18),
+};
+static const unsigned int drif1_ctrl_a_mux[] = {
+       RIF1_CLK_A_MARK, RIF1_SYNC_A_MARK,
+};
+static const unsigned int drif1_data0_a_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(6, 19),
+};
+static const unsigned int drif1_data0_a_mux[] = {
+       RIF1_D0_A_MARK,
+};
+static const unsigned int drif1_data1_a_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(6, 20),
+};
+static const unsigned int drif1_data1_a_mux[] = {
+       RIF1_D1_A_MARK,
+};
+static const unsigned int drif1_ctrl_b_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 3),
+};
+static const unsigned int drif1_ctrl_b_mux[] = {
+       RIF1_CLK_B_MARK, RIF1_SYNC_B_MARK,
+};
+static const unsigned int drif1_data0_b_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(5, 7),
+};
+static const unsigned int drif1_data0_b_mux[] = {
+       RIF1_D0_B_MARK,
+};
+static const unsigned int drif1_data1_b_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(5, 8),
+};
+static const unsigned int drif1_data1_b_mux[] = {
+       RIF1_D1_B_MARK,
+};
+static const unsigned int drif1_ctrl_c_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 11),
+};
+static const unsigned int drif1_ctrl_c_mux[] = {
+       RIF1_CLK_C_MARK, RIF1_SYNC_C_MARK,
+};
+static const unsigned int drif1_data0_c_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(5, 6),
+};
+static const unsigned int drif1_data0_c_mux[] = {
+       RIF1_D0_C_MARK,
+};
+static const unsigned int drif1_data1_c_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(5, 10),
+};
+static const unsigned int drif1_data1_c_mux[] = {
+       RIF1_D1_C_MARK,
+};
+/* - DRIF2 --------------------------------------------------------------- */
+static const unsigned int drif2_ctrl_a_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9),
+};
+static const unsigned int drif2_ctrl_a_mux[] = {
+       RIF2_CLK_A_MARK, RIF2_SYNC_A_MARK,
+};
+static const unsigned int drif2_data0_a_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(6, 7),
+};
+static const unsigned int drif2_data0_a_mux[] = {
+       RIF2_D0_A_MARK,
+};
+static const unsigned int drif2_data1_a_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(6, 10),
+};
+static const unsigned int drif2_data1_a_mux[] = {
+       RIF2_D1_A_MARK,
+};
+static const unsigned int drif2_ctrl_b_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(6, 26), RCAR_GP_PIN(6, 27),
+};
+static const unsigned int drif2_ctrl_b_mux[] = {
+       RIF2_CLK_B_MARK, RIF2_SYNC_B_MARK,
+};
+static const unsigned int drif2_data0_b_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(6, 30),
+};
+static const unsigned int drif2_data0_b_mux[] = {
+       RIF2_D0_B_MARK,
+};
+static const unsigned int drif2_data1_b_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(6, 31),
+};
+static const unsigned int drif2_data1_b_mux[] = {
+       RIF2_D1_B_MARK,
+};
+/* - DRIF3 --------------------------------------------------------------- */
+static const unsigned int drif3_ctrl_a_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18),
+};
+static const unsigned int drif3_ctrl_a_mux[] = {
+       RIF3_CLK_A_MARK, RIF3_SYNC_A_MARK,
+};
+static const unsigned int drif3_data0_a_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(6, 19),
+};
+static const unsigned int drif3_data0_a_mux[] = {
+       RIF3_D0_A_MARK,
+};
+static const unsigned int drif3_data1_a_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(6, 20),
+};
+static const unsigned int drif3_data1_a_mux[] = {
+       RIF3_D1_A_MARK,
+};
+static const unsigned int drif3_ctrl_b_pins[] = {
+       /* CLK, SYNC */
+       RCAR_GP_PIN(6, 24), RCAR_GP_PIN(6, 25),
+};
+static const unsigned int drif3_ctrl_b_mux[] = {
+       RIF3_CLK_B_MARK, RIF3_SYNC_B_MARK,
+};
+static const unsigned int drif3_data0_b_pins[] = {
+       /* D0 */
+       RCAR_GP_PIN(6, 28),
+};
+static const unsigned int drif3_data0_b_mux[] = {
+       RIF3_D0_B_MARK,
+};
+static const unsigned int drif3_data1_b_pins[] = {
+       /* D1 */
+       RCAR_GP_PIN(6, 29),
+};
+static const unsigned int drif3_data1_b_mux[] = {
+       RIF3_D1_B_MARK,
+};
+
+/* - DU --------------------------------------------------------------------- */
+static const unsigned int du_rgb666_pins[] = {
+       /* R[7:2], G[7:2], B[7:2] */
+       RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13),
+       RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
+       RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
+       RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
+       RCAR_GP_PIN(1, 7),  RCAR_GP_PIN(1, 6),  RCAR_GP_PIN(1, 5),
+       RCAR_GP_PIN(1, 4),  RCAR_GP_PIN(1, 3),  RCAR_GP_PIN(1, 2),
+};
+static const unsigned int du_rgb666_mux[] = {
+       DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK,
+       DU_DR3_MARK, DU_DR2_MARK,
+       DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK,
+       DU_DG3_MARK, DU_DG2_MARK,
+       DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK,
+       DU_DB3_MARK, DU_DB2_MARK,
+};
+static const unsigned int du_rgb888_pins[] = {
+       /* R[7:0], G[7:0], B[7:0] */
+       RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13),
+       RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
+       RCAR_GP_PIN(0, 9),  RCAR_GP_PIN(0, 8),
+       RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
+       RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
+       RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 16),
+       RCAR_GP_PIN(1, 7),  RCAR_GP_PIN(1, 6),  RCAR_GP_PIN(1, 5),
+       RCAR_GP_PIN(1, 4),  RCAR_GP_PIN(1, 3),  RCAR_GP_PIN(1, 2),
+       RCAR_GP_PIN(1, 1),  RCAR_GP_PIN(1, 0),
+};
+static const unsigned int du_rgb888_mux[] = {
+       DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK,
+       DU_DR3_MARK, DU_DR2_MARK, DU_DR1_MARK, DU_DR0_MARK,
+       DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK,
+       DU_DG3_MARK, DU_DG2_MARK, DU_DG1_MARK, DU_DG0_MARK,
+       DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK,
+       DU_DB3_MARK, DU_DB2_MARK, DU_DB1_MARK, DU_DB0_MARK,
+};
+static const unsigned int du_clk_out_0_pins[] = {
+       /* CLKOUT */
+       RCAR_GP_PIN(1, 27),
+};
+static const unsigned int du_clk_out_0_mux[] = {
+       DU_DOTCLKOUT0_MARK
+};
+static const unsigned int du_clk_out_1_pins[] = {
+       /* CLKOUT */
+       RCAR_GP_PIN(2, 3),
+};
+static const unsigned int du_clk_out_1_mux[] = {
+       DU_DOTCLKOUT1_MARK
+};
+static const unsigned int du_sync_pins[] = {
+       /* EXVSYNC/VSYNC, EXHSYNC/HSYNC */
+       RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 4),
+};
+static const unsigned int du_sync_mux[] = {
+       DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK
+};
+static const unsigned int du_oddf_pins[] = {
+       /* EXDISP/EXODDF/EXCDE */
+       RCAR_GP_PIN(2, 2),
+};
+static const unsigned int du_oddf_mux[] = {
+       DU_EXODDF_DU_ODDF_DISP_CDE_MARK,
+};
+static const unsigned int du_cde_pins[] = {
+       /* CDE */
+       RCAR_GP_PIN(2, 0),
+};
+static const unsigned int du_cde_mux[] = {
+       DU_CDE_MARK,
+};
+static const unsigned int du_disp_pins[] = {
+       /* DISP */
+       RCAR_GP_PIN(2, 1),
+};
+static const unsigned int du_disp_mux[] = {
+       DU_DISP_MARK,
+};
+
+/* - I2C -------------------------------------------------------------------- */
+static const unsigned int i2c1_a_pins[] = {
+       /* SDA, SCL */
+       RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 10),
+};
+static const unsigned int i2c1_a_mux[] = {
+       SDA1_A_MARK, SCL1_A_MARK,
+};
+static const unsigned int i2c1_b_pins[] = {
+       /* SDA, SCL */
+       RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 23),
+};
+static const unsigned int i2c1_b_mux[] = {
+       SDA1_B_MARK, SCL1_B_MARK,
+};
+static const unsigned int i2c2_a_pins[] = {
+       /* SDA, SCL */
+       RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 4),
+};
+static const unsigned int i2c2_a_mux[] = {
+       SDA2_A_MARK, SCL2_A_MARK,
+};
+static const unsigned int i2c2_b_pins[] = {
+       /* SDA, SCL */
+       RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 12),
+};
+static const unsigned int i2c2_b_mux[] = {
+       SDA2_B_MARK, SCL2_B_MARK,
+};
+static const unsigned int i2c6_a_pins[] = {
+       /* SDA, SCL */
+       RCAR_GP_PIN(1, 8), RCAR_GP_PIN(1, 11),
+};
+static const unsigned int i2c6_a_mux[] = {
+       SDA6_A_MARK, SCL6_A_MARK,
+};
+static const unsigned int i2c6_b_pins[] = {
+       /* SDA, SCL */
+       RCAR_GP_PIN(1, 26), RCAR_GP_PIN(1, 25),
+};
+static const unsigned int i2c6_b_mux[] = {
+       SDA6_B_MARK, SCL6_B_MARK,
+};
+static const unsigned int i2c6_c_pins[] = {
+       /* SDA, SCL */
+       RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14),
+};
+static const unsigned int i2c6_c_mux[] = {
+       SDA6_C_MARK, SCL6_C_MARK,
+};
+
 /* - SCIF0 ------------------------------------------------------------------ */
 static const unsigned int scif0_data_pins[] = {
        /* RX, TX */
@@ -1912,6 +2324,60 @@ static const unsigned int sdhi3_ds_mux[] = {
 };
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
+       SH_PFC_PIN_GROUP(avb_link),
+       SH_PFC_PIN_GROUP(avb_magic),
+       SH_PFC_PIN_GROUP(avb_phy_int),
+       SH_PFC_PIN_GROUP(avb_mdc),
+       SH_PFC_PIN_GROUP(avb_avtp_pps),
+       SH_PFC_PIN_GROUP(avb_avtp_match_a),
+       SH_PFC_PIN_GROUP(avb_avtp_capture_a),
+       SH_PFC_PIN_GROUP(avb_avtp_match_b),
+       SH_PFC_PIN_GROUP(avb_avtp_capture_b),
+       SH_PFC_PIN_GROUP(drif0_ctrl_a),
+       SH_PFC_PIN_GROUP(drif0_data0_a),
+       SH_PFC_PIN_GROUP(drif0_data1_a),
+       SH_PFC_PIN_GROUP(drif0_ctrl_b),
+       SH_PFC_PIN_GROUP(drif0_data0_b),
+       SH_PFC_PIN_GROUP(drif0_data1_b),
+       SH_PFC_PIN_GROUP(drif0_ctrl_c),
+       SH_PFC_PIN_GROUP(drif0_data0_c),
+       SH_PFC_PIN_GROUP(drif0_data1_c),
+       SH_PFC_PIN_GROUP(drif1_ctrl_a),
+       SH_PFC_PIN_GROUP(drif1_data0_a),
+       SH_PFC_PIN_GROUP(drif1_data1_a),
+       SH_PFC_PIN_GROUP(drif1_ctrl_b),
+       SH_PFC_PIN_GROUP(drif1_data0_b),
+       SH_PFC_PIN_GROUP(drif1_data1_b),
+       SH_PFC_PIN_GROUP(drif1_ctrl_c),
+       SH_PFC_PIN_GROUP(drif1_data0_c),
+       SH_PFC_PIN_GROUP(drif1_data1_c),
+       SH_PFC_PIN_GROUP(drif2_ctrl_a),
+       SH_PFC_PIN_GROUP(drif2_data0_a),
+       SH_PFC_PIN_GROUP(drif2_data1_a),
+       SH_PFC_PIN_GROUP(drif2_ctrl_b),
+       SH_PFC_PIN_GROUP(drif2_data0_b),
+       SH_PFC_PIN_GROUP(drif2_data1_b),
+       SH_PFC_PIN_GROUP(drif3_ctrl_a),
+       SH_PFC_PIN_GROUP(drif3_data0_a),
+       SH_PFC_PIN_GROUP(drif3_data1_a),
+       SH_PFC_PIN_GROUP(drif3_ctrl_b),
+       SH_PFC_PIN_GROUP(drif3_data0_b),
+       SH_PFC_PIN_GROUP(drif3_data1_b),
+       SH_PFC_PIN_GROUP(du_rgb666),
+       SH_PFC_PIN_GROUP(du_rgb888),
+       SH_PFC_PIN_GROUP(du_clk_out_0),
+       SH_PFC_PIN_GROUP(du_clk_out_1),
+       SH_PFC_PIN_GROUP(du_sync),
+       SH_PFC_PIN_GROUP(du_oddf),
+       SH_PFC_PIN_GROUP(du_cde),
+       SH_PFC_PIN_GROUP(du_disp),
+       SH_PFC_PIN_GROUP(i2c1_a),
+       SH_PFC_PIN_GROUP(i2c1_b),
+       SH_PFC_PIN_GROUP(i2c2_a),
+       SH_PFC_PIN_GROUP(i2c2_b),
+       SH_PFC_PIN_GROUP(i2c6_a),
+       SH_PFC_PIN_GROUP(i2c6_b),
+       SH_PFC_PIN_GROUP(i2c6_c),
        SH_PFC_PIN_GROUP(scif0_data),
        SH_PFC_PIN_GROUP(scif0_clk),
        SH_PFC_PIN_GROUP(scif0_ctrl),
@@ -1969,6 +2435,87 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(sdhi3_ds),
 };
 
+static const char * const avb_groups[] = {
+       "avb_link",
+       "avb_magic",
+       "avb_phy_int",
+       "avb_mdc",
+       "avb_avtp_pps",
+       "avb_avtp_match_a",
+       "avb_avtp_capture_a",
+       "avb_avtp_match_b",
+       "avb_avtp_capture_b",
+};
+
+static const char * const drif0_groups[] = {
+       "drif0_ctrl_a",
+       "drif0_data0_a",
+       "drif0_data1_a",
+       "drif0_ctrl_b",
+       "drif0_data0_b",
+       "drif0_data1_b",
+       "drif0_ctrl_c",
+       "drif0_data0_c",
+       "drif0_data1_c",
+};
+
+static const char * const drif1_groups[] = {
+       "drif1_ctrl_a",
+       "drif1_data0_a",
+       "drif1_data1_a",
+       "drif1_ctrl_b",
+       "drif1_data0_b",
+       "drif1_data1_b",
+       "drif1_ctrl_c",
+       "drif1_data0_c",
+       "drif1_data1_c",
+};
+
+static const char * const drif2_groups[] = {
+       "drif2_ctrl_a",
+       "drif2_data0_a",
+       "drif2_data1_a",
+       "drif2_ctrl_b",
+       "drif2_data0_b",
+       "drif2_data1_b",
+};
+
+static const char * const drif3_groups[] = {
+       "drif3_ctrl_a",
+       "drif3_data0_a",
+       "drif3_data1_a",
+       "drif3_ctrl_b",
+       "drif3_data0_b",
+       "drif3_data1_b",
+};
+
+static const char * const du_groups[] = {
+       "du_rgb666",
+       "du_rgb888",
+       "du_clk_out_0",
+       "du_clk_out_1",
+       "du_sync",
+       "du_oddf",
+       "du_cde",
+       "du_disp",
+};
+
+static const char * const i2c1_groups[] = {
+       "i2c1_a",
+       "i2c1_b",
+};
+
+static const char * const i2c2_groups[] = {
+       "i2c2_a",
+       "i2c2_b",
+};
+
+static const char * const i2c6_groups[] = {
+       "i2c6_a",
+       "i2c6_b",
+       "i2c6_c",
+};
+
 static const char * const scif0_groups[] = {
        "scif0_data",
        "scif0_clk",
@@ -2058,6 +2605,15 @@ static const char * const sdhi3_groups[] = {
 };
 
 static const struct sh_pfc_function pinmux_functions[] = {
+       SH_PFC_FUNCTION(avb),
+       SH_PFC_FUNCTION(drif0),
+       SH_PFC_FUNCTION(drif1),
+       SH_PFC_FUNCTION(drif2),
+       SH_PFC_FUNCTION(drif3),
+       SH_PFC_FUNCTION(du),
+       SH_PFC_FUNCTION(i2c1),
+       SH_PFC_FUNCTION(i2c2),
+       SH_PFC_FUNCTION(i2c6),
        SH_PFC_FUNCTION(scif0),
        SH_PFC_FUNCTION(scif1),
        SH_PFC_FUNCTION(scif2),
index c5772584594ce3c48686f5df0315586dc2e9f8b2..fcacfa73ef6e9b657fb043186fcd6c9cd0d2dfeb 100644 (file)
@@ -570,7 +570,8 @@ static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin,
 
        switch (param) {
        case PIN_CONFIG_BIAS_DISABLE:
-               return true;
+               return pin->configs &
+                       (SH_PFC_PIN_CFG_PULL_UP | SH_PFC_PIN_CFG_PULL_DOWN);
 
        case PIN_CONFIG_BIAS_PULL_UP:
                return pin->configs & SH_PFC_PIN_CFG_PULL_UP;
index 2345421103db342e537187380f088240e3b1bf59..e42cc7a8d10ee75c0af30bb6cc200c9a31f5d3e1 100644 (file)
@@ -189,6 +189,12 @@ struct sh_pfc_window {
        unsigned long size;
 };
 
+struct sh_pfc_bias_info {
+       u16 pin;
+       u16 reg : 11;
+       u16 bit : 5;
+};
+
 struct sh_pfc_pin_range;
 
 struct sh_pfc {
@@ -540,6 +546,14 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info;
                .configs = SH_PFC_PIN_CFG_NO_GPIO,                      \
        }
 
+/* SH_PFC_PIN_NAMED_CFG - Expand to a sh_pfc_pin entry with the given name */
+#define SH_PFC_PIN_NAMED_CFG(row, col, _name, cfgs)                    \
+       {                                                               \
+               .pin = PIN_NUMBER(row, col),                            \
+               .name = __stringify(PIN_##_name),                       \
+               .configs = SH_PFC_PIN_CFG_NO_GPIO | cfgs,               \
+       }
+
 /* PINMUX_DATA_ALL - Expand to a list of PORT_name_DATA, PORT_name_FN0,
  *                  PORT_name_OUT, PORT_name_IN marks
  */
index e9b15dc0654bc67371e2f1967350b560cd78a508..990b867b96254b59f748c87b27355384833bdf58 100644 (file)
@@ -1584,8 +1584,4 @@ static struct platform_driver stm32f429_pinctrl_driver = {
        },
 };
 
-static int __init stm32f429_pinctrl_init(void)
-{
-       return platform_driver_register(&stm32f429_pinctrl_driver);
-}
-device_initcall(stm32f429_pinctrl_init);
+builtin_platform_driver(stm32f429_pinctrl_driver);
index 2904d2b7378b98195841cbcb6ae61b9125910fbc..2f232c3a057950ed9d89fabd00b003f46535b4e8 100644 (file)
@@ -12,7 +12,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -525,7 +525,6 @@ static const struct of_device_id sun5i_gr8_pinctrl_match[] = {
        { .compatible = "nextthing,gr8-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun5i_gr8_pinctrl_match);
 
 static struct platform_driver sun5i_gr8_pinctrl_driver = {
        .probe  = sun5i_gr8_pinctrl_probe,
@@ -534,8 +533,4 @@ static struct platform_driver sun5i_gr8_pinctrl_driver = {
                .of_match_table = sun5i_gr8_pinctrl_match,
        },
 };
-module_platform_driver(sun5i_gr8_pinctrl_driver);
-
-MODULE_AUTHOR("Mylene Josserand <mylene.josserand@free-electrons.com");
-MODULE_DESCRIPTION("NextThing GR8 pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun5i_gr8_pinctrl_driver);
index 862a096c5dbae3544d036e950887920b6b0105d9..fb30b86a97ee6a2083f0dadea78d26d83e13ed57 100644 (file)
@@ -10,7 +10,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -1035,7 +1035,6 @@ static const struct of_device_id sun4i_a10_pinctrl_match[] = {
        { .compatible = "allwinner,sun4i-a10-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun4i_a10_pinctrl_match);
 
 static struct platform_driver sun4i_a10_pinctrl_driver = {
        .probe  = sun4i_a10_pinctrl_probe,
@@ -1044,8 +1043,4 @@ static struct platform_driver sun4i_a10_pinctrl_driver = {
                .of_match_table = sun4i_a10_pinctrl_match,
        },
 };
-module_platform_driver(sun4i_a10_pinctrl_driver);
-
-MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
-MODULE_DESCRIPTION("Allwinner A10 pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun4i_a10_pinctrl_driver);
index f9a3f8f446f76afe28177d5f9dcb8b8376b0310b..a5b57fdff9e11f555467f47ee53f1b28ab808a6d 100644 (file)
@@ -10,7 +10,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -674,7 +674,6 @@ static const struct of_device_id sun5i_a10s_pinctrl_match[] = {
        { .compatible = "allwinner,sun5i-a10s-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun5i_a10s_pinctrl_match);
 
 static struct platform_driver sun5i_a10s_pinctrl_driver = {
        .probe  = sun5i_a10s_pinctrl_probe,
@@ -683,8 +682,4 @@ static struct platform_driver sun5i_a10s_pinctrl_driver = {
                .of_match_table = sun5i_a10s_pinctrl_match,
        },
 };
-module_platform_driver(sun5i_a10s_pinctrl_driver);
-
-MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
-MODULE_DESCRIPTION("Allwinner A10s pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun5i_a10s_pinctrl_driver);
index 2bb07b38834f743b7705af3d816803567064311f..8575f3f6d3ddf2b5525d2fcc72d8aac66be467a6 100644 (file)
@@ -10,7 +10,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -392,7 +392,6 @@ static const struct of_device_id sun5i_a13_pinctrl_match[] = {
        { .compatible = "allwinner,sun5i-a13-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun5i_a13_pinctrl_match);
 
 static struct platform_driver sun5i_a13_pinctrl_driver = {
        .probe  = sun5i_a13_pinctrl_probe,
@@ -401,8 +400,4 @@ static struct platform_driver sun5i_a13_pinctrl_driver = {
                .of_match_table = sun5i_a13_pinctrl_match,
        },
 };
-module_platform_driver(sun5i_a13_pinctrl_driver);
-
-MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
-MODULE_DESCRIPTION("Allwinner A13 pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun5i_a13_pinctrl_driver);
index d4bc4f0e8be02814473b67bdcc724fa7676fe430..a22bd88a1f03ebf5b7533df7bebd3d5cf3f3c597 100644 (file)
@@ -12,7 +12,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -136,7 +136,6 @@ static const struct of_device_id sun6i_a31_r_pinctrl_match[] = {
        { .compatible = "allwinner,sun6i-a31-r-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun6i_a31_r_pinctrl_match);
 
 static struct platform_driver sun6i_a31_r_pinctrl_driver = {
        .probe  = sun6i_a31_r_pinctrl_probe,
@@ -145,9 +144,4 @@ static struct platform_driver sun6i_a31_r_pinctrl_driver = {
                .of_match_table = sun6i_a31_r_pinctrl_match,
        },
 };
-module_platform_driver(sun6i_a31_r_pinctrl_driver);
-
-MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com");
-MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
-MODULE_DESCRIPTION("Allwinner A31 R_PIO pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun6i_a31_r_pinctrl_driver);
index a70b52957e24be9d760425732538f548ddf0e191..9e58926bef37f4f28a6b2ee520a6ff7137a8147d 100644 (file)
@@ -10,7 +10,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -934,7 +934,6 @@ static const struct of_device_id sun6i_a31_pinctrl_match[] = {
        { .compatible = "allwinner,sun6i-a31-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun6i_a31_pinctrl_match);
 
 static struct platform_driver sun6i_a31_pinctrl_driver = {
        .probe  = sun6i_a31_pinctrl_probe,
@@ -943,8 +942,4 @@ static struct platform_driver sun6i_a31_pinctrl_driver = {
                .of_match_table = sun6i_a31_pinctrl_match,
        },
 };
-module_platform_driver(sun6i_a31_pinctrl_driver);
-
-MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
-MODULE_DESCRIPTION("Allwinner A31 pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun6i_a31_pinctrl_driver);
index e570d5c93ecc87fa1327e10b17475193e97e464f..231a746a53568ac10728052eb0ad39101fb596c6 100644 (file)
@@ -11,7 +11,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -798,7 +798,6 @@ static const struct of_device_id sun6i_a31s_pinctrl_match[] = {
        { .compatible = "allwinner,sun6i-a31s-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun6i_a31s_pinctrl_match);
 
 static struct platform_driver sun6i_a31s_pinctrl_driver = {
        .probe  = sun6i_a31s_pinctrl_probe,
@@ -807,8 +806,4 @@ static struct platform_driver sun6i_a31s_pinctrl_driver = {
                .of_match_table = sun6i_a31s_pinctrl_match,
        },
 };
-module_platform_driver(sun6i_a31s_pinctrl_driver);
-
-MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("Allwinner A31s pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun6i_a31s_pinctrl_driver);
index 435ad30f45dbf7a46ac8ff299efe66f60b4e405e..b6f4c68ffb39eac5bdf821b35c2c7767a49a23d3 100644 (file)
@@ -10,7 +10,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -1045,7 +1045,6 @@ static const struct of_device_id sun7i_a20_pinctrl_match[] = {
        { .compatible = "allwinner,sun7i-a20-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun7i_a20_pinctrl_match);
 
 static struct platform_driver sun7i_a20_pinctrl_driver = {
        .probe  = sun7i_a20_pinctrl_probe,
@@ -1054,8 +1053,4 @@ static struct platform_driver sun7i_a20_pinctrl_driver = {
                .of_match_table = sun7i_a20_pinctrl_match,
        },
 };
-module_platform_driver(sun7i_a20_pinctrl_driver);
-
-MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
-MODULE_DESCRIPTION("Allwinner A20 pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun7i_a20_pinctrl_driver);
index 05628763587335b7e8c1a1689bd937fd723d8cbe..2292e05a397b4686e1b115e9de6df88c3d34c1e6 100644 (file)
@@ -15,7 +15,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -123,7 +123,6 @@ static const 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,
@@ -132,10 +131,4 @@ static struct platform_driver sun8i_a23_r_pinctrl_driver = {
                .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");
+builtin_platform_driver(sun8i_a23_r_pinctrl_driver);
index f9d661e5c14abb56c94493f29d0f028ba9b1b078..721b6935baf308820f74705e1de7a4ba8f889f1e 100644 (file)
@@ -14,7 +14,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -575,7 +575,6 @@ static const 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,
@@ -584,9 +583,4 @@ static struct platform_driver sun8i_a23_pinctrl_driver = {
                .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");
+builtin_platform_driver(sun8i_a23_pinctrl_driver);
index 3131cac2b76ffcc830948fbff94ed4ad57669c84..ef1e0bef4099f95c2651a8bdce6803d0cea13235 100644 (file)
@@ -12,7 +12,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -498,7 +498,6 @@ static const struct of_device_id sun8i_a33_pinctrl_match[] = {
        { .compatible = "allwinner,sun8i-a33-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun8i_a33_pinctrl_match);
 
 static struct platform_driver sun8i_a33_pinctrl_driver = {
        .probe  = sun8i_a33_pinctrl_probe,
@@ -507,8 +506,4 @@ static struct platform_driver sun8i_a33_pinctrl_driver = {
                .of_match_table = sun8i_a33_pinctrl_match,
        },
 };
-module_platform_driver(sun8i_a33_pinctrl_driver);
-
-MODULE_AUTHOR("Vishnu Patekar <vishnupatekar0510@gmail.com>");
-MODULE_DESCRIPTION("Allwinner a33 pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun8i_a33_pinctrl_driver);
index 90b973e159821c5889d95e58513bb04661bf8ff5..9aec1d2232dd830e2c19a8e1e394e6033e621c21 100644 (file)
@@ -12,7 +12,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -587,7 +587,6 @@ static const struct of_device_id sun8i_a83t_pinctrl_match[] = {
        { .compatible = "allwinner,sun8i-a83t-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun8i_a83t_pinctrl_match);
 
 static struct platform_driver sun8i_a83t_pinctrl_driver = {
        .probe  = sun8i_a83t_pinctrl_probe,
@@ -596,8 +595,4 @@ static struct platform_driver sun8i_a83t_pinctrl_driver = {
                .of_match_table = sun8i_a83t_pinctrl_match,
        },
 };
-module_platform_driver(sun8i_a83t_pinctrl_driver);
-
-MODULE_AUTHOR("Vishnu Patekar <vishnupatekar0510@gmail.com>");
-MODULE_DESCRIPTION("Allwinner a83t pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun8i_a83t_pinctrl_driver);
index 1b580ba764531a6d04d2293486f9e1b78a466f45..bc14e954d7a2abd923add205a57cb850e72fb65d 100644 (file)
@@ -10,7 +10,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -733,7 +733,6 @@ static const struct of_device_id sun9i_a80_pinctrl_match[] = {
        { .compatible = "allwinner,sun9i-a80-pinctrl", },
        {}
 };
-MODULE_DEVICE_TABLE(of, sun9i_a80_pinctrl_match);
 
 static struct platform_driver sun9i_a80_pinctrl_driver = {
        .probe  = sun9i_a80_pinctrl_probe,
@@ -742,8 +741,4 @@ static struct platform_driver sun9i_a80_pinctrl_driver = {
                .of_match_table = sun9i_a80_pinctrl_match,
        },
 };
-module_platform_driver(sun9i_a80_pinctrl_driver);
-
-MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
-MODULE_DESCRIPTION("Allwinner A80 pinctrl driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun9i_a80_pinctrl_driver);
index 0facbea5f465f0912630770e1b4cbc6255d817da..0eb51e33cb1be5412ab11d10e7cdb474a2faa061 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
 #include "../core.h"
 #include "pinctrl-sunxi.h"
 
@@ -145,6 +147,171 @@ static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
        return 0;
 }
 
+static bool sunxi_pctrl_has_bias_prop(struct device_node *node)
+{
+       return of_find_property(node, "bias-pull-up", NULL) ||
+               of_find_property(node, "bias-pull-down", NULL) ||
+               of_find_property(node, "bias-disable", NULL) ||
+               of_find_property(node, "allwinner,pull", NULL);
+}
+
+static bool sunxi_pctrl_has_drive_prop(struct device_node *node)
+{
+       return of_find_property(node, "drive-strength", NULL) ||
+               of_find_property(node, "allwinner,drive", NULL);
+}
+
+static int sunxi_pctrl_parse_bias_prop(struct device_node *node)
+{
+       u32 val;
+
+       /* Try the new style binding */
+       if (of_find_property(node, "bias-pull-up", NULL))
+               return PIN_CONFIG_BIAS_PULL_UP;
+
+       if (of_find_property(node, "bias-pull-down", NULL))
+               return PIN_CONFIG_BIAS_PULL_DOWN;
+
+       if (of_find_property(node, "bias-disable", NULL))
+               return PIN_CONFIG_BIAS_DISABLE;
+
+       /* And fall back to the old binding */
+       if (of_property_read_u32(node, "allwinner,pull", &val))
+               return -EINVAL;
+
+       switch (val) {
+       case SUN4I_PINCTRL_NO_PULL:
+               return PIN_CONFIG_BIAS_DISABLE;
+       case SUN4I_PINCTRL_PULL_UP:
+               return PIN_CONFIG_BIAS_PULL_UP;
+       case SUN4I_PINCTRL_PULL_DOWN:
+               return PIN_CONFIG_BIAS_PULL_DOWN;
+       }
+
+       return -EINVAL;
+}
+
+static int sunxi_pctrl_parse_drive_prop(struct device_node *node)
+{
+       u32 val;
+
+       /* Try the new style binding */
+       if (!of_property_read_u32(node, "drive-strength", &val)) {
+               /* We can't go below 10mA ... */
+               if (val < 10)
+                       return -EINVAL;
+
+               /* ... and only up to 40 mA ... */
+               if (val > 40)
+                       val = 40;
+
+               /* by steps of 10 mA */
+               return rounddown(val, 10);
+       }
+
+       /* And then fall back to the old binding */
+       if (of_property_read_u32(node, "allwinner,drive", &val))
+               return -EINVAL;
+
+       return (val + 1) * 10;
+}
+
+static const char *sunxi_pctrl_parse_function_prop(struct device_node *node)
+{
+       const char *function;
+       int ret;
+
+       /* Try the generic binding */
+       ret = of_property_read_string(node, "function", &function);
+       if (!ret)
+               return function;
+
+       /* And fall back to our legacy one */
+       ret = of_property_read_string(node, "allwinner,function", &function);
+       if (!ret)
+               return function;
+
+       return NULL;
+}
+
+static const char *sunxi_pctrl_find_pins_prop(struct device_node *node,
+                                             int *npins)
+{
+       int count;
+
+       /* Try the generic binding */
+       count = of_property_count_strings(node, "pins");
+       if (count > 0) {
+               *npins = count;
+               return "pins";
+       }
+
+       /* And fall back to our legacy one */
+       count = of_property_count_strings(node, "allwinner,pins");
+       if (count > 0) {
+               *npins = count;
+               return "allwinner,pins";
+       }
+
+       return NULL;
+}
+
+static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node,
+                                                  unsigned int *len)
+{
+       unsigned long *pinconfig;
+       unsigned int configlen = 0, idx = 0;
+       int ret;
+
+       if (sunxi_pctrl_has_drive_prop(node))
+               configlen++;
+       if (sunxi_pctrl_has_bias_prop(node))
+               configlen++;
+
+       /*
+        * If we don't have any configuration, bail out
+        */
+       if (!configlen)
+               return NULL;
+
+       pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
+       if (!pinconfig)
+               return ERR_PTR(-ENOMEM);
+
+       if (sunxi_pctrl_has_drive_prop(node)) {
+               int drive = sunxi_pctrl_parse_drive_prop(node);
+               if (drive < 0) {
+                       ret = drive;
+                       goto err_free;
+               }
+
+               pinconfig[idx++] = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
+                                                         drive);
+       }
+
+       if (sunxi_pctrl_has_bias_prop(node)) {
+               int pull = sunxi_pctrl_parse_bias_prop(node);
+               int arg = 0;
+               if (pull < 0) {
+                       ret = pull;
+                       goto err_free;
+               }
+
+               if (pull != PIN_CONFIG_BIAS_DISABLE)
+                       arg = 1; /* hardware uses weak pull resistors */
+
+               pinconfig[idx++] = pinconf_to_config_packed(pull, arg);
+       }
+
+
+       *len = configlen;
+       return pinconfig;
+
+err_free:
+       kfree(pinconfig);
+       return ERR_PTR(ret);
+}
+
 static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
                                      struct device_node *node,
                                      struct pinctrl_map **map,
@@ -153,38 +320,48 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
        unsigned long *pinconfig;
        struct property *prop;
-       const char *function;
+       const char *function, *pin_prop;
        const char *group;
-       int ret, nmaps, i = 0;
-       u32 val;
+       int ret, npins, nmaps, configlen = 0, i = 0;
 
        *map = NULL;
        *num_maps = 0;
 
-       ret = of_property_read_string(node, "allwinner,function", &function);
-       if (ret) {
-               dev_err(pctl->dev,
-                       "missing allwinner,function property in node %s\n",
+       function = sunxi_pctrl_parse_function_prop(node);
+       if (!function) {
+               dev_err(pctl->dev, "missing function property in node %s\n",
                        node->name);
                return -EINVAL;
        }
 
-       nmaps = of_property_count_strings(node, "allwinner,pins") * 2;
-       if (nmaps < 0) {
-               dev_err(pctl->dev,
-                       "missing allwinner,pins property in node %s\n",
+       pin_prop = sunxi_pctrl_find_pins_prop(node, &npins);
+       if (!pin_prop) {
+               dev_err(pctl->dev, "missing pins property in node %s\n",
                        node->name);
                return -EINVAL;
        }
 
+       /*
+        * We have two maps for each pin: one for the function, one
+        * for the configuration (bias, strength, etc).
+        *
+        * We might be slightly overshooting, since we might not have
+        * any configuration.
+        */
+       nmaps = npins * 2;
        *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
        if (!*map)
                return -ENOMEM;
 
-       of_property_for_each_string(node, "allwinner,pins", prop, group) {
+       pinconfig = sunxi_pctrl_build_pin_config(node, &configlen);
+       if (IS_ERR(pinconfig)) {
+               ret = PTR_ERR(pinconfig);
+               goto err_free_map;
+       }
+
+       of_property_for_each_string(node, pin_prop, prop, group) {
                struct sunxi_pinctrl_group *grp =
                        sunxi_pinctrl_find_group_by_name(pctl, group);
-               int j = 0, configlen = 0;
 
                if (!grp) {
                        dev_err(pctl->dev, "unknown pin %s", group);
@@ -205,45 +382,31 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 
                i++;
 
-               (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
-               (*map)[i].data.configs.group_or_pin = group;
-
-               if (of_find_property(node, "allwinner,drive", NULL))
-                       configlen++;
-               if (of_find_property(node, "allwinner,pull", NULL))
-                       configlen++;
-
-               pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
-               if (!pinconfig) {
-                       kfree(*map);
-                       return -ENOMEM;
+               if (pinconfig) {
+                       (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+                       (*map)[i].data.configs.group_or_pin = group;
+                       (*map)[i].data.configs.configs = pinconfig;
+                       (*map)[i].data.configs.num_configs = configlen;
+                       i++;
                }
-
-               if (!of_property_read_u32(node, "allwinner,drive", &val)) {
-                       u16 strength = (val + 1) * 10;
-                       pinconfig[j++] =
-                               pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
-                                                        strength);
-               }
-
-               if (!of_property_read_u32(node, "allwinner,pull", &val)) {
-                       enum pin_config_param pull = PIN_CONFIG_END;
-                       if (val == 1)
-                               pull = PIN_CONFIG_BIAS_PULL_UP;
-                       else if (val == 2)
-                               pull = PIN_CONFIG_BIAS_PULL_DOWN;
-                       pinconfig[j++] = pinconf_to_config_packed(pull, 0);
-               }
-
-               (*map)[i].data.configs.configs = pinconfig;
-               (*map)[i].data.configs.num_configs = configlen;
-
-               i++;
        }
 
-       *num_maps = nmaps;
+       *num_maps = i;
+
+       /*
+        * We know have the number of maps we need, we can resize our
+        * map array
+        */
+       *map = krealloc(*map, i * sizeof(struct pinctrl_map), GFP_KERNEL);
+       if (!*map)
+               return -ENOMEM;
 
        return 0;
+
+err_free_map:
+       kfree(*map);
+       *map = NULL;
+       return ret;
 }
 
 static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev,
@@ -252,9 +415,17 @@ static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev,
 {
        int i;
 
-       for (i = 0; i < num_maps; i++) {
-               if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
-                       kfree(map[i].data.configs.configs);
+       /* pin config is never in the first map */
+       for (i = 1; i < num_maps; i++) {
+               if (map[i].type != PIN_MAP_TYPE_CONFIGS_GROUP)
+                       continue;
+
+               /*
+                * All the maps share the same pin config,
+                * free only the first one we find.
+                */
+               kfree(map[i].data.configs.configs);
+               break;
        }
 
        kfree(map);
@@ -268,15 +439,91 @@ static const struct pinctrl_ops sunxi_pctrl_ops = {
        .get_group_pins         = sunxi_pctrl_get_group_pins,
 };
 
+static int sunxi_pconf_reg(unsigned pin, enum pin_config_param param,
+                          u32 *offset, u32 *shift, u32 *mask)
+{
+       switch (param) {
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               *offset = sunxi_dlevel_reg(pin);
+               *shift = sunxi_dlevel_offset(pin);
+               *mask = DLEVEL_PINS_MASK;
+               break;
+
+       case PIN_CONFIG_BIAS_PULL_UP:
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+       case PIN_CONFIG_BIAS_DISABLE:
+               *offset = sunxi_pull_reg(pin);
+               *shift = sunxi_pull_offset(pin);
+               *mask = PULL_PINS_MASK;
+               break;
+
+       default:
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int sunxi_pconf_get(struct pinctrl_dev *pctldev, unsigned pin,
+                          unsigned long *config)
+{
+       struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+       enum pin_config_param param = pinconf_to_config_param(*config);
+       u32 offset, shift, mask, val;
+       u16 arg;
+       int ret;
+
+       pin -= pctl->desc->pin_base;
+
+       ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask);
+       if (ret < 0)
+               return ret;
+
+       val = (readl(pctl->membase + offset) >> shift) & mask;
+
+       switch (pinconf_to_config_param(*config)) {
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               arg = (val + 1) * 10;
+               break;
+
+       case PIN_CONFIG_BIAS_PULL_UP:
+               if (val != SUN4I_PINCTRL_PULL_UP)
+                       return -EINVAL;
+               arg = 1; /* hardware is weak pull-up */
+               break;
+
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+               if (val != SUN4I_PINCTRL_PULL_DOWN)
+                       return -EINVAL;
+               arg = 1; /* hardware is weak pull-down */
+               break;
+
+       case PIN_CONFIG_BIAS_DISABLE:
+               if (val != SUN4I_PINCTRL_NO_PULL)
+                       return -EINVAL;
+               arg = 0;
+               break;
+
+       default:
+               /* sunxi_pconf_reg should catch anything unsupported */
+               WARN_ON(1);
+               return -ENOTSUPP;
+       }
+
+       *config = pinconf_to_config_packed(param, arg);
+
+       return 0;
+}
+
 static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
                                 unsigned group,
                                 unsigned long *config)
 {
        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+       struct sunxi_pinctrl_group *g = &pctl->groups[group];
 
-       *config = pctl->groups[group].config;
-
-       return 0;
+       /* We only support 1 pin per group. Chain it to the pin callback */
+       return sunxi_pconf_get(pctldev, g->pin, config);
 }
 
 static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
@@ -286,23 +533,27 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
 {
        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
        struct sunxi_pinctrl_group *g = &pctl->groups[group];
-       unsigned long flags;
        unsigned pin = g->pin - pctl->desc->pin_base;
-       u32 val, mask;
-       u16 strength;
-       u8 dlevel;
        int i;
 
-       spin_lock_irqsave(&pctl->lock, flags);
-
        for (i = 0; i < num_configs; i++) {
-               switch (pinconf_to_config_param(configs[i])) {
+               enum pin_config_param param;
+               unsigned long flags;
+               u32 offset, shift, mask, reg;
+               u16 arg, val;
+               int ret;
+
+               param = pinconf_to_config_param(configs[i]);
+               arg = pinconf_to_config_argument(configs[i]);
+
+               ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask);
+               if (ret < 0)
+                       return ret;
+
+               switch (param) {
                case PIN_CONFIG_DRIVE_STRENGTH:
-                       strength = pinconf_to_config_argument(configs[i]);
-                       if (strength > 40) {
-                               spin_unlock_irqrestore(&pctl->lock, flags);
+                       if (arg < 10 || arg > 40)
                                return -EINVAL;
-                       }
                        /*
                         * We convert from mA to what the register expects:
                         *   0: 10mA
@@ -310,38 +561,40 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
                         *   2: 30mA
                         *   3: 40mA
                         */
-                       dlevel = strength / 10 - 1;
-                       val = readl(pctl->membase + sunxi_dlevel_reg(pin));
-                       mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(pin);
-                       writel((val & ~mask)
-                               | dlevel << sunxi_dlevel_offset(pin),
-                               pctl->membase + sunxi_dlevel_reg(pin));
+                       val = arg / 10 - 1;
+                       break;
+               case PIN_CONFIG_BIAS_DISABLE:
+                       val = 0;
                        break;
                case PIN_CONFIG_BIAS_PULL_UP:
-                       val = readl(pctl->membase + sunxi_pull_reg(pin));
-                       mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
-                       writel((val & ~mask) | 1 << sunxi_pull_offset(pin),
-                               pctl->membase + sunxi_pull_reg(pin));
+                       if (arg == 0)
+                               return -EINVAL;
+                       val = 1;
                        break;
                case PIN_CONFIG_BIAS_PULL_DOWN:
-                       val = readl(pctl->membase + sunxi_pull_reg(pin));
-                       mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
-                       writel((val & ~mask) | 2 << sunxi_pull_offset(pin),
-                               pctl->membase + sunxi_pull_reg(pin));
+                       if (arg == 0)
+                               return -EINVAL;
+                       val = 2;
                        break;
                default:
-                       break;
+                       /* sunxi_pconf_reg should catch anything unsupported */
+                       WARN_ON(1);
+                       return -ENOTSUPP;
                }
-               /* cache the config value */
-               g->config = configs[i];
-       } /* for each config */
 
-       spin_unlock_irqrestore(&pctl->lock, flags);
+               spin_lock_irqsave(&pctl->lock, flags);
+               reg = readl(pctl->membase + offset);
+               reg &= ~(mask << shift);
+               writel(reg | val << shift, pctl->membase + offset);
+               spin_unlock_irqrestore(&pctl->lock, flags);
+       } /* for each config */
 
        return 0;
 }
 
 static const struct pinconf_ops sunxi_pconf_ops = {
+       .is_generic             = true,
+       .pin_config_get         = sunxi_pconf_get,
        .pin_config_group_get   = sunxi_pconf_group_get,
        .pin_config_group_set   = sunxi_pconf_group_set,
 };
@@ -870,6 +1123,91 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
        return 0;
 }
 
+static int sunxi_pinctrl_get_debounce_div(struct clk *clk, int freq, int *diff)
+{
+       unsigned long clock = clk_get_rate(clk);
+       unsigned int best_diff, best_div;
+       int i;
+
+       best_diff = abs(freq - clock);
+       best_div = 0;
+
+       for (i = 1; i < 8; i++) {
+               int cur_diff = abs(freq - (clock >> i));
+
+               if (cur_diff < best_diff) {
+                       best_diff = cur_diff;
+                       best_div = i;
+               }
+       }
+
+       *diff = best_diff;
+       return best_div;
+}
+
+static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
+                                       struct device_node *node)
+{
+       unsigned int hosc_diff, losc_diff;
+       unsigned int hosc_div, losc_div;
+       struct clk *hosc, *losc;
+       u8 div, src;
+       int i, ret;
+
+       /* Deal with old DTs that didn't have the oscillators */
+       if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3)
+               return 0;
+
+       /* If we don't have any setup, bail out */
+       if (!of_find_property(node, "input-debounce", NULL))
+               return 0;
+
+       losc = devm_clk_get(pctl->dev, "losc");
+       if (IS_ERR(losc))
+               return PTR_ERR(losc);
+
+       hosc = devm_clk_get(pctl->dev, "hosc");
+       if (IS_ERR(hosc))
+               return PTR_ERR(hosc);
+
+       for (i = 0; i < pctl->desc->irq_banks; i++) {
+               unsigned long debounce_freq;
+               u32 debounce;
+
+               ret = of_property_read_u32_index(node, "input-debounce",
+                                                i, &debounce);
+               if (ret)
+                       return ret;
+
+               if (!debounce)
+                       continue;
+
+               debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce);
+               losc_div = sunxi_pinctrl_get_debounce_div(losc,
+                                                         debounce_freq,
+                                                         &losc_diff);
+
+               hosc_div = sunxi_pinctrl_get_debounce_div(hosc,
+                                                         debounce_freq,
+                                                         &hosc_diff);
+
+               if (hosc_diff < losc_diff) {
+                       div = hosc_div;
+                       src = 1;
+               } else {
+                       div = losc_div;
+                       src = 0;
+               }
+
+               writel(src | div << 4,
+                      pctl->membase +
+                      sunxi_irq_debounce_reg_from_bank(i,
+                                                       pctl->desc->irq_bank_base));
+       }
+
+       return 0;
+}
+
 int sunxi_pinctrl_init(struct platform_device *pdev,
                       const struct sunxi_pinctrl_desc *desc)
 {
@@ -1032,6 +1370,8 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
                                                 pctl);
        }
 
+       sunxi_pinctrl_setup_debounce(pctl, node);
+
        dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
 
        return 0;
index 0afce1ab12d039515a1ea40f66bdb3806ca9f5ca..f78a44a03189fa2bf7124c1ce5f9d47c8e37278c 100644 (file)
@@ -69,6 +69,8 @@
 #define IRQ_STATUS_IRQ_BITS            1
 #define IRQ_STATUS_IRQ_MASK            ((1 << IRQ_STATUS_IRQ_BITS) - 1)
 
+#define IRQ_DEBOUNCE_REG       0x218
+
 #define IRQ_MEM_SIZE           0x20
 
 #define IRQ_EDGE_RISING                0x00
@@ -109,7 +111,6 @@ struct sunxi_pinctrl_function {
 
 struct sunxi_pinctrl_group {
        const char      *name;
-       unsigned long   config;
        unsigned        pin;
 };
 
@@ -266,6 +267,11 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq)
        return irq_num * IRQ_CTRL_IRQ_BITS;
 }
 
+static inline u32 sunxi_irq_debounce_reg_from_bank(u8 bank, unsigned bank_base)
+{
+       return IRQ_DEBOUNCE_REG + (bank_base + bank) * IRQ_MEM_SIZE;
+}
+
 static inline u32 sunxi_irq_status_reg_from_bank(u8 bank, unsigned bank_base)
 {
        return IRQ_STATUS_REG + (bank_base + bank) * IRQ_MEM_SIZE;
index ca946b3dbdb4f717b2543ee9fade272c4c0926ea..767f340d6b115f00d798a06aa86612c500c8bbe7 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -473,11 +473,6 @@ static int vt8500_pinctrl_probe(struct platform_device *pdev)
        return wmt_pinctrl_probe(pdev, data);
 }
 
-static int vt8500_pinctrl_remove(struct platform_device *pdev)
-{
-       return wmt_pinctrl_remove(pdev);
-}
-
 static const struct of_device_id wmt_pinctrl_of_match[] = {
        { .compatible = "via,vt8500-pinctrl" },
        { /* sentinel */ },
@@ -485,16 +480,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = {
 
 static struct platform_driver wmt_pinctrl_driver = {
        .probe  = vt8500_pinctrl_probe,
-       .remove = vt8500_pinctrl_remove,
        .driver = {
                .name   = "pinctrl-vt8500",
                .of_match_table = wmt_pinctrl_of_match,
+               .suppress_bind_attrs = true,
        },
 };
-
-module_platform_driver(wmt_pinctrl_driver);
-
-MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
-MODULE_DESCRIPTION("VIA VT8500 Pincontrol driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match);
+builtin_platform_driver(wmt_pinctrl_driver);
index 626fc7ec017462948e784715851f84dd58281b35..a56fdbd87e42b9da3bd3c80976eb2f28155fe7cc 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -504,11 +504,6 @@ static int wm8505_pinctrl_probe(struct platform_device *pdev)
        return wmt_pinctrl_probe(pdev, data);
 }
 
-static int wm8505_pinctrl_remove(struct platform_device *pdev)
-{
-       return wmt_pinctrl_remove(pdev);
-}
-
 static const struct of_device_id wmt_pinctrl_of_match[] = {
        { .compatible = "wm,wm8505-pinctrl" },
        { /* sentinel */ },
@@ -516,16 +511,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = {
 
 static struct platform_driver wmt_pinctrl_driver = {
        .probe  = wm8505_pinctrl_probe,
-       .remove = wm8505_pinctrl_remove,
        .driver = {
                .name   = "pinctrl-wm8505",
                .of_match_table = wmt_pinctrl_of_match,
+               .suppress_bind_attrs = true,
        },
 };
-
-module_platform_driver(wmt_pinctrl_driver);
-
-MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
-MODULE_DESCRIPTION("Wondermedia WM8505 Pincontrol driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match);
+builtin_platform_driver(wmt_pinctrl_driver);
index 8953aba8bfc2261e5c6cef9392d69cb4c5b1209f..270dd491f5a1e8c82d8968bdbdb49d24ee284903 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -342,11 +342,6 @@ static int wm8650_pinctrl_probe(struct platform_device *pdev)
        return wmt_pinctrl_probe(pdev, data);
 }
 
-static int wm8650_pinctrl_remove(struct platform_device *pdev)
-{
-       return wmt_pinctrl_remove(pdev);
-}
-
 static const struct of_device_id wmt_pinctrl_of_match[] = {
        { .compatible = "wm,wm8650-pinctrl" },
        { /* sentinel */ },
@@ -354,16 +349,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = {
 
 static struct platform_driver wmt_pinctrl_driver = {
        .probe  = wm8650_pinctrl_probe,
-       .remove = wm8650_pinctrl_remove,
        .driver = {
                .name   = "pinctrl-wm8650",
                .of_match_table = wmt_pinctrl_of_match,
+               .suppress_bind_attrs = true,
        },
 };
-
-module_platform_driver(wmt_pinctrl_driver);
-
-MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
-MODULE_DESCRIPTION("Wondermedia WM8650 Pincontrol driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match);
+builtin_platform_driver(wmt_pinctrl_driver);
index c79053d430db5ad6894ebf60d10e30fdbfe05b06..74f7b3a18f3a859272598f58b800407ff9b871a4 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -381,11 +381,6 @@ static int wm8750_pinctrl_probe(struct platform_device *pdev)
        return wmt_pinctrl_probe(pdev, data);
 }
 
-static int wm8750_pinctrl_remove(struct platform_device *pdev)
-{
-       return wmt_pinctrl_remove(pdev);
-}
-
 static const struct of_device_id wmt_pinctrl_of_match[] = {
        { .compatible = "wm,wm8750-pinctrl" },
        { /* sentinel */ },
@@ -393,16 +388,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = {
 
 static struct platform_driver wmt_pinctrl_driver = {
        .probe  = wm8750_pinctrl_probe,
-       .remove = wm8750_pinctrl_remove,
        .driver = {
                .name   = "pinctrl-wm8750",
                .of_match_table = wmt_pinctrl_of_match,
+               .suppress_bind_attrs = true,
        },
 };
-
-module_platform_driver(wmt_pinctrl_driver);
-
-MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
-MODULE_DESCRIPTION("Wondermedia WM8750 Pincontrol driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match);
+builtin_platform_driver(wmt_pinctrl_driver);
index f232b163c735cfb4e9a4c3fa11033c9d5142739f..45792aa7a06e31efdd9536bc392df0395ce8c77c 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -360,11 +360,6 @@ static int wm8850_pinctrl_probe(struct platform_device *pdev)
        return wmt_pinctrl_probe(pdev, data);
 }
 
-static int wm8850_pinctrl_remove(struct platform_device *pdev)
-{
-       return wmt_pinctrl_remove(pdev);
-}
-
 static const struct of_device_id wmt_pinctrl_of_match[] = {
        { .compatible = "wm,wm8850-pinctrl" },
        { /* sentinel */ },
@@ -372,16 +367,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = {
 
 static struct platform_driver wmt_pinctrl_driver = {
        .probe  = wm8850_pinctrl_probe,
-       .remove = wm8850_pinctrl_remove,
        .driver = {
                .name   = "pinctrl-wm8850",
                .of_match_table = wmt_pinctrl_of_match,
+               .suppress_bind_attrs = true,
        },
 };
-
-module_platform_driver(wmt_pinctrl_driver);
-
-MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
-MODULE_DESCRIPTION("Wondermedia WM8850 Pincontrol driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match);
+builtin_platform_driver(wmt_pinctrl_driver);
index cbc6386316783daabc445cb26d9d7d56d9673380..270ca2a47a8c9a8237921800d64c46192f3e3437 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
-#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/pinctrl/consumer.h>
@@ -608,12 +607,3 @@ fail_range:
        gpiochip_remove(&data->gpio_chip);
        return err;
 }
-
-int wmt_pinctrl_remove(struct platform_device *pdev)
-{
-       struct wmt_pinctrl_data *data = platform_get_drvdata(pdev);
-
-       gpiochip_remove(&data->gpio_chip);
-
-       return 0;
-}
index 41f5f2deb5d6215983012c82e9f827577ed0001c..885613396fe78aba18d3ec87647319f1d63e04ad 100644 (file)
@@ -76,4 +76,3 @@ struct wmt_pinctrl_data {
 
 int wmt_pinctrl_probe(struct platform_device *pdev,
                      struct wmt_pinctrl_data *data);
-int wmt_pinctrl_remove(struct platform_device *pdev);
diff --git a/include/dt-bindings/gpio/meson-gxl-gpio.h b/include/dt-bindings/gpio/meson-gxl-gpio.h
new file mode 100644 (file)
index 0000000..684d0d7
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * GPIO definitions for Amlogic Meson GXL SoCs
+ *
+ * Copyright (C) 2016 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DT_BINDINGS_MESON_GXL_GPIO_H
+#define _DT_BINDINGS_MESON_GXL_GPIO_H
+
+#define        GPIOAO_0        0
+#define        GPIOAO_1        1
+#define        GPIOAO_2        2
+#define        GPIOAO_3        3
+#define        GPIOAO_4        4
+#define        GPIOAO_5        5
+#define        GPIOAO_6        6
+#define        GPIOAO_7        7
+#define        GPIOAO_8        8
+#define        GPIOAO_9        9
+
+#define        GPIOZ_0         0
+#define        GPIOZ_1         1
+#define        GPIOZ_2         2
+#define        GPIOZ_3         3
+#define        GPIOZ_4         4
+#define        GPIOZ_5         5
+#define        GPIOZ_6         6
+#define        GPIOZ_7         7
+#define        GPIOZ_8         8
+#define        GPIOZ_9         9
+#define        GPIOZ_10        10
+#define        GPIOZ_11        11
+#define        GPIOZ_12        12
+#define        GPIOZ_13        13
+#define        GPIOZ_14        14
+#define        GPIOZ_15        15
+#define        GPIOH_0         16
+#define        GPIOH_1         17
+#define        GPIOH_2         18
+#define        GPIOH_3         19
+#define        GPIOH_4         20
+#define        GPIOH_5         21
+#define        GPIOH_6         22
+#define        GPIOH_7         23
+#define        GPIOH_8         24
+#define        GPIOH_9         25
+#define        BOOT_0          26
+#define        BOOT_1          27
+#define        BOOT_2          28
+#define        BOOT_3          29
+#define        BOOT_4          30
+#define        BOOT_5          31
+#define        BOOT_6          32
+#define        BOOT_7          33
+#define        BOOT_8          34
+#define        BOOT_9          35
+#define        BOOT_10         36
+#define        BOOT_11         37
+#define        BOOT_12         38
+#define        BOOT_13         39
+#define        BOOT_14         40
+#define        BOOT_15         41
+#define        CARD_0          42
+#define        CARD_1          43
+#define        CARD_2          44
+#define        CARD_3          45
+#define        CARD_4          46
+#define        CARD_5          47
+#define        CARD_6          48
+#define        GPIODV_0        49
+#define        GPIODV_1        50
+#define        GPIODV_2        51
+#define        GPIODV_3        52
+#define        GPIODV_4        53
+#define        GPIODV_5        54
+#define        GPIODV_6        55
+#define        GPIODV_7        56
+#define        GPIODV_8        57
+#define        GPIODV_9        58
+#define        GPIODV_10       59
+#define        GPIODV_11       60
+#define        GPIODV_12       61
+#define        GPIODV_13       62
+#define        GPIODV_14       63
+#define        GPIODV_15       64
+#define        GPIODV_16       65
+#define        GPIODV_17       66
+#define        GPIODV_18       67
+#define        GPIODV_19       68
+#define        GPIODV_20       69
+#define        GPIODV_21       70
+#define        GPIODV_22       71
+#define        GPIODV_23       72
+#define        GPIODV_24       73
+#define        GPIODV_25       74
+#define        GPIODV_26       75
+#define        GPIODV_27       76
+#define        GPIODV_28       77
+#define        GPIODV_29       78
+#define        GPIOX_0         79
+#define        GPIOX_1         80
+#define        GPIOX_2         81
+#define        GPIOX_3         82
+#define        GPIOX_4         83
+#define        GPIOX_5         84
+#define        GPIOX_6         85
+#define        GPIOX_7         86
+#define        GPIOX_8         87
+#define        GPIOX_9         88
+#define        GPIOX_10        89
+#define        GPIOX_11        90
+#define        GPIOX_12        91
+#define        GPIOX_13        92
+#define        GPIOX_14        93
+#define        GPIOX_15        94
+#define        GPIOX_16        95
+#define        GPIOX_17        96
+#define        GPIOX_18        97
+#define        GPIOCLK_0       98
+#define        GPIOCLK_1       99
+#define        GPIO_TEST_N     100
+
+#endif
index bbca3d038900730a1f203eea2e15cb0ddcb19155..2732d6c0fb39ebd28ef4ec81d415fc0d0677c8e7 100644 (file)
@@ -15,6 +15,8 @@
 #define AT91_PINCTRL_DEGLITCH          (1 << 2)
 #define AT91_PINCTRL_PULL_DOWN         (1 << 3)
 #define AT91_PINCTRL_DIS_SCHMIT                (1 << 4)
+#define AT91_PINCTRL_OUTPUT            (1 << 7)
+#define AT91_PINCTRL_OUTPUT_VAL(x)     ((x & 0x1) << 8)
 #define AT91_PINCTRL_DEBOUNCE          (1 << 16)
 #define AT91_PINCTRL_DEBOUNCE_VAL(x)   (x << 17)