linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/2] This is a patch series for pinctrl driver of Sunplus SP7021 SoC.
@ 2021-12-14 10:53 Wells Lu
  2021-12-14 10:53 ` [PATCH v4 1/2] dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021 Wells Lu
  2021-12-14 10:53 ` [PATCH v4 2/2] pinctrl: Add driver " Wells Lu
  0 siblings, 2 replies; 10+ messages in thread
From: Wells Lu @ 2021-12-14 10:53 UTC (permalink / raw)
  To: linus.walleij, linux-gpio, linux-kernel, robh+dt, devicetree,
	linux-arm-kernel
  Cc: wells.lu, dvorkin, Wells Lu

Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates
many peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and
etc.) into a single chip. It is designed for industrial control
applications.

Refer to:
https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
https://tibbo.com/store/plus1.html

Wells Lu (2):
  dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021
  pinctrl: Add driver for Sunplus SP7021

 .../bindings/pinctrl/sunplus,sp7021-pinctrl.yaml   |  375 ++++++
 MAINTAINERS                                        |   10 +
 drivers/pinctrl/Kconfig                            |    1 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/sunplus/Kconfig                    |   21 +
 drivers/pinctrl/sunplus/Makefile                   |    5 +
 drivers/pinctrl/sunplus/sppctl.c                   | 1192 ++++++++++++++++++++
 drivers/pinctrl/sunplus/sppctl.h                   |  167 +++
 drivers/pinctrl/sunplus/sppctl_sp7021.c            |  536 +++++++++
 include/dt-bindings/pinctrl/sppctl-sp7021.h        |  173 +++
 include/dt-bindings/pinctrl/sppctl.h               |   40 +
 11 files changed, 2521 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
 create mode 100644 drivers/pinctrl/sunplus/Kconfig
 create mode 100644 drivers/pinctrl/sunplus/Makefile
 create mode 100644 drivers/pinctrl/sunplus/sppctl.c
 create mode 100644 drivers/pinctrl/sunplus/sppctl.h
 create mode 100644 drivers/pinctrl/sunplus/sppctl_sp7021.c
 create mode 100644 include/dt-bindings/pinctrl/sppctl-sp7021.h
 create mode 100644 include/dt-bindings/pinctrl/sppctl.h

-- 
2.7.4


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 1/2] dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021
  2021-12-14 10:53 [PATCH v4 0/2] This is a patch series for pinctrl driver of Sunplus SP7021 SoC Wells Lu
@ 2021-12-14 10:53 ` Wells Lu
  2021-12-14 15:21   ` Rob Herring
  2021-12-14 10:53 ` [PATCH v4 2/2] pinctrl: Add driver " Wells Lu
  1 sibling, 1 reply; 10+ messages in thread
From: Wells Lu @ 2021-12-14 10:53 UTC (permalink / raw)
  To: linus.walleij, linux-gpio, linux-kernel, robh+dt, devicetree,
	linux-arm-kernel
  Cc: wells.lu, dvorkin, Wells Lu

Add dt-bindings header files and documentation for Sunplus SP7021 SoC.

Signed-off-by: Wells Lu <wellslutw@gmail.com>
---
Changes in V4
  - Addressed comments of Mr. Linus Walleij.
    - Remove 'if type object then' stuff for patternProperties '-pins$'.
    - Added more descriptions about pins control of SP7021.
    - Modified name property 'pins' to 'sunplus,pins' (vendor specific).
    - Modified name property 'zero_func' to 'sunplus,zero_func' (vendor specific).

 .../bindings/pinctrl/sunplus,sp7021-pinctrl.yaml   | 375 +++++++++++++++++++++
 MAINTAINERS                                        |   9 +
 include/dt-bindings/pinctrl/sppctl-sp7021.h        | 173 ++++++++++
 include/dt-bindings/pinctrl/sppctl.h               |  40 +++
 4 files changed, 597 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
 create mode 100644 include/dt-bindings/pinctrl/sppctl-sp7021.h
 create mode 100644 include/dt-bindings/pinctrl/sppctl.h

diff --git a/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
new file mode 100644
index 0000000..6ecd999
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
@@ -0,0 +1,375 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/sunplus,sp7021-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 Pin Controller Device Tree Bindings
+
+maintainers:
+  - Dvorkin Dmitry <dvorkin@tibbo.com>
+  - Wells Lu <wellslutw@gmail.com>
+
+description: |
+  The Sunplus SP7021 pin controller is used to control SoC pins. Please
+  refer to pinctrl-bindings.txt in this directory for details of the common
+  pinctrl bindings used by client devices.
+
+  SP7021 has 99 digital GPIO pins which are numbered from GPIO 0 to 98. All
+  are multiplexed with some special function pins. SP7021 has 3 types of
+  special function pins:
+
+  (1) function-group pins:
+      Ex 1 (SPI-NOR flash):
+        If control-field SPI_FLASH_SEL is set to 1, GPIO 83, 84, 86 and 87
+        will be pins of SPI-NOR flash. If it is set to 2, GPIO 76, 78, 79
+        and 81 will be pins of SPI-NOR flash.
+
+      Ex 2 (UART_0):
+        If control-bit UA0_SEL is set to 1, GPIO 88 and 89 will be TX and
+        RX pins of UART_0 (UART channel 0).
+
+      Ex 3 (eMMC):
+        If control-bit EMMC_SEL is set to 1, GPIO 72, 73, 74, 75, 76, 77,
+        78, 79, 80, 81 will be pins of an eMMC device.
+
+      Properties "function" and "groups" are used to select function-group
+      pins.
+
+  (2) fully pin-mux (like phone exchange mux) pins:
+      GPIO 8 to 71 are 'fully pin-mux' pins. Any pins of peripherals of
+      SP7021 (ex: UART_1, UART_2, UART_3, UART_4, I2C_0, I2C_1, and etc.)
+      can be routed to any pins of fully pin-mux pins.
+
+      Ex 1 (UART channel 1):
+        If control-field UA1_TX_SEL is set to 3, TX pin of UART_1 will be
+        routed to GPIO 10 (3 - 1 + 8 = 10).
+        If control-field UA1_RX_SEL is set to 4, RX pin of UART_1 will be
+        routed to GPIO 11 (4 - 1 + 8 = 11).
+        If control-field UA1_RTS_SEL is set to 5, RTS pin of UART_1 will
+        be routed to GPIO 12 (5 - 1 + 8 = 12).
+        If control-field UA1_CTS_SEL is set to 6, CTS pin of UART_1 will
+        be routed to GPIO 13 (6 - 1 + 8 = 13).
+
+      Ex 2 (I2C channel 0):
+        If control-field I2C0_CLK_SEL is set to 20, CLK pin of I2C_0 will
+        be routed to GPIO 27 (20 - 1 + 8 = 27).
+        If control-field I2C0_DATA_SEL is set to 21, DATA pin of I2C_0
+        will be routed to GPIO 28 (21 - 1 + 9 = 28).
+
+      Totally, SP7021 has 120 peripheral pins. The peripheral pins can be
+      routed to any of 64 'fully pin-mux' pins.
+
+  (3) I/O processor pins
+      SP7021 has a built-in I/O processor.
+      Any GPIO pins (GPIO 0 to 98) can be set to pins of I/O processor.
+
+  Vendor property "sunplus,pins" is used to select "fully pin-mux" pins,
+  "I/O processor pins" and "digital GPIO" pins.
+
+  The device node of pin controller of Sunplus SP7021 has following
+  properties.
+
+properties:
+  compatible:
+    const: sunplus,sp7021-pctl
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  reg:
+    items:
+      - description: the MOON2 registers
+      - description: the GPIOXT registers
+      - description: the GPIOXT2 registers
+      - description: the FIRST registers
+      - description: the MOON1 registers
+
+  reg-names:
+    items:
+      - const: moon2
+      - const: gpioxt
+      - const: gpioxt2
+      - const: first
+      - const: moon1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+patternProperties:
+  '-pins$':
+    type: object
+    description: |
+      A pinctrl node should contain at least one subnodes representing the
+      pins or function-pins group available on the machine. Each subnode
+      will list the pins it needs, and how they should be configured.
+
+      Pinctrl node's client devices use subnodes for desired pin
+      configuration. Client device subnodes use below standard properties.
+
+    properties:
+      sunplus,pins:
+        description: |
+          Define 'sunplus,pins' which are used by pinctrl node's client
+          device.
+
+          It consists of one or more integers which represents the config
+          setting for corresponding pin. Each integer defines a individual
+          pin in which:
+
+          Bit 32~24: defines GPIO number. Its range is 0 ~ 98.
+          Bit 23~16: defines types: (1) fully pin-mux pins
+                                    (2) IO processor pins
+                                    (3) digital GPIO pins
+          Bit 15~8:  defines pins of peripherals (which are defined in
+                     'include/dt-binging/pinctrl/sppctl.h').
+          Bit 7~0:   defines types or initial-state of digital GPIO pins.
+
+          Please use macro SPPCTL_IOPAD to define the integers for pins.
+
+        $ref: /schemas/types.yaml#/definitions/uint32-array
+
+      function:
+        description: |
+          Define pin-function which is used by pinctrl node's client device.
+          The name should be one of string in the following enumeration.
+        $ref: "/schemas/types.yaml#/definitions/string"
+        enum: [ SPI_FLASH, SPI_FLASH_4BIT, SPI_NAND, CARD0_EMMC, SD_CARD,
+                UA0, FPGA_IFX, HDMI_TX, LCDIF, USB0_OTG, USB1_OTG ]
+
+      groups:
+        description: |
+          Define pin-group in a specified pin-function.
+          The name should be one of string in the following enumeration.
+        $ref: "/schemas/types.yaml#/definitions/string"
+        enum: [ SPI_FLASH1, SPI_FLASH2, SPI_FLASH_4BIT1, SPI_FLASH_4BIT2,
+                SPI_NAND, CARD0_EMMC, SD_CARD, UA0, FPGA_IFX, HDMI_TX1,
+                HDMI_TX2, HDMI_TX3, LCDIF, USB0_OTG, USB1_OTG ]
+
+      sunplus,zero_func:
+        description: |
+          This is a vendor specific property. It is used to disable pins
+          which are not used by pinctrl node's client device.
+          Some pins may be enabled by boot-loader. We can use this
+          property to disable them.
+        $ref: /schemas/types.yaml#/definitions/uint32-array
+
+    additionalProperties: false
+
+    allOf:
+      - if:
+          properties:
+            function:
+              enum:
+                - SPI_FLASH
+        then:
+          properties:
+            groups:
+              enum:
+                - SPI_FLASH1
+                - SPI_FLASH2
+      - if:
+          properties:
+            function:
+              enum:
+                - SPI_FLASH_4BIT
+        then:
+          properties:
+            groups:
+              enum:
+                - SPI_FLASH_4BIT1
+                - SPI_FLASH_4BIT2
+      - if:
+          properties:
+            function:
+              enum:
+                - SPI_NAND
+        then:
+          properties:
+            groups:
+              enum:
+                - SPI_NAND
+      - if:
+          properties:
+            function:
+              enum:
+                - CARD0_EMMC
+        then:
+          properties:
+            groups:
+              enum:
+                - CARD0_EMMC
+      - if:
+          properties:
+            function:
+              enum:
+                - SD_CARD
+        then:
+          properties:
+            groups:
+              enum:
+                - SD_CARD
+      - if:
+          properties:
+            function:
+              enum:
+                - UA0
+        then:
+          properties:
+            groups:
+              enum:
+                - UA0
+      - if:
+          properties:
+            function:
+              enum:
+                - FPGA_IFX
+        then:
+          properties:
+            groups:
+              enum:
+                - FPGA_IFX
+      - if:
+          properties:
+            function:
+              enum:
+                - HDMI_TX
+        then:
+          properties:
+            groups:
+              enum:
+                - HDMI_TX1
+                - HDMI_TX2
+                - HDMI_TX3
+      - if:
+          properties:
+            function:
+              enum:
+                - LCDIF
+        then:
+          properties:
+            groups:
+              enum:
+                - LCDIF
+      - if:
+          properties:
+            function:
+              enum:
+                - USB0_OTG
+        then:
+          properties:
+            groups:
+              enum:
+                - USB0_OTG
+      - if:
+          properties:
+            function:
+              enum:
+                - USB1_OTG
+        then:
+          properties:
+            groups:
+              enum:
+                - USB1_OTG
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#gpio-cells"
+  - gpio-controller
+  - clocks
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/sppctl-sp7021.h>
+
+    pinctl@9c000100 {
+        compatible = "sunplus,sp7021-pctl";
+        reg = <0x9c000100 0x100>, <0x9c000300 0x80>, <0x9c000380 0x80>,
+              <0x9c0032e4 0x1c>, <0x9c000080 0x20>;
+        reg-names = "moon2", "gpioxt", "gpioxt2", "first", "moon1";
+        gpio-controller;
+        #gpio-cells = <2>;
+        clocks = <&clkc 0x83>;
+        resets = <&rstc 0x73>;
+
+        uart0-pins {
+            function = "UA0";
+            groups = "UA0";
+        };
+
+        spinand0-pins {
+            function = "SPI_NAND";
+            groups = "SPI_NAND";
+        };
+
+        uart1-pins {
+            sunplus,pins = <
+                SPPCTL_IOPAD(11, SPPCTL_PCTL_G_PMUX, MUXF_UA1_TX, 0)
+                SPPCTL_IOPAD(10, SPPCTL_PCTL_G_PMUX, MUXF_UA1_RX, 0)
+            >;
+        };
+
+        uart2-pins {
+            sunplus,pins = <
+                SPPCTL_IOPAD(20, SPPCTL_PCTL_G_PMUX, MUXF_UA1_TX, 0)
+                SPPCTL_IOPAD(21, SPPCTL_PCTL_G_PMUX, MUXF_UA1_RX, 0)
+                SPPCTL_IOPAD(22, SPPCTL_PCTL_G_PMUX, MUXF_UA1_RTS, 0)
+                SPPCTL_IOPAD(23, SPPCTL_PCTL_G_PMUX, MUXF_UA1_CTS, 0)
+            >;
+        };
+
+        emmc-pins {
+            function = "CARD0_EMMC";
+            groups = "CARD0_EMMC";
+        };
+
+        sdcard-pins {
+            function = "SD_CARD";
+            groups = "SD_CARD";
+            sunplus,pins = < SPPCTL_IOPAD(91, SPPCTL_PCTL_G_GPIO, 0, 0) >;
+        };
+
+        hdmi_A_tx1-pins {
+            function = "HDMI_TX";
+            groups = "HDMI_TX1";
+        };
+        hdmi_A_tx2-pins {
+            function = "HDMI_TX";
+            groups = "HDMI_TX2";
+        };
+        hdmi_A_tx3-pins {
+            function = "HDMI_TX";
+            groups = "HDMI_TX3";
+        };
+
+        ethernet-pins {
+            sunplus,pins = <
+                SPPCTL_IOPAD(49,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_CLK_OUT,0)
+                SPPCTL_IOPAD(44,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_MAC_SMI_MDC,0)
+                SPPCTL_IOPAD(43,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_MAC_SMI_MDIO,0)
+                SPPCTL_IOPAD(52,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXEN,0)
+                SPPCTL_IOPAD(50,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXD0,0)
+                SPPCTL_IOPAD(51,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXD1,0)
+                SPPCTL_IOPAD(46,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_CRSDV,0)
+                SPPCTL_IOPAD(47,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXD0,0)
+                SPPCTL_IOPAD(48,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXD1,0)
+            >;
+            sunplus,zero_func = <
+                MUXF_L2SW_LED_FLASH0
+                MUXF_L2SW_LED_ON0
+                MUXF_L2SW_P0_MAC_RMII_RXER
+            >;
+        };
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 13f9a84..6a11176 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15127,6 +15127,15 @@ L:	linux-omap@vger.kernel.org
 S:	Maintained
 F:	drivers/pinctrl/pinctrl-single.c
 
+PIN CONTROLLER - SUNPLUS / TIBBO
+M:	Dvorkin Dmitry <dvorkin@tibbo.com>
+M:	Wells Lu <wellslutw@gmail.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+W:	https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
+F:	Documentation/devicetree/bindings/pinctrl/sunplus,*
+F:	include/dt-bindings/pinctrl/sppctl*
+
 PKTCDVD DRIVER
 M:	linux-block@vger.kernel.org
 S:	Orphan
diff --git a/include/dt-bindings/pinctrl/sppctl-sp7021.h b/include/dt-bindings/pinctrl/sppctl-sp7021.h
new file mode 100644
index 0000000..6721bd4
--- /dev/null
+++ b/include/dt-bindings/pinctrl/sppctl-sp7021.h
@@ -0,0 +1,173 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/* Sunplus SP7021 dt-bindings Pinctrl header file
+ * Copyright (C) Sunplus Tech/Tibbo Tech.
+ * Author: Dvorkin Dmitry <dvorkin@tibbo.com>
+ */
+
+#ifndef	__DT_BINDINGS_PINCTRL_SPPCTL_SP7021_H__
+#define	__DT_BINDINGS_PINCTRL_SPPCTL_SP7021_H__
+
+#include <dt-bindings/pinctrl/sppctl.h>
+
+/* Please don't change the order of the
+ * following defines. They are based on
+ * order of control register define of
+ * MOON2 and MOON4 registers.
+ */
+#define MUXF_GPIO			0
+#define MUXF_IOP			1
+#define MUXF_L2SW_CLK_OUT		2
+#define MUXF_L2SW_MAC_SMI_MDC		3
+#define MUXF_L2SW_LED_FLASH0		4
+#define MUXF_L2SW_LED_FLASH1		5
+#define MUXF_L2SW_LED_ON0		6
+#define MUXF_L2SW_LED_ON1		7
+#define MUXF_L2SW_MAC_SMI_MDIO		8
+#define MUXF_L2SW_P0_MAC_RMII_TXEN	9
+#define MUXF_L2SW_P0_MAC_RMII_TXD0	10
+#define MUXF_L2SW_P0_MAC_RMII_TXD1	11
+#define MUXF_L2SW_P0_MAC_RMII_CRSDV	12
+#define MUXF_L2SW_P0_MAC_RMII_RXD0	13
+#define MUXF_L2SW_P0_MAC_RMII_RXD1	14
+#define MUXF_L2SW_P0_MAC_RMII_RXER	15
+#define MUXF_L2SW_P1_MAC_RMII_TXEN	16
+#define MUXF_L2SW_P1_MAC_RMII_TXD0	17
+#define MUXF_L2SW_P1_MAC_RMII_TXD1	18
+#define MUXF_L2SW_P1_MAC_RMII_CRSDV	19
+#define MUXF_L2SW_P1_MAC_RMII_RXD0	20
+#define MUXF_L2SW_P1_MAC_RMII_RXD1	21
+#define MUXF_L2SW_P1_MAC_RMII_RXER	22
+#define MUXF_DAISY_MODE			23
+#define MUXF_SDIO_CLK			24
+#define MUXF_SDIO_CMD			25
+#define MUXF_SDIO_D0			26
+#define MUXF_SDIO_D1			27
+#define MUXF_SDIO_D2			28
+#define MUXF_SDIO_D3			29
+#define MUXF_PWM0			30
+#define MUXF_PWM1			31
+#define MUXF_PWM2			32
+#define MUXF_PWM3			33
+#define MUXF_PWM4			34
+#define MUXF_PWM5			35
+#define MUXF_PWM6			36
+#define MUXF_PWM7			37
+#define MUXF_ICM0_D			38
+#define MUXF_ICM1_D			39
+#define MUXF_ICM2_D			40
+#define MUXF_ICM3_D			41
+#define MUXF_ICM0_CLK			42
+#define MUXF_ICM1_CLK			43
+#define MUXF_ICM2_CLK			44
+#define MUXF_ICM3_CLK			45
+#define MUXF_SPIM0_INT			46
+#define MUXF_SPIM0_CLK			47
+#define MUXF_SPIM0_EN			48
+#define MUXF_SPIM0_DO			49
+#define MUXF_SPIM0_DI			50
+#define MUXF_SPIM1_INT			51
+#define MUXF_SPIM1_CLK			52
+#define MUXF_SPIM1_EN			53
+#define MUXF_SPIM1_DO			54
+#define MUXF_SPIM1_DI			55
+#define MUXF_SPIM2_INT			56
+#define MUXF_SPIM2_CLK			57
+#define MUXF_SPIM2_EN			58
+#define MUXF_SPIM2_DO			59
+#define MUXF_SPIM2_DI			60
+#define MUXF_SPIM3_INT			61
+#define MUXF_SPIM3_CLK			62
+#define MUXF_SPIM3_EN			63
+#define MUXF_SPIM3_DO			64
+#define MUXF_SPIM3_DI			65
+#define MUXF_SPI0S_INT			66
+#define MUXF_SPI0S_CLK			67
+#define MUXF_SPI0S_EN			68
+#define MUXF_SPI0S_DO			69
+#define MUXF_SPI0S_DI			70
+#define MUXF_SPI1S_INT			71
+#define MUXF_SPI1S_CLK			72
+#define MUXF_SPI1S_EN			73
+#define MUXF_SPI1S_DO			74
+#define MUXF_SPI1S_DI			75
+#define MUXF_SPI2S_INT			76
+#define MUXF_SPI2S_CLK			77
+#define MUXF_SPI2S_EN			78
+#define MUXF_SPI2S_DO			79
+#define MUXF_SPI2S_DI			80
+#define MUXF_SPI3S_INT			81
+#define MUXF_SPI3S_CLK			82
+#define MUXF_SPI3S_EN			83
+#define MUXF_SPI3S_DO			84
+#define MUXF_SPI3S_DI			85
+#define MUXF_I2CM0_CLK			86
+#define MUXF_I2CM0_DAT			87
+#define MUXF_I2CM1_CLK			88
+#define MUXF_I2CM1_DAT			89
+#define MUXF_I2CM2_CLK			90
+#define MUXF_I2CM2_DAT			91
+#define MUXF_I2CM3_CLK			92
+#define MUXF_I2CM3_DAT			93
+#define MUXF_UA1_TX			94
+#define MUXF_UA1_RX			95
+#define MUXF_UA1_CTS			96
+#define MUXF_UA1_RTS			97
+#define MUXF_UA2_TX			98
+#define MUXF_UA2_RX			99
+#define MUXF_UA2_CTS			100
+#define MUXF_UA2_RTS			101
+#define MUXF_UA3_TX			102
+#define MUXF_UA3_RX			103
+#define MUXF_UA3_CTS			104
+#define MUXF_UA3_RTS			105
+#define MUXF_UA4_TX			106
+#define MUXF_UA4_RX			107
+#define MUXF_UA4_CTS			108
+#define MUXF_UA4_RTS			109
+#define MUXF_TIMER0_INT			110
+#define MUXF_TIMER1_INT			111
+#define MUXF_TIMER2_INT			112
+#define MUXF_TIMER3_INT			113
+#define MUXF_GPIO_INT0			114
+#define MUXF_GPIO_INT1			115
+#define MUXF_GPIO_INT2			116
+#define MUXF_GPIO_INT3			117
+#define MUXF_GPIO_INT4			118
+#define MUXF_GPIO_INT5			119
+#define MUXF_GPIO_INT6			120
+#define MUXF_GPIO_INT7			121
+
+#define GROP_SPI_FLASH			122
+#define GROP_SPI_FLASH_4BIT		123
+#define GROP_SPI_NAND			124
+#define GROP_CARD0_EMMC			125
+#define GROP_SD_CARD			126
+#define GROP_UA0			127
+#define GROP_ACHIP_DEBUG		128
+#define GROP_ACHIP_UA2AXI		129
+#define GROP_FPGA_IFX			130
+#define GROP_HDMI_TX			131
+#define GROP_AUD_EXT_ADC_IFX0		132
+#define GROP_AUD_EXT_DAC_IFX0		133
+#define GROP_SPDIF_RX			134
+#define GROP_SPDIF_TX			135
+#define GROP_TDMTX_IFX0			136
+#define GROP_TDMRX_IFX0			137
+#define GROP_PDMRX_IFX0			138
+#define GROP_PCM_IEC_TX			139
+#define GROP_LCDIF			140
+#define GROP_DVD_DSP_DEBUG		141
+#define GROP_I2C_DEBUG			142
+#define GROP_I2C_SLAVE			143
+#define GROP_WAKEUP			144
+#define GROP_UART2AXI			145
+#define GROP_USB0_I2C			146
+#define GROP_USB1_I2C			147
+#define GROP_USB0_OTG			148
+#define GROP_USB1_OTG			149
+#define GROP_UPHY0_DEBUG		150
+#define GROP_UPHY1_DEBUG		151
+#define GROP_UPHY0_EXT			152
+#define GROP_PROBE_PORT			153
+
+#endif
diff --git a/include/dt-bindings/pinctrl/sppctl.h b/include/dt-bindings/pinctrl/sppctl.h
new file mode 100644
index 0000000..8b8ec66
--- /dev/null
+++ b/include/dt-bindings/pinctrl/sppctl.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/* Sunplus dt-bindings Pinctrl header file
+ * Copyright (C) Sunplus Tech/Tibbo Tech.
+ * Author: Dvorkin Dmitry <dvorkin@tibbo.com>
+ */
+
+#ifndef __DT_BINDINGS_PINCTRL_SPPCTL_H__
+#define __DT_BINDINGS_PINCTRL_SPPCTL_H__
+
+#define IOP_G_MASTE		(0x01 << 0)
+#define IOP_G_FIRST		(0x01 << 1)
+
+#define SPPCTL_PCTL_G_PMUX	(0x00        | IOP_G_MASTE)
+#define SPPCTL_PCTL_G_GPIO	(IOP_G_FIRST | IOP_G_MASTE)
+#define SPPCTL_PCTL_G_IOPP	(IOP_G_FIRST | 0x00)
+
+#define SPPCTL_PCTL_L_OUT	(0x01 << 0)	/* Output LOW        */
+#define SPPCTL_PCTL_L_OU1	(0x01 << 1)	/* Output HIGH       */
+#define SPPCTL_PCTL_L_INV	(0x01 << 2)	/* Input Invert      */
+#define SPPCTL_PCTL_L_ONV	(0x01 << 3)	/* Output Invert     */
+#define SPPCTL_PCTL_L_ODR	(0x01 << 4)	/* Output Open Drain */
+
+#define SPPCTL_PCTLE_P(v)	((v) << 24)
+#define SPPCTL_PCTLE_G(v)	((v) << 16)
+#define SPPCTL_PCTLE_F(v)	((v) << 8)
+#define SPPCTL_PCTLE_L(v)	((v) << 0)
+
+#define SPPCTL_PCTLD_P(v)	(((v) >> 24) & 0xff)
+#define SPPCTL_PCTLD_G(v)	(((v) >> 16) & 0xff)
+#define SPPCTL_PCTLD_F(v)	(((v) >>  8) & 0xff)
+#define SPPCTL_PCTLD_L(v)	(((v) >>  0) & 0xff)
+
+/*
+ * pack into 32-bit value:
+ * pin#(8bit), typ(8bit), function(8bit), flag(8bit)
+ */
+#define SPPCTL_IOPAD(pin, typ, fun, flg)	(((pin) << 24) | ((typ) << 16) | \
+						((fun) << 8) | (flg))
+
+#endif
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 2/2] pinctrl: Add driver for Sunplus SP7021
  2021-12-14 10:53 [PATCH v4 0/2] This is a patch series for pinctrl driver of Sunplus SP7021 SoC Wells Lu
  2021-12-14 10:53 ` [PATCH v4 1/2] dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021 Wells Lu
@ 2021-12-14 10:53 ` Wells Lu
  2021-12-14 23:14   ` Andy Shevchenko
  1 sibling, 1 reply; 10+ messages in thread
From: Wells Lu @ 2021-12-14 10:53 UTC (permalink / raw)
  To: linus.walleij, linux-gpio, linux-kernel, robh+dt, devicetree,
	linux-arm-kernel
  Cc: wells.lu, dvorkin, Wells Lu

Add driver for Sunplus SP7021 SoC.

Signed-off-by: Wells Lu <wellslutw@gmail.com>
---
Changes in V4
  - Addressed comments of Mr. Linus Walleij.
    - Added more comments on pin control registers.
    - Use BIT, GENMASK and explicit calculations to improve readability.
    - Removed some empty operation functions.
    - Removed empty function sppctl_remove().
    - others

 MAINTAINERS                             |    1 +
 drivers/pinctrl/Kconfig                 |    1 +
 drivers/pinctrl/Makefile                |    1 +
 drivers/pinctrl/sunplus/Kconfig         |   21 +
 drivers/pinctrl/sunplus/Makefile        |    5 +
 drivers/pinctrl/sunplus/sppctl.c        | 1192 +++++++++++++++++++++++++++++++
 drivers/pinctrl/sunplus/sppctl.h        |  167 +++++
 drivers/pinctrl/sunplus/sppctl_sp7021.c |  536 ++++++++++++++
 8 files changed, 1924 insertions(+)
 create mode 100644 drivers/pinctrl/sunplus/Kconfig
 create mode 100644 drivers/pinctrl/sunplus/Makefile
 create mode 100644 drivers/pinctrl/sunplus/sppctl.c
 create mode 100644 drivers/pinctrl/sunplus/sppctl.h
 create mode 100644 drivers/pinctrl/sunplus/sppctl_sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6a11176..5782f83 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15134,6 +15134,7 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 W:	https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
 F:	Documentation/devicetree/bindings/pinctrl/sunplus,*
+F:	drivers/pinctrl/sunplus/
 F:	include/dt-bindings/pinctrl/sppctl*
 
 PKTCDVD DRIVER
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 6a961d5..5aa4e29 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -459,6 +459,7 @@ source "drivers/pinctrl/samsung/Kconfig"
 source "drivers/pinctrl/spear/Kconfig"
 source "drivers/pinctrl/sprd/Kconfig"
 source "drivers/pinctrl/stm32/Kconfig"
+source "drivers/pinctrl/sunplus/Kconfig"
 source "drivers/pinctrl/sunxi/Kconfig"
 source "drivers/pinctrl/tegra/Kconfig"
 source "drivers/pinctrl/ti/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 5e63de2..9f1eef3 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_PINCTRL_SAMSUNG)	+= samsung/
 obj-$(CONFIG_PINCTRL_SPEAR)	+= spear/
 obj-y				+= sprd/
 obj-$(CONFIG_PINCTRL_STM32)	+= stm32/
+obj-y				+= sunplus/
 obj-$(CONFIG_PINCTRL_SUNXI)	+= sunxi/
 obj-y				+= ti/
 obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
diff --git a/drivers/pinctrl/sunplus/Kconfig b/drivers/pinctrl/sunplus/Kconfig
new file mode 100644
index 0000000..d9291a7
--- /dev/null
+++ b/drivers/pinctrl/sunplus/Kconfig
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Sunplus Pin control driver configuration
+#
+
+config PINCTRL_SPPCTL
+	bool "Sunplus SP7021 PinMux and GPIO driver"
+	depends on SOC_SP7021
+	depends on OF && HAS_IOMEM
+	select GENERIC_PINCTRL_GROUPS
+	select GENERIC_PINMUX_FUNCTIONS
+	select GENERIC_PINCONF
+	select PINCONF
+	select PINMUX
+	select GPIOLIB
+	select OF_GPIO
+	help
+	  Say Y here to support Sunplus SP7021 pinmux controller.
+	  The driver is selected automatically by platform.
+	  This driver requires the pinctrl framework.
+	  GPIO is provided by the same driver.
diff --git a/drivers/pinctrl/sunplus/Makefile b/drivers/pinctrl/sunplus/Makefile
new file mode 100644
index 0000000..63482da
--- /dev/null
+++ b/drivers/pinctrl/sunplus/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Sunplus Pin control drivers.
+#
+obj-$(CONFIG_PINCTRL_SPPCTL) += sppctl.o sppctl_sp7021.o
diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c
new file mode 100644
index 0000000..23aa3b6
--- /dev/null
+++ b/drivers/pinctrl/sunplus/sppctl.c
@@ -0,0 +1,1192 @@
+// SPDX-License-Identifier: GPL-2.0
+/* SP7021 Pin Controller Driver.
+ * Copyright (C) Sunplus Tech/Tibbo Tech.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/bitfield.h>
+
+#include <dt-bindings/pinctrl/sppctl-sp7021.h>
+#include "../pinctrl-utils.h"
+#include "../core.h"
+#include "sppctl.h"
+
+/* sppctl_func_set - Set pin of fully pin-mux function.
+ *
+ * Mask-fields and control-fields of fully pin-mux function of SP7021 are
+ * arranged as shown below:
+ *
+ *  func# | register |  mask-field  | control-field
+ * -------+----------+--------------+---------------
+ *    0   | base[0]  |  (22 : 16)   |   ( 6 : 0)
+ *    1   | base[0]  |  (30 : 24)   |   (14 : 8)
+ *    2   | base[1]  |  (22 : 16)   |   ( 6 : 0)
+ *    3   | baeg[1]  |  (30 : 24)   |   (14 : 8)
+ *    :   |    :     |      :       |       :
+ *
+ * where mask-fields are used to protect control-fields from write-in
+ * accidentally. Set the corresponding bits in the mask-field before
+ * you write a value into a control-field.
+ *
+ * Control-fields are used to set where the function pin is going to
+ * be routed to.
+ *
+ * Note that mask-fields and control-fields of even number of 'func'
+ * are located at bits (22:16) and (6:0), while odd number of 'func's
+ * are located at bits (30:24) and (14:8).
+ */
+static void sppctl_func_set(struct sppctl_pdata *pctl, u8 func, u8 val)
+{
+	u32 reg, offset;
+
+	/* Note that upper 16-bit word are mask-fields and lower 16-bit
+	 * word are the control-fields. Set corresponding bits in mask-
+	 * field before write to a control-field.
+	 */
+	reg = SPPCTL_FULLY_PINMUX_MASK_MASK | val;
+
+	/* Check if 'func' is an odd number or not. Mask and control-
+	 * fields of odd number 'func' is located at upper portion of
+	 * a register. Extra shift is needed.
+	 */
+	if (func & BIT(0))
+		reg <<= SPPCTL_FULLY_PINMUX_UPPER_SHIFT;
+
+	/* Convert func# to register offset w.r.t. base register. */
+	offset = func * 2;
+	offset &= GENMASK(31, 2);
+
+	dev_dbg(pctl->pctl_dev->dev, "%s(0x%x, 0x%x): offset: 0x%x, reg: 0x%08x\n",
+		__func__, func, val, offset, reg);
+
+	writel(reg, pctl->moon2_base + offset);
+}
+
+static u8 sppctl_func_get(struct sppctl_pdata *pctl, u8 func)
+{
+	u32 reg, offset;
+	u8 val;
+
+	/* Refer to descriptions of sppctl_func_set().
+	 * Convert func# to register offset w.r.t. base register.
+	 */
+	offset = func * 2;
+	offset &= GENMASK(31, 2);
+
+	reg = readl(pctl->moon2_base + offset);
+
+	/* Check if 'func' is an odd number or not. Mask and control-
+	 * fields of odd number 'func' is located at upper portion of
+	 * a register. Extra shift is needed.
+	 */
+	if (func & BIT(0))
+		val = reg >> SPPCTL_FULLY_PINMUX_UPPER_SHIFT;
+	else
+		val = reg;
+	val = FIELD_GET(SPPCTL_FULLY_PINMUX_SEL_MASK, val);
+
+	dev_dbg(pctl->pctl_dev->dev, "%s(0x%x): offset: 0x%x, reg: 0x%08X, val: 0x%x\n",
+		__func__, func, offset, reg, val);
+
+	return val;
+}
+
+/* sppctl_gmx_set - Set pin of group pin-mux.
+ *
+ * Mask-fields and control-fields of group pin-mux function of SP7021 are
+ * arranged as shown below:
+ *
+ *  register |  mask-fields | control-fields
+ * ----------+--------------+----------------
+ *  base[0]  |  (31 : 16)   |   (15 : 0)
+ *  base[1]  |  (31 : 24)   |   (15 : 0)
+ *  base[2]  |  (31 : 24)   |   (15 : 0)
+ *     :     |      :       |       :
+ *
+ * where mask-fields are used to protect control-fields from write-in
+ * accidentally. Set the corresponding bits in the mask-field before
+ * you write a value into a control-field.
+ *
+ * Control-fields are used to set where the function pin is going to
+ * be routed to. A control-field consists of one or more bits.
+ */
+static void sppctl_gmx_set(struct sppctl_pdata *pctl, u8 gmx, u8 bit_off, u8 bit_sz,
+			   u8 val)
+{
+	u32 mask, reg;
+
+	/* Note that upper 16-bit word are mask-fields and lower 16-bit
+	 * word are the control-fields. Set corresponding bits in mask-
+	 * field before write to a control-field.
+	 */
+	mask = GENMASK(bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT + bit_sz - 1,
+		       bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT);
+	reg = mask | (val << bit_off);
+
+	writel(reg, pctl->moon1_base + gmx * 4);
+
+	dev_dbg(pctl->pctl_dev->dev, "%s(0x%x, 0x%x, 0x%x, 0x%x): reg: 0x%08X\n",
+		__func__, gmx, bit_off, bit_sz, val, reg);
+}
+
+/* sppctl_first_get - get bit of first register.
+ *
+ * There are 4 FIRST registers. Each has 32 control-bits.
+ * Totally, there are 4 * 32 = 128 control-bits.
+ * Control-bits are arranged as shown below:
+ *
+ *  registers | control-bits
+ * -----------+--------------
+ *  first[0]  |  (31 :  0)
+ *  first[1]  |  (63 : 32)
+ *  first[2]  |  (95 : 64)
+ *  first[3]  | (127 : 96)
+ *
+ * Each control-bit sets type of a GPIO pin.
+ *   0: a fully pin-mux pin
+ *   1: a GPIO or IOP pin
+ */
+static int sppctl_first_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off = (offset / 32) * 4;
+	u32 bit_off = offset % 32;
+	u32 reg;
+	int val;
+
+	reg = readl(spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + reg_off);
+	val = (reg & BIT(bit_off)) ? 1 : 0;
+
+	dev_dbg(chip->parent, "%s(%u): addr = %p, reg = %08x, val = %d\n", __func__, offset,
+		spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST +	reg_off, reg, val);
+
+	return val;
+}
+
+/* sppctl_master_get - get bit of master register.
+ *
+ * There are 8 MASTER registers. Each has 16 mask-bits and 16 control-bits.
+ * Upper 16-bit of MASTER registers are mask-bits while lower 16-bit are
+ * control-bits. Totally, there are 128 mask-bits and 128 control-bits.
+ * They are arranged as shown below:
+ *
+ *  register  |  mask-bits  | control-bits
+ * -----------+-------------+--------------
+ *  master[0] |  (15 :   0) |  (15 :   0)
+ *  master[1] |  (31 :  16) |  (31 :  16)
+ *  master[2] |  (47 :  32) |  (47 :  32)
+ *     :      |      :      |      :
+ *  master[7] | (127 : 112) | (127 : 112)
+ *
+ * where mask-bits are used to protect control-bits from write-in
+ * accidentally. Set the corresponding mask-bit before you write
+ * a value into a control-bit.
+ *
+ * Each control-bit sets type of a GPIO pin when FIRST bit is 1.
+ *   0: a IOP pin
+ *   1: a GPIO pin
+ */
+static int sppctl_master_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off = (offset / 16) * 4;
+	u32 bit_off = offset % 16;
+	u32 reg;
+	int val;
+
+	reg = readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + reg_off);
+	val = (reg & BIT(bit_off)) ? 1 : 0;
+
+	dev_dbg(chip->parent, "%s(%u): addr = %p, reg = %08x, val = %d\n", __func__, offset,
+		spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + reg_off, reg, val);
+
+	return val;
+}
+
+static void sppctl_first_master_set(struct gpio_chip *chip, unsigned int offset,
+				    enum mux_f_mg first, enum mux_m_ig master)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+	int val;
+
+	/* FIRST register */
+	if (first != mux_f_keep) {
+		/* Refer to descriptions of function sppctl_first_get()
+		 * for usage of FIRST registers.
+		 */
+		reg_off = (offset / 32) * 4;
+		bit_off = offset % 32;
+
+		reg = readl(spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + reg_off);
+		val = (reg & BIT(bit_off)) ? 1 : 0;
+
+		dev_dbg(chip->parent, "First: %08x (%p)\n", reg, spp_gchip->first_base +
+			SPPCTL_GPIO_OFF_FIRST + reg_off);
+
+		if (first != val) {
+			if (first == mux_f_gpio)
+				reg |= BIT(bit_off);
+			else
+				reg &= ~BIT(bit_off);
+			writel(reg, spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + reg_off);
+
+			dev_dbg(chip->parent, "First: %08x\n", reg);
+		}
+	}
+
+	/* MASTER register */
+	if (master != mux_m_keep) {
+		/* Refer to descriptions of function sppctl_master_get()
+		 * for usage of MASTER registers.
+		 */
+		reg_off = (offset / 16) * 4;
+		bit_off = offset % 16;
+
+		reg = BIT(bit_off) << SPPCTL_MASTER_MASK_SHIFT;
+		if (master == mux_m_gpio)
+			reg |= BIT(bit_off);
+		writel(reg, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + reg_off);
+
+		dev_dbg(chip->parent, "Master: %08x (%p)\n", reg, spp_gchip->gpioxt_base +
+			SPPCTL_GPIO_OFF_MASTER + reg_off);
+	}
+}
+
+static void sppctl_gpio_input_inv_set(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+	reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) | BIT(bit_off);
+
+	writel(reg, spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_IINV + reg_off);
+}
+
+static void sppctl_gpio_output_inv_set(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+	reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) | BIT(bit_off);
+
+	writel(reg, spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OINV + reg_off);
+}
+
+static int sppctl_gpio_output_od_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+	reg = readl(spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD + reg_off);
+
+	return (reg & BIT(bit_off)) ? 1 : 0;
+}
+
+static void sppctl_gpio_output_od_set(struct gpio_chip *chip, unsigned int offset,
+				      unsigned int val)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+	reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) | BIT(bit_off);
+
+	writel(reg, spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD + reg_off);
+}
+
+static int sppctl_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+	reg = readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + reg_off);
+
+	return (reg & BIT(bit_off)) ? 0 : 1;
+}
+
+static int sppctl_gpio_inv_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+	u16 inv_off;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+
+	inv_off = SPPCTL_GPIO_OFF_IINV;
+	if (sppctl_gpio_get_direction(chip, offset) == 0)
+		inv_off = SPPCTL_GPIO_OFF_OINV;
+	reg = readl(spp_gchip->gpioxt2_base + inv_off + reg_off);
+
+	return (reg & BIT(bit_off)) ? 1 : 0;
+}
+
+static int sppctl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+	reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT);
+
+	writel(reg, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + reg_off);
+	return 0;
+}
+
+static int sppctl_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int val)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+	reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) | BIT(bit_off);
+	writel(reg, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + reg_off);
+
+	if (val < 0)
+		return 0;
+
+	reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT);
+	if (val)
+		reg |= BIT(bit_off);
+
+	writel(reg, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OUT + reg_off);
+	return 0;
+}
+
+static int sppctl_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	reg_off = (offset / 32) * 4;
+	bit_off = offset % 32;
+	reg = readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IN + reg_off);
+
+	return (reg & BIT(bit_off)) ? 1 : 0;
+}
+
+static void sppctl_gpio_set(struct gpio_chip *chip, unsigned int offset, int val)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	/* Upper 16-bit word is mask. Lower 16-bit word is value.
+	 * Refer to descriptions of function sppctl_master_get().
+	 */
+	reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+	reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT);
+	if (val)
+		reg |= BIT(bit_off);
+
+	writel(reg, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OUT + reg_off);
+}
+
+static int sppctl_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+				  unsigned long config)
+{
+	enum pin_config_param param = pinconf_to_config_param(config);
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u16 arg = pinconf_to_config_argument(config);
+	u32 reg_off, bit_off, reg;
+	int ret = 0;
+
+	dev_dbg(chip->parent, "%s(%03d, %lX) param: %d, arg: %d\n", __func__,
+		offset, config, param, arg);
+
+	switch (param) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		/* Upper 16-bit word is mask. Lower 16-bit word is value.
+		 * Refer to descriptions of function sppctl_master_get().
+		 */
+		reg_off = (offset / 16) * 4;
+		bit_off = offset % 16;
+		reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) | BIT(bit_off);
+
+		writel(reg, spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD + reg_off);
+		break;
+
+	case PIN_CONFIG_INPUT_ENABLE:
+		dev_dbg(chip->parent, "%s(%03d, %lX) arg: %d\n", __func__,
+			offset, config, arg);
+		break;
+
+	case PIN_CONFIG_OUTPUT:
+		ret = sppctl_gpio_direction_output(chip, offset, 0);
+		break;
+
+	case PIN_CONFIG_PERSIST_STATE:
+		dev_dbg(chip->parent, "%s(%03d, %lX) not support, param: %d\n", __func__,
+			offset, config, param);
+		ret = -ENOTSUPP;
+		break;
+
+	default:
+		dev_dbg(chip->parent, "%s(%03d, %lX) unknown, param: %d\n", __func__,
+			offset, config, param);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void sppctl_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	const char *label;
+	int i;
+
+	for (i = 0; i < chip->ngpio; i++) {
+		label = gpiochip_is_requested(chip, i);
+		if (!label)
+			label = "";
+
+		seq_printf(s, " gpio-%03d (%-16.16s | %-16.16s)", i + chip->base,
+			   chip->names[i], label);
+		seq_printf(s, " %c", sppctl_gpio_get_direction(chip, i) == 0 ? 'O' : 'I');
+		seq_printf(s, ":%d", sppctl_gpio_get(chip, i));
+		seq_printf(s, " %s", (sppctl_first_get(chip, i) ? "gpi" : "mux"));
+		seq_printf(s, " %s", (sppctl_master_get(chip, i) ? "gpi" : "iop"));
+		seq_printf(s, " %s", (sppctl_gpio_inv_get(chip, i) ? "inv" : "   "));
+		seq_printf(s, " %s", (sppctl_gpio_output_od_get(chip, i) ? "oDr" : ""));
+		seq_puts(s, "\n");
+	}
+}
+#endif
+
+static int sppctl_gpio_new(struct platform_device *pdev, struct sppctl_pdata *pctl)
+{
+	struct sppctl_gpio_chip *spp_gchip;
+	struct gpio_chip *gchip;
+	int err;
+
+	if (!of_find_property(pdev->dev.of_node, "gpio-controller", NULL)) {
+		dev_err_probe(&pdev->dev, -EINVAL, "Not a gpio-controller!\n");
+		return -EINVAL;
+	}
+
+	spp_gchip = devm_kzalloc(&pdev->dev, sizeof(*spp_gchip), GFP_KERNEL);
+	if (!spp_gchip)
+		return -ENOMEM;
+	pctl->spp_gchip = spp_gchip;
+
+	spp_gchip->gpioxt_base  = pctl->gpioxt_base;
+	spp_gchip->gpioxt2_base = pctl->gpioxt2_base;
+	spp_gchip->first_base   = pctl->first_base;
+
+	gchip =                    &spp_gchip->chip;
+	gchip->label =             SPPCTL_MODULE_NAME;
+	gchip->parent =            &pdev->dev;
+	gchip->owner =             THIS_MODULE;
+	gchip->request =           gpiochip_generic_request;
+	gchip->free =              gpiochip_generic_free;
+	gchip->get_direction =     sppctl_gpio_get_direction;
+	gchip->direction_input =   sppctl_gpio_direction_input;
+	gchip->direction_output =  sppctl_gpio_direction_output;
+	gchip->get =               sppctl_gpio_get;
+	gchip->set =               sppctl_gpio_set;
+	gchip->set_config =        sppctl_gpio_set_config;
+#ifdef CONFIG_DEBUG_FS
+	gchip->dbg_show =          sppctl_gpio_dbg_show;
+#endif
+	gchip->base =              0; /* it is main platform GPIO controller */
+	gchip->ngpio =             sppctl_gpio_list_sz;
+	gchip->names =             sppctl_gpio_list_s;
+	gchip->can_sleep =         0;
+	gchip->of_node =           pdev->dev.of_node;
+	gchip->of_gpio_n_cells =   2;
+
+	pctl->pctl_grange.npins = gchip->ngpio;
+	pctl->pctl_grange.base =  gchip->base;
+	pctl->pctl_grange.name =  gchip->label;
+	pctl->pctl_grange.gc =    gchip;
+
+	err = devm_gpiochip_add_data(&pdev->dev, gchip, spp_gchip);
+	if (err) {
+		dev_err_probe(&pdev->dev, err, "Failed to add gpiochip!\n");
+		return err;
+	}
+
+	return 0;
+}
+
+/* pinconf operations */
+static int sppctl_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
+				 unsigned long *config)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int param = pinconf_to_config_param(*config);
+	unsigned int arg = 0;
+
+	dev_dbg(pctldev->dev, "%s(%d)\n", __func__, pin);
+
+	switch (param) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (!sppctl_gpio_output_od_get(&pctl->spp_gchip->chip, pin))
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_OUTPUT:
+		if (!sppctl_first_get(&pctl->spp_gchip->chip, pin))
+			return -EINVAL;
+		if (!sppctl_master_get(&pctl->spp_gchip->chip, pin))
+			return -EINVAL;
+		if (sppctl_gpio_get_direction(&pctl->spp_gchip->chip, pin) != 0)
+			return -EINVAL;
+		arg = sppctl_gpio_get(&pctl->spp_gchip->chip, pin);
+		break;
+
+	default:
+		dev_dbg(pctldev->dev, "%s(%d) skipping, param: 0x%x\n",
+			__func__, pin, param);
+		return -EOPNOTSUPP;
+	}
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int sppctl_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+				 unsigned long *configs, unsigned int num_configs)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	int i = 0;
+
+	dev_dbg(pctldev->dev, "%s(%d, %ld, %d)\n", __func__, pin, *configs, num_configs);
+
+	/* Special handling for IOP */
+	if (configs[i] == 0xFF) {
+		sppctl_first_master_set(&pctl->spp_gchip->chip, pin, mux_f_gpio, mux_m_iop);
+		return 0;
+	}
+
+	for (i = 0; i < num_configs; i++) {
+		if (configs[i] & SPPCTL_PCTL_L_OUT) {
+			dev_dbg(pctldev->dev, "%d: OUT\n", i);
+			sppctl_gpio_direction_output(&pctl->spp_gchip->chip, pin, 0);
+		}
+		if (configs[i] & SPPCTL_PCTL_L_OU1) {
+			dev_dbg(pctldev->dev, "%d: OU1\n", i);
+			sppctl_gpio_direction_output(&pctl->spp_gchip->chip, pin, 1);
+		}
+		if (configs[i] & SPPCTL_PCTL_L_INV) {
+			dev_dbg(pctldev->dev, "%d: INV\n", i);
+			sppctl_gpio_input_inv_set(&pctl->spp_gchip->chip, pin);
+		}
+		if (configs[i] & SPPCTL_PCTL_L_ONV) {
+			dev_dbg(pctldev->dev, "%d: ONV\n", i);
+			sppctl_gpio_output_inv_set(&pctl->spp_gchip->chip, pin);
+		}
+		if (configs[i] & SPPCTL_PCTL_L_ODR) {
+			dev_dbg(pctldev->dev, "%d: ODR\n", i);
+			sppctl_gpio_output_od_set(&pctl->spp_gchip->chip, pin, 1);
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void sppctl_config_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+				   unsigned int offset)
+{
+	dev_dbg(pctldev->dev, "%s(%d)\n", __func__, offset);
+	seq_printf(s, " %s", dev_name(pctldev->dev));
+}
+#endif
+
+static const struct pinconf_ops sppctl_pconf_ops = {
+	.is_generic                 = true,
+	.pin_config_get             = sppctl_pin_config_get,
+	.pin_config_set             = sppctl_pin_config_set,
+#ifdef CONFIG_DEBUG_FS
+	.pin_config_dbg_show        = sppctl_config_dbg_show,
+#endif
+};
+
+/* pinmux operations */
+static int sppctl_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	return sppctl_list_funcs_sz;
+}
+
+static const char *sppctl_get_function_name(struct pinctrl_dev *pctldev,
+					    unsigned int selector)
+{
+	return sppctl_list_funcs[selector].name;
+}
+
+static int sppctl_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector,
+				      const char * const **groups, unsigned int *num_groups)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct sppctl_func *f = &sppctl_list_funcs[selector];
+
+	*num_groups = 0;
+	switch (f->freg) {
+	case f_off_i:
+	case f_off_0:   /* gen GPIO/IOP: all groups = all pins */
+		*num_groups = sppctl_gpio_list_sz;
+		*groups = sppctl_gpio_list_s;
+		break;
+
+	case f_off_m:   /* pin-mux */
+		*num_groups = sppctl_pmux_list_sz;
+		*groups = sppctl_pmux_list_s;
+		break;
+
+	case f_off_g:   /* pin-group */
+		if (!f->grps)
+			break;
+		*num_groups = f->gnum;
+		*groups = &pctl->groups_name[selector * SPPCTL_MAX_GROUPS];
+		break;
+
+	default:
+		dev_err(pctldev->dev, "%s(selector: %d) unknown fOFF %d\n", __func__,
+			selector, f->freg);
+		break;
+	}
+
+	dev_dbg(pctldev->dev, "%s(selector: %d) %d\n", __func__, selector, *num_groups);
+	return 0;
+}
+
+static int sppctl_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
+			  unsigned int group_selector)
+{
+	const struct sppctl_func *f = &sppctl_list_funcs[func_selector];
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct grp2fp_map g2fpm = pctl->g2fp_maps[group_selector];
+	int i, j;
+
+	dev_dbg(pctldev->dev, "%s(func: %d, grp: %d)\n", __func__, func_selector,
+		group_selector);
+
+	switch (f->freg) {
+	case f_off_0:   /* Detach from full pin-mux pin */
+		j = -1;
+		for (i = 0; i < sppctl_list_funcs_sz; i++) {
+			if (sppctl_list_funcs[i].freg != f_off_m)
+				continue;
+			j++; /* j starts at 0 because its initial value is -1. */
+			if (sppctl_func_get(pctl, j) != group_selector)
+				continue;
+			sppctl_func_set(pctl, j, 0);
+		}
+		break;
+
+	case f_off_m:   /* fully pin-mux */
+		sppctl_first_master_set(&pctl->spp_gchip->chip, group_selector,
+					mux_f_mux, mux_m_keep);
+		sppctl_func_set(pctl, func_selector - SPPCTL_FULLY_PINMUX_TBL_START,
+				(group_selector == 0) ?	group_selector :
+				SPPCTL_FULLY_PINMUX_CONV(group_selector));
+		break;
+
+	case f_off_g:   /* group pin-mux*/
+		for (i = 0; i < f->grps[g2fpm.g_idx].pnum; i++)
+			sppctl_first_master_set(&pctl->spp_gchip->chip,
+						f->grps[g2fpm.g_idx].pins[i],
+						mux_f_mux, mux_m_keep);
+		sppctl_gmx_set(pctl, f->roff, f->boff, f->blen, f->grps[g2fpm.g_idx].gval);
+		break;
+
+	case f_off_i:   /* IOP */
+		sppctl_first_master_set(&pctl->spp_gchip->chip, group_selector,
+					mux_f_gpio, mux_m_iop);
+		break;
+
+	default:
+		dev_err(pctldev->dev, "%s(func_selector: %d) unknown f_off: %d\n",
+			__func__, func_selector, f->freg);
+		break;
+	}
+
+	return 0;
+}
+
+static int sppctl_gpio_request_enable(struct pinctrl_dev *pctldev,
+				      struct pinctrl_gpio_range *range, unsigned int offset)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	int g_f, g_m;
+
+	dev_dbg(pctldev->dev, "%s(%d)\n", __func__, offset);
+
+	g_f = sppctl_first_get(&pctl->spp_gchip->chip, offset);
+	g_m = sppctl_master_get(&pctl->spp_gchip->chip, offset);
+	if (g_f == mux_f_gpio && g_m == mux_m_gpio)
+		return 0;
+
+	pin_desc_get(pctldev, offset);
+
+	sppctl_first_master_set(&pctl->spp_gchip->chip, offset, mux_f_gpio, mux_m_gpio);
+	return 0;
+}
+
+static const struct pinmux_ops sppctl_pinmux_ops = {
+	.get_functions_count = sppctl_get_functions_count,
+	.get_function_name   = sppctl_get_function_name,
+	.get_function_groups = sppctl_get_function_groups,
+	.set_mux             = sppctl_set_mux,
+	.gpio_request_enable = sppctl_gpio_request_enable,
+	.strict              = true
+};
+
+/* pinctrl operations */
+static int sppctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->unq_grps_sz;
+}
+
+static const char *sppctl_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->unq_grps[selector];
+}
+
+static int sppctl_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
+				 const unsigned int **pins, unsigned int *num_pins)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct grp2fp_map g2fpm = pctl->g2fp_maps[selector];
+	const struct sppctl_func *f;
+
+	f = &sppctl_list_funcs[g2fpm.f_idx];
+	dev_dbg(pctldev->dev, "%s(%d), f_idx: %d, g_idx: %d, freg: %d\n",
+		__func__, selector, g2fpm.f_idx, g2fpm.g_idx, f->freg);
+
+	*num_pins = 0;
+
+	/* MUX | GPIO | IOP: 1 pin -> 1 group */
+	if (f->freg != f_off_g) {
+		*num_pins = 1;
+		*pins = &sppctl_pins_gpio[selector];
+		return 0;
+	}
+
+	/* IOP (several pins at once in a group) */
+	if (!f->grps)
+		return 0;
+	if (f->gnum < 1)
+		return 0;
+
+	*num_pins = f->grps[g2fpm.g_idx].pnum;
+	*pins = f->grps[g2fpm.g_idx].pins;
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void sppctl_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+				unsigned int offset)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const char *tmpp;
+	u8 g_f, g_m;
+
+	seq_printf(s, "%s", dev_name(pctldev->dev));
+	g_f = sppctl_first_get(&pctl->spp_gchip->chip, offset);
+	g_m = sppctl_master_get(&pctl->spp_gchip->chip, offset);
+
+	tmpp = "?";
+	if (g_f &&  g_m)
+		tmpp = "GPIO";
+	if (g_f && !g_m)
+		tmpp = " IOP";
+	if (!g_f)
+		tmpp = " MUX";
+	seq_printf(s, " %s", tmpp);
+}
+#endif
+
+static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config,
+				 struct pinctrl_map **map, unsigned int *num_maps)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	int nmG = of_property_count_strings(np_config, "groups");
+	const struct sppctl_func *f = NULL;
+	struct device_node *parent;
+	unsigned long *configs;
+	struct property *prop;
+	const char *s_f, *s_g;
+	u8 p_p, p_g, p_f, p_l;
+	const __be32 *list;
+	u32 dt_pin, dt_fun;
+	int i, size = 0;
+
+	list = of_get_property(np_config, "sunplus,pins", &size);
+
+	if (nmG <= 0)
+		nmG = 0;
+
+	parent = of_get_parent(np_config);
+	*num_maps = size / sizeof(*list);
+
+	/* Check if out of range or invalid? */
+	for (i = 0; i < (*num_maps); i++) {
+		dt_pin = be32_to_cpu(list[i]);
+		p_p = SPPCTL_PCTLD_P(dt_pin);
+		p_g = SPPCTL_PCTLD_G(dt_pin);
+
+		if (p_p >= sppctl_pins_all_sz) {
+			dev_dbg(pctldev->dev, "Invalid pin property at index %d (0x%08x)\n",
+				i, dt_pin);
+			return -EINVAL;
+		}
+	}
+
+	*map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL);
+	for (i = 0; i < (*num_maps); i++) {
+		dt_pin = be32_to_cpu(list[i]);
+		p_p = SPPCTL_PCTLD_P(dt_pin);
+		p_g = SPPCTL_PCTLD_G(dt_pin);
+		p_f = SPPCTL_PCTLD_F(dt_pin);
+		p_l = SPPCTL_PCTLD_L(dt_pin);
+		(*map)[i].name = parent->name;
+		dev_dbg(pctldev->dev, "map [%d]=%08x, p=%d, g=%d, f=%d, l=%d\n",
+			i, dt_pin, p_p, p_g, p_f, p_l);
+
+		if (p_g == SPPCTL_PCTL_G_GPIO) {
+			(*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+			(*map)[i].data.configs.num_configs = 1;
+			(*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, p_p);
+			configs = kcalloc(1, sizeof(*configs), GFP_KERNEL);
+			*configs = p_l;
+			(*map)[i].data.configs.configs = configs;
+
+			dev_dbg(pctldev->dev, "%s(%d) = 0x%x\n",
+				(*map)[i].data.configs.group_or_pin, p_p, p_l);
+		} else if (p_g == SPPCTL_PCTL_G_IOPP) {
+			(*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+			(*map)[i].data.configs.num_configs = 1;
+			(*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, p_p);
+			configs = kcalloc(1, sizeof(*configs), GFP_KERNEL);
+			*configs = 0xFF;
+			(*map)[i].data.configs.configs = configs;
+
+			dev_dbg(pctldev->dev, "%s(%d) = 0x%x\n",
+				(*map)[i].data.configs.group_or_pin, p_p, p_l);
+		} else {
+			(*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
+			(*map)[i].data.mux.function = sppctl_list_funcs[p_f].name;
+			(*map)[i].data.mux.group = pin_get_name(pctldev, p_p);
+
+			dev_dbg(pctldev->dev, "f->p: %s(%d)->%s(%d)\n",
+				(*map)[i].data.mux.function, p_f,
+				(*map)[i].data.mux.group, p_p);
+		}
+	}
+
+	/* Handle pin-group function. */
+	if (nmG > 0 && of_property_read_string(np_config, "function", &s_f) == 0) {
+		dev_dbg(pctldev->dev, "found func: %s\n", s_f);
+		of_property_for_each_string(np_config, "groups", prop, s_g) {
+			dev_dbg(pctldev->dev, " %s: %s\n", s_f, s_g);
+			(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+			(*map)[*num_maps].data.mux.function = s_f;
+			(*map)[*num_maps].data.mux.group = s_g;
+			dev_dbg(pctldev->dev, "f->g: %s->%s\n",
+				(*map)[*num_maps].data.mux.function,
+				(*map)[*num_maps].data.mux.group);
+			(*num_maps)++;
+		}
+	}
+
+	/* Handle zero function. */
+	list = of_get_property(np_config, "sunplus,zero_func", &size);
+	if (list) {
+		for (i = 0; i < (size / sizeof(*list)); i++) {
+			dt_fun = be32_to_cpu(list[i]);
+			if (dt_fun >= sppctl_list_funcs_sz) {
+				dev_err(pctldev->dev, "Zero-func %d out of range!\n",
+					dt_fun);
+				continue;
+			}
+
+			f = &sppctl_list_funcs[dt_fun];
+			switch (f->freg) {
+			case f_off_m:
+				dev_dbg(pctldev->dev, "Zero-func: %d (%s)\n",
+					dt_fun, f->name);
+				sppctl_func_set(pctl, dt_fun - 2, 0);
+				break;
+
+			case f_off_g:
+				dev_dbg(pctldev->dev, "zero-group: %d (%s)\n",
+					dt_fun, f->name);
+				sppctl_gmx_set(pctl, f->roff, f->boff, f->blen, 0);
+				break;
+
+			default:
+				dev_err(pctldev->dev, "Wrong zero-group: %d (%s)\n",
+					dt_fun, f->name);
+				break;
+			}
+		}
+	}
+
+	of_node_put(parent);
+	dev_dbg(pctldev->dev, "%d pins mapped\n", *num_maps);
+	return 0;
+}
+
+static void sppctl_dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map,
+			       unsigned int num_maps)
+{
+	dev_dbg(pctldev->dev, "%s(%d)\n", __func__, num_maps);
+	pinctrl_utils_free_map(pctldev, map, num_maps);
+}
+
+static const struct pinctrl_ops sppctl_pctl_ops = {
+	.get_groups_count = sppctl_get_groups_count,
+	.get_group_name   = sppctl_get_group_name,
+	.get_group_pins   = sppctl_get_group_pins,
+#ifdef CONFIG_DEBUG_FS
+	.pin_dbg_show     = sppctl_pin_dbg_show,
+#endif
+	.dt_node_to_map   = sppctl_dt_node_to_map,
+	.dt_free_map      = sppctl_dt_free_map,
+};
+
+/* platform driver functions */
+static int sppctl_group_groups(struct platform_device *pdev)
+{
+	struct sppctl_pdata *sppctl = pdev->dev.platform_data;
+	const char *name;
+	int i, k, j;
+
+	/* Fill array of all groups. */
+	sppctl->unq_grps = NULL;
+	sppctl->unq_grps_sz = sppctl_gpio_list_sz;
+
+	/* Calculate unique group names array size. */
+	for (i = 0; i < sppctl_list_funcs_sz; i++)
+		if (sppctl_list_funcs[i].freg == f_off_g)
+			sppctl->unq_grps_sz += sppctl_list_funcs[i].gnum;
+
+	/* Fill up unique group names array. */
+	sppctl->unq_grps = devm_kzalloc(&pdev->dev, (sppctl->unq_grps_sz + 1) *
+					sizeof(char *), GFP_KERNEL);
+	if (!sppctl->unq_grps)
+		return -ENOMEM;
+
+	sppctl->g2fp_maps = devm_kzalloc(&pdev->dev, (sppctl->unq_grps_sz + 1) *
+					 sizeof(struct grp2fp_map), GFP_KERNEL);
+	if (!sppctl->g2fp_maps)
+		return -ENOMEM;
+
+	sppctl->groups_name = devm_kzalloc(&pdev->dev, sppctl_list_funcs_sz *
+					   SPPCTL_MAX_GROUPS * sizeof(char *), GFP_KERNEL);
+	if (!sppctl->groups_name)
+		return -ENOMEM;
+
+	/* gpio */
+	for (i = 0; i < sppctl_gpio_list_sz; i++) {
+		sppctl->unq_grps[i] = sppctl_gpio_list_s[i];
+		sppctl->g2fp_maps[i].f_idx = 0;
+		sppctl->g2fp_maps[i].g_idx = i;
+	}
+
+	/* groups */
+	j = sppctl_gpio_list_sz;
+	for (i = 0; i < sppctl_list_funcs_sz; i++) {
+		if (sppctl_list_funcs[i].freg != f_off_g)
+			continue;
+
+		for (k = 0; k < sppctl_list_funcs[i].gnum; k++) {
+			name = sppctl_list_funcs[i].grps[k].name;
+			sppctl->groups_name[i * SPPCTL_MAX_GROUPS + k] = name;
+			sppctl->unq_grps[j] = name;
+			sppctl->g2fp_maps[j].f_idx = i;
+			sppctl->g2fp_maps[j].g_idx = k;
+			j++;
+		}
+	}
+
+	dev_dbg(&pdev->dev, "funcs: %zd unq_grps: %zd\n", sppctl_list_funcs_sz,
+		sppctl->unq_grps_sz);
+	return 0;
+}
+
+static int sppctl_pinctrl_init(struct platform_device *pdev)
+{
+	struct device_node *np = of_node_get(pdev->dev.of_node);
+	struct sppctl_pdata *sppctl = pdev->dev.platform_data;
+	int err;
+
+	/* Initialize pctl_desc */
+	sppctl->pctl_desc.owner   = THIS_MODULE;
+	sppctl->pctl_desc.name    = dev_name(&pdev->dev);
+	sppctl->pctl_desc.pins    = &sppctl_pins_all[0];
+	sppctl->pctl_desc.npins   = sppctl_pins_all_sz;
+	sppctl->pctl_desc.pctlops = &sppctl_pctl_ops;
+	sppctl->pctl_desc.confops = &sppctl_pconf_ops;
+	sppctl->pctl_desc.pmxops  = &sppctl_pinmux_ops;
+
+	err = sppctl_group_groups(pdev);
+	if (err) {
+		of_node_put(np);
+		return err;
+	}
+
+	err = devm_pinctrl_register_and_init(&pdev->dev, &sppctl->pctl_desc,
+					     sppctl, &sppctl->pctl_dev);
+	if (err) {
+		dev_err_probe(&pdev->dev, err, "Failed to register pinctrl!\n");
+		of_node_put(np);
+		return err;
+	}
+
+	pinctrl_enable(sppctl->pctl_dev);
+	return 0;
+}
+
+static int sppctl_resource_map(struct platform_device *pdev, struct sppctl_pdata *sppctl)
+{
+	struct resource *rp;
+	int ret;
+
+	/* MOON2 registers */
+	rp = platform_get_resource_byname(pdev, IORESOURCE_MEM, "moon2");
+	sppctl->moon2_base = devm_ioremap_resource(&pdev->dev, rp);
+	if (IS_ERR(sppctl->moon2_base)) {
+		ret = PTR_ERR(sppctl->moon2_base);
+		goto ioremap_failed;
+	}
+	dev_dbg(&pdev->dev, "MOON2:   %pr\n", rp);
+
+	/* GPIOXT registers */
+	rp = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpioxt");
+	sppctl->gpioxt_base = devm_ioremap_resource(&pdev->dev, rp);
+	if (IS_ERR(sppctl->gpioxt_base)) {
+		ret = PTR_ERR(sppctl->gpioxt_base);
+		goto ioremap_failed;
+	}
+	dev_dbg(&pdev->dev, "GPIOXT:  %pr\n", rp);
+
+	/* GPIOXT 2 registers */
+	rp = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpioxt2");
+	sppctl->gpioxt2_base = devm_ioremap_resource(&pdev->dev, rp);
+	if (IS_ERR(sppctl->gpioxt2_base)) {
+		ret = PTR_ERR(sppctl->gpioxt2_base);
+		goto ioremap_failed;
+	}
+	dev_dbg(&pdev->dev, "GPIOXT2: %pr\n", rp);
+
+	/* FIRST registers */
+	rp = platform_get_resource_byname(pdev, IORESOURCE_MEM, "first");
+	sppctl->first_base = devm_ioremap_resource(&pdev->dev, rp);
+	if (IS_ERR(sppctl->first_base)) {
+		ret = PTR_ERR(sppctl->first_base);
+		goto ioremap_failed;
+	}
+	dev_dbg(&pdev->dev, "FIRST:   %pr\n", rp);
+
+	/* MOON1 registers */
+	rp = platform_get_resource_byname(pdev, IORESOURCE_MEM, "moon1");
+	sppctl->moon1_base = devm_ioremap_resource(&pdev->dev, rp);
+	if (IS_ERR(sppctl->moon1_base)) {
+		ret = PTR_ERR(sppctl->moon1_base);
+		goto ioremap_failed;
+	}
+	dev_dbg(&pdev->dev, "MOON1:   %pr\n", rp);
+
+	return 0;
+
+ioremap_failed:
+	dev_err_probe(&pdev->dev, ret, "ioremap failed!\n");
+	return ret;
+}
+
+static int sppctl_probe(struct platform_device *pdev)
+{
+	struct sppctl_pdata *sppctl;
+	int ret;
+
+	sppctl = devm_kzalloc(&pdev->dev, sizeof(*sppctl), GFP_KERNEL);
+	if (!sppctl)
+		return -ENOMEM;
+	pdev->dev.platform_data = sppctl;
+
+	ret = sppctl_resource_map(pdev, sppctl);
+	if (ret)
+		return ret;
+
+	ret = sppctl_gpio_new(pdev, sppctl);
+	if (ret)
+		return ret;
+
+	ret = sppctl_pinctrl_init(pdev);
+	if (ret)
+		return ret;
+
+	pinctrl_add_gpio_range(sppctl->pctl_dev, &sppctl->pctl_grange);
+	dev_info(&pdev->dev, "SP7021 PinCtrl by Sunplus/Tibbo Tech. (c)");
+
+	return 0;
+}
+
+static const struct of_device_id sppctl_match_table[] = {
+	{ .compatible = "sunplus,sp7021-pctl" },
+	{ /* zero */ }
+};
+
+static struct platform_driver sppctl_pinctrl_driver = {
+	.driver = {
+		.name           = SPPCTL_MODULE_NAME,
+		.owner          = THIS_MODULE,
+		.of_match_table = sppctl_match_table,
+	},
+	.probe  = sppctl_probe,
+};
+builtin_platform_driver(sppctl_pinctrl_driver)
+
+MODULE_AUTHOR("Dvorkin Dmitry <dvorkin@tibbo.com>");
+MODULE_AUTHOR("Wells Lu <wellslutw@gmail.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Pin Control and GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/sunplus/sppctl.h b/drivers/pinctrl/sunplus/sppctl.h
new file mode 100644
index 0000000..43fbdef
--- /dev/null
+++ b/drivers/pinctrl/sunplus/sppctl.h
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* SP7021 Pin Controller Driver.
+ * Copyright (C) Sunplus Tech/Tibbo Tech.
+ */
+
+#ifndef __SPPCTL_H__
+#define __SPPCTL_H__
+
+#define SPPCTL_MODULE_NAME		"sppctl_sp7021"
+#define SPPCTL_MAX_GROUPS		5
+
+#define SPPCTL_GPIO_OFF_FIRST		0x00
+#define SPPCTL_GPIO_OFF_MASTER		0x00
+#define SPPCTL_GPIO_OFF_OE		0x20
+#define SPPCTL_GPIO_OFF_OUT		0x40
+#define SPPCTL_GPIO_OFF_IN		0x60
+#define SPPCTL_GPIO_OFF_IINV		0x00
+#define SPPCTL_GPIO_OFF_OINV		0x20
+#define SPPCTL_GPIO_OFF_OD		0x40
+
+#define SPPCTL_FULLY_PINMUX_MASK_MASK	GENMASK(22, 16)
+#define SPPCTL_FULLY_PINMUX_SEL_MASK	GENMASK(6, 0)
+#define SPPCTL_FULLY_PINMUX_UPPER_SHIFT	8
+#define SPPCTL_FULLY_PINMUX_TBL_START	2
+
+/* Fully pin-mux pin maps to GPIO(8 : 71)
+ * Refer to following table:
+ *
+ * control-field |  GPIO
+ * --------------+--------
+ *        1      |    8
+ *        2      |    9
+ *        3      |   10
+ *        :      |    :
+ *       65      |   71
+ */
+#define SPPCTL_FULLY_PINMUX_CONV(x)	((x) - 7)
+
+#define SPPCTL_GROUP_PINMUX_MASK_SHIFT	16
+#define SPPCTL_MASTER_MASK_SHIFT	16
+#define SPPCTL_GPIO_MASK_SHIFT		16
+
+#define FNCE(n, r, o, bo, bl, g) { \
+	.name = n, \
+	.freg = r, \
+	.roff = o, \
+	.boff = bo, \
+	.blen = bl, \
+	.grps = (g), \
+	.gnum = ARRAY_SIZE(g), \
+}
+
+#define FNCN(n, r, o, bo, bl) { \
+	.name = n, \
+	.freg = r, \
+	.roff = o, \
+	.boff = bo, \
+	.blen = bl, \
+	.grps = NULL, \
+	.gnum = 0, \
+}
+
+#define EGRP(n, v, p) { \
+	.name = n, \
+	.gval = (v), \
+	.pins = (p), \
+	.pnum = ARRAY_SIZE(p), \
+}
+
+/* FIRST register:
+ *   0: MUX
+ *   1: GPIO/IOP
+ *   2: No change
+ */
+enum mux_f_mg {
+	mux_f_mux = 0,
+	mux_f_gpio = 1,
+	mux_f_keep = 2,
+};
+
+/* MASTER register:
+ *   0: IOP
+ *   1: GPIO
+ *   2: No change
+ */
+enum mux_m_ig {
+	mux_m_iop = 0,
+	mux_m_gpio = 1,
+	mux_m_keep = 2,
+};
+
+enum f_off {
+	f_off_0,	/* nowhere          */
+	f_off_m,	/* mux registers    */
+	f_off_g,	/* group registers  */
+	f_off_i,	/* iop registers    */
+};
+
+struct grp2fp_map {
+	u16 f_idx;      /* function index   */
+	u16 g_idx;      /* pins/group index */
+};
+
+struct sppctl_sdata {
+	u8 i;
+	u8 ridx;
+	struct sppctl_pdata *pdata;
+};
+
+struct sppctl_gpio_chip {
+	void __iomem *gpioxt_base;	/* MASTER, OE, OUT, IN */
+	void __iomem *gpioxt2_base;	/* I_INV, O_INV, OD    */
+	void __iomem *first_base;	/* GPIO_FIRST          */
+
+	struct gpio_chip chip;
+};
+
+struct sppctl_pdata {
+	/* base addresses */
+	void __iomem *moon2_base;	/* MOON2               */
+	void __iomem *gpioxt_base;	/* MASTER, OE, OUT, IN */
+	void __iomem *gpioxt2_base;	/* I_INV, O_INV, OD    */
+	void __iomem *first_base;	/* FIRST               */
+	void __iomem *moon1_base;	/* MOON1               */
+
+	/* pinctrl and gpio-chip */
+	struct pinctrl_desc pctl_desc;
+	struct pinctrl_dev *pctl_dev;
+	struct pinctrl_gpio_range pctl_grange;
+	struct sppctl_gpio_chip *spp_gchip;
+
+	/* others */
+	char const **unq_grps;
+	struct grp2fp_map *g2fp_maps;
+	size_t unq_grps_sz;
+	const char **groups_name;
+};
+
+struct sppctl_grp {
+	const char * const name;
+	const u8 gval;                  /* group number    */
+	const unsigned * const pins;    /* list of pins    */
+	const unsigned int pnum;        /* number of pins  */
+};
+
+struct sppctl_func {
+	const char * const name;
+	const enum f_off freg;          /* function register type */
+	const u8 roff;                  /* register offset        */
+	const u8 boff;                  /* bit offset             */
+	const u8 blen;                  /* bit length             */
+	const struct sppctl_grp * const grps; /* list of groups   */
+	const unsigned int gnum;        /* number of groups       */
+};
+
+extern const struct sppctl_func sppctl_list_funcs[];
+extern const char * const sppctl_pmux_list_s[];
+extern const char * const sppctl_gpio_list_s[];
+extern const struct pinctrl_pin_desc sppctl_pins_all[];
+extern const unsigned int sppctl_pins_gpio[];
+
+extern const size_t sppctl_list_funcs_sz;
+extern const size_t sppctl_pmux_list_sz;
+extern const size_t sppctl_gpio_list_sz;
+extern const size_t sppctl_pins_all_sz;
+
+#endif
diff --git a/drivers/pinctrl/sunplus/sppctl_sp7021.c b/drivers/pinctrl/sunplus/sppctl_sp7021.c
new file mode 100644
index 0000000..457342e
--- /dev/null
+++ b/drivers/pinctrl/sunplus/sppctl_sp7021.c
@@ -0,0 +1,536 @@
+// SPDX-License-Identifier: GPL-2.0
+/* SP7021 Pin Controller Driver.
+ * Copyright (C) Sunplus Tech/Tibbo Tech.
+ */
+
+#include <linux/gpio/driver.h>
+
+#include "sppctl.h"
+
+#define D_PIS(x, y)	"P" __stringify(x) "_0" __stringify(y)
+#define D(x, y)		((x) * 8 + (y))
+#define P(x, y)		PINCTRL_PIN(D(x, y), D_PIS(x, y))
+
+const char * const sppctl_gpio_list_s[] = {
+	D_PIS(0, 0),  D_PIS(0, 1),  D_PIS(0, 2),  D_PIS(0, 3),
+	D_PIS(0, 4),  D_PIS(0, 5),  D_PIS(0, 6),  D_PIS(0, 7),
+	D_PIS(1, 0),  D_PIS(1, 1),  D_PIS(1, 2),  D_PIS(1, 3),
+	D_PIS(1, 4),  D_PIS(1, 5),  D_PIS(1, 6),  D_PIS(1, 7),
+	D_PIS(2, 0),  D_PIS(2, 1),  D_PIS(2, 2),  D_PIS(2, 3),
+	D_PIS(2, 4),  D_PIS(2, 5),  D_PIS(2, 6),  D_PIS(2, 7),
+	D_PIS(3, 0),  D_PIS(3, 1),  D_PIS(3, 2),  D_PIS(3, 3),
+	D_PIS(3, 4),  D_PIS(3, 5),  D_PIS(3, 6),  D_PIS(3, 7),
+	D_PIS(4, 0),  D_PIS(4, 1),  D_PIS(4, 2),  D_PIS(4, 3),
+	D_PIS(4, 4),  D_PIS(4, 5),  D_PIS(4, 6),  D_PIS(4, 7),
+	D_PIS(5, 0),  D_PIS(5, 1),  D_PIS(5, 2),  D_PIS(5, 3),
+	D_PIS(5, 4),  D_PIS(5, 5),  D_PIS(5, 6),  D_PIS(5, 7),
+	D_PIS(6, 0),  D_PIS(6, 1),  D_PIS(6, 2),  D_PIS(6, 3),
+	D_PIS(6, 4),  D_PIS(6, 5),  D_PIS(6, 6),  D_PIS(6, 7),
+	D_PIS(7, 0),  D_PIS(7, 1),  D_PIS(7, 2),  D_PIS(7, 3),
+	D_PIS(7, 4),  D_PIS(7, 5),  D_PIS(7, 6),  D_PIS(7, 7),
+	D_PIS(8, 0),  D_PIS(8, 1),  D_PIS(8, 2),  D_PIS(8, 3),
+	D_PIS(8, 4),  D_PIS(8, 5),  D_PIS(8, 6),  D_PIS(8, 7),
+	D_PIS(9, 0),  D_PIS(9, 1),  D_PIS(9, 2),  D_PIS(9, 3),
+	D_PIS(9, 4),  D_PIS(9, 5),  D_PIS(9, 6),  D_PIS(9, 7),
+	D_PIS(10, 0), D_PIS(10, 1), D_PIS(10, 2), D_PIS(10, 3),
+	D_PIS(10, 4), D_PIS(10, 5), D_PIS(10, 6), D_PIS(10, 7),
+	D_PIS(11, 0), D_PIS(11, 1), D_PIS(11, 2), D_PIS(11, 3),
+	D_PIS(11, 4), D_PIS(11, 5), D_PIS(11, 6), D_PIS(11, 7),
+	D_PIS(12, 0), D_PIS(12, 1), D_PIS(12, 2)
+};
+
+const size_t sppctl_gpio_list_sz = ARRAY_SIZE(sppctl_gpio_list_s);
+
+/* function: GPIO. list of groups (pins) */
+const unsigned int sppctl_pins_gpio[] = {
+	D(0, 0), D(0, 1), D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7),
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7),
+	D(2, 0), D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7),
+	D(3, 0), D(3, 1), D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7),
+	D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7),
+	D(6, 0), D(6, 1), D(6, 2), D(6, 3), D(6, 4), D(6, 5), D(6, 6), D(6, 7),
+	D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7),
+	D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6), D(8, 7),
+	D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5), D(9, 6), D(9, 7),
+	D(10, 0), D(10, 1), D(10, 2), D(10, 3), D(10, 4), D(10, 5), D(10, 6), D(10, 7),
+	D(11, 0), D(11, 1), D(11, 2), D(11, 3), D(11, 4), D(11, 5), D(11, 6), D(11, 7),
+	D(12, 0), D(12, 1), D(12, 2)
+};
+
+const struct pinctrl_pin_desc sppctl_pins_all[] = {
+	/* gpio and iop only */
+	P(0, 0), P(0, 1), P(0, 2), P(0, 3), P(0, 4), P(0, 5), P(0, 6), P(0, 7),
+	/* gpio, iop, muxable */
+	P(1, 0), P(1, 1), P(1, 2), P(1, 3), P(1, 4), P(1, 5), P(1, 6), P(1, 7),
+	P(2, 0), P(2, 1), P(2, 2), P(2, 3), P(2, 4), P(2, 5), P(2, 6), P(2, 7),
+	P(3, 0), P(3, 1), P(3, 2), P(3, 3), P(3, 4), P(3, 5), P(3, 6), P(3, 7),
+	P(4, 0), P(4, 1), P(4, 2), P(4, 3), P(4, 4), P(4, 5), P(4, 6), P(4, 7),
+	P(5, 0), P(5, 1), P(5, 2), P(5, 3), P(5, 4), P(5, 5), P(5, 6), P(5, 7),
+	P(6, 0), P(6, 1), P(6, 2), P(6, 3), P(6, 4), P(6, 5), P(6, 6), P(6, 7),
+	P(7, 0), P(7, 1), P(7, 2), P(7, 3), P(7, 4), P(7, 5), P(7, 6), P(7, 7),
+	P(8, 0), P(8, 1), P(8, 2), P(8, 3), P(8, 4), P(8, 5), P(8, 6), P(8, 7),
+	/* gpio (not wired) and iop only */
+	P(9, 0),  P(9, 1),  P(9, 2),  P(9, 3),  P(9, 4),  P(9, 5),  P(9, 6),  P(9, 7),
+	P(10, 0), P(10, 1), P(10, 2), P(10, 3), P(10, 4), P(10, 5), P(10, 6), P(10, 7),
+	P(11, 0), P(11, 1), P(11, 2), P(11, 3), P(11, 4), P(11, 5), P(11, 6), P(11, 7),
+	P(12, 0), P(12, 1), P(12, 2)
+};
+
+const size_t sppctl_pins_all_sz = ARRAY_SIZE(sppctl_pins_all);
+
+/* pmux groups: some pins are muxable. group = pin */
+const char * const sppctl_pmux_list_s[] = {
+	D_PIS(0, 0),
+	D_PIS(1, 0), D_PIS(1, 1), D_PIS(1, 2), D_PIS(1, 3),
+	D_PIS(1, 4), D_PIS(1, 5), D_PIS(1, 6), D_PIS(1, 7),
+	D_PIS(2, 0), D_PIS(2, 1), D_PIS(2, 2), D_PIS(2, 3),
+	D_PIS(2, 4), D_PIS(2, 5), D_PIS(2, 6), D_PIS(2, 7),
+	D_PIS(3, 0), D_PIS(3, 1), D_PIS(3, 2), D_PIS(3, 3),
+	D_PIS(3, 4), D_PIS(3, 5), D_PIS(3, 6), D_PIS(3, 7),
+	D_PIS(4, 0), D_PIS(4, 1), D_PIS(4, 2), D_PIS(4, 3),
+	D_PIS(4, 4), D_PIS(4, 5), D_PIS(4, 6), D_PIS(4, 7),
+	D_PIS(5, 0), D_PIS(5, 1), D_PIS(5, 2), D_PIS(5, 3),
+	D_PIS(5, 4), D_PIS(5, 5), D_PIS(5, 6), D_PIS(5, 7),
+	D_PIS(6, 0), D_PIS(6, 1), D_PIS(6, 2), D_PIS(6, 3),
+	D_PIS(6, 4), D_PIS(6, 5), D_PIS(6, 6), D_PIS(6, 7),
+	D_PIS(7, 0), D_PIS(7, 1), D_PIS(7, 2), D_PIS(7, 3),
+	D_PIS(7, 4), D_PIS(7, 5), D_PIS(7, 6), D_PIS(7, 7),
+	D_PIS(8, 0), D_PIS(8, 1), D_PIS(8, 2), D_PIS(8, 3),
+	D_PIS(8, 4), D_PIS(8, 5), D_PIS(8, 6), D_PIS(8, 7)
+};
+
+const size_t sppctl_pmux_list_sz = ARRAY_SIZE(sppctl_pmux_list_s);
+
+static const unsigned int pins_spif1[] = { D(10, 3), D(10, 4), D(10, 6), D(10, 7) };
+static const unsigned int pins_spif2[] = { D(9, 4), D(9, 6), D(9, 7), D(10, 1) };
+static const struct sppctl_grp sp7021grps_spif[] = {
+	EGRP("SPI_FLASH1", 1, pins_spif1),
+	EGRP("SPI_FLASH2", 2, pins_spif2)
+};
+
+static const unsigned int pins_spi41[] = { D(10, 2), D(10, 5) };
+static const unsigned int pins_spi42[] = { D(9, 5), D(9, 8) };
+static const struct sppctl_grp sp7021grps_spi4[] = {
+	EGRP("SPI_FLASH_4BIT1", 1, pins_spi41),
+	EGRP("SPI_FLASH_4BIT2", 2, pins_spi42)
+};
+
+static const unsigned int pins_snan[] = {
+	D(9, 4), D(9, 5), D(9, 6), D(9, 7), D(10, 0), D(10, 1)
+};
+
+static const struct sppctl_grp sp7021grps_snan[] = {
+	EGRP("SPI_NAND", 1, pins_snan)
+};
+
+static const unsigned int pins_emmc[] = {
+	D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5),
+	D(9, 6), D(9, 7), D(10, 0), D(10, 1) };
+
+static const struct sppctl_grp sp7021grps_emmc[] = {
+	EGRP("CARD0_EMMC", 1, pins_emmc)
+};
+
+static const unsigned int pins_sdsd[] = {
+	D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6)
+};
+
+static const struct sppctl_grp sp7021grps_sdsd[] = {
+	EGRP("SD_CARD", 1, pins_sdsd)
+};
+
+static const unsigned int pins_uar0[] = { D(11, 0), D(11, 1) };
+
+static const struct sppctl_grp sp7021grps_uar0[] = {
+	EGRP("UA0", 1, pins_uar0)
+};
+
+static const unsigned int pins_adbg1[] = { D(10, 2), D(10, 3) };
+static const unsigned int pins_adbg2[] = { D(7, 1), D(7, 2) };
+
+static const struct sppctl_grp sp7021grps_adbg[] = {
+	EGRP("ACHIP_DEBUG1", 1, pins_adbg1),
+	EGRP("ACHIP_DEBUG2", 2, pins_adbg2)
+};
+
+static const unsigned int pins_aua2axi1[] = { D(2, 0), D(2, 1), D(2, 2) };
+static const unsigned int pins_aua2axi2[] = { D(1, 0), D(1, 1), D(1, 2) };
+
+static const struct sppctl_grp sp7021grps_au2x[] = {
+	EGRP("ACHIP_UA2AXI1", 1, pins_aua2axi1),
+	EGRP("ACHIP_UA2AXI2", 2, pins_aua2axi2)
+};
+
+static const unsigned int pins_fpga[] = {
+	D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7),
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5),
+	D(1, 6), D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3),
+	D(2, 4), D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1),
+	D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5),
+	D(4, 6), D(4, 7), D(5, 0), D(5, 1), D(5, 2)
+};
+
+static const struct sppctl_grp sp7021grps_fpga[] = {
+	EGRP("FPGA_IFX", 1, pins_fpga)
+};
+
+static const unsigned int pins_hdmi1[] = { D(10, 6), D(12, 2), D(12, 1) };
+static const unsigned int pins_hdmi2[] = { D(8, 3), D(8, 5), D(8, 6) };
+static const unsigned int pins_hdmi3[] = { D(7, 4), D(7, 6), D(7, 7) };
+
+static const struct sppctl_grp sp7021grps_hdmi[] = {
+	EGRP("HDMI_TX1", 1, pins_hdmi1),
+	EGRP("HDMI_TX2", 2, pins_hdmi2),
+	EGRP("HDMI_TX3", 3, pins_hdmi3)
+};
+
+static const unsigned int pins_eadc[] = {
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6)
+};
+
+static const struct sppctl_grp sp7021grps_eadc[] = {
+	EGRP("AUD_EXT_ADC_IFX0", 1, pins_eadc)
+};
+
+static const unsigned int pins_edac[] = {
+	D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), D(3, 2), D(3, 4)
+};
+
+static const struct sppctl_grp sp7021grps_edac[] = {
+	EGRP("AUD_EXT_DAC_IFX0", 1, pins_edac)
+};
+
+static const unsigned int pins_spdi[] = { D(2, 4) };
+
+static const struct sppctl_grp sp7021grps_spdi[] = {
+	EGRP("AUD_IEC_RX0", 1, pins_spdi)
+};
+
+static const unsigned int pins_spdo[] = { D(3, 6) };
+
+static const struct sppctl_grp sp7021grps_spdo[] = {
+	EGRP("AUD_IEC_TX0", 1, pins_spdo)
+};
+
+static const unsigned int pins_tdmt[] = {
+	D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), D(3, 2)
+};
+
+static const struct sppctl_grp sp7021grps_tdmt[] = {
+	EGRP("TDMTX_IFX0", 1, pins_tdmt)
+};
+
+static const unsigned int pins_tdmr[] = { D(1, 7), D(2, 0), D(2, 1), D(2, 2) };
+
+static const struct sppctl_grp sp7021grps_tdmr[] = {
+	EGRP("TDMRX_IFX0", 1, pins_tdmr)
+};
+
+static const unsigned int pins_pdmr[] = {
+	D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3)
+};
+
+static const struct sppctl_grp sp7021grps_pdmr[] = {
+	EGRP("PDMRX_IFX0", 1, pins_pdmr)
+};
+
+static const unsigned int pins_pcmt[] = {
+	D(3, 7), D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4)
+};
+
+static const struct sppctl_grp sp7021grps_pcmt[] = {
+	EGRP("PCM_IEC_TX", 1, pins_pcmt)
+};
+
+static const unsigned int pins_lcdi[] = {
+	D(1, 4), D(1, 5),
+	D(1, 6), D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3),
+	D(2, 4), D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1),
+	D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5),
+	D(4, 6), D(4, 7)
+};
+
+static const struct sppctl_grp sp7021grps_lcdi[] = {
+	EGRP("LCDIF", 1, pins_lcdi)
+};
+
+static const unsigned int pins_dvdd[] = {
+	D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7),
+	D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5)
+};
+
+static const struct sppctl_grp sp7021grps_dvdd[] = {
+	EGRP("DVD_DSP_DEBUG", 1, pins_dvdd)
+};
+
+static const unsigned int pins_i2cd[] = { D(1, 0), D(1, 1) };
+
+static const struct sppctl_grp sp7021grps_i2cd[] = {
+	EGRP("I2C_DEBUG", 1, pins_i2cd)
+};
+
+static const unsigned int pins_i2cs[] = { D(0, 0), D(0, 1) };
+
+static const struct sppctl_grp sp7021grps_i2cs[] = {
+	EGRP("I2C_SLAVE", 1, pins_i2cs)
+};
+
+static const unsigned int pins_wakp[] = { D(10, 5) };
+
+static const struct sppctl_grp sp7021grps_wakp[] = {
+	EGRP("WAKEUP", 1, pins_wakp)
+};
+
+static const unsigned int pins_u2ax[] = { D(2, 0), D(2, 1), D(3, 0), D(3, 1) };
+
+static const struct sppctl_grp sp7021grps_u2ax[] = {
+	EGRP("UART2AXI", 1, pins_u2ax)
+};
+
+static const unsigned int pins_u0ic[] = {
+	D(0, 0), D(0, 1), D(0, 4), D(0, 5), D(1, 0), D(1, 1)
+};
+
+static const struct sppctl_grp sp7021grps_u0ic[] = {
+	EGRP("USB0_I2C", 1, pins_u0ic)
+};
+
+static const unsigned int pins_u1ic[] = {
+	D(0, 2), D(0, 3), D(0, 6), D(0, 7), D(1, 2), D(1, 3)
+};
+
+static const struct sppctl_grp sp7021grps_u1ic[] = {
+	EGRP("USB1_I2C", 1, pins_u1ic)
+};
+
+static const unsigned int pins_u0ot[] = { D(11, 2) };
+
+static const struct sppctl_grp sp7021grps_u0ot[] = {
+	EGRP("USB0_OTG", 1, pins_u0ot)
+};
+
+static const unsigned int pins_u1ot[] = { D(11, 3) };
+
+static const struct sppctl_grp sp7021grps_u1ot[] = {
+	EGRP("USB1_OTG", 1, pins_u1ot)
+};
+
+static const unsigned int pins_uphd[] = {
+	D(0, 1), D(0, 2), D(0, 3), D(7, 4), D(7, 5), D(7, 6),
+	D(7, 7), D(8, 0), D(8, 1), D(8, 2), D(8, 3),
+	D(9, 7), D(10, 2), D(10, 3), D(10, 4)
+};
+
+static const struct sppctl_grp sp7021grps_up0d[] = {
+	EGRP("UPHY0_DEBUG", 1, pins_uphd)
+};
+
+static const struct sppctl_grp sp7021grps_up1d[] = {
+	EGRP("UPHY1_DEBUG", 1, pins_uphd)
+};
+
+static const unsigned int pins_upex[] = {
+	D(0, 0), D(0, 1), D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7),
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7),
+	D(2, 0), D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7),
+	D(3, 0), D(3, 1), D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7),
+	D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7),
+	D(6, 0), D(6, 1), D(6, 2), D(6, 3), D(6, 4), D(6, 5), D(6, 6), D(6, 7),
+	D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7),
+	D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6), D(8, 7),
+	D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5), D(9, 6), D(9, 7),
+	D(10, 0), D(10, 1), D(10, 2), D(10, 3), D(10, 4), D(10, 5), D(10, 6), D(10, 7)
+};
+
+static const struct sppctl_grp sp7021grps_upex[] = {
+	EGRP("UPHY0_EXT", 1, pins_upex)
+};
+
+static const unsigned int pins_prp1[] = {
+	D(0, 6), D(0, 7),
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7),
+	D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7),
+	D(3, 0), D(3, 1), D(3, 2)
+};
+
+static const unsigned int pins_prp2[] = {
+	D(3, 4), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7),
+	D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7),
+	D(6, 4)
+};
+
+static const struct sppctl_grp sp7021grps_prbp[] = {
+	EGRP("PROBE_PORT1", 1, pins_prp1),
+	EGRP("PROBE_PORT2", 2, pins_prp2)
+};
+
+const struct sppctl_func sppctl_list_funcs[] = {
+	FNCN("GPIO",            f_off_0, 0x00, 0, 0),
+	FNCN("IOP",             f_off_0, 0x00, 0, 0),
+
+	FNCN("L2SW_CLK_OUT",        f_off_m, 0x00, 0, 7),
+	FNCN("L2SW_MAC_SMI_MDC",    f_off_m, 0x00, 8, 7),
+	FNCN("L2SW_LED_FLASH0",     f_off_m, 0x01, 0, 7),
+	FNCN("L2SW_LED_FLASH1",     f_off_m, 0x01, 8, 7),
+	FNCN("L2SW_LED_ON0",        f_off_m, 0x02, 0, 7),
+	FNCN("L2SW_LED_ON1",        f_off_m, 0x02, 8, 7),
+	FNCN("L2SW_MAC_SMI_MDIO",   f_off_m, 0x03, 0, 7),
+	FNCN("L2SW_P0_MAC_RMII_TXEN",   f_off_m, 0x03, 8, 7),
+	FNCN("L2SW_P0_MAC_RMII_TXD0",   f_off_m, 0x04, 0, 7),
+	FNCN("L2SW_P0_MAC_RMII_TXD1",   f_off_m, 0x04, 8, 7),
+	FNCN("L2SW_P0_MAC_RMII_CRSDV",  f_off_m, 0x05, 0, 7),
+	FNCN("L2SW_P0_MAC_RMII_RXD0",   f_off_m, 0x05, 8, 7),
+	FNCN("L2SW_P0_MAC_RMII_RXD1",   f_off_m, 0x06, 0, 7),
+	FNCN("L2SW_P0_MAC_RMII_RXER",   f_off_m, 0x06, 8, 7),
+	FNCN("L2SW_P1_MAC_RMII_TXEN",   f_off_m, 0x07, 0, 7),
+	FNCN("L2SW_P1_MAC_RMII_TXD0",   f_off_m, 0x07, 8, 7),
+	FNCN("L2SW_P1_MAC_RMII_TXD1",   f_off_m, 0x08, 0, 7),
+	FNCN("L2SW_P1_MAC_RMII_CRSDV",  f_off_m, 0x08, 8, 7),
+	FNCN("L2SW_P1_MAC_RMII_RXD0",   f_off_m, 0x09, 0, 7),
+	FNCN("L2SW_P1_MAC_RMII_RXD1",   f_off_m, 0x09, 8, 7),
+	FNCN("L2SW_P1_MAC_RMII_RXER",   f_off_m, 0x0A, 0, 7),
+	FNCN("DAISY_MODE",      f_off_m, 0x0A, 8, 7),
+	FNCN("SDIO_CLK",        f_off_m, 0x0B, 0, 7),
+	FNCN("SDIO_CMD",        f_off_m, 0x0B, 8, 7),
+	FNCN("SDIO_D0",         f_off_m, 0x0C, 0, 7),
+	FNCN("SDIO_D1",         f_off_m, 0x0C, 8, 7),
+	FNCN("SDIO_D2",         f_off_m, 0x0D, 0, 7),
+	FNCN("SDIO_D3",         f_off_m, 0x0D, 8, 7),
+	FNCN("PWM0",            f_off_m, 0x0E, 0, 7),
+	FNCN("PWM1",            f_off_m, 0x0E, 8, 7),
+	FNCN("PWM2",            f_off_m, 0x0F, 0, 7),
+	FNCN("PWM3",            f_off_m, 0x0F, 8, 7),
+
+	FNCN("PWM4",            f_off_m, 0x10, 0, 7),
+	FNCN("PWM5",            f_off_m, 0x10, 8, 7),
+	FNCN("PWM6",            f_off_m, 0x11, 0, 7),
+	FNCN("PWM7",            f_off_m, 0x11, 8, 7),
+	FNCN("ICM0_D",          f_off_m, 0x12, 0, 7),    /* 4x Input captures */
+	FNCN("ICM1_D",          f_off_m, 0x12, 8, 7),
+	FNCN("ICM2_D",          f_off_m, 0x13, 0, 7),
+	FNCN("ICM3_D",          f_off_m, 0x13, 8, 7),
+	FNCN("ICM0_CLK",        f_off_m, 0x14, 0, 7),
+	FNCN("ICM1_CLK",        f_off_m, 0x14, 8, 7),
+	FNCN("ICM2_CLK",        f_off_m, 0x15, 0, 7),
+	FNCN("ICM3_CLK",        f_off_m, 0x15, 8, 7),
+	FNCN("SPIM0_INT",       f_off_m, 0x16, 0, 7),    /* 4x SPI masters */
+	FNCN("SPIM0_CLK",       f_off_m, 0x16, 8, 7),
+	FNCN("SPIM0_EN",        f_off_m, 0x17, 0, 7),
+	FNCN("SPIM0_DO",        f_off_m, 0x17, 8, 7),
+	FNCN("SPIM0_DI",        f_off_m, 0x18, 0, 7),
+	FNCN("SPIM1_INT",       f_off_m, 0x18, 8, 7),
+	FNCN("SPIM1_CLK",       f_off_m, 0x19, 0, 7),
+	FNCN("SPIM1_EN",        f_off_m, 0x19, 8, 7),
+	FNCN("SPIM1_DO",        f_off_m, 0x1A, 0, 7),
+	FNCN("SPIM1_DI",        f_off_m, 0x1A, 8, 7),
+	FNCN("SPIM2_INT",       f_off_m, 0x1B, 0, 7),
+	FNCN("SPIM2_CLK",       f_off_m, 0x1B, 8, 7),
+	FNCN("SPIM2_EN",        f_off_m, 0x1C, 0, 7),
+	FNCN("SPIM2_DO",        f_off_m, 0x1C, 8, 7),
+	FNCN("SPIM2_DI",        f_off_m, 0x1D, 0, 7),
+	FNCN("SPIM3_INT",       f_off_m, 0x1D, 8, 7),
+	FNCN("SPIM3_CLK",       f_off_m, 0x1E, 0, 7),
+	FNCN("SPIM3_EN",        f_off_m, 0x1E, 8, 7),
+	FNCN("SPIM3_DO",        f_off_m, 0x1F, 0, 7),
+	FNCN("SPIM3_DI",        f_off_m, 0x1F, 8, 7),
+
+	FNCN("SPI0S_INT",       f_off_m, 0x20, 0, 7),    /* 4x SPI slaves */
+	FNCN("SPI0S_CLK",       f_off_m, 0x20, 8, 7),
+	FNCN("SPI0S_EN",        f_off_m, 0x21, 0, 7),
+	FNCN("SPI0S_DO",        f_off_m, 0x21, 8, 7),
+	FNCN("SPI0S_DI",        f_off_m, 0x22, 0, 7),
+	FNCN("SPI1S_INT",       f_off_m, 0x22, 8, 7),
+	FNCN("SPI1S_CLK",       f_off_m, 0x23, 0, 7),
+	FNCN("SPI1S_EN",        f_off_m, 0x23, 8, 7),
+	FNCN("SPI1S_DO",        f_off_m, 0x24, 0, 7),
+	FNCN("SPI1S_DI",        f_off_m, 0x24, 8, 7),
+	FNCN("SPI2S_INT",       f_off_m, 0x25, 0, 7),
+	FNCN("SPI2S_CLK",       f_off_m, 0x25, 8, 7),
+	FNCN("SPI2S_EN",        f_off_m, 0x26, 0, 7),
+	FNCN("SPI2S_DO",        f_off_m, 0x26, 8, 7),
+	FNCN("SPI2S_DI",        f_off_m, 0x27, 0, 7),
+	FNCN("SPI3S_INT",       f_off_m, 0x27, 8, 7),
+	FNCN("SPI3S_CLK",       f_off_m, 0x28, 0, 7),
+	FNCN("SPI3S_EN",        f_off_m, 0x28, 8, 7),
+	FNCN("SPI3S_DO",        f_off_m, 0x29, 0, 7),
+	FNCN("SPI3S_DI",        f_off_m, 0x29, 8, 7),
+	FNCN("I2CM0_CLK",       f_off_m, 0x2A, 0, 7),    /* 4x I2C masters */
+	FNCN("I2CM0_DAT",       f_off_m, 0x2A, 8, 7),
+	FNCN("I2CM1_CLK",       f_off_m, 0x2B, 0, 7),
+	FNCN("I2CM1_DAT",       f_off_m, 0x2B, 8, 7),
+	FNCN("I2CM2_CLK",       f_off_m, 0x2C, 0, 7),
+	FNCN("I2CM2_DAT",       f_off_m, 0x2C, 8, 7),
+	FNCN("I2CM3_CLK",       f_off_m, 0x2D, 0, 7),
+	FNCN("I2CM3_DAT",       f_off_m, 0x2D, 8, 7),
+	FNCN("UA1_TX",          f_off_m, 0x2E, 0, 7),    /* 4x UARTS */
+	FNCN("UA1_RX",          f_off_m, 0x2E, 8, 7),
+	FNCN("UA1_CTS",         f_off_m, 0x2F, 0, 7),
+	FNCN("UA1_RTS",         f_off_m, 0x2F, 8, 7),
+
+	FNCN("UA2_TX",          f_off_m, 0x30, 0, 7),
+	FNCN("UA2_RX",          f_off_m, 0x30, 8, 7),
+	FNCN("UA2_CTS",         f_off_m, 0x31, 0, 7),
+	FNCN("UA2_RTS",         f_off_m, 0x31, 8, 7),
+	FNCN("UA3_TX",          f_off_m, 0x32, 0, 7),
+	FNCN("UA3_RX",          f_off_m, 0x32, 8, 7),
+	FNCN("UA3_CTS",         f_off_m, 0x33, 0, 7),
+	FNCN("UA3_RTS",         f_off_m, 0x33, 8, 7),
+	FNCN("UA4_TX",          f_off_m, 0x34, 0, 7),
+	FNCN("UA4_RX",          f_off_m, 0x34, 8, 7),
+	FNCN("UA4_CTS",         f_off_m, 0x35, 0, 7),
+	FNCN("UA4_RTS",         f_off_m, 0x35, 8, 7),
+	FNCN("TIMER0_INT",      f_off_m, 0x36, 0, 7),    /* 4x timer int. */
+	FNCN("TIMER1_INT",      f_off_m, 0x36, 8, 7),
+	FNCN("TIMER2_INT",      f_off_m, 0x37, 0, 7),
+	FNCN("TIMER3_INT",      f_off_m, 0x37, 8, 7),
+	FNCN("GPIO_INT0",       f_off_m, 0x38, 0, 7),    /* 8x GPIO int. */
+	FNCN("GPIO_INT1",       f_off_m, 0x38, 8, 7),
+	FNCN("GPIO_INT2",       f_off_m, 0x39, 0, 7),
+	FNCN("GPIO_INT3",       f_off_m, 0x39, 8, 7),
+	FNCN("GPIO_INT4",       f_off_m, 0x3A, 0, 7),
+	FNCN("GPIO_INT5",       f_off_m, 0x3A, 8, 7),
+	FNCN("GPIO_INT6",       f_off_m, 0x3B, 0, 7),
+	FNCN("GPIO_INT7",       f_off_m, 0x3B, 8, 7),
+
+	/* MOON1 register */
+	FNCE("SPI_FLASH",       f_off_g, 0x01,  0, 2, sp7021grps_spif),
+	FNCE("SPI_FLASH_4BIT",  f_off_g, 0x01,  2, 2, sp7021grps_spi4),
+	FNCE("SPI_NAND",        f_off_g, 0x01,  4, 1, sp7021grps_snan),
+	FNCE("CARD0_EMMC",      f_off_g, 0x01,  5, 1, sp7021grps_emmc),
+	FNCE("SD_CARD",         f_off_g, 0x01,  6, 1, sp7021grps_sdsd),
+	FNCE("UA0",             f_off_g, 0x01,  7, 1, sp7021grps_uar0),
+	FNCE("ACHIP_DEBUG",     f_off_g, 0x01,  8, 2, sp7021grps_adbg),
+	FNCE("ACHIP_UA2AXI",    f_off_g, 0x01, 10, 2, sp7021grps_au2x),
+	FNCE("FPGA_IFX",        f_off_g, 0x01, 12, 1, sp7021grps_fpga),
+	FNCE("HDMI_TX",         f_off_g, 0x01, 13, 2, sp7021grps_hdmi),
+
+	FNCE("AUD_EXT_ADC_IFX0", f_off_g, 0x01, 15, 1, sp7021grps_eadc),
+	FNCE("AUD_EXT_DAC_IFX0", f_off_g, 0x02,  0, 1, sp7021grps_edac),
+	FNCE("SPDIF_RX",        f_off_g, 0x02,  2, 1, sp7021grps_spdi),
+	FNCE("SPDIF_TX",        f_off_g, 0x02,  3, 1, sp7021grps_spdo),
+	FNCE("TDMTX_IFX0",      f_off_g, 0x02,  4, 1, sp7021grps_tdmt),
+	FNCE("TDMRX_IFX0",      f_off_g, 0x02,  5, 1, sp7021grps_tdmr),
+	FNCE("PDMRX_IFX0",      f_off_g, 0x02,  6, 1, sp7021grps_pdmr),
+	FNCE("PCM_IEC_TX",      f_off_g, 0x02,  7, 1, sp7021grps_pcmt),
+	FNCE("LCDIF",           f_off_g, 0x04,  6, 1, sp7021grps_lcdi),
+	FNCE("DVD_DSP_DEBUG",   f_off_g, 0x02,  8, 1, sp7021grps_dvdd),
+	FNCE("I2C_DEBUG",       f_off_g, 0x02,  9, 1, sp7021grps_i2cd),
+	FNCE("I2C_SLAVE",       f_off_g, 0x02, 10, 1, sp7021grps_i2cs),
+	FNCE("WAKEUP",          f_off_g, 0x02, 11, 1, sp7021grps_wakp),
+	FNCE("UART2AXI",        f_off_g, 0x02, 12, 2, sp7021grps_u2ax),
+	FNCE("USB0_I2C",        f_off_g, 0x02, 14, 2, sp7021grps_u0ic),
+	FNCE("USB1_I2C",        f_off_g, 0x03,  0, 2, sp7021grps_u1ic),
+	FNCE("USB0_OTG",        f_off_g, 0x03,  2, 1, sp7021grps_u0ot),
+	FNCE("USB1_OTG",        f_off_g, 0x03,  3, 1, sp7021grps_u1ot),
+	FNCE("UPHY0_DEBUG",     f_off_g, 0x03,  4, 1, sp7021grps_up0d),
+	FNCE("UPHY1_DEBUG",     f_off_g, 0x03,  5, 1, sp7021grps_up1d),
+	FNCE("UPHY0_EXT",       f_off_g, 0x03,  6, 1, sp7021grps_upex),
+	FNCE("PROBE_PORT",      f_off_g, 0x03,  7, 2, sp7021grps_prbp),
+};
+
+const size_t sppctl_list_funcs_sz = ARRAY_SIZE(sppctl_list_funcs);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 1/2] dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021
  2021-12-14 10:53 ` [PATCH v4 1/2] dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021 Wells Lu
@ 2021-12-14 15:21   ` Rob Herring
  2021-12-15 11:10     ` Wells Lu 呂芳騰
  0 siblings, 1 reply; 10+ messages in thread
From: Rob Herring @ 2021-12-14 15:21 UTC (permalink / raw)
  To: Wells Lu
  Cc: devicetree, linux-gpio, robh+dt, dvorkin, linus.walleij,
	linux-kernel, linux-arm-kernel, wells.lu

On Tue, 14 Dec 2021 18:53:08 +0800, Wells Lu wrote:
> Add dt-bindings header files and documentation for Sunplus SP7021 SoC.
> 
> Signed-off-by: Wells Lu <wellslutw@gmail.com>
> ---
> Changes in V4
>   - Addressed comments of Mr. Linus Walleij.
>     - Remove 'if type object then' stuff for patternProperties '-pins$'.
>     - Added more descriptions about pins control of SP7021.
>     - Modified name property 'pins' to 'sunplus,pins' (vendor specific).
>     - Modified name property 'zero_func' to 'sunplus,zero_func' (vendor specific).
> 
>  .../bindings/pinctrl/sunplus,sp7021-pinctrl.yaml   | 375 +++++++++++++++++++++
>  MAINTAINERS                                        |   9 +
>  include/dt-bindings/pinctrl/sppctl-sp7021.h        | 173 ++++++++++
>  include/dt-bindings/pinctrl/sppctl.h               |  40 +++
>  4 files changed, 597 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
>  create mode 100644 include/dt-bindings/pinctrl/sppctl-sp7021.h
>  create mode 100644 include/dt-bindings/pinctrl/sppctl.h
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.example.dt.yaml: uart1-pins: 'sunplus,pins' does not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^al,.*', '^alcatel,.*', '^allegro,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', '^anvo,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asus,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*', '^buffalo,.*', '^bur,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^edimax,.*', '^edt,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^gardena,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goodix,.*', '^google,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haoyu,.*', '^hardkernel,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hsg,.*', '^hugsun,.*', '^hwacom,.*', '^hycon,.*', '^hydis,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^img,.*', '^imi,.*', '^incircuit,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inversepath,.*', '^iom,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jdi,.*', '^jedec,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongson,.*', '^lsi,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^miniand,.*', '^minix,.*', '^miramems,.*', '^mitsubishi,.*', '^mntre,.*', '^modtronix,.*', '^mosaixtech,.*', '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^opencores,.*', '^openembed,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*', '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*', '^roseapplepi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shimafuji,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartlabs,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^sony,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*', '^starry,.*', '^startek,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^summit,.*', '^sunchip,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^teltonika,.*', '^tempo,.*', '^terasic,.*', '^tfc,.*', '^thine,.*', '^thingyjp,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^tyan,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ugoos,.*', '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^via,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^wiligear,.*', '^winbond,.*', '^winstar,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^x-powers,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/vendor-prefixes.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.example.dt.yaml: uart2-pins: 'sunplus,pins' does not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^al,.*', '^alcatel,.*', '^allegro,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', '^anvo,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asus,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*', '^buffalo,.*', '^bur,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^edimax,.*', '^edt,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^gardena,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goodix,.*', '^google,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haoyu,.*', '^hardkernel,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hsg,.*', '^hugsun,.*', '^hwacom,.*', '^hycon,.*', '^hydis,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^img,.*', '^imi,.*', '^incircuit,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inversepath,.*', '^iom,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jdi,.*', '^jedec,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongson,.*', '^lsi,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^miniand,.*', '^minix,.*', '^miramems,.*', '^mitsubishi,.*', '^mntre,.*', '^modtronix,.*', '^mosaixtech,.*', '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^opencores,.*', '^openembed,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*', '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*', '^roseapplepi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shimafuji,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartlabs,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^sony,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*', '^starry,.*', '^startek,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^summit,.*', '^sunchip,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^teltonika,.*', '^tempo,.*', '^terasic,.*', '^tfc,.*', '^thine,.*', '^thingyjp,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^tyan,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ugoos,.*', '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^via,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^wiligear,.*', '^winbond,.*', '^winstar,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^x-powers,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/vendor-prefixes.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.example.dt.yaml: sdcard-pins: 'sunplus,pins' does not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^al,.*', '^alcatel,.*', '^allegro,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', '^anvo,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asus,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*', '^buffalo,.*', '^bur,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^edimax,.*', '^edt,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^gardena,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goodix,.*', '^google,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haoyu,.*', '^hardkernel,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hsg,.*', '^hugsun,.*', '^hwacom,.*', '^hycon,.*', '^hydis,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^img,.*', '^imi,.*', '^incircuit,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inversepath,.*', '^iom,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jdi,.*', '^jedec,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongson,.*', '^lsi,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^miniand,.*', '^minix,.*', '^miramems,.*', '^mitsubishi,.*', '^mntre,.*', '^modtronix,.*', '^mosaixtech,.*', '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^opencores,.*', '^openembed,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*', '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*', '^roseapplepi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shimafuji,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartlabs,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^sony,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*', '^starry,.*', '^startek,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^summit,.*', '^sunchip,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^teltonika,.*', '^tempo,.*', '^terasic,.*', '^tfc,.*', '^thine,.*', '^thingyjp,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^tyan,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ugoos,.*', '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^via,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^wiligear,.*', '^winbond,.*', '^winstar,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^x-powers,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/vendor-prefixes.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.example.dt.yaml: ethernet-pins: 'sunplus,pins', 'sunplus,zero_func' do not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^al,.*', '^alcatel,.*', '^allegro,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', '^anvo,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asus,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*', '^buffalo,.*', '^bur,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^edimax,.*', '^edt,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^gardena,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goodix,.*', '^google,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haoyu,.*', '^hardkernel,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hsg,.*', '^hugsun,.*', '^hwacom,.*', '^hycon,.*', '^hydis,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^img,.*', '^imi,.*', '^incircuit,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inversepath,.*', '^iom,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jdi,.*', '^jedec,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongson,.*', '^lsi,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^miniand,.*', '^minix,.*', '^miramems,.*', '^mitsubishi,.*', '^mntre,.*', '^modtronix,.*', '^mosaixtech,.*', '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^opencores,.*', '^openembed,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*', '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*', '^roseapplepi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shimafuji,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartlabs,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^sony,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*', '^starry,.*', '^startek,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^summit,.*', '^sunchip,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^teltonika,.*', '^tempo,.*', '^terasic,.*', '^tfc,.*', '^thine,.*', '^thingyjp,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^tyan,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ugoos,.*', '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^via,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^wiligear,.*', '^winbond,.*', '^winstar,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^x-powers,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/vendor-prefixes.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1567651

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 2/2] pinctrl: Add driver for Sunplus SP7021
  2021-12-14 10:53 ` [PATCH v4 2/2] pinctrl: Add driver " Wells Lu
@ 2021-12-14 23:14   ` Andy Shevchenko
  2021-12-15  9:40     ` Wells Lu 呂芳騰
  0 siblings, 1 reply; 10+ messages in thread
From: Andy Shevchenko @ 2021-12-14 23:14 UTC (permalink / raw)
  To: Wells Lu
  Cc: Linus Walleij, open list:GPIO SUBSYSTEM,
	Linux Kernel Mailing List, Rob Herring, devicetree,
	linux-arm Mailing List, Wells Lu 呂芳騰,
	dvorkin

On Tue, Dec 14, 2021 at 5:08 PM Wells Lu <wellslutw@gmail.com> wrote:
>
> Add driver for Sunplus SP7021 SoC.

It needs much more work, my comments below.

...

> +/* SP7021 Pin Controller Driver.
> + * Copyright (C) Sunplus Tech/Tibbo Tech.
> + */

This is wrong style for multi-line comments. Fix it everywhere accordingly.

...

> +#include <linux/platform_device.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/module.h>
> +#include <linux/bitfield.h>

Keep them in order. Besides that it seems missed a few headers, such as of.h.

> +
> +#include <dt-bindings/pinctrl/sppctl-sp7021.h>

+ blank line

> +#include "../pinctrl-utils.h"
> +#include "../core.h"

+ blank line

> +#include "sppctl.h"

...

> +       mask = GENMASK(bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT + bit_sz - 1,
> +                      bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT);

GENMASK() with non-const arguments may be not a good choice and see, even

       mask = GENMASK(bit_sz - 1, 0) << (bit_off +
SPPCTL_GROUP_PINMUX_MASK_SHIFT);

is way much better.

...

> +       val = (reg & BIT(bit_off)) ? 1 : 0;

!!(...) may also work, but it's rather style preference.

...

> +       reg = readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + reg_off);

I noticed a potentially big issue with this driver. Are you sure it's
brave enough to do I/O without any synchronisation? Did I miss a lock?

...

> +       reg = readl(spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD + reg_off);

You may create an I/O wrappers to achieve a much better to read code
(no repetition of this arithmetics, etc).

...

> +       for (i = 0; i < chip->ngpio; i++) {
> +               label = gpiochip_is_requested(chip, i);
> +               if (!label)
> +                       label = "";

Perhaps to show only requested ones? In such case you may use
for_each_requested_gpio() macro.

> +               seq_printf(s, " gpio-%03d (%-16.16s | %-16.16s)", i + chip->base,
> +                          chip->names[i], label);
> +               seq_printf(s, " %c", sppctl_gpio_get_direction(chip, i) == 0 ? 'O' : 'I');
> +               seq_printf(s, ":%d", sppctl_gpio_get(chip, i));
> +               seq_printf(s, " %s", (sppctl_first_get(chip, i) ? "gpi" : "mux"));
> +               seq_printf(s, " %s", (sppctl_master_get(chip, i) ? "gpi" : "iop"));
> +               seq_printf(s, " %s", (sppctl_gpio_inv_get(chip, i) ? "inv" : "   "));
> +               seq_printf(s, " %s", (sppctl_gpio_output_od_get(chip, i) ? "oDr" : ""));

Too many parentheses in a few of above lines.

> +               seq_puts(s, "\n");
> +       }

...

> +               dev_err_probe(&pdev->dev, -EINVAL, "Not a gpio-controller!\n");
> +               return -EINVAL;

Unite them in one return statement.
Ditto for zillion similar cases in this driver.

...

> +       gchip->parent =            &pdev->dev;

> +       gchip->of_node =           pdev->dev.of_node;

Drop this dup. GPIO library already does it for you.

...

> +       int i = 0;

What for this assingment?

> +       dev_dbg(pctldev->dev, "%s(%d, %ld, %d)\n", __func__, pin, *configs, num_configs);

Noise. Better to consider to add necessary tracepoints to pin control core.

> +       /* Special handling for IOP */
> +       if (configs[i] == 0xFF) {

Why out of a sudden capitilazed hex value?

> +               sppctl_first_master_set(&pctl->spp_gchip->chip, pin, mux_f_gpio, mux_m_iop);
> +               return 0;
> +       }

...

> +       dev_dbg(pctldev->dev, "%s(%d)\n", __func__, offset);

Noise. And so on, so on...

...

> +       dev_dbg(pctldev->dev, "%s(%d), f_idx: %d, g_idx: %d, freg: %d\n",
> +               __func__, selector, g2fpm.f_idx, g2fpm.g_idx, f->freg);

No need to use __func__, and especially in case of _dbg / _debug. It
can be enabled at run-time with help of Dynamic Debug.

...

> +       seq_printf(s, "%s", dev_name(pctldev->dev));

Isn't it printed by core?

...

> +static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config,
> +                                struct pinctrl_map **map, unsigned int *num_maps)
> +{

Looking into this rather quite big function why you can't use what pin
control core provides?

> +}

...

> +       /* Fill up unique group names array. */
> +       sppctl->unq_grps = devm_kzalloc(&pdev->dev, (sppctl->unq_grps_sz + 1) *
> +                                       sizeof(char *), GFP_KERNEL);

You need to use devm_kcalloc() variant for arrays.

> +       if (!sppctl->unq_grps)
> +               return -ENOMEM;

> +       sppctl->g2fp_maps = devm_kzalloc(&pdev->dev, (sppctl->unq_grps_sz + 1) *
> +                                        sizeof(struct grp2fp_map), GFP_KERNEL);

Ditto, besides the fact of better use of sizeof() of the type of
variable, done by sizeof(*..._maps).

> +       if (!sppctl->g2fp_maps)
> +               return -ENOMEM;
> +
> +       sppctl->groups_name = devm_kzalloc(&pdev->dev, sppctl_list_funcs_sz *
> +                                          SPPCTL_MAX_GROUPS * sizeof(char *), GFP_KERNEL);

Ditto. And check some interesting macros in overflow.h.

> +       if (!sppctl->groups_name)
> +               return -ENOMEM;

...

> +       /* gpio */

GPIO, but either way seems not so valueable comment.

...

> +       err = devm_pinctrl_register_and_init(&pdev->dev, &sppctl->pctl_desc,
> +                                            sppctl, &sppctl->pctl_dev);
> +       if (err) {

> +               dev_err_probe(&pdev->dev, err, "Failed to register pinctrl!\n");
> +               of_node_put(np);

Swap them and use the form of
return dev_err_probe();

> +               return err;
> +       }

...

> +       /* MOON2 registers */
> +       rp = platform_get_resource_byname(pdev, IORESOURCE_MEM, "moon2");
> +       sppctl->moon2_base = devm_ioremap_resource(&pdev->dev, rp);

We have an API that provides two in one.

> +       if (IS_ERR(sppctl->moon2_base)) {
> +               ret = PTR_ERR(sppctl->moon2_base);

> +               goto ioremap_failed;

What is this for? Use return dev_err_probe() directly.

> +       }

> +       dev_dbg(&pdev->dev, "MOON2:   %pr\n", rp);

This cryptic noise has to be removed.

Above comments are applicable to all similar cases.

...

> +ioremap_failed:
> +       dev_err_probe(&pdev->dev, ret, "ioremap failed!\n");

This doesn't bring any value, besides the fact that API you have used
already prints a message.

...

> +       pdev->dev.platform_data = sppctl;

Don't we have special setter for this field?

...

> +       dev_info(&pdev->dev, "SP7021 PinCtrl by Sunplus/Tibbo Tech. (c)");

No value.

...

> +       { /* zero */ }

Comment with no value.

> +};

...

> +               .owner          = THIS_MODULE,

It's probably 5+ years that we don't need this (it's applied implicitly).

...

> +#ifndef __SPPCTL_H__
> +#define __SPPCTL_H__

This header misses the inclusions such as bits.h.
And I belive more than that.

...

> +/* FIRST register:
> + *   0: MUX
> + *   1: GPIO/IOP
> + *   2: No change
> + */

For all comments starting from here and for similar cases elsewhere:
 - why it is not in kernel doc?
 - what the value that add?
(Some of them so cryptic or so obvious)

...

> +static const struct sppctl_grp sp7021grps_spif[] = {
> +       EGRP("SPI_FLASH1", 1, pins_spif1),
> +       EGRP("SPI_FLASH2", 2, pins_spif2)

Here and everywhere else, leave a comma if it's not a terminator entry.

> +};

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH v4 2/2] pinctrl: Add driver for Sunplus SP7021
  2021-12-14 23:14   ` Andy Shevchenko
@ 2021-12-15  9:40     ` Wells Lu 呂芳騰
  2021-12-15 12:03       ` Andy Shevchenko
  0 siblings, 1 reply; 10+ messages in thread
From: Wells Lu 呂芳騰 @ 2021-12-15  9:40 UTC (permalink / raw)
  To: Andy Shevchenko, Wells Lu
  Cc: Linus Walleij, open list:GPIO SUBSYSTEM,
	Linux Kernel Mailing List, Rob Herring, devicetree,
	linux-arm Mailing List, dvorkin

Hi Andy,

Thank you very much for your review!

Please see my replies and questions below.


> >
> > Add driver for Sunplus SP7021 SoC.
> 
> It needs much more work, my comments below.
> 
> ...
> 
> > +/* SP7021 Pin Controller Driver.
> > + * Copyright (C) Sunplus Tech/Tibbo Tech.
> > + */
> 
> This is wrong style for multi-line comments. Fix it everywhere accordingly.

I'll modify all multi-line comments, for example, as shown below:

/*
 * SP7021 Pin Controller Driver.
 * Copyright (C) Sunplus Tech/Tibbo Tech.
 */

Now, I realized that each subsystem has its own comment style.


> ...
> 
> > +#include <linux/platform_device.h>
> > +#include <linux/pinctrl/pinmux.h>
> > +#include <linux/gpio/driver.h>
> > +#include <linux/module.h>
> > +#include <linux/bitfield.h>
> 
> Keep them in order. Besides that it seems missed a few headers, such as of.h.

I am not sure what order should I keep for inclusions.
Reversed x'mas tree order? Alphabetic order?

Some reviewers ask to remove unnecessary header files.
So I removed all unnecessary header files if compilation 
completes without any errors or warnings.

I suppose <linux/of.h> has included by other inclusion.
Need I add <linux/of.h> or other inclusions back?


> > +
> > +#include <dt-bindings/pinctrl/sppctl-sp7021.h>
> 
> + blank line
> 
> > +#include "../pinctrl-utils.h"
> > +#include "../core.h"
> 
> + blank line
> 
> > +#include "sppctl.h"

I'll add the blank lines.


> ...
> 
> > +       mask = GENMASK(bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT + bit_sz - 1,
> > +                      bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT);
> 
> GENMASK() with non-const arguments may be not a good choice and see, even
> 
>        mask = GENMASK(bit_sz - 1, 0) << (bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT);
> 
> is way much better.

I'll modify it as your suggestion:

mask = GENMASK(bit_sz - 1, 0) << (bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT);


> ...
> 
> > +       val = (reg & BIT(bit_off)) ? 1 : 0;
> 
> !!(...) may also work, but it's rather style preference.

The return value is integer 0 or 1, not Boolean.


> ...
> 
> > +       reg = readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER +
> > + reg_off);
> 
> I noticed a potentially big issue with this driver. Are you sure it's brave enough to do
> I/O without any synchronisation? Did I miss a lock?

Do I need to add spin_lock() for all gpio operation functions?
Please teach me what operation functions I need to add lock or 
all operation functions need lock?


> ...
> 
> > +       reg = readl(spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD +
> > + reg_off);
> 
> You may create an I/O wrappers to achieve a much better to read code (no repetition of
> this arithmetics, etc).

I think this is the simplest in-line form:

"spp_gchip->gpioxt2_base" is base address.
SPPCTL_GPIO_OFF_OD is register offset to base of OD (open-drain) registers.
reg_off is register offset to an OD register (SP7021 has 7 OD registers totally).

Need I add macros (wrappers) for accessing registers?

For example,

#define SPPCTL_GPIO_OD(off)	(spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD + off)

reg = readl(SPPCTL_GPIO_OD(reg_off));

or 

writel(reg, SPPCTL_GPIO_OD(reg_off));


Mr. Linus Walleij told me that he likes in-line (direct) form, instead of macro
because in-line form has better readability (No need to jump to other file for
reading macros).

Could you please share me with your idea?


> ...
> 
> > +       for (i = 0; i < chip->ngpio; i++) {
> > +               label = gpiochip_is_requested(chip, i);
> > +               if (!label)
> > +                       label = "";
> 
> Perhaps to show only requested ones? In such case you may use
> for_each_requested_gpio() macro.

I'd like to keep showing status of all GPIOs.
This helps us know status of all GPIOs when debugging hardware issue.


> > +               seq_printf(s, " gpio-%03d (%-16.16s | %-16.16s)", i + chip->base,
> > +                          chip->names[i], label);
> > +               seq_printf(s, " %c", sppctl_gpio_get_direction(chip, i) == 0 ? 'O' : 'I');
> > +               seq_printf(s, ":%d", sppctl_gpio_get(chip, i));
> > +               seq_printf(s, " %s", (sppctl_first_get(chip, i) ? "gpi" : "mux"));
> > +               seq_printf(s, " %s", (sppctl_master_get(chip, i) ? "gpi" : "iop"));
> > +               seq_printf(s, " %s", (sppctl_gpio_inv_get(chip, i) ? "inv" : "   "));
> > +               seq_printf(s, " %s", (sppctl_gpio_output_od_get(chip,
> > + i) ? "oDr" : ""));
> 
> Too many parentheses in a few of above lines.

I'll remove extra parentheses.


> > +               seq_puts(s, "\n");
> > +       }
> 
> ...
> 
> > +               dev_err_probe(&pdev->dev, -EINVAL, "Not a gpio-controller!\n");
> > +               return -EINVAL;
> 
> Unite them in one return statement.
> Ditto for zillion similar cases in this driver.

I'll modify code as shown below:

	return dev_err_probe(&pdev->dev, -EINVAL, "Not a gpio-controller!\n");


> ...
> 
> > +       gchip->parent =            &pdev->dev;
> 
> > +       gchip->of_node =           pdev->dev.of_node;
> 
> Drop this dup. GPIO library already does it for you.

But when I removed the two statements, I found both 'gchip->parent' and
'gchip->of_node' are always 0. No one helps set it.

Do I miss doing somethings?


> ...
> 
> > +       int i = 0;
> 
> What for this assignment?

The following statement "if (configs[i] == 0xFF) {"
needs "i" to be initialized to 0.

I'll remove the initialization and revise the statement

	if (configs[i] == 0x0ff) {

to

	if (configs[0] == 0xff) {


> > +       dev_dbg(pctldev->dev, "%s(%d, %ld, %d)\n", __func__, pin,
> > + *configs, num_configs);
> 
> Noise. Better to consider to add necessary tracepoints to pin control core.

What should I do?
Should I remove it?


> > +       /* Special handling for IOP */
> > +       if (configs[i] == 0xFF) {
> 
> Why out of a sudden capitilazed hex value?

I'll modify it to lowercase.
'configs' is set to 0xff to remember we need special process for IOP pin-mux pins.


> > +               sppctl_first_master_set(&pctl->spp_gchip->chip, pin, mux_f_gpio,
> mux_m_iop);
> > +               return 0;
> > +       }
> 
> ...
> 
> > +       dev_dbg(pctldev->dev, "%s(%d)\n", __func__, offset);
> 
> Noise. And so on, so on...

Should I remove dev_dbg? Or modify it?
But it will not print out anything in normal run, only for debugging.


> ...
> 
> > +       dev_dbg(pctldev->dev, "%s(%d), f_idx: %d, g_idx: %d, freg: %d\n",
> > +               __func__, selector, g2fpm.f_idx, g2fpm.g_idx,
> > + f->freg);
> 
> No need to use __func__, and especially in case of _dbg / _debug. It can be enabled at
> run-time with help of Dynamic Debug.

Should I need to remove all __func__ in this driver?


> ...
> 
> > +       seq_printf(s, "%s", dev_name(pctldev->dev));
> 
> Isn't it printed by core?

I'll remove the "seq_printf(...);"


> ...
> 
> > +static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
> *np_config,
> > +                                struct pinctrl_map **map, unsigned
> > +int *num_maps) {
> 
> Looking into this rather quite big function why you can't use what pin control core provides?

No, we cannot use functions pin-control core provides.
Please refer to dt-bindings document, "pinctrl/sunplus,sp7021-pinctrl.yaml".
We have more explanation there.


> > +}
> ...
> 
> > +       /* Fill up unique group names array. */
> > +       sppctl->unq_grps = devm_kzalloc(&pdev->dev, (sppctl->unq_grps_sz + 1) *
> > +                                       sizeof(char *), GFP_KERNEL);
> 
> You need to use devm_kcalloc() variant for arrays.

I'll modify code to use devm_kcalloc().

I'll modify sizeof() to use type of variable, that is:
	sizeof(*sppctl->unq_grps)


> > +       if (!sppctl->unq_grps)
> > +               return -ENOMEM;
> 
> > +       sppctl->g2fp_maps = devm_kzalloc(&pdev->dev, (sppctl->unq_grps_sz + 1) *
> > +                                        sizeof(struct grp2fp_map),
> > + GFP_KERNEL);
> 
> Ditto, besides the fact of better use of sizeof() of the type of variable, done by
> sizeof(*..._maps).

I'll modify code to use devm_kcalloc().

I'll modify sizeof() to use type of variable, that is:
	sizeof(*sppctl->g2fp_maps)


> > +       if (!sppctl->g2fp_maps)
> > +               return -ENOMEM;
> > +
> > +       sppctl->groups_name = devm_kzalloc(&pdev->dev, sppctl_list_funcs_sz *
> > +                                          SPPCTL_MAX_GROUPS *
> > + sizeof(char *), GFP_KERNEL);
> 
> Ditto. And check some interesting macros in overflow.h.

I'll modify code to use devm_kcalloc().

I'll modify sizeof() to use type of variable, that is:
	sizeof(*sppctl->groups_name)

Please teach me what macros should I check?
There are many macros in overflow.h.


> > +       if (!sppctl->groups_name)
> > +               return -ENOMEM;
> ...
> 
> > +       /* gpio */
> 
> GPIO, but either way seems not so valuable comment.

I'll modify the comment to let it more meaningful.


> ...
> 
> > +       err = devm_pinctrl_register_and_init(&pdev->dev, &sppctl->pctl_desc,
> > +                                            sppctl, &sppctl->pctl_dev);
> > +       if (err) {
> 
> > +               dev_err_probe(&pdev->dev, err, "Failed to register pinctrl!\n");
> > +               of_node_put(np);
> 
> Swap them and use the form of
> return dev_err_probe();

I'll modify it.


> > +               return err;
> > +       }
> 
> ...
> 
> > +       /* MOON2 registers */
> > +       rp = platform_get_resource_byname(pdev, IORESOURCE_MEM, "moon2");
> > +       sppctl->moon2_base = devm_ioremap_resource(&pdev->dev, rp);
> 
> We have an API that provides two in one.

I'll modify code to use devm_platform_ioremap_resource_byname().


> > +       if (IS_ERR(sppctl->moon2_base)) {
> > +               ret = PTR_ERR(sppctl->moon2_base);
> > +               goto ioremap_failed;
> 
> What is this for? Use return dev_err_probe() directly.

There are 5 devm_ioremap_resource() in this function.
To avoid from duplication, goto an error-handling when ioremap failed.


> > +       }
> 
> > +       dev_dbg(&pdev->dev, "MOON2:   %pr\n", rp);
> 
> This cryptic noise has to be removed.
> 
> Above comments are applicable to all similar cases.

I'll remove all them.


> ...
> 
> > +ioremap_failed:
> > +       dev_err_probe(&pdev->dev, ret, "ioremap failed!\n");
> 
> This doesn't bring any value, besides the fact that API you have used already prints a
> message.

I'll modify code to as shown below (error-handling here):

ioremap_failed:
	return dev_err_probe(&pdev->dev, ret, "ioremap failed!\n");
}

Is this ok?
If not, please teach me how to modify.


> ...
> 
> > +       pdev->dev.platform_data = sppctl;
> 
> Don't we have special setter for this field?

I know platform_set_drvdata() function is used to set "dev->driver_data".
I cannot find a function to set "dev->platform_data".
Please teach me what function should I use to set "dev->platform_data"?


> ...
> 
> > +       dev_info(&pdev->dev, "SP7021 PinCtrl by Sunplus/Tibbo Tech.
> > + (c)");
> 
> No value.

This shows that pinctrl driver has probed successfully.
Many drivers show this kind of information.
Do I need to remove it? Or change to dev_dbg(...).


> ...
> 
> > +       { /* zero */ }
> 
> Comment with no value.

I'll remove the comment.


> > +};
> 
> ...
> 
> > +               .owner          = THIS_MODULE,
> 
> It's probably 5+ years that we don't need this (it's applied implicitly).

I'll remove it.


> ...
> 
> > +#ifndef __SPPCTL_H__
> > +#define __SPPCTL_H__
> 
> This header misses the inclusions such as bits.h.
> And I believe more than that.

Some reviewers ask to remove unnecessary header files.
I removed all unnecessary header files if compilation completes 
without any errors or warnings.

If compilation has done successfully, does it mean all 
necessary inclusions has included well?

Besides, before private header files are included,
Linux or system header files will be included.
No need extra inclusion here, right?


> ...
> 
> > +/* FIRST register:
> > + *   0: MUX
> > + *   1: GPIO/IOP
> > + *   2: No change
> > + */
> 
> For all comments starting from here and for similar cases elsewhere:
>  - why it is not in kernel doc?
>  - what the value that add?
> (Some of them so cryptic or so obvious)

The comment explains usage of 'enum mux_f_mg'
The 'enum' is only used in the driver.
It helps programmers to remember or look-up the define of the enum.
Need we add this kind of comment to kernel doc?


> ...
> 
> > +static const struct sppctl_grp sp7021grps_spif[] = {
> > +       EGRP("SPI_FLASH1", 1, pins_spif1),
> > +       EGRP("SPI_FLASH2", 2, pins_spif2)
> 
> Here and everywhere else, leave a comma if it's not a terminator entry.

The constant array 'sp7021grps_spif[]' is declared and initialized 
to have 2 elements. 'EGRP("SPI_FLASH2", 2, pins_spif2)' is the 
latest element.
Why do we need to add 'comma' for the latest element of an array?
If we add extra comma, the array will have one more element.


> > +};
> 
> --
> With Best Regards,
> Andy Shevchenko

Best regards,
Wells Lu


^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH v4 1/2] dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021
  2021-12-14 15:21   ` Rob Herring
@ 2021-12-15 11:10     ` Wells Lu 呂芳騰
  0 siblings, 0 replies; 10+ messages in thread
From: Wells Lu 呂芳騰 @ 2021-12-15 11:10 UTC (permalink / raw)
  To: Rob Herring, Wells Lu
  Cc: devicetree, linux-gpio, robh+dt, dvorkin, linus.walleij,
	linux-kernel, linux-arm-kernel

Hi Rob,

Thanks a lot for review.

I ran 'make dt_binding_check' and got PASS before I submitted the 
dt-binding doc (yaml) file.

I found the "dtschema/dtc warnings/errors:" is resulted from lack 
of vendor name in "vendor-prefixes.yaml".

My colleague has submitted a patch for adding our company name to 
the yaml file. It was acknowledged by you but not yet committed 
into tree.

Refer to:

On Mon, 01 Nov 2021 13:01:51 +0800, Qin Jian wrote:
> Add vendor prefix for Sunplus Technology Co., Ltd.
> 
> Signed-off-by: Qin Jian <qinjian@cqplus1.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>


Can this error be waived?
When I send a new patch, should I add "vendor-prefixes.yaml"?


Best regards,
Wells

> > Add dt-bindings header files and documentation for Sunplus SP7021 SoC.
> >
> > Signed-off-by: Wells Lu <wellslutw@gmail.com>
> > ---
> > Changes in V4
> >   - Addressed comments of Mr. Linus Walleij.
> >     - Remove 'if type object then' stuff for patternProperties '-pins$'.
> >     - Added more descriptions about pins control of SP7021.
> >     - Modified name property 'pins' to 'sunplus,pins' (vendor specific).
> >     - Modified name property 'zero_func' to 'sunplus,zero_func' (vendor specific).
> >
> >  .../bindings/pinctrl/sunplus,sp7021-pinctrl.yaml   | 375 +++++++++++++++++++++
> >  MAINTAINERS                                        |   9 +
> >  include/dt-bindings/pinctrl/sppctl-sp7021.h        | 173 ++++++++++
> >  include/dt-bindings/pinctrl/sppctl.h               |  40 +++
> >  4 files changed, 597 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
> >  create mode 100644 include/dt-bindings/pinctrl/sppctl-sp7021.h
> >  create mode 100644 include/dt-bindings/pinctrl/sppctl.h
> >
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/pinctrl/sunplus,
> sp7021-pinctrl.example.dt.yaml: uart1-pins: 'sunplus,pins' does not match any of the
> regexes: '^#.*',
> '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio
> ),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*',
> '^(pinctrl-single|#pinctrl-single|PowerPC),.*',
> '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*',
> '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*',
> '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$',
> '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*',
> '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*',
> '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^advantech,.*',
> '^aeroflexgaisler,.*', '^aesop,.*', '^al,.*', '^alcatel,.*', '^allegro,.*', '^allo,.*',
> '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*',
> '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*',
> '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', '^anvo,.*',
> '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arctic,.*',
> '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*',
> '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asus,.*', '^atlas,.*',
> '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*',
> '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*',
> '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^blutek,.*',
> '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*',
> '^buffalo,.*', '^bur,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*',
> '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*',
> '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*',
> '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*',
> '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cloudengines,.*',
> '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coreriver,.*',
> '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*',
> '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*',
> '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*',
> '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*',
> '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*',
> '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*',
> '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebs-systart,.*', '^ebv,.*',
> '^eckelmann,.*', '^edimax,.*', '^edt,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*',
> '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*',
> '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*',
> '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^epcos,.*', '^epfl,.*',
> '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*',
> '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*',
> '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*',
> '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^frida,.*',
> '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^gardena,.*', '^gateworks,.*', '^gcw,.*',
> '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^geniatech,.*', '^giantec,.*',
> '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goodix,.*',
> '^google,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*',
> '^haoyu,.*', '^hardkernel,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*',
> '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*',
> '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hsg,.*', '^hugsun,.*', '^hwacom,.*',
> '^hycon,.*', '^hydis,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*',
> '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^img,.*', '^imi,.*', '^incircuit,.*',
> '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^innolux,.*',
> '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*',
> '^invensense,.*', '^inversepath,.*', '^iom,.*', '^isee,.*', '^isil,.*', '^issi,.*',
> '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jdi,.*', '^jedec,.*',
> '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*',
> '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*',
> '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*',
> '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*',
> '^lattice,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*',
> '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*',
> '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*',
> '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*',
> '^longcheer,.*', '^lontium,.*', '^loongson,.*', '^lsi,.*', '^lwn,.*', '^lxa,.*',
> '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marvell,.*',
> '^maxbotix,.*', '^maxim,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*',
> '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*',
> '^mellanox,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*',
> '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*',
> '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^miniand,.*', '^minix,.*',
> '^miramems,.*', '^mitsubishi,.*', '^mntre,.*', '^modtronix,.*', '^mosaixtech,.*',
> '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*',
> '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*',
> '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*',
> '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*',
> '^newhaven,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*',
> '^nokia,.*', '^nordic,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*',
> '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*',
> '^olpc,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^opencores,.*',
> '^openembed,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*',
> '^ortustech,.*', '^osddisplays,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*',
> '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*',
> '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*',
> '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*',
> '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^portwell,.*', '^poslab,.*',
> '^pov,.*', '^powertip,.*', '^powervr,.*', '^primux,.*', '^probox2,.*', '^prt,.*',
> '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*',
> '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^radxa,.*',
> '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*',
> '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*',
> '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*',
> '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*',
> '^roseapplepi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*',
> '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*',
> '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sff,.*', '^sgd,.*',
> '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shimafuji,.*', '^shiratech,.*', '^si-en,.*',
> '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*',
> '^silabs,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*',
> '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*',
> '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*',
> '^smartlabs,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*',
> '^solomon,.*', '^sony,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*',
> '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*',
> '^starry,.*', '^startek,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*',
> '^summit,.*', '^sunchip,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*',
> '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*',
> '^technexion,.*', '^technologic,.*', '^techstar,.*', '^teltonika,.*', '^tempo,.*',
> '^terasic,.*', '^tfc,.*', '^thine,.*', '^thingyjp,.*', '^ti,.*', '^tianma,.*', '^tlm,.*',
> '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*',
> '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*',
> '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^tyan,.*',
> '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ugoos,.*',
> '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*',
> '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^via,.*', '^videostrong,.*', '^virtio,.*',
> '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*',
> '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wand,.*', '^waveshare,.*', '^wd,.*',
> '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*',
> '^wiligear,.*', '^winbond,.*', '^winstar,.*', '^wits,.*', '^wlf,.*', '^wm,.*',
> '^wobo,.*', '^x-powers,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*',
> '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*',
> '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^ylm,.*', '^yna,.*',
> '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*',
> '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
> 	From schema:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/vendor-prefixes.
> yaml
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/pinctrl/sunplus,
> sp7021-pinctrl.example.dt.yaml: uart2-pins: 'sunplus,pins' does not match any of the
> regexes: '^#.*',
> '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio
> ),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*',
> '^(pinctrl-single|#pinctrl-single|PowerPC),.*',
> '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*',
> '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*',
> '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$',
> '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*',
> '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*',
> '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^advantech,.*',
> '^aeroflexgaisler,.*', '^aesop,.*', '^al,.*', '^alcatel,.*', '^allegro,.*', '^allo,.*',
> '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*',
> '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*',
> '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', '^anvo,.*',
> '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arctic,.*',
> '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*',
> '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asus,.*', '^atlas,.*',
> '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*',
> '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*',
> '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^blutek,.*',
> '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*',
> '^buffalo,.*', '^bur,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*',
> '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*',
> '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*',
> '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*',
> '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cloudengines,.*',
> '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coreriver,.*',
> '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*',
> '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*',
> '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*',
> '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*',
> '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*',
> '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*',
> '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebs-systart,.*', '^ebv,.*',
> '^eckelmann,.*', '^edimax,.*', '^edt,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*',
> '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*',
> '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*',
> '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^epcos,.*', '^epfl,.*',
> '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*',
> '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*',
> '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*',
> '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^frida,.*',
> '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^gardena,.*', '^gateworks,.*', '^gcw,.*',
> '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^geniatech,.*', '^giantec,.*',
> '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goodix,.*',
> '^google,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*',
> '^haoyu,.*', '^hardkernel,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*',
> '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*',
> '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hsg,.*', '^hugsun,.*', '^hwacom,.*',
> '^hycon,.*', '^hydis,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*',
> '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^img,.*', '^imi,.*', '^incircuit,.*',
> '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^innolux,.*',
> '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*',
> '^invensense,.*', '^inversepath,.*', '^iom,.*', '^isee,.*', '^isil,.*', '^issi,.*',
> '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jdi,.*', '^jedec,.*',
> '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*',
> '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*',
> '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*',
> '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*',
> '^lattice,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*',
> '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*',
> '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*',
> '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*',
> '^longcheer,.*', '^lontium,.*', '^loongson,.*', '^lsi,.*', '^lwn,.*', '^lxa,.*',
> '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marvell,.*',
> '^maxbotix,.*', '^maxim,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*',
> '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*',
> '^mellanox,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*',
> '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*',
> '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^miniand,.*', '^minix,.*',
> '^miramems,.*', '^mitsubishi,.*', '^mntre,.*', '^modtronix,.*', '^mosaixtech,.*',
> '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*',
> '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*',
> '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*',
> '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*',
> '^newhaven,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*',
> '^nokia,.*', '^nordic,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*',
> '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*',
> '^olpc,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^opencores,.*',
> '^openembed,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*',
> '^ortustech,.*', '^osddisplays,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*',
> '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*',
> '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*',
> '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*',
> '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^portwell,.*', '^poslab,.*',
> '^pov,.*', '^powertip,.*', '^powervr,.*', '^primux,.*', '^probox2,.*', '^prt,.*',
> '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*',
> '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^radxa,.*',
> '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*',
> '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*',
> '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*',
> '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*',
> '^roseapplepi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*',
> '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*',
> '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sff,.*', '^sgd,.*',
> '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shimafuji,.*', '^shiratech,.*', '^si-en,.*',
> '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*',
> '^silabs,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*',
> '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*',
> '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*',
> '^smartlabs,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*',
> '^solomon,.*', '^sony,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*',
> '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*',
> '^starry,.*', '^startek,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*',
> '^summit,.*', '^sunchip,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*',
> '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*',
> '^technexion,.*', '^technologic,.*', '^techstar,.*', '^teltonika,.*', '^tempo,.*',
> '^terasic,.*', '^tfc,.*', '^thine,.*', '^thingyjp,.*', '^ti,.*', '^tianma,.*', '^tlm,.*',
> '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*',
> '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*',
> '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^tyan,.*',
> '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ugoos,.*',
> '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*',
> '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^via,.*', '^videostrong,.*', '^virtio,.*',
> '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*',
> '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wand,.*', '^waveshare,.*', '^wd,.*',
> '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*',
> '^wiligear,.*', '^winbond,.*', '^winstar,.*', '^wits,.*', '^wlf,.*', '^wm,.*',
> '^wobo,.*', '^x-powers,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*',
> '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*',
> '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^ylm,.*', '^yna,.*',
> '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*',
> '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
> 	From schema:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/vendor-prefixes.
> yaml
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/pinctrl/sunplus,
> sp7021-pinctrl.example.dt.yaml: sdcard-pins: 'sunplus,pins' does not match any of the
> regexes: '^#.*',
> '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio
> ),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*',
> '^(pinctrl-single|#pinctrl-single|PowerPC),.*',
> '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*',
> '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*',
> '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$',
> '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*',
> '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*',
> '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^advantech,.*',
> '^aeroflexgaisler,.*', '^aesop,.*', '^al,.*', '^alcatel,.*', '^allegro,.*', '^allo,.*',
> '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*',
> '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*',
> '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', '^anvo,.*',
> '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arctic,.*',
> '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*',
> '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asus,.*', '^atlas,.*',
> '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*',
> '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*',
> '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^blutek,.*',
> '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*',
> '^buffalo,.*', '^bur,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*',
> '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*',
> '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*',
> '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*',
> '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cloudengines,.*',
> '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coreriver,.*',
> '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*',
> '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*',
> '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*',
> '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*',
> '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*',
> '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*',
> '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebs-systart,.*', '^ebv,.*',
> '^eckelmann,.*', '^edimax,.*', '^edt,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*',
> '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*',
> '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*',
> '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^epcos,.*', '^epfl,.*',
> '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*',
> '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*',
> '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*',
> '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^frida,.*',
> '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^gardena,.*', '^gateworks,.*', '^gcw,.*',
> '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^geniatech,.*', '^giantec,.*',
> '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goodix,.*',
> '^google,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*',
> '^haoyu,.*', '^hardkernel,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*',
> '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*',
> '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hsg,.*', '^hugsun,.*', '^hwacom,.*',
> '^hycon,.*', '^hydis,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*',
> '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^img,.*', '^imi,.*', '^incircuit,.*',
> '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^innolux,.*',
> '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*',
> '^invensense,.*', '^inversepath,.*', '^iom,.*', '^isee,.*', '^isil,.*', '^issi,.*',
> '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jdi,.*', '^jedec,.*',
> '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*',
> '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*',
> '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*',
> '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*',
> '^lattice,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*',
> '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*',
> '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*',
> '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*',
> '^longcheer,.*', '^lontium,.*', '^loongson,.*', '^lsi,.*', '^lwn,.*', '^lxa,.*',
> '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marvell,.*',
> '^maxbotix,.*', '^maxim,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*',
> '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*',
> '^mellanox,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*',
> '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*',
> '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^miniand,.*', '^minix,.*',
> '^miramems,.*', '^mitsubishi,.*', '^mntre,.*', '^modtronix,.*', '^mosaixtech,.*',
> '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*',
> '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*',
> '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*',
> '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*',
> '^newhaven,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*',
> '^nokia,.*', '^nordic,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*',
> '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*',
> '^olpc,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^opencores,.*',
> '^openembed,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*',
> '^ortustech,.*', '^osddisplays,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*',
> '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*',
> '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*',
> '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*',
> '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^portwell,.*', '^poslab,.*',
> '^pov,.*', '^powertip,.*', '^powervr,.*', '^primux,.*', '^probox2,.*', '^prt,.*',
> '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*',
> '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^radxa,.*',
> '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*',
> '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*',
> '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*',
> '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*',
> '^roseapplepi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*',
> '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*',
> '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sff,.*', '^sgd,.*',
> '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shimafuji,.*', '^shiratech,.*', '^si-en,.*',
> '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*',
> '^silabs,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*',
> '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*',
> '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*',
> '^smartlabs,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*',
> '^solomon,.*', '^sony,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*',
> '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*',
> '^starry,.*', '^startek,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*',
> '^summit,.*', '^sunchip,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*',
> '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*',
> '^technexion,.*', '^technologic,.*', '^techstar,.*', '^teltonika,.*', '^tempo,.*',
> '^terasic,.*', '^tfc,.*', '^thine,.*', '^thingyjp,.*', '^ti,.*', '^tianma,.*', '^tlm,.*',
> '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*',
> '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*',
> '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^tyan,.*',
> '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ugoos,.*',
> '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*',
> '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^via,.*', '^videostrong,.*', '^virtio,.*',
> '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*',
> '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wand,.*', '^waveshare,.*', '^wd,.*',
> '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*',
> '^wiligear,.*', '^winbond,.*', '^winstar,.*', '^wits,.*', '^wlf,.*', '^wm,.*',
> '^wobo,.*', '^x-powers,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*',
> '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*',
> '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^ylm,.*', '^yna,.*',
> '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*',
> '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
> 	From schema:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/vendor-prefixes.
> yaml
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/pinctrl/sunplus,
> sp7021-pinctrl.example.dt.yaml: ethernet-pins: 'sunplus,pins', 'sunplus,zero_func' do
> not match any of the regexes: '^#.*',
> '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio
> ),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*',
> '^(pinctrl-single|#pinctrl-single|PowerPC),.*',
> '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*',
> '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*',
> '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$',
> '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*',
> '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*',
> '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^advantech,.*',
> '^aeroflexgaisler,.*', '^aesop,.*', '^al,.*', '^alcatel,.*', '^allegro,.*', '^allo,.*',
> '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*',
> '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*',
> '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', '^anvo,.*',
> '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arctic,.*',
> '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*',
> '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asus,.*', '^atlas,.*',
> '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*',
> '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*',
> '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^blutek,.*',
> '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*',
> '^buffalo,.*', '^bur,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*',
> '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*',
> '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*',
> '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*',
> '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^cloudengines,.*',
> '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coreriver,.*',
> '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*',
> '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*',
> '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*',
> '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*',
> '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*',
> '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*',
> '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebs-systart,.*', '^ebv,.*',
> '^eckelmann,.*', '^edimax,.*', '^edt,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*',
> '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*',
> '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*',
> '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^epcos,.*', '^epfl,.*',
> '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*',
> '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*',
> '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*',
> '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^frida,.*',
> '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^gardena,.*', '^gateworks,.*', '^gcw,.*',
> '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^geniatech,.*', '^giantec,.*',
> '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goodix,.*',
> '^google,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*',
> '^haoyu,.*', '^hardkernel,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*',
> '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*',
> '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hsg,.*', '^hugsun,.*', '^hwacom,.*',
> '^hycon,.*', '^hydis,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*',
> '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^img,.*', '^imi,.*', '^incircuit,.*',
> '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^innolux,.*',
> '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*',
> '^invensense,.*', '^inversepath,.*', '^iom,.*', '^isee,.*', '^isil,.*', '^issi,.*',
> '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jdi,.*', '^jedec,.*',
> '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*',
> '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*',
> '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*',
> '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*',
> '^lattice,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*',
> '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*',
> '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*',
> '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*',
> '^longcheer,.*', '^lontium,.*', '^loongson,.*', '^lsi,.*', '^lwn,.*', '^lxa,.*',
> '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marvell,.*',
> '^maxbotix,.*', '^maxim,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*',
> '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*',
> '^mellanox,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*',
> '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*',
> '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^miniand,.*', '^minix,.*',
> '^miramems,.*', '^mitsubishi,.*', '^mntre,.*', '^modtronix,.*', '^mosaixtech,.*',
> '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*',
> '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*',
> '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*',
> '^netlogic,.*', '^netron-dy,..*', '^netronix,.*', '^netxeon,.*', '^neweast,.*',
> '^newhaven,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*',
> '^nokia,.*', '^nordic,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*',
> '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*',
> '^olpc,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^opencores,.*',
> '^openembed,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*',
> '^ortustech,.*', '^osddisplays,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*',
> '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*',
> '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*',
> '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*',
> '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^portwell,.*', '^poslab,.*',
> '^pov,.*', '^powertip,.*', '^powervr,.*', '^primux,.*', '^probox2,.*', '^prt,.*',
> '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*',
> '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^radxa,.*',
> '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*',
> '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*',
> '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*',
> '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*',
> '^roseapplepi,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*',
> '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*',
> '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sff,.*', '^sgd,.*',
> '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shimafuji,.*', '^shiratech,.*', '^si-en,.*',
> '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*',
> '^silabs,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*',
> '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*',
> '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*',
> '^smartlabs,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*',
> '^solomon,.*', '^sony,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*',
> '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*',
> '^starry,.*', '^startek,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*',
> '^summit,.*', '^sunchip,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*',
> '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*',
> '^technexion,.*', '^technologic,.*', '^techstar,.*', '^teltonika,.*', '^tempo,.*',
> '^terasic,.*', '^tfc,.*', '^thine,.*', '^thingyjp,.*', '^ti,.*', '^tianma,.*', '^tlm,.*',
> '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*',
> '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*',
> '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^tyan,.*',
> '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ugoos,.*',
> '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*',
> '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^via,.*', '^videostrong,.*', '^virtio,.*',
> '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*',
> '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wand,.*', '^waveshare,.*', '^wd,.*',
> '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*',
> '^wiligear,.*', '^winbond,.*', '^winstar,.*', '^wits,.*', '^wlf,.*', '^wm,.*',
> '^wobo,.*', '^x-powers,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*',
> '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*',
> '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^ylm,.*', '^yna,.*',
> '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*',
> '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*'
> 	From schema:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/vendor-prefixes.
> yaml
> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/patch/1567651
> 
> This check can fail if there are any dependencies. The base for a patch series is generally
> the most recent rc1.
> 
> If you already ran 'make dt_binding_check' and didn't see the above error(s), then make
> sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 2/2] pinctrl: Add driver for Sunplus SP7021
  2021-12-15  9:40     ` Wells Lu 呂芳騰
@ 2021-12-15 12:03       ` Andy Shevchenko
  2021-12-15 15:32         ` Wells Lu 呂芳騰
  2021-12-20  6:02         ` Wells Lu 呂芳騰
  0 siblings, 2 replies; 10+ messages in thread
From: Andy Shevchenko @ 2021-12-15 12:03 UTC (permalink / raw)
  To: Wells Lu 呂芳騰
  Cc: Wells Lu, Linus Walleij, open list:GPIO SUBSYSTEM,
	Linux Kernel Mailing List, Rob Herring, devicetree,
	linux-arm Mailing List, dvorkin

On Wed, Dec 15, 2021 at 11:40 AM Wells Lu 呂芳騰 <wells.lu@sunplus.com> wrote:

...

> > > +/* SP7021 Pin Controller Driver.
> > > + * Copyright (C) Sunplus Tech/Tibbo Tech.
> > > + */
> >
> > This is wrong style for multi-line comments. Fix it everywhere accordingly.
>
> I'll modify all multi-line comments, for example, as shown below:
>
> /*
>  * SP7021 Pin Controller Driver.
>  * Copyright (C) Sunplus Tech/Tibbo Tech.
>  */
>
> Now, I realized that each subsystem has its own comment style.

Actually there are only two styles:
 - this one (as updated version) for entire kernel with the exception of
 - net / network one (as you used originally)

> > ...
> >
> > > +#include <linux/platform_device.h>
> > > +#include <linux/pinctrl/pinmux.h>
> > > +#include <linux/gpio/driver.h>
> > > +#include <linux/module.h>
> > > +#include <linux/bitfield.h>
> >
> > Keep them in order. Besides that it seems missed a few headers, such as of.h.
>
> I am not sure what order should I keep for inclusions.
> Reversed x'mas tree order? Alphabetic order?

Alphabetical. When you don't see a direct answer the rule of thumb is
to go to the recent contributions and check a few new drivers to see
how they are doing.

> Some reviewers ask to remove unnecessary header files.

So that reviewers are right and maybe wrong (see below for the
details), I don't see those reviews so I can't judge.

> So I removed all unnecessary header files if compilation
> completes without any errors or warnings.

Have you checked how deep and sudden the header inclusion went?

> I suppose <linux/of.h> has included by other inclusion.

Of course and it's wrong in your case. No header from above guarantees
that. See below.

> Need I add <linux/of.h> or other inclusions back?

The rule of thumb is that you have to include all headers you are a
direct user of.
There are some that guarantee inclusion of others, like
bits.h is always included if you use bitmap.h  (via bitops.h) or
compiler_attributes.h is always provided by types.h.

You have to find a golden ratio here (yes, it's kinda knowledge that
doesn't come at once, needs to have some experience).

...

> > > +       val = (reg & BIT(bit_off)) ? 1 : 0;
> >
> > !!(...) may also work, but it's rather style preference.
>
> The return value is integer 0 or 1, not Boolean.

Yes, and it's exactly what has been suggested. It's a C standard
allowed trick. With the -O2 compiler gives you the same code for both
(at least on x86).

...

> > > +       reg = readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER +
> > > + reg_off);
> >
> > I noticed a potentially big issue with this driver. Are you sure it's brave enough to do
> > I/O without any synchronisation? Did I miss a lock?
>
> Do I need to add spin_lock() for all gpio operation functions?
> Please teach me what operation functions I need to add lock or
> all operation functions need lock?

I don't know. You need to answer this question, it's your code. And
you know how it's supposed to be used etc, etc.

...

> > > +       reg = readl(spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD +
> > > + reg_off);
> >
> > You may create an I/O wrappers to achieve a much better to read code (no repetition of
> > this arithmetics, etc).
>
> I think this is the simplest in-line form:

No, it's harder to read and easy to mistake what the base and / or
offset is used, what value, etc.

> "spp_gchip->gpioxt2_base" is base address.
> SPPCTL_GPIO_OFF_OD is register offset to base of OD (open-drain) registers.
> reg_off is register offset to an OD register (SP7021 has 7 OD registers totally).
>
> Need I add macros (wrappers) for accessing registers?
>
> For example,
>
> #define SPPCTL_GPIO_OD(off)     (spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD + off)
>
> reg = readl(SPPCTL_GPIO_OD(reg_off));
>
> or
>
> writel(reg, SPPCTL_GPIO_OD(reg_off));
>
>
> Mr. Linus Walleij told me that he likes in-line (direct) form, instead of macro
> because in-line form has better readability (No need to jump to other file for
> reading macros).
>
> Could you please share me with your idea?

It's an idea that is used in zillions of the drivers (and not via macros).

static inline spp_readl(struct ... *spp, u32 offset)
{
  return readl(...);
}

Same for _writel() and so on.

...

> > Perhaps to show only requested ones? In such case you may use
> > for_each_requested_gpio() macro.
>
> I'd like to keep showing status of all GPIOs.
> This helps us know status of all GPIOs when debugging hardware issue.

Since it's a pin control driver, the pin control debug callback can
show this. For GPIO I would rather not be bothered with not requested
pins. But it's your decision.

...

> > > +       gchip->parent =            &pdev->dev;
> >
> > > +       gchip->of_node =           pdev->dev.of_node;
> >
> > Drop this dup. GPIO library already does it for you.
>
> But when I removed the two statements, I found both 'gchip->parent' and
> 'gchip->of_node' are always 0. No one helps set it.
>
> Do I miss doing somethings?

Yes, I put blank lines around the dup and left context (as a first
line) to show why the second one is a dup. When you miss something,
read the implementation code. It's open source at the end!

...

> > > +       dev_dbg(pctldev->dev, "%s(%d, %ld, %d)\n", __func__, pin,
> > > + *configs, num_configs);
> >
> > Noise. Better to consider to add necessary tracepoints to pin control core.
>
> What should I do?
> Should I remove it?

I wouldn't expect these to be in the production-ready driver. And
since you are committing to drivers/pinctrl and not to drivers/staging
I consider that you are trying to push this code as production-ready.

...

> > > +       dev_dbg(pctldev->dev, "%s(%d)\n", __func__, offset);
> >
> > Noise. And so on, so on...
>
> Should I remove dev_dbg? Or modify it?
> But it will not print out anything in normal run, only for debugging.

See above.

...

> > > +       dev_dbg(pctldev->dev, "%s(%d), f_idx: %d, g_idx: %d, freg: %d\n",
> > > +               __func__, selector, g2fpm.f_idx, g2fpm.g_idx,
> > > + f->freg);
> >
> > No need to use __func__, and especially in case of _dbg / _debug. It can be enabled at
> > run-time with help of Dynamic Debug.
>
> Should I need to remove all __func__ in this driver?

As the first step, the second one is to remove 90%+ of these messages
as I explained above.

...

> > Looking into this rather quite big function why you can't use what pin control core provides?
>
> No, we cannot use functions pin-control core provides.
> Please refer to dt-bindings document, "pinctrl/sunplus,sp7021-pinctrl.yaml".
> We have more explanation there.

Fine, can you reuse some library functions, etc? Please, consider
refactoring to make it more readable.

...

> > > +       sppctl->groups_name = devm_kzalloc(&pdev->dev, sppctl_list_funcs_sz *
> > > +                                          SPPCTL_MAX_GROUPS *
> > > + sizeof(char *), GFP_KERNEL);
> >
> > Ditto. And check some interesting macros in overflow.h.
>
> I'll modify code to use devm_kcalloc().
>
> I'll modify sizeof() to use type of variable, that is:
>         sizeof(*sppctl->groups_name)
>
> Please teach me what macros should I check?
> There are many macros in overflow.h.

Do your homework, it's not me who makes this contribution :-)
Hint: something about multiplication.

...

> > > +       if (IS_ERR(sppctl->moon2_base)) {
> > > +               ret = PTR_ERR(sppctl->moon2_base);
> > > +               goto ioremap_failed;
> >
> > What is this for? Use return dev_err_probe() directly.
>
> There are 5 devm_ioremap_resource() in this function.
> To avoid from duplication, goto an error-handling when ioremap failed.

What error handling? You have the same point which does the same for
them, I don't see duplication avoidance. See below as well.

> > > +       }

...

> > > +ioremap_failed:
> > > +       dev_err_probe(&pdev->dev, ret, "ioremap failed!\n");
> >
> > This doesn't bring any value,
>> besides the fact that API you have used already prints a
> > message.

(1)

> I'll modify code to as shown below (error-handling here):
>
> ioremap_failed:
>         return dev_err_probe(&pdev->dev, ret, "ioremap failed!\n");
> }
>
> Is this ok?

No.

> If not, please teach me how to modify.

Read again what I wrote in (1).

> > > +       pdev->dev.platform_data = sppctl;
> >
> > Don't we have special setter for this field?
>
> I know platform_set_drvdata() function is used to set "dev->driver_data".
> I cannot find a function to set "dev->platform_data".
> Please teach me what function should I use to set "dev->platform_data"?

Ah, now I even may say that the above assignment is simply wrong.
It's not designed for what you think it's for. Use different ways.

...

> > > +       dev_info(&pdev->dev, "SP7021 PinCtrl by Sunplus/Tibbo Tech.
> > > + (c)");
> >
> > No value.
>
> This shows that pinctrl driver has probed successfully.
> Many drivers show this kind of information.

And there is no value in this information.

> Do I need to remove it? Or change to dev_dbg(...).

Neither in this case.

Explain the point "why?". In general you have to explain each line of
your code "why are you doing this or that?".

...

> > > +#ifndef __SPPCTL_H__
> > > +#define __SPPCTL_H__
> >
> > This header misses the inclusions such as bits.h.
> > And I believe more than that.
>
> Some reviewers ask to remove unnecessary header files.

What do you mean by this in this case. This is a clear miss of bits.h
here as you use macros from it. Imagine if you include this file
somewhere where bits.h hasn't found its mysterious ways.

> I removed all unnecessary header files if compilation completes
> without any errors or warnings.
>
> If compilation has done successfully,

So what? It doesn't mean the code is bad in one way or another, :-)

> does it mean all
> necessary inclusions has included well?

> Besides, before private header files are included,
> Linux or system header files will be included.
> No need extra inclusion here, right?

See above.

...

> > > +/* FIRST register:
> > > + *   0: MUX
> > > + *   1: GPIO/IOP
> > > + *   2: No change
> > > + */
> >
> > For all comments starting from here and for similar cases elsewhere:
> >  - why it is not in kernel doc?
> >  - what the value that add?
> > (Some of them so cryptic or so obvious)
>
> The comment explains usage of 'enum mux_f_mg'
> The 'enum' is only used in the driver.
> It helps programmers to remember or look-up the define of the enum.
> Need we add this kind of comment to kernel doc?

Why not?

> > > +static const struct sppctl_grp sp7021grps_spif[] = {
> > > +       EGRP("SPI_FLASH1", 1, pins_spif1),
> > > +       EGRP("SPI_FLASH2", 2, pins_spif2)
> >
> > Here and everywhere else, leave a comma if it's not a terminator entry.
>
> The constant array 'sp7021grps_spif[]' is declared and initialized
> to have 2 elements. 'EGRP("SPI_FLASH2", 2, pins_spif2)' is the
> latest element.
> Why do we need to add 'comma' for the latest element of an array?

To avoid the churn in the future when it will be expanded. Believe I
saw this kind of "proves" that this or that won't ever be expanded and
then... you may picture what happens.

> If we add extra comma, the array will have one more element.

Yes, with touching the "last" one here. Please, add commas where it's
not a crystal clear a termination (which is not in many cases, usually
arrays with NULL entry or enums with MAX value at the end).

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH v4 2/2] pinctrl: Add driver for Sunplus SP7021
  2021-12-15 12:03       ` Andy Shevchenko
@ 2021-12-15 15:32         ` Wells Lu 呂芳騰
  2021-12-20  6:02         ` Wells Lu 呂芳騰
  1 sibling, 0 replies; 10+ messages in thread
From: Wells Lu 呂芳騰 @ 2021-12-15 15:32 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Wells Lu, Linus Walleij, open list:GPIO SUBSYSTEM,
	Linux Kernel Mailing List, Rob Herring, devicetree,
	linux-arm Mailing List, dvorkin

Hi Andy,

Thank you for answers and comments.

I'll modify code accordingly and will
send a new patch when ready.


Thanks,

Wells Lu

> ...
> 
> > > > +/* SP7021 Pin Controller Driver.
> > > > + * Copyright (C) Sunplus Tech/Tibbo Tech.
> > > > + */
> > >
> > > This is wrong style for multi-line comments. Fix it everywhere accordingly.
> >
> > I'll modify all multi-line comments, for example, as shown below:
> >
> > /*
> >  * SP7021 Pin Controller Driver.
> >  * Copyright (C) Sunplus Tech/Tibbo Tech.
> >  */
> >
> > Now, I realized that each subsystem has its own comment style.
> 
> Actually there are only two styles:
>  - this one (as updated version) for entire kernel with the exception of
>  - net / network one (as you used originally)
> 
> > > ...
> > >
> > > > +#include <linux/platform_device.h> #include
> > > > +<linux/pinctrl/pinmux.h> #include <linux/gpio/driver.h> #include
> > > > +<linux/module.h> #include <linux/bitfield.h>
> > >
> > > Keep them in order. Besides that it seems missed a few headers, such as of.h.
> >
> > I am not sure what order should I keep for inclusions.
> > Reversed x'mas tree order? Alphabetic order?
> 
> Alphabetical. When you don't see a direct answer the rule of thumb is to go to the recent
> contributions and check a few new drivers to see how they are doing.
> 
> > Some reviewers ask to remove unnecessary header files.
> 
> So that reviewers are right and maybe wrong (see below for the details), I don't see those
> reviews so I can't judge.
> 
> > So I removed all unnecessary header files if compilation completes
> > without any errors or warnings.
> 
> Have you checked how deep and sudden the header inclusion went?
> 
> > I suppose <linux/of.h> has included by other inclusion.
> 
> Of course and it's wrong in your case. No header from above guarantees that. See below.
> 
> > Need I add <linux/of.h> or other inclusions back?
> 
> The rule of thumb is that you have to include all headers you are a direct user of.
> There are some that guarantee inclusion of others, like bits.h is always included if you
> use bitmap.h  (via bitops.h) or compiler_attributes.h is always provided by types.h.
> 
> You have to find a golden ratio here (yes, it's kinda knowledge that doesn't come at once,
> needs to have some experience).
> 
> ...
> 
> > > > +       val = (reg & BIT(bit_off)) ? 1 : 0;
> > >
> > > !!(...) may also work, but it's rather style preference.
> >
> > The return value is integer 0 or 1, not Boolean.
> 
> Yes, and it's exactly what has been suggested. It's a C standard allowed trick. With the
> -O2 compiler gives you the same code for both (at least on x86).
> 
> ...
> 
> > > > +       reg = readl(spp_gchip->gpioxt_base +
> > > > + SPPCTL_GPIO_OFF_MASTER + reg_off);
> > >
> > > I noticed a potentially big issue with this driver. Are you sure
> > > it's brave enough to do I/O without any synchronisation? Did I miss a lock?
> >
> > Do I need to add spin_lock() for all gpio operation functions?
> > Please teach me what operation functions I need to add lock or all
> > operation functions need lock?
> 
> I don't know. You need to answer this question, it's your code. And you know how it's supposed
> to be used etc, etc.
> 
> ...
> 
> > > > +       reg = readl(spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD +
> > > > + reg_off);
> > >
> > > You may create an I/O wrappers to achieve a much better to read code
> > > (no repetition of this arithmetics, etc).
> >
> > I think this is the simplest in-line form:
> 
> No, it's harder to read and easy to mistake what the base and / or offset is used, what
> value, etc.
> 
> > "spp_gchip->gpioxt2_base" is base address.
> > SPPCTL_GPIO_OFF_OD is register offset to base of OD (open-drain) registers.
> > reg_off is register offset to an OD register (SP7021 has 7 OD registers totally).
> >
> > Need I add macros (wrappers) for accessing registers?
> >
> > For example,
> >
> > #define SPPCTL_GPIO_OD(off)     (spp_gchip->gpioxt2_base + SPPCTL_GPIO_OFF_OD + off)
> >
> > reg = readl(SPPCTL_GPIO_OD(reg_off));
> >
> > or
> >
> > writel(reg, SPPCTL_GPIO_OD(reg_off));
> >
> >
> > Mr. Linus Walleij told me that he likes in-line (direct) form, instead
> > of macro because in-line form has better readability (No need to jump
> > to other file for reading macros).
> >
> > Could you please share me with your idea?
> 
> It's an idea that is used in zillions of the drivers (and not via macros).
> 
> static inline spp_readl(struct ... *spp, u32 offset) {
>   return readl(...);
> }
> 
> Same for _writel() and so on.
> 
> ...
> 
> > > Perhaps to show only requested ones? In such case you may use
> > > for_each_requested_gpio() macro.
> >
> > I'd like to keep showing status of all GPIOs.
> > This helps us know status of all GPIOs when debugging hardware issue.
> 
> Since it's a pin control driver, the pin control debug callback can show this. For GPIO
> I would rather not be bothered with not requested pins. But it's your decision.
> 
> ...
> 
> > > > +       gchip->parent =            &pdev->dev;
> > >
> > > > +       gchip->of_node =           pdev->dev.of_node;
> > >
> > > Drop this dup. GPIO library already does it for you.
> >
> > But when I removed the two statements, I found both 'gchip->parent'
> > and 'gchip->of_node' are always 0. No one helps set it.
> >
> > Do I miss doing somethings?
> 
> Yes, I put blank lines around the dup and left context (as a first
> line) to show why the second one is a dup. When you miss something, read the implementation
> code. It's open source at the end!
> 
> ...
> 
> > > > +       dev_dbg(pctldev->dev, "%s(%d, %ld, %d)\n", __func__, pin,
> > > > + *configs, num_configs);
> > >
> > > Noise. Better to consider to add necessary tracepoints to pin control core.
> >
> > What should I do?
> > Should I remove it?
> 
> I wouldn't expect these to be in the production-ready driver. And since you are committing
> to drivers/pinctrl and not to drivers/staging I consider that you are trying to push this
> code as production-ready.
> 
> ...
> 
> > > > +       dev_dbg(pctldev->dev, "%s(%d)\n", __func__, offset);
> > >
> > > Noise. And so on, so on...
> >
> > Should I remove dev_dbg? Or modify it?
> > But it will not print out anything in normal run, only for debugging.
> 
> See above.
> 
> ...
> 
> > > > +       dev_dbg(pctldev->dev, "%s(%d), f_idx: %d, g_idx: %d, freg: %d\n",
> > > > +               __func__, selector, g2fpm.f_idx, g2fpm.g_idx,
> > > > + f->freg);
> > >
> > > No need to use __func__, and especially in case of _dbg / _debug. It
> > > can be enabled at run-time with help of Dynamic Debug.
> >
> > Should I need to remove all __func__ in this driver?
> 
> As the first step, the second one is to remove 90%+ of these messages as I explained above.
> 
> ...
> 
> > > Looking into this rather quite big function why you can't use what pin control core
> provides?
> >
> > No, we cannot use functions pin-control core provides.
> > Please refer to dt-bindings document, "pinctrl/sunplus,sp7021-pinctrl.yaml".
> > We have more explanation there.
> 
> Fine, can you reuse some library functions, etc? Please, consider refactoring to make it
> more readable.
> 
> ...
> 
> > > > +       sppctl->groups_name = devm_kzalloc(&pdev->dev, sppctl_list_funcs_sz *
> > > > +                                          SPPCTL_MAX_GROUPS *
> > > > + sizeof(char *), GFP_KERNEL);
> > >
> > > Ditto. And check some interesting macros in overflow.h.
> >
> > I'll modify code to use devm_kcalloc().
> >
> > I'll modify sizeof() to use type of variable, that is:
> >         sizeof(*sppctl->groups_name)
> >
> > Please teach me what macros should I check?
> > There are many macros in overflow.h.
> 
> Do your homework, it's not me who makes this contribution :-)
> Hint: something about multiplication.
> 
> ...
> 
> > > > +       if (IS_ERR(sppctl->moon2_base)) {
> > > > +               ret = PTR_ERR(sppctl->moon2_base);
> > > > +               goto ioremap_failed;
> > >
> > > What is this for? Use return dev_err_probe() directly.
> >
> > There are 5 devm_ioremap_resource() in this function.
> > To avoid from duplication, goto an error-handling when ioremap failed.
> 
> What error handling? You have the same point which does the same for them, I don't see
> duplication avoidance. See below as well.
> 
> > > > +       }
> 
> ...
> 
> > > > +ioremap_failed:
> > > > +       dev_err_probe(&pdev->dev, ret, "ioremap failed!\n");
> > >
> > > This doesn't bring any value,
> >> besides the fact that API you have used already prints a
> > > message.
> 
> (1)
> 
> > I'll modify code to as shown below (error-handling here):
> >
> > ioremap_failed:
> >         return dev_err_probe(&pdev->dev, ret, "ioremap failed!\n"); }
> >
> > Is this ok?
> 
> No.
> 
> > If not, please teach me how to modify.
> 
> Read again what I wrote in (1).
> 
> > > > +       pdev->dev.platform_data = sppctl;
> > >
> > > Don't we have special setter for this field?
> >
> > I know platform_set_drvdata() function is used to set "dev->driver_data".
> > I cannot find a function to set "dev->platform_data".
> > Please teach me what function should I use to set "dev->platform_data"?
> 
> Ah, now I even may say that the above assignment is simply wrong.
> It's not designed for what you think it's for. Use different ways.
> 
> ...
> 
> > > > +       dev_info(&pdev->dev, "SP7021 PinCtrl by Sunplus/Tibbo Tech.
> > > > + (c)");
> > >
> > > No value.
> >
> > This shows that pinctrl driver has probed successfully.
> > Many drivers show this kind of information.
> 
> And there is no value in this information.
> 
> > Do I need to remove it? Or change to dev_dbg(...).
> 
> Neither in this case.
> 
> Explain the point "why?". In general you have to explain each line of your code "why are
> you doing this or that?".
> 
> ...
> 
> > > > +#ifndef __SPPCTL_H__
> > > > +#define __SPPCTL_H__
> > >
> > > This header misses the inclusions such as bits.h.
> > > And I believe more than that.
> >
> > Some reviewers ask to remove unnecessary header files.
> 
> What do you mean by this in this case. This is a clear miss of bits.h here as you use macros
> from it. Imagine if you include this file somewhere where bits.h hasn't found its mysterious
> ways.
> 
> > I removed all unnecessary header files if compilation completes
> > without any errors or warnings.
> >
> > If compilation has done successfully,
> 
> So what? It doesn't mean the code is bad in one way or another, :-)
> 
> > does it mean all
> > necessary inclusions has included well?
> 
> > Besides, before private header files are included, Linux or system
> > header files will be included.
> > No need extra inclusion here, right?
> 
> See above.
> 
> ...
> 
> > > > +/* FIRST register:
> > > > + *   0: MUX
> > > > + *   1: GPIO/IOP
> > > > + *   2: No change
> > > > + */
> > >
> > > For all comments starting from here and for similar cases elsewhere:
> > >  - why it is not in kernel doc?
> > >  - what the value that add?
> > > (Some of them so cryptic or so obvious)
> >
> > The comment explains usage of 'enum mux_f_mg'
> > The 'enum' is only used in the driver.
> > It helps programmers to remember or look-up the define of the enum.
> > Need we add this kind of comment to kernel doc?
> 
> Why not?
> 
> > > > +static const struct sppctl_grp sp7021grps_spif[] = {
> > > > +       EGRP("SPI_FLASH1", 1, pins_spif1),
> > > > +       EGRP("SPI_FLASH2", 2, pins_spif2)
> > >
> > > Here and everywhere else, leave a comma if it's not a terminator entry.
> >
> > The constant array 'sp7021grps_spif[]' is declared and initialized to
> > have 2 elements. 'EGRP("SPI_FLASH2", 2, pins_spif2)' is the latest
> > element.
> > Why do we need to add 'comma' for the latest element of an array?
> 
> To avoid the churn in the future when it will be expanded. Believe I saw this kind of "proves"
> that this or that won't ever be expanded and then... you may picture what happens.
> 
> > If we add extra comma, the array will have one more element.
> 
> Yes, with touching the "last" one here. Please, add commas where it's not a crystal clear
> a termination (which is not in many cases, usually arrays with NULL entry or enums with
> MAX value at the end).
> 
> --
> With Best Regards,
> Andy Shevchenko

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH v4 2/2] pinctrl: Add driver for Sunplus SP7021
  2021-12-15 12:03       ` Andy Shevchenko
  2021-12-15 15:32         ` Wells Lu 呂芳騰
@ 2021-12-20  6:02         ` Wells Lu 呂芳騰
  1 sibling, 0 replies; 10+ messages in thread
From: Wells Lu 呂芳騰 @ 2021-12-20  6:02 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Wells Lu, Linus Walleij, open list:GPIO SUBSYSTEM,
	Linux Kernel Mailing List, Rob Herring, devicetree,
	linux-arm Mailing List, dvorkin

Hi Andy,


> > > > > +/* FIRST register:
> > > > > + *   0: MUX
> > > > > + *   1: GPIO/IOP
> > > > > + *   2: No change
> > > > > + */
> > > >
> > > > For all comments starting from here and for similar cases elsewhere:
> > > >  - why it is not in kernel doc?
> > > >  - what the value that add?
> > > > (Some of them so cryptic or so obvious)
> > >
> > > The comment explains usage of 'enum mux_f_mg'
> > > The 'enum' is only used in the driver.
> > > It helps programmers to remember or look-up the define of the enum.
> > > Need we add this kind of comment to kernel doc?
> >
> > Why not?

Does the kerenl doc mean dt-binding document?

If not, could you pleae tell me where should I put the kernel document?
Any references for pinctrl drivers?

Can I add more comments for the enum in c file, instead of creating new
kernel doc?



Best regards,

Wells Lu

Smart Computing Program
Home Entertainment Business Unit
Sunplus Technology Co., Ltd.
19, Innovation 1st Road,
Science-based Industrial Park
Hsin-Chu, Taiwan 300
TEL:886-3-5786005 ext. 2580


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-12-20  6:02 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-14 10:53 [PATCH v4 0/2] This is a patch series for pinctrl driver of Sunplus SP7021 SoC Wells Lu
2021-12-14 10:53 ` [PATCH v4 1/2] dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021 Wells Lu
2021-12-14 15:21   ` Rob Herring
2021-12-15 11:10     ` Wells Lu 呂芳騰
2021-12-14 10:53 ` [PATCH v4 2/2] pinctrl: Add driver " Wells Lu
2021-12-14 23:14   ` Andy Shevchenko
2021-12-15  9:40     ` Wells Lu 呂芳騰
2021-12-15 12:03       ` Andy Shevchenko
2021-12-15 15:32         ` Wells Lu 呂芳騰
2021-12-20  6:02         ` Wells Lu 呂芳騰

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).