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
Add dt-bindings header files and documentation for Sunplus SP7021 SoC.
Signed-off-by: Wells Lu <[email protected]>
---
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 <[email protected]>
+ - Wells Lu <[email protected]>
+
+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: [email protected]
S: Maintained
F: drivers/pinctrl/pinctrl-single.c
+PIN CONTROLLER - SUNPLUS / TIBBO
+M: Dvorkin Dmitry <[email protected]>
+M: Wells Lu <[email protected]>
+L: [email protected] (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: [email protected]
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 <[email protected]>
+ */
+
+#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 <[email protected]>
+ */
+
+#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
Add driver for Sunplus SP7021 SoC.
Signed-off-by: Wells Lu <[email protected]>
---
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: [email protected] (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 <[email protected]>");
+MODULE_AUTHOR("Wells Lu <[email protected]>");
+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
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 <[email protected]>
> ---
> 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.
On Tue, Dec 14, 2021 at 5:08 PM Wells Lu <[email protected]> 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
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
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 <[email protected]>
> ---
> Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
Acked-by: Rob Herring <[email protected]>
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 <[email protected]>
> > ---
> > 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.
On Wed, Dec 15, 2021 at 11:40 AM Wells Lu 呂芳騰 <[email protected]> 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
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
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