Skip to contentSkip to conversation

pinctrl: nuvoton: add driver for NPCM7xx

PATCH Superseded Tomer Maimon 3 participants 9 messages Jul 12, 2018 – Jul 29, 2018

Subsystems (4)

v2 of 6 Superseded Latest is v6 →

lore
Share & tools
lore

Tomer Maimon

author maintainer
#0 lore raw

v2 cover pinctrl: nuvoton: add driver for NPCM7xx

This patch set adds pinmux and GPIO controller for the Nuvoton NPCM750/730/715/705 Baseboard Management Controller (BMC).

The Nuvoton BMC NPCM750/730/715/705 Pinmux functions accessible only for pin groups and pinconf parameters available only for individual pins.

The Nuvoton BMC NPCM750/730/715/705 has eight identical GPIO modules, each module has 32 GPIO ports.

Most of the GPIO ports are multiplexed with other system functions.

The NPCM7xx pinctrl and GPIO driver tested on NPCM750 evaluation board.

Addressed comments from:.
- Rob Herring: https://www.spinics.net/lists/kernel/msg2853083.html

Changes since version 1:
- Remove Kconfig MFD_SYSCON dependency.
- Modify setfunc function.
- Modify dt-binding documentation according Rob comments.

Tomer Maimon (2):
dt-binding: pinctrl: Add NPCM7xx pinctrl and GPIO documentation
pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver

 .../bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt   |  216 ++
 drivers/pinctrl/Kconfig                            |    1 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/nuvoton/Kconfig                    |   12 +
 drivers/pinctrl/nuvoton/Makefile                   |    4 +
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c          | 2089 ++++++++++++++++++++
 6 files changed, 2323 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt
 create mode 100644 drivers/pinctrl/nuvoton/Kconfig
 create mode 100644 drivers/pinctrl/nuvoton/Makefile
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
Signature · 1 line
2.14.1
author maintainer
#1 lore raw

PATCH v2 1/2 dt-binding: pinctrl: Add NPCM7xx pinctrl and GPIO documentation

Added device tree binding documentation for Nuvoton BMC NPCM750/730/715/705 pinmux and GPIO controller.

---
 .../bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt   | 216 +++++++++++++++++++++
 1 file changed, 216 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt new file +216 -0
new file mode 100644
index 000000000000..83f4bbac94bb
@@ -0,0 +1,216 @@
+Nuvoton NPCM7XX Pin Controllers
+
+The Nuvoton BMC NPCM7XX Pin Controller multi-function routed through
+the multiplexing block, Each pin supports GPIO functionality (GPIOx)
+and multiple functions that directly connect the pin to different
+hardware blocks.
+
+Required properties:
+- #address-cells : should be 1.
+- #size-cells	 : should be 1.
+- compatible	 : "nuvoton,npcm750-pinctrl" for Poleg NPCM7XX.
+- ranges	 : defines mapping ranges between pin controller node (parent)
+			to GPIO bank node (children).
+
+=== GPIO Bank Subnode ===
+
+The NPCM7XX has 8 GPIO Banks each GPIO bank supports 32 GPIO.
+
+Required GPIO Bank subnode-properties:
+- reg 			: specifies physical base address and size of the GPIO
+				bank registers.
+- gpio-controller	: Marks the device node as a GPIO controller.
+- #gpio-cells		: Must be <2>. The first cell is the gpio pin number
+				and the second cell is used for optional parameters.
+- interrupts		: contain the GPIO bank interrupt with flags for falling edge.
+- gpio-ranges		: defines the range of pins managed by the GPIO bank controller.
+
+For example, GPIO bank subnodes like the following:
+	gpio0: gpio@f0010000 {
+		gpio-controller;
+		#gpio-cells = <2>;
+		reg = <0x0 0x80>;
+		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-ranges = <&pinctrl 0 0 32>;
+	};
+
+=== Pin Mux Subnode ===
+
+- pin: A string containing the name of the pin
+	An array of strings, each string containing the name of a pin.
+	These pin are used for selecting pin configuration.
+
+The following are the list of pins available:
+	"GPIO0/IOX1DI", "GPIO1/IOX1LD",	"GPIO2/IOX1CK", "GPIO3/IOX1D0",
+	"GPIO4/IOX2DI/SMB1DSDA", "GPIO5/IOX2LD/SMB1DSCL", "GPIO6/IOX2CK/SMB2DSDA",
+	"GPIO7/IOX2D0/SMB2DSCL", "GPIO8/LKGPO1", "GPIO9/LKGPO2", "GPIO10/IOXHLD",
+	"GPIO11/IOXHCK", "GPIO12/GSPICK/SMB5BSCL", "GPIO13/GSPIDO/SMB5BSDA",
+	"GPIO14/GSPIDI/SMB5CSCL", "GPIO15/GSPICS/SMB5CSDA", "GPIO16/LKGPO0",
+	"GPIO17/PSPI2DI/SMB4DEN","GPIO18/PSPI2D0/SMB4BSDA", "GPIO19/PSPI2CK/SMB4BSCL",
+	"GPIO20/SMB4CSDA/SMB15SDA", "GPIO21/SMB4CSCL/SMB15SCL", "GPIO22/SMB4DSDA/SMB14SDA",
+	"GPIO23/SMB4DSCL/SMB14SCL", "GPIO24/IOXHDO", "GPIO25/IOXHDI", "GPIO26/SMB5SDA",
+	"GPIO27/SMB5SCL", "GPIO28/SMB4SDA", "GPIO29/SMB4SCL", "GPIO30/SMB3SDA",
+	"GPIO31/SMB3SCL", "GPIO32/nSPI0CS1","SPI0D2", "SPI0D3", "GPIO37/SMB3CSDA",
+	"GPIO38/SMB3CSCL", "GPIO39/SMB3BSDA", "GPIO40/SMB3BSCL", "GPIO41/BSPRXD",
+	"GPO42/BSPTXD/STRAP11", "GPIO43/RXD1/JTMS2/BU1RXD", "GPIO44/nCTS1/JTDI2/BU1CTS",
+	"GPIO45/nDCD1/JTDO2", "GPIO46/nDSR1/JTCK2", "GPIO47/nRI1/JCP_RDY2",
+	"GPIO48/TXD2/BSPTXD", "GPIO49/RXD2/BSPRXD", "GPIO50/nCTS2", "GPO51/nRTS2/STRAP2",
+	"GPIO52/nDCD2", "GPO53/nDTR2_BOUT2/STRAP1", "GPIO54/nDSR2", "GPIO55/nRI2",
+	"GPIO56/R1RXERR", "GPIO57/R1MDC", "GPIO58/R1MDIO", "GPIO59/SMB3DSDA",
+	"GPIO60/SMB3DSCL", "GPO61/nDTR1_BOUT1/STRAP6", "GPO62/nRTST1/STRAP5",
+	"GPO63/TXD1/STRAP4", "GPIO64/FANIN0", "GPIO65/FANIN1", "GPIO66/FANIN2",
+	"GPIO67/FANIN3", "GPIO68/FANIN4", "GPIO69/FANIN5", "GPIO70/FANIN6", "GPIO71/FANIN7",
+	"GPIO72/FANIN8", "GPIO73/FANIN9", "GPIO74/FANIN10", "GPIO75/FANIN11",
+	"GPIO76/FANIN12", "GPIO77/FANIN13","GPIO78/FANIN14", "GPIO79/FANIN15",
+	"GPIO80/PWM0", "GPIO81/PWM1", "GPIO82/PWM2", "GPIO83/PWM3", "GPIO84/R2TXD0",
+	"GPIO85/R2TXD1", "GPIO86/R2TXEN", "GPIO87/R2RXD0", "GPIO88/R2RXD1", "GPIO89/R2CRSDV",
+	"GPIO90/R2RXERR", "GPIO91/R2MDC", "GPIO92/R2MDIO", "GPIO93/GA20/SMB5DSCL",
+	"GPIO94/nKBRST/SMB5DSDA", "GPIO95/nLRESET/nESPIRST", "GPIO96/RG1TXD0",
+	"GPIO97/RG1TXD1", "GPIO98/RG1TXD2", "GPIO99/RG1TXD3","GPIO100/RG1TXC",
+	"GPIO101/RG1TXCTL", "GPIO102/RG1RXD0", "GPIO103/RG1RXD1", "GPIO104/RG1RXD2",
+	"GPIO105/RG1RXD3", "GPIO106/RG1RXC", "GPIO107/RG1RXCTL", "GPIO108/RG1MDC",
+	"GPIO109/RG1MDIO", "GPIO110/RG2TXD0/DDRV0", "GPIO111/RG2TXD1/DDRV1",
+	"GPIO112/RG2TXD2/DDRV2", "GPIO113/RG2TXD3/DDRV3", "GPIO114/SMB0SCL",
+	"GPIO115/SMB0SDA", "GPIO116/SMB1SCL", "GPIO117/SMB1SDA", "GPIO118/SMB2SCL",
+	"GPIO119/SMB2SDA", "GPIO120/SMB2CSDA", "GPIO121/SMB2CSCL", "GPIO122/SMB2BSDA",
+	"GPIO123/SMB2BSCL", "GPIO124/SMB1CSDA", "GPIO125/SMB1CSCL","GPIO126/SMB1BSDA",
+	"GPIO127/SMB1BSCL", "GPIO128/SMB8SCL", "GPIO129/SMB8SDA", "GPIO130/SMB9SCL",
+	"GPIO131/SMB9SDA", "GPIO132/SMB10SCL", "GPIO133/SMB10SDA","GPIO134/SMB11SCL",
+	"GPIO135/SMB11SDA", "GPIO136/SD1DT0", "GPIO137/SD1DT1", "GPIO138/SD1DT2",
+	"GPIO139/SD1DT3", "GPIO140/SD1CLK", "GPIO141/SD1WP", "GPIO142/SD1CMD",
+	"GPIO143/SD1CD/SD1PWR", "GPIO144/PWM4",	"GPIO145/PWM5",	"GPIO146/PWM6",
+	"GPIO147/PWM7",	"GPIO148/MMCDT4", "GPIO149/MMCDT5", "GPIO150/MMCDT6",
+	"GPIO151/MMCDT7", "GPIO152/MMCCLK", "GPIO153/MMCWP", "GPIO154/MMCCMD",
+	"GPIO155/nMMCCD/nMMCRST", "GPIO156/MMCDT0", "GPIO157/MMCDT1", "GPIO158/MMCDT2",
+	"GPIO159/MMCDT3", "GPIO160/CLKOUT/RNGOSCOUT", "GPIO161/nLFRAME/nESPICS",
+	"GPIO162/SERIRQ", "GPIO163/LCLK/ESPICLK", "GPIO164/LAD0/ESPI_IO0",
+	"GPIO165/LAD1/ESPI_IO1", "GPIO166/LAD2/ESPI_IO2", "GPIO167/LAD3/ESPI_IO3",
+	"GPIO168/nCLKRUN/nESPIALERT", "GPIO169/nSCIPME", "GPIO170/nSMI", "GPIO171/SMB6SCL",
+	"GPIO172/SMB6SDA", "GPIO173/SMB7SCL", "GPIO174/SMB7SDA", "GPIO175/PSPI1CK/FANIN19",
+	"GPIO176/PSPI1DO/FANIN18", "GPIO177/PSPI1DI/FANIN17", "GPIO178/R1TXD0",
+	"GPIO179/R1TXD1", "GPIO180/R1TXEN", "GPIO181/R1RXD0", "GPIO182/R1RXD1",
+	"GPIO183/SPI3CK", "GPO184/SPI3D0/STRAP9", "GPO185/SPI3D1/STRAP10",
+	"GPIO186/nSPI3CS0", "GPIO187/nSPI3CS1",	"GPIO188/SPI3D2/nSPI3CS2",
+	"GPIO189/SPI3D3/nSPI3CS3", "GPIO190/nPRD_SMI", "GPIO191", "GPIO192", "GPIO193/R1CRSDV",
+	"GPIO194/SMB0BSCL", "GPIO195/SMB0BSDA", "GPIO196/SMB0CSCL", "GPIO197/SMB0DEN",
+	"GPIO198/SMB0DSDA", "GPIO199/SMB0DSCL", "GPIO200/R2CK", "GPIO201/R1CK",
+	"GPIO202/SMB0CSDA", "GPIO203/FANIN16", "GPIO204/DDC2SCL", "GPIO205/DDC2SDA",
+	"GPIO206/HSYNC2", "GPIO207/VSYNC2", "GPIO208/RG2TXC/DVCK", "GPIO209/RG2TXCTL/DDRV4",
+	"GPIO210/RG2RXD0/DDRV5", "GPIO211/RG2RXD1/DDRV6", "GPIO212/RG2RXD2/DDRV7",
+	"GPIO213/RG2RXD3/DDRV8", "GPIO214/RG2RXC/DDRV9", "GPIO215/RG2RXCTL/DDRV10",
+	"GPIO216/RG2MDC/DDRV11", "GPIO217/RG2MDIO/DVHSYNC", "GPIO218/nWDO1",
+	"GPIO219/nWDO2", "GPIO220/SMB12SCL", "GPIO221/SMB12SDA", "GPIO222/SMB13SCL",
+	"GPIO223/SMB13SDA", "GPIO224/SPIXCK", "GPO225/SPIXD0/STRAP12", "GPO226/SPIXD1/STRAP13",
+	"GPIO227/nSPIXCS0", "GPIO228/nSPIXCS1",	"GPO229/SPIXD2/STRAP3", "GPIO230/SPIXD3",
+	"GPIO231/nCLKREQ", "GPI255/DACOSEL"
+
+Optional Properties:
+ bias-disable, bias-pull-down, bias-pull-up, input-enable,
+ input-disable, output-high, output-low, drive-push-pull,
+ drive-open-drain, input-debounce, slew-rate, drive-strength
+
+ slew-rate valid arguments are:
+				<0> - slow
+				<1> - fast
+ drive-strength valid arguments are:
+				<2> - 2mA
+				<4> - 4mA
+				<8> - 8mA
+				<12> - 12mA
+				<16> - 16mA
+				<24> - 24mA
+
+For example, pinctrl might have pinmux subnodes like the following:
+
+	gpio0_iox1d1_pin: gpio0-iox1d1-pin {
+		pins = "GPIO0/IOX1DI";
+		output-high;
+	};
+	gpio0_iox1ck_pin: gpio0-iox1ck-pin {
+		pins = "GPIO2/IOX1CK";
+		output_high;
+	};
+
+=== Pin Group Subnode ===
+
+Required pin group subnode-properties:
+- groups : A string containing the name of the group to mux.
+- function: A string containing the name of the function to mux to the
+  group.
+
+The following are the list of the available groups and functions :
+	smb0, smb0b, smb0c, smb0d, smb0den, smb1, smb1b, smb1c, smb1d,
+	smb2, smb2b, smb2c, smb2d, smb3, smb3b, smb3c, smb3d, smb4, smb4b,
+	smb4c, smb4d, smb4den, smb5, smb5b, smb5c, smb5d, ga20kbc, smb6,
+	smb7, smb8, smb9, smb10, smb11, smb12, smb13, smb14, smb15, fanin0,
+	fanin1, fanin2, fanin3, fanin4, fanin5, fanin6, fanin7, fanin8,
+	fanin9, fanin10, fanin11 fanin12 fanin13, fanin14, fanin15, faninx,
+	pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, pwm6, pwm7, rg1, rg1mdio, rg2,
+	rg2mdio, ddr, uart1, uart2, bmcuart0a, bmcuart0b, bmcuart1, iox1,
+	iox2, ioxh, gspi, mmc, mmcwp, mmccd, mmcrst, mmc8, r1, r1err, r1md,
+	r2, r2err, r2md, sd1, sd1pwr, wdog1, wdog2, scipme, sci, serirq,
+	jtag2, spix, spixcs1, pspi1, pspi2, ddc, clkreq, clkout, spi3, spi3cs1,
+	spi3quad, spi3cs2, spi3cs3, spi0cs1, lpc, lpcclk, espi, lkgpo0, lkgpo1,
+	lkgpo2, nprd_smi
+
+For example, pinctrl might have group subnodes like the following:
+	r1err_pins: r1err-pins {
+		groups = "r1err";
+		function = "r1err";
+	};
+	r1md_pins: r1md-pins {
+		groups = "r1md";
+		function = "r1md";
+	};
+	r1_pins: r1-pins {
+		groups = "r1";
+		function = "r1";
+	};
+
+Examples
+========
+pinctrl: pinctrl@f0800000 {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "nuvoton,npcm750-pinctrl";
+	ranges = <0 0xf0010000 0x8000>;
+
+	gpio0: gpio@f0010000 {
+		gpio-controller;
+		#gpio-cells = <2>;
+		reg = <0x0 0x80>;
+		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-ranges = <&pinctrl 0 0 32>;
+	};
+
+	....
+
+	gpio7: gpio@f0017000 {
+		gpio-controller;
+		#gpio-cells = <2>;
+		reg = <0x7000 0x80>;
+		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-ranges = <&pinctrl 0 224 32>;
+	};
+
+	gpio0_iox1d1_pin: gpio0-iox1d1-pin {
+		pins = "GPIO0/IOX1DI";
+		output-high;
+	};
+
+	iox1_pins: iox1-pins {
+		groups = "iox1";
+		function = "iox1";
+	};
+	iox2_pins: iox2-pins {
+		groups = "iox2";
+		function = "iox2";
+	};
+
+	....
+
+	clkreq_pins: clkreq-pins {
+		groups = "clkreq";
+		function = "clkreq";
+	};
+};
\ No newline at end of file
Signature · 1 line
2.14.1
maintainer
#2 lore raw

Re: [PATCH v2 1/2] dt-binding: pinctrl: Add NPCM7xx pinctrl and GPIO documentation

Quoted 177 lines · Tomer Maimon

Added device tree binding documentation for Nuvoton BMC NPCM750/730/715/705 pinmux and GPIO controller.

---
 .../bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt   | 216 +++++++++++++++++++++
 1 file changed, 216 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt new file +162 -0
new file mode 100644
index 000000000000..83f4bbac94bb
@@ -0,0 +1,216 @@
+Nuvoton NPCM7XX Pin Controllers
+
+The Nuvoton BMC NPCM7XX Pin Controller multi-function routed through
+the multiplexing block, Each pin supports GPIO functionality (GPIOx)
+and multiple functions that directly connect the pin to different
+hardware blocks.
+
+Required properties:
+- #address-cells : should be 1.
+- #size-cells	 : should be 1.
+- compatible	 : "nuvoton,npcm750-pinctrl" for Poleg NPCM7XX.
+- ranges	 : defines mapping ranges between pin controller node (parent)
+			to GPIO bank node (children).
+
+=== GPIO Bank Subnode ===
+
+The NPCM7XX has 8 GPIO Banks each GPIO bank supports 32 GPIO.
+
+Required GPIO Bank subnode-properties:
+- reg 			: specifies physical base address and size of the GPIO
+				bank registers.
+- gpio-controller	: Marks the device node as a GPIO controller.
+- #gpio-cells		: Must be <2>. The first cell is the gpio pin number
+				and the second cell is used for optional parameters.
+- interrupts		: contain the GPIO bank interrupt with flags for falling edge.
+- gpio-ranges		: defines the range of pins managed by the GPIO bank controller.
+
+For example, GPIO bank subnodes like the following:
+	gpio0: gpio@f0010000 {
+		gpio-controller;
+		#gpio-cells = <2>;
+		reg = <0x0 0x80>;
+		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-ranges = <&pinctrl 0 0 32>;
+	};
+
+=== Pin Mux Subnode ===
+
+- pin: A string containing the name of the pin
+	An array of strings, each string containing the name of a pin.
+	These pin are used for selecting pin configuration.
+
+The following are the list of pins available:
+	"GPIO0/IOX1DI", "GPIO1/IOX1LD",	"GPIO2/IOX1CK", "GPIO3/IOX1D0",
+	"GPIO4/IOX2DI/SMB1DSDA", "GPIO5/IOX2LD/SMB1DSCL", "GPIO6/IOX2CK/SMB2DSDA",
+	"GPIO7/IOX2D0/SMB2DSCL", "GPIO8/LKGPO1", "GPIO9/LKGPO2", "GPIO10/IOXHLD",
+	"GPIO11/IOXHCK", "GPIO12/GSPICK/SMB5BSCL", "GPIO13/GSPIDO/SMB5BSDA",
+	"GPIO14/GSPIDI/SMB5CSCL", "GPIO15/GSPICS/SMB5CSDA", "GPIO16/LKGPO0",
+	"GPIO17/PSPI2DI/SMB4DEN","GPIO18/PSPI2D0/SMB4BSDA", "GPIO19/PSPI2CK/SMB4BSCL",
+	"GPIO20/SMB4CSDA/SMB15SDA", "GPIO21/SMB4CSCL/SMB15SCL", "GPIO22/SMB4DSDA/SMB14SDA",
+	"GPIO23/SMB4DSCL/SMB14SCL", "GPIO24/IOXHDO", "GPIO25/IOXHDI", "GPIO26/SMB5SDA",
+	"GPIO27/SMB5SCL", "GPIO28/SMB4SDA", "GPIO29/SMB4SCL", "GPIO30/SMB3SDA",
+	"GPIO31/SMB3SCL", "GPIO32/nSPI0CS1","SPI0D2", "SPI0D3", "GPIO37/SMB3CSDA",
+	"GPIO38/SMB3CSCL", "GPIO39/SMB3BSDA", "GPIO40/SMB3BSCL", "GPIO41/BSPRXD",
+	"GPO42/BSPTXD/STRAP11", "GPIO43/RXD1/JTMS2/BU1RXD", "GPIO44/nCTS1/JTDI2/BU1CTS",
+	"GPIO45/nDCD1/JTDO2", "GPIO46/nDSR1/JTCK2", "GPIO47/nRI1/JCP_RDY2",
+	"GPIO48/TXD2/BSPTXD", "GPIO49/RXD2/BSPRXD", "GPIO50/nCTS2", "GPO51/nRTS2/STRAP2",
+	"GPIO52/nDCD2", "GPO53/nDTR2_BOUT2/STRAP1", "GPIO54/nDSR2", "GPIO55/nRI2",
+	"GPIO56/R1RXERR", "GPIO57/R1MDC", "GPIO58/R1MDIO", "GPIO59/SMB3DSDA",
+	"GPIO60/SMB3DSCL", "GPO61/nDTR1_BOUT1/STRAP6", "GPO62/nRTST1/STRAP5",
+	"GPO63/TXD1/STRAP4", "GPIO64/FANIN0", "GPIO65/FANIN1", "GPIO66/FANIN2",
+	"GPIO67/FANIN3", "GPIO68/FANIN4", "GPIO69/FANIN5", "GPIO70/FANIN6", "GPIO71/FANIN7",
+	"GPIO72/FANIN8", "GPIO73/FANIN9", "GPIO74/FANIN10", "GPIO75/FANIN11",
+	"GPIO76/FANIN12", "GPIO77/FANIN13","GPIO78/FANIN14", "GPIO79/FANIN15",
+	"GPIO80/PWM0", "GPIO81/PWM1", "GPIO82/PWM2", "GPIO83/PWM3", "GPIO84/R2TXD0",
+	"GPIO85/R2TXD1", "GPIO86/R2TXEN", "GPIO87/R2RXD0", "GPIO88/R2RXD1", "GPIO89/R2CRSDV",
+	"GPIO90/R2RXERR", "GPIO91/R2MDC", "GPIO92/R2MDIO", "GPIO93/GA20/SMB5DSCL",
+	"GPIO94/nKBRST/SMB5DSDA", "GPIO95/nLRESET/nESPIRST", "GPIO96/RG1TXD0",
+	"GPIO97/RG1TXD1", "GPIO98/RG1TXD2", "GPIO99/RG1TXD3","GPIO100/RG1TXC",
+	"GPIO101/RG1TXCTL", "GPIO102/RG1RXD0", "GPIO103/RG1RXD1", "GPIO104/RG1RXD2",
+	"GPIO105/RG1RXD3", "GPIO106/RG1RXC", "GPIO107/RG1RXCTL", "GPIO108/RG1MDC",
+	"GPIO109/RG1MDIO", "GPIO110/RG2TXD0/DDRV0", "GPIO111/RG2TXD1/DDRV1",
+	"GPIO112/RG2TXD2/DDRV2", "GPIO113/RG2TXD3/DDRV3", "GPIO114/SMB0SCL",
+	"GPIO115/SMB0SDA", "GPIO116/SMB1SCL", "GPIO117/SMB1SDA", "GPIO118/SMB2SCL",
+	"GPIO119/SMB2SDA", "GPIO120/SMB2CSDA", "GPIO121/SMB2CSCL", "GPIO122/SMB2BSDA",
+	"GPIO123/SMB2BSCL", "GPIO124/SMB1CSDA", "GPIO125/SMB1CSCL","GPIO126/SMB1BSDA",
+	"GPIO127/SMB1BSCL", "GPIO128/SMB8SCL", "GPIO129/SMB8SDA", "GPIO130/SMB9SCL",
+	"GPIO131/SMB9SDA", "GPIO132/SMB10SCL", "GPIO133/SMB10SDA","GPIO134/SMB11SCL",
+	"GPIO135/SMB11SDA", "GPIO136/SD1DT0", "GPIO137/SD1DT1", "GPIO138/SD1DT2",
+	"GPIO139/SD1DT3", "GPIO140/SD1CLK", "GPIO141/SD1WP", "GPIO142/SD1CMD",
+	"GPIO143/SD1CD/SD1PWR", "GPIO144/PWM4",	"GPIO145/PWM5",	"GPIO146/PWM6",
+	"GPIO147/PWM7",	"GPIO148/MMCDT4", "GPIO149/MMCDT5", "GPIO150/MMCDT6",
+	"GPIO151/MMCDT7", "GPIO152/MMCCLK", "GPIO153/MMCWP", "GPIO154/MMCCMD",
+	"GPIO155/nMMCCD/nMMCRST", "GPIO156/MMCDT0", "GPIO157/MMCDT1", "GPIO158/MMCDT2",
+	"GPIO159/MMCDT3", "GPIO160/CLKOUT/RNGOSCOUT", "GPIO161/nLFRAME/nESPICS",
+	"GPIO162/SERIRQ", "GPIO163/LCLK/ESPICLK", "GPIO164/LAD0/ESPI_IO0",
+	"GPIO165/LAD1/ESPI_IO1", "GPIO166/LAD2/ESPI_IO2", "GPIO167/LAD3/ESPI_IO3",
+	"GPIO168/nCLKRUN/nESPIALERT", "GPIO169/nSCIPME", "GPIO170/nSMI", "GPIO171/SMB6SCL",
+	"GPIO172/SMB6SDA", "GPIO173/SMB7SCL", "GPIO174/SMB7SDA", "GPIO175/PSPI1CK/FANIN19",
+	"GPIO176/PSPI1DO/FANIN18", "GPIO177/PSPI1DI/FANIN17", "GPIO178/R1TXD0",
+	"GPIO179/R1TXD1", "GPIO180/R1TXEN", "GPIO181/R1RXD0", "GPIO182/R1RXD1",
+	"GPIO183/SPI3CK", "GPO184/SPI3D0/STRAP9", "GPO185/SPI3D1/STRAP10",
+	"GPIO186/nSPI3CS0", "GPIO187/nSPI3CS1",	"GPIO188/SPI3D2/nSPI3CS2",
+	"GPIO189/SPI3D3/nSPI3CS3", "GPIO190/nPRD_SMI", "GPIO191", "GPIO192", "GPIO193/R1CRSDV",
+	"GPIO194/SMB0BSCL", "GPIO195/SMB0BSDA", "GPIO196/SMB0CSCL", "GPIO197/SMB0DEN",
+	"GPIO198/SMB0DSDA", "GPIO199/SMB0DSCL", "GPIO200/R2CK", "GPIO201/R1CK",
+	"GPIO202/SMB0CSDA", "GPIO203/FANIN16", "GPIO204/DDC2SCL", "GPIO205/DDC2SDA",
+	"GPIO206/HSYNC2", "GPIO207/VSYNC2", "GPIO208/RG2TXC/DVCK", "GPIO209/RG2TXCTL/DDRV4",
+	"GPIO210/RG2RXD0/DDRV5", "GPIO211/RG2RXD1/DDRV6", "GPIO212/RG2RXD2/DDRV7",
+	"GPIO213/RG2RXD3/DDRV8", "GPIO214/RG2RXC/DDRV9", "GPIO215/RG2RXCTL/DDRV10",
+	"GPIO216/RG2MDC/DDRV11", "GPIO217/RG2MDIO/DVHSYNC", "GPIO218/nWDO1",
+	"GPIO219/nWDO2", "GPIO220/SMB12SCL", "GPIO221/SMB12SDA", "GPIO222/SMB13SCL",
+	"GPIO223/SMB13SDA", "GPIO224/SPIXCK", "GPO225/SPIXD0/STRAP12", "GPO226/SPIXD1/STRAP13",
+	"GPIO227/nSPIXCS0", "GPIO228/nSPIXCS1",	"GPO229/SPIXD2/STRAP3", "GPIO230/SPIXD3",
+	"GPIO231/nCLKREQ", "GPI255/DACOSEL"
+
+Optional Properties:
+ bias-disable, bias-pull-down, bias-pull-up, input-enable,
+ input-disable, output-high, output-low, drive-push-pull,
+ drive-open-drain, input-debounce, slew-rate, drive-strength
+
+ slew-rate valid arguments are:
+				<0> - slow
+				<1> - fast
+ drive-strength valid arguments are:
+				<2> - 2mA
+				<4> - 4mA
+				<8> - 8mA
+				<12> - 12mA
+				<16> - 16mA
+				<24> - 24mA
+
+For example, pinctrl might have pinmux subnodes like the following:
+
+	gpio0_iox1d1_pin: gpio0-iox1d1-pin {
+		pins = "GPIO0/IOX1DI";
+		output-high;
+	};
+	gpio0_iox1ck_pin: gpio0-iox1ck-pin {
+		pins = "GPIO2/IOX1CK";
+		output_high;
+	};
+
+=== Pin Group Subnode ===
+
+Required pin group subnode-properties:
+- groups : A string containing the name of the group to mux.
+- function: A string containing the name of the function to mux to the
+  group.
+
+The following are the list of the available groups and functions :
+	smb0, smb0b, smb0c, smb0d, smb0den, smb1, smb1b, smb1c, smb1d,
+	smb2, smb2b, smb2c, smb2d, smb3, smb3b, smb3c, smb3d, smb4, smb4b,
+	smb4c, smb4d, smb4den, smb5, smb5b, smb5c, smb5d, ga20kbc, smb6,
+	smb7, smb8, smb9, smb10, smb11, smb12, smb13, smb14, smb15, fanin0,
+	fanin1, fanin2, fanin3, fanin4, fanin5, fanin6, fanin7, fanin8,
+	fanin9, fanin10, fanin11 fanin12 fanin13, fanin14, fanin15, faninx,
+	pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, pwm6, pwm7, rg1, rg1mdio, rg2,
+	rg2mdio, ddr, uart1, uart2, bmcuart0a, bmcuart0b, bmcuart1, iox1,
+	iox2, ioxh, gspi, mmc, mmcwp, mmccd, mmcrst, mmc8, r1, r1err, r1md,
+	r2, r2err, r2md, sd1, sd1pwr, wdog1, wdog2, scipme, sci, serirq,
+	jtag2, spix, spixcs1, pspi1, pspi2, ddc, clkreq, clkout, spi3, spi3cs1,
+	spi3quad, spi3cs2, spi3cs3, spi0cs1, lpc, lpcclk, espi, lkgpo0, lkgpo1,
+	lkgpo2, nprd_smi
+
+For example, pinctrl might have group subnodes like the following:
+	r1err_pins: r1err-pins {
+		groups = "r1err";
+		function = "r1err";
+	};
+	r1md_pins: r1md-pins {
+		groups = "r1md";

Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt line 172

Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt new file +10 -0
+		function = "r1md";
+	};
+	r1_pins: r1-pins {
+		groups = "r1";
+		function = "r1";
+	};
+
+Examples
+========
+pinctrl: pinctrl@f0800000 {

reg is missing or this doesn't match ranges.

Quoted 35 lines
Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt new file +35 -0
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "nuvoton,npcm750-pinctrl";
+	ranges = <0 0xf0010000 0x8000>;
+
+	gpio0: gpio@f0010000 {
+		gpio-controller;
+		#gpio-cells = <2>;
+		reg = <0x0 0x80>;
+		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-ranges = <&pinctrl 0 0 32>;
+	};
+
+	....
+
+	gpio7: gpio@f0017000 {
+		gpio-controller;
+		#gpio-cells = <2>;
+		reg = <0x7000 0x80>;
+		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-ranges = <&pinctrl 0 224 32>;
+	};
+
+	gpio0_iox1d1_pin: gpio0-iox1d1-pin {
+		pins = "GPIO0/IOX1DI";
+		output-high;
+	};
+
+	iox1_pins: iox1-pins {
+		groups = "iox1";
+		function = "iox1";
+	};
+	iox2_pins: iox2-pins {
+		groups = "iox2";
+		function = "iox2";

Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt line 216

Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt new file +9 -0
+	};
+
+	....
+
+	clkreq_pins: clkreq-pins {
+		groups = "clkreq";
+		function = "clkreq";
+	};
+};
\ No newline at end of file

^^^

author maintainer
#3 lore raw

Re: [PATCH v2 1/2] dt-binding: pinctrl: Add NPCM7xx pinctrl and GPIO documentation

Hi Rob,

Quoted 250 lines · Rob Herring
Quoted 6 lines · Tomer Maimon

Added device tree binding documentation for Nuvoton BMC NPCM750/730/715/705 pinmux and GPIO controller.

---
 .../bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt   | 216

+++++++++++++++++++++

Quoted 2 lines
 1 file changed, 216 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/nuvoton,

npcm7xx-pinctrl.txt

Review

Quoted 2 lines
(quoted diff) +0 -0

b/Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt

Documentation/devicetree/bindings/pinctrl/nuvoton,

Quoted 4 lines

new file mode 100644
index 000000000000..83f4bbac94bb

Documentation/devicetree/bindings/pinctrl/nuvoton, new file +0 -0

npcm7xx-pinctrl.txt

Documentation/devicetree/bindings/pinctrl/nuvoton, line 12

Quoted 13 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +12 -0
@@ -0,0 +1,216 @@
+Nuvoton NPCM7XX Pin Controllers
+
+The Nuvoton BMC NPCM7XX Pin Controller multi-function routed through
+the multiplexing block, Each pin supports GPIO functionality (GPIOx)
+and multiple functions that directly connect the pin to different
+hardware blocks.
+
+Required properties:
+- #address-cells : should be 1.
+- #size-cells         : should be 1.
+- compatible  : "nuvoton,npcm750-pinctrl" for Poleg NPCM7XX.
+- ranges      : defines mapping ranges between pin controller node

(parent)

Documentation/devicetree/bindings/pinctrl/nuvoton, line 20

Quoted 8 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +8 -0
+                     to GPIO bank node (children).
+
+=== GPIO Bank Subnode ===
+
+The NPCM7XX has 8 GPIO Banks each GPIO bank supports 32 GPIO.
+
+Required GPIO Bank subnode-properties:
+- reg                        : specifies physical base address and size

of the GPIO

Documentation/devicetree/bindings/pinctrl/nuvoton, line 23

Quoted 3 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +3 -0
+                             bank registers.
+- gpio-controller    : Marks the device node as a GPIO controller.
+- #gpio-cells                : Must be <2>. The first cell is the gpio

pin number

Documentation/devicetree/bindings/pinctrl/nuvoton, line 24

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+                             and the second cell is used for optional

parameters.

Documentation/devicetree/bindings/pinctrl/nuvoton, line 25

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+- interrupts         : contain the GPIO bank interrupt with flags for

falling edge.

Documentation/devicetree/bindings/pinctrl/nuvoton, line 26

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+- gpio-ranges                : defines the range of pins managed by the

GPIO bank controller.

Quoted 9 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +9 -0
+
+For example, GPIO bank subnodes like the following:
+     gpio0: gpio@f0010000 {
+             gpio-controller;
+             #gpio-cells = <2>;
+             reg = <0x0 0x80>;
+             interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+             gpio-ranges = <&pinctrl 0 0 32>;
+     };

Documentation/devicetree/bindings/pinctrl/nuvoton, line 45

Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +10 -0
+
+=== Pin Mux Subnode ===
+
+- pin: A string containing the name of the pin
+     An array of strings, each string containing the name of a pin.
+     These pin are used for selecting pin configuration.
+
+The following are the list of pins available:
+     "GPIO0/IOX1DI", "GPIO1/IOX1LD", "GPIO2/IOX1CK", "GPIO3/IOX1D0",
+     "GPIO4/IOX2DI/SMB1DSDA", "GPIO5/IOX2LD/SMB1DSCL",

"GPIO6/IOX2CK/SMB2DSDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 46

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO7/IOX2D0/SMB2DSCL", "GPIO8/LKGPO1", "GPIO9/LKGPO2",

"GPIO10/IOXHLD",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 47

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO11/IOXHCK", "GPIO12/GSPICK/SMB5BSCL",

"GPIO13/GSPIDO/SMB5BSDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 48

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO14/GSPIDI/SMB5CSCL", "GPIO15/GSPICS/SMB5CSDA",

"GPIO16/LKGPO0",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 49

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO17/PSPI2DI/SMB4DEN","GPIO18/PSPI2D0/SMB4BSDA",

"GPIO19/PSPI2CK/SMB4BSCL",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 50

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO20/SMB4CSDA/SMB15SDA", "GPIO21/SMB4CSCL/SMB15SCL",

"GPIO22/SMB4DSDA/SMB14SDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 51

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO23/SMB4DSCL/SMB14SCL", "GPIO24/IOXHDO", "GPIO25/IOXHDI",

"GPIO26/SMB5SDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 52

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO27/SMB5SCL", "GPIO28/SMB4SDA", "GPIO29/SMB4SCL",

"GPIO30/SMB3SDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 53

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO31/SMB3SCL", "GPIO32/nSPI0CS1","SPI0D2", "SPI0D3",

"GPIO37/SMB3CSDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 54

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO38/SMB3CSCL", "GPIO39/SMB3BSDA", "GPIO40/SMB3BSCL",

"GPIO41/BSPRXD",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 55

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPO42/BSPTXD/STRAP11", "GPIO43/RXD1/JTMS2/BU1RXD",

"GPIO44/nCTS1/JTDI2/BU1CTS",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 57

Quoted 2 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +2 -0
+     "GPIO45/nDCD1/JTDO2", "GPIO46/nDSR1/JTCK2", "GPIO47/nRI1/JCP_RDY2",
+     "GPIO48/TXD2/BSPTXD", "GPIO49/RXD2/BSPRXD", "GPIO50/nCTS2",

"GPO51/nRTS2/STRAP2",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 58

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO52/nDCD2", "GPO53/nDTR2_BOUT2/STRAP1", "GPIO54/nDSR2",

"GPIO55/nRI2",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 59

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO56/R1RXERR", "GPIO57/R1MDC", "GPIO58/R1MDIO",

"GPIO59/SMB3DSDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 60

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO60/SMB3DSCL", "GPO61/nDTR1_BOUT1/STRAP6",

"GPO62/nRTST1/STRAP5",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 61

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPO63/TXD1/STRAP4", "GPIO64/FANIN0", "GPIO65/FANIN1",

"GPIO66/FANIN2",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 62

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO67/FANIN3", "GPIO68/FANIN4", "GPIO69/FANIN5",

"GPIO70/FANIN6", "GPIO71/FANIN7",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 63

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO72/FANIN8", "GPIO73/FANIN9", "GPIO74/FANIN10",

"GPIO75/FANIN11",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 64

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO76/FANIN12", "GPIO77/FANIN13","GPIO78/FANIN14",

"GPIO79/FANIN15",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 65

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO80/PWM0", "GPIO81/PWM1", "GPIO82/PWM2", "GPIO83/PWM3",

"GPIO84/R2TXD0",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 66

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO85/R2TXD1", "GPIO86/R2TXEN", "GPIO87/R2RXD0",

"GPIO88/R2RXD1", "GPIO89/R2CRSDV",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 67

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO90/R2RXERR", "GPIO91/R2MDC", "GPIO92/R2MDIO",

"GPIO93/GA20/SMB5DSCL",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 68

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO94/nKBRST/SMB5DSDA", "GPIO95/nLRESET/nESPIRST",

"GPIO96/RG1TXD0",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 69

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO97/RG1TXD1", "GPIO98/RG1TXD2", "GPIO99/RG1TXD3","GPIO100/

RG1TXC",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 70

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO101/RG1TXCTL", "GPIO102/RG1RXD0", "GPIO103/RG1RXD1",

"GPIO104/RG1RXD2",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 71

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO105/RG1RXD3", "GPIO106/RG1RXC", "GPIO107/RG1RXCTL",

"GPIO108/RG1MDC",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 72

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO109/RG1MDIO", "GPIO110/RG2TXD0/DDRV0",

"GPIO111/RG2TXD1/DDRV1",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 73

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO112/RG2TXD2/DDRV2", "GPIO113/RG2TXD3/DDRV3",

"GPIO114/SMB0SCL",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 74

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO115/SMB0SDA", "GPIO116/SMB1SCL", "GPIO117/SMB1SDA",

"GPIO118/SMB2SCL",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 75

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO119/SMB2SDA", "GPIO120/SMB2CSDA", "GPIO121/SMB2CSCL",

"GPIO122/SMB2BSDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 76

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO123/SMB2BSCL", "GPIO124/SMB1CSDA",

"GPIO125/SMB1CSCL","GPIO126/SMB1BSDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 77

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO127/SMB1BSCL", "GPIO128/SMB8SCL", "GPIO129/SMB8SDA",

"GPIO130/SMB9SCL",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 78

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO131/SMB9SDA", "GPIO132/SMB10SCL", "GPIO133/SMB10SDA","GPIO134/

SMB11SCL",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 79

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO135/SMB11SDA", "GPIO136/SD1DT0", "GPIO137/SD1DT1",

"GPIO138/SD1DT2",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 80

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO139/SD1DT3", "GPIO140/SD1CLK", "GPIO141/SD1WP",

"GPIO142/SD1CMD",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 81

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO143/SD1CD/SD1PWR", "GPIO144/PWM4", "GPIO145/PWM5",

"GPIO146/PWM6",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 82

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO147/PWM7", "GPIO148/MMCDT4", "GPIO149/MMCDT5",

"GPIO150/MMCDT6",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 83

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO151/MMCDT7", "GPIO152/MMCCLK", "GPIO153/MMCWP",

"GPIO154/MMCCMD",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 84

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO155/nMMCCD/nMMCRST", "GPIO156/MMCDT0", "GPIO157/MMCDT1",

"GPIO158/MMCDT2",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 85

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO159/MMCDT3", "GPIO160/CLKOUT/RNGOSCOUT",

"GPIO161/nLFRAME/nESPICS",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 87

Quoted 2 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +2 -0
+     "GPIO162/SERIRQ", "GPIO163/LCLK/ESPICLK", "GPIO164/LAD0/ESPI_IO0",
+     "GPIO165/LAD1/ESPI_IO1", "GPIO166/LAD2/ESPI_IO2",

"GPIO167/LAD3/ESPI_IO3",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 88

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO168/nCLKRUN/nESPIALERT", "GPIO169/nSCIPME", "GPIO170/nSMI",

"GPIO171/SMB6SCL",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 89

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO172/SMB6SDA", "GPIO173/SMB7SCL", "GPIO174/SMB7SDA",

"GPIO175/PSPI1CK/FANIN19",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 90

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO176/PSPI1DO/FANIN18", "GPIO177/PSPI1DI/FANIN17",

"GPIO178/R1TXD0",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 91

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO179/R1TXD1", "GPIO180/R1TXEN", "GPIO181/R1RXD0",

"GPIO182/R1RXD1",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 94

Quoted 3 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +3 -0
+     "GPIO183/SPI3CK", "GPO184/SPI3D0/STRAP9", "GPO185/SPI3D1/STRAP10",
+     "GPIO186/nSPI3CS0", "GPIO187/nSPI3CS1", "GPIO188/SPI3D2/nSPI3CS2",
+     "GPIO189/SPI3D3/nSPI3CS3", "GPIO190/nPRD_SMI", "GPIO191",

"GPIO192", "GPIO193/R1CRSDV",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 95

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO194/SMB0BSCL", "GPIO195/SMB0BSDA", "GPIO196/SMB0CSCL",

"GPIO197/SMB0DEN",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 96

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO198/SMB0DSDA", "GPIO199/SMB0DSCL", "GPIO200/R2CK",

"GPIO201/R1CK",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 97

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO202/SMB0CSDA", "GPIO203/FANIN16", "GPIO204/DDC2SCL",

"GPIO205/DDC2SDA",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 98

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO206/HSYNC2", "GPIO207/VSYNC2", "GPIO208/RG2TXC/DVCK",

"GPIO209/RG2TXCTL/DDRV4",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 99

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO210/RG2RXD0/DDRV5", "GPIO211/RG2RXD1/DDRV6",

"GPIO212/RG2RXD2/DDRV7",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 100

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO213/RG2RXD3/DDRV8", "GPIO214/RG2RXC/DDRV9",

"GPIO215/RG2RXCTL/DDRV10",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 101

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO216/RG2MDC/DDRV11", "GPIO217/RG2MDIO/DVHSYNC",

"GPIO218/nWDO1",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 102

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO219/nWDO2", "GPIO220/SMB12SCL", "GPIO221/SMB12SDA",

"GPIO222/SMB13SCL",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 103

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO223/SMB13SDA", "GPIO224/SPIXCK", "GPO225/SPIXD0/STRAP12",

"GPO226/SPIXD1/STRAP13",

Documentation/devicetree/bindings/pinctrl/nuvoton, line 104

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     "GPIO227/nSPIXCS0", "GPIO228/nSPIXCS1", "GPO229/SPIXD2/STRAP3",

"GPIO230/SPIXD3",

Quoted 38 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +38 -0
+     "GPIO231/nCLKREQ", "GPI255/DACOSEL"
+
+Optional Properties:
+ bias-disable, bias-pull-down, bias-pull-up, input-enable,
+ input-disable, output-high, output-low, drive-push-pull,
+ drive-open-drain, input-debounce, slew-rate, drive-strength
+
+ slew-rate valid arguments are:
+                             <0> - slow
+                             <1> - fast
+ drive-strength valid arguments are:
+                             <2> - 2mA
+                             <4> - 4mA
+                             <8> - 8mA
+                             <12> - 12mA
+                             <16> - 16mA
+                             <24> - 24mA
+
+For example, pinctrl might have pinmux subnodes like the following:
+
+     gpio0_iox1d1_pin: gpio0-iox1d1-pin {
+             pins = "GPIO0/IOX1DI";
+             output-high;
+     };
+     gpio0_iox1ck_pin: gpio0-iox1ck-pin {
+             pins = "GPIO2/IOX1CK";
+             output_high;
+     };
+
+=== Pin Group Subnode ===
+
+Required pin group subnode-properties:
+- groups : A string containing the name of the group to mux.
+- function: A string containing the name of the function to mux to the
+  group.
+
+The following are the list of the available groups and functions :
+     smb0, smb0b, smb0c, smb0d, smb0den, smb1, smb1b, smb1c, smb1d,

Documentation/devicetree/bindings/pinctrl/nuvoton, line 152

Quoted 10 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +10 -0
+     smb2, smb2b, smb2c, smb2d, smb3, smb3b, smb3c, smb3d, smb4, smb4b,
+     smb4c, smb4d, smb4den, smb5, smb5b, smb5c, smb5d, ga20kbc, smb6,
+     smb7, smb8, smb9, smb10, smb11, smb12, smb13, smb14, smb15, fanin0,
+     fanin1, fanin2, fanin3, fanin4, fanin5, fanin6, fanin7, fanin8,
+     fanin9, fanin10, fanin11 fanin12 fanin13, fanin14, fanin15, faninx,
+     pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, pwm6, pwm7, rg1, rg1mdio, rg2,
+     rg2mdio, ddr, uart1, uart2, bmcuart0a, bmcuart0b, bmcuart1, iox1,
+     iox2, ioxh, gspi, mmc, mmcwp, mmccd, mmcrst, mmc8, r1, r1err, r1md,
+     r2, r2err, r2md, sd1, sd1pwr, wdog1, wdog2, scipme, sci, serirq,
+     jtag2, spix, spixcs1, pspi1, pspi2, ddc, clkreq, clkout, spi3,

spi3cs1,

Documentation/devicetree/bindings/pinctrl/nuvoton, line 153

Quoted 1 line
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +1 -0
+     spi3quad, spi3cs2, spi3cs3, spi0cs1, lpc, lpcclk, espi, lkgpo0,

lkgpo1,

Quoted 13 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +13 -0
+     lkgpo2, nprd_smi
+
+For example, pinctrl might have group subnodes like the following:
+     r1err_pins: r1err-pins {
+             groups = "r1err";
+             function = "r1err";
+     };
+     r1md_pins: r1md-pins {
+             groups = "r1md";
+             function = "r1md";
+     };
+     r1_pins: r1-pins {
+             groups = "r1";
Quoted 9 lines

Documentation/devicetree/bindings/pinctrl/nuvoton, line 172

Quoted 6 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +6 -0
+             function = "r1";
+     };
+
+Examples
+========
+pinctrl: pinctrl@f0800000 {

reg is missing or this doesn't match ranges.

the Control of the Pinmux is through the GCR (General control register), and because the GCR controlling also on other things
in the BMC we have a separate node for the GCR and it handled by regmap. GCR node in our device tree:

                gcr: gcr@800000 {

                        compatible = "nuvoton,npcm750-gcr", "syscon",
                                "simple-mfd";
                        reg = <0x800000 0x1000>;
                };

The address of the GCR is f0800000 this is why the pinctrl name pinctrl@f0800000 please let me know if it is better to modify it to the GPIO address.

the ranges is address GPIO ranges

Quoted 39 lines
Quoted 39 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +39 -0
+     #address-cells = <1>;
+     #size-cells = <1>;
+     compatible = "nuvoton,npcm750-pinctrl";
+     ranges = <0 0xf0010000 0x8000>;
+
+     gpio0: gpio@f0010000 {
+             gpio-controller;
+             #gpio-cells = <2>;
+             reg = <0x0 0x80>;
+             interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+             gpio-ranges = <&pinctrl 0 0 32>;
+     };
+
+     ....
+
+     gpio7: gpio@f0017000 {
+             gpio-controller;
+             #gpio-cells = <2>;
+             reg = <0x7000 0x80>;
+             interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+             gpio-ranges = <&pinctrl 0 224 32>;
+     };
+
+     gpio0_iox1d1_pin: gpio0-iox1d1-pin {
+             pins = "GPIO0/IOX1DI";
+             output-high;
+     };
+
+     iox1_pins: iox1-pins {
+             groups = "iox1";
+             function = "iox1";
+     };
+     iox2_pins: iox2-pins {
+             groups = "iox2";
+             function = "iox2";
+     };
+
+     ....
+
Quoted 9 lines

Documentation/devicetree/bindings/pinctrl/nuvoton, line 216

Quoted 6 lines
Documentation/devicetree/bindings/pinctrl/nuvoton, new file +5 -0
+     clkreq_pins: clkreq-pins {
+             groups = "clkreq";
+             function = "clkreq";
+     };
+};
\ No newline at end of file

^^^

Thanks,

Tomer

author maintainer
#4 lore raw

PATCH v2 2/2 pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver

In reply to Tomer Maimon

Add Nuvoton BMC NPCM750/730/715/705 Pinmux and
GPIO controller driver.

---
 drivers/pinctrl/Kconfig                   |    1 +
 drivers/pinctrl/Makefile                  |    1 +
 drivers/pinctrl/nuvoton/Kconfig           |   12 +
 drivers/pinctrl/nuvoton/Makefile          |    4 +
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 2089 +++++++++++++++++++++++++++++
 5 files changed, 2107 insertions(+)
 create mode 100644 drivers/pinctrl/nuvoton/Kconfig
 create mode 100644 drivers/pinctrl/nuvoton/Makefile
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
drivers/pinctrl/Kconfig +1 -0
index dd50371225bc..c966d94c2320 100644
@@ -345,6 +345,7 @@ source "drivers/pinctrl/freescale/Kconfig"
 source "drivers/pinctrl/intel/Kconfig"
 source "drivers/pinctrl/mvebu/Kconfig"
 source "drivers/pinctrl/nomadik/Kconfig"
+source "drivers/pinctrl/nuvoton/Kconfig"
 source "drivers/pinctrl/pxa/Kconfig"
 source "drivers/pinctrl/qcom/Kconfig"
 source "drivers/pinctrl/samsung/Kconfig"
drivers/pinctrl/Makefile +1 -0
index de40863e7297..1797c09c8981 100644
@@ -51,6 +51,7 @@ obj-y				+= freescale/
 obj-$(CONFIG_X86)		+= intel/
 obj-y				+= mvebu/
 obj-y				+= nomadik/
+obj-$(CONFIG_ARCH_NPCM7XX)	+= nuvoton/
 obj-$(CONFIG_PINCTRL_PXA)	+= pxa/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
 obj-$(CONFIG_PINCTRL_SAMSUNG)	+= samsung/
drivers/pinctrl/nuvoton/Kconfig new file +12 -0
new file mode 100644
index 000000000000..70542c16b656
@@ -0,0 +1,12 @@
+config PINCTRL_NPCM7XX
+	bool "Pinctrl and GPIO driver for Nuvoton NPCM7XX"
+	depends on (ARCH_NPCM7XX || COMPILE_TEST) && OF
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	select GPIOLIB
+	select GPIOLIB_IRQCHIP
+	help
+	  Say Y here to enable pin controller and GPIO support
+	  for Nuvoton NPCM750/730/715/705 SoCs.
+
drivers/pinctrl/nuvoton/Makefile new file +4 -0
new file mode 100644
index 000000000000..886d00784cef
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+# Nuvoton pinctrl support
+
+obj-$(CONFIG_PINCTRL_NPCM7XX)	+= pinctrl-npcm7xx.o
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +2089 -0

2,089 lines not on this page · raw message

Signature · 1 line
2.14.1
#5 lore raw

Re: [PATCH v2 2/2] pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver

Quoted 4 lines · Tomer Maimon

Add Nuvoton BMC NPCM750/730/715/705 Pinmux and
GPIO controller driver.

(...)

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 6

Quoted 8 lines

+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +6 -0
@@ -0,0 +1,2089 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2016-2018 Nuvoton Technology corporation.
+// Copyright (c) 2016, Dell Inc
+
+#include <linux/device.h>
+#include <linux/gpio.h>

As this is a driver you should only include <linux/gpio/driver.h>

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 9

Quoted 3 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +3 -0
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/syscon.h>

If you need syscon then the driver should select or depend on MFD_SYSCON in Kconfig.

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 13

Quoted 4 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +4 -0
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>

Do you really need this include?

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 76

Quoted 2 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +2 -0
+/* Structure for register banks */
+struct NPCM7XX_GPIO {

Can we have this lowercase? Please?

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 85

Quoted 9 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +9 -0
+       void __iomem            *base;
+       struct gpio_chip        gc;
+       int                     irqbase;
+       int                     irq;
+       spinlock_t              lock;
+       void                    *priv;
+       struct irq_chip         irq_chip;
+       u32                     pinctrl_id;
+};

So each GPIO bank has its own gpio chip and register base, that is NICE! Because then it looks like you can select GPIO_GENERIC and use the MMIO GPIO helper library to handle the registers. Let's look into that option!

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 91

Quoted 5 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +5 -0
+struct NPCM7xx_pinctrl {
+       struct pinctrl_dev      *pctldev;
+       struct device           *dev;
+       struct NPCM7XX_GPIO     gpio_bank[NPCM7XX_GPIO_BANK_NUM];
+       struct irq_domain       *domain;

I wonder why the pin controller needs and IRQ domain but I keep reading the code and I might find out...

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 102

Quoted 6 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +6 -0
+enum operand {
+       op_set,
+       op_getbit,
+       op_setbit,
+       op_clrbit,
+};

This looks complicated. I suspect you can use GPIO_GENERIC to set/get and clear bits in the register(s).

Quoted 18 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +18 -0
+/* Perform locked bit operations on GPIO registers */
+static int gpio_bitop(struct NPCM7XX_GPIO *bank, int op, unsigned int offset,
+                     int reg)
+{
+       unsigned long flags;
+       u32 mask, val;
+
+       mask = (1L << offset);
+       spin_lock_irqsave(&bank->lock, flags);
+       switch (op) {
+       case op_set:
+               iowrite32(mask, bank->base + reg);
+               break;
+       case op_getbit:
+               mask &= ioread32(bank->base + reg);
+               break;
+       case op_setbit:
+               val = ioread32(bank->base + reg);

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 133

Quoted 10 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +10 -0
+               iowrite32(val | mask, bank->base + reg);
+               break;
+       case op_clrbit:
+               val = ioread32(bank->base + reg);
+               iowrite32(val & (~mask), bank->base + reg);
+               break;
+       }
+       spin_unlock_irqrestore(&bank->lock, flags);
+       return !!mask;
+}

This is essentially a reimplementation of drivers/gpio/gpio-mmio.c (GPIO_GENERIC, also using a spinlock to protect the registers) so let's use that instead :)

There are drivers already that reuse the spinlock inside the generic GPIO chip to protect their other registers like for IRQ registers.

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 185

Quoted 12 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +12 -0
+static int npcmgpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+       struct NPCM7XX_GPIO *bank = gpiochip_get_data(chip);
+       u32 oe, ie;
+
+       /* Get Input & Output state */
+       ie = gpio_bitop(bank, op_getbit, offset, NPCM7XX_GP_N_IEM);
+       oe = gpio_bitop(bank, op_getbit, offset, NPCM7XX_GP_N_OE);
+       if (ie && !oe)
+               return GPIOF_DIR_IN;
+       else if (oe && !ie)
+               return GPIOF_DIR_OUT;

These are consumer flags and should not be used in drivers. Use plain 0/1 instead.

Anyways the problem goes away with GPIO_GENERIC.

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 194

Quoted 4 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +4 -0
+static int npcmgpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+       return pinctrl_gpio_direction_input(offset + chip->base);
+}

It's a bit tricksy to get this to work with GPIO_GENERIC.

After calling bgpio_init() you need to overwrite the assigned .direction_input handler with this and then direct back to the one assigned by GPIO_GENERIC.

Something like this:

1. Add two indirection pointers to the npcm7xx_gpio state container:

struct npcm7xx_gpio {
     (...)
      int (*direction_input)(struct gpio_chip *chip, unsigned offset);
      int (*direction_output)(struct gpio_chip *chip, unsigned offset,
int value);
     (...)
};

2. Save the pointers

struct npcm7xx_gpio *npcm;

bgpio_init( ... register setup ...) npcm->direction_input = npcm->gc.direction_input; npcm->direction_output = npcm->gc.direction_output; npcm->gc.direction_input = npcmgpio_direction_input; npcm->gc.direction_output = npcmgpio_direction_output;

3. Modify the functions like that:

static int npcmgpio_direction_input(struct gpio_chip *chip, unsigned int offset)

{
    struct npcm7xx_gpio *npcm = gpiochip_get_data(chip);
    int ret;

    ret = pinctrl_gpio_direction_input(offset + chip->base);
    if (ret)
        return ret;
    return npcm->direction_input(chip);
}

I'm sure you get the idea... if you think we can modify gpio-mmio to be more helpful with this, suggestions are welcome!

Quoted 7 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +7 -0
+/* Set GPIO to Output with initial value */
+static int npcmgpio_direction_output(struct gpio_chip *chip,
+                                    unsigned int offset, int value)
+{
+       struct NPCM7XX_GPIO *bank = gpiochip_get_data(chip);
+
+       dev_dbg(chip->parent, "gpio_direction_output: offset%d = %x\n", offset,

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 212

Quoted 10 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +10 -0
+               value);
+
+       /* Check if we're enabled as an interrupt.. */
+       if (gpio_bitop(bank, op_getbit, offset, NPCM7XX_GP_N_EVEN) &&
+           gpio_bitop(bank, op_getbit, offset, NPCM7XX_GP_N_IEM)) {
+               dev_dbg(chip->parent,
+                       "gpio_direction_output: IRQ enabled on offset%d\n",
+                       offset);
+               return -EINVAL;
+       }

This should not be necessary as you are using GPIOLIB_IRQCHIP, which locks the GPIO for interrupt and disallows this to happen.

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 253

Quoted 11 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +11 -0
+static int npcmgpio_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+       dev_dbg(chip->parent, "gpio_request: offset%d\n", offset);
+       return pinctrl_gpio_request(offset + chip->base);
+}
+
+static void npcmgpio_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+       dev_dbg(chip->parent, "gpio_free: offset%d\n", offset);
+       pinctrl_gpio_free(offset + chip->base);
+}

This needs the same pattern as the direction functions above, then you can use GPIO_GENERIC (mmio).

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 368

Quoted 9 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +9 -0
+static unsigned int npcmgpio_irq_startup(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = d->hwirq;
+
+       /* active-high, input, clear interrupt, enable interrupt */
+       dev_dbg(d->chip->parent_device, "startup: %u.%u\n", gpio, d->irq);
+       npcmgpio_direction_output(gc, gpio, 1);
+       npcmgpio_direction_input(gc, gpio);

Interesting dance. So it is required to set the line to 1 and then switch to input?

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 382

Quoted 8 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +8 -0
+static struct irq_chip npcmgpio_irqchip = {
+       .name = "NPCM7XX-GPIO-IRQ",
+       .irq_ack = npcmgpio_irq_ack,
+       .irq_unmask = npcmgpio_irq_unmask,
+       .irq_mask = npcmgpio_irq_mask,
+       .irq_set_type = npcmgpio_set_irq_type,
+       .irq_startup = npcmgpio_irq_startup,
+};

This code is looking good BTW.

The patch in my inbox just ends in the middle of everything, I wonder why :( suspect the new gmail interface I'm using.

Anyways: the pointers above should keep you busy for the next iteration of the patch, the pin control part seems pretty straight-forward.

Yours,
Linus Walleij

author maintainer
#6 lore raw

Re: [PATCH v2 2/2] pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver

Hi Linus,

Thanks a lot for your comments.

Sorry for my late reply, I was on vacation.

The last days I have been working to move NPCM pinctrl GPIO to GENERIC GPIO, most of the work have been done but I had the some issue.

I initialize bgpio as follow:

                        ret = bgpio_init(&pctrl->gpio_bank[id].gc,
                                         pctrl->dev, 4,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_DIN,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_DOUT,
                                         NULL,
                                         NULL,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_IEM,
                                         BGPIOF_READ_OUTPUT_REG_SET);

After doing it, the directions functions I used are:
bgpio_dir_out_inv, bgpio_dir_in_inv, bgpio_get_dir_inv

and the I/O get function is bgpio_get_set

By using inv directions:

direction out = 0 (gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio))

direction in = 1 (gc->bgpio_dir |= bgpio_line2mask(gc, gpio))

The problem occur when reading the GPIO value from bgpio_get_set function, because the directions value are inverse it reading the wrong I/O registers

For direction out it reading dat register (instead of set register)

For direction in it calling set register (instead of dat register)

	if (gc->bgpio_dir & pinmask)
		return !!(gc->read_reg(gc->reg_set) & pinmask);
	else
		return !!(gc->read_reg(gc->reg_dat) & pinmask);

the same issue occur at bgpio_get_set_multiple function.

Maybe in bgpio_dir parameter direction out should be in both cases 1 and direction in = 0.

for now i did a local fix in the npcm pinctrl driver by setting bgpio_dir parameters as direction out = 1 and direction in = 0.

Thanks a lot,

Tomer

Quoted 255 lines · Linus Walleij
Quoted 4 lines · Tomer Maimon

Add Nuvoton BMC NPCM750/730/715/705 Pinmux and
GPIO controller driver.

(...)

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 6

Quoted 8 lines

+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +6 -0
@@ -0,0 +1,2089 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2016-2018 Nuvoton Technology corporation.
+// Copyright (c) 2016, Dell Inc
+
+#include <linux/device.h>
+#include <linux/gpio.h>

As this is a driver you should only include <linux/gpio/driver.h>

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 9

Quoted 3 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +3 -0
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/syscon.h>

If you need syscon then the driver should select or depend on MFD_SYSCON in Kconfig.

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 13

Quoted 4 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +4 -0
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>

Do you really need this include?

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 76

Quoted 2 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +2 -0
+/* Structure for register banks */
+struct NPCM7XX_GPIO {

Can we have this lowercase? Please?

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 85

Quoted 9 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +9 -0
+       void __iomem            *base;
+       struct gpio_chip        gc;
+       int                     irqbase;
+       int                     irq;
+       spinlock_t              lock;
+       void                    *priv;
+       struct irq_chip         irq_chip;
+       u32                     pinctrl_id;
+};

So each GPIO bank has its own gpio chip and register base, that is NICE! Because then it looks like you can select GPIO_GENERIC and use the MMIO GPIO helper library to handle the registers. Let's look into that option!

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 91

Quoted 5 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +5 -0
+struct NPCM7xx_pinctrl {
+       struct pinctrl_dev      *pctldev;
+       struct device           *dev;
+       struct NPCM7XX_GPIO     gpio_bank[NPCM7XX_GPIO_BANK_NUM];
+       struct irq_domain       *domain;

I wonder why the pin controller needs and IRQ domain but I keep reading the code and I might find out...

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 102

Quoted 6 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +6 -0
+enum operand {
+       op_set,
+       op_getbit,
+       op_setbit,
+       op_clrbit,
+};

This looks complicated. I suspect you can use GPIO_GENERIC to set/get and clear bits in the register(s).

Review line 37

Quoted 2 lines
(quoted diff) +2 -0
+/* Perform locked bit operations on GPIO registers */
+static int gpio_bitop(struct NPCM7XX_GPIO *bank, int op, unsigned int

offset,

Quoted 16 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +16 -0
+                     int reg)
+{
+       unsigned long flags;
+       u32 mask, val;
+
+       mask = (1L << offset);
+       spin_lock_irqsave(&bank->lock, flags);
+       switch (op) {
+       case op_set:
+               iowrite32(mask, bank->base + reg);
+               break;
+       case op_getbit:
+               mask &= ioread32(bank->base + reg);
+               break;
+       case op_setbit:
+               val = ioread32(bank->base + reg);

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 133

Quoted 10 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +10 -0
+               iowrite32(val | mask, bank->base + reg);
+               break;
+       case op_clrbit:
+               val = ioread32(bank->base + reg);
+               iowrite32(val & (~mask), bank->base + reg);
+               break;
+       }
+       spin_unlock_irqrestore(&bank->lock, flags);
+       return !!mask;
+}

This is essentially a reimplementation of drivers/gpio/gpio-mmio.c (GPIO_GENERIC, also using a spinlock to protect the registers) so let's use that instead :)

There are drivers already that reuse the spinlock inside the generic GPIO chip to protect their other registers like for IRQ registers.

Review line 64

Quoted 1 line
(quoted diff) +1 -0
+static int npcmgpio_get_direction(struct gpio_chip *chip, unsigned int

offset)

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 185

Quoted 11 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +11 -0
+{
+       struct NPCM7XX_GPIO *bank = gpiochip_get_data(chip);
+       u32 oe, ie;
+
+       /* Get Input & Output state */
+       ie = gpio_bitop(bank, op_getbit, offset, NPCM7XX_GP_N_IEM);
+       oe = gpio_bitop(bank, op_getbit, offset, NPCM7XX_GP_N_OE);
+       if (ie && !oe)
+               return GPIOF_DIR_IN;
+       else if (oe && !ie)
+               return GPIOF_DIR_OUT;

These are consumer flags and should not be used in drivers. Use plain 0/1 instead.

Anyways the problem goes away with GPIO_GENERIC.

Review line 76

Quoted 1 line
(quoted diff) +1 -0
+static int npcmgpio_direction_input(struct gpio_chip *chip, unsigned

int offset)

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 194

Quoted 3 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +3 -0
+{
+       return pinctrl_gpio_direction_input(offset + chip->base);
+}

It's a bit tricksy to get this to work with GPIO_GENERIC.

After calling bgpio_init() you need to overwrite the assigned .direction_input handler with this and then direct back to the one assigned by GPIO_GENERIC.

Something like this:

1. Add two indirection pointers to the npcm7xx_gpio state container:

struct npcm7xx_gpio {
     (...)
      int (*direction_input)(struct gpio_chip *chip, unsigned offset);
      int (*direction_output)(struct gpio_chip *chip, unsigned offset,
int value);
     (...)
};

2. Save the pointers

struct npcm7xx_gpio *npcm;

bgpio_init( ... register setup ...) npcm->direction_input = npcm->gc.direction_input; npcm->direction_output = npcm->gc.direction_output; npcm->gc.direction_input = npcmgpio_direction_input; npcm->gc.direction_output = npcmgpio_direction_output;

3. Modify the functions like that:

static int npcmgpio_direction_input(struct gpio_chip *chip, unsigned int offset)

{
    struct npcm7xx_gpio *npcm = gpiochip_get_data(chip);
    int ret;

    ret = pinctrl_gpio_direction_input(offset + chip->base);
    if (ret)
        return ret;
    return npcm->direction_input(chip);
}

I'm sure you get the idea... if you think we can modify gpio-mmio to be more helpful with this, suggestions are welcome!

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c

Quoted 7 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +7 -0
+/* Set GPIO to Output with initial value */
+static int npcmgpio_direction_output(struct gpio_chip *chip,
+                                    unsigned int offset, int value)
+{
+       struct NPCM7XX_GPIO *bank = gpiochip_get_data(chip);
+
+       dev_dbg(chip->parent, "gpio_direction_output: offset%d = %x\n",

offset,

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c

Quoted 7 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +7 -0
+               value);
+
+       /* Check if we're enabled as an interrupt.. */
+       if (gpio_bitop(bank, op_getbit, offset, NPCM7XX_GP_N_EVEN) &&
+           gpio_bitop(bank, op_getbit, offset, NPCM7XX_GP_N_IEM)) {
+               dev_dbg(chip->parent,
+                       "gpio_direction_output: IRQ enabled on

offset%d\n",

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 212

Quoted 3 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +3 -0
+                       offset);
+               return -EINVAL;
+       }

This should not be necessary as you are using GPIOLIB_IRQCHIP, which locks the GPIO for interrupt and disallows this to happen.

Review line 97

Quoted 1 line
(quoted diff) +1 -0
+static int npcmgpio_gpio_request(struct gpio_chip *chip, unsigned int

offset)

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c

Quoted 6 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +6 -0
+{
+       dev_dbg(chip->parent, "gpio_request: offset%d\n", offset);
+       return pinctrl_gpio_request(offset + chip->base);
+}
+
+static void npcmgpio_gpio_free(struct gpio_chip *chip, unsigned int

offset)

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 253

Quoted 4 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +4 -0
+{
+       dev_dbg(chip->parent, "gpio_free: offset%d\n", offset);
+       pinctrl_gpio_free(offset + chip->base);
+}

This needs the same pattern as the direction functions above, then you can use GPIO_GENERIC (mmio).

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c

Quoted 7 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +7 -0
+static unsigned int npcmgpio_irq_startup(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = d->hwirq;
+
+       /* active-high, input, clear interrupt, enable interrupt */
+       dev_dbg(d->chip->parent_device, "startup: %u.%u\n", gpio,

d->irq);

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 368

Quoted 2 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +2 -0
+       npcmgpio_direction_output(gc, gpio, 1);
+       npcmgpio_direction_input(gc, gpio);

Interesting dance. So it is required to set the line to 1 and then switch to input?

drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c line 382

Quoted 8 lines
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c new file +8 -0
+static struct irq_chip npcmgpio_irqchip = {
+       .name = "NPCM7XX-GPIO-IRQ",
+       .irq_ack = npcmgpio_irq_ack,
+       .irq_unmask = npcmgpio_irq_unmask,
+       .irq_mask = npcmgpio_irq_mask,
+       .irq_set_type = npcmgpio_set_irq_type,
+       .irq_startup = npcmgpio_irq_startup,
+};

This code is looking good BTW.

The patch in my inbox just ends in the middle of everything, I wonder why :( suspect the new gmail interface I'm using.

Anyways: the pointers above should keep you busy for the next iteration of the patch, the pin control part seems pretty straight-forward.

Yours,
Linus Walleij

#7 lore raw

Re: [PATCH v2 2/2] pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver

Quoted 13 lines · Tomer Maimon

I initialize bgpio as follow:

                        ret = bgpio_init(&pctrl->gpio_bank[id].gc,
                                         pctrl->dev, 4,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_DIN,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_DOUT,
                                         NULL,
                                         NULL,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_IEM,
                                         BGPIOF_READ_OUTPUT_REG_SET);

(...)

Quoted 6 lines

The problem occur when reading the GPIO value from bgpio_get_set function, because the directions value are inverse it reading the wrong I/O registers

For direction out it reading dat register (instead of set register)

For direction in it calling set register (instead of dat register)

Hm I don't quite get it... sorry. Maybe if you show your fix and what you expect to happen I can understand better?

Do you mean that because you write the inverse value to IEM this happens, and the BGPIO code assumes that you always write 1 to set a line as input and 0 to set it as output?

I would say if this causes the problem we should just add a new BGPIOF_INVERTED_REG_DIR with comment in include/linux/gpio/driver.h and make the necessary fix to respect this flag in the gpio-mmio.c core so it works right.

If you do this as a separate patch I would be grateful :)

Yours,
Linus Walleij

author maintainer
#8 lore raw

Re: [PATCH v2 2/2] pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver

Hi Linus,

Quoted 20 lines · Linus Walleij
Quoted 13 lines · Tomer Maimon

I initialize bgpio as follow:

                        ret = bgpio_init(&pctrl->gpio_bank[id].gc,
                                         pctrl->dev, 4,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_DIN,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_DOUT,
                                         NULL,
                                         NULL,
                                         pctrl->gpio_bank[id].base +
                                         NPCM7XX_GP_N_IEM,
                                         BGPIOF_READ_OUTPUT_REG_SET);

(...)

Quoted 1 line

The problem occur when reading the GPIO value from bgpio_get_set

function,

Quoted 1 line

because the directions value are inverse it reading the wrong I/O

Quoted 9 lines

registers

Quoted 4 lines

For direction out it reading dat register (instead of set register)

For direction in it calling set register (instead of dat register)

Hm I don't quite get it... sorry. Maybe if you show your fix and what you expect to happen I can understand better?

Of course, in the last patch sent three days a go (V3 -
https://patchwork.ozlabs.org/patch/949942/) I did as follow to workaround the issue:

       int (*get)(struct gpio_chip *chip, unsigned offset);
       int (*get_multiple)(struct gpio_chip *chip, unsigned long *mask,
                           unsigned long *bits);

......

static int npcmgpio_get_value(struct gpio_chip *chip, unsigned int offset)

{
       struct npcm7xx_gpio *bank = gpiochip_get_data(chip);
       unsigned long tmp_bgpio_dir = bank->gc.bgpio_dir;
       int val;

       /*
        * sets bgpio_dir parameter value to the opposite value
        * for calling the right registers in bgpio_get_set
        * function
        */

* bank->gc.bgpio_dir = ~bank->gc.bgpio_dir; val =
bank->get(chip, offset); bank->gc.bgpio_dir = tmp_bgpio_dir;*

       return val;
}

static int npcmgpio_get_multiple_value(struct gpio_chip *chip,
unsigned long *mask, unsigned long
*bits)

{
       struct npcm7xx_gpio *bank = gpiochip_get_data(chip);
       unsigned long tmp_bgpio_dir = bank->gc.bgpio_dir;
       int val;

       /*
        * sets bgpio_dir parameter value to the opposite value
        * for calling the right registers in bgpio_get_set_multiple
        * function
        */

* bank->gc.bgpio_dir = ~bank->gc.bgpio_dir; val =
bank->get_multiple(chip, mask, bits); bank->gc.bgpio_dir =
tmp_bgpio_dir;*

       return val;
}

......

       pctrl->gpio_bank[id].get = pctrl->gpio_bank[id].gc.get;
       pctrl->gpio_bank[id].gc.get = npcmgpio_get_value;
       pctrl->gpio_bank[id].get_multiple = ptrl->gpio_bank[id].gc.get_mul
tiple;
       pctrl->gpio_bank[id].gc.get_multiple = npcmgpio_get_multiple_value;

but it is not that good solution, because the bold commands are not atomic (locked) operations.

Quoted 6 lines

Do you mean that because you write the inverse value to IEM this happens, and the BGPIO code assumes that you always write 1 to set a line as input and 0 to set it as output?

yes, because of it the bgpio_get_set and bgpio_get_set_multiple setting the opposite data registers .

Quoted 8 lines

I would say if this causes the problem we should just add a new BGPIOF_INVERTED_REG_DIR with comment in include/linux/gpio/driver.h and make the necessary fix to respect this flag in the gpio-mmio.c core so it works right.

If you do this as a separate patch I would be grateful :)

Sure, I will send a separate patch later on to overcome it.

Quoted 4 lines

Yours,
Linus Walleij

Thanks,

Tomer