]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge tag 'pinctrl-v5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 2 Apr 2020 22:47:18 +0000 (15:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 2 Apr 2020 22:47:18 +0000 (15:47 -0700)
Pull pin control updates from Linus Walleij:
 "This is the bulk of pin control changes for the v5.7 kernel cycle.

  There are no core changes this time, only driver developments:

   - New driver for the Dialog Semiconductor DA9062 Power Management
     Integrated Circuit (PMIC).

   - Renesas SH-PFC has improved consistency, with group and register
     checks in the configuration checker.

   - New subdriver for the Qualcomm IPQ6018.

   - Add the RGMII pin control functionality to Qualcomm IPQ8064.

   - Performance and code quality cleanups in the Mediatek driver.

   - Improve the Broadcom BCM2835 support to cover all the GPIOs that
     exist in it.

   - The Allwinner/Sunxi driver properly masks non-wakeup IRQs on
     suspend.

   - Add some missing groups and functions to the Ingenic driver.

   - Convert some of the Freescale device tree bindings to use the new
     and all improved JSON YAML markup.

   - Refactorings and support for the SFIO/GPIO in the Tegra194 SoC
     driver.

   - Support high impedance mode in the Spreadtrum/Unisoc driver"

* tag 'pinctrl-v5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (64 commits)
  pinctrl: qcom: fix compilation error
  pinctrl: qcom: use scm_call to route GPIO irq to Apps
  pinctrl: sprd: Add pin high impedance mode support
  pinctrl: sprd: Use the correct pin output configuration
  pinctrl: tegra: Add SFIO/GPIO programming on Tegra194
  pinctrl: tegra: Renumber the GG.0 and GG.1 pins
  pinctrl: tegra: Do not add default pin range on Tegra194
  pinctrl: tegra: Pass struct tegra_pmx for pin range check
  pinctrl: tegra: Fix "Scmitt" -> "Schmitt" typo
  pinctrl: tegra: Fix whitespace issues for improved readability
  pinctrl: mediatek: Use scnprintf() for avoiding potential buffer overflow
  pinctrl: freescale: drop the dependency on ARM64 for i.MX8M
  Revert "pinctrl: mvebu: armada-37xx: use use platform api"
  dt-bindings: pinctrl: at91: Fix a typo ("descibe")
  pinctrl: meson: add tsin pinctrl for meson gxbb/gxl/gxm
  pinctrl: sprd: Fix the kconfig warning
  pinctrl: ingenic: add hdmi-ddc pin control group
  pinctrl: sirf/atlas7: Replace zero-length array with flexible-array member
  pinctrl: sprd: Allow the SPRD pinctrl driver building into a module
  pinctrl: Export some needed symbols at module load time
  ...

64 files changed:
Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.txt [deleted file]
Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/fsl,imx8mn-pinctrl.txt [deleted file]
Documentation/devicetree/bindings/pinctrl/fsl,imx8mn-pinctrl.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/fsl,imx8mp-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.txt [deleted file]
Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/qcom,ipq6018-pinctrl.yaml [new file with mode: 0644]
MAINTAINERS
drivers/gpio/gpiolib.c
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/actions/pinctrl-s700.c
drivers/pinctrl/bcm/pinctrl-bcm2835.c
drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
drivers/pinctrl/core.c
drivers/pinctrl/freescale/Kconfig
drivers/pinctrl/mediatek/pinctrl-mt6765.c
drivers/pinctrl/mediatek/pinctrl-mt8183.c
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
drivers/pinctrl/mediatek/pinctrl-mtk-common.c
drivers/pinctrl/mediatek/pinctrl-paris.c
drivers/pinctrl/mediatek/pinctrl-paris.h
drivers/pinctrl/meson/pinctrl-meson-gxbb.c
drivers/pinctrl/meson/pinctrl-meson-gxl.c
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
drivers/pinctrl/nomadik/pinctrl-nomadik.c
drivers/pinctrl/pinconf-generic.c
drivers/pinctrl/pinctrl-amd.c
drivers/pinctrl/pinctrl-at91.c
drivers/pinctrl/pinctrl-axp209.c
drivers/pinctrl/pinctrl-da9062.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-ingenic.c
drivers/pinctrl/pinctrl-ocelot.c
drivers/pinctrl/pinctrl-oxnas.c
drivers/pinctrl/pinctrl-pic32.c
drivers/pinctrl/pinctrl-pistachio.c
drivers/pinctrl/pinctrl-rk805.c
drivers/pinctrl/pinctrl-rockchip.c
drivers/pinctrl/pinctrl-rza1.c
drivers/pinctrl/pinctrl-rza2.c
drivers/pinctrl/pinctrl-st.c
drivers/pinctrl/pinctrl-stmfx.c
drivers/pinctrl/pinctrl-sx150x.c
drivers/pinctrl/qcom/Kconfig
drivers/pinctrl/qcom/Makefile
drivers/pinctrl/qcom/pinctrl-ipq6018.c [new file with mode: 0644]
drivers/pinctrl/qcom/pinctrl-ipq8064.c
drivers/pinctrl/qcom/pinctrl-msm.c
drivers/pinctrl/sh-pfc/Kconfig
drivers/pinctrl/sh-pfc/core.c
drivers/pinctrl/sh-pfc/gpio.c
drivers/pinctrl/sirf/pinctrl-atlas7.c
drivers/pinctrl/sprd/Kconfig
drivers/pinctrl/sprd/pinctrl-sprd.c
drivers/pinctrl/stm32/pinctrl-stm32.c
drivers/pinctrl/sunxi/pinctrl-sunxi.c
drivers/pinctrl/tegra/pinctrl-tegra.c
drivers/pinctrl/tegra/pinctrl-tegra.h
drivers/pinctrl/tegra/pinctrl-tegra194.c
drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
drivers/pinctrl/vt8500/pinctrl-wmt.c

index eb39f5051159f3aa29c0ace536288b7e592dae05..e8abbdad7b5daa6ce05bfd5ad256c2bc358e7833 100644 (file)
@@ -38,7 +38,7 @@ Bank: 3 (A, B and C)
   0xffffffff 0x7fff3ccf  /* pioB */
   0xffffffff 0x007fffff  /* pioC */
 
-For each peripheral/bank we will descibe in a u32 if a pin can be
+For each peripheral/bank we will describe in a u32 if a pin can be
 configured in it by putting 1 to the pin bit (1 << pin)
 
 Let's take the pioA on peripheral B
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.txt
deleted file mode 100644 (file)
index e4e01c0..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-* Freescale IMX8MM IOMUX Controller
-
-Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
-for common binding part and usage.
-
-Required properties:
-- compatible: "fsl,imx8mm-iomuxc"
-- reg: should contain the base physical address and size of the iomuxc
-  registers.
-
-Required properties in sub-nodes:
-- fsl,pins: each entry consists of 6 integers and represents the mux and config
-  setting for one pin.  The first 5 integers <mux_reg conf_reg input_reg mux_val
-  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
-  <arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h>. The last integer CONFIG is
-  the pad setting value like pull-up on this pin.  Please refer to i.MX8M Mini
-  Reference Manual for detailed CONFIG settings.
-
-Examples:
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1>;
-};
-
-iomuxc: pinctrl@30330000 {
-        compatible = "fsl,imx8mm-iomuxc";
-        reg = <0x0 0x30330000 0x0 0x10000>;
-
-        pinctrl_uart1: uart1grp {
-                fsl,pins = <
-                        MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX             0x140
-                        MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX             0x140
-                >;
-        };
-};
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mm-pinctrl.yaml
new file mode 100644 (file)
index 0000000..d98a386
--- /dev/null
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/fsl,imx8mm-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale IMX8MM IOMUX Controller
+
+maintainers:
+  - Anson Huang <Anson.Huang@nxp.com>
+
+description:
+  Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
+  for common binding part and usage.
+
+properties:
+  compatible:
+    const: fsl,imx8mm-iomuxc
+
+  reg:
+    maxItems: 1
+
+# Client device subnode's properties
+patternProperties:
+  'grp$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      fsl,pins:
+        description:
+          each entry consists of 6 integers and represents the mux and config
+          setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
+          mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
+          be found in <arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h>. The last
+          integer CONFIG is the pad setting value like pull-up on this pin. Please
+          refer to i.MX8M Mini Reference Manual for detailed CONFIG settings.
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32-matrix
+          - items:
+              items:
+                - description: |
+                    "mux_reg" indicates the offset of mux register.
+                - description: |
+                    "conf_reg" indicates the offset of pad configuration register.
+                - description: |
+                    "input_reg" indicates the offset of select input register.
+                - description: |
+                    "mux_val" indicates the mux value to be applied.
+                - description: |
+                    "input_val" indicates the select input value to be applied.
+                - description: |
+                    "pad_setting" indicates the pad configuration value to be applied.
+
+    required:
+      - fsl,pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Pinmux controller node
+  - |
+    iomuxc: pinctrl@30330000 {
+        compatible = "fsl,imx8mm-iomuxc";
+        reg = <0x30330000 0x10000>;
+
+        pinctrl_uart2: uart2grp {
+            fsl,pins =
+                <0x23C 0x4A4 0x4FC 0x0 0x0     0x140>,
+                <0x240 0x4A8 0x000 0x0 0x0     0x140>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8mn-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mn-pinctrl.txt
deleted file mode 100644 (file)
index 330716c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-* Freescale IMX8MN IOMUX Controller
-
-Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
-for common binding part and usage.
-
-Required properties:
-- compatible: "fsl,imx8mn-iomuxc"
-- reg: should contain the base physical address and size of the iomuxc
-  registers.
-
-Required properties in sub-nodes:
-- fsl,pins: each entry consists of 6 integers and represents the mux and config
-  setting for one pin.  The first 5 integers <mux_reg conf_reg input_reg mux_val
-  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
-  <arch/arm64/boot/dts/freescale/imx8mn-pinfunc.h>. The last integer CONFIG is
-  the pad setting value like pull-up on this pin. Please refer to i.MX8M Nano
-  Reference Manual for detailed CONFIG settings.
-
-Examples:
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1>;
-};
-
-iomuxc: pinctrl@30330000 {
-        compatible = "fsl,imx8mn-iomuxc";
-        reg = <0x0 0x30330000 0x0 0x10000>;
-
-        pinctrl_uart1: uart1grp {
-                fsl,pins = <
-                       MX8MN_IOMUXC_UART1_RXD_UART1_DCE_RX     0x140
-                       MX8MN_IOMUXC_UART1_TXD_UART1_DCE_TX     0x140
-                       MX8MN_IOMUXC_UART3_RXD_UART1_DCE_CTS_B  0x140
-                       MX8MN_IOMUXC_UART3_TXD_UART1_DCE_RTS_B  0x140
-                       MX8MN_IOMUXC_SD1_DATA4_GPIO2_IO6        0x19
-                >;
-        };
-};
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8mn-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mn-pinctrl.yaml
new file mode 100644 (file)
index 0000000..b9aa180
--- /dev/null
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/fsl,imx8mn-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale IMX8MN IOMUX Controller
+
+maintainers:
+  - Anson Huang <Anson.Huang@nxp.com>
+
+description:
+  Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
+  for common binding part and usage.
+
+properties:
+  compatible:
+    const: fsl,imx8mn-iomuxc
+
+  reg:
+    maxItems: 1
+
+# Client device subnode's properties
+patternProperties:
+  'grp$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      fsl,pins:
+        description:
+          each entry consists of 6 integers and represents the mux and config
+          setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
+          mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
+          be found in <arch/arm64/boot/dts/freescale/imx8mn-pinfunc.h>. The last
+          integer CONFIG is the pad setting value like pull-up on this pin. Please
+          refer to i.MX8M Nano Reference Manual for detailed CONFIG settings.
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32-matrix
+          - items:
+              items:
+                - description: |
+                    "mux_reg" indicates the offset of mux register.
+                - description: |
+                    "conf_reg" indicates the offset of pad configuration register.
+                - description: |
+                    "input_reg" indicates the offset of select input register.
+                - description: |
+                    "mux_val" indicates the mux value to be applied.
+                - description: |
+                    "input_val" indicates the select input value to be applied.
+                - description: |
+                    "pad_setting" indicates the pad configuration value to be applied.
+
+    required:
+      - fsl,pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Pinmux controller node
+  - |
+    iomuxc: pinctrl@30330000 {
+        compatible = "fsl,imx8mn-iomuxc";
+        reg = <0x30330000 0x10000>;
+
+        pinctrl_uart2: uart2grp {
+            fsl,pins =
+                <0x23C 0x4A4 0x4FC 0x0 0x0     0x140>,
+                <0x240 0x4A8 0x000 0x0 0x0     0x140>;
+        };
+    };
+
+...
index 2e31e120395e494daaeb9fa547b197bcdab7dd7d..6297e78418cf8666b3068730e827454bbc44c599 100644 (file)
@@ -30,8 +30,6 @@ patternProperties:
 
     properties:
       fsl,pins:
-        allOf:
-          - $ref: /schemas/types.yaml#/definitions/uint32-array
         description:
           each entry consists of 6 integers and represents the mux and config
           setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
@@ -39,6 +37,22 @@ patternProperties:
           be found in <arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h>. The last
           integer CONFIG is the pad setting value like pull-up on this pin. Please
           refer to i.MX8M Plus Reference Manual for detailed CONFIG settings.
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32-matrix
+          - items:
+              items:
+                - description: |
+                    "mux_reg" indicates the offset of mux register.
+                - description: |
+                    "conf_reg" indicates the offset of pad configuration register.
+                - description: |
+                    "input_reg" indicates the offset of select input register.
+                - description: |
+                    "mux_val" indicates the mux value to be applied.
+                - description: |
+                    "input_val" indicates the select input value to be applied.
+                - description: |
+                    "pad_setting" indicates the pad configuration value to be applied.
 
     required:
       - fsl,pins
@@ -59,10 +73,9 @@ examples:
         reg = <0x30330000 0x10000>;
 
         pinctrl_uart2: uart2grp {
-            fsl,pins = <
-                0x228 0x488 0x5F0 0x0 0x6      0x49
-                0x228 0x488 0x000 0x0 0x0      0x49
-            >;
+            fsl,pins =
+                <0x228 0x488 0x5F0 0x0 0x6     0x49>,
+                <0x228 0x488 0x000 0x0 0x0     0x49>;
         };
     };
 
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.txt
deleted file mode 100644 (file)
index 66de750..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-* Freescale IMX8MQ IOMUX Controller
-
-Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
-for common binding part and usage.
-
-Required properties:
-- compatible: "fsl,imx8mq-iomuxc"
-- reg: should contain the base physical address and size of the iomuxc
-  registers.
-
-Required properties in sub-nodes:
-- fsl,pins: each entry consists of 6 integers and represents the mux and config
-  setting for one pin.  The first 5 integers <mux_reg conf_reg input_reg mux_val
-  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
-  imx8mq-pinfunc.h under device tree source folder.  The last integer CONFIG is
-  the pad setting value like pull-up on this pin.  Please refer to i.MX8M Quad
-  Reference Manual for detailed CONFIG settings.
-
-Examples:
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1>;
-};
-
-iomuxc: pinctrl@30330000 {
-        compatible = "fsl,imx8mq-iomuxc";
-        reg = <0x0 0x30330000 0x0 0x10000>;
-
-        pinctrl_uart1: uart1grp {
-                fsl,pins = <
-                        MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX             0x49
-                        MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX             0x49
-                >;
-        };
-};
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx8mq-pinctrl.yaml
new file mode 100644 (file)
index 0000000..b30c704
--- /dev/null
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/fsl,imx8mq-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale IMX8MQ IOMUX Controller
+
+maintainers:
+  - Anson Huang <Anson.Huang@nxp.com>
+
+description:
+  Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
+  for common binding part and usage.
+
+properties:
+  compatible:
+    const: fsl,imx8mq-iomuxc
+
+  reg:
+    maxItems: 1
+
+# Client device subnode's properties
+patternProperties:
+  'grp$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      fsl,pins:
+        description:
+          each entry consists of 6 integers and represents the mux and config
+          setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
+          mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
+          be found in <arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h>. The last
+          integer CONFIG is the pad setting value like pull-up on this pin. Please
+          refer to i.MX8M Quad Reference Manual for detailed CONFIG settings.
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32-matrix
+          - items:
+              items:
+                - description: |
+                    "mux_reg" indicates the offset of mux register.
+                - description: |
+                    "conf_reg" indicates the offset of pad configuration register.
+                - description: |
+                    "input_reg" indicates the offset of select input register.
+                - description: |
+                    "mux_val" indicates the mux value to be applied.
+                - description: |
+                    "input_val" indicates the select input value to be applied.
+                - description: |
+                    "pad_setting" indicates the pad configuration value to be applied.
+
+    required:
+      - fsl,pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Pinmux controller node
+  - |
+    iomuxc: pinctrl@30330000 {
+        compatible = "fsl,imx8mq-iomuxc";
+        reg = <0x30330000 0x10000>;
+
+        pinctrl_uart1: uart1grp {
+            fsl,pins =
+                <0x234 0x49C 0x4F4 0x0 0x0     0x49>,
+                <0x238 0x4A0 0x4F4 0x0 0x0     0x49>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq6018-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,ipq6018-pinctrl.yaml
new file mode 100644 (file)
index 0000000..63d1cfe
--- /dev/null
@@ -0,0 +1,153 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,ipq6018-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. IPQ6018 TLMM block
+
+maintainers:
+  - Sricharan R <sricharan@codeaurora.org>
+
+description: |
+  This binding describes the Top Level Mode Multiplexer block found in the
+  IPQ6018 platform.
+
+properties:
+  compatible:
+    const: qcom,ipq6018-pinctrl
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    description: Specifies the TLMM summary IRQ
+    maxItems: 1
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    description:
+      Specifies the PIN numbers and Flags, as defined in defined in
+      include/dt-bindings/interrupt-controller/irq.h
+    const: 2
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    description: Specifying the pin number and flags, as defined in
+      include/dt-bindings/gpio/gpio.h
+    const: 2
+
+  gpio-ranges:
+    maxItems: 1
+
+#PIN CONFIGURATION NODES
+patternProperties:
+  '-pinmux$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    allOf:
+      - $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          oneOf:
+            - pattern: "^gpio([1-9]|[1-7][0-9]|80)$"
+            - enum: [ sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd,
+              sdc2_data, qdsd_cmd, qdsd_data0, qdsd_data1, qdsd_data2,
+              qdsd_data3 ]
+        minItems: 1
+        maxItems: 4
+
+      function:
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+        enum: [ adsp_ext, alsp_int, atest_bbrx0, atest_bbrx1, atest_char,
+          atest_char0, atest_char1, atest_char2, atest_char3, atest_combodac,
+          atest_gpsadc0, atest_gpsadc1, atest_tsens, atest_wlan0,
+          atest_wlan1, backlight_en, bimc_dte0, bimc_dte1, blsp1_i2c,
+          blsp2_i2c, blsp3_i2c, blsp4_i2c, blsp5_i2c, blsp6_i2c,  blsp1_spi,
+          blsp1_spi_cs1, blsp1_spi_cs2, blsp1_spi_cs3, blsp2_spi,
+          blsp2_spi_cs1, blsp2_spi_cs2, blsp2_spi_cs3, blsp3_spi,
+          blsp3_spi_cs1, blsp3_spi_cs2, blsp3_spi_cs3, blsp4_spi, blsp5_spi,
+          blsp6_spi, blsp1_uart, blsp2_uart, blsp1_uim, blsp2_uim, cam1_rst,
+          cam1_standby, cam_mclk0, cam_mclk1, cci_async, cci_i2c, cci_timer0,
+          cci_timer1, cci_timer2, cdc_pdm0, codec_mad, dbg_out, display_5v,
+          dmic0_clk, dmic0_data, dsi_rst, ebi0_wrcdc, euro_us, ext_lpass,
+          flash_strobe, gcc_gp1_clk_a, gcc_gp1_clk_b, gcc_gp2_clk_a,
+          gcc_gp2_clk_b, gcc_gp3_clk_a, gcc_gp3_clk_b, gpio, gsm0_tx0,
+          gsm0_tx1, gsm1_tx0, gsm1_tx1, gyro_accl, kpsns0, kpsns1, kpsns2,
+          ldo_en, ldo_update, mag_int, mdp_vsync, modem_tsync, m_voc,
+          nav_pps, nav_tsync, pa_indicator, pbs0, pbs1, pbs2, pri_mi2s,
+          pri_mi2s_ws, prng_rosc, pwr_crypto_enabled_a, pwr_crypto_enabled_b,
+          pwr_modem_enabled_a,  pwr_modem_enabled_b, pwr_nav_enabled_a,
+          pwr_nav_enabled_b, qdss_ctitrig_in_a0, qdss_ctitrig_in_a1,
+          qdss_ctitrig_in_b0, qdss_ctitrig_in_b1, qdss_ctitrig_out_a0,
+          qdss_ctitrig_out_a1, qdss_ctitrig_out_b0, qdss_ctitrig_out_b1,
+          qdss_traceclk_a, qdss_traceclk_b, qdss_tracectl_a, qdss_tracectl_b,
+          qdss_tracedata_a, qdss_tracedata_b, reset_n, sd_card, sd_write,
+          sec_mi2s, smb_int, ssbi_wtr0, ssbi_wtr1, uim1, uim2, uim3,
+          uim_batt, wcss_bt, wcss_fm, wcss_wlan, webcam1_rst ]
+
+      drive-strength:
+        enum: [2, 4, 6, 8, 10, 12, 14, 16]
+        default: 2
+        description:
+          Selects the drive strength for the specified pins, in mA.
+
+      bias-pull-down: true
+
+      bias-pull-up: true
+
+      bias-disable: true
+
+      output-high: true
+
+      output-low: true
+
+    required:
+      - pins
+      - function
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - '#interrupt-cells'
+  - gpio-controller
+  - '#gpio-cells'
+  - gpio-ranges
+
+additionalProperties: false
+
+examples:
+  - |
+        #include <dt-bindings/interrupt-controller/arm-gic.h>
+        tlmm: pinctrl@1000000 {
+              compatible = "qcom,ipq6018-pinctrl";
+              reg = <0x01000000 0x300000>;
+              interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+              interrupt-controller;
+              #interrupt-cells = <2>;
+              gpio-controller;
+              #gpio-cells = <2>;
+              gpio-ranges = <&tlmm 0 80>;
+
+              serial3-pinmux {
+                      pins = "gpio44", "gpio45";
+                      function = "blsp2_uart";
+                      drive-strength = <8>;
+                      bias-pull-down;
+              };
+        };
index 6849e8ddf55a3b56b010792cc27a661f4940d18b..0ffb16414b9b715d1c76eb325bd4b8a9a07428a3 100644 (file)
@@ -2743,8 +2743,8 @@ L:        linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
 L:     openbmc@lists.ozlabs.org (moderated for non-subscribers)
 L:     linux-gpio@vger.kernel.org
 S:     Maintained
-F:     drivers/pinctrl/aspeed/
 F:     Documentation/devicetree/bindings/pinctrl/aspeed,*
+F:     drivers/pinctrl/aspeed/
 
 ASPEED SCU INTERRUPT CONTROLLER DRIVER
 M:     Eddie James <eajames@linux.ibm.com>
@@ -4958,6 +4958,7 @@ F:        drivers/leds/leds-da90??.c
 F:     drivers/mfd/da903x.c
 F:     drivers/mfd/da90??-*.c
 F:     drivers/mfd/da91??-*.c
+F:     drivers/pinctrl/pinctrl-da90??.c
 F:     drivers/power/supply/da9052-battery.c
 F:     drivers/power/supply/da91??-*.c
 F:     drivers/regulator/da903x.c
@@ -13267,21 +13268,13 @@ K:    \b(clone_args|kernel_clone_args)\b
 PIN CONTROL SUBSYSTEM
 M:     Linus Walleij <linus.walleij@linaro.org>
 L:     linux-gpio@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
 F:     Documentation/devicetree/bindings/pinctrl/
 F:     Documentation/driver-api/pinctl.rst
 F:     drivers/pinctrl/
 F:     include/linux/pinctrl/
 
-PIN CONTROLLER - MICROCHIP AT91
-M:     Ludovic Desroches <ludovic.desroches@microchip.com>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-L:     linux-gpio@vger.kernel.org
-S:     Supported
-F:     drivers/pinctrl/pinctrl-at91*
-F:     drivers/gpio/gpio-sama5d2-piobu.c
-
 PIN CONTROLLER - FREESCALE
 M:     Dong Aisheng <aisheng.dong@nxp.com>
 M:     Fabio Estevam <festevam@gmail.com>
@@ -13290,14 +13283,14 @@ M:    Stefan Agner <stefan@agner.ch>
 R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 L:     linux-gpio@vger.kernel.org
 S:     Maintained
-F:     drivers/pinctrl/freescale/
 F:     Documentation/devicetree/bindings/pinctrl/fsl,*
+F:     drivers/pinctrl/freescale/
 
 PIN CONTROLLER - INTEL
 M:     Mika Westerberg <mika.westerberg@linux.intel.com>
 M:     Andy Shevchenko <andy@kernel.org>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git
 F:     drivers/pinctrl/intel/
 
 PIN CONTROLLER - MEDIATEK
@@ -13308,18 +13301,26 @@ F:    Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
 F:     Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
 F:     drivers/pinctrl/mediatek/
 
+PIN CONTROLLER - MICROCHIP AT91
+M:     Ludovic Desroches <ludovic.desroches@microchip.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-gpio@vger.kernel.org
+S:     Supported
+F:     drivers/gpio/gpio-sama5d2-piobu.c
+F:     drivers/pinctrl/pinctrl-at91*
+
 PIN CONTROLLER - QUALCOMM
 M:     Bjorn Andersson <bjorn.andersson@linaro.org>
-S:     Maintained
 L:     linux-arm-msm@vger.kernel.org
+S:     Maintained
 F:     Documentation/devicetree/bindings/pinctrl/qcom,*.txt
 F:     drivers/pinctrl/qcom/
 
 PIN CONTROLLER - RENESAS
 M:     Geert Uytterhoeven <geert+renesas@glider.be>
 L:     linux-renesas-soc@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git sh-pfc
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git sh-pfc
 F:     drivers/pinctrl/pinctrl-rz*
 F:     drivers/pinctrl/sh-pfc/
 
@@ -13329,12 +13330,12 @@ M:    Krzysztof Kozlowski <krzk@kernel.org>
 M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
-Q:     https://patchwork.kernel.org/project/linux-samsung-soc/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
+Q:     https://patchwork.kernel.org/project/linux-samsung-soc/list/
+F:     Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
 F:     drivers/pinctrl/samsung/
 F:     include/dt-bindings/pinctrl/samsung.h
-F:     Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
 
 PIN CONTROLLER - SINGLE
 M:     Tony Lindgren <tony@atomide.com>
@@ -13347,8 +13348,8 @@ F:      drivers/pinctrl/pinctrl-single.c
 PIN CONTROLLER - ST SPEAR
 M:     Viresh Kumar <vireshk@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W:     http://www.st.com/spear
 S:     Maintained
+W:     http://www.st.com/spear
 F:     drivers/pinctrl/spear/
 
 PISTACHIO SOC SUPPORT
index 00fb91feba7086e77827e16e84aee8494b62986f..86bde1e30a6091cb43b8c32d209ad16bd6d4e0ac 100644 (file)
@@ -149,6 +149,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
 
        return &gdev->descs[hwnum];
 }
+EXPORT_SYMBOL_GPL(gpiochip_get_desc);
 
 /**
  * desc_to_gpio - convert a GPIO descriptor to the integer namespace
index df0ef69dd4748606391b339e7c99a661fa3501a9..834c59950d1cf8e05652ed99584d6cd89c011aa8 100644 (file)
@@ -126,6 +126,18 @@ config PINCTRL_DA850_PUPD
          Driver for TI DA850/OMAP-L138/AM18XX pinconf. Used to control
          pullup/pulldown pin groups.
 
+config PINCTRL_DA9062
+       tristate "Dialog Semiconductor DA9062 PMIC pinctrl and GPIO Support"
+       depends on MFD_DA9062
+       select GPIOLIB
+       help
+         The Dialog DA9062 PMIC provides multiple GPIOs that can be muxed for
+         different functions. This driver bundles a pinctrl driver to select the
+         function muxing and a GPIO driver to handle the GPIO when the GPIO
+         function is selected.
+
+         Say yes to enable pinctrl and GPIO support for the DA9062 PMIC.
+
 config PINCTRL_DIGICOLOR
        bool
        depends on OF && (ARCH_DIGICOLOR || COMPILE_TEST)
index 879f312bfb7577e44dd56bae3c0cc7646be25131..0b36a1cfca8a113031ad5663bc73084a4eecd195 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_AT91PIO4)        += pinctrl-at91-pio4.o
 obj-$(CONFIG_PINCTRL_AMD)      += pinctrl-amd.o
 obj-$(CONFIG_PINCTRL_BM1880)   += pinctrl-bm1880.o
 obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
+obj-$(CONFIG_PINCTRL_DA9062)   += pinctrl-da9062.o
 obj-$(CONFIG_PINCTRL_DIGICOLOR)        += pinctrl-digicolor.o
 obj-$(CONFIG_PINCTRL_FALCON)   += pinctrl-falcon.o
 obj-$(CONFIG_PINCTRL_GEMINI)   += pinctrl-gemini.o
index 771d6fd50b4599b69af021f8b626df44da0e8c84..47a4ccd9fed43d01930a474e94dcdb17039a8c35 100644 (file)
@@ -1125,317 +1125,317 @@ static const struct owl_pingroup s700_groups[] = {
 };
 
 static const char * const nor_groups[] = {
-       "lcd0_d18",
-       "i2s_d0",
-       "i2s0_pcm0",
-       "i2s1_pcm0",
-       "i2s_d1",
-       "ks_in2",
-       "ks_in1",
-       "ks_in0",
-       "ks_in3",
-       "ks_out0",
-       "ks_out1",
-       "ks_out2",
-       "lcd0_d2",
-       "lvds_ee_pn",
-       "uart2_rx_tx",
-       "spi0_i2c_pcm",
-       "lvds_e_pn",
-       "sd0_d0",
-       "sd0_d1",
-       "sd0_d2_d3",
-       "sd1_d0_d3",
-       "sd0_cmd",
-       "sd1_cmd",
-       "sens0_ckout",
-       "sen0_pclk",
+       "lcd0_d18_mfp",
+       "i2s_d0_mfp",
+       "i2s0_pcm0_mfp",
+       "i2s1_pcm0_mfp",
+       "i2s_d1_mfp",
+       "ks_in2_mfp",
+       "ks_in1_mfp",
+       "ks_in0_mfp",
+       "ks_in3_mfp",
+       "ks_out0_mfp",
+       "ks_out1_mfp",
+       "ks_out2_mfp",
+       "lcd0_d2_mfp",
+       "lvds_ee_pn_mfp",
+       "uart2_rx_tx_mfp",
+       "spi0_i2c_pcm_mfp",
+       "lvds_e_pn_mfp",
+       "sd0_d0_mfp",
+       "sd0_d1_mfp",
+       "sd0_d2_d3_mfp",
+       "sd1_d0_d3_mfp",
+       "sd0_cmd_mfp",
+       "sd1_cmd_mfp",
+       "sens0_ckout_mfp",
+       "sen0_pclk_mfp",
 };
 
 static const char * const eth_rmii_groups[] = {
-       "rgmii_txd23",
-       "rgmii_rxd2",
-       "rgmii_rxd3",
-       "rgmii_txd01",
-       "rgmii_txd0",
-       "rgmii_txd1",
-       "rgmii_txen",
-       "rgmii_rxen",
-       "rgmii_rxd1",
-       "rgmii_rxd0",
-       "rgmii_ref_clk",
+       "rgmii_txd23_mfp",
+       "rgmii_rxd2_mfp",
+       "rgmii_rxd3_mfp",
+       "rgmii_txd01_mfp",
+       "rgmii_txd0_mfp",
+       "rgmii_txd1_mfp",
+       "rgmii_txen_mfp",
+       "rgmii_rxen_mfp",
+       "rgmii_rxd1_mfp",
+       "rgmii_rxd0_mfp",
+       "rgmii_ref_clk_mfp",
        "eth_smi_dummy",
 };
 
 static const char * const eth_smii_groups[] = {
-       "rgmii_txd0",
-       "rgmii_txd1",
-       "rgmii_rxd0",
-       "rgmii_rxd1",
-       "rgmii_ref_clk",
+       "rgmii_txd0_mfp",
+       "rgmii_txd1_mfp",
+       "rgmii_rxd0_mfp",
+       "rgmii_rxd1_mfp",
+       "rgmii_ref_clk_mfp",
        "eth_smi_dummy",
 };
 
 static const char * const spi0_groups[] = {
-       "dsi_dn0",
-       "dsi_dp2",
-       "dsi_dp0",
-       "uart2_rx_tx",
-       "spi0_i2c_pcm",
-       "dsi_dn2",
+       "dsi_dn0_mfp",
+       "dsi_dp2_mfp",
+       "dsi_dp0_mfp",
+       "uart2_rx_tx_mfp",
+       "spi0_i2c_pcm_mfp",
+       "dsi_dn2_mfp",
 };
 
 static const char * const spi1_groups[] = {
-       "uart0_rx",
-       "uart0_tx",
+       "uart0_rx_mfp",
+       "uart0_tx_mfp",
        "i2c0_mfp",
 };
 
 static const char * const spi2_groups[] = {
-       "rgmii_txd01",
-       "rgmii_txd0",
-       "rgmii_txd1",
-       "rgmii_ref_clk",
-       "dnand_acle_ce0",
+       "rgmii_txd01_mfp",
+       "rgmii_txd0_mfp",
+       "rgmii_txd1_mfp",
+       "rgmii_ref_clk_mfp",
+       "dnand_acle_ce0_mfp",
 };
 
 static const char * const spi3_groups[] = {
-       "rgmii_txen",
-       "rgmii_rxen",
-       "rgmii_rxd1",
-       "rgmii_rxd0",
+       "rgmii_txen_mfp",
+       "rgmii_rxen_mfp",
+       "rgmii_rxd1_mfp",
+       "rgmii_rxd0_mfp",
 };
 
 static const char * const sens0_groups[] = {
-       "csi_cn_cp",
-       "sens0_ckout",
-       "csi_dn_dp",
-       "sen0_pclk",
+       "csi_cn_cp_mfp",
+       "sens0_ckout_mfp",
+       "csi_dn_dp_mfp",
+       "sen0_pclk_mfp",
 };
 
 static const char * const sens1_groups[] = {
-       "lcd0_d18",
-       "ks_in2",
-       "ks_in1",
-       "ks_in0",
-       "ks_in3",
-       "ks_out0",
-       "ks_out1",
-       "ks_out2",
-       "sens0_ckout",
-       "pcm1_in",
-       "pcm1_clk",
-       "pcm1_sync",
-       "pcm1_out",
+       "lcd0_d18_mfp",
+       "ks_in2_mfp",
+       "ks_in1_mfp",
+       "ks_in0_mfp",
+       "ks_in3_mfp",
+       "ks_out0_mfp",
+       "ks_out1_mfp",
+       "ks_out2_mfp",
+       "sens0_ckout_mfp",
+       "pcm1_in_mfp",
+       "pcm1_clk_mfp",
+       "pcm1_sync_mfp",
+       "pcm1_out_mfp",
 };
 
 static const char * const uart0_groups[] = {
-       "uart2_rtsb",
-       "uart2_ctsb",
-       "uart0_rx",
-       "uart0_tx",
+       "uart2_rtsb_mfp",
+       "uart2_ctsb_mfp",
+       "uart0_rx_mfp",
+       "uart0_tx_mfp",
 };
 
 static const char * const uart1_groups[] = {
-       "sd0_d2_d3",
+       "sd0_d2_d3_mfp",
        "i2c0_mfp",
 };
 
 static const char * const uart2_groups[] = {
-       "rgmii_txen",
-       "rgmii_rxen",
-       "rgmii_rxd1",
-       "rgmii_rxd0",
-       "dsi_dn0",
-       "dsi_dp2",
-       "dsi_dp0",
-       "uart2_rx_tx",
-       "dsi_dn2",
-       "uart2_rtsb",
-       "uart2_ctsb",
-       "sd0_d0",
-       "sd0_d1",
-       "sd0_d2_d3",
-       "uart0_rx",
-       "uart0_tx",
+       "rgmii_txen_mfp",
+       "rgmii_rxen_mfp",
+       "rgmii_rxd1_mfp",
+       "rgmii_rxd0_mfp",
+       "dsi_dn0_mfp",
+       "dsi_dp2_mfp",
+       "dsi_dp0_mfp",
+       "uart2_rx_tx_mfp",
+       "dsi_dn2_mfp",
+       "uart2_rtsb_mfp",
+       "uart2_ctsb_mfp",
+       "sd0_d0_mfp",
+       "sd0_d1_mfp",
+       "sd0_d2_d3_mfp",
+       "uart0_rx_mfp",
+       "uart0_tx_mfp",
        "i2c0_mfp",
        "uart2_dummy"
 };
 
 static const char * const uart3_groups[] = {
-       "rgmii_txd23",
-       "rgmii_rxd2",
-       "rgmii_rxd3",
-       "uart3_rtsb",
-       "uart3_ctsb",
+       "rgmii_txd23_mfp",
+       "rgmii_rxd2_mfp",
+       "rgmii_rxd3_mfp",
+       "uart3_rtsb_mfp",
+       "uart3_ctsb_mfp",
        "uart3_dummy"
 };
 
 static const char * const uart4_groups[] = {
-       "rgmii_txd01",
-       "rgmii_ref_clk",
-       "ks_out0",
-       "ks_out1",
+       "rgmii_txd01_mfp",
+       "rgmii_ref_clk_mfp",
+       "ks_out0_mfp",
+       "ks_out1_mfp",
 };
 
 static const char * const uart5_groups[] = {
-       "rgmii_rxd1",
-       "rgmii_rxd0",
-       "ks_out0",
-       "ks_out2",
-       "uart3_rtsb",
-       "uart3_ctsb",
-       "sd0_d0",
-       "sd0_d1",
+       "rgmii_rxd1_mfp",
+       "rgmii_rxd0_mfp",
+       "ks_out0_mfp",
+       "ks_out2_mfp",
+       "uart3_rtsb_mfp",
+       "uart3_ctsb_mfp",
+       "sd0_d0_mfp",
+       "sd0_d1_mfp",
 };
 
 static const char * const uart6_groups[] = {
-       "rgmii_txd0",
-       "rgmii_txd1",
+       "rgmii_txd0_mfp",
+       "rgmii_txd1_mfp",
 };
 
 static const char * const i2s0_groups[] = {
-       "i2s_d0",
-       "i2s_pcm1",
-       "i2s0_pcm0",
+       "i2s_d0_mfp",
+       "i2s_pcm1_mfp",
+       "i2s0_pcm0_mfp",
 };
 
 static const char * const i2s1_groups[] = {
-       "i2s1_pcm0",
-       "i2s_d1",
+       "i2s1_pcm0_mfp",
+       "i2s_d1_mfp",
        "i2s1_dummy",
-       "spi0_i2c_pcm",
-       "uart0_rx",
-       "uart0_tx",
+       "spi0_i2c_pcm_mfp",
+       "uart0_rx_mfp",
+       "uart0_tx_mfp",
 };
 
 static const char * const pcm1_groups[] = {
-       "i2s_pcm1",
-       "spi0_i2c_pcm",
-       "uart0_rx",
-       "uart0_tx",
-       "pcm1_in",
-       "pcm1_clk",
-       "pcm1_sync",
-       "pcm1_out",
+       "i2s_pcm1_mfp",
+       "spi0_i2c_pcm_mfp",
+       "uart0_rx_mfp",
+       "uart0_tx_mfp",
+       "pcm1_in_mfp",
+       "pcm1_clk_mfp",
+       "pcm1_sync_mfp",
+       "pcm1_out_mfp",
 };
 
 static const char * const pcm0_groups[] = {
-       "i2s0_pcm0",
-       "i2s1_pcm0",
-       "uart2_rx_tx",
-       "spi0_i2c_pcm",
+       "i2s0_pcm0_mfp",
+       "i2s1_pcm0_mfp",
+       "uart2_rx_tx_mfp",
+       "spi0_i2c_pcm_mfp",
 };
 
 static const char * const ks_groups[] = {
-       "ks_in2",
-       "ks_in1",
-       "ks_in0",
-       "ks_in3",
-       "ks_out0",
-       "ks_out1",
-       "ks_out2",
+       "ks_in2_mfp",
+       "ks_in1_mfp",
+       "ks_in0_mfp",
+       "ks_in3_mfp",
+       "ks_out0_mfp",
+       "ks_out1_mfp",
+       "ks_out2_mfp",
 };
 
 static const char * const jtag_groups[] = {
-       "ks_in2",
-       "ks_in1",
-       "ks_in0",
-       "ks_in3",
-       "ks_out1",
-       "sd0_d0",
-       "sd0_d2_d3",
-       "sd0_cmd",
-       "sd0_clk",
+       "ks_in2_mfp",
+       "ks_in1_mfp",
+       "ks_in0_mfp",
+       "ks_in3_mfp",
+       "ks_out1_mfp",
+       "sd0_d0_mfp",
+       "sd0_d2_d3_mfp",
+       "sd0_cmd_mfp",
+       "sd0_clk_mfp",
 };
 
 static const char * const pwm0_groups[] = {
-       "rgmii_rxd2",
-       "rgmii_txen",
-       "ks_in2",
-       "sen0_pclk",
+       "rgmii_rxd2_mfp",
+       "rgmii_txen_mfp",
+       "ks_in2_mfp",
+       "sen0_pclk_mfp",
 };
 
 static const char * const pwm1_groups[] = {
-       "rgmii_rxen",
-       "ks_in1",
-       "ks_in3",
-       "sens0_ckout",
+       "rgmii_rxen_mfp",
+       "ks_in1_mfp",
+       "ks_in3_mfp",
+       "sens0_ckout_mfp",
 };
 
 static const char * const pwm2_groups[] = {
-       "lcd0_d18",
-       "rgmii_rxd3",
-       "rgmii_rxd1",
-       "ks_out0",
-       "ks_out2",
+       "lcd0_d18_mfp",
+       "rgmii_rxd3_mfp",
+       "rgmii_rxd1_mfp",
+       "ks_out0_mfp",
+       "ks_out2_mfp",
 };
 
 static const char * const pwm3_groups[] = {
-       "rgmii_rxd0",
-       "ks_out1",
-       "lcd0_d2",
+       "rgmii_rxd0_mfp",
+       "ks_out1_mfp",
+       "lcd0_d2_mfp",
 };
 
 static const char * const pwm4_groups[] = {
-       "lcd0_d18",
-       "rgmii_txd01",
-       "rgmii_txd0",
-       "ks_in0",
-       "pcm1_in",
-       "nand_ceb3",
+       "lcd0_d18_mfp",
+       "rgmii_txd01_mfp",
+       "rgmii_txd0_mfp",
+       "ks_in0_mfp",
+       "pcm1_in_mfp",
+       "nand_ceb3_mfp",
 };
 
 static const char * const pwm5_groups[] = {
-       "rgmii_txd1",
-       "ks_in1",
-       "pcm1_clk",
-       "nand_ceb2",
+       "rgmii_txd1_mfp",
+       "ks_in1_mfp",
+       "pcm1_clk_mfp",
+       "nand_ceb2_mfp",
 };
 
 static const char * const p0_groups[] = {
-       "ks_in2",
-       "ks_in0",
+       "ks_in2_mfp",
+       "ks_in0_mfp",
 };
 
 static const char * const sd0_groups[] = {
-       "ks_out0",
-       "ks_out1",
-       "ks_out2",
-       "lcd0_d2",
-       "dsi_dp3",
-       "dsi_dp0",
-       "sd0_d0",
-       "sd0_d1",
-       "sd0_d2_d3",
-       "sd1_d0_d3",
-       "sd0_cmd",
-       "sd0_clk",
+       "ks_out0_mfp",
+       "ks_out1_mfp",
+       "ks_out2_mfp",
+       "lcd0_d2_mfp",
+       "dsi_dp3_mfp",
+       "dsi_dp0_mfp",
+       "sd0_d0_mfp",
+       "sd0_d1_mfp",
+       "sd0_d2_d3_mfp",
+       "sd1_d0_d3_mfp",
+       "sd0_cmd_mfp",
+       "sd0_clk_mfp",
 };
 
 static const char * const sd1_groups[] = {
-       "dsi_dp2",
-       "mfp1_16_14",
-       "lcd0_d2",
-       "mfp1_16_14_d17",
-       "dsi_dp3",
-       "dsi_dn3",
-       "dsi_dnp1_cp_d2",
-       "dsi_dnp1_cp_d17",
-       "dsi_dn2",
-       "sd1_d0_d3",
-       "sd1_cmd",
+       "dsi_dp2_mfp",
+       "mfp1_16_14_mfp",
+       "lcd0_d2_mfp",
+       "mfp1_16_14_d17_mfp",
+       "dsi_dp3_mfp",
+       "dsi_dn3_mfp",
+       "dsi_dnp1_cp_d2_mfp",
+       "dsi_dnp1_cp_d17_mfp",
+       "dsi_dn2_mfp",
+       "sd1_d0_d3_mfp",
+       "sd1_cmd_mfp",
        "sd1_dummy",
 };
 
 static const char * const sd2_groups[] = {
-       "dnand_data_wr",
+       "dnand_data_wr_mfp",
 };
 
 static const char * const i2c0_groups[] = {
-       "uart0_rx",
-       "uart0_tx",
-       "i2c0_mfp",
+       "uart0_rx_mfp",
+       "uart0_tx_mfp",
+       "i2c0_mfp_mfp",
 };
 
 static const char * const i2c1_groups[] = {
@@ -1448,85 +1448,85 @@ static const char * const i2c2_groups[] = {
 };
 
 static const char * const i2c3_groups[] = {
-       "uart2_rx_tx",
-       "pcm1_sync",
-       "pcm1_out",
+       "uart2_rx_tx_mfp",
+       "pcm1_sync_mfp",
+       "pcm1_out_mfp",
 };
 
 static const char * const lvds_groups[] = {
-       "lvds_o_pn",
-       "lvds_ee_pn",
-       "lvds_e_pn",
+       "lvds_o_pn_mfp",
+       "lvds_ee_pn_mfp",
+       "lvds_e_pn_mfp",
 };
 
 static const char * const bt_groups[] = {
-       "i2s_pcm1",
-       "i2s0_pcm0",
-       "i2s1_pcm0",
-       "ks_in2",
-       "ks_in1",
-       "ks_in0",
-       "ks_in3",
-       "ks_out0",
-       "ks_out1",
-       "ks_out2",
-       "lvds_o_pn",
-       "lvds_ee_pn",
-       "pcm1_in",
-       "pcm1_clk",
-       "pcm1_sync",
-       "pcm1_out",
+       "i2s_pcm1_mfp",
+       "i2s0_pcm0_mfp",
+       "i2s1_pcm0_mfp",
+       "ks_in2_mfp",
+       "ks_in1_mfp",
+       "ks_in0_mfp",
+       "ks_in3_mfp",
+       "ks_out0_mfp",
+       "ks_out1_mfp",
+       "ks_out2_mfp",
+       "lvds_o_pn_mfp",
+       "lvds_ee_pn_mfp",
+       "pcm1_in_mfp",
+       "pcm1_clk_mfp",
+       "pcm1_sync_mfp",
+       "pcm1_out_mfp",
 };
 
 static const char * const lcd0_groups[] = {
-       "lcd0_d18",
-       "lcd0_d2",
-       "mfp1_16_14_d17",
-       "lvds_o_pn",
-       "dsi_dp3",
-       "dsi_dn3",
-       "lvds_ee_pn",
-       "dsi_dnp1_cp_d2",
-       "dsi_dnp1_cp_d17",
-       "lvds_e_pn",
+       "lcd0_d18_mfp",
+       "lcd0_d2_mfp",
+       "mfp1_16_14_d17_mfp",
+       "lvds_o_pn_mfp",
+       "dsi_dp3_mfp",
+       "dsi_dn3_mfp",
+       "lvds_ee_pn_mfp",
+       "dsi_dnp1_cp_d2_mfp",
+       "dsi_dnp1_cp_d17_mfp",
+       "lvds_e_pn_mfp",
 };
 
 
 static const char * const usb30_groups[] = {
-       "ks_in1",
+       "ks_in1_mfp",
 };
 
 static const char * const clko_25m_groups[] = {
-       "clko_25m",
+       "clko_25m_mfp",
 };
 
 static const char * const mipi_csi_groups[] = {
-       "csi_cn_cp",
-       "csi_dn_dp",
+       "csi_cn_cp_mfp",
+       "csi_dn_dp_mfp",
 };
 
 static const char * const dsi_groups[] = {
-       "dsi_dn0",
-       "dsi_dp2",
-       "dsi_dp3",
-       "dsi_dn3",
-       "dsi_dp0",
-       "dsi_dnp1_cp_d2",
-       "dsi_dnp1_cp_d17",
-       "dsi_dn2",
+       "dsi_dn0_mfp",
+       "dsi_dp2_mfp",
+       "dsi_dp3_mfp",
+       "dsi_dn3_mfp",
+       "dsi_dp0_mfp",
+       "dsi_dnp1_cp_d2_mfp",
+       "dsi_dnp1_cp_d17_mfp",
+       "dsi_dn2_mfp",
        "dsi_dummy",
 };
 
 static const char * const nand_groups[] = {
-       "dnand_data_wr",
-       "dnand_acle_ce0",
-       "nand_ceb2",
-       "nand_ceb3",
+       "dnand_data_wr_mfp",
+       "dnand_acle_ce0_mfp",
+       "nand_ceb2_mfp",
+       "nand_ceb3_mfp",
        "nand_dummy",
 };
 
 static const char * const spdif_groups[] = {
-       "uart0_tx",
+       "uart0_tx_mfp",
 };
 
 static const char * const sirq0_groups[] = {
index 0de1a3a96984cce09bcb0ce406a3a44a4eeebfe1..06bd2b70af3cc30f7da81f9978d569711c6bd2c6 100644 (file)
 
 #define MODULE_NAME "pinctrl-bcm2835"
 #define BCM2835_NUM_GPIOS 54
+#define BCM2711_NUM_GPIOS 58
 #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)
-
 /* GPIO register offsets */
 #define GPFSEL0                0x0     /* Function Select */
 #define GPSET0         0x1c    /* Pin Output Set */
@@ -81,10 +79,11 @@ struct bcm2835_pinctrl {
 
        /* 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];
+       unsigned int irq_type[BCM2711_NUM_GPIOS];
 
        struct pinctrl_dev *pctl_dev;
        struct gpio_chip gpio_chip;
+       struct pinctrl_desc pctl_desc;
        struct pinctrl_gpio_range gpio_range;
 
        raw_spinlock_t irq_lock[BCM2835_NUM_BANKS];
@@ -147,6 +146,10 @@ static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
        BCM2835_GPIO_PIN(51),
        BCM2835_GPIO_PIN(52),
        BCM2835_GPIO_PIN(53),
+       BCM2835_GPIO_PIN(54),
+       BCM2835_GPIO_PIN(55),
+       BCM2835_GPIO_PIN(56),
+       BCM2835_GPIO_PIN(57),
 };
 
 /* one pin per group */
@@ -205,6 +208,10 @@ static const char * const bcm2835_gpio_groups[] = {
        "gpio51",
        "gpio52",
        "gpio53",
+       "gpio54",
+       "gpio55",
+       "gpio56",
+       "gpio57",
 };
 
 enum bcm2835_fsel {
@@ -322,7 +329,10 @@ static int bcm2835_gpio_get_direction(struct gpio_chip *chip, unsigned int offse
        if (fsel > BCM2835_FSEL_GPIO_OUT)
                return -EINVAL;
 
-       return (fsel == BCM2835_FSEL_GPIO_IN);
+       if (fsel == BCM2835_FSEL_GPIO_IN)
+               return GPIO_LINE_DIRECTION_IN;
+
+       return GPIO_LINE_DIRECTION_OUT;
 }
 
 static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -355,6 +365,22 @@ static const struct gpio_chip bcm2835_gpio_chip = {
        .can_sleep = false,
 };
 
+static const struct gpio_chip bcm2711_gpio_chip = {
+       .label = "pinctrl-bcm2711",
+       .owner = THIS_MODULE,
+       .request = gpiochip_generic_request,
+       .free = gpiochip_generic_free,
+       .direction_input = bcm2835_gpio_direction_input,
+       .direction_output = bcm2835_gpio_direction_output,
+       .get_direction = bcm2835_gpio_get_direction,
+       .get = bcm2835_gpio_get,
+       .set = bcm2835_gpio_set,
+       .set_config = gpiochip_generic_config,
+       .base = -1,
+       .ngpio = BCM2711_NUM_GPIOS,
+       .can_sleep = false,
+};
+
 static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
                                         unsigned int bank, u32 mask)
 {
@@ -401,7 +427,7 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
                bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
                bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
                break;
-       case 2: /* IRQ2 covers GPIOs 46-53 */
+       case 2: /* IRQ2 covers GPIOs 46-57 */
                bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
                break;
        }
@@ -620,7 +646,7 @@ static struct irq_chip bcm2835_gpio_irq_chip = {
 
 static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
 {
-       return ARRAY_SIZE(bcm2835_gpio_groups);
+       return BCM2835_NUM_GPIOS;
 }
 
 static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev,
@@ -778,7 +804,7 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
                err = of_property_read_u32_index(np, "brcm,pins", i, &pin);
                if (err)
                        goto out;
-               if (pin >= ARRAY_SIZE(bcm2835_gpio_pins)) {
+               if (pin >= pc->pctl_desc.npins) {
                        dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n",
                                np, pin);
                        err = -EINVAL;
@@ -854,7 +880,7 @@ static int bcm2835_pmx_get_function_groups(struct pinctrl_dev *pctldev,
 {
        /* every pin can do every function */
        *groups = bcm2835_gpio_groups;
-       *num_groups = ARRAY_SIZE(bcm2835_gpio_groups);
+       *num_groups = BCM2835_NUM_GPIOS;
 
        return 0;
 }
@@ -1054,29 +1080,62 @@ static const struct pinconf_ops bcm2711_pinconf_ops = {
        .pin_config_set = bcm2711_pinconf_set,
 };
 
-static struct pinctrl_desc bcm2835_pinctrl_desc = {
+static const struct pinctrl_desc bcm2835_pinctrl_desc = {
        .name = MODULE_NAME,
        .pins = bcm2835_gpio_pins,
-       .npins = ARRAY_SIZE(bcm2835_gpio_pins),
+       .npins = BCM2835_NUM_GPIOS,
        .pctlops = &bcm2835_pctl_ops,
        .pmxops = &bcm2835_pmx_ops,
        .confops = &bcm2835_pinconf_ops,
        .owner = THIS_MODULE,
 };
 
-static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
+static const struct pinctrl_desc bcm2711_pinctrl_desc = {
+       .name = "pinctrl-bcm2711",
+       .pins = bcm2835_gpio_pins,
+       .npins = BCM2711_NUM_GPIOS,
+       .pctlops = &bcm2835_pctl_ops,
+       .pmxops = &bcm2835_pmx_ops,
+       .confops = &bcm2711_pinconf_ops,
+       .owner = THIS_MODULE,
+};
+
+static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
        .name = MODULE_NAME,
        .npins = BCM2835_NUM_GPIOS,
 };
 
+static const struct pinctrl_gpio_range bcm2711_pinctrl_gpio_range = {
+       .name = "pinctrl-bcm2711",
+       .npins = BCM2711_NUM_GPIOS,
+};
+
+struct bcm_plat_data {
+       const struct gpio_chip *gpio_chip;
+       const struct pinctrl_desc *pctl_desc;
+       const struct pinctrl_gpio_range *gpio_range;
+};
+
+static const struct bcm_plat_data bcm2835_plat_data = {
+       .gpio_chip = &bcm2835_gpio_chip,
+       .pctl_desc = &bcm2835_pinctrl_desc,
+       .gpio_range = &bcm2835_pinctrl_gpio_range,
+};
+
+static const struct bcm_plat_data bcm2711_plat_data = {
+       .gpio_chip = &bcm2711_gpio_chip,
+       .pctl_desc = &bcm2711_pinctrl_desc,
+       .gpio_range = &bcm2711_pinctrl_gpio_range,
+};
+
 static const struct of_device_id bcm2835_pinctrl_match[] = {
        {
                .compatible = "brcm,bcm2835-gpio",
-               .data = &bcm2835_pinconf_ops,
+               .data = &bcm2835_plat_data,
        },
        {
                .compatible = "brcm,bcm2711-gpio",
-               .data = &bcm2711_pinconf_ops,
+               .data = &bcm2711_plat_data,
        },
        {}
 };
@@ -1085,14 +1144,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
+       const struct bcm_plat_data *pdata;
        struct bcm2835_pinctrl *pc;
        struct gpio_irq_chip *girq;
        struct resource iomem;
        int err, i;
        const struct of_device_id *match;
 
-       BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS);
-       BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS);
+       BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
+       BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
 
        pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
        if (!pc)
@@ -1111,7 +1171,13 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
        if (IS_ERR(pc->base))
                return PTR_ERR(pc->base);
 
-       pc->gpio_chip = bcm2835_gpio_chip;
+       match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
+       if (!match)
+               return -EINVAL;
+
+       pdata = match->data;
+
+       pc->gpio_chip = *pdata->gpio_chip;
        pc->gpio_chip.parent = dev;
        pc->gpio_chip.of_node = np;
 
@@ -1162,19 +1228,14 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
                return err;
        }
 
-       match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
-       if (match) {
-               bcm2835_pinctrl_desc.confops =
-                       (const struct pinconf_ops *)match->data;
-       }
-
-       pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
+       pc->pctl_desc = *pdata->pctl_desc;
+       pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
        if (IS_ERR(pc->pctl_dev)) {
                gpiochip_remove(&pc->gpio_chip);
                return PTR_ERR(pc->pctl_dev);
        }
 
-       pc->gpio_range = bcm2835_pinctrl_gpio_range;
+       pc->gpio_range = *pdata->gpio_range;
        pc->gpio_range.base = pc->gpio_chip.base;
        pc->gpio_range.gc = &pc->gpio_chip;
        pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
index 25166217c3e0c77e871c160e309e445190acab50..a38f0d5f47ce929f47026ea1c68ed397ac34bd9f 100644 (file)
@@ -363,7 +363,10 @@ static int iproc_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
        unsigned int offset = IPROC_GPIO_REG(gpio, IPROC_GPIO_OUT_EN_OFFSET);
        unsigned int shift = IPROC_GPIO_SHIFT(gpio);
 
-       return !(readl(chip->base + offset) & BIT(shift));
+       if (readl(chip->base + offset) & BIT(shift))
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
index f23c55e221955ed0a7721019aedc2c31c27ec4d5..821242bb4b16a71e50e61fa6ef3be5866c72c0fd 100644 (file)
@@ -176,6 +176,7 @@ const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin)
 
        return desc->name;
 }
+EXPORT_SYMBOL_GPL(pin_get_name);
 
 /* Deletes a range of pin descriptors */
 static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
index de775a85a51e6261d58dd895fb5c7c81bea0b1a6..c784663b00ad8c7b40230b34a541b49488f14a95 100644 (file)
@@ -125,28 +125,28 @@ config PINCTRL_IMX7ULP
 
 config PINCTRL_IMX8MM
        bool "IMX8MM pinctrl driver"
-       depends on ARCH_MXC && ARM64
+       depends on ARCH_MXC
        select PINCTRL_IMX
        help
          Say Y here to enable the imx8mm pinctrl driver
 
 config PINCTRL_IMX8MN
        bool "IMX8MN pinctrl driver"
-       depends on ARCH_MXC && ARM64
+       depends on ARCH_MXC
        select PINCTRL_IMX
        help
          Say Y here to enable the imx8mn pinctrl driver
 
 config PINCTRL_IMX8MP
        bool "IMX8MP pinctrl driver"
-       depends on ARCH_MXC && ARM64
+       depends on ARCH_MXC
        select PINCTRL_IMX
        help
          Say Y here to enable the imx8mp pinctrl driver
 
 config PINCTRL_IMX8MQ
        bool "IMX8MQ pinctrl driver"
-       depends on ARCH_MXC && ARM64
+       depends on ARCH_MXC
        select PINCTRL_IMX
        help
          Say Y here to enable the imx8mq pinctrl driver
index 32451e8693be718ff47342949454f33374d4aad2..905dae8c3fd86cdf3ebb33dda658344ce0670a9e 100644 (file)
@@ -1070,15 +1070,12 @@ static const struct mtk_pin_soc mt6765_data = {
        .ngrps = ARRAY_SIZE(mtk_pins_mt6765),
        .eint_hw = &mt6765_eint_hw,
        .gpio_m = 0,
-       .ies_present = true,
        .base_names = mt6765_pinctrl_register_base_names,
        .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
-       .bias_disable_set = mtk_pinconf_bias_disable_set,
-       .bias_disable_get = mtk_pinconf_bias_disable_get,
-       .bias_set = mtk_pinconf_bias_set,
-       .bias_get = mtk_pinconf_bias_get,
-       .drive_set = mtk_pinconf_drive_set_rev1,
-       .drive_get = mtk_pinconf_drive_get_rev1,
+       .bias_set_combo = mtk_pinconf_bias_set_combo,
+       .bias_get_combo = mtk_pinconf_bias_get_combo,
+       .drive_set = mtk_pinconf_drive_set_raw,
+       .drive_get = mtk_pinconf_drive_get_raw,
        .adv_pull_get = mtk_pinconf_adv_pull_get,
        .adv_pull_set = mtk_pinconf_adv_pull_set,
 };
index 9a74d5025be648d4c23835db33f0a860938f472c..60318339b618322ea7586568f48df2f5065b99b1 100644 (file)
@@ -554,13 +554,10 @@ static const struct mtk_pin_soc mt8183_data = {
        .ngrps = ARRAY_SIZE(mtk_pins_mt8183),
        .eint_hw = &mt8183_eint_hw,
        .gpio_m = 0,
-       .ies_present = true,
        .base_names = mt8183_pinctrl_register_base_names,
        .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
-       .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
-       .bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
-       .bias_set = mtk_pinconf_bias_set_rev1,
-       .bias_get = mtk_pinconf_bias_get_rev1,
+       .bias_set_combo = mtk_pinconf_bias_set_combo,
+       .bias_get_combo = mtk_pinconf_bias_get_combo,
        .drive_set = mtk_pinconf_drive_set_rev1,
        .drive_get = mtk_pinconf_drive_get_rev1,
        .adv_pull_get = mtk_pinconf_adv_pull_get,
index 20e1c890e73b30cf512a25ec1547fe0fa0708882..d3169a87e1b36f639edf94f33cebf7de1b2cf90f 100644 (file)
@@ -6,6 +6,7 @@
  *
  */
 
+#include <dt-bindings/pinctrl/mt65xx.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
@@ -66,34 +67,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
                                   const struct mtk_pin_desc *desc,
                                   int field, struct mtk_pin_field *pfd)
 {
-       const struct mtk_pin_field_calc *c, *e;
+       const struct mtk_pin_field_calc *c;
        const struct mtk_pin_reg_calc *rc;
+       int start = 0, end, check;
+       bool found = false;
        u32 bits;
 
        if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
                rc = &hw->soc->reg_cal[field];
        } else {
                dev_dbg(hw->dev,
-                       "Not support field %d for pin %d (%s)\n",
-                       field, desc->number, desc->name);
+                       "Not support field %d for this soc\n", field);
                return -ENOTSUPP;
        }
 
-       c = rc->range;
-       e = c + rc->nranges;
+       end = rc->nranges - 1;
 
-       while (c < e) {
-               if (desc->number >= c->s_pin && desc->number <= c->e_pin)
+       while (start <= end) {
+               check = (start + end) >> 1;
+               if (desc->number >= rc->range[check].s_pin
+                && desc->number <= rc->range[check].e_pin) {
+                       found = true;
+                       break;
+               } else if (start == end)
                        break;
-               c++;
+               else if (desc->number < rc->range[check].s_pin)
+                       end = check - 1;
+               else
+                       start = check + 1;
        }
 
-       if (c >= e) {
+       if (!found) {
                dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
                        field, desc->number, desc->name);
                return -ENOTSUPP;
        }
 
+       c = rc->range + check;
+
        if (c->i_base > hw->nbase - 1) {
                dev_err(hw->dev,
                        "Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
        if (err)
                return err;
 
+       if (value < 0 || value > pf.mask)
+               return -EINVAL;
+
        if (!pf.next)
                mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
                        (value & pf.mask) << pf.bitpos);
@@ -502,6 +516,226 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
        return 0;
 }
 
+/* Combo for the following pull register type:
+ * 1. PU + PD
+ * 2. PULLSEL + PULLEN
+ * 3. PUPD + R0 + R1
+ */
+static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 pullup, u32 arg)
+{
+       int err, pu, pd;
+
+       if (arg == MTK_DISABLE) {
+               pu = 0;
+               pd = 0;
+       } else if ((arg == MTK_ENABLE) && pullup) {
+               pu = 1;
+               pd = 0;
+       } else if ((arg == MTK_ENABLE) && !pullup) {
+               pu = 0;
+               pd = 1;
+       } else {
+               err = -EINVAL;
+               goto out;
+       }
+
+       err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
+       if (err)
+               goto out;
+
+       err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+
+out:
+       return err;
+}
+
+static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 pullup, u32 arg)
+{
+       int err, enable;
+
+       if (arg == MTK_DISABLE)
+               enable = 0;
+       else if (arg == MTK_ENABLE)
+               enable = 1;
+       else {
+               err = -EINVAL;
+               goto out;
+       }
+
+       err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
+       if (err)
+               goto out;
+
+       err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
+
+out:
+       return err;
+}
+
+static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 pullup, u32 arg)
+{
+       int err, r0, r1;
+
+       if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
+               pullup = 0;
+               r0 = 0;
+               r1 = 0;
+       } else if (arg == MTK_PUPD_SET_R1R0_01) {
+               r0 = 1;
+               r1 = 0;
+       } else if (arg == MTK_PUPD_SET_R1R0_10) {
+               r0 = 0;
+               r1 = 1;
+       } else if (arg == MTK_PUPD_SET_R1R0_11) {
+               r0 = 1;
+               r1 = 1;
+       } else {
+               err = -EINVAL;
+               goto out;
+       }
+
+       /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
+       err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
+       if (err)
+               goto out;
+
+       err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
+       if (err)
+               goto out;
+
+       err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
+
+out:
+       return err;
+}
+
+static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 *pullup, u32 *enable)
+{
+       int err, pu, pd;
+
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
+       if (err)
+               goto out;
+
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
+       if (err)
+               goto out;
+
+       if (pu == 0 && pd == 0) {
+               *pullup = 0;
+               *enable = MTK_DISABLE;
+       } else if (pu == 1 && pd == 0) {
+               *pullup = 1;
+               *enable = MTK_ENABLE;
+       } else if (pu == 0 && pd == 1) {
+               *pullup = 0;
+               *enable = MTK_ENABLE;
+       } else
+               err = -EINVAL;
+
+out:
+       return err;
+}
+
+static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 *pullup, u32 *enable)
+{
+       int err;
+
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
+       if (err)
+               goto out;
+
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
+
+out:
+       return err;
+}
+
+static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 *pullup, u32 *enable)
+{
+       int err, r0, r1;
+
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
+       if (err)
+               goto out;
+       /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
+       *pullup = !(*pullup);
+
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
+       if (err)
+               goto out;
+
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
+       if (err)
+               goto out;
+
+       if ((r1 == 0) && (r0 == 0))
+               *enable = MTK_PUPD_SET_R1R0_00;
+       else if ((r1 == 0) && (r0 == 1))
+               *enable = MTK_PUPD_SET_R1R0_01;
+       else if ((r1 == 1) && (r0 == 0))
+               *enable = MTK_PUPD_SET_R1R0_10;
+       else if ((r1 == 1) && (r0 == 1))
+               *enable = MTK_PUPD_SET_R1R0_11;
+       else
+               err = -EINVAL;
+
+out:
+       return err;
+}
+
+int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 pullup, u32 arg)
+{
+       int err;
+
+       err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+       if (!err)
+               goto out;
+
+       err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
+       if (!err)
+               goto out;
+
+       err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
+
+out:
+       return err;
+}
+
+int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
+                             const struct mtk_pin_desc *desc,
+                             u32 *pullup, u32 *enable)
+{
+       int err;
+
+       err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+       if (!err)
+               goto out;
+
+       err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
+       if (!err)
+               goto out;
+
+       err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
+
+out:
+       return err;
+}
+
 /* Revision 0 */
 int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
                          const struct mtk_pin_desc *desc, u32 arg)
@@ -593,6 +827,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
        return 0;
 }
 
+int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
+                              const struct mtk_pin_desc *desc, u32 arg)
+{
+       return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+}
+
+int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
+                              const struct mtk_pin_desc *desc, int *val)
+{
+       return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
+}
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
                             const struct mtk_pin_desc *desc, bool pullup,
                             u32 arg)
index 1b7da42aa1d53e4cfd5b7eefadd1f8b2ee13abea..27df08736396099b7f8c2de50f4e0e8cd12e20df 100644 (file)
@@ -216,6 +216,11 @@ struct mtk_pin_soc {
        int (*bias_get)(struct mtk_pinctrl *hw,
                        const struct mtk_pin_desc *desc, bool pullup, int *res);
 
+       int (*bias_set_combo)(struct mtk_pinctrl *hw,
+                       const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
+       int (*bias_get_combo)(struct mtk_pinctrl *hw,
+                       const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
+
        int (*drive_set)(struct mtk_pinctrl *hw,
                         const struct mtk_pin_desc *desc, u32 arg);
        int (*drive_get)(struct mtk_pinctrl *hw,
@@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
 int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
                              const struct mtk_pin_desc *desc, bool pullup,
                              int *res);
+int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 pullup, u32 enable);
+int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
+                             const struct mtk_pin_desc *desc,
+                             u32 *pullup, u32 *enable);
 
 int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
                          const struct mtk_pin_desc *desc, u32 arg);
@@ -288,6 +299,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
                               const struct mtk_pin_desc *desc, int *val);
 
+int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
+                              const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
+                              const struct mtk_pin_desc *desc, int *val);
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
                             const struct mtk_pin_desc *desc, bool pullup,
                             u32 arg);
index 67f8444f7a0cb6a5eb725c24ca90b0a8241850ca..a02ad10ec6fada549a1f03d2903d6c11da1aa4aa 100644 (file)
@@ -804,7 +804,10 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
                pctl->devdata->spec_dir_set(&reg_addr, offset);
 
        regmap_read(pctl->regmap1, reg_addr, &read_val);
-       return !(read_val & bit);
+       if (read_val & bit)
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset)
index 923264d0e9ef2c595b93d559bc04fb209e736045..3853ec3a2a8e683481e1b9e864c61c8a22f34d74 100644 (file)
@@ -78,93 +78,88 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 {
        struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
        u32 param = pinconf_to_config_param(*config);
-       int val, val2, err, reg, ret = 1;
+       int pullup, err, reg, ret = 1;
        const struct mtk_pin_desc *desc;
 
+       if (pin >= hw->soc->npins) {
+               err = -EINVAL;
+               goto out;
+       }
        desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
        switch (param) {
        case PIN_CONFIG_BIAS_DISABLE:
-               if (hw->soc->bias_disable_get) {
-                       err = hw->soc->bias_disable_get(hw, desc, &ret);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
-               break;
        case PIN_CONFIG_BIAS_PULL_UP:
-               if (hw->soc->bias_get) {
-                       err = hw->soc->bias_get(hw, desc, 1, &ret);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
-               break;
        case PIN_CONFIG_BIAS_PULL_DOWN:
-               if (hw->soc->bias_get) {
-                       err = hw->soc->bias_get(hw, desc, 0, &ret);
+               if (hw->soc->bias_get_combo) {
+                       err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
                        if (err)
-                               return err;
+                               goto out;
+                       if (param == PIN_CONFIG_BIAS_DISABLE) {
+                               if (ret == MTK_PUPD_SET_R1R0_00)
+                                       ret = MTK_DISABLE;
+                       } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
+                               /* When desire to get pull-up value, return
+                                *  error if current setting is pull-down
+                                */
+                               if (!pullup)
+                                       err = -EINVAL;
+                       } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
+                               /* When desire to get pull-down value, return
+                                *  error if current setting is pull-up
+                                */
+                               if (pullup)
+                                       err = -EINVAL;
+                       }
                } else {
-                       return -ENOTSUPP;
+                       err = -ENOTSUPP;
                }
                break;
        case PIN_CONFIG_SLEW_RATE:
-               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
-               if (err)
-                       return err;
-
-               if (!val)
-                       return -EINVAL;
-
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
                break;
        case PIN_CONFIG_INPUT_ENABLE:
        case PIN_CONFIG_OUTPUT_ENABLE:
-               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
                if (err)
-                       return err;
-
-               /* HW takes input mode as zero; output mode as non-zero */
-               if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
-                   (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
-                       return -EINVAL;
+                       goto out;
+               /*     CONFIG     Current direction return value
+                * -------------  ----------------- ----------------------
+                * OUTPUT_ENABLE       output       1 (= HW value)
+                *                     input        0 (= HW value)
+                * INPUT_ENABLE        output       0 (= reverse HW value)
+                *                     input        1 (= reverse HW value)
+                */
+               if (param == PIN_CONFIG_INPUT_ENABLE)
+                       ret = !ret;
 
                break;
        case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
                if (err)
-                       return err;
-
-               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
-               if (err)
-                       return err;
+                       goto out;
+               /* return error when in output mode
+                * because schmitt trigger only work in input mode
+                */
+               if (ret) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
-               if (val || !val2)
-                       return -EINVAL;
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
 
                break;
        case PIN_CONFIG_DRIVE_STRENGTH:
-               if (hw->soc->drive_get) {
+               if (hw->soc->drive_get)
                        err = hw->soc->drive_get(hw, desc, &ret);
-                       if (err)
-                               return err;
-               } else {
+               else
                        err = -ENOTSUPP;
-               }
                break;
        case MTK_PIN_CONFIG_TDSEL:
        case MTK_PIN_CONFIG_RDSEL:
                reg = (param == MTK_PIN_CONFIG_TDSEL) ?
                       PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
-
-               err = mtk_hw_get_value(hw, desc, reg, &val);
-               if (err)
-                       return err;
-
-               ret = val;
-
+               err = mtk_hw_get_value(hw, desc, reg, &ret);
                break;
        case MTK_PIN_CONFIG_PU_ADV:
        case MTK_PIN_CONFIG_PD_ADV:
@@ -173,28 +168,24 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 
                        pullup = param == MTK_PIN_CONFIG_PU_ADV;
                        err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
+               } else
+                       err = -ENOTSUPP;
                break;
        case MTK_PIN_CONFIG_DRV_ADV:
-               if (hw->soc->adv_drive_get) {
+               if (hw->soc->adv_drive_get)
                        err = hw->soc->adv_drive_get(hw, desc, &ret);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
+               else
+                       err = -ENOTSUPP;
                break;
        default:
-               return -ENOTSUPP;
+               err = -ENOTSUPP;
        }
 
-       *config = pinconf_to_config_packed(param, ret);
+out:
+       if (!err)
+               *config = pinconf_to_config_packed(param, ret);
 
-       return 0;
+       return err;
 }
 
 static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
@@ -206,64 +197,55 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
        int err = 0;
        u32 reg;
 
+       if (pin >= hw->soc->npins) {
+               err = -EINVAL;
+               goto err;
+       }
        desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
        switch ((u32)param) {
        case PIN_CONFIG_BIAS_DISABLE:
-               if (hw->soc->bias_disable_set) {
-                       err = hw->soc->bias_disable_set(hw, desc);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
+               if (hw->soc->bias_set_combo)
+                       err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
+               else
+                       err = -ENOTSUPP;
                break;
        case PIN_CONFIG_BIAS_PULL_UP:
-               if (hw->soc->bias_set) {
-                       err = hw->soc->bias_set(hw, desc, 1);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
+               if (hw->soc->bias_set_combo)
+                       err = hw->soc->bias_set_combo(hw, desc, 1, arg);
+               else
+                       err = -ENOTSUPP;
                break;
        case PIN_CONFIG_BIAS_PULL_DOWN:
-               if (hw->soc->bias_set) {
-                       err = hw->soc->bias_set(hw, desc, 0);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
+               if (hw->soc->bias_set_combo)
+                       err = hw->soc->bias_set_combo(hw, desc, 0, arg);
+               else
+                       err = -ENOTSUPP;
                break;
        case PIN_CONFIG_OUTPUT_ENABLE:
                err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
                                       MTK_DISABLE);
-               if (err)
+               /* Keep set direction to consider the case that a GPIO pin
+                *  does not have SMT control
+                */
+               if (err != -ENOTSUPP)
                        goto err;
 
                err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
                                       MTK_OUTPUT);
-               if (err)
-                       goto err;
                break;
        case PIN_CONFIG_INPUT_ENABLE:
-               if (hw->soc->ies_present) {
-                       mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
-                                        MTK_ENABLE);
-               }
+               /* regard all non-zero value as enable */
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
+               if (err)
+                       goto err;
 
                err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
                                       MTK_INPUT);
-               if (err)
-                       goto err;
                break;
        case PIN_CONFIG_SLEW_RATE:
-               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
-                                      arg);
-               if (err)
-                       goto err;
-
+               /* regard all non-zero value as enable */
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
                break;
        case PIN_CONFIG_OUTPUT:
                err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
@@ -273,41 +255,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 
                err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
                                       arg);
-               if (err)
-                       goto err;
                break;
+       case PIN_CONFIG_INPUT_SCHMITT:
        case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
                /* arg = 1: Input mode & SMT enable ;
                 * arg = 0: Output mode & SMT disable
                 */
-               arg = arg ? 2 : 1;
-               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
-                                      arg & 1);
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
                if (err)
                        goto err;
 
-               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
-                                      !!(arg & 2));
-               if (err)
-                       goto err;
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
                break;
        case PIN_CONFIG_DRIVE_STRENGTH:
-               if (hw->soc->drive_set) {
+               if (hw->soc->drive_set)
                        err = hw->soc->drive_set(hw, desc, arg);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
+               else
+                       err = -ENOTSUPP;
                break;
        case MTK_PIN_CONFIG_TDSEL:
        case MTK_PIN_CONFIG_RDSEL:
                reg = (param == MTK_PIN_CONFIG_TDSEL) ?
                       PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
-
                err = mtk_hw_set_value(hw, desc, reg, arg);
-               if (err)
-                       goto err;
                break;
        case MTK_PIN_CONFIG_PU_ADV:
        case MTK_PIN_CONFIG_PD_ADV:
@@ -317,20 +287,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                        pullup = param == MTK_PIN_CONFIG_PU_ADV;
                        err = hw->soc->adv_pull_set(hw, desc, pullup,
                                                    arg);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
+               } else
+                       err = -ENOTSUPP;
                break;
        case MTK_PIN_CONFIG_DRV_ADV:
-               if (hw->soc->adv_drive_set) {
+               if (hw->soc->adv_drive_set)
                        err = hw->soc->adv_drive_set(hw, desc, arg);
-                       if (err)
-                               return err;
-               } else {
-                       return -ENOTSUPP;
-               }
+               else
+                       err = -ENOTSUPP;
                break;
        default:
                err = -ENOTSUPP;
@@ -575,12 +539,120 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
        return 0;
 }
 
+static int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
+{
+       const struct mtk_pin_desc *desc;
+       int value, err;
+
+       if (gpio >= hw->soc->npins)
+               return -EINVAL;
+
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+       err = mtk_hw_get_value(hw, desc, field, &value);
+       if (err)
+               return err;
+
+       return value;
+}
+
+#define mtk_pctrl_get_pinmux(hw, gpio)                 \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_MODE)
+
+#define mtk_pctrl_get_direction(hw, gpio)              \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DIR)
+
+#define mtk_pctrl_get_out(hw, gpio)                    \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DO)
+
+#define mtk_pctrl_get_in(hw, gpio)                     \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DI)
+
+#define mtk_pctrl_get_smt(hw, gpio)                    \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_SMT)
+
+#define mtk_pctrl_get_ies(hw, gpio)                    \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_IES)
+
+#define mtk_pctrl_get_driving(hw, gpio)                        \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DRV)
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+       unsigned int gpio, char *buf, unsigned int bufLen)
+{
+       int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1;
+       const struct mtk_pin_desc *desc;
+
+       if (gpio >= hw->soc->npins)
+               return -EINVAL;
+
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+       pinmux = mtk_pctrl_get_pinmux(hw, gpio);
+       if (pinmux >= hw->soc->nfuncs)
+               pinmux -= hw->soc->nfuncs;
+
+       mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+       if (pullen == MTK_PUPD_SET_R1R0_00) {
+               pullen = 0;
+               r1 = 0;
+               r0 = 0;
+       } else if (pullen == MTK_PUPD_SET_R1R0_01) {
+               pullen = 1;
+               r1 = 0;
+               r0 = 1;
+       } else if (pullen == MTK_PUPD_SET_R1R0_10) {
+               pullen = 1;
+               r1 = 1;
+               r0 = 0;
+       } else if (pullen == MTK_PUPD_SET_R1R0_11) {
+               pullen = 1;
+               r1 = 1;
+               r0 = 1;
+       } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
+               pullen = 0;
+       }
+       len += scnprintf(buf + len, bufLen - len,
+                       "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
+                       gpio,
+                       pinmux,
+                       mtk_pctrl_get_direction(hw, gpio),
+                       mtk_pctrl_get_out(hw, gpio),
+                       mtk_pctrl_get_in(hw, gpio),
+                       mtk_pctrl_get_driving(hw, gpio),
+                       mtk_pctrl_get_smt(hw, gpio),
+                       mtk_pctrl_get_ies(hw, gpio),
+                       pullen,
+                       pullup);
+
+       if (r1 != -1) {
+               len += scnprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+                       r1, r0);
+       } else {
+               len += scnprintf(buf + len, bufLen - len, "\n");
+       }
+
+       return len;
+}
+
+#define PIN_DBG_BUF_SZ 96
+static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+                         unsigned int gpio)
+{
+       struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+       char buf[PIN_DBG_BUF_SZ];
+
+       (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+       seq_printf(s, "%s", buf);
+}
+
 static const struct pinctrl_ops mtk_pctlops = {
        .dt_node_to_map         = mtk_pctrl_dt_node_to_map,
        .dt_free_map            = pinctrl_utils_free_map,
        .get_groups_count       = mtk_pctrl_get_groups_count,
        .get_group_name         = mtk_pctrl_get_group_name,
        .get_group_pins         = mtk_pctrl_get_group_pins,
+       .pin_dbg_show           = mtk_pctrl_dbg_show,
 };
 
 static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@@ -677,6 +749,7 @@ static const struct pinconf_ops mtk_confops = {
        .pin_config_get = mtk_pinconf_get,
        .pin_config_group_get   = mtk_pconf_group_get,
        .pin_config_group_set   = mtk_pconf_group_set,
+       .is_generic = true,
 };
 
 static struct pinctrl_desc mtk_desc = {
@@ -693,13 +766,19 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
        const struct mtk_pin_desc *desc;
        int value, err;
 
+       if (gpio >= hw->soc->npins)
+               return -EINVAL;
+
        desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
        err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
        if (err)
                return err;
 
-       return !value;
+       if (value)
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
@@ -708,6 +787,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
        const struct mtk_pin_desc *desc;
        int value, err;
 
+       if (gpio >= hw->soc->npins)
+               return -EINVAL;
+
        desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
        err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,6 +804,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
        struct mtk_pinctrl *hw = gpiochip_get_data(chip);
        const struct mtk_pin_desc *desc;
 
+       if (gpio >= hw->soc->npins)
+               return;
+
        desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
        mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@@ -729,12 +814,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
 
 static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
 {
+       struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+       if (gpio >= hw->soc->npins)
+               return -EINVAL;
+
        return pinctrl_gpio_direction_input(chip->base + gpio);
 }
 
 static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
                                     int value)
 {
+       struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+       if (gpio >= hw->soc->npins)
+               return -EINVAL;
+
        mtk_gpio_set(chip, gpio, value);
 
        return pinctrl_gpio_direction_output(chip->base + gpio);
index 3d43771074e6de0cc0d1e108d4148dbef7290b7b..afb7650fd25bd3508a2d0f0330a5ef7265a9a230 100644 (file)
@@ -60,6 +60,9 @@
 int mtk_paris_pinctrl_probe(struct platform_device *pdev,
                            const struct mtk_pin_soc *soc);
 
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+       unsigned int gpio, char *buf, unsigned int bufLen);
+
 extern const struct dev_pm_ops mtk_paris_pinctrl_pm_ops;
 
 #endif /* __PINCTRL_PARIS_H */
index 926b9997159a912ac881491f91cc1cd3f99781e7..d130c635f74b0cd7fa18b014864949483acb8eb2 100644 (file)
@@ -231,10 +231,24 @@ static const unsigned int hdmi_hpd_pins[] = { GPIOH_0 };
 static const unsigned int hdmi_sda_pins[]      = { GPIOH_1 };
 static const unsigned int hdmi_scl_pins[]      = { GPIOH_2 };
 
+static const unsigned int tsin_a_d_valid_pins[] = { GPIOY_0 };
+static const unsigned int tsin_a_sop_pins[]    = { GPIOY_1 };
+static const unsigned int tsin_a_clk_pins[]    = { GPIOY_2 };
+static const unsigned int tsin_a_d0_pins[]     = { GPIOY_3 };
+static const unsigned int tsin_a_dp_pins[]     = {
+       GPIOY_4, GPIOY_5, GPIOY_6, GPIOY_7, GPIOY_8, GPIOY_9, GPIOY_10
+};
+
+static const unsigned int tsin_a_fail_pins[]   = { GPIOY_11 };
 static const unsigned int i2s_out_ch23_y_pins[]        = { GPIOY_8 };
 static const unsigned int i2s_out_ch45_y_pins[]        = { GPIOY_9 };
 static const unsigned int i2s_out_ch67_y_pins[]        = { GPIOY_10 };
 
+static const unsigned int tsin_b_d_valid_pins[] = { GPIOX_6 };
+static const unsigned int tsin_b_sop_pins[]    = { GPIOX_7 };
+static const unsigned int tsin_b_clk_pins[]    = { GPIOX_8 };
+static const unsigned int tsin_b_d0_pins[]     = { GPIOX_9 };
+
 static const unsigned int spdif_out_y_pins[]   = { GPIOY_12 };
 
 static const unsigned int gen_clk_out_pins[]   = { GPIOY_15 };
@@ -437,12 +451,22 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
        GROUP(pwm_a_x,          3,      17),
        GROUP(pwm_e,            2,      30),
        GROUP(pwm_f_x,          3,      18),
+       GROUP(tsin_b_d_valid,   3,      9),
+       GROUP(tsin_b_sop,       3,      8),
+       GROUP(tsin_b_clk,       3,      10),
+       GROUP(tsin_b_d0,        3,      7),
 
        /* Bank Y */
        GROUP(uart_cts_c,       1,      17),
        GROUP(uart_rts_c,       1,      16),
        GROUP(uart_tx_c,        1,      19),
        GROUP(uart_rx_c,        1,      18),
+       GROUP(tsin_a_fail,      3,      3),
+       GROUP(tsin_a_d_valid,   3,      2),
+       GROUP(tsin_a_sop,       3,      1),
+       GROUP(tsin_a_clk,       3,      0),
+       GROUP(tsin_a_d0,        3,      4),
+       GROUP(tsin_a_dp,        3,      5),
        GROUP(pwm_a_y,          1,      21),
        GROUP(pwm_f_y,          1,      20),
        GROUP(i2s_out_ch23_y,   1,      5),
@@ -601,6 +625,15 @@ static const char * const gpio_periphs_groups[] = {
        "GPIOX_20", "GPIOX_21", "GPIOX_22",
 };
 
+static const char * const tsin_a_groups[] = {
+       "tsin_a_clk", "tsin_a_sop", "tsin_a_d_valid", "tsin_a_d0",
+       "tsin_a_dp", "tsin_a_fail",
+};
+
+static const char * const tsin_b_groups[] = {
+       "tsin_b_clk", "tsin_b_sop", "tsin_b_d_valid", "tsin_b_d0",
+};
+
 static const char * const emmc_groups[] = {
        "emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
 };
@@ -792,6 +825,8 @@ static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
        FUNCTION(i2s_out),
        FUNCTION(spdif_out),
        FUNCTION(gen_clk_out),
+       FUNCTION(tsin_a),
+       FUNCTION(tsin_b),
 };
 
 static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
index 2ac921c83da9140fa2907bc89db297cd0ef5071d..32552d795bb2cd405a8da4dd60262103c609706c 100644 (file)
@@ -241,6 +241,17 @@ static const unsigned int tsin_a_dp_pins[] = {
        GPIODV_1, GPIODV_2, GPIODV_3, GPIODV_4, GPIODV_5, GPIODV_6, GPIODV_7,
 };
 
+static const unsigned int tsin_b_clk_pins[]    = { GPIOH_6 };
+static const unsigned int tsin_b_d0_pins[]     = { GPIOH_7 };
+static const unsigned int tsin_b_sop_pins[]    = { GPIOH_8 };
+static const unsigned int tsin_b_d_valid_pins[] = { GPIOH_9 };
+
+static const unsigned int tsin_b_fail_z4_pins[] = { GPIOZ_4 };
+static const unsigned int tsin_b_clk_z3_pins[] = { GPIOZ_3 };
+static const unsigned int tsin_b_d0_z2_pins[]  = { GPIOZ_2 };
+static const unsigned int tsin_b_sop_z1_pins[] = { GPIOZ_1 };
+static const unsigned int tsin_b_d_valid_z0_pins[] = { GPIOZ_0 };
+
 static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = {
        MESON_PIN(GPIOAO_0),
        MESON_PIN(GPIOAO_1),
@@ -438,6 +449,11 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
        GROUP(eth_txd1,         4,      12),
        GROUP(eth_txd2,         4,      11),
        GROUP(eth_txd3,         4,      10),
+       GROUP(tsin_b_fail_z4,   3,      15),
+       GROUP(tsin_b_clk_z3,    3,      16),
+       GROUP(tsin_b_d0_z2,     3,      17),
+       GROUP(tsin_b_sop_z1,    3,      18),
+       GROUP(tsin_b_d_valid_z0, 3,     19),
        GROUP(pwm_c,            3,      20),
        GROUP(i2s_out_ch23_z,   3,      26),
        GROUP(i2s_out_ch45_z,   3,      25),
@@ -454,6 +470,10 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
        GROUP(i2s_out_lr_clk,   6,      24),
        GROUP(i2s_out_ch01,     6,      23),
        GROUP(spdif_out_h,      6,      28),
+       GROUP(tsin_b_d0,        6,      17),
+       GROUP(tsin_b_sop,       6,      18),
+       GROUP(tsin_b_d_valid,   6,      19),
+       GROUP(tsin_b_clk,       6,      20),
 
        /* Bank DV */
        GROUP(uart_tx_b,        2,      16),
@@ -689,6 +709,12 @@ static const char * const tsin_a_groups[] = {
        "tsin_a_dp", "tsin_a_fail",
 };
 
+static const char * const tsin_b_groups[] = {
+       "tsin_b_clk", "tsin_b_sop", "tsin_b_d_valid", "tsin_b_d0",
+       "tsin_b_clk_z3", "tsin_b_sop_z1", "tsin_b_d_valid_z0", "tsin_b_d0_z2",
+       "tsin_b_fail_z4",
+};
+
 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",
@@ -764,6 +790,7 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = {
        FUNCTION(spdif_out),
        FUNCTION(eth_led),
        FUNCTION(tsin_a),
+       FUNCTION(tsin_b),
 };
 
 static struct meson_pmx_func meson_gxl_aobus_functions[] = {
index 243fba2541750d508a029231f57822410c40b83d..5f125bd6279dd315b16e567cc590433ad4dfc12a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinctrl.h>
@@ -402,7 +403,10 @@ static int armada_37xx_gpio_get_direction(struct gpio_chip *chip,
        mask = BIT(offset);
        regmap_read(info->regmap, reg, &val);
 
-       return !(val & mask);
+       if (val & mask)
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int armada_37xx_gpio_direction_output(struct gpio_chip *chip,
@@ -738,14 +742,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
                return ret;
        }
 
-       nr_irq_parent = platform_irq_count(pdev);
-       if (nr_irq_parent < 0) {
-               if (nr_irq_parent != -EPROBE_DEFER)
-                       dev_err(dev, "Couldn't determine irq count: %pe\n",
-                               ERR_PTR(nr_irq_parent));
-               return nr_irq_parent;
-       }
-
+       nr_irq_parent = of_irq_count(np);
        spin_lock_init(&info->irq_lock);
 
        if (!nr_irq_parent) {
@@ -782,7 +779,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
        if (!girq->parents)
                return -ENOMEM;
        for (i = 0; i < nr_irq_parent; i++) {
-               int irq = platform_get_irq(pdev, i);
+               int irq = irq_of_parse_and_map(np, i);
 
                if (irq < 0)
                        continue;
index 95f864dfdef4978e445cf7a689e054ac6c410b5e..ca7bbe4164c017991808a8a00e00a93d6248bf53 100644 (file)
@@ -831,11 +831,14 @@ static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned offset)
 
        clk_enable(nmk_chip->clk);
 
-       dir = !(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
+       dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
 
        clk_disable(nmk_chip->clk);
 
-       return dir;
+       if (dir)
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
index 9eb86309c70bf78a4279df5b5d62585552fae4b2..dfef471201f60c269bd1e1aec89391f717eb68c1 100644 (file)
@@ -286,6 +286,7 @@ out:
        kfree(cfg);
        return ret;
 }
+EXPORT_SYMBOL_GPL(pinconf_generic_parse_dt_config);
 
 int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
                struct device_node *np, struct pinctrl_map **map,
index 73aff6591de21df2455a1bfb43a3c7f59c6ef721..1fe62a35bb12dc43693d75ca0479e4b20a0c319d 100644 (file)
@@ -46,7 +46,10 @@ static int amd_gpio_get_direction(struct gpio_chip *gc, unsigned offset)
        pin_reg = readl(gpio_dev->base + offset * 4);
        raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-       return !(pin_reg & BIT(OUTPUT_ENABLE_OFF));
+       if (pin_reg & BIT(OUTPUT_ENABLE_OFF))
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int amd_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
index 207f266e9cf2c2f5a692809d907279813b33346b..52386ad29f282e543bcbe8676f18d311ec7d05ac 100644 (file)
@@ -1414,7 +1414,10 @@ static int at91_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
        u32 osr;
 
        osr = readl_relaxed(pio + PIO_OSR);
-       return !(osr & mask);
+       if (osr & mask)
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
index be5b645815e58c26075af2a43d5080ebb820130d..207cbae3a7bf9f44cb3f75ac34d33d38d05fcae9 100644 (file)
@@ -149,13 +149,16 @@ static int axp20x_gpio_get_direction(struct gpio_chip *chip,
         * going to change the value soon anyway. Default to output.
         */
        if ((val & AXP20X_GPIO_FUNCTIONS) > 2)
-               return 0;
+               return GPIO_LINE_DIRECTION_OUT;
 
        /*
         * The GPIO directions are the three lowest values.
         * 2 is input, 0 and 1 are output
         */
-       return val & 2;
+       if (val & 2)
+               return GPIO_LINE_DIRECTION_IN;
+
+       return GPIO_LINE_DIRECTION_OUT;
 }
 
 static int axp20x_gpio_output(struct gpio_chip *chip, unsigned int offset,
diff --git a/drivers/pinctrl/pinctrl-da9062.c b/drivers/pinctrl/pinctrl-da9062.c
new file mode 100644 (file)
index 0000000..1c08579
--- /dev/null
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Dialog DA9062 pinctrl and GPIO driver.
+ * Based on DA9055 GPIO driver.
+ *
+ * TODO:
+ *   - add pinmux and pinctrl support (gpio alternate mode)
+ *
+ * Documents:
+ * [1] https://www.dialog-semiconductor.com/sites/default/files/da9062_datasheet_3v6.pdf
+ *
+ * Copyright (C) 2019 Pengutronix, Marco Felsch <kernel@pengutronix.de>
+ */
+#include <linux/bits.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <linux/gpio/driver.h>
+
+#include <linux/mfd/da9062/core.h>
+#include <linux/mfd/da9062/registers.h>
+
+/*
+ * We need this get the gpio_desc from a <gpio_chip,offset> tuple to decide if
+ * the gpio is active low without a vendor specific dt-binding.
+ */
+#include "../gpio/gpiolib.h"
+
+#define DA9062_TYPE(offset)            (4 * (offset % 2))
+#define DA9062_PIN_SHIFT(offset)       (4 * (offset % 2))
+#define DA9062_PIN_ALTERNATE           0x00 /* gpio alternate mode */
+#define DA9062_PIN_GPI                 0x01 /* gpio in */
+#define DA9062_PIN_GPO_OD              0x02 /* gpio out open-drain */
+#define DA9062_PIN_GPO_PP              0x03 /* gpio out push-pull */
+#define DA9062_GPIO_NUM                        5
+
+struct da9062_pctl {
+       struct da9062 *da9062;
+       struct gpio_chip gc;
+       unsigned int pin_config[DA9062_GPIO_NUM];
+};
+
+static int da9062_pctl_get_pin_mode(struct da9062_pctl *pctl,
+                                   unsigned int offset)
+{
+       struct regmap *regmap = pctl->da9062->regmap;
+       int ret, val;
+
+       ret = regmap_read(regmap, DA9062AA_GPIO_0_1 + (offset >> 1), &val);
+       if (ret < 0)
+               return ret;
+
+       val >>= DA9062_PIN_SHIFT(offset);
+       val &= DA9062AA_GPIO0_PIN_MASK;
+
+       return val;
+}
+
+static int da9062_pctl_set_pin_mode(struct da9062_pctl *pctl,
+                                   unsigned int offset, unsigned int mode_req)
+{
+       struct regmap *regmap = pctl->da9062->regmap;
+       unsigned int mode = mode_req;
+       unsigned int mask;
+       int ret;
+
+       mode &= DA9062AA_GPIO0_PIN_MASK;
+       mode <<= DA9062_PIN_SHIFT(offset);
+       mask = DA9062AA_GPIO0_PIN_MASK << DA9062_PIN_SHIFT(offset);
+
+       ret = regmap_update_bits(regmap, DA9062AA_GPIO_0_1 + (offset >> 1),
+                                mask, mode);
+       if (!ret)
+               pctl->pin_config[offset] = mode_req;
+
+       return ret;
+}
+
+static int da9062_gpio_get(struct gpio_chip *gc, unsigned int offset)
+{
+       struct da9062_pctl *pctl = gpiochip_get_data(gc);
+       struct regmap *regmap = pctl->da9062->regmap;
+       int gpio_mode, val;
+       int ret;
+
+       gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
+       if (gpio_mode < 0)
+               return gpio_mode;
+
+       switch (gpio_mode) {
+       case DA9062_PIN_ALTERNATE:
+               return -ENOTSUPP;
+       case DA9062_PIN_GPI:
+               ret = regmap_read(regmap, DA9062AA_STATUS_B, &val);
+               if (ret < 0)
+                       return ret;
+               break;
+       case DA9062_PIN_GPO_OD:
+       case DA9062_PIN_GPO_PP:
+               ret = regmap_read(regmap, DA9062AA_GPIO_MODE0_4, &val);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return !!(val & BIT(offset));
+}
+
+static void da9062_gpio_set(struct gpio_chip *gc, unsigned int offset,
+                           int value)
+{
+       struct da9062_pctl *pctl = gpiochip_get_data(gc);
+       struct regmap *regmap = pctl->da9062->regmap;
+
+       regmap_update_bits(regmap, DA9062AA_GPIO_MODE0_4, BIT(offset),
+                          value << offset);
+}
+
+static int da9062_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+       struct da9062_pctl *pctl = gpiochip_get_data(gc);
+       int gpio_mode;
+
+       gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
+       if (gpio_mode < 0)
+               return gpio_mode;
+
+       switch (gpio_mode) {
+       case DA9062_PIN_ALTERNATE:
+               return -ENOTSUPP;
+       case DA9062_PIN_GPI:
+               return GPIO_LINE_DIRECTION_IN;
+       case DA9062_PIN_GPO_OD:
+       case DA9062_PIN_GPO_PP:
+               return GPIO_LINE_DIRECTION_OUT;
+       }
+
+       return -EINVAL;
+}
+
+static int da9062_gpio_direction_input(struct gpio_chip *gc,
+                                      unsigned int offset)
+{
+       struct da9062_pctl *pctl = gpiochip_get_data(gc);
+       struct regmap *regmap = pctl->da9062->regmap;
+       struct gpio_desc *desc = gpiochip_get_desc(gc, offset);
+       unsigned int gpi_type;
+       int ret;
+
+       ret = da9062_pctl_set_pin_mode(pctl, offset, DA9062_PIN_GPI);
+       if (ret)
+               return ret;
+
+       /*
+        * If the gpio is active low we should set it in hw too. No worries
+        * about gpio_get() because we read and return the gpio-level. So the
+        * gpiolib active_low handling is still correct.
+        *
+        * 0 - active low, 1 - active high
+        */
+       gpi_type = !gpiod_is_active_low(desc);
+
+       return regmap_update_bits(regmap, DA9062AA_GPIO_0_1 + (offset >> 1),
+                               DA9062AA_GPIO0_TYPE_MASK << DA9062_TYPE(offset),
+                               gpi_type << DA9062_TYPE(offset));
+}
+
+static int da9062_gpio_direction_output(struct gpio_chip *gc,
+                                       unsigned int offset, int value)
+{
+       struct da9062_pctl *pctl = gpiochip_get_data(gc);
+       unsigned int pin_config = pctl->pin_config[offset];
+       int ret;
+
+       ret = da9062_pctl_set_pin_mode(pctl, offset, pin_config);
+       if (ret)
+               return ret;
+
+       da9062_gpio_set(gc, offset, value);
+
+       return 0;
+}
+
+static int da9062_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
+                                 unsigned long config)
+{
+       struct da9062_pctl *pctl = gpiochip_get_data(gc);
+       struct regmap *regmap = pctl->da9062->regmap;
+       int gpio_mode;
+
+       /*
+        * We need to meet the following restrictions [1, Figure 18]:
+        * - PIN_CONFIG_BIAS_PULL_DOWN -> only allowed if the pin is used as
+        *                                gpio input
+        * - PIN_CONFIG_BIAS_PULL_UP   -> only allowed if the pin is used as
+        *                                gpio output open-drain.
+        */
+
+       switch (pinconf_to_config_param(config)) {
+       case PIN_CONFIG_BIAS_DISABLE:
+               return regmap_update_bits(regmap, DA9062AA_CONFIG_K,
+                                         BIT(offset), 0);
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+               gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
+               if (gpio_mode < 0)
+                       return -EINVAL;
+               else if (gpio_mode != DA9062_PIN_GPI)
+                       return -ENOTSUPP;
+               return regmap_update_bits(regmap, DA9062AA_CONFIG_K,
+                                         BIT(offset), BIT(offset));
+       case PIN_CONFIG_BIAS_PULL_UP:
+               gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
+               if (gpio_mode < 0)
+                       return -EINVAL;
+               else if (gpio_mode != DA9062_PIN_GPO_OD)
+                       return -ENOTSUPP;
+               return regmap_update_bits(regmap, DA9062AA_CONFIG_K,
+                                         BIT(offset), BIT(offset));
+       case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+               return da9062_pctl_set_pin_mode(pctl, offset,
+                                               DA9062_PIN_GPO_OD);
+       case PIN_CONFIG_DRIVE_PUSH_PULL:
+               return da9062_pctl_set_pin_mode(pctl, offset,
+                                               DA9062_PIN_GPO_PP);
+       default:
+               return -ENOTSUPP;
+       }
+}
+
+static int da9062_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
+{
+       struct da9062_pctl *pctl = gpiochip_get_data(gc);
+       struct da9062 *da9062 = pctl->da9062;
+
+       return regmap_irq_get_virq(da9062->regmap_irq,
+                                  DA9062_IRQ_GPI0 + offset);
+}
+
+static const struct gpio_chip reference_gc = {
+       .owner = THIS_MODULE,
+       .get = da9062_gpio_get,
+       .set = da9062_gpio_set,
+       .get_direction = da9062_gpio_get_direction,
+       .direction_input = da9062_gpio_direction_input,
+       .direction_output = da9062_gpio_direction_output,
+       .set_config = da9062_gpio_set_config,
+       .to_irq = da9062_gpio_to_irq,
+       .can_sleep = true,
+       .ngpio = DA9062_GPIO_NUM,
+       .base = -1,
+};
+
+static int da9062_pctl_probe(struct platform_device *pdev)
+{
+       struct device *parent = pdev->dev.parent;
+       struct da9062_pctl *pctl;
+       int i;
+
+       pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+       if (!pctl)
+               return -ENOMEM;
+
+       pctl->da9062 = dev_get_drvdata(parent);
+       if (!pctl->da9062)
+               return -EINVAL;
+
+       if (!device_property_present(parent, "gpio-controller"))
+               return 0;
+
+       for (i = 0; i < ARRAY_SIZE(pctl->pin_config); i++)
+               pctl->pin_config[i] = DA9062_PIN_GPO_PP;
+
+       /*
+        * Currently the driver handles only the GPIO support. The
+        * pinctrl/pinmux support can be added later if needed.
+        */
+       pctl->gc = reference_gc;
+       pctl->gc.label = dev_name(&pdev->dev);
+       pctl->gc.parent = &pdev->dev;
+#ifdef CONFIG_OF_GPIO
+       pctl->gc.of_node = parent->of_node;
+#endif
+
+       platform_set_drvdata(pdev, pctl);
+
+       return devm_gpiochip_add_data(&pdev->dev, &pctl->gc, pctl);
+}
+
+static struct platform_driver da9062_pctl_driver = {
+       .probe = da9062_pctl_probe,
+       .driver = {
+               .name   = "da9062-gpio",
+       },
+};
+module_platform_driver(da9062_pctl_driver);
+
+MODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de>");
+MODULE_DESCRIPTION("DA9062 PMIC pinctrl and GPIO Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:da9062-gpio");
index 96f04d121ebd01db1c95a8f8d553151427e7c6e8..7f5376ce7fb1846b2adc27d4b2406d1a57e56988 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
  * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
+ * Copyright (c) 2017, 2019 Paul Boddie <paul@boddie.org.uk>
  */
 
 #include <linux/compiler.h>
@@ -900,6 +901,7 @@ static int jz4780_mmc0_8bit_a_pins[] = { 0x04, 0x05, 0x06, 0x07, 0x18, };
 static int jz4780_i2c3_pins[] = { 0x6a, 0x6b, };
 static int jz4780_i2c4_e_pins[] = { 0x8c, 0x8d, };
 static int jz4780_i2c4_f_pins[] = { 0xb9, 0xb8, };
+static int jz4780_hdmi_ddc_pins[] = { 0xb9, 0xb8, };
 
 static int jz4780_uart2_data_funcs[] = { 1, 1, };
 static int jz4780_uart2_hwflow_funcs[] = { 1, 1, };
@@ -908,6 +910,7 @@ static int jz4780_mmc0_8bit_a_funcs[] = { 1, 1, 1, 1, 1, };
 static int jz4780_i2c3_funcs[] = { 1, 1, };
 static int jz4780_i2c4_e_funcs[] = { 1, 1, };
 static int jz4780_i2c4_f_funcs[] = { 1, 1, };
+static int jz4780_hdmi_ddc_funcs[] = { 0, 0, };
 
 static const struct group_desc jz4780_groups[] = {
        INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
@@ -950,6 +953,7 @@ static const struct group_desc jz4780_groups[] = {
        INGENIC_PIN_GROUP("i2c3-data", jz4780_i2c3),
        INGENIC_PIN_GROUP("i2c4-data-e", jz4780_i2c4_e),
        INGENIC_PIN_GROUP("i2c4-data-f", jz4780_i2c4_f),
+       INGENIC_PIN_GROUP("hdmi-ddc", jz4780_hdmi_ddc),
        INGENIC_PIN_GROUP("cim-data", jz4770_cim_8bit),
        INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit),
        { "lcd-no-pins", },
@@ -982,6 +986,7 @@ static const char *jz4780_nemc_groups[] = {
 static const char *jz4780_i2c3_groups[] = { "i2c3-data", };
 static const char *jz4780_i2c4_groups[] = { "i2c4-data-e", "i2c4-data-f", };
 static const char *jz4780_cim_groups[] = { "cim-data", };
+static const char *jz4780_hdmi_ddc_groups[] = { "hdmi-ddc", };
 
 static const struct function_desc jz4780_functions[] = {
        { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
@@ -1014,6 +1019,8 @@ static const struct function_desc jz4780_functions[] = {
        { "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
        { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
        { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
+       { "hdmi-ddc", jz4780_hdmi_ddc_groups,
+                     ARRAY_SIZE(jz4780_hdmi_ddc_groups), },
 };
 
 static const struct ingenic_chip_info jz4780_chip_info = {
@@ -1437,6 +1444,19 @@ static int x1830_mmc1_4bit_pins[] = { 0x45, 0x46, 0x47, };
 static int x1830_i2c0_pins[] = { 0x0c, 0x0d, };
 static int x1830_i2c1_pins[] = { 0x39, 0x3a, };
 static int x1830_i2c2_pins[] = { 0x5b, 0x5c, };
+static int x1830_lcd_rgb_18bit_pins[] = {
+       0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+       0x68, 0x69, 0x6c, 0x6d, 0x6e, 0x6f,
+       0x70, 0x71, 0x72, 0x73, 0x76, 0x77,
+       0x78, 0x79, 0x7a, 0x7b,
+};
+static int x1830_lcd_slcd_8bit_pins[] = {
+       0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x6c, 0x6d,
+       0x69, 0x72, 0x73, 0x7b, 0x7a,
+};
+static int x1830_lcd_slcd_16bit_pins[] = {
+       0x6e, 0x6f, 0x70, 0x71, 0x76, 0x77, 0x78, 0x79,
+};
 static int x1830_pwm_pwm0_b_pins[] = { 0x31, };
 static int x1830_pwm_pwm0_c_pins[] = { 0x4b, };
 static int x1830_pwm_pwm1_b_pins[] = { 0x32, };
@@ -1486,6 +1506,16 @@ static int x1830_mmc1_4bit_funcs[] = { 0, 0, 0, };
 static int x1830_i2c0_funcs[] = { 1, 1, };
 static int x1830_i2c1_funcs[] = { 0, 0, };
 static int x1830_i2c2_funcs[] = { 1, 1, };
+static int x1830_lcd_rgb_18bit_funcs[] = {
+       0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0,
+};
+static int x1830_lcd_slcd_8bit_funcs[] = {
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+static int x1830_lcd_slcd_16bit_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, };
 static int x1830_pwm_pwm0_b_funcs[] = { 0, };
 static int x1830_pwm_pwm0_c_funcs[] = { 1, };
 static int x1830_pwm_pwm1_b_funcs[] = { 0, };
@@ -1534,6 +1564,10 @@ static const struct group_desc x1830_groups[] = {
        INGENIC_PIN_GROUP("i2c0-data", x1830_i2c0),
        INGENIC_PIN_GROUP("i2c1-data", x1830_i2c1),
        INGENIC_PIN_GROUP("i2c2-data", x1830_i2c2),
+       INGENIC_PIN_GROUP("lcd-rgb-18bit", x1830_lcd_rgb_18bit),
+       INGENIC_PIN_GROUP("lcd-slcd-8bit", x1830_lcd_slcd_8bit),
+       INGENIC_PIN_GROUP("lcd-slcd-16bit", x1830_lcd_slcd_16bit),
+       { "lcd-no-pins", },
        INGENIC_PIN_GROUP("pwm0-b", x1830_pwm_pwm0_b),
        INGENIC_PIN_GROUP("pwm0-c", x1830_pwm_pwm0_c),
        INGENIC_PIN_GROUP("pwm1-b", x1830_pwm_pwm1_b),
@@ -1572,6 +1606,9 @@ static const char *x1830_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
 static const char *x1830_i2c0_groups[] = { "i2c0-data", };
 static const char *x1830_i2c1_groups[] = { "i2c1-data", };
 static const char *x1830_i2c2_groups[] = { "i2c2-data", };
+static const char *x1830_lcd_groups[] = {
+       "lcd-rgb-18bit", "lcd-slcd-8bit", "lcd-slcd-16bit", "lcd-no-pins",
+};
 static const char *x1830_pwm0_groups[] = { "pwm0-b", "pwm0-c", };
 static const char *x1830_pwm1_groups[] = { "pwm1-b", "pwm1-c", };
 static const char *x1830_pwm2_groups[] = { "pwm2-c-8", "pwm2-c-13", };
@@ -1593,6 +1630,7 @@ static const struct function_desc x1830_functions[] = {
        { "i2c0", x1830_i2c0_groups, ARRAY_SIZE(x1830_i2c0_groups), },
        { "i2c1", x1830_i2c1_groups, ARRAY_SIZE(x1830_i2c1_groups), },
        { "i2c2", x1830_i2c2_groups, ARRAY_SIZE(x1830_i2c2_groups), },
+       { "lcd", x1830_lcd_groups, ARRAY_SIZE(x1830_lcd_groups), },
        { "pwm0", x1830_pwm0_groups, ARRAY_SIZE(x1830_pwm0_groups), },
        { "pwm1", x1830_pwm1_groups, ARRAY_SIZE(x1830_pwm1_groups), },
        { "pwm2", x1830_pwm2_groups, ARRAY_SIZE(x1830_pwm2_groups), },
@@ -1916,13 +1954,19 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
        struct ingenic_pinctrl *jzpc = jzgc->jzpc;
        unsigned int pin = gc->base + offset;
 
-       if (jzpc->info->version >= ID_JZ4760)
-               return ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1);
+       if (jzpc->info->version >= ID_JZ4760) {
+               if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1))
+                       return GPIO_LINE_DIRECTION_IN;
+               return GPIO_LINE_DIRECTION_OUT;
+       }
 
        if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT))
-               return true;
+               return GPIO_LINE_DIRECTION_IN;
+
+       if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR))
+               return GPIO_LINE_DIRECTION_OUT;
 
-       return !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR);
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static const struct pinctrl_ops ingenic_pctlops = {
@@ -2158,7 +2202,8 @@ static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                        break;
 
                default:
-                       unreachable();
+                       /* unreachable */
+                       break;
                }
        }
 
index eb3dd0d46d6c0f2963d11f006c045bb11ad62bee..ed8eac6c14944c9616d9133ab59dc21451443a22 100644 (file)
@@ -604,7 +604,10 @@ static int ocelot_gpio_get_direction(struct gpio_chip *chip,
 
        regmap_read(info->map, REG(OCELOT_GPIO_OE, info, offset), &val);
 
-       return !(val & BIT(offset % 32));
+       if (val & BIT(offset % 32))
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int ocelot_gpio_direction_input(struct gpio_chip *chip,
index 674b7b5919df527aaf39414ed38b3128fe7520cd..5a312279b3c78e6bc354bff35af52d0c4bcd8963 100644 (file)
@@ -756,7 +756,10 @@ static int oxnas_gpio_get_direction(struct gpio_chip *chip,
        struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
        u32 mask = BIT(offset);
 
-       return !(readl_relaxed(bank->reg_base + OUTPUT_EN) & mask);
+       if (readl_relaxed(bank->reg_base + OUTPUT_EN) & mask)
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int oxnas_gpio_direction_input(struct gpio_chip *chip,
index e5d6d3f9753e3df40a2c706cd48f214c21b637d3..a6e2a4a4ca9529510f158b131af77d2a87e38fba 100644 (file)
@@ -1990,7 +1990,10 @@ static int pic32_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
 {
        struct pic32_gpio_bank *bank = gpiochip_get_data(chip);
 
-       return !!(readl(bank->reg_base + TRIS_REG) & BIT(offset));
+       if (readl(bank->reg_base + TRIS_REG) & BIT(offset))
+               return GPIO_LINE_DIRECTION_IN;
+
+       return GPIO_LINE_DIRECTION_OUT;
 }
 
 static void pic32_gpio_irq_ack(struct irq_data *data)
index fa370c171cadd1bd686bef84c61f5a7f84109bed..ec761ba2a2da82132983f1a62ad360aaac477f79 100644 (file)
@@ -1166,7 +1166,10 @@ static int pistachio_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
 {
        struct pistachio_gpio_bank *bank = gpiochip_get_data(chip);
 
-       return !(gpio_readl(bank, GPIO_OUTPUT_EN) & BIT(offset));
+       if (gpio_readl(bank, GPIO_OUTPUT_EN) & BIT(offset))
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int pistachio_gpio_get(struct gpio_chip *chip, unsigned offset)
index 26adbe9d6d42091079e65c502042145c7d3af492..cccbe072274e314defd810b639c9579737b0c6c2 100644 (file)
@@ -184,7 +184,7 @@ static int rk805_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
 
        /* default output*/
        if (!pci->pin_cfg[offset].dir_msk)
-               return 0;
+               return GPIO_LINE_DIRECTION_OUT;
 
        ret = regmap_read(pci->rk808->regmap,
                          pci->pin_cfg[offset].reg,
@@ -194,7 +194,10 @@ static int rk805_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
                return ret;
        }
 
-       return !(val & pci->pin_cfg[offset].dir_msk);
+       if (val & pci->pin_cfg[offset].dir_msk)
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static const struct gpio_chip rk805_gpio_chip = {
index fc9a2a9959d9ae447892eac9306873b5a626cf31..0989513463393291d27e981f80dba051f79534c4 100644 (file)
@@ -2549,7 +2549,10 @@ static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
        data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
        clk_disable(bank->clk);
 
-       return !(data & BIT(offset));
+       if (data & BIT(offset))
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 /*
index 617585be6a7d025f4c804ea12e56893bb50b3a2c..da2d8365c690ed01ae60ebe47ccfa9c5246bba85 100644 (file)
@@ -777,7 +777,10 @@ static int rza1_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
 {
        struct rza1_port *port = gpiochip_get_data(chip);
 
-       return !!rza1_get_bit(port, RZA1_PM_REG, gpio);
+       if (rza1_get_bit(port, RZA1_PM_REG, gpio))
+               return GPIO_LINE_DIRECTION_IN;
+
+       return GPIO_LINE_DIRECTION_OUT;
 }
 
 static int rza1_gpio_direction_input(struct gpio_chip *chip,
index a205964e839b594fa2564ef6856011b69653e45f..c5bf98c86b2b369d5f2de20609717aebbdd3fdae 100644 (file)
@@ -135,10 +135,10 @@ static int rza2_chip_get_direction(struct gpio_chip *chip, unsigned int offset)
        reg16 = (reg16 >> (pin * 2)) & RZA2_PDR_MASK;
 
        if (reg16 == RZA2_PDR_OUTPUT)
-               return 0;
+               return GPIO_LINE_DIRECTION_OUT;
 
        if (reg16 == RZA2_PDR_INPUT)
-               return 1;
+               return GPIO_LINE_DIRECTION_IN;
 
        /*
         * This GPIO controller has a default Hi-Z state that is not input or
@@ -146,7 +146,7 @@ static int rza2_chip_get_direction(struct gpio_chip *chip, unsigned int offset)
         */
        rza2_pin_to_gpio(priv->base, offset, 1);
 
-       return 1;
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int rza2_chip_direction_input(struct gpio_chip *chip,
index 4f39a7945d0178557289ba2f30cbcfcd38c3c8e4..7b8c7a0b13de09b483dd054e6cc47a47e0447349 100644 (file)
@@ -746,7 +746,10 @@ static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
        function = st_pctl_get_pin_function(&pc, offset);
        if (function) {
                st_pinconf_get_direction(&pc, offset, &config);
-               return !ST_PINCONF_UNPACK_OE(config);
+               if (ST_PINCONF_UNPACK_OE(config))
+                       return GPIO_LINE_DIRECTION_OUT;
+
+               return GPIO_LINE_DIRECTION_IN;
        }
 
        /*
@@ -758,7 +761,10 @@ static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
                direction |= ((value >> offset) & 0x1) << i;
        }
 
-       return (direction == ST_GPIO_DIRECTION_IN);
+       if (direction == ST_GPIO_DIRECTION_IN)
+               return GPIO_LINE_DIRECTION_IN;
+
+       return GPIO_LINE_DIRECTION_OUT;
 }
 
 /* Pinctrl Groups */
@@ -996,6 +1002,7 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
        unsigned int function;
        int offset = st_gpio_pin(pin_id);
        char f[16];
+       int oe;
 
        mutex_unlock(&pctldev->mutex);
        pc = st_get_pio_control(pctldev, pin_id);
@@ -1008,10 +1015,11 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
        else
                snprintf(f, 5, "GPIO");
 
+       oe = st_gpio_get_direction(&pc_to_bank(pc)->gpio_chip, offset);
        seq_printf(s, "[OE:%d,PU:%ld,OD:%ld]\t%s\n"
                "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
                "de:%ld,rt-clk:%ld,rt-delay:%ld]",
-               !st_gpio_get_direction(&pc_to_bank(pc)->gpio_chip, offset),
+               (oe == GPIO_LINE_DIRECTION_OUT),
                ST_PINCONF_UNPACK_PU(config),
                ST_PINCONF_UNPACK_OD(config),
                f,
index 16723797fa7caf7992b793273fa27b442229d71c..60100b45f5e5ed8377df9eaaad3785be36901328 100644 (file)
@@ -134,10 +134,14 @@ static int stmfx_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
        ret = regmap_read(pctl->stmfx->map, reg, &val);
        /*
         * On stmfx, gpio pins direction is (0)input, (1)output.
-        * .get_direction returns 0=out, 1=in
         */
+       if (ret)
+               return ret;
 
-       return ret ? ret : !(val & mask);
+       if (val & mask)
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int stmfx_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
@@ -223,6 +227,13 @@ static int stmfx_pinconf_get(struct pinctrl_dev *pctldev,
        dir = stmfx_gpio_get_direction(&pctl->gpio_chip, pin);
        if (dir < 0)
                return dir;
+
+       /*
+        * Currently the gpiolib IN is 1 and OUT is 0 but let's not count
+        * on it just to be on the safe side also in the future :)
+        */
+       dir = (dir == GPIO_LINE_DIRECTION_IN) ? 1 : 0;
+
        type = stmfx_pinconf_get_type(pctl, pin);
        if (type < 0)
                return type;
@@ -360,7 +371,7 @@ static void stmfx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
        if (val < 0)
                return;
 
-       if (!dir) {
+       if (dir == GPIO_LINE_DIRECTION_OUT) {
                seq_printf(s, "output %s ", val ? "high" : "low");
                if (type)
                        seq_printf(s, "open drain %s internal pull-up ",
index 566665931a042a9df00e53425575ff0fb6ae596b..6e74bd87d9591b21a97ab1cd10638decbd4b83ba 100644 (file)
@@ -391,13 +391,16 @@ static int sx150x_gpio_get_direction(struct gpio_chip *chip,
        int ret;
 
        if (sx150x_pin_is_oscio(pctl, offset))
-               return false;
+               return GPIO_LINE_DIRECTION_OUT;
 
        ret = regmap_read(pctl->regmap, pctl->data->reg_dir, &value);
        if (ret < 0)
                return ret;
 
-       return !!(value & BIT(offset));
+       if (value & BIT(offset))
+               return GPIO_LINE_DIRECTION_IN;
+
+       return GPIO_LINE_DIRECTION_OUT;
 }
 
 static int sx150x_gpio_get(struct gpio_chip *chip, unsigned int offset)
@@ -687,7 +690,7 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
                if (ret < 0)
                        return ret;
 
-               if (ret)
+               if (ret == GPIO_LINE_DIRECTION_IN)
                        return -EINVAL;
 
                ret = sx150x_gpio_get(&pctl->gpio, pin);
index 811af2f81c398cb8dffc22f7c8f6d7e4b3c294f6..c5d4428f1f9489e97a4c5435ec9b2e74caadd896 100644 (file)
@@ -50,6 +50,16 @@ config PINCTRL_IPQ8074
          Qualcomm Technologies Inc. IPQ8074 platform. Select this for
          IPQ8074.
 
+config PINCTRL_IPQ6018
+       tristate "Qualcomm Technologies, Inc. IPQ6018 pin controller driver"
+       depends on GPIOLIB && OF
+       select PINCTRL_MSM
+       help
+         This is the pinctrl, pinmux, pinconf and gpiolib driver for
+         the Qualcomm Technologies Inc. TLMM block found on the
+         Qualcomm Technologies Inc. IPQ6018 platform. Select this for
+         IPQ6018.
+
 config PINCTRL_MSM8660
        tristate "Qualcomm 8660 pin controller driver"
        depends on GPIOLIB && OF
index c2c2f9ad6827dabe07843a279c642792cdab4b98..d9e09045a7764b341f4106f2cac09c2c7e9f9d4a 100644 (file)
@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_APQ8084)   += pinctrl-apq8084.o
 obj-$(CONFIG_PINCTRL_IPQ4019)  += pinctrl-ipq4019.o
 obj-$(CONFIG_PINCTRL_IPQ8064)  += pinctrl-ipq8064.o
 obj-$(CONFIG_PINCTRL_IPQ8074)  += pinctrl-ipq8074.o
+obj-$(CONFIG_PINCTRL_IPQ6018)  += pinctrl-ipq6018.o
 obj-$(CONFIG_PINCTRL_MSM8660)  += pinctrl-msm8660.o
 obj-$(CONFIG_PINCTRL_MSM8960)  += pinctrl-msm8960.o
 obj-$(CONFIG_PINCTRL_MSM8X74)  += pinctrl-msm8x74.o
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq6018.c b/drivers/pinctrl/qcom/pinctrl-ipq6018.c
new file mode 100644 (file)
index 0000000..38c33a7
--- /dev/null
@@ -0,0 +1,1107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ */
+
+#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 REG_SIZE 0x1000
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9)       \
+       {                                               \
+               .name = "gpio" #id,                     \
+               .pins = gpio##id##_pins,                \
+               .npins = (unsigned int)ARRAY_SIZE(gpio##id##_pins),     \
+               .funcs = (int[]){                       \
+                       msm_mux_gpio, /* gpio mode */   \
+                       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                    \
+               },                                      \
+               .nfuncs = 10,                           \
+               .ctl_reg = REG_SIZE * id,                       \
+               .io_reg = 0x4 + REG_SIZE * id,          \
+               .intr_cfg_reg = 0x8 + REG_SIZE * id,            \
+               .intr_status_reg = 0xc + REG_SIZE * id, \
+               .intr_target_reg = 0x8 + REG_SIZE * 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 = 3,      \
+               .intr_raw_status_bit = 4,       \
+               .intr_polarity_bit = 1,         \
+               .intr_detection_bit = 2,        \
+               .intr_detection_width = 2,      \
+       }
+
+static const struct pinctrl_pin_desc ipq6018_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"),
+};
+
+#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);
+
+enum ipq6018_functions {
+       msm_mux_atest_char,
+       msm_mux_atest_char0,
+       msm_mux_atest_char1,
+       msm_mux_atest_char2,
+       msm_mux_atest_char3,
+       msm_mux_audio0,
+       msm_mux_audio1,
+       msm_mux_audio2,
+       msm_mux_audio3,
+       msm_mux_audio_rxbclk,
+       msm_mux_audio_rxfsync,
+       msm_mux_audio_rxmclk,
+       msm_mux_audio_rxmclkin,
+       msm_mux_audio_txbclk,
+       msm_mux_audio_txfsync,
+       msm_mux_audio_txmclk,
+       msm_mux_audio_txmclkin,
+       msm_mux_blsp0_i2c,
+       msm_mux_blsp0_spi,
+       msm_mux_blsp0_uart,
+       msm_mux_blsp1_i2c,
+       msm_mux_blsp1_spi,
+       msm_mux_blsp1_uart,
+       msm_mux_blsp2_i2c,
+       msm_mux_blsp2_spi,
+       msm_mux_blsp2_uart,
+       msm_mux_blsp3_i2c,
+       msm_mux_blsp3_spi,
+       msm_mux_blsp3_uart,
+       msm_mux_blsp4_i2c,
+       msm_mux_blsp4_spi,
+       msm_mux_blsp4_uart,
+       msm_mux_blsp5_i2c,
+       msm_mux_blsp5_uart,
+       msm_mux_burn0,
+       msm_mux_burn1,
+       msm_mux_cri_trng,
+       msm_mux_cri_trng0,
+       msm_mux_cri_trng1,
+       msm_mux_cxc0,
+       msm_mux_cxc1,
+       msm_mux_dbg_out,
+       msm_mux_gcc_plltest,
+       msm_mux_gcc_tlmm,
+       msm_mux_gpio,
+       msm_mux_lpass_aud,
+       msm_mux_lpass_aud0,
+       msm_mux_lpass_aud1,
+       msm_mux_lpass_aud2,
+       msm_mux_lpass_pcm,
+       msm_mux_lpass_pdm,
+       msm_mux_mac00,
+       msm_mux_mac01,
+       msm_mux_mac10,
+       msm_mux_mac11,
+       msm_mux_mac12,
+       msm_mux_mac13,
+       msm_mux_mac20,
+       msm_mux_mac21,
+       msm_mux_mdc,
+       msm_mux_mdio,
+       msm_mux_pcie0_clk,
+       msm_mux_pcie0_rst,
+       msm_mux_pcie0_wake,
+       msm_mux_prng_rosc,
+       msm_mux_pta1_0,
+       msm_mux_pta1_1,
+       msm_mux_pta1_2,
+       msm_mux_pta2_0,
+       msm_mux_pta2_1,
+       msm_mux_pta2_2,
+       msm_mux_pwm00,
+       msm_mux_pwm01,
+       msm_mux_pwm02,
+       msm_mux_pwm03,
+       msm_mux_pwm04,
+       msm_mux_pwm10,
+       msm_mux_pwm11,
+       msm_mux_pwm12,
+       msm_mux_pwm13,
+       msm_mux_pwm14,
+       msm_mux_pwm20,
+       msm_mux_pwm21,
+       msm_mux_pwm22,
+       msm_mux_pwm23,
+       msm_mux_pwm24,
+       msm_mux_pwm30,
+       msm_mux_pwm31,
+       msm_mux_pwm32,
+       msm_mux_pwm33,
+       msm_mux_qdss_cti_trig_in_a0,
+       msm_mux_qdss_cti_trig_in_a1,
+       msm_mux_qdss_cti_trig_out_a0,
+       msm_mux_qdss_cti_trig_out_a1,
+       msm_mux_qdss_cti_trig_in_b0,
+       msm_mux_qdss_cti_trig_in_b1,
+       msm_mux_qdss_cti_trig_out_b0,
+       msm_mux_qdss_cti_trig_out_b1,
+       msm_mux_qdss_traceclk_a,
+       msm_mux_qdss_tracectl_a,
+       msm_mux_qdss_tracedata_a,
+       msm_mux_qdss_traceclk_b,
+       msm_mux_qdss_tracectl_b,
+       msm_mux_qdss_tracedata_b,
+       msm_mux_qpic_pad,
+       msm_mux_rx0,
+       msm_mux_rx1,
+       msm_mux_rx_swrm,
+       msm_mux_rx_swrm0,
+       msm_mux_rx_swrm1,
+       msm_mux_sd_card,
+       msm_mux_sd_write,
+       msm_mux_tsens_max,
+       msm_mux_tx_swrm,
+       msm_mux_tx_swrm0,
+       msm_mux_tx_swrm1,
+       msm_mux_tx_swrm2,
+       msm_mux_wci20,
+       msm_mux_wci21,
+       msm_mux_wci22,
+       msm_mux_wci23,
+       msm_mux_wsa_swrm,
+       msm_mux__,
+};
+
+static const char * const blsp3_uart_groups[] = {
+       "gpio73", "gpio74", "gpio75", "gpio76",
+};
+
+static const char * const blsp3_i2c_groups[] = {
+       "gpio73", "gpio74",
+};
+
+static const char * const blsp3_spi_groups[] = {
+       "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", "gpio78", "gpio79",
+};
+
+static const char * const wci20_groups[] = {
+       "gpio0", "gpio2",
+};
+
+static const char * const qpic_pad_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio9", "gpio10",
+       "gpio11", "gpio17",
+};
+
+static const char * const burn0_groups[] = {
+       "gpio0",
+};
+
+static const char * const mac12_groups[] = {
+       "gpio1", "gpio11",
+};
+
+static const char * const qdss_tracectl_b_groups[] = {
+       "gpio1",
+};
+
+static const char * const burn1_groups[] = {
+       "gpio1",
+};
+
+static const char * const qdss_traceclk_b_groups[] = {
+       "gpio0",
+};
+
+static const char * const qdss_tracedata_b_groups[] = {
+       "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8", "gpio9",
+       "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15", "gpio16",
+       "gpio17",
+};
+
+static const char * const mac01_groups[] = {
+       "gpio3", "gpio4",
+};
+
+static const char * const mac21_groups[] = {
+       "gpio5", "gpio6",
+};
+
+static const char * const atest_char_groups[] = {
+       "gpio9",
+};
+
+static const char * const cxc0_groups[] = {
+       "gpio9", "gpio16",
+};
+
+static const char * const mac13_groups[] = {
+       "gpio9", "gpio16",
+};
+
+static const char * const dbg_out_groups[] = {
+       "gpio9",
+};
+
+static const char * const wci22_groups[] = {
+       "gpio11", "gpio17",
+};
+
+static const char * const pwm00_groups[] = {
+       "gpio18",
+};
+
+static const char * const atest_char0_groups[] = {
+       "gpio18",
+};
+
+static const char * const wci23_groups[] = {
+       "gpio18", "gpio19",
+};
+
+static const char * const mac11_groups[] = {
+       "gpio18", "gpio19",
+};
+
+static const char * const pwm10_groups[] = {
+       "gpio19",
+};
+
+static const char * const atest_char1_groups[] = {
+       "gpio19",
+};
+
+static const char * const pwm20_groups[] = {
+       "gpio20",
+};
+
+static const char * const atest_char2_groups[] = {
+       "gpio20",
+};
+
+static const char * const pwm30_groups[] = {
+       "gpio21",
+};
+
+static const char * const atest_char3_groups[] = {
+       "gpio21",
+};
+
+static const char * const audio_txmclk_groups[] = {
+       "gpio22",
+};
+
+static const char * const audio_txmclkin_groups[] = {
+       "gpio22",
+};
+
+static const char * const pwm02_groups[] = {
+       "gpio22",
+};
+
+static const char * const tx_swrm0_groups[] = {
+       "gpio22",
+};
+
+static const char * const qdss_cti_trig_out_b0_groups[] = {
+       "gpio22",
+};
+
+static const char * const audio_txbclk_groups[] = {
+       "gpio23",
+};
+
+static const char * const pwm12_groups[] = {
+       "gpio23",
+};
+
+static const char * const wsa_swrm_groups[] = {
+       "gpio23", "gpio24",
+};
+
+static const char * const tx_swrm1_groups[] = {
+       "gpio23",
+};
+
+static const char * const qdss_cti_trig_in_b0_groups[] = {
+       "gpio23",
+};
+
+static const char * const audio_txfsync_groups[] = {
+       "gpio24",
+};
+
+static const char * const pwm22_groups[] = {
+       "gpio24",
+};
+
+static const char * const tx_swrm2_groups[] = {
+       "gpio24",
+};
+
+static const char * const qdss_cti_trig_out_b1_groups[] = {
+       "gpio24",
+};
+
+static const char * const audio0_groups[] = {
+       "gpio25", "gpio32",
+};
+
+static const char * const pwm32_groups[] = {
+       "gpio25",
+};
+
+static const char * const tx_swrm_groups[] = {
+       "gpio25",
+};
+
+static const char * const qdss_cti_trig_in_b1_groups[] = {
+       "gpio25",
+};
+
+static const char * const audio1_groups[] = {
+       "gpio26", "gpio33",
+};
+
+static const char * const pwm04_groups[] = {
+       "gpio26",
+};
+
+static const char * const audio2_groups[] = {
+       "gpio27",
+};
+
+static const char * const pwm14_groups[] = {
+       "gpio27",
+};
+
+static const char * const audio3_groups[] = {
+       "gpio28",
+};
+
+static const char * const pwm24_groups[] = {
+       "gpio28",
+};
+
+static const char * const audio_rxmclk_groups[] = {
+       "gpio29",
+};
+
+static const char * const audio_rxmclkin_groups[] = {
+       "gpio29",
+};
+
+static const char * const pwm03_groups[] = {
+       "gpio29",
+};
+
+static const char * const lpass_pdm_groups[] = {
+       "gpio29", "gpio30", "gpio31", "gpio32",
+};
+
+static const char * const lpass_aud_groups[] = {
+       "gpio29",
+};
+
+static const char * const qdss_cti_trig_in_a1_groups[] = {
+       "gpio29",
+};
+
+static const char * const audio_rxbclk_groups[] = {
+       "gpio30",
+};
+
+static const char * const pwm13_groups[] = {
+       "gpio30",
+};
+
+static const char * const lpass_aud0_groups[] = {
+       "gpio30",
+};
+
+static const char * const rx_swrm_groups[] = {
+       "gpio30",
+};
+
+static const char * const qdss_cti_trig_out_a1_groups[] = {
+       "gpio30",
+};
+
+static const char * const audio_rxfsync_groups[] = {
+       "gpio31",
+};
+
+static const char * const pwm23_groups[] = {
+       "gpio31",
+};
+
+static const char * const lpass_aud1_groups[] = {
+       "gpio31",
+};
+
+static const char * const rx_swrm0_groups[] = {
+       "gpio31",
+};
+
+static const char * const qdss_cti_trig_in_a0_groups[] = {
+       "gpio31",
+};
+
+static const char * const pwm33_groups[] = {
+       "gpio32",
+};
+
+static const char * const lpass_aud2_groups[] = {
+       "gpio32",
+};
+
+static const char * const rx_swrm1_groups[] = {
+       "gpio32",
+};
+
+static const char * const qdss_cti_trig_out_a0_groups[] = {
+       "gpio32",
+};
+
+static const char * const lpass_pcm_groups[] = {
+       "gpio34", "gpio35", "gpio36", "gpio37",
+};
+
+static const char * const mac10_groups[] = {
+       "gpio34", "gpio35",
+};
+
+static const char * const mac00_groups[] = {
+       "gpio34", "gpio35",
+};
+
+static const char * const mac20_groups[] = {
+       "gpio36", "gpio37",
+};
+
+static const char * const blsp0_uart_groups[] = {
+       "gpio38", "gpio39", "gpio40", "gpio41",
+};
+
+static const char * const blsp0_i2c_groups[] = {
+       "gpio38", "gpio39",
+};
+
+static const char * const blsp0_spi_groups[] = {
+       "gpio38", "gpio39", "gpio40", "gpio41",
+};
+
+static const char * const blsp2_uart_groups[] = {
+       "gpio42", "gpio43", "gpio44", "gpio45",
+};
+
+static const char * const blsp2_i2c_groups[] = {
+       "gpio42", "gpio43",
+};
+
+static const char * const blsp2_spi_groups[] = {
+       "gpio42", "gpio43", "gpio44", "gpio45",
+};
+
+static const char * const blsp5_i2c_groups[] = {
+       "gpio46", "gpio47",
+};
+
+static const char * const blsp5_uart_groups[] = {
+       "gpio48", "gpio49",
+};
+
+static const char * const qdss_traceclk_a_groups[] = {
+       "gpio48",
+};
+
+static const char * const qdss_tracectl_a_groups[] = {
+       "gpio49",
+};
+
+static const char * const pwm01_groups[] = {
+       "gpio50",
+};
+
+static const char * const pta1_1_groups[] = {
+       "gpio51",
+};
+
+static const char * const pwm11_groups[] = {
+       "gpio51",
+};
+
+static const char * const rx1_groups[] = {
+       "gpio51",
+};
+
+static const char * const pta1_2_groups[] = {
+       "gpio52",
+};
+
+static const char * const pwm21_groups[] = {
+       "gpio52",
+};
+
+static const char * const pta1_0_groups[] = {
+       "gpio53",
+};
+
+static const char * const pwm31_groups[] = {
+       "gpio53",
+};
+
+static const char * const prng_rosc_groups[] = {
+       "gpio53",
+};
+
+static const char * const blsp4_uart_groups[] = {
+       "gpio55", "gpio56", "gpio57", "gpio58",
+};
+
+static const char * const blsp4_i2c_groups[] = {
+       "gpio55", "gpio56",
+};
+
+static const char * const blsp4_spi_groups[] = {
+       "gpio55", "gpio56", "gpio57", "gpio58",
+};
+
+static const char * const pcie0_clk_groups[] = {
+       "gpio59",
+};
+
+static const char * const cri_trng0_groups[] = {
+       "gpio59",
+};
+
+static const char * const pcie0_rst_groups[] = {
+       "gpio60",
+};
+
+static const char * const cri_trng1_groups[] = {
+       "gpio60",
+};
+
+static const char * const pcie0_wake_groups[] = {
+       "gpio61",
+};
+
+static const char * const cri_trng_groups[] = {
+       "gpio61",
+};
+
+static const char * const sd_card_groups[] = {
+       "gpio62",
+};
+
+static const char * const sd_write_groups[] = {
+       "gpio63",
+};
+
+static const char * const rx0_groups[] = {
+       "gpio63",
+};
+
+static const char * const tsens_max_groups[] = {
+       "gpio63",
+};
+
+static const char * const mdc_groups[] = {
+       "gpio64",
+};
+
+static const char * const qdss_tracedata_a_groups[] = {
+       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+       "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+       "gpio78", "gpio79",
+};
+
+static const char * const mdio_groups[] = {
+       "gpio65",
+};
+
+static const char * const pta2_0_groups[] = {
+       "gpio66",
+};
+
+static const char * const wci21_groups[] = {
+       "gpio66", "gpio68",
+};
+
+static const char * const cxc1_groups[] = {
+       "gpio66", "gpio68",
+};
+
+static const char * const pta2_1_groups[] = {
+       "gpio67",
+};
+
+static const char * const pta2_2_groups[] = {
+       "gpio68",
+};
+
+static const char * const blsp1_uart_groups[] = {
+       "gpio69", "gpio70", "gpio71", "gpio72",
+};
+
+static const char * const blsp1_i2c_groups[] = {
+       "gpio69", "gpio70",
+};
+
+static const char * const blsp1_spi_groups[] = {
+       "gpio69", "gpio70", "gpio71", "gpio72",
+};
+
+static const char * const gcc_plltest_groups[] = {
+       "gpio69", "gpio71",
+};
+
+static const char * const gcc_tlmm_groups[] = {
+       "gpio70",
+};
+
+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",
+};
+
+static const struct msm_function ipq6018_functions[] = {
+       FUNCTION(atest_char),
+       FUNCTION(atest_char0),
+       FUNCTION(atest_char1),
+       FUNCTION(atest_char2),
+       FUNCTION(atest_char3),
+       FUNCTION(audio0),
+       FUNCTION(audio1),
+       FUNCTION(audio2),
+       FUNCTION(audio3),
+       FUNCTION(audio_rxbclk),
+       FUNCTION(audio_rxfsync),
+       FUNCTION(audio_rxmclk),
+       FUNCTION(audio_rxmclkin),
+       FUNCTION(audio_txbclk),
+       FUNCTION(audio_txfsync),
+       FUNCTION(audio_txmclk),
+       FUNCTION(audio_txmclkin),
+       FUNCTION(blsp0_i2c),
+       FUNCTION(blsp0_spi),
+       FUNCTION(blsp0_uart),
+       FUNCTION(blsp1_i2c),
+       FUNCTION(blsp1_spi),
+       FUNCTION(blsp1_uart),
+       FUNCTION(blsp2_i2c),
+       FUNCTION(blsp2_spi),
+       FUNCTION(blsp2_uart),
+       FUNCTION(blsp3_i2c),
+       FUNCTION(blsp3_spi),
+       FUNCTION(blsp3_uart),
+       FUNCTION(blsp4_i2c),
+       FUNCTION(blsp4_spi),
+       FUNCTION(blsp4_uart),
+       FUNCTION(blsp5_i2c),
+       FUNCTION(blsp5_uart),
+       FUNCTION(burn0),
+       FUNCTION(burn1),
+       FUNCTION(cri_trng),
+       FUNCTION(cri_trng0),
+       FUNCTION(cri_trng1),
+       FUNCTION(cxc0),
+       FUNCTION(cxc1),
+       FUNCTION(dbg_out),
+       FUNCTION(gcc_plltest),
+       FUNCTION(gcc_tlmm),
+       FUNCTION(gpio),
+       FUNCTION(lpass_aud),
+       FUNCTION(lpass_aud0),
+       FUNCTION(lpass_aud1),
+       FUNCTION(lpass_aud2),
+       FUNCTION(lpass_pcm),
+       FUNCTION(lpass_pdm),
+       FUNCTION(mac00),
+       FUNCTION(mac01),
+       FUNCTION(mac10),
+       FUNCTION(mac11),
+       FUNCTION(mac12),
+       FUNCTION(mac13),
+       FUNCTION(mac20),
+       FUNCTION(mac21),
+       FUNCTION(mdc),
+       FUNCTION(mdio),
+       FUNCTION(pcie0_clk),
+       FUNCTION(pcie0_rst),
+       FUNCTION(pcie0_wake),
+       FUNCTION(prng_rosc),
+       FUNCTION(pta1_0),
+       FUNCTION(pta1_1),
+       FUNCTION(pta1_2),
+       FUNCTION(pta2_0),
+       FUNCTION(pta2_1),
+       FUNCTION(pta2_2),
+       FUNCTION(pwm00),
+       FUNCTION(pwm01),
+       FUNCTION(pwm02),
+       FUNCTION(pwm03),
+       FUNCTION(pwm04),
+       FUNCTION(pwm10),
+       FUNCTION(pwm11),
+       FUNCTION(pwm12),
+       FUNCTION(pwm13),
+       FUNCTION(pwm14),
+       FUNCTION(pwm20),
+       FUNCTION(pwm21),
+       FUNCTION(pwm22),
+       FUNCTION(pwm23),
+       FUNCTION(pwm24),
+       FUNCTION(pwm30),
+       FUNCTION(pwm31),
+       FUNCTION(pwm32),
+       FUNCTION(pwm33),
+       FUNCTION(qdss_cti_trig_in_a0),
+       FUNCTION(qdss_cti_trig_in_a1),
+       FUNCTION(qdss_cti_trig_out_a0),
+       FUNCTION(qdss_cti_trig_out_a1),
+       FUNCTION(qdss_cti_trig_in_b0),
+       FUNCTION(qdss_cti_trig_in_b1),
+       FUNCTION(qdss_cti_trig_out_b0),
+       FUNCTION(qdss_cti_trig_out_b1),
+       FUNCTION(qdss_traceclk_a),
+       FUNCTION(qdss_tracectl_a),
+       FUNCTION(qdss_tracedata_a),
+       FUNCTION(qdss_traceclk_b),
+       FUNCTION(qdss_tracectl_b),
+       FUNCTION(qdss_tracedata_b),
+       FUNCTION(qpic_pad),
+       FUNCTION(rx0),
+       FUNCTION(rx1),
+       FUNCTION(rx_swrm),
+       FUNCTION(rx_swrm0),
+       FUNCTION(rx_swrm1),
+       FUNCTION(sd_card),
+       FUNCTION(sd_write),
+       FUNCTION(tsens_max),
+       FUNCTION(tx_swrm),
+       FUNCTION(tx_swrm0),
+       FUNCTION(tx_swrm1),
+       FUNCTION(tx_swrm2),
+       FUNCTION(wci20),
+       FUNCTION(wci21),
+       FUNCTION(wci22),
+       FUNCTION(wci23),
+       FUNCTION(wsa_swrm),
+};
+
+static const struct msm_pingroup ipq6018_groups[] = {
+       PINGROUP(0, qpic_pad, wci20, qdss_traceclk_b, _, burn0, _, _, _, _),
+       PINGROUP(1, qpic_pad, mac12, qdss_tracectl_b, _, burn1, _, _, _, _),
+       PINGROUP(2, qpic_pad, wci20, qdss_tracedata_b, _, _, _, _, _, _),
+       PINGROUP(3, qpic_pad, mac01, qdss_tracedata_b, _, _, _, _, _, _),
+       PINGROUP(4, qpic_pad, mac01, qdss_tracedata_b, _, _, _, _, _, _),
+       PINGROUP(5, qpic_pad, mac21, qdss_tracedata_b, _, _, _, _, _, _),
+       PINGROUP(6, qpic_pad, mac21, qdss_tracedata_b, _, _, _, _, _, _),
+       PINGROUP(7, qpic_pad, qdss_tracedata_b, _, _, _, _, _, _, _),
+       PINGROUP(8, qpic_pad, qdss_tracedata_b, _, _, _, _, _, _, _),
+       PINGROUP(9, qpic_pad, atest_char, cxc0, mac13, dbg_out, qdss_tracedata_b, _, _, _),
+       PINGROUP(10, qpic_pad, qdss_tracedata_b, _, _, _, _, _, _, _),
+       PINGROUP(11, qpic_pad, wci22, mac12, qdss_tracedata_b, _, _, _, _, _),
+       PINGROUP(12, qpic_pad, qdss_tracedata_b, _, _, _, _, _, _, _),
+       PINGROUP(13, qpic_pad, qdss_tracedata_b, _, _, _, _, _, _, _),
+       PINGROUP(14, qpic_pad, qdss_tracedata_b, _, _, _, _, _, _, _),
+       PINGROUP(15, qpic_pad, qdss_tracedata_b, _, _, _, _, _, _, _),
+       PINGROUP(16, qpic_pad, cxc0, mac13, qdss_tracedata_b, _, _, _, _, _),
+       PINGROUP(17, qpic_pad, qdss_tracedata_b, wci22, _, _, _, _, _, _),
+       PINGROUP(18, pwm00, atest_char0, wci23, mac11, _, _, _, _, _),
+       PINGROUP(19, pwm10, atest_char1, wci23, mac11, _, _, _, _, _),
+       PINGROUP(20, pwm20, atest_char2, _, _, _, _, _, _, _),
+       PINGROUP(21, pwm30, atest_char3, _, _, _, _, _, _, _),
+       PINGROUP(22, audio_txmclk, audio_txmclkin, pwm02, tx_swrm0, _, qdss_cti_trig_out_b0, _, _, _),
+       PINGROUP(23, audio_txbclk, pwm12, wsa_swrm, tx_swrm1, _, qdss_cti_trig_in_b0, _, _, _),
+       PINGROUP(24, audio_txfsync, pwm22, wsa_swrm, tx_swrm2, _, qdss_cti_trig_out_b1, _, _, _),
+       PINGROUP(25, audio0, pwm32, tx_swrm, _, qdss_cti_trig_in_b1, _, _, _, _),
+       PINGROUP(26, audio1, pwm04, _, _, _, _, _, _, _),
+       PINGROUP(27, audio2, pwm14, _, _, _, _, _, _, _),
+       PINGROUP(28, audio3, pwm24, _, _, _, _, _, _, _),
+       PINGROUP(29, audio_rxmclk, audio_rxmclkin, pwm03, lpass_pdm, lpass_aud, qdss_cti_trig_in_a1, _, _, _),
+       PINGROUP(30, audio_rxbclk, pwm13, lpass_pdm, lpass_aud0, rx_swrm, _, qdss_cti_trig_out_a1, _, _),
+       PINGROUP(31, audio_rxfsync, pwm23, lpass_pdm, lpass_aud1, rx_swrm0, _, qdss_cti_trig_in_a0, _, _),
+       PINGROUP(32, audio0, pwm33, lpass_pdm, lpass_aud2, rx_swrm1, _, qdss_cti_trig_out_a0, _, _),
+       PINGROUP(33, audio1, _, _, _, _, _, _, _, _),
+       PINGROUP(34, lpass_pcm, mac10, mac00, _, _, _, _, _, _),
+       PINGROUP(35, lpass_pcm, mac10, mac00, _, _, _, _, _, _),
+       PINGROUP(36, lpass_pcm, mac20, _, _, _, _, _, _, _),
+       PINGROUP(37, lpass_pcm, mac20, _, _, _, _, _, _, _),
+       PINGROUP(38, blsp0_uart, blsp0_i2c, blsp0_spi, _, _, _, _, _, _),
+       PINGROUP(39, blsp0_uart, blsp0_i2c, blsp0_spi, _, _, _, _, _, _),
+       PINGROUP(40, blsp0_uart, blsp0_spi, _, _, _, _, _, _, _),
+       PINGROUP(41, blsp0_uart, blsp0_spi, _, _, _, _, _, _, _),
+       PINGROUP(42, blsp2_uart, blsp2_i2c, blsp2_spi, _, _, _, _, _, _),
+       PINGROUP(43, blsp2_uart, blsp2_i2c, blsp2_spi, _, _, _, _, _, _),
+       PINGROUP(44, blsp2_uart, blsp2_spi, _, _, _, _, _, _, _),
+       PINGROUP(45, blsp2_uart, blsp2_spi, _, _, _, _, _, _, _),
+       PINGROUP(46, blsp5_i2c, _, _, _, _, _, _, _, _),
+       PINGROUP(47, blsp5_i2c, _, _, _, _, _, _, _, _),
+       PINGROUP(48, blsp5_uart, _, qdss_traceclk_a, _, _, _, _, _, _),
+       PINGROUP(49, blsp5_uart, _, qdss_tracectl_a, _, _, _, _, _, _),
+       PINGROUP(50, pwm01, _, _, _, _, _, _, _, _),
+       PINGROUP(51, pta1_1, pwm11, _, rx1, _, _, _, _, _),
+       PINGROUP(52, pta1_2, pwm21, _, _, _, _, _, _, _),
+       PINGROUP(53, pta1_0, pwm31, prng_rosc, _, _, _, _, _, _),
+       PINGROUP(54, _, _, _, _, _, _, _, _, _),
+       PINGROUP(55, blsp4_uart, blsp4_i2c, blsp4_spi, _, _, _, _, _, _),
+       PINGROUP(56, blsp4_uart, blsp4_i2c, blsp4_spi, _, _, _, _, _, _),
+       PINGROUP(57, blsp4_uart, blsp4_spi, _, _, _, _, _, _, _),
+       PINGROUP(58, blsp4_uart, blsp4_spi, _, _, _, _, _, _, _),
+       PINGROUP(59, pcie0_clk, _, _, cri_trng0, _, _, _, _, _),
+       PINGROUP(60, pcie0_rst, _, _, cri_trng1, _, _, _, _, _),
+       PINGROUP(61, pcie0_wake, _, _, cri_trng, _, _, _, _, _),
+       PINGROUP(62, sd_card, _, _, _, _, _, _, _, _),
+       PINGROUP(63, sd_write, rx0, _, tsens_max, _, _, _, _, _),
+       PINGROUP(64, mdc, _, qdss_tracedata_a, _, _, _, _, _, _),
+       PINGROUP(65, mdio, _, qdss_tracedata_a, _, _, _, _, _, _),
+       PINGROUP(66, pta2_0, wci21, cxc1, qdss_tracedata_a, _, _, _, _, _),
+       PINGROUP(67, pta2_1, qdss_tracedata_a, _, _, _, _, _, _, _),
+       PINGROUP(68, pta2_2, wci21, cxc1, qdss_tracedata_a, _, _, _, _, _),
+       PINGROUP(69, blsp1_uart, blsp1_i2c, blsp1_spi, gcc_plltest, qdss_tracedata_a, _, _, _, _),
+       PINGROUP(70, blsp1_uart, blsp1_i2c, blsp1_spi, gcc_tlmm, qdss_tracedata_a, _, _, _, _),
+       PINGROUP(71, blsp1_uart, blsp1_spi, gcc_plltest, qdss_tracedata_a, _, _, _, _, _),
+       PINGROUP(72, blsp1_uart, blsp1_spi, qdss_tracedata_a, _, _, _, _, _, _),
+       PINGROUP(73, blsp3_uart, blsp3_i2c, blsp3_spi, _, qdss_tracedata_a, _, _, _, _),
+       PINGROUP(74, blsp3_uart, blsp3_i2c, blsp3_spi, _, qdss_tracedata_a, _, _, _, _),
+       PINGROUP(75, blsp3_uart, blsp3_spi, _, qdss_tracedata_a, _, _, _, _, _),
+       PINGROUP(76, blsp3_uart, blsp3_spi, _, qdss_tracedata_a, _, _, _, _, _),
+       PINGROUP(77, blsp3_spi, _, qdss_tracedata_a, _, _, _, _, _, _),
+       PINGROUP(78, blsp3_spi, _, qdss_tracedata_a, _, _, _, _, _, _),
+       PINGROUP(79, blsp3_spi, _, qdss_tracedata_a, _, _, _, _, _, _),
+};
+
+static const struct msm_pinctrl_soc_data ipq6018_pinctrl = {
+       .pins = ipq6018_pins,
+       .npins = ARRAY_SIZE(ipq6018_pins),
+       .functions = ipq6018_functions,
+       .nfunctions = ARRAY_SIZE(ipq6018_functions),
+       .groups = ipq6018_groups,
+       .ngroups = ARRAY_SIZE(ipq6018_groups),
+       .ngpios = 80,
+};
+
+static int ipq6018_pinctrl_probe(struct platform_device *pdev)
+{
+       return msm_pinctrl_probe(pdev, &ipq6018_pinctrl);
+}
+
+static const struct of_device_id ipq6018_pinctrl_of_match[] = {
+       { .compatible = "qcom,ipq6018-pinctrl", },
+       { },
+};
+
+static struct platform_driver ipq6018_pinctrl_driver = {
+       .driver = {
+               .name = "ipq6018-pinctrl",
+               .of_match_table = ipq6018_pinctrl_of_match,
+       },
+       .probe = ipq6018_pinctrl_probe,
+       .remove = msm_pinctrl_remove,
+};
+
+static int __init ipq6018_pinctrl_init(void)
+{
+       return platform_driver_register(&ipq6018_pinctrl_driver);
+}
+arch_initcall(ipq6018_pinctrl_init);
+
+static void __exit ipq6018_pinctrl_exit(void)
+{
+       platform_driver_unregister(&ipq6018_pinctrl_driver);
+}
+module_exit(ipq6018_pinctrl_exit);
+
+MODULE_DESCRIPTION("QTI ipq6018 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, ipq6018_pinctrl_of_match);
index c2fb1ddf2f221a570d4edde7fce3270c09975582..ac717ee38416a6f1eb26394a9a0cf8423d40f180 100644 (file)
@@ -299,7 +299,7 @@ static const char * const gpio_groups[] = {
 };
 
 static const char * const mdio_groups[] = {
-       "gpio0", "gpio1", "gpio10", "gpio11",
+       "gpio0", "gpio1", "gpio2", "gpio10", "gpio11", "gpio66",
 };
 
 static const char * const mi2s_groups[] = {
@@ -403,8 +403,8 @@ static const char * const usb2_hsic_groups[] = {
 };
 
 static const char * const rgmii2_groups[] = {
-       "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-       "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62",
+       "gpio2", "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
+       "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62", "gpio66",
 };
 
 static const char * const sata_groups[] = {
@@ -539,7 +539,7 @@ static const struct msm_function ipq8064_functions[] = {
 static const struct msm_pingroup ipq8064_groups[] = {
        PINGROUP(0, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(1, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(2, gsbi5_spi_cs3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(2, gsbi5_spi_cs3, rgmii2, mdio, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(3, pcie1_rst, pcie1_prsnt, pdm, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(4, pcie1_pwren_n, pcie1_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(5, pcie1_clk_req, pcie1_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
@@ -603,7 +603,7 @@ static const struct msm_pingroup ipq8064_groups[] = {
        PINGROUP(63, pcie3_rst, NA, NA, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(65, pcie3_clk_req, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(66, rgmii2, mdio, NA, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(67, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(68, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
        SDC_PINGROUP(sdc3_clk, 0x204a, 14, 6),
index 1a948c3f54b7ca4ad6fd246d097d34f7a9115583..9a398a211d30a4db31ae07b6db09f8512019fb07 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/reboot.h>
 #include <linux/pm.h>
 #include <linux/log2.h>
+#include <linux/qcom_scm.h>
+#include <linux/io.h>
 
 #include <linux/soc/qcom/irq.h>
 
@@ -60,6 +62,8 @@ struct msm_pinctrl {
        struct irq_chip irq_chip;
        int irq;
 
+       bool intr_target_use_scm;
+
        raw_spinlock_t lock;
 
        DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
@@ -68,6 +72,7 @@ struct msm_pinctrl {
 
        const struct msm_pinctrl_soc_data *soc;
        void __iomem *regs[MAX_NR_TILES];
+       u32 phys_base[MAX_NR_TILES];
 };
 
 #define MSM_ACCESSOR(name) \
@@ -489,8 +494,8 @@ static int msm_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
 
        val = msm_readl_ctl(pctrl, g);
 
-       /* 0 = output, 1 = input */
-       return val & BIT(g->oe_bit) ? 0 : 1;
+       return val & BIT(g->oe_bit) ? GPIO_LINE_DIRECTION_OUT :
+                                     GPIO_LINE_DIRECTION_IN;
 }
 
 static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -882,11 +887,30 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        else
                clear_bit(d->hwirq, pctrl->dual_edge_irqs);
 
-       /* Route interrupts to application cpu */
-       val = msm_readl_intr_target(pctrl, g);
-       val &= ~(7 << g->intr_target_bit);
-       val |= g->intr_target_kpss_val << g->intr_target_bit;
-       msm_writel_intr_target(val, pctrl, g);
+       /* Route interrupts to application cpu.
+        * With intr_target_use_scm interrupts are routed to
+        * application cpu using scm calls.
+        */
+       if (pctrl->intr_target_use_scm) {
+               u32 addr = pctrl->phys_base[0] + g->intr_target_reg;
+               int ret;
+
+               qcom_scm_io_readl(addr, &val);
+
+               val &= ~(7 << g->intr_target_bit);
+               val |= g->intr_target_kpss_val << g->intr_target_bit;
+
+               ret = qcom_scm_io_writel(addr, val);
+               if (ret)
+                       dev_err(pctrl->dev,
+                               "Failed routing %lu interrupt to Apps proc",
+                               d->hwirq);
+       } else {
+               val = msm_readl_intr_target(pctrl, g);
+               val &= ~(7 << g->intr_target_bit);
+               val |= g->intr_target_kpss_val << g->intr_target_bit;
+               msm_writel_intr_target(val, pctrl, g);
+       }
 
        /* Update configuration for gpio.
         * RAW_STATUS_EN is left on for all gpio irqs. Due to the
@@ -1240,6 +1264,9 @@ int msm_pinctrl_probe(struct platform_device *pdev,
        pctrl->dev = &pdev->dev;
        pctrl->soc = soc_data;
        pctrl->chip = msm_gpio_template;
+       pctrl->intr_target_use_scm = of_device_is_compatible(
+                                       pctrl->dev->of_node,
+                                       "qcom,ipq8064-pinctrl");
 
        raw_spin_lock_init(&pctrl->lock);
 
@@ -1252,9 +1279,12 @@ int msm_pinctrl_probe(struct platform_device *pdev,
                                return PTR_ERR(pctrl->regs[i]);
                }
        } else {
-               pctrl->regs[0] = devm_platform_ioremap_resource(pdev, 0);
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               pctrl->regs[0] = devm_ioremap_resource(&pdev->dev, res);
                if (IS_ERR(pctrl->regs[0]))
                        return PTR_ERR(pctrl->regs[0]);
+
+               pctrl->phys_base[0] = res->start;
        }
 
        msm_pinctrl_setup_pm_reset(pctrl);
index cf0e0dc42b84c06f972fb6b32206358a9c73db1f..9552851b96f12e08d818cc58ec3c510bf86c134b 100644 (file)
@@ -26,8 +26,8 @@ config PINCTRL_SH_PFC
        select PINCTRL_PFC_R8A7792 if ARCH_R8A7792
        select PINCTRL_PFC_R8A7793 if ARCH_R8A7793
        select PINCTRL_PFC_R8A7794 if ARCH_R8A7794
-       select PINCTRL_PFC_R8A77950 if ARCH_R8A77950 || ARCH_R8A7795
-       select PINCTRL_PFC_R8A77951 if ARCH_R8A77951 || ARCH_R8A7795
+       select PINCTRL_PFC_R8A77950 if ARCH_R8A77950
+       select PINCTRL_PFC_R8A77951 if ARCH_R8A77951
        select PINCTRL_PFC_R8A77960 if ARCH_R8A77960
        select PINCTRL_PFC_R8A77961 if ARCH_R8A77961
        select PINCTRL_PFC_R8A77965 if ARCH_R8A77965
index 82209116955b153a55b8966aec5db50ea37f1304..a2e19efa26e31b98884a4cb49aeba21394370071 100644 (file)
@@ -726,6 +726,27 @@ static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; }
 #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
 
 #ifdef DEBUG
+#define SH_PFC_MAX_REGS                300
+#define SH_PFC_MAX_ENUMS       3000
+
+static unsigned int sh_pfc_errors __initdata = 0;
+static unsigned int sh_pfc_warnings __initdata = 0;
+static u32 *sh_pfc_regs __initdata = NULL;
+static u32 sh_pfc_num_regs __initdata = 0;
+static u16 *sh_pfc_enums __initdata = NULL;
+static u32 sh_pfc_num_enums __initdata = 0;
+
+#define sh_pfc_err(fmt, ...)                                   \
+       do {                                                    \
+               pr_err("%s: " fmt, drvname, ##__VA_ARGS__);     \
+               sh_pfc_errors++;                                \
+       } while (0)
+#define sh_pfc_warn(fmt, ...)                                  \
+       do {                                                    \
+               pr_warn("%s: " fmt, drvname, ##__VA_ARGS__);    \
+               sh_pfc_warnings++;                              \
+       } while (0)
+
 static bool __init is0s(const u16 *enum_ids, unsigned int n)
 {
        unsigned int i;
@@ -737,77 +758,181 @@ static bool __init is0s(const u16 *enum_ids, unsigned int n)
        return true;
 }
 
-static unsigned int sh_pfc_errors __initdata = 0;
-static unsigned int sh_pfc_warnings __initdata = 0;
+static bool __init same_name(const char *a, const char *b)
+{
+       if (!a || !b)
+               return false;
+
+       return !strcmp(a, b);
+}
+
+static void __init sh_pfc_check_reg(const char *drvname, u32 reg)
+{
+       unsigned int i;
+
+       for (i = 0; i < sh_pfc_num_regs; i++)
+               if (reg == sh_pfc_regs[i]) {
+                       sh_pfc_err("reg 0x%x conflict\n", reg);
+                       return;
+               }
+
+       if (sh_pfc_num_regs == SH_PFC_MAX_REGS) {
+               pr_warn_once("%s: Please increase SH_PFC_MAX_REGS\n", drvname);
+               return;
+       }
+
+       sh_pfc_regs[sh_pfc_num_regs++] = reg;
+}
+
+static int __init sh_pfc_check_enum(const char *drvname, u16 enum_id)
+{
+       unsigned int i;
+
+       for (i = 0; i < sh_pfc_num_enums; i++) {
+               if (enum_id == sh_pfc_enums[i])
+                       return -EINVAL;
+       }
+
+       if (sh_pfc_num_enums == SH_PFC_MAX_ENUMS) {
+               pr_warn_once("%s: Please increase SH_PFC_MAX_ENUMS\n", drvname);
+               return 0;
+       }
+
+       sh_pfc_enums[sh_pfc_num_enums++] = enum_id;
+       return 0;
+}
+
+static void __init sh_pfc_check_reg_enums(const char *drvname, u32 reg,
+                                         const u16 *enums, unsigned int n)
+{
+       unsigned int i;
+
+       for (i = 0; i < n; i++) {
+               if (enums[i] && sh_pfc_check_enum(drvname, enums[i]))
+                       sh_pfc_err("reg 0x%x enum_id %u conflict\n", reg,
+                                  enums[i]);
+       }
+}
+
+static void __init sh_pfc_check_pin(const struct sh_pfc_soc_info *info,
+                                   u32 reg, unsigned int pin)
+{
+       const char *drvname = info->name;
+       unsigned int i;
+
+       if (pin == SH_PFC_PIN_NONE)
+               return;
+
+       for (i = 0; i < info->nr_pins; i++) {
+               if (pin == info->pins[i].pin)
+                       return;
+       }
+
+       sh_pfc_err("reg 0x%x: pin %u not found\n", reg, pin);
+}
 
 static void __init sh_pfc_check_cfg_reg(const char *drvname,
                                        const struct pinmux_cfg_reg *cfg_reg)
 {
        unsigned int i, n, rw, fw;
 
+       sh_pfc_check_reg(drvname, cfg_reg->reg);
+
        if (cfg_reg->field_width) {
-               /* Checked at build time */
-               return;
+               n = cfg_reg->reg_width / cfg_reg->field_width;
+               /* Skip field checks (done at build time) */
+               goto check_enum_ids;
        }
 
        for (i = 0, n = 0, rw = 0; (fw = cfg_reg->var_field_width[i]); i++) {
-               if (fw > 3 && is0s(&cfg_reg->enum_ids[n], 1 << fw)) {
-                       pr_warn("%s: reg 0x%x: reserved field [%u:%u] can be split to reduce table size\n",
-                               drvname, cfg_reg->reg, rw, rw + fw - 1);
-                       sh_pfc_warnings++;
-               }
+               if (fw > 3 && is0s(&cfg_reg->enum_ids[n], 1 << fw))
+                       sh_pfc_warn("reg 0x%x: reserved field [%u:%u] can be split to reduce table size\n",
+                                   cfg_reg->reg, rw, rw + fw - 1);
                n += 1 << fw;
                rw += fw;
        }
 
-       if (rw != cfg_reg->reg_width) {
-               pr_err("%s: reg 0x%x: var_field_width declares %u instead of %u bits\n",
-                      drvname, cfg_reg->reg, rw, cfg_reg->reg_width);
-               sh_pfc_errors++;
-       }
+       if (rw != cfg_reg->reg_width)
+               sh_pfc_err("reg 0x%x: var_field_width declares %u instead of %u bits\n",
+                          cfg_reg->reg, rw, cfg_reg->reg_width);
+
+       if (n != cfg_reg->nr_enum_ids)
+               sh_pfc_err("reg 0x%x: enum_ids[] has %u instead of %u values\n",
+                          cfg_reg->reg, cfg_reg->nr_enum_ids, n);
+
+check_enum_ids:
+       sh_pfc_check_reg_enums(drvname, cfg_reg->reg, cfg_reg->enum_ids, n);
+}
+
+static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info,
+                                         const struct pinmux_drive_reg *drive)
+{
+       const char *drvname = info->name;
+       unsigned long seen = 0, mask;
+       unsigned int i;
+
+       sh_pfc_check_reg(info->name, drive->reg);
+       for (i = 0; i < ARRAY_SIZE(drive->fields); i++) {
+               const struct pinmux_drive_reg_field *field = &drive->fields[i];
+
+               if (!field->pin && !field->offset && !field->size)
+                       continue;
+
+               mask = GENMASK(field->offset + field->size, field->offset);
+               if (mask & seen)
+                       sh_pfc_err("drive_reg 0x%x: field %u overlap\n",
+                                  drive->reg, i);
+               seen |= mask;
 
-       if (n != cfg_reg->nr_enum_ids) {
-               pr_err("%s: reg 0x%x: enum_ids[] has %u instead of %u values\n",
-                      drvname, cfg_reg->reg, cfg_reg->nr_enum_ids, n);
-               sh_pfc_errors++;
+               sh_pfc_check_pin(info, drive->reg, field->pin);
        }
 }
 
+static void __init sh_pfc_check_bias_reg(const struct sh_pfc_soc_info *info,
+                                        const struct pinmux_bias_reg *bias)
+{
+       unsigned int i;
+
+       sh_pfc_check_reg(info->name, bias->puen);
+       if (bias->pud)
+               sh_pfc_check_reg(info->name, bias->pud);
+       for (i = 0; i < ARRAY_SIZE(bias->pins); i++)
+               sh_pfc_check_pin(info, bias->puen, bias->pins[i]);
+}
+
 static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
 {
-       const struct sh_pfc_function *func;
        const char *drvname = info->name;
        unsigned int *refcnts;
        unsigned int i, j, k;
 
        pr_info("Checking %s\n", drvname);
+       sh_pfc_num_regs = 0;
+       sh_pfc_num_enums = 0;
 
        /* Check pins */
        for (i = 0; i < info->nr_pins; i++) {
+               const struct sh_pfc_pin *pin = &info->pins[i];
+
+               if (!pin->name) {
+                       sh_pfc_err("empty pin %u\n", i);
+                       continue;
+               }
                for (j = 0; j < i; j++) {
-                       if (!strcmp(info->pins[i].name, info->pins[j].name)) {
-                               pr_err("%s: pin %s/%s: name conflict\n",
-                                      drvname, info->pins[i].name,
-                                      info->pins[j].name);
-                               sh_pfc_errors++;
-                       }
+                       const struct sh_pfc_pin *pin2 = &info->pins[j];
 
-                       if (info->pins[i].pin != (u16)-1 &&
-                           info->pins[i].pin == info->pins[j].pin) {
-                               pr_err("%s: pin %s/%s: pin %u conflict\n",
-                                      drvname, info->pins[i].name,
-                                      info->pins[j].name, info->pins[i].pin);
-                               sh_pfc_errors++;
-                       }
+                       if (same_name(pin->name, pin2->name))
+                               sh_pfc_err("pin %s: name conflict\n",
+                                          pin->name);
 
-                       if (info->pins[i].enum_id &&
-                           info->pins[i].enum_id == info->pins[j].enum_id) {
-                               pr_err("%s: pin %s/%s: enum_id %u conflict\n",
-                                      drvname, info->pins[i].name,
-                                      info->pins[j].name,
-                                      info->pins[i].enum_id);
-                               sh_pfc_errors++;
-                       }
+                       if (pin->pin != (u16)-1 && pin->pin == pin2->pin)
+                               sh_pfc_err("pin %s/%s: pin %u conflict\n",
+                                          pin->name, pin2->name, pin->pin);
+
+                       if (pin->enum_id && pin->enum_id == pin2->enum_id)
+                               sh_pfc_err("pin %s/%s: enum_id %u conflict\n",
+                                          pin->name, pin2->name,
+                                          pin->enum_id);
                }
        }
 
@@ -817,45 +942,49 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
                return;
 
        for (i = 0; i < info->nr_functions; i++) {
-               func = &info->functions[i];
+               const struct sh_pfc_function *func = &info->functions[i];
+
                if (!func->name) {
-                       pr_err("%s: empty function %u\n", drvname, i);
-                       sh_pfc_errors++;
+                       sh_pfc_err("empty function %u\n", i);
                        continue;
                }
+               for (j = 0; j < i; j++) {
+                       if (same_name(func->name, info->functions[j].name))
+                               sh_pfc_err("function %s: name conflict\n",
+                                          func->name);
+               }
                for (j = 0; j < func->nr_groups; j++) {
                        for (k = 0; k < info->nr_groups; k++) {
-                               if (info->groups[k].name &&
-                                   !strcmp(func->groups[j],
-                                           info->groups[k].name)) {
+                               if (same_name(func->groups[j],
+                                             info->groups[k].name)) {
                                        refcnts[k]++;
                                        break;
                                }
                        }
 
-                       if (k == info->nr_groups) {
-                               pr_err("%s: function %s: group %s not found\n",
-                                      drvname, func->name, func->groups[j]);
-                               sh_pfc_errors++;
-                       }
+                       if (k == info->nr_groups)
+                               sh_pfc_err("function %s: group %s not found\n",
+                                          func->name, func->groups[j]);
                }
        }
 
        for (i = 0; i < info->nr_groups; i++) {
-               if (!info->groups[i].name) {
-                       pr_err("%s: empty group %u\n", drvname, i);
-                       sh_pfc_errors++;
+               const struct sh_pfc_pin_group *group = &info->groups[i];
+
+               if (!group->name) {
+                       sh_pfc_err("empty group %u\n", i);
                        continue;
                }
-               if (!refcnts[i]) {
-                       pr_err("%s: orphan group %s\n", drvname,
-                              info->groups[i].name);
-                       sh_pfc_errors++;
-               } else if (refcnts[i] > 1) {
-                       pr_warn("%s: group %s referenced by %u functions\n",
-                               drvname, info->groups[i].name, refcnts[i]);
-                       sh_pfc_warnings++;
+               for (j = 0; j < i; j++) {
+                       if (same_name(group->name, info->groups[j].name))
+                               sh_pfc_err("group %s: name conflict\n",
+                                          group->name);
                }
+               if (!refcnts[i])
+                       sh_pfc_err("orphan group %s\n", group->name);
+               else if (refcnts[i] > 1)
+                       sh_pfc_warn("group %s referenced by %u functions\n",
+                                   group->name, refcnts[i]);
        }
 
        kfree(refcnts);
@@ -863,12 +992,62 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
        /* Check config register descriptions */
        for (i = 0; info->cfg_regs && info->cfg_regs[i].reg; i++)
                sh_pfc_check_cfg_reg(drvname, &info->cfg_regs[i]);
+
+       /* Check drive strength registers */
+       for (i = 0; info->drive_regs && info->drive_regs[i].reg; i++)
+               sh_pfc_check_drive_reg(info, &info->drive_regs[i]);
+
+       /* Check bias registers */
+       for (i = 0; info->bias_regs && info->bias_regs[i].puen; i++)
+               sh_pfc_check_bias_reg(info, &info->bias_regs[i]);
+
+       /* Check ioctrl registers */
+       for (i = 0; info->ioctrl_regs && info->ioctrl_regs[i].reg; i++)
+               sh_pfc_check_reg(drvname, info->ioctrl_regs[i].reg);
+
+       /* Check data registers */
+       for (i = 0; info->data_regs && info->data_regs[i].reg; i++) {
+               sh_pfc_check_reg(drvname, info->data_regs[i].reg);
+               sh_pfc_check_reg_enums(drvname, info->data_regs[i].reg,
+                                      info->data_regs[i].enum_ids,
+                                      info->data_regs[i].reg_width);
+       }
+
+#ifdef CONFIG_PINCTRL_SH_FUNC_GPIO
+       /* Check function GPIOs */
+       for (i = 0; i < info->nr_func_gpios; i++) {
+               const struct pinmux_func *func = &info->func_gpios[i];
+
+               if (!func->name) {
+                       sh_pfc_err("empty function gpio %u\n", i);
+                       continue;
+               }
+               for (j = 0; j < i; j++) {
+                       if (same_name(func->name, info->func_gpios[j].name))
+                               sh_pfc_err("func_gpio %s: name conflict\n",
+                                          func->name);
+               }
+               if (sh_pfc_check_enum(drvname, func->enum_id))
+                       sh_pfc_err("%s enum_id %u conflict\n", func->name,
+                                  func->enum_id);
+       }
+#endif
 }
 
 static void __init sh_pfc_check_driver(const struct platform_driver *pdrv)
 {
        unsigned int i;
 
+       sh_pfc_regs = kcalloc(SH_PFC_MAX_REGS, sizeof(*sh_pfc_regs),
+                             GFP_KERNEL);
+       if (!sh_pfc_regs)
+               return;
+
+       sh_pfc_enums = kcalloc(SH_PFC_MAX_ENUMS, sizeof(*sh_pfc_enums),
+                             GFP_KERNEL);
+       if (!sh_pfc_enums)
+               goto free_regs;
+
        pr_warn("Checking builtin pinmux tables\n");
 
        for (i = 0; pdrv->id_table[i].name[0]; i++)
@@ -881,6 +1060,10 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv)
 
        pr_warn("Detected %u errors and %u warnings\n", sh_pfc_errors,
                sh_pfc_warnings);
+
+       kfree(sh_pfc_enums);
+free_regs:
+       kfree(sh_pfc_regs);
 }
 
 #else /* !DEBUG */
index 8213e118aa408573ed204c513bec9668de3ad0e2..9c6e931ae766edf73722e826dff6454778eb528a 100644 (file)
@@ -205,14 +205,11 @@ static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset)
 
                for (k = 0; gpios[k] >= 0; k++) {
                        if (gpios[k] == offset)
-                               goto found;
+                               return pfc->irqs[i];
                }
        }
 
        return 0;
-
-found:
-       return pfc->irqs[i];
 }
 
 static int gpio_pin_setup(struct sh_pfc_chip *chip)
index b1a9611f46b34b4a0f6648add77d24a49e3712b4..50df9e08441425a51ea8884a77e885a0b7163def 100644 (file)
@@ -352,7 +352,7 @@ struct atlas7_gpio_chip {
        int nbank;
        raw_spinlock_t lock;
        struct gpio_chip chip;
-       struct atlas7_gpio_bank banks[0];
+       struct atlas7_gpio_bank banks[];
 };
 
 /**
index b6c5479b58fb839f9d663cead80203679df3c0ca..eef35d01b7701b89bc3a79c57e850ba078b164d5 100644 (file)
@@ -4,9 +4,7 @@
 #
 
 config PINCTRL_SPRD
-       bool "Spreadtrum pinctrl driver"
-       depends on OF
-       depends on ARCH_SPRD || COMPILE_TEST
+       tristate
        select PINMUX
        select PINCONF
        select GENERIC_PINCONF
@@ -15,7 +13,9 @@ config PINCTRL_SPRD
          Say Y here to enable Spreadtrum pinctrl driver
 
 config PINCTRL_SPRD_SC9860
-       bool "Spreadtrum SC9860 pinctrl driver"
-       depends on PINCTRL_SPRD
+       tristate "Spreadtrum SC9860 pinctrl driver"
+       depends on OF
+       depends on ARCH_SPRD || COMPILE_TEST
+       select PINCTRL_SPRD
        help
          Say Y here to enable Spreadtrum SC9860 pinctrl driver
index 157712ab05a89aeafeb6ac3b52ce1927f4e8b11d..48cbf2a2837f128c27a1339335d2e5f56bc3f175 100644 (file)
@@ -464,9 +464,15 @@ static int sprd_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin_id,
                case PIN_CONFIG_INPUT_ENABLE:
                        arg = (reg >> SLEEP_INPUT_SHIFT) & SLEEP_INPUT_MASK;
                        break;
-               case PIN_CONFIG_OUTPUT:
+               case PIN_CONFIG_OUTPUT_ENABLE:
                        arg = reg & SLEEP_OUTPUT_MASK;
                        break;
+               case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+                       if ((reg & SLEEP_OUTPUT) || (reg & SLEEP_INPUT))
+                               return -EINVAL;
+
+                       arg = 1;
+                       break;
                case PIN_CONFIG_DRIVE_STRENGTH:
                        arg = (reg >> DRIVE_STRENGTH_SHIFT) &
                                DRIVE_STRENGTH_MASK;
@@ -635,13 +641,23 @@ static int sprd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id,
                                        shift = SLEEP_INPUT_SHIFT;
                                }
                                break;
-                       case PIN_CONFIG_OUTPUT:
+                       case PIN_CONFIG_OUTPUT_ENABLE:
                                if (is_sleep_config == true) {
-                                       val |= SLEEP_OUTPUT;
+                                       if (arg > 0)
+                                               val |= SLEEP_OUTPUT;
+                                       else
+                                               val &= ~SLEEP_OUTPUT;
+
                                        mask = SLEEP_OUTPUT_MASK;
                                        shift = SLEEP_OUTPUT_SHIFT;
                                }
                                break;
+                       case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+                               if (is_sleep_config == true) {
+                                       val = shift = 0;
+                                       mask = SLEEP_OUTPUT | SLEEP_INPUT;
+                               }
+                               break;
                        case PIN_CONFIG_DRIVE_STRENGTH:
                                if (arg < 2 || arg > 60)
                                        return -EINVAL;
@@ -1090,6 +1106,7 @@ int sprd_pinctrl_core_probe(struct platform_device *pdev,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(sprd_pinctrl_core_probe);
 
 int sprd_pinctrl_remove(struct platform_device *pdev)
 {
@@ -1098,6 +1115,7 @@ int sprd_pinctrl_remove(struct platform_device *pdev)
        pinctrl_unregister(sprd_pctl->pctl);
        return 0;
 }
+EXPORT_SYMBOL_GPL(sprd_pinctrl_remove);
 
 void sprd_pinctrl_shutdown(struct platform_device *pdev)
 {
@@ -1112,6 +1130,7 @@ void sprd_pinctrl_shutdown(struct platform_device *pdev)
                return;
        pinctrl_select_state(pinctl, state);
 }
+EXPORT_SYMBOL_GPL(sprd_pinctrl_shutdown);
 
 MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");
 MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");
index af3b24f26ff2b72de40d4fc39a9abb5bd2dceb60..a657cd829ce6a6dccf1d5f581de40376c0c3e018 100644 (file)
@@ -284,9 +284,9 @@ static int stm32_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
 
        stm32_pmx_get_mode(bank, pin, &mode, &alt);
        if ((alt == 0) && (mode == 0))
-               ret = 1;
+               ret = GPIO_LINE_DIRECTION_IN;
        else if ((alt == 0) && (mode == 1))
-               ret = 0;
+               ret = GPIO_LINE_DIRECTION_OUT;
        else
                ret = -EINVAL;
 
index b35c3245ab3f02b60284d198cb57a27a35cfb2b1..8e792f8e2dc9adcaef6f1ad0c56ca53712e2128b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
 #include <linux/irqdomain.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/export.h>
@@ -1058,6 +1059,14 @@ static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
        sunxi_pinctrl_irq_unmask(d);
 }
 
+static int sunxi_pinctrl_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+       struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+       u8 bank = d->hwirq / IRQ_PER_BANK;
+
+       return irq_set_irq_wake(pctl->irq[bank], on);
+}
+
 static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
        .name           = "sunxi_pio_edge",
        .irq_ack        = sunxi_pinctrl_irq_ack,
@@ -1066,7 +1075,8 @@ static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
        .irq_request_resources = sunxi_pinctrl_irq_request_resources,
        .irq_release_resources = sunxi_pinctrl_irq_release_resources,
        .irq_set_type   = sunxi_pinctrl_irq_set_type,
-       .flags          = IRQCHIP_SKIP_SET_WAKE,
+       .irq_set_wake   = sunxi_pinctrl_irq_set_wake,
+       .flags          = IRQCHIP_MASK_ON_SUSPEND,
 };
 
 static struct irq_chip sunxi_pinctrl_level_irq_chip = {
@@ -1081,7 +1091,9 @@ static struct irq_chip sunxi_pinctrl_level_irq_chip = {
        .irq_request_resources = sunxi_pinctrl_irq_request_resources,
        .irq_release_resources = sunxi_pinctrl_irq_release_resources,
        .irq_set_type   = sunxi_pinctrl_irq_set_type,
-       .flags          = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED |
+       .irq_set_wake   = sunxi_pinctrl_irq_set_wake,
+       .flags          = IRQCHIP_EOI_THREADED |
+                         IRQCHIP_MASK_ON_SUSPEND |
                          IRQCHIP_EOI_IF_HANDLED,
 };
 
index cefbbb8d1a686c5b2592130cf773258311077982..21661f6490d681d8ab9b97225c70be008c35bfd6 100644 (file)
@@ -275,11 +275,57 @@ static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
        return 0;
 }
 
+static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
+                                            struct pinctrl_gpio_range *range,
+                                            unsigned int offset)
+{
+       struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+       const struct tegra_pingroup *group;
+       u32 value;
+
+       if (!pmx->soc->sfsel_in_mux)
+               return 0;
+
+       group = &pmx->soc->groups[offset];
+
+       if (group->mux_reg < 0 || group->sfsel_bit < 0)
+               return -EINVAL;
+
+       value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
+       value &= ~BIT(group->sfsel_bit);
+       pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
+
+       return 0;
+}
+
+static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
+                                           struct pinctrl_gpio_range *range,
+                                           unsigned int offset)
+{
+       struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+       const struct tegra_pingroup *group;
+       u32 value;
+
+       if (!pmx->soc->sfsel_in_mux)
+               return;
+
+       group = &pmx->soc->groups[offset];
+
+       if (group->mux_reg < 0 || group->sfsel_bit < 0)
+               return;
+
+       value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
+       value |= BIT(group->sfsel_bit);
+       pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
+}
+
 static const struct pinmux_ops tegra_pinmux_ops = {
        .get_functions_count = tegra_pinctrl_get_funcs_count,
        .get_function_name = tegra_pinctrl_get_func_name,
        .get_function_groups = tegra_pinctrl_get_func_groups,
        .set_mux = tegra_pinctrl_set_mux,
+       .gpio_request_enable = tegra_pinctrl_gpio_request_enable,
+       .gpio_disable_free = tegra_pinctrl_gpio_disable_free,
 };
 
 static int tegra_pinconf_reg(struct tegra_pmx *pmx,
@@ -689,12 +735,12 @@ const struct dev_pm_ops tegra_pinctrl_pm = {
        .resume = &tegra_pinctrl_resume
 };
 
-static bool gpio_node_has_range(const char *compatible)
+static bool tegra_pinctrl_gpio_node_has_range(struct tegra_pmx *pmx)
 {
        struct device_node *np;
        bool has_prop = false;
 
-       np = of_find_compatible_node(NULL, NULL, compatible);
+       np = of_find_compatible_node(NULL, NULL, pmx->soc->gpio_compatible);
        if (!np)
                return has_prop;
 
@@ -794,7 +840,7 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
 
        tegra_pinctrl_clear_parked_bits(pmx);
 
-       if (!gpio_node_has_range(pmx->soc->gpio_compatible))
+       if (pmx->soc->ngpios > 0 && !tegra_pinctrl_gpio_node_has_range(pmx))
                pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
 
        platform_set_drvdata(pdev, pmx);
index 0fc82eea9cf1224cc5bae8b9771cd0c93aec1fb2..fcad7f74c5a25bae6b6cd9e7d127898911e36955 100644 (file)
@@ -107,7 +107,8 @@ struct tegra_function {
  *                     drvup, slwr, slwf, and drvtype parameters.
  * @drv_bank:          Drive fields register bank.
  * @hsm_bit:           High Speed Mode register bit.
- * @schmitt_bit:       Scmitt register bit.
+ * @sfsel_bit:         GPIO/SFIO selection register bit.
+ * @schmitt_bit:       Schmitt register bit.
  * @lpmd_bit:          Low Power Mode register bit.
  * @drvdn_bit:         Drive Down register bit.
  * @drvdn_width:       Drive Down field width.
@@ -153,6 +154,7 @@ struct tegra_pingroup {
        s32 ioreset_bit:6;
        s32 rcv_sel_bit:6;
        s32 hsm_bit:6;
+       s32 sfsel_bit:6;
        s32 schmitt_bit:6;
        s32 lpmd_bit:6;
        s32 drvdn_bit:6;
@@ -192,6 +194,7 @@ struct tegra_pinctrl_soc_data {
        bool hsm_in_mux;
        bool schmitt_in_mux;
        bool drvtype_in_mux;
+       bool sfsel_in_mux;
 };
 
 extern const struct dev_pm_ops tegra_pinctrl_pm;
index daf44cf240c901250b5f1b12e6325a0c06901ed5..2e0b5f7bb095bebd5de52b15d437f3f82eaf6c9e 100644 (file)
 
 /* Define unique ID for each pins */
 enum pin_id {
-       TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0 = 256,
-       TEGRA_PIN_PEX_L5_RST_N_PGG1 = 257,
-       TEGRA_PIN_NUM_GPIOS = 258,
+       TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0,
+       TEGRA_PIN_PEX_L5_RST_N_PGG1,
 };
 
 /* Table for pin descriptor */
 static const struct pinctrl_pin_desc tegra194_pins[] = {
-       PINCTRL_PIN(TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0,
-                   "TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0"),
-       PINCTRL_PIN(TEGRA_PIN_PEX_L5_RST_N_PGG1,
-                   "TEGRA_PIN_PEX_L5_RST_N_PGG1"),
+       PINCTRL_PIN(TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0, "PEX_L5_CLKREQ_N_PGG0"),
+       PINCTRL_PIN(TEGRA_PIN_PEX_L5_RST_N_PGG1, "PEX_L5_RST_N_PGG1"),
 };
 
 static const unsigned int pex_l5_clkreq_n_pgg0_pins[] = {
@@ -59,6 +56,7 @@ enum tegra_mux_dt {
        {                                       \
                .name = #lid,                   \
        }
+
 static struct tegra_function tegra194_functions[] = {
        TEGRA_PIN_FUNCTION(rsvd0),
        TEGRA_PIN_FUNCTION(rsvd1),
@@ -70,7 +68,7 @@ static struct tegra_function tegra194_functions[] = {
 #define DRV_PINGROUP_ENTRY_Y(r, drvdn_b, drvdn_w, drvup_b,     \
                             drvup_w, slwr_b, slwr_w, slwf_b,   \
                             slwf_w, bank)                      \
-               .drv_reg = ((r)),                       \
+               .drv_reg = ((r)),                               \
                .drv_bank = bank,                               \
                .drvdn_bit = drvdn_b,                           \
                .drvdn_width = drvdn_w,                         \
@@ -89,7 +87,7 @@ static struct tegra_function tegra194_functions[] = {
                .hsm_bit = -1,                                  \
                .mux_bank = bank,                               \
                .mux_bit = 0,                                   \
-               .pupd_reg = ((r)),              \
+               .pupd_reg = ((r)),                              \
                .pupd_bank = bank,                              \
                .pupd_bit = 2,                                  \
                .tri_reg = ((r)),                               \
@@ -97,6 +95,7 @@ static struct tegra_function tegra194_functions[] = {
                .tri_bit = 4,                                   \
                .einput_bit = e_input,                          \
                .odrain_bit = e_od,                             \
+               .sfsel_bit = 10,                                \
                .schmitt_bit = schmitt_b,                       \
                .drvtype_bit = 13,                              \
                .drv_reg = -1,                                  \
@@ -109,20 +108,20 @@ static struct tegra_function tegra194_functions[] = {
 
 #define PINGROUP(pg_name, f0, f1, f2, f3, r, bank, pupd, e_lpbk,       \
                 e_input, e_lpdr, e_od, schmitt_b, drvtype, io_rail)    \
-       {                                                       \
-               .name = #pg_name,                               \
-               .pins = pg_name##_pins,                         \
-               .npins = ARRAY_SIZE(pg_name##_pins),            \
-                       .funcs = {                              \
-                               TEGRA_MUX_##f0,                 \
-                               TEGRA_MUX_##f1,                 \
-                               TEGRA_MUX_##f2,                 \
-                               TEGRA_MUX_##f3,                 \
-                       },                                      \
-               PIN_PINGROUP_ENTRY_Y(r, bank, pupd, e_lpbk,     \
-                                    e_input, e_od,             \
-                                    schmitt_b, drvtype),       \
-               drive_##pg_name,                                \
+       {                                                               \
+               .name = #pg_name,                                       \
+               .pins = pg_name##_pins,                                 \
+               .npins = ARRAY_SIZE(pg_name##_pins),                    \
+                       .funcs = {                                      \
+                               TEGRA_MUX_##f0,                         \
+                               TEGRA_MUX_##f1,                         \
+                               TEGRA_MUX_##f2,                         \
+                               TEGRA_MUX_##f3,                         \
+                       },                                              \
+               PIN_PINGROUP_ENTRY_Y(r, bank, pupd, e_lpbk,             \
+                                    e_input, e_od,                     \
+                                    schmitt_b, drvtype),               \
+               drive_##pg_name,                                        \
        }
 
 static const struct tegra_pingroup tegra194_groups[] = {
@@ -133,7 +132,6 @@ static const struct tegra_pingroup tegra194_groups[] = {
 };
 
 static const struct tegra_pinctrl_soc_data tegra194_pinctrl = {
-       .ngpios = TEGRA_PIN_NUM_GPIOS,
        .pins = tegra194_pins,
        .npins = ARRAY_SIZE(tegra194_pins),
        .functions = tegra194_functions,
@@ -143,6 +141,7 @@ static const struct tegra_pinctrl_soc_data tegra194_pinctrl = {
        .hsm_in_mux = true,
        .schmitt_in_mux = true,
        .drvtype_in_mux = true,
+       .sfsel_in_mux = true,
 };
 
 static int tegra194_pinctrl_probe(struct platform_device *pdev)
index 57babf31e320f2aa5bf7285478ef4d2303a47327..ade348b49b3148cea6cc5d31bbf34cdecd977451 100644 (file)
@@ -29,7 +29,7 @@ struct uniphier_pinctrl_reg_region {
        struct list_head node;
        unsigned int base;
        unsigned int nregs;
-       u32 vals[0];
+       u32 vals[];
 };
 
 struct uniphier_pinctrl_priv {
index ea910a18b4d77378af59b9ac0a2c9f45a0f81eb4..65b97e240196d3e94cd9629287b89ba7b77f24a5 100644 (file)
@@ -486,8 +486,10 @@ static int wmt_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
        u32 val;
 
        val = readl_relaxed(data->base + reg_dir);
-       /* Return 0 == output, 1 == input */
-       return !(val & BIT(bit));
+       if (val & BIT(bit))
+               return GPIO_LINE_DIRECTION_OUT;
+
+       return GPIO_LINE_DIRECTION_IN;
 }
 
 static int wmt_gpio_get_value(struct gpio_chip *chip, unsigned offset)