Skip to contentSkip to conversation

spi: Add Nuvoton MA35D1 SPI controller support

PATCH In review Chi-Wen Weng 4 participants 11 messages Oct 1 – Oct 5

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v2 cover spi: Add Nuvoton MA35D1 SPI controller support

From: Chi-Wen Weng <[email protected]>

This series adds support for the SPI controller found on the Nuvoton MA35D1 SoC.

The MA35D1 provides separate SPI and QSPI controller IPs. They expose the same Devicetree-visible resources and provide up to two native chip selects, so the existing MA35D1 QSPI binding is extended to also cover the SPI controller.

The SPI driver supports host mode using polling-based PIO transfers, SPI modes 0 through 3, 8 to 32 bits per word, LSB-first transfers, native chip selects and GPIO chip selects. The PIO path also honors per-word delays requested through struct spi_transfer.

The existing MA35D1 QSPI driver is updated separately to support GPIO chip selects through the SPI core. SPI-mem operations for devices using GPIO chip selects fall back to the regular SPI transfer path, while native chip selects continue to use the controller's SSCTL register.

This series is based on the current broonie/spi.git for-7.4 branch and therefore includes the already applied MA35D1 QSPI reset handling and DTR follow-up fixes.

Changes in v2:
- Extend the existing MA35D1 QSPI binding to also cover the SPI controller.
- Add GPIO chip-select support to the MA35D1 QSPI driver and allow cs-gpios in the shared binding.
- Remove the unnecessary SSCTL spinlock from the SPI driver.
- Cache the controller clock rate instead of querying it for every transfer.
- Rely on the SPI core for transfer defaults and validation.
- Avoid disabling and re-enabling the controller when the transfer configuration has not changed.
- Add per-word delay handling to the SPI PIO transfer path.
- Add system sleep support using the SPI core suspend/resume helpers.
- Rebase on the current broonie/spi.git for-7.4 branch.

Based on:
broonie/spi.git for-7.4
93914f171867 ("Add enhance SPI DMA support for JHB100 SFC")

Chi-Wen Weng (3):
spi: dt-bindings: nuvoton,ma35d1-qspi: Add MA35D1 SPI controller
spi: ma35d1: Add Nuvoton MA35D1 SPI controller support
spi: ma35d1-qspi: Add GPIO chip select support

 .../bindings/spi/nuvoton,ma35d1-qspi.yaml     |  41 +-
 drivers/spi/Kconfig                           |  11 +
 drivers/spi/Makefile                          |   1 +
 drivers/spi/spi-ma35d1-qspi.c                 |  39 +-
 drivers/spi/spi-ma35d1.c                      | 716 ++++++++++++++++++
 5 files changed, 799 insertions(+), 9 deletions(-)
 create mode 100644 drivers/spi/spi-ma35d1.c

base-commit: 93914f1718676aec13ccd3787642c8b05e2b8309

Signature · 1 line
2.25.1
#1 lore raw

PATCH v2 1/3 spi: dt-bindings: nuvoton,ma35d1-qspi: Add MA35D1 SPI controller

From: Chi-Wen Weng <[email protected]>

Extend the existing MA35D1 QSPI binding to also describe the MA35D1 SPI controller.

The SPI and QSPI controllers are separate hardware IPs. QSPI additionally supports dual, quad and DTR transfers and a target-mode timeout function, but these differences do not require additional controller-specific Devicetree properties.

Both controllers expose the same Devicetree-visible resources and provide up to two native chip-select signals. GPIO chip selects are supported through the generic SPI controller binding. Since the MA35D1 QSPI driver now supports GPIO chip selects, also remove the existing restriction on cs-gpios for the QSPI compatible.

Add the nuvoton,ma35d1-spi compatible and update the binding description and examples to cover both controllers.

---
 .../bindings/spi/nuvoton,ma35d1-qspi.yaml     | 41 +++++++++++++++++--
 1 file changed, 37 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml +37 -4
index 40965ec5163b..72f2e1e1219a 100644
@@ -4,7 +4,17 @@
 $id: http://devicetree.org/schemas/spi/nuvoton,ma35d1-qspi.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Nuvoton MA35D1 Quad SPI Controller
+title: Nuvoton MA35D1 SPI and Quad SPI Controllers
+
+description: |
+  The Nuvoton MA35D1 SoC contains separate SPI and QSPI controller IPs.
+  Both controllers expose the same Devicetree-visible resources and provide
+  two native chip-select signals. GPIO chip selects are supported through the
+  generic SPI controller binding.
+
+  The QSPI controller additionally supports dual, quad and DTR transfers and
+  a target-mode timeout function. These capability differences do not require
+  additional controller properties.
 
 maintainers:
   - Chi-Wen Weng <[email protected]>
@@ -14,7 +24,9 @@ allOf:
 
 properties:
   compatible:
-    const: nuvoton,ma35d1-qspi
+    enum:
+      - nuvoton,ma35d1-spi
+      - nuvoton,ma35d1-qspi
 
   reg:
     maxItems: 1
@@ -33,8 +45,6 @@ properties:
     maximum: 2
     default: 2
 
-  cs-gpios: false
-
 required:
   - compatible
   - reg
@@ -59,7 +69,30 @@ examples:
             interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
             clocks = <&clk QSPI0_GATE>;
             resets = <&sys MA35D1_RESET_QSPI0>;
+
+            #address-cells = <1>;
+            #size-cells = <0>;
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+    #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        spi@40600000 {
+            compatible = "nuvoton,ma35d1-spi";
+            reg = <0 0x40600000 0 0x10000>;
+            interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&clk SPI0_GATE>;
+            resets = <&sys MA35D1_RESET_SPI0>;
+
             #address-cells = <1>;
             #size-cells = <0>;
         };
     };
+...
Signature · 1 line
2.25.1
#2 lore raw

Re: [PATCH v2 1/3] spi: dt-bindings: nuvoton,ma35d1-qspi: Add MA35D1 SPI controller

Quoted 10 lines · Chi-Wen Weng

From: Chi-Wen Weng <[email protected]>

Extend the existing MA35D1 QSPI binding to also describe the MA35D1 SPI controller.

The SPI and QSPI controllers are separate hardware IPs. QSPI additionally supports dual, quad and DTR transfers and a target-mode timeout function, but these differences do not require additional controller-specific Devicetree properties.

Quoted 5 lines

Both controllers expose the same Devicetree-visible resources and provide up to two native chip-select signals. GPIO chip selects are supported through the generic SPI controller binding. Since the MA35D1 QSPI driver now supports GPIO chip selects, also remove the existing restriction on cs-gpios for the QSPI compatible.

This has to be a separate commit.

Quoted 57 lines

Add the nuvoton,ma35d1-spi compatible and update the binding description and examples to cover both controllers.

---
 .../bindings/spi/nuvoton,ma35d1-qspi.yaml     | 41 +++++++++++++++++--
 1 file changed, 37 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml +15 -4
index 40965ec5163b..72f2e1e1219a 100644
@@ -4,7 +4,17 @@
 $id: http://devicetree.org/schemas/spi/nuvoton,ma35d1-qspi.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Nuvoton MA35D1 Quad SPI Controller
+title: Nuvoton MA35D1 SPI and Quad SPI Controllers
+
+description: |
+  The Nuvoton MA35D1 SoC contains separate SPI and QSPI controller IPs.
+  Both controllers expose the same Devicetree-visible resources and provide
+  two native chip-select signals. GPIO chip selects are supported through the
+  generic SPI controller binding.
+
+  The QSPI controller additionally supports dual, quad and DTR transfers and
+  a target-mode timeout function. These capability differences do not require
+  additional controller properties.
 
 maintainers:
   - Chi-Wen Weng <[email protected]>
@@ -14,7 +24,9 @@ allOf:
 
 properties:
   compatible:
-    const: nuvoton,ma35d1-qspi
+    enum:
+      - nuvoton,ma35d1-spi
+      - nuvoton,ma35d1-qspi
 
   reg:
     maxItems: 1
@@ -33,8 +45,6 @@ properties:
     maximum: 2
     default: 2
 
-  cs-gpios: false
-
 required:
   - compatible
   - reg
@@ -59,7 +69,30 @@ examples:
             interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
             clocks = <&clk QSPI0_GATE>;
             resets = <&sys MA35D1_RESET_QSPI0>;
+

Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml examples: · line 82

Quoted 10 lines
Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml +10 -0
+            #address-cells = <1>;
+            #size-cells = <0>;
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+    #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
+

No need for a new example, for exactly the same node. Difference in value of a property does not justify it.

Best regards,
Krzysztof

#3 lore raw

Re: [PATCH v2 1/3] spi: dt-bindings: nuvoton,ma35d1-qspi: Add MA35D1 SPI controller

Krzysztof Kozlowski 於 2026/10/3 下午 10:25 寫道:

Quoted 90 lines · Chi-Wen Weng
Quoted 10 lines

From: Chi-Wen Weng <[email protected]>

Extend the existing MA35D1 QSPI binding to also describe the MA35D1 SPI controller.

The SPI and QSPI controllers are separate hardware IPs. QSPI additionally supports dual, quad and DTR transfers and a target-mode timeout function, but these differences do not require additional controller-specific Devicetree properties.

Quoted 5 lines

Both controllers expose the same Devicetree-visible resources and provide up to two native chip-select signals. GPIO chip selects are supported through the generic SPI controller binding. Since the MA35D1 QSPI driver now supports GPIO chip selects, also remove the existing restriction on cs-gpios for the QSPI compatible.

This has to be a separate commit.

Quoted 57 lines

Add the nuvoton,ma35d1-spi compatible and update the binding description and examples to cover both controllers.

---
  .../bindings/spi/nuvoton,ma35d1-qspi.yaml     | 41 +++++++++++++++++--
  1 file changed, 37 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml +15 -4
index 40965ec5163b..72f2e1e1219a 100644
@@ -4,7 +4,17 @@
  $id: http://devicetree.org/schemas/spi/nuvoton,ma35d1-qspi.yaml#
  $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Nuvoton MA35D1 Quad SPI Controller
+title: Nuvoton MA35D1 SPI and Quad SPI Controllers
+
+description: |
+  The Nuvoton MA35D1 SoC contains separate SPI and QSPI controller IPs.
+  Both controllers expose the same Devicetree-visible resources and provide
+  two native chip-select signals. GPIO chip selects are supported through the
+  generic SPI controller binding.
+
+  The QSPI controller additionally supports dual, quad and DTR transfers and
+  a target-mode timeout function. These capability differences do not require
+  additional controller properties.
 
  maintainers:
    - Chi-Wen Weng <[email protected]>
@@ -14,7 +24,9 @@ allOf:
 
  properties:
    compatible:
-    const: nuvoton,ma35d1-qspi
+    enum:
+      - nuvoton,ma35d1-spi
+      - nuvoton,ma35d1-qspi
 
    reg:
      maxItems: 1
@@ -33,8 +45,6 @@ properties:
      maximum: 2
      default: 2
 
-  cs-gpios: false
-
  required:
    - compatible
    - reg
@@ -59,7 +69,30 @@ examples:
              interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
              clocks = <&clk QSPI0_GATE>;
              resets = <&sys MA35D1_RESET_QSPI0>;
+

Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml examples: · line 82

Quoted 10 lines
Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml +10 -0
+            #address-cells = <1>;
+            #size-cells = <0>;
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+    #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
+

No need for a new example, for exactly the same node. Difference in value of a property does not justify it.

Quoted 2 lines

Best regards,
Krzysztof

Hi Krzysztof,

Thanks for the review.

I will address both comments in v3.

For the binding changes, I will split the current patch into two separate commits:

1. Extend the existing MA35D1 QSPI binding to also describe the MA35D1 SPI controller.

This patch will only update the title, description and compatible list to cover both the SPI and QSPI controllers.

The existing cs-gpios: false restriction will remain in this commit.

2. Add a separate binding patch to allow GPIO chip selects.

This patch will remove the existing cs-gpios: false restriction so that the generic SPI controller binding can provide GPIO chip-select support.

I will also drop the additional SPI example. Since the SPI and QSPI controllers use the same node structure and only differ in property values, the existing example is sufficient.

So the v3 series is planned as:

1. spi: dt-bindings: nuvoton,ma35d1-qspi: Add MA35D1 SPI controller
2. spi: dt-bindings: nuvoton,ma35d1-qspi: Allow GPIO chip selects
3. spi: ma35d1: Add Nuvoton MA35D1 SPI controller support
4. spi: ma35d1-qspi: Add GPIO chip select support

Thanks,
Chi-Wen

#4 lore raw

PATCH v2 2/3 spi: ma35d1: Add Nuvoton MA35D1 SPI controller support

In reply to Chi-Wen Weng

From: Chi-Wen Weng <[email protected]>

Add support for the SPI controller found in the Nuvoton MA35D1 SoC.

The driver supports SPI host mode using polling-based PIO transfers, with SPI modes 0 through 3, LSB-first operation, and word sizes from 8 to 32 bits.

Support the two native chip-select outputs as well as GPIO chip selects through the SPI core GPIO descriptor support.

Configure the SPI clock divider according to the hardware requirement that only odd CLKDIV register values are valid, ensuring that the generated SPI clock does not exceed the requested transfer frequency.

The controller must be disabled before changing CTL, CLKDIV, SSCTL or FIFOCTL. Avoid unnecessary enable/disable cycles by reconfiguring the controller only when the transfer settings change.

Add system sleep support using the SPI core suspend and resume helpers. The MA35D1 SPI registers are retained across power-down and deep sleep, so no hardware state restoration is required after resume.

---
 drivers/spi/Kconfig      |  11 +
 drivers/spi/Makefile     |   1 +
 drivers/spi/spi-ma35d1.c | 716 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 728 insertions(+)
 create mode 100644 drivers/spi/spi-ma35d1.c
drivers/spi/Kconfig +11 -0
index eb042cf5268f..49088e5886d3 100644
@@ -667,6 +667,17 @@ config SPI_LP8841_RTC
 	  Say N here unless you plan to run the kernel on an ICP DAS
 	  LP-8x4x industrial computer.
 
+config SPI_MA35D1
+	tristate "Nuvoton MA35D1 SPI controller"
+	depends on ARCH_MA35 || COMPILE_TEST
+	help
+	  This enables support for the SPI controller found in
+	  Nuvoton MA35D1 SoCs.
+
+	  The controller supports standard SPI peripheral devices with
+	  configurable clock polarity and phase, chip select, and data
+	  word sizes from 8 to 32 bits.
+
 config SPI_MA35D1_QSPI
 	tristate "Nuvoton MA35D1 QSPI controller"
 	depends on ARCH_MA35 || COMPILE_TEST
drivers/spi/Makefile +1 -0
index 37c6eec9b541..b493f50b93e3 100644
@@ -86,6 +86,7 @@ obj-$(CONFIG_SPI_LOONGSON_CORE)		+= spi-loongson-core.o
 obj-$(CONFIG_SPI_LOONGSON_PCI)		+= spi-loongson-pci.o
 obj-$(CONFIG_SPI_LOONGSON_PLATFORM)	+= spi-loongson-plat.o
 obj-$(CONFIG_SPI_LP8841_RTC)		+= spi-lp8841-rtc.o
+obj-$(CONFIG_SPI_MA35D1)		+= spi-ma35d1.o
 obj-$(CONFIG_SPI_MA35D1_QSPI)		+= spi-ma35d1-qspi.o
 obj-$(CONFIG_SPI_MESON_SPICC)		+= spi-meson-spicc.o
 obj-$(CONFIG_SPI_MESON_SPIFC)		+= spi-meson-spifc.o
drivers/spi/spi-ma35d1.c new file +716 -0

716 lines not on this page · raw message

Signature · 1 line
2.25.1
#5 lore raw

Re: [PATCH v2 2/3] spi: ma35d1: Add Nuvoton MA35D1 SPI controller support

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] spi: ma35d1: probe fails on valid DT with num-cs > 2 when using GPIO CS --

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] spi: ma35d1: probe fails on valid DT with num-cs > 2 when using GPIO CS --

commit 297501e7117bfad68b786ba4098b2489480c1405
Author: Chi-Wen Weng <[email protected]>

spi: ma35d1: Add Nuvoton MA35D1 SPI controller support

This commit adds a new driver for the SPI controller found in the Nuvoton MA35D1 SoC. The driver supports SPI host mode using polling-based PIO transfers, standard SPI modes, and natively controls up to two chip selects.

Quoted 5 lines
drivers/spi/spi-ma35d1.c new file +0 -0
new file mode 100644
index 0000000000000..7560cb7e0b099

[ ... ]

Quoted 2 lines
drivers/spi/spi-ma35d1.c new file +2 -0
+static int nuvoton_spi_probe(struct platform_device *pdev)
+{

[ ... ]

drivers/spi/spi-ma35d1.c line 641

Quoted 7 lines
drivers/spi/spi-ma35d1.c new file +7 -0
+	ret = device_property_read_u32(dev, "num-cs", &num_cs);
+	if (ret && ret != -EINVAL)
+		return dev_err_probe(dev, ret, "failed to read num-cs\n");
+
+	if (!num_cs || num_cs > NUVOTON_SPI_MAX_NATIVE_CS)
+		return dev_err_probe(dev, -EINVAL, "invalid num-cs %u\n",
+				     num_cs);

[Severity: Medium]
Will this check inadvertently reject valid device tree configurations that use GPIO chip selects for additional devices?

The SPI core correctly supports expanding the total number of chip selects beyond the native hardware limit when using GPIO descriptors. Since this driver sets ctlr->use_gpio_descriptors to true, a device tree could specify a num-cs value greater than NUVOTON_SPI_MAX_NATIVE_CS (which is 2) in order to attach a 3rd or 4th SPI target using GPIOs.

Because nuvoton_spi_probe() checks the total num-cs read from the device tree directly against NUVOTON_SPI_MAX_NATIVE_CS and returns -EINVAL, could this artificially limit the bus to 2 devices overall and prevent GPIO chip select expansion?

Quoted 4 lines
drivers/spi/spi-ma35d1.c new file +4 -0
+
+	ctlr->num_chipselect = num_cs;
+	ctlr->max_native_cs = NUVOTON_SPI_MAX_NATIVE_CS;
+	ctlr->use_gpio_descriptors = true;

[ ... ]

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
#6 lore raw

Re: [PATCH v2 2/3] spi: ma35d1: Add Nuvoton MA35D1 SPI controller support

[email protected] 於 2026/10/1 下午 09:37 寫道:

Quoted 45 lines

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] spi: ma35d1: probe fails on valid DT with num-cs > 2 when using GPIO CS --

commit 297501e7117bfad68b786ba4098b2489480c1405
Author: Chi-Wen Weng <[email protected]>

spi: ma35d1: Add Nuvoton MA35D1 SPI controller support

This commit adds a new driver for the SPI controller found in the Nuvoton MA35D1 SoC. The driver supports SPI host mode using polling-based PIO transfers, standard SPI modes, and natively controls up to two chip selects.

Quoted 5 lines
drivers/spi/spi-ma35d1.c new file +0 -0
new file mode 100644
index 0000000000000..7560cb7e0b099

[ ... ]

Quoted 2 lines
drivers/spi/spi-ma35d1.c new file +2 -0
+static int nuvoton_spi_probe(struct platform_device *pdev)
+{

[ ... ]

drivers/spi/spi-ma35d1.c line 641

Quoted 7 lines
drivers/spi/spi-ma35d1.c new file +7 -0
+	ret = device_property_read_u32(dev, "num-cs", &num_cs);
+	if (ret && ret != -EINVAL)
+		return dev_err_probe(dev, ret, "failed to read num-cs\n");
+
+	if (!num_cs || num_cs > NUVOTON_SPI_MAX_NATIVE_CS)
+		return dev_err_probe(dev, -EINVAL, "invalid num-cs %u\n",
+				     num_cs);

[Severity: Medium]
Will this check inadvertently reject valid device tree configurations that use GPIO chip selects for additional devices?

The SPI core correctly supports expanding the total number of chip selects beyond the native hardware limit when using GPIO descriptors. Since this driver sets ctlr->use_gpio_descriptors to true, a device tree could specify a num-cs value greater than NUVOTON_SPI_MAX_NATIVE_CS (which is 2) in order to attach a 3rd or 4th SPI target using GPIOs.

Because nuvoton_spi_probe() checks the total num-cs read from the device tree directly against NUVOTON_SPI_MAX_NATIVE_CS and returns -EINVAL, could this artificially limit the bus to 2 devices overall and prevent GPIO chip select expansion?

Quoted 6 lines
Quoted 4 lines
drivers/spi/spi-ma35d1.c new file +4 -0
+
+	ctlr->num_chipselect = num_cs;
+	ctlr->max_native_cs = NUVOTON_SPI_MAX_NATIVE_CS;
+	ctlr->use_gpio_descriptors = true;

[ ... ]

Hi,

Thanks for the review.

I don't think this check prevents additional GPIO chip selects.

For the MA35D1 binding, num-cs is limited to the two native hardware chip selects:

    num-cs:
      minimum: 1
      maximum: 2
      default: 2

Additional chip selects are described by entries in cs-gpios, rather than by increasing num-cs beyond two.

Since the driver sets:

    ctlr->max_native_cs = NUVOTON_SPI_MAX_NATIVE_CS;
    ctlr->use_gpio_descriptors = true;

the SPI core handles the GPIO chip-select expansion in spi_get_gpio_descs(). In particular, it updates num_chipselect using the number of cs-gpios entries:

    ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect);

For example, with two native chip selects and two additional GPIO chip selects, num-cs remains 2 while cs-gpios contains four entries. The SPI core then expands ctlr->num_chipselect to 4.

max_native_cs only limits chip-select indices which do not have a GPIO descriptor, so the additional GPIO-backed chip selects are not rejected.

Therefore a DT with num-cs > 2 is not valid for this controller binding, while valid configurations using additional GPIO chip selects continue to work through the SPI core.

Thanks,
Chi-Wen

#7 lore raw

PATCH v2 3/3 spi: ma35d1-qspi: Add GPIO chip select support

In reply to Chi-Wen Weng

From: Chi-Wen Weng <[email protected]>

The generic SPI controller binding allows GPIO-based chip selects, but the MA35D1 QSPI driver does not currently enable the SPI core's GPIO descriptor handling.

Enable GPIO chip-select support and specify that the controller provides two native chip selects. Add a setup callback to reject active-high polarity only for native chip selects, while allowing GPIO chip selects to use the polarity handled by the GPIO subsystem.

This keeps the binding capable of describing valid board wiring while preserving the active-low limitation of the controller's native chip selects.

---
 drivers/spi/spi-ma35d1-qspi.c | 39 ++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)
drivers/spi/spi-ma35d1-qspi.c +34 -5
index 30e3239f777d..0644bb2990b8 100644
@@ -62,7 +62,7 @@
 #define NUVOTON_QSPI_STATUS_RXEMPTY_MASK	BIT(8) /* Receive FIFO Empty */
 #define NUVOTON_QSPI_STATUS_BUSY_MASK	BIT(0) /* Busy Status */
 
-#define NUVOTON_QSPI_MAX_NUM_CS		2
+#define NUVOTON_QSPI_MAX_NATIVE_CS	2
 #define NUVOTON_QSPI_DEFAULT_NUM_CS	2
 #define NUVOTON_QSPI_DEFAULT_BPW	8
 /* Bound PIO operations to avoid long atomic polling loops. */
@@ -442,13 +442,35 @@ static void nuvoton_qspi_set_cs_level(struct nuvoton_qspi *qspi,
 	spin_unlock_irqrestore(&qspi->ssctl_lock, flags);
 }
 
+static int nuvoton_qspi_setup(struct spi_device *spi)
+{
+	unsigned int cs = spi_get_chipselect(spi, 0);
+
+	if (spi_get_csgpiod(spi, 0))
+		return 0;
+
+	if (cs >= NUVOTON_QSPI_MAX_NATIVE_CS) {
+		dev_err(&spi->dev, "invalid native chip select %u\n", cs);
+		return -EINVAL;
+	}
+
+	if (spi->mode & SPI_CS_HIGH) {
+		dev_err(&spi->dev,
+			"active-high native chip select is not supported\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static void nuvoton_qspi_set_cs(struct spi_device *spi, bool level)
 {
 	struct nuvoton_qspi *qspi = spi_controller_get_devdata(spi->controller);
 
 	/*
-	 * The SPI core passes the physical CS level to ->set_cs(). This
-	 * initial driver only supports active-low native chip selects.
+	 * GPIO chip selects are handled by the SPI core. For native chip
+	 * selects, the core passes the physical CS level to ->set_cs().
+	 * Native chip selects are active low.
 	 */
 	nuvoton_qspi_set_cs_level(qspi, spi_get_chipselect(spi, 0), !level);
 }
@@ -457,7 +479,11 @@ static void nuvoton_qspi_mem_set_cs(struct spi_device *spi, bool assert)
 {
 	struct nuvoton_qspi *qspi = spi_controller_get_devdata(spi->controller);
 
-	/* The direct spi-mem path passes a logical assertion state. */
+	/*
+	 * Direct spi-mem operations are only executed for native chip
+	 * selects. GPIO chip selects use the regular SPI fallback path.
+	 * This helper takes a logical assertion state.
+	 */
 	nuvoton_qspi_set_cs_level(qspi, spi_get_chipselect(spi, 0), assert);
 }
 
@@ -638,18 +664,21 @@ static int nuvoton_qspi_probe(struct platform_device *pdev)
 		goto err_assert;
 	}
 
-	if (!num_cs || num_cs > NUVOTON_QSPI_MAX_NUM_CS) {
+	if (!num_cs || num_cs > NUVOTON_QSPI_MAX_NATIVE_CS) {
 		ret = dev_err_probe(dev, -EINVAL, "invalid num-cs %u\n",
 				     num_cs);
 		goto err_assert;
 	}
 
 	ctlr->num_chipselect = num_cs;
+	ctlr->max_native_cs = NUVOTON_QSPI_MAX_NATIVE_CS;
+	ctlr->use_gpio_descriptors = true;
 	ctlr->max_transfer_size = nuvoton_qspi_max_transfer_size;
 	ctlr->max_message_size = nuvoton_qspi_max_message_size;
 	ctlr->mem_ops = &nuvoton_qspi_mem_ops;
 	ctlr->mem_caps = &nuvoton_qspi_mem_caps;
 	ctlr->dtr_caps = true;
+	ctlr->setup = nuvoton_qspi_setup;
 	ctlr->set_cs = nuvoton_qspi_set_cs;
 	ctlr->transfer_one = nuvoton_qspi_transfer_one;
 	ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
Signature · 1 line
2.25.1
#8 lore raw

Re: [PATCH v2 3/3] spi: ma35d1-qspi: Add GPIO chip select support

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] spi: incorrect validation of total chip selects limits GPIO expansion --

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] spi: incorrect validation of total chip selects limits GPIO expansion --

commit bf74299215867df971e01913ae533377b76db610
Author: Chi-Wen Weng <[email protected]>

spi: ma35d1-qspi: Add GPIO chip select support

The generic SPI controller binding allows GPIO-based chip selects, but the MA35D1 QSPI driver does not currently enable the SPI core's GPIO descriptor handling. This patch enables GPIO chip-select support and specifies that the controller provides two native chip selects.

Quoted 4 lines
drivers/spi/spi-ma35d1-qspi.c +0 -0
index 30e3239f777d6..0644bb2990b8c 100644

[ ... ]

drivers/spi/spi-ma35d1-qspi.c static int nuvoton_qspi_probe(struct platform_device *pdev) · line 667

Quoted 6 lines
drivers/spi/spi-ma35d1-qspi.c +1 -1
@@ -638,18 +664,21 @@ static int nuvoton_qspi_probe(struct platform_device *pdev)
 		goto err_assert;
 	}
 
-	if (!num_cs || num_cs > NUVOTON_QSPI_MAX_NUM_CS) {
+	if (!num_cs || num_cs > NUVOTON_QSPI_MAX_NATIVE_CS) {

[Severity: Medium]
Does this validation check incorrectly apply the native chip select limit to the total number of chip selects?

If the Devicetree specifies a num-cs greater than 2 to declare additional GPIO-backed chip selects, it appears this check will cause nuvoton_qspi_probe() to fail unconditionally, preventing the use of the new GPIO expansion feature.

Quoted 8 lines
drivers/spi/spi-ma35d1-qspi.c +2 -0
 		ret = dev_err_probe(dev, -EINVAL, "invalid num-cs %u\n",
 				     num_cs);
 		goto err_assert;
 	}
 
 	ctlr->num_chipselect = num_cs;
+	ctlr->max_native_cs = NUVOTON_QSPI_MAX_NATIVE_CS;
+	ctlr->use_gpio_descriptors = true;
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
#9 lore raw

Re: [PATCH v2 3/3] spi: ma35d1-qspi: Add GPIO chip select support

[email protected] 於 2026/10/1 下午 09:46 寫道:

Quoted 34 lines

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] spi: incorrect validation of total chip selects limits GPIO expansion --

commit bf74299215867df971e01913ae533377b76db610
Author: Chi-Wen Weng <[email protected]>

spi: ma35d1-qspi: Add GPIO chip select support

The generic SPI controller binding allows GPIO-based chip selects, but the MA35D1 QSPI driver does not currently enable the SPI core's GPIO descriptor handling. This patch enables GPIO chip-select support and specifies that the controller provides two native chip selects.

Quoted 4 lines
drivers/spi/spi-ma35d1-qspi.c +0 -0
index 30e3239f777d6..0644bb2990b8c 100644

[ ... ]

drivers/spi/spi-ma35d1-qspi.c static int nuvoton_qspi_probe(struct platform_device *pdev) · line 667

Quoted 6 lines
drivers/spi/spi-ma35d1-qspi.c +1 -1
@@ -638,18 +664,21 @@ static int nuvoton_qspi_probe(struct platform_device *pdev)
  		goto err_assert;
  	}
 
-	if (!num_cs || num_cs > NUVOTON_QSPI_MAX_NUM_CS) {
+	if (!num_cs || num_cs > NUVOTON_QSPI_MAX_NATIVE_CS) {

[Severity: Medium]
Does this validation check incorrectly apply the native chip select limit to the total number of chip selects?

If the Devicetree specifies a num-cs greater than 2 to declare additional GPIO-backed chip selects, it appears this check will cause nuvoton_qspi_probe() to fail unconditionally, preventing the use of the new GPIO expansion feature.

Quoted 9 lines

drivers/spi/spi-ma35d1-qspi.c static int nuvoton_qspi_probe(struct platform_device *pdev) · line 675

Quoted 8 lines
drivers/spi/spi-ma35d1-qspi.c +2 -0
  		ret = dev_err_probe(dev, -EINVAL, "invalid num-cs %u\n",
  				     num_cs);
  		goto err_assert;
  	}
 
  	ctlr->num_chipselect = num_cs;
+	ctlr->max_native_cs = NUVOTON_QSPI_MAX_NATIVE_CS;
+	ctlr->use_gpio_descriptors = true;

Hi,

Thanks for the review.

I don't think this check prevents additional GPIO chip selects.

For the MA35D1 binding, num-cs is limited to the two native hardware chip selects:

    num-cs:
      minimum: 1
      maximum: 2
      default: 2

Additional chip selects are described by entries in cs-gpios, rather than by increasing num-cs beyond two.

Since the driver sets:

    ctlr->max_native_cs = NUVOTON_QSPI_MAX_NATIVE_CS;
    ctlr->use_gpio_descriptors = true;

the SPI core handles the GPIO chip-select expansion when the controller is registered. The number of usable chip-select slots is expanded according to the number of cs-gpios entries.

For example, with two native chip selects and two additional GPIO chip selects, num-cs remains 2 while cs-gpios contains four entries. The SPI core then expands ctlr->num_chipselect to 4.

max_native_cs only limits native chip-select indices. GPIO-backed chip selects beyond that native limit are still valid.

Therefore a DT with num-cs > 2 is not valid for this controller binding, while valid configurations using additional GPIO chip selects continue to work through the SPI core.

Thanks,
Chi-Wen

maintainer
#10 lore raw
In reply to Chi-Wen Weng
Quoted 8 lines · Chi-Wen Weng

spi: Add Nuvoton MA35D1 SPI controller support

From: Chi-Wen Weng <[email protected]>

This series adds support for the SPI controller found on the Nuvoton MA35D1 SoC.

[...]

Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-7.4

Thanks!

[1/3] spi: dt-bindings: nuvoton,ma35d1-qspi: Add MA35D1 SPI controller

      https://git.kernel.org/broonie/spi/c/1cdbe8d7c228
[2/3] spi: ma35d1: Add Nuvoton MA35D1 SPI controller support
      https://git.kernel.org/broonie/spi/c/dd3fb3b25952
[3/3] spi: ma35d1-qspi: Add GPIO chip select support
      https://git.kernel.org/broonie/spi/c/8767f4599551

All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying to this mail.

Thanks,
Mark