* [PATCH 0/6] Add RSPI support for RZ/V2H
@ 2025-06-24 19:22 Fabrizio Castro
2025-06-24 19:22 ` [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs Fabrizio Castro
` (6 more replies)
0 siblings, 7 replies; 21+ messages in thread
From: Fabrizio Castro @ 2025-06-24 19:22 UTC (permalink / raw)
To: Fabrizio Castro, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Geert Uytterhoeven, Magnus Damm, Catalin Marinas,
Will Deacon, Michael Turquette, Stephen Boyd, Philipp Zabel
Cc: SPL2 Bot, Bjorn Andersson, Arnd Bergmann, Nishanth Menon,
Lad Prabhakar, Nícolas F. R. A. Prado, Taniya Das,
Eric Biggers, Kuninori Morimoto, linux-spi, linux-renesas-soc,
devicetree, linux-kernel, linux-arm-kernel, linux-clk, Biju Das
From: SPL2 Bot <spl2-bot-eu@lm.renesas.com>
Dear All,
This series adds support for the Renesas RZ/V2H RSPI IP.
Cheers,
Fab
Fabrizio Castro (6):
clk: renesas: r9a09g057: Add entries for the RSPIs
spi: dt-bindings: Document the RZ/V2H(P) RSPI
spi: Add driver for the RZ/V2H(P) RSPI IP
MAINTAINERS: Add entries for the RZ/V2H(P) RSPI
arm64: defconfig: Enable the RZ/V2H(P) RSPI driver
arm64: dts: renesas: r9a09g057: Add RSPI nodes
.../bindings/spi/renesas,rzv2h-rspi.yaml | 96 ++++
MAINTAINERS | 8 +
arch/arm64/boot/dts/renesas/r9a09g057.dtsi | 63 +++
arch/arm64/configs/defconfig | 1 +
drivers/clk/renesas/r9a09g057-cpg.c | 24 +
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-rzv2h-rspi.c | 469 ++++++++++++++++++
8 files changed, 670 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
create mode 100644 drivers/spi/spi-rzv2h-rspi.c
--
2.34.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs
2025-06-24 19:22 [PATCH 0/6] Add RSPI support for RZ/V2H Fabrizio Castro
@ 2025-06-24 19:22 ` Fabrizio Castro
2025-06-24 19:37 ` Biju Das
2025-07-01 13:17 ` Geert Uytterhoeven
2025-06-24 19:23 ` [PATCH 2/6] spi: dt-bindings: Document the RZ/V2H(P) RSPI Fabrizio Castro
` (5 subsequent siblings)
6 siblings, 2 replies; 21+ messages in thread
From: Fabrizio Castro @ 2025-06-24 19:22 UTC (permalink / raw)
To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd
Cc: Fabrizio Castro, linux-renesas-soc, linux-clk, linux-kernel,
Biju Das, Lad Prabhakar
Add clock and reset entries for the Renesas RZ/V2H(P) RSPI IPs.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
drivers/clk/renesas/r9a09g057-cpg.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c
index da908e820950..f39bd2e78312 100644
--- a/drivers/clk/renesas/r9a09g057-cpg.c
+++ b/drivers/clk/renesas/r9a09g057-cpg.c
@@ -217,6 +217,24 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = {
BUS_MSTOP(5, BIT(13))),
DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18,
BUS_MSTOP(5, BIT(13))),
+ DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20,
+ BUS_MSTOP(11, BIT(0))),
+ DEF_MOD("rspi_0_pclk_sfr", CLK_PLLCLN_DIV8, 5, 5, 2, 21,
+ BUS_MSTOP(11, BIT(0))),
+ DEF_MOD("rspi_0_tclk", CLK_PLLCLN_DIV8, 5, 6, 2, 22,
+ BUS_MSTOP(11, BIT(0))),
+ DEF_MOD("rspi_1_pclk", CLK_PLLCLN_DIV8, 5, 7, 2, 23,
+ BUS_MSTOP(11, BIT(1))),
+ DEF_MOD("rspi_1_pclk_sfr", CLK_PLLCLN_DIV8, 5, 8, 2, 24,
+ BUS_MSTOP(11, BIT(1))),
+ DEF_MOD("rspi_1_tclk", CLK_PLLCLN_DIV8, 5, 9, 2, 25,
+ BUS_MSTOP(11, BIT(1))),
+ DEF_MOD("rspi_2_pclk", CLK_PLLCLN_DIV8, 5, 10, 2, 26,
+ BUS_MSTOP(11, BIT(2))),
+ DEF_MOD("rspi_2_pclk_sfr", CLK_PLLCLN_DIV8, 5, 11, 2, 27,
+ BUS_MSTOP(11, BIT(2))),
+ DEF_MOD("rspi_2_tclk", CLK_PLLCLN_DIV8, 5, 12, 2, 28,
+ BUS_MSTOP(11, BIT(2))),
DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15,
BUS_MSTOP(3, BIT(14))),
DEF_MOD("riic_8_ckm", CLK_PLLCM33_DIV16, 9, 3, 4, 19,
@@ -349,6 +367,12 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = {
DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */
DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */
DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */
+ DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */
+ DEF_RST(7, 12, 3, 13), /* RSPI_0_TRESETN */
+ DEF_RST(7, 13, 3, 14), /* RSPI_1_PRESETN */
+ DEF_RST(7, 14, 3, 15), /* RSPI_1_TRESETN */
+ DEF_RST(7, 15, 3, 16), /* RSPI_2_PRESETN */
+ DEF_RST(8, 0, 3, 17), /* RSPI_2_TRESETN */
DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */
DEF_RST(9, 8, 4, 9), /* RIIC_0_MRST */
DEF_RST(9, 9, 4, 10), /* RIIC_1_MRST */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/6] spi: dt-bindings: Document the RZ/V2H(P) RSPI
2025-06-24 19:22 [PATCH 0/6] Add RSPI support for RZ/V2H Fabrizio Castro
2025-06-24 19:22 ` [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs Fabrizio Castro
@ 2025-06-24 19:23 ` Fabrizio Castro
2025-06-27 20:28 ` Rob Herring (Arm)
2025-07-01 13:29 ` Geert Uytterhoeven
2025-06-24 19:23 ` [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP Fabrizio Castro
` (4 subsequent siblings)
6 siblings, 2 replies; 21+ messages in thread
From: Fabrizio Castro @ 2025-06-24 19:23 UTC (permalink / raw)
To: Fabrizio Castro, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Geert Uytterhoeven, Magnus Damm
Cc: linux-spi, linux-renesas-soc, devicetree, linux-kernel, Biju Das,
Lad Prabhakar
Add dt-bindings for the RSPI IP found inside the Renesas RZ/V2H(P)
SoC.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
.../bindings/spi/renesas,rzv2h-rspi.yaml | 96 +++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
diff --git a/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
new file mode 100644
index 000000000000..ab27fefc3c3a
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/renesas,rzv2h-rspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/V2H(P) Renesas Serial Peripheral Interface (RSPI)
+
+maintainers:
+ - Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+
+allOf:
+ - $ref: spi-controller.yaml#
+
+properties:
+ compatible:
+ const: renesas,r9a09g057-rspi # RZ/V2H(P)
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ items:
+ - description: Idle Interrupt
+ - description: Error Interrupt
+ - description: Communication End Interrupt
+ - description: Receive Buffer Full Interrupt
+ - description: Transmit Buffer Empty Interrupt
+
+ interrupt-names:
+ items:
+ - const: idle
+ - const: error
+ - const: end
+ - const: rx
+ - const: tx
+
+ clocks:
+ maxItems: 3
+
+ clock-names:
+ items:
+ - const: pclk
+ - const: pclk_sfr
+ - const: tclk
+
+ resets:
+ maxItems: 2
+
+ reset-names:
+ items:
+ - const: presetn
+ - const: tresetn
+
+ power-domains:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - interrupt-names
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+ - power-domains
+ - '#address-cells'
+ - '#size-cells'
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/renesas-cpg-mssr.h>
+ spi@12800800 {
+ compatible = "renesas,r9a09g057-rspi";
+
+ reg = <0x12800800 0x400>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 504 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 505 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_MOD 0x5a>,
+ <&cpg CPG_MOD 0x5b>,
+ <&cpg CPG_MOD 0x5c>;
+ clock-names = "pclk", "pclk_sfr", "tclk";
+ resets = <&cpg 0x7f>, <&cpg 0x80>;
+ reset-names = "presetn", "tresetn";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
2025-06-24 19:22 [PATCH 0/6] Add RSPI support for RZ/V2H Fabrizio Castro
2025-06-24 19:22 ` [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs Fabrizio Castro
2025-06-24 19:23 ` [PATCH 2/6] spi: dt-bindings: Document the RZ/V2H(P) RSPI Fabrizio Castro
@ 2025-06-24 19:23 ` Fabrizio Castro
2025-06-25 10:19 ` Biju Das
` (2 more replies)
2025-06-24 19:23 ` [PATCH 4/6] MAINTAINERS: Add entries for the RZ/V2H(P) RSPI Fabrizio Castro
` (3 subsequent siblings)
6 siblings, 3 replies; 21+ messages in thread
From: Fabrizio Castro @ 2025-06-24 19:23 UTC (permalink / raw)
To: Mark Brown, Fabrizio Castro, Philipp Zabel, Geert Uytterhoeven,
Magnus Damm
Cc: linux-kernel, linux-spi, linux-renesas-soc, Biju Das,
Lad Prabhakar
The Renesas RZ/V2H(P) RSPI IP supports 4-wire and 3-wire
serial communications in both host role and target role.
It can use a DMA, but the I/O can also be driven by the
processor.
RX-only, TX-only, and RX-TX operations are available in
DMA mode, while in processor I/O mode it only RX-TX
operations are supported.
Add a driver to support 4-wire serial communications as
host role in processor I/O mode.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
I have noticed a problem when unbinding the driver that is solved by:
https://lore.kernel.org/all/20250616135357.3929441-1-claudiu.beznea.uj@bp.renesas.com/
Once the above series gets accepted I'll send a patch to add runtime pm
support, and I'll also switch to using devm_spi_register_controller.
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-rzv2h-rspi.c | 469 +++++++++++++++++++++++++++++++++++
3 files changed, 478 insertions(+)
create mode 100644 drivers/spi/spi-rzv2h-rspi.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index f2d2295a5501..fcc6987945fa 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -923,6 +923,14 @@ config SPI_RSPI
help
SPI driver for Renesas RSPI and QSPI blocks.
+config SPI_RZV2H_RSPI
+ tristate "Renesas RZ/V2H RSPI controller"
+ depends on ARCH_RENESAS || COMPILE_TEST
+ help
+ RSPI driver for the Renesas RZ/V2H Serial Peripheral Interface (RSPI).
+ RSPI supports both SPI host and SPI target roles. This option only
+ enables the SPI host role.
+
config SPI_RZV2M_CSI
tristate "Renesas RZ/V2M CSI controller"
depends on ARCH_RENESAS || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 4ea89f6fc531..c19d02653b8a 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -126,6 +126,7 @@ obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
obj-$(CONFIG_SPI_REALTEK_SNAND) += spi-realtek-rtl-snand.o
obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
+obj-$(CONFIG_SPI_RZV2H_RSPI) += spi-rzv2h-rspi.o
obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o
obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o
obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
new file mode 100644
index 000000000000..9541f2c2ab2b
--- /dev/null
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -0,0 +1,469 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Renesas RZ/V2H Renesas Serial Peripheral Interface (RSPI)
+ *
+ * Copyright (C) 2025 Renesas Electronics Corporation
+ */
+
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/limits.h>
+#include <linux/log2.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/reset.h>
+#include <linux/spi/spi.h>
+
+/* Registers */
+#define RSPI_SPDR 0x00
+#define RSPI_SPCR 0x08
+#define RSPI_SSLP 0x10
+#define RSPI_SPBR 0x11
+#define RSPI_SPSCR 0x13
+#define RSPI_SPCMD 0x14
+#define RSPI_SPDCR2 0x44
+#define RSPI_SPSR 0x52
+#define RSPI_SPSRC 0x6a
+#define RSPI_SPFCR 0x6c
+
+/* Register SPCR */
+#define RSPI_SPCR_MSTR BIT(30)
+#define RSPI_SPCR_SPRIE BIT(17)
+#define RSPI_SPCR_SCKASE BIT(12)
+#define RSPI_SPCR_SPE BIT(0)
+
+/* Register SPBR */
+#define RSPI_SPBR_SPR_MIN 0
+#define RSPI_SPBR_SPR_MAX 255
+
+/* Register SPCMD */
+#define RSPI_SPCMD_SSLA GENMASK(25, 24)
+#define RSPI_SPCMD_SPB GENMASK(20, 16)
+#define RSPI_SPCMD_LSBF BIT(12)
+#define RSPI_SPCMD_SSLKP BIT(7)
+#define RSPI_SPCMD_BRDV GENMASK(3, 2)
+#define RSPI_SPCMD_CPOL BIT(1)
+#define RSPI_SPCMD_CPHA BIT(0)
+
+#define RSPI_SPCMD_BRDV_MIN 0
+#define RSPI_SPCMD_BRDV_MAX 3
+
+/* Register SPDCR2 */
+#define RSPI_SPDCR2_TTRG GENMASK(11, 8)
+#define RSPI_SPDCR2_RTRG GENMASK(3, 0)
+#define RSPI_FIFO_SIZE 16
+
+/* Register SPSR */
+#define RSPI_SPSR_SPRF BIT(15)
+
+/* Register RSPI_SPSRC */
+#define RSPI_SPSRC_CLEAR 0xfd80
+
+#define RSPI_RESET_NUM 2
+
+enum rspi_clocks {
+ RSPI_CLK_PCLK,
+ RSPI_CLK_PCLK_SFR,
+ RSPI_CLK_TCLK,
+ RSPI_CLK_NUM
+};
+
+struct rzv2h_rspi_priv {
+ struct reset_control_bulk_data resets[RSPI_RESET_NUM];
+ struct clk_bulk_data clks[RSPI_CLK_NUM];
+ struct spi_controller *controller;
+ void __iomem *base;
+ wait_queue_head_t wait;
+ unsigned int bytes_per_word;
+ u32 freq;
+ u16 status;
+};
+
+#define RZV2H_RSPI_TX(func, type) \
+static inline void rzv2h_rspi_tx_##type(struct rzv2h_rspi_priv *rspi, \
+ const void *txbuf, \
+ unsigned int index) { \
+ type buf = 0; \
+ \
+ if (txbuf) \
+ buf = ((type *)txbuf)[index]; \
+ \
+ func(buf, rspi->base + RSPI_SPDR); \
+}
+
+#define RZV2H_RSPI_RX(func, type) \
+static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
+ void *rxbuf, \
+ unsigned int index) { \
+ type buf = func(rspi->base + RSPI_SPDR); \
+ \
+ if (rxbuf) \
+ ((type *)rxbuf)[index] = buf; \
+}
+
+RZV2H_RSPI_TX(writel, u32)
+RZV2H_RSPI_TX(writew, u16)
+RZV2H_RSPI_TX(writeb, u8)
+RZV2H_RSPI_RX(readl, u32)
+RZV2H_RSPI_RX(readw, u16)
+RZV2H_RSPI_RX(readl, u8)
+
+static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
+ int reg_offs, u32 bit_mask, u32 value)
+{
+ u32 tmp;
+
+ value <<= __ffs(bit_mask);
+ tmp = (readl(rspi->base + reg_offs) & ~bit_mask) | value;
+ writel(tmp, rspi->base + reg_offs);
+}
+
+static inline void rzv2h_rspi_spe_disable(const struct rzv2h_rspi_priv *rspi)
+{
+ rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 0);
+}
+
+static inline void rzv2h_rspi_spe_enable(const struct rzv2h_rspi_priv *rspi)
+{
+ rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 1);
+}
+
+static inline void rzv2h_rspi_clear_fifos(const struct rzv2h_rspi_priv *rspi)
+{
+ writeb(1, rspi->base + RSPI_SPFCR);
+}
+
+static inline void rzv2h_rspi_clear_all_irqs(struct rzv2h_rspi_priv *rspi)
+{
+ writew(RSPI_SPSRC_CLEAR, rspi->base + RSPI_SPSRC);
+ rspi->status = 0;
+}
+
+static irqreturn_t rzv2h_rx_irq_handler(int irq, void *data)
+{
+ struct rzv2h_rspi_priv *rspi = data;
+
+ rspi->status = readw(rspi->base + RSPI_SPSR);
+ wake_up(&rspi->wait);
+
+ return IRQ_HANDLED;
+}
+
+static inline int rzv2h_rspi_wait_for_interrupt(struct rzv2h_rspi_priv *rspi,
+ u32 wait_mask)
+{
+ return wait_event_timeout(rspi->wait, (rspi->status & wait_mask),
+ HZ) == 0 ? -ETIMEDOUT : 0;
+}
+
+static void rzv2h_rspi_send(struct rzv2h_rspi_priv *rspi, const void *txbuf,
+ unsigned int index)
+{
+ switch (rspi->bytes_per_word) {
+ case 4:
+ rzv2h_rspi_tx_u32(rspi, txbuf, index);
+ break;
+ case 2:
+ rzv2h_rspi_tx_u16(rspi, txbuf, index);
+ break;
+ default:
+ rzv2h_rspi_tx_u8(rspi, txbuf, index);
+ }
+}
+
+static int rzv2h_rspi_receive(struct rzv2h_rspi_priv *rspi, void *rxbuf,
+ unsigned int index)
+{
+ int ret;
+
+ ret = rzv2h_rspi_wait_for_interrupt(rspi, RSPI_SPSR_SPRF);
+ if (ret)
+ return ret;
+
+ switch (rspi->bytes_per_word) {
+ case 4:
+ rzv2h_rspi_rx_u32(rspi, rxbuf, index);
+ break;
+ case 2:
+ rzv2h_rspi_rx_u16(rspi, rxbuf, index);
+ break;
+ default:
+ rzv2h_rspi_rx_u8(rspi, rxbuf, index);
+ }
+
+ return 0;
+}
+
+static int rzv2h_rspi_transfer_one(struct spi_controller *controller,
+ struct spi_device *spi,
+ struct spi_transfer *transfer)
+{
+ struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(controller);
+ unsigned int words_to_transfer, i;
+ int ret = 0;
+
+ transfer->effective_speed_hz = rspi->freq;
+ words_to_transfer = transfer->len / rspi->bytes_per_word;
+
+ for (i = 0; i < words_to_transfer; i++) {
+ rzv2h_rspi_clear_all_irqs(rspi);
+
+ rzv2h_rspi_send(rspi, transfer->tx_buf, i);
+
+ ret = rzv2h_rspi_receive(rspi, transfer->rx_buf, i);
+ if (ret)
+ break;
+ }
+
+ rzv2h_rspi_clear_all_irqs(rspi);
+
+ if (ret)
+ transfer->error = SPI_TRANS_FAIL_IO;
+
+ spi_finalize_current_transfer(controller);
+
+ return ret;
+}
+
+static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
+ u8 brdv)
+{
+ return DIV_ROUND_UP(tclk_rate, (2 * (spr + 1) * (1 << brdv)));
+}
+
+static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
+{
+ unsigned long tclk_rate;
+ int spr;
+ u8 brdv;
+
+ /*
+ * From the manual:
+ * Bit rate = f(RSPI_n_TCLK)/(2*(n+1)*2^(N))
+ *
+ * Where:
+ * * RSPI_n_TCLK is fixed to 200MHz on V2H
+ * * n = SPR - is RSPI_SPBR.SPR (from 0 to 255)
+ * * N = BRDV - is RSPI_SPCMD.BRDV (from 0 to 3)
+ */
+ tclk_rate = clk_get_rate(rspi->clks[RSPI_CLK_TCLK].clk);
+ for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
+ spr = DIV_ROUND_UP(tclk_rate, hz * (1 << (brdv + 1)));
+ spr--;
+ if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
+ goto clock_found;
+ }
+
+ return 0;
+
+clock_found:
+ rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_BRDV, brdv);
+ writeb(spr, rspi->base + RSPI_SPBR);
+
+ return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv);
+}
+
+static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
+ struct spi_message *message)
+{
+ struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
+ const struct spi_device *spi = message->spi;
+ struct spi_transfer *xfer;
+ u32 speed_hz = U32_MAX;
+ u8 bits_per_word;
+ u32 conf32;
+ u16 conf16;
+
+ /* Make sure SPCR.SPE is 0 before amending the configuration */
+ rzv2h_rspi_spe_disable(rspi);
+
+ /* Configure the device to work in "host" mode */
+ conf32 = RSPI_SPCR_MSTR;
+
+ /* Auto-stop function */
+ conf32 |= RSPI_SPCR_SCKASE;
+
+ /* SPI receive buffer full interrupt enable */
+ conf32 |= RSPI_SPCR_SPRIE;
+
+ writel(conf32, rspi->base + RSPI_SPCR);
+
+ /* Use SPCMD0 only */
+ writeb(0x0, rspi->base + RSPI_SPSCR);
+
+ /* Setup mode */
+ conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL));
+ conf32 |= FIELD_PREP(RSPI_SPCMD_CPHA, !!(spi->mode & SPI_CPHA));
+ conf32 |= FIELD_PREP(RSPI_SPCMD_LSBF, !!(spi->mode & SPI_LSB_FIRST));
+ conf32 |= FIELD_PREP(RSPI_SPCMD_SSLKP, 1);
+ conf32 |= FIELD_PREP(RSPI_SPCMD_SSLA, spi_get_chipselect(spi, 0));
+ writel(conf32, rspi->base + RSPI_SPCMD);
+ if (spi->mode & SPI_CS_HIGH)
+ writeb(BIT(spi_get_chipselect(spi, 0)), rspi->base + RSPI_SSLP);
+ else
+ writeb(0, rspi->base + RSPI_SSLP);
+
+ /* Setup FIFO thresholds */
+ conf16 = FIELD_PREP(RSPI_SPDCR2_TTRG, RSPI_FIFO_SIZE - 1);
+ conf16 |= FIELD_PREP(RSPI_SPDCR2_RTRG, 0);
+ writew(conf16, rspi->base + RSPI_SPDCR2);
+
+ rzv2h_rspi_clear_fifos(rspi);
+
+ list_for_each_entry(xfer, &message->transfers, transfer_list) {
+ if (!xfer->speed_hz)
+ continue;
+
+ speed_hz = min(xfer->speed_hz, speed_hz);
+ bits_per_word = xfer->bits_per_word;
+ }
+
+ if (speed_hz == U32_MAX)
+ return -EINVAL;
+
+ rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word));
+ rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_SPB, bits_per_word - 1);
+
+ rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
+ if (!rspi->freq)
+ return -EINVAL;
+
+ rzv2h_rspi_spe_enable(rspi);
+
+ return 0;
+}
+
+static int rzv2h_rspi_unprepare_message(struct spi_controller *ctlr,
+ struct spi_message *message)
+{
+ struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
+
+ rzv2h_rspi_spe_disable(rspi);
+ rzv2h_rspi_clear_fifos(rspi);
+
+ return 0;
+}
+
+static int rzv2h_rspi_probe(struct platform_device *pdev)
+{
+ struct spi_controller *controller;
+ struct device *dev = &pdev->dev;
+ struct rzv2h_rspi_priv *rspi;
+ unsigned long tclk_rate;
+ int irq_rx, ret;
+
+ controller = devm_spi_alloc_host(dev, sizeof(*rspi));
+ if (!controller)
+ return -ENOMEM;
+
+ rspi = spi_controller_get_devdata(controller);
+ platform_set_drvdata(pdev, rspi);
+
+ rspi->controller = controller;
+
+ rspi->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rspi->base))
+ return PTR_ERR(rspi->base);
+
+ rspi->clks[RSPI_CLK_PCLK].id = "pclk";
+ rspi->clks[RSPI_CLK_PCLK_SFR].id = "pclk_sfr";
+ rspi->clks[RSPI_CLK_TCLK].id = "tclk";
+ ret = devm_clk_bulk_get(dev, RSPI_CLK_NUM, rspi->clks);
+ if (ret)
+ return dev_err_probe(dev, ret, "cannot get clocks\n");
+
+ rspi->resets[0].id = "presetn";
+ rspi->resets[1].id = "tresetn";
+ ret = devm_reset_control_bulk_get_exclusive(dev, RSPI_RESET_NUM,
+ rspi->resets);
+ if (ret)
+ return dev_err_probe(dev, ret, "cannot get resets\n");
+
+ irq_rx = platform_get_irq_byname(pdev, "rx");
+ if (irq_rx < 0)
+ return dev_err_probe(dev, irq_rx, "cannot get IRQ 'rx'\n");
+
+ ret = devm_request_irq(dev, irq_rx, rzv2h_rx_irq_handler, 0,
+ dev_name(dev), rspi);
+ if (ret)
+ return dev_err_probe(dev, ret, "cannot request `rx` IRQ\n");
+
+ ret = clk_bulk_prepare_enable(RSPI_CLK_NUM, rspi->clks);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to enable clocks\n");
+
+ ret = reset_control_bulk_deassert(RSPI_RESET_NUM, rspi->resets);
+ if (ret) {
+ dev_err(dev, "failed to deassert resets\n");
+ goto quit_clocks;
+ }
+
+ init_waitqueue_head(&rspi->wait);
+
+ tclk_rate = clk_get_rate(rspi->clks[RSPI_CLK_TCLK].clk);
+
+ controller->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH |
+ SPI_LSB_FIRST;
+ controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+ controller->prepare_message = rzv2h_rspi_prepare_message;
+ controller->unprepare_message = rzv2h_rspi_unprepare_message;
+ controller->num_chipselect = 4;
+ controller->transfer_one = rzv2h_rspi_transfer_one;
+ controller->min_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
+ RSPI_SPBR_SPR_MAX,
+ RSPI_SPCMD_BRDV_MAX);
+ controller->max_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
+ RSPI_SPBR_SPR_MIN,
+ RSPI_SPCMD_BRDV_MIN);
+
+ device_set_node(&controller->dev, dev_fwnode(dev));
+
+ ret = spi_register_controller(controller);
+ if (ret) {
+ dev_err(dev, "register controller failed\n");
+ goto quit_resets;
+ }
+
+ return 0;
+
+quit_resets:
+ reset_control_bulk_assert(RSPI_RESET_NUM, rspi->resets);
+
+quit_clocks:
+ clk_bulk_disable_unprepare(RSPI_CLK_NUM, rspi->clks);
+
+ return ret;
+}
+
+static void rzv2h_rspi_remove(struct platform_device *pdev)
+{
+ struct rzv2h_rspi_priv *rspi = platform_get_drvdata(pdev);
+
+ spi_unregister_controller(rspi->controller);
+
+ reset_control_bulk_assert(RSPI_RESET_NUM, rspi->resets);
+ clk_bulk_disable_unprepare(RSPI_CLK_NUM, rspi->clks);
+}
+
+static const struct of_device_id rzv2h_rspi_match[] = {
+ { .compatible = "renesas,r9a09g057-rspi" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rzv2h_rspi_match);
+
+static struct platform_driver rzv2h_rspi_drv = {
+ .probe = rzv2h_rspi_probe,
+ .remove = rzv2h_rspi_remove,
+ .driver = {
+ .name = "rzv2h_rspi",
+ .of_match_table = rzv2h_rspi_match,
+ },
+};
+module_platform_driver(rzv2h_rspi_drv);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro.jz@renesas.com>");
+MODULE_DESCRIPTION("Renesas RZ/V2H(P) Serial Peripheral Interface Driver");
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/6] MAINTAINERS: Add entries for the RZ/V2H(P) RSPI
2025-06-24 19:22 [PATCH 0/6] Add RSPI support for RZ/V2H Fabrizio Castro
` (2 preceding siblings ...)
2025-06-24 19:23 ` [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP Fabrizio Castro
@ 2025-06-24 19:23 ` Fabrizio Castro
2025-07-01 13:30 ` Geert Uytterhoeven
2025-06-24 19:23 ` [PATCH 5/6] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver Fabrizio Castro
` (2 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Fabrizio Castro @ 2025-06-24 19:23 UTC (permalink / raw)
To: Geert Uytterhoeven, Magnus Damm
Cc: Fabrizio Castro, linux-kernel, linux-renesas-soc, Biju Das,
Lad Prabhakar
Add the MAINTAINERS entries for the Renesas RZ/V2H(P) RSPI
driver.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
MAINTAINERS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8d9b940ee8ee..f467e6900c09 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21219,6 +21219,14 @@ S: Maintained
F: Documentation/devicetree/bindings/net/renesas,r9a09g057-gbeth.yaml
F: drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
+RENESAS RZ/V2H(P) RSPI DRIVER
+M: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+L: linux-spi@vger.kernel.org
+L: linux-renesas-soc@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
+F: drivers/spi/spi-rzv2h-rspi.c
+
RENESAS RZ/V2H(P) USB2PHY PORT RESET DRIVER
M: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
M: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 5/6] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver
2025-06-24 19:22 [PATCH 0/6] Add RSPI support for RZ/V2H Fabrizio Castro
` (3 preceding siblings ...)
2025-06-24 19:23 ` [PATCH 4/6] MAINTAINERS: Add entries for the RZ/V2H(P) RSPI Fabrizio Castro
@ 2025-06-24 19:23 ` Fabrizio Castro
2025-07-01 13:31 ` Geert Uytterhoeven
2025-06-24 19:23 ` [PATCH 6/6] arm64: dts: renesas: r9a09g057: Add RSPI nodes Fabrizio Castro
2025-06-25 7:59 ` [PATCH 0/6] Add RSPI support for RZ/V2H Chris Paterson
6 siblings, 1 reply; 21+ messages in thread
From: Fabrizio Castro @ 2025-06-24 19:23 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Geert Uytterhoeven
Cc: Fabrizio Castro, Krzysztof Kozlowski, Bjorn Andersson,
Nishanth Menon, Arnd Bergmann, Lad Prabhakar,
Nícolas F. R. A. Prado, Taniya Das, Kuninori Morimoto,
Eric Biggers, linux-arm-kernel, linux-kernel, Biju Das,
linux-renesas-soc
Enable the Renesas RZ/V2H(P) RSPI driver for the benefit of
RZ/V2H(P) based platforms.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 42ec6e4ce407..64e7fdad51fd 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -575,6 +575,7 @@ CONFIG_SPI_ROCKCHIP=y
CONFIG_SPI_ROCKCHIP_SFC=m
CONFIG_SPI_RPCIF=m
CONFIG_SPI_RSPI=m
+CONFIG_SPI_RZV2H_RSPI=m
CONFIG_SPI_RZV2M_CSI=m
CONFIG_SPI_QCOM_QSPI=m
CONFIG_SPI_QUP=y
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 6/6] arm64: dts: renesas: r9a09g057: Add RSPI nodes
2025-06-24 19:22 [PATCH 0/6] Add RSPI support for RZ/V2H Fabrizio Castro
` (4 preceding siblings ...)
2025-06-24 19:23 ` [PATCH 5/6] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver Fabrizio Castro
@ 2025-06-24 19:23 ` Fabrizio Castro
2025-07-01 13:32 ` Geert Uytterhoeven
2025-06-25 7:59 ` [PATCH 0/6] Add RSPI support for RZ/V2H Chris Paterson
6 siblings, 1 reply; 21+ messages in thread
From: Fabrizio Castro @ 2025-06-24 19:23 UTC (permalink / raw)
To: Geert Uytterhoeven, Magnus Damm, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Fabrizio Castro, linux-renesas-soc, devicetree, linux-kernel,
Biju Das, Lad Prabhakar
Add nodes for the RSPI IPs found in the Renesas RZ/V2H(P) SoC.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
arch/arm64/boot/dts/renesas/r9a09g057.dtsi | 63 ++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi
index 45aedd62a259..ae1f88b7aac5 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi
@@ -586,6 +586,69 @@ scif: serial@11c01400 {
status = "disabled";
};
+ rspi0: spi@12800000 {
+ compatible = "renesas,r9a09g057-rspi";
+ reg = <0x0 0x12800000 0x0 0x400>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 500 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 501 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_MOD 0x54>,
+ <&cpg CPG_MOD 0x55>,
+ <&cpg CPG_MOD 0x56>;
+ clock-names = "pclk", "pclk_sfr", "tclk";
+ resets = <&cpg 0x7b>, <&cpg 0x7c>;
+ reset-names = "presetn", "tresetn";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rspi1: spi@12800400 {
+ compatible = "renesas,r9a09g057-rspi";
+ reg = <0x0 0x12800400 0x0 0x400>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 502 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 503 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_MOD 0x57>,
+ <&cpg CPG_MOD 0x58>,
+ <&cpg CPG_MOD 0x59>;
+ clock-names = "pclk", "pclk_sfr", "tclk";
+ resets = <&cpg 0x7d>, <&cpg 0x7e>;
+ reset-names = "presetn", "tresetn";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rspi2: spi@12800800 {
+ compatible = "renesas,r9a09g057-rspi";
+ reg = <0x0 0x12800800 0x0 0x400>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 504 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 505 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_MOD 0x5a>,
+ <&cpg CPG_MOD 0x5b>,
+ <&cpg CPG_MOD 0x5c>;
+ clock-names = "pclk", "pclk_sfr", "tclk";
+ resets = <&cpg 0x7f>, <&cpg 0x80>;
+ reset-names = "presetn", "tresetn";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
i2c0: i2c@14400400 {
compatible = "renesas,riic-r9a09g057";
reg = <0 0x14400400 0 0x400>;
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* RE: [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs
2025-06-24 19:22 ` [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs Fabrizio Castro
@ 2025-06-24 19:37 ` Biju Das
2025-07-01 13:17 ` Geert Uytterhoeven
1 sibling, 0 replies; 21+ messages in thread
From: Biju Das @ 2025-06-24 19:37 UTC (permalink / raw)
To: Fabrizio Castro, Geert Uytterhoeven, Michael Turquette,
Stephen Boyd
Cc: Fabrizio Castro, linux-renesas-soc@vger.kernel.org,
linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org,
Prabhakar Mahadev Lad
Hi Fabrizio,
Thanks for the patch.
> -----Original Message-----
> From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> Sent: 24 June 2025 20:23
> Subject: [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs
>
> Add clock and reset entries for the Renesas RZ/V2H(P) RSPI IPs.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Cheers,
Biju
> ---
> drivers/clk/renesas/r9a09g057-cpg.c | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c
> index da908e820950..f39bd2e78312 100644
> --- a/drivers/clk/renesas/r9a09g057-cpg.c
> +++ b/drivers/clk/renesas/r9a09g057-cpg.c
> @@ -217,6 +217,24 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = {
> BUS_MSTOP(5, BIT(13))),
> DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18,
> BUS_MSTOP(5, BIT(13))),
> + DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20,
> + BUS_MSTOP(11, BIT(0))),
> + DEF_MOD("rspi_0_pclk_sfr", CLK_PLLCLN_DIV8, 5, 5, 2, 21,
> + BUS_MSTOP(11, BIT(0))),
> + DEF_MOD("rspi_0_tclk", CLK_PLLCLN_DIV8, 5, 6, 2, 22,
> + BUS_MSTOP(11, BIT(0))),
> + DEF_MOD("rspi_1_pclk", CLK_PLLCLN_DIV8, 5, 7, 2, 23,
> + BUS_MSTOP(11, BIT(1))),
> + DEF_MOD("rspi_1_pclk_sfr", CLK_PLLCLN_DIV8, 5, 8, 2, 24,
> + BUS_MSTOP(11, BIT(1))),
> + DEF_MOD("rspi_1_tclk", CLK_PLLCLN_DIV8, 5, 9, 2, 25,
> + BUS_MSTOP(11, BIT(1))),
> + DEF_MOD("rspi_2_pclk", CLK_PLLCLN_DIV8, 5, 10, 2, 26,
> + BUS_MSTOP(11, BIT(2))),
> + DEF_MOD("rspi_2_pclk_sfr", CLK_PLLCLN_DIV8, 5, 11, 2, 27,
> + BUS_MSTOP(11, BIT(2))),
> + DEF_MOD("rspi_2_tclk", CLK_PLLCLN_DIV8, 5, 12, 2, 28,
> + BUS_MSTOP(11, BIT(2))),
> DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15,
> BUS_MSTOP(3, BIT(14))),
> DEF_MOD("riic_8_ckm", CLK_PLLCM33_DIV16, 9, 3, 4, 19,
> @@ -349,6 +367,12 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = {
> DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */
> DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */
> DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */
> + DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */
> + DEF_RST(7, 12, 3, 13), /* RSPI_0_TRESETN */
> + DEF_RST(7, 13, 3, 14), /* RSPI_1_PRESETN */
> + DEF_RST(7, 14, 3, 15), /* RSPI_1_TRESETN */
> + DEF_RST(7, 15, 3, 16), /* RSPI_2_PRESETN */
> + DEF_RST(8, 0, 3, 17), /* RSPI_2_TRESETN */
> DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */
> DEF_RST(9, 8, 4, 9), /* RIIC_0_MRST */
> DEF_RST(9, 9, 4, 10), /* RIIC_1_MRST */
> --
> 2.34.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH 0/6] Add RSPI support for RZ/V2H
2025-06-24 19:22 [PATCH 0/6] Add RSPI support for RZ/V2H Fabrizio Castro
` (5 preceding siblings ...)
2025-06-24 19:23 ` [PATCH 6/6] arm64: dts: renesas: r9a09g057: Add RSPI nodes Fabrizio Castro
@ 2025-06-25 7:59 ` Chris Paterson
2025-06-25 8:21 ` Fabrizio Castro
6 siblings, 1 reply; 21+ messages in thread
From: Chris Paterson @ 2025-06-25 7:59 UTC (permalink / raw)
To: Fabrizio Castro, Fabrizio Castro, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Catalin Marinas, Will Deacon, Michael Turquette,
Stephen Boyd, Philipp Zabel
Cc: Bjorn Andersson, Arnd Bergmann, Nishanth Menon,
Prabhakar Mahadev Lad, Nícolas F. R. A. Prado, Taniya Das,
Eric Biggers, Kuninori Morimoto, linux-spi@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
Biju Das
Hi Fabrizio,
> From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> Sent: 24 June 2025 20:23
>
> From: SPL2 Bot <spl2-bot-eu@lm.renesas.com>
From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Script fail?
The patches in the series look okay.
Kind regards, Chris
>
> Dear All,
>
> This series adds support for the Renesas RZ/V2H RSPI IP.
>
> Cheers,
> Fab
>
> Fabrizio Castro (6):
> clk: renesas: r9a09g057: Add entries for the RSPIs
> spi: dt-bindings: Document the RZ/V2H(P) RSPI
> spi: Add driver for the RZ/V2H(P) RSPI IP
> MAINTAINERS: Add entries for the RZ/V2H(P) RSPI
> arm64: defconfig: Enable the RZ/V2H(P) RSPI driver
> arm64: dts: renesas: r9a09g057: Add RSPI nodes
>
> .../bindings/spi/renesas,rzv2h-rspi.yaml | 96 ++++
> MAINTAINERS | 8 +
> arch/arm64/boot/dts/renesas/r9a09g057.dtsi | 63 +++
> arch/arm64/configs/defconfig | 1 +
> drivers/clk/renesas/r9a09g057-cpg.c | 24 +
> drivers/spi/Kconfig | 8 +
> drivers/spi/Makefile | 1 +
> drivers/spi/spi-rzv2h-rspi.c | 469 ++++++++++++++++++
> 8 files changed, 670 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/spi/renesas,rzv2h-
> rspi.yaml
> create mode 100644 drivers/spi/spi-rzv2h-rspi.c
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH 0/6] Add RSPI support for RZ/V2H
2025-06-25 7:59 ` [PATCH 0/6] Add RSPI support for RZ/V2H Chris Paterson
@ 2025-06-25 8:21 ` Fabrizio Castro
0 siblings, 0 replies; 21+ messages in thread
From: Fabrizio Castro @ 2025-06-25 8:21 UTC (permalink / raw)
To: Chris Paterson, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Geert Uytterhoeven, Magnus Damm, Catalin Marinas,
Will Deacon, Michael Turquette, Stephen Boyd, Philipp Zabel
Cc: Bjorn Andersson, Arnd Bergmann, Nishanth Menon,
Prabhakar Mahadev Lad, Nícolas F. R. A. Prado, Taniya Das,
Eric Biggers, Kuninori Morimoto, linux-spi@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
Biju Das
Hi Chris,
> From: Chris Paterson <Chris.Paterson2@renesas.com>
> Sent: 25 June 2025 09:00
> To: Fabrizio Castro <fabrizio.castro.jz@renesas.com>; Fabrizio Castro
> Subject: RE: [PATCH 0/6] Add RSPI support for RZ/V2H
>
> Hi Fabrizio,
>
> > From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> > Sent: 24 June 2025 20:23
> >
> > From: SPL2 Bot <spl2-bot-eu@lm.renesas.com>
Doh!
> From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
>
> Script fail?
Indeed, thankfully it's just the cover letter.
Thanks for highlighting this.
Cheers,
Fab
> The patches in the series look okay.
>
> Kind regards, Chris
>
> >
> > Dear All,
> >
> > This series adds support for the Renesas RZ/V2H RSPI IP.
> >
> > Cheers,
> > Fab
> >
> > Fabrizio Castro (6):
> > clk: renesas: r9a09g057: Add entries for the RSPIs
> > spi: dt-bindings: Document the RZ/V2H(P) RSPI
> > spi: Add driver for the RZ/V2H(P) RSPI IP
> > MAINTAINERS: Add entries for the RZ/V2H(P) RSPI
> > arm64: defconfig: Enable the RZ/V2H(P) RSPI driver
> > arm64: dts: renesas: r9a09g057: Add RSPI nodes
> >
> > .../bindings/spi/renesas,rzv2h-rspi.yaml | 96 ++++
> > MAINTAINERS | 8 +
> > arch/arm64/boot/dts/renesas/r9a09g057.dtsi | 63 +++
> > arch/arm64/configs/defconfig | 1 +
> > drivers/clk/renesas/r9a09g057-cpg.c | 24 +
> > drivers/spi/Kconfig | 8 +
> > drivers/spi/Makefile | 1 +
> > drivers/spi/spi-rzv2h-rspi.c | 469 ++++++++++++++++++
> > 8 files changed, 670 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/spi/renesas,rzv2h-
> > rspi.yaml
> > create mode 100644 drivers/spi/spi-rzv2h-rspi.c
> >
> > --
> > 2.34.1
> >
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
2025-06-24 19:23 ` [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP Fabrizio Castro
@ 2025-06-25 10:19 ` Biju Das
2025-07-04 14:14 ` Fabrizio Castro
2025-06-25 11:32 ` kernel test robot
2025-06-25 19:09 ` Mark Brown
2 siblings, 1 reply; 21+ messages in thread
From: Biju Das @ 2025-06-25 10:19 UTC (permalink / raw)
To: Fabrizio Castro, Mark Brown, Fabrizio Castro, Philipp Zabel,
Geert Uytterhoeven, Magnus Damm
Cc: linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, Prabhakar Mahadev Lad
Hi Fabrizio,
Thanks for the patch.
> -----Original Message-----
> From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> Sent: 24 June 2025 20:23
> Das <biju.das.jz@bp.renesas.com>; Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Subject: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
>
> The Renesas RZ/V2H(P) RSPI IP supports 4-wire and 3-wire serial communications in both host role and
> target role.
> It can use a DMA, but the I/O can also be driven by the processor.
>
> RX-only, TX-only, and RX-TX operations are available in DMA mode, while in processor I/O mode it only
> RX-TX operations are supported.
>
> Add a driver to support 4-wire serial communications as host role in processor I/O mode.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> ---
>
> I have noticed a problem when unbinding the driver that is solved by:
> https://lore.kernel.org/all/20250616135357.3929441-1-claudiu.beznea.uj@bp.renesas.com/
>
> Once the above series gets accepted I'll send a patch to add runtime pm support, and I'll also switch
> to using devm_spi_register_controller.
>
> drivers/spi/Kconfig | 8 +
> drivers/spi/Makefile | 1 +
> drivers/spi/spi-rzv2h-rspi.c | 469 +++++++++++++++++++++++++++++++++++
> 3 files changed, 478 insertions(+)
> create mode 100644 drivers/spi/spi-rzv2h-rspi.c
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f2d2295a5501..fcc6987945fa 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -923,6 +923,14 @@ config SPI_RSPI
> help
> SPI driver for Renesas RSPI and QSPI blocks.
>
> +config SPI_RZV2H_RSPI
> + tristate "Renesas RZ/V2H RSPI controller"
> + depends on ARCH_RENESAS || COMPILE_TEST
> + help
> + RSPI driver for the Renesas RZ/V2H Serial Peripheral Interface (RSPI).
> + RSPI supports both SPI host and SPI target roles. This option only
> + enables the SPI host role.
> +
> config SPI_RZV2M_CSI
> tristate "Renesas RZ/V2M CSI controller"
> depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 4ea89f6fc531..c19d02653b8a 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -126,6 +126,7 @@ obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
> obj-$(CONFIG_SPI_REALTEK_SNAND) += spi-realtek-rtl-snand.o
> obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
> obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
> +obj-$(CONFIG_SPI_RZV2H_RSPI) += spi-rzv2h-rspi.o
> obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o
> obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o
> obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o
> diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c new file mode 100644 index
> 000000000000..9541f2c2ab2b
> --- /dev/null
> +++ b/drivers/spi/spi-rzv2h-rspi.c
> @@ -0,0 +1,469 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Renesas RZ/V2H Renesas Serial Peripheral Interface (RSPI)
> + *
> + * Copyright (C) 2025 Renesas Electronics Corporation */
> +
> +#include <linux/bitops.h>
> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/interrupt.h>
> +#include <linux/limits.h>
> +#include <linux/log2.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/reset.h>
> +#include <linux/spi/spi.h>
> +
> +/* Registers */
> +#define RSPI_SPDR 0x00
> +#define RSPI_SPCR 0x08
> +#define RSPI_SSLP 0x10
> +#define RSPI_SPBR 0x11
> +#define RSPI_SPSCR 0x13
> +#define RSPI_SPCMD 0x14
> +#define RSPI_SPDCR2 0x44
> +#define RSPI_SPSR 0x52
> +#define RSPI_SPSRC 0x6a
> +#define RSPI_SPFCR 0x6c
> +
> +/* Register SPCR */
> +#define RSPI_SPCR_MSTR BIT(30)
> +#define RSPI_SPCR_SPRIE BIT(17)
> +#define RSPI_SPCR_SCKASE BIT(12)
> +#define RSPI_SPCR_SPE BIT(0)
> +
> +/* Register SPBR */
> +#define RSPI_SPBR_SPR_MIN 0
> +#define RSPI_SPBR_SPR_MAX 255
> +
> +/* Register SPCMD */
> +#define RSPI_SPCMD_SSLA GENMASK(25, 24)
> +#define RSPI_SPCMD_SPB GENMASK(20, 16)
> +#define RSPI_SPCMD_LSBF BIT(12)
> +#define RSPI_SPCMD_SSLKP BIT(7)
> +#define RSPI_SPCMD_BRDV GENMASK(3, 2)
> +#define RSPI_SPCMD_CPOL BIT(1)
> +#define RSPI_SPCMD_CPHA BIT(0)
> +
> +#define RSPI_SPCMD_BRDV_MIN 0
> +#define RSPI_SPCMD_BRDV_MAX 3
> +
> +/* Register SPDCR2 */
> +#define RSPI_SPDCR2_TTRG GENMASK(11, 8)
> +#define RSPI_SPDCR2_RTRG GENMASK(3, 0)
> +#define RSPI_FIFO_SIZE 16
> +
> +/* Register SPSR */
> +#define RSPI_SPSR_SPRF BIT(15)
> +
> +/* Register RSPI_SPSRC */
> +#define RSPI_SPSRC_CLEAR 0xfd80
> +
> +#define RSPI_RESET_NUM 2
> +
> +enum rspi_clocks {
> + RSPI_CLK_PCLK,
> + RSPI_CLK_PCLK_SFR,
> + RSPI_CLK_TCLK,
> + RSPI_CLK_NUM
> +};
Do we need this enum?
> +
> +struct rzv2h_rspi_priv {
> + struct reset_control_bulk_data resets[RSPI_RESET_NUM];
> + struct clk_bulk_data clks[RSPI_CLK_NUM];
It is used only in probe/remove. By using devm_clk_bulk_get_all_enabled()
this can be local??
> + struct spi_controller *controller;
> + void __iomem *base;
> + wait_queue_head_t wait;
> + unsigned int bytes_per_word;
> + u32 freq;
> + u16 status;
> +};
> +
> +#define RZV2H_RSPI_TX(func, type) \
> +static inline void rzv2h_rspi_tx_##type(struct rzv2h_rspi_priv *rspi, \
> + const void *txbuf, \
> + unsigned int index) { \
> + type buf = 0; \
> + \
> + if (txbuf) \
> + buf = ((type *)txbuf)[index]; \
> + \
> + func(buf, rspi->base + RSPI_SPDR); \
> +}
> +
> +#define RZV2H_RSPI_RX(func, type) \
> +static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
> + void *rxbuf, \
> + unsigned int index) { \
> + type buf = func(rspi->base + RSPI_SPDR); \
> + \
> + if (rxbuf) \
> + ((type *)rxbuf)[index] = buf; \
> +}
> +
> +RZV2H_RSPI_TX(writel, u32)
> +RZV2H_RSPI_TX(writew, u16)
> +RZV2H_RSPI_TX(writeb, u8)
> +RZV2H_RSPI_RX(readl, u32)
> +RZV2H_RSPI_RX(readw, u16)
> +RZV2H_RSPI_RX(readl, u8)
> +
> +static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
> + int reg_offs, u32 bit_mask, u32 value) {
> + u32 tmp;
> +
> + value <<= __ffs(bit_mask);
> + tmp = (readl(rspi->base + reg_offs) & ~bit_mask) | value;
> + writel(tmp, rspi->base + reg_offs);
> +}
> +
> +static inline void rzv2h_rspi_spe_disable(const struct rzv2h_rspi_priv
> +*rspi) {
> + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 0); }
> +
> +static inline void rzv2h_rspi_spe_enable(const struct rzv2h_rspi_priv
> +*rspi) {
> + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 1); }
> +
> +static inline void rzv2h_rspi_clear_fifos(const struct rzv2h_rspi_priv
> +*rspi) {
> + writeb(1, rspi->base + RSPI_SPFCR);
> +}
> +
> +static inline void rzv2h_rspi_clear_all_irqs(struct rzv2h_rspi_priv
> +*rspi) {
> + writew(RSPI_SPSRC_CLEAR, rspi->base + RSPI_SPSRC);
> + rspi->status = 0;
> +}
> +
> +static irqreturn_t rzv2h_rx_irq_handler(int irq, void *data) {
> + struct rzv2h_rspi_priv *rspi = data;
> +
> + rspi->status = readw(rspi->base + RSPI_SPSR);
> + wake_up(&rspi->wait);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static inline int rzv2h_rspi_wait_for_interrupt(struct rzv2h_rspi_priv *rspi,
> + u32 wait_mask)
> +{
> + return wait_event_timeout(rspi->wait, (rspi->status & wait_mask),
> + HZ) == 0 ? -ETIMEDOUT : 0;
> +}
> +
> +static void rzv2h_rspi_send(struct rzv2h_rspi_priv *rspi, const void *txbuf,
> + unsigned int index)
> +{
> + switch (rspi->bytes_per_word) {
> + case 4:
> + rzv2h_rspi_tx_u32(rspi, txbuf, index);
> + break;
> + case 2:
> + rzv2h_rspi_tx_u16(rspi, txbuf, index);
> + break;
> + default:
> + rzv2h_rspi_tx_u8(rspi, txbuf, index);
> + }
> +}
> +
> +static int rzv2h_rspi_receive(struct rzv2h_rspi_priv *rspi, void *rxbuf,
> + unsigned int index)
> +{
> + int ret;
> +
> + ret = rzv2h_rspi_wait_for_interrupt(rspi, RSPI_SPSR_SPRF);
> + if (ret)
> + return ret;
> +
> + switch (rspi->bytes_per_word) {
> + case 4:
> + rzv2h_rspi_rx_u32(rspi, rxbuf, index);
> + break;
> + case 2:
> + rzv2h_rspi_rx_u16(rspi, rxbuf, index);
> + break;
> + default:
> + rzv2h_rspi_rx_u8(rspi, rxbuf, index);
> + }
> +
> + return 0;
> +}
> +
> +static int rzv2h_rspi_transfer_one(struct spi_controller *controller,
> + struct spi_device *spi,
> + struct spi_transfer *transfer)
> +{
> + struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(controller);
> + unsigned int words_to_transfer, i;
> + int ret = 0;
> +
> + transfer->effective_speed_hz = rspi->freq;
> + words_to_transfer = transfer->len / rspi->bytes_per_word;
> +
> + for (i = 0; i < words_to_transfer; i++) {
> + rzv2h_rspi_clear_all_irqs(rspi);
> +
> + rzv2h_rspi_send(rspi, transfer->tx_buf, i);
> +
> + ret = rzv2h_rspi_receive(rspi, transfer->rx_buf, i);
> + if (ret)
> + break;
> + }
> +
> + rzv2h_rspi_clear_all_irqs(rspi);
> +
> + if (ret)
> + transfer->error = SPI_TRANS_FAIL_IO;
> +
> + spi_finalize_current_transfer(controller);
> +
> + return ret;
> +}
> +
> +static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
> + u8 brdv)
> +{
> + return DIV_ROUND_UP(tclk_rate, (2 * (spr + 1) * (1 << brdv))); }
> +
> +static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
> +{
> + unsigned long tclk_rate;
> + int spr;
> + u8 brdv;
> +
> + /*
> + * From the manual:
> + * Bit rate = f(RSPI_n_TCLK)/(2*(n+1)*2^(N))
> + *
> + * Where:
> + * * RSPI_n_TCLK is fixed to 200MHz on V2H
> + * * n = SPR - is RSPI_SPBR.SPR (from 0 to 255)
> + * * N = BRDV - is RSPI_SPCMD.BRDV (from 0 to 3)
> + */
> + tclk_rate = clk_get_rate(rspi->clks[RSPI_CLK_TCLK].clk);
> + for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
> + spr = DIV_ROUND_UP(tclk_rate, hz * (1 << (brdv + 1)));
> + spr--;
> + if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
> + goto clock_found;
> + }
> +
> + return 0;
> +
> +clock_found:
> + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_BRDV, brdv);
> + writeb(spr, rspi->base + RSPI_SPBR);
> +
> + return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv); }
> +
> +static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
> + struct spi_message *message)
> +{
> + struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
> + const struct spi_device *spi = message->spi;
> + struct spi_transfer *xfer;
> + u32 speed_hz = U32_MAX;
> + u8 bits_per_word;
> + u32 conf32;
> + u16 conf16;
> +
> + /* Make sure SPCR.SPE is 0 before amending the configuration */
> + rzv2h_rspi_spe_disable(rspi);
> +
> + /* Configure the device to work in "host" mode */
> + conf32 = RSPI_SPCR_MSTR;
> +
> + /* Auto-stop function */
> + conf32 |= RSPI_SPCR_SCKASE;
> +
> + /* SPI receive buffer full interrupt enable */
> + conf32 |= RSPI_SPCR_SPRIE;
> +
> + writel(conf32, rspi->base + RSPI_SPCR);
> +
> + /* Use SPCMD0 only */
> + writeb(0x0, rspi->base + RSPI_SPSCR);
> +
> + /* Setup mode */
> + conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL));
> + conf32 |= FIELD_PREP(RSPI_SPCMD_CPHA, !!(spi->mode & SPI_CPHA));
> + conf32 |= FIELD_PREP(RSPI_SPCMD_LSBF, !!(spi->mode & SPI_LSB_FIRST));
> + conf32 |= FIELD_PREP(RSPI_SPCMD_SSLKP, 1);
> + conf32 |= FIELD_PREP(RSPI_SPCMD_SSLA, spi_get_chipselect(spi, 0));
> + writel(conf32, rspi->base + RSPI_SPCMD);
> + if (spi->mode & SPI_CS_HIGH)
> + writeb(BIT(spi_get_chipselect(spi, 0)), rspi->base + RSPI_SSLP);
> + else
> + writeb(0, rspi->base + RSPI_SSLP);
> +
> + /* Setup FIFO thresholds */
> + conf16 = FIELD_PREP(RSPI_SPDCR2_TTRG, RSPI_FIFO_SIZE - 1);
> + conf16 |= FIELD_PREP(RSPI_SPDCR2_RTRG, 0);
> + writew(conf16, rspi->base + RSPI_SPDCR2);
> +
> + rzv2h_rspi_clear_fifos(rspi);
> +
> + list_for_each_entry(xfer, &message->transfers, transfer_list) {
> + if (!xfer->speed_hz)
> + continue;
> +
> + speed_hz = min(xfer->speed_hz, speed_hz);
> + bits_per_word = xfer->bits_per_word;
> + }
> +
> + if (speed_hz == U32_MAX)
> + return -EINVAL;
> +
> + rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word));
> + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_SPB, bits_per_word -
> +1);
> +
> + rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
> + if (!rspi->freq)
> + return -EINVAL;
> +
> + rzv2h_rspi_spe_enable(rspi);
> +
> + return 0;
> +}
> +
> +static int rzv2h_rspi_unprepare_message(struct spi_controller *ctlr,
> + struct spi_message *message)
> +{
> + struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
> +
> + rzv2h_rspi_spe_disable(rspi);
> + rzv2h_rspi_clear_fifos(rspi);
> +
> + return 0;
> +}
> +
> +static int rzv2h_rspi_probe(struct platform_device *pdev) {
> + struct spi_controller *controller;
> + struct device *dev = &pdev->dev;
> + struct rzv2h_rspi_priv *rspi;
> + unsigned long tclk_rate;
> + int irq_rx, ret;
> +
> + controller = devm_spi_alloc_host(dev, sizeof(*rspi));
> + if (!controller)
> + return -ENOMEM;
> +
> + rspi = spi_controller_get_devdata(controller);
> + platform_set_drvdata(pdev, rspi);
> +
> + rspi->controller = controller;
> +
> + rspi->base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(rspi->base))
> + return PTR_ERR(rspi->base);
> +
> + rspi->clks[RSPI_CLK_PCLK].id = "pclk";
> + rspi->clks[RSPI_CLK_PCLK_SFR].id = "pclk_sfr";
> + rspi->clks[RSPI_CLK_TCLK].id = "tclk";
> + ret = devm_clk_bulk_get(dev, RSPI_CLK_NUM, rspi->clks);
> + if (ret)
> + return dev_err_probe(dev, ret, "cannot get clocks\n");
> +
> + rspi->resets[0].id = "presetn";
> + rspi->resets[1].id = "tresetn";
> + ret = devm_reset_control_bulk_get_exclusive(dev, RSPI_RESET_NUM,
> + rspi->resets);
> + if (ret)
> + return dev_err_probe(dev, ret, "cannot get resets\n");
> +
> + irq_rx = platform_get_irq_byname(pdev, "rx");
> + if (irq_rx < 0)
> + return dev_err_probe(dev, irq_rx, "cannot get IRQ 'rx'\n");
> +
> + ret = devm_request_irq(dev, irq_rx, rzv2h_rx_irq_handler, 0,
> + dev_name(dev), rspi);
> + if (ret)
> + return dev_err_probe(dev, ret, "cannot request `rx` IRQ\n");
> +
> + ret = clk_bulk_prepare_enable(RSPI_CLK_NUM, rspi->clks);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to enable clocks\n");
Can't we use devm_clk_bulk_get_all_enabled() instead that will fill struct clk_bulk_data??
> +
> + ret = reset_control_bulk_deassert(RSPI_RESET_NUM, rspi->resets);
> + if (ret) {
> + dev_err(dev, "failed to deassert resets\n");
> + goto quit_clocks;
> + }
> +
> + init_waitqueue_head(&rspi->wait);
> +
> + tclk_rate = clk_get_rate(rspi->clks[RSPI_CLK_TCLK].clk);
Is it not possible to get this clk from struct clk_bulk_data by using the id "tclk"??
Cheers,
Biju
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
2025-06-24 19:23 ` [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP Fabrizio Castro
2025-06-25 10:19 ` Biju Das
@ 2025-06-25 11:32 ` kernel test robot
2025-06-25 19:09 ` Mark Brown
2 siblings, 0 replies; 21+ messages in thread
From: kernel test robot @ 2025-06-25 11:32 UTC (permalink / raw)
To: Fabrizio Castro, Mark Brown, Philipp Zabel, Geert Uytterhoeven,
Magnus Damm
Cc: oe-kbuild-all, linux-kernel, linux-spi, linux-renesas-soc,
Biju Das, Lad Prabhakar
Hi Fabrizio,
kernel test robot noticed the following build errors:
[auto build test ERROR on broonie-spi/for-next]
[also build test ERROR on geert-renesas-drivers/renesas-clk arm64/for-next/core geert-renesas-devel/next robh/for-next linus/master v6.16-rc3 next-20250625]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Fabrizio-Castro/clk-renesas-r9a09g057-Add-entries-for-the-RSPIs/20250625-032714
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
patch link: https://lore.kernel.org/r/20250624192304.338979-4-fabrizio.castro.jz%40renesas.com
patch subject: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20250625/202506251915.mDWx8v2S-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250625/202506251915.mDWx8v2S-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202506251915.mDWx8v2S-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/spi/spi-rzv2h-rspi.c: In function 'rzv2h_rspi_prepare_message':
>> drivers/spi/spi-rzv2h-rspi.c:298:18: error: implicit declaration of function 'FIELD_PREP' [-Wimplicit-function-declaration]
298 | conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL));
| ^~~~~~~~~~
vim +/FIELD_PREP +298 drivers/spi/spi-rzv2h-rspi.c
268
269 static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
270 struct spi_message *message)
271 {
272 struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
273 const struct spi_device *spi = message->spi;
274 struct spi_transfer *xfer;
275 u32 speed_hz = U32_MAX;
276 u8 bits_per_word;
277 u32 conf32;
278 u16 conf16;
279
280 /* Make sure SPCR.SPE is 0 before amending the configuration */
281 rzv2h_rspi_spe_disable(rspi);
282
283 /* Configure the device to work in "host" mode */
284 conf32 = RSPI_SPCR_MSTR;
285
286 /* Auto-stop function */
287 conf32 |= RSPI_SPCR_SCKASE;
288
289 /* SPI receive buffer full interrupt enable */
290 conf32 |= RSPI_SPCR_SPRIE;
291
292 writel(conf32, rspi->base + RSPI_SPCR);
293
294 /* Use SPCMD0 only */
295 writeb(0x0, rspi->base + RSPI_SPSCR);
296
297 /* Setup mode */
> 298 conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL));
299 conf32 |= FIELD_PREP(RSPI_SPCMD_CPHA, !!(spi->mode & SPI_CPHA));
300 conf32 |= FIELD_PREP(RSPI_SPCMD_LSBF, !!(spi->mode & SPI_LSB_FIRST));
301 conf32 |= FIELD_PREP(RSPI_SPCMD_SSLKP, 1);
302 conf32 |= FIELD_PREP(RSPI_SPCMD_SSLA, spi_get_chipselect(spi, 0));
303 writel(conf32, rspi->base + RSPI_SPCMD);
304 if (spi->mode & SPI_CS_HIGH)
305 writeb(BIT(spi_get_chipselect(spi, 0)), rspi->base + RSPI_SSLP);
306 else
307 writeb(0, rspi->base + RSPI_SSLP);
308
309 /* Setup FIFO thresholds */
310 conf16 = FIELD_PREP(RSPI_SPDCR2_TTRG, RSPI_FIFO_SIZE - 1);
311 conf16 |= FIELD_PREP(RSPI_SPDCR2_RTRG, 0);
312 writew(conf16, rspi->base + RSPI_SPDCR2);
313
314 rzv2h_rspi_clear_fifos(rspi);
315
316 list_for_each_entry(xfer, &message->transfers, transfer_list) {
317 if (!xfer->speed_hz)
318 continue;
319
320 speed_hz = min(xfer->speed_hz, speed_hz);
321 bits_per_word = xfer->bits_per_word;
322 }
323
324 if (speed_hz == U32_MAX)
325 return -EINVAL;
326
327 rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word));
328 rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_SPB, bits_per_word - 1);
329
330 rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
331 if (!rspi->freq)
332 return -EINVAL;
333
334 rzv2h_rspi_spe_enable(rspi);
335
336 return 0;
337 }
338
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
2025-06-24 19:23 ` [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP Fabrizio Castro
2025-06-25 10:19 ` Biju Das
2025-06-25 11:32 ` kernel test robot
@ 2025-06-25 19:09 ` Mark Brown
2025-07-04 14:17 ` Fabrizio Castro
2 siblings, 1 reply; 21+ messages in thread
From: Mark Brown @ 2025-06-25 19:09 UTC (permalink / raw)
To: Fabrizio Castro
Cc: Philipp Zabel, Geert Uytterhoeven, Magnus Damm, linux-kernel,
linux-spi, linux-renesas-soc, Biju Das, Lad Prabhakar
[-- Attachment #1: Type: text/plain, Size: 1132 bytes --]
On Tue, Jun 24, 2025 at 08:23:01PM +0100, Fabrizio Castro wrote:
> +static int rzv2h_rspi_unprepare_message(struct spi_controller *ctlr,
> + struct spi_message *message)
> +{
> + struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
> +
> + rzv2h_rspi_spe_disable(rspi);
> + rzv2h_rspi_clear_fifos(rspi);
A bit interesting that we need to clear the FIFOs, but it's just one
register write so probably not worth worrying about.
> + ret = devm_clk_bulk_get(dev, RSPI_CLK_NUM, rspi->clks);
> + if (ret)
> + return dev_err_probe(dev, ret, "cannot get clocks\n");
> + ret = devm_request_irq(dev, irq_rx, rzv2h_rx_irq_handler, 0,
> + dev_name(dev), rspi);
> + if (ret)
> + return dev_err_probe(dev, ret, "cannot request `rx` IRQ\n");
> +
> + ret = clk_bulk_prepare_enable(RSPI_CLK_NUM, rspi->clks);
Are you sure that the interrupt handler is safe with the IP in reset and
clocks disabled...
> + init_waitqueue_head(&rspi->wait);
...and the wakequeue head it wakes up not yet initialised? This is also
a concern during unregistration where devm things will be unwound after
the remove() function has run.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] spi: dt-bindings: Document the RZ/V2H(P) RSPI
2025-06-24 19:23 ` [PATCH 2/6] spi: dt-bindings: Document the RZ/V2H(P) RSPI Fabrizio Castro
@ 2025-06-27 20:28 ` Rob Herring (Arm)
2025-07-01 13:29 ` Geert Uytterhoeven
1 sibling, 0 replies; 21+ messages in thread
From: Rob Herring (Arm) @ 2025-06-27 20:28 UTC (permalink / raw)
To: Fabrizio Castro
Cc: Mark Brown, Conor Dooley, devicetree, Magnus Damm,
Krzysztof Kozlowski, Geert Uytterhoeven, linux-spi, Biju Das,
linux-kernel, linux-renesas-soc, Lad Prabhakar
On Tue, 24 Jun 2025 20:23:00 +0100, Fabrizio Castro wrote:
> Add dt-bindings for the RSPI IP found inside the Renesas RZ/V2H(P)
> SoC.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> ---
> .../bindings/spi/renesas,rzv2h-rspi.yaml | 96 +++++++++++++++++++
> 1 file changed, 96 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs
2025-06-24 19:22 ` [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs Fabrizio Castro
2025-06-24 19:37 ` Biju Das
@ 2025-07-01 13:17 ` Geert Uytterhoeven
1 sibling, 0 replies; 21+ messages in thread
From: Geert Uytterhoeven @ 2025-07-01 13:17 UTC (permalink / raw)
To: Fabrizio Castro
Cc: Michael Turquette, Stephen Boyd, linux-renesas-soc, linux-clk,
linux-kernel, Biju Das, Lad Prabhakar
On Tue, 24 Jun 2025 at 21:23, Fabrizio Castro
<fabrizio.castro.jz@renesas.com> wrote:
> Add clock and reset entries for the Renesas RZ/V2H(P) RSPI IPs.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-clk for v6.17.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] spi: dt-bindings: Document the RZ/V2H(P) RSPI
2025-06-24 19:23 ` [PATCH 2/6] spi: dt-bindings: Document the RZ/V2H(P) RSPI Fabrizio Castro
2025-06-27 20:28 ` Rob Herring (Arm)
@ 2025-07-01 13:29 ` Geert Uytterhoeven
1 sibling, 0 replies; 21+ messages in thread
From: Geert Uytterhoeven @ 2025-07-01 13:29 UTC (permalink / raw)
To: Fabrizio Castro
Cc: Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, linux-spi, linux-renesas-soc, devicetree,
linux-kernel, Biju Das, Lad Prabhakar
On Tue, 24 Jun 2025 at 21:23, Fabrizio Castro
<fabrizio.castro.jz@renesas.com> wrote:
> Add dt-bindings for the RSPI IP found inside the Renesas RZ/V2H(P)
> SoC.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/6] MAINTAINERS: Add entries for the RZ/V2H(P) RSPI
2025-06-24 19:23 ` [PATCH 4/6] MAINTAINERS: Add entries for the RZ/V2H(P) RSPI Fabrizio Castro
@ 2025-07-01 13:30 ` Geert Uytterhoeven
0 siblings, 0 replies; 21+ messages in thread
From: Geert Uytterhoeven @ 2025-07-01 13:30 UTC (permalink / raw)
To: Fabrizio Castro
Cc: Magnus Damm, linux-kernel, linux-renesas-soc, Biju Das,
Lad Prabhakar
On Tue, 24 Jun 2025 at 21:23, Fabrizio Castro
<fabrizio.castro.jz@renesas.com> wrote:
> Add the MAINTAINERS entries for the Renesas RZ/V2H(P) RSPI
> driver.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 5/6] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver
2025-06-24 19:23 ` [PATCH 5/6] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver Fabrizio Castro
@ 2025-07-01 13:31 ` Geert Uytterhoeven
0 siblings, 0 replies; 21+ messages in thread
From: Geert Uytterhoeven @ 2025-07-01 13:31 UTC (permalink / raw)
To: Fabrizio Castro
Cc: Catalin Marinas, Will Deacon, Krzysztof Kozlowski,
Bjorn Andersson, Nishanth Menon, Arnd Bergmann, Lad Prabhakar,
Nícolas F. R. A. Prado, Taniya Das, Kuninori Morimoto,
Eric Biggers, linux-arm-kernel, linux-kernel, Biju Das,
linux-renesas-soc
On Tue, 24 Jun 2025 at 21:23, Fabrizio Castro
<fabrizio.castro.jz@renesas.com> wrote:
> Enable the Renesas RZ/V2H(P) RSPI driver for the benefit of
> RZ/V2H(P) based platforms.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-devel for v6.17, pending acceptance of
the driver.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 6/6] arm64: dts: renesas: r9a09g057: Add RSPI nodes
2025-06-24 19:23 ` [PATCH 6/6] arm64: dts: renesas: r9a09g057: Add RSPI nodes Fabrizio Castro
@ 2025-07-01 13:32 ` Geert Uytterhoeven
0 siblings, 0 replies; 21+ messages in thread
From: Geert Uytterhoeven @ 2025-07-01 13:32 UTC (permalink / raw)
To: Fabrizio Castro
Cc: Magnus Damm, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-renesas-soc, devicetree, linux-kernel, Biju Das,
Lad Prabhakar
On Tue, 24 Jun 2025 at 21:23, Fabrizio Castro
<fabrizio.castro.jz@renesas.com> wrote:
> Add nodes for the RSPI IPs found in the Renesas RZ/V2H(P) SoC.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-devel for v6.17, pending acceptance of
the bindings.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
2025-06-25 10:19 ` Biju Das
@ 2025-07-04 14:14 ` Fabrizio Castro
0 siblings, 0 replies; 21+ messages in thread
From: Fabrizio Castro @ 2025-07-04 14:14 UTC (permalink / raw)
To: Biju Das, Mark Brown, Philipp Zabel, Geert Uytterhoeven,
Magnus Damm
Cc: linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, Prabhakar Mahadev Lad
Hi Biju,
> From: Biju Das <biju.das.jz@bp.renesas.com>
> Sent: 25 June 2025 11:20
> To: Fabrizio Castro <fabrizio.castro.jz@renesas.com>; Mark Brown <broonie@kernel.org>; Fabrizio Castro
> <fabrizio.castro.jz@renesas.com>; Philipp Zabel <p.zabel@pengutronix.de>; Geert Uytterhoeven
> <geert+renesas@glider.be>; Magnus Damm <magnus.damm@gmail.com>
> Cc: linux-kernel@vger.kernel.org; linux-spi@vger.kernel.org; linux-renesas-soc@vger.kernel.org;
> Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Subject: RE: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
>
> Hi Fabrizio,
>
> Thanks for the patch.
>
> > -----Original Message-----
> > From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> > Sent: 24 June 2025 20:23
> > Das <biju.das.jz@bp.renesas.com>; Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>
> > Subject: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
> >
> > The Renesas RZ/V2H(P) RSPI IP supports 4-wire and 3-wire serial communications in both host role and
> > target role.
> > It can use a DMA, but the I/O can also be driven by the processor.
> >
> > RX-only, TX-only, and RX-TX operations are available in DMA mode, while in processor I/O mode it only
> > RX-TX operations are supported.
> >
> > Add a driver to support 4-wire serial communications as host role in processor I/O mode.
> >
> > Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> > ---
> >
> > I have noticed a problem when unbinding the driver that is solved by:
> > https://lore.kernel.org/all/20250616135357.3929441-1-claudiu.beznea.uj@bp.renesas.com/
> >
> > Once the above series gets accepted I'll send a patch to add runtime pm support, and I'll also switch
> > to using devm_spi_register_controller.
> >
> > drivers/spi/Kconfig | 8 +
> > drivers/spi/Makefile | 1 +
> > drivers/spi/spi-rzv2h-rspi.c | 469 +++++++++++++++++++++++++++++++++++
> > 3 files changed, 478 insertions(+)
> > create mode 100644 drivers/spi/spi-rzv2h-rspi.c
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f2d2295a5501..fcc6987945fa 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -923,6 +923,14 @@ config SPI_RSPI
> > help
> > SPI driver for Renesas RSPI and QSPI blocks.
> >
> > +config SPI_RZV2H_RSPI
> > + tristate "Renesas RZ/V2H RSPI controller"
> > + depends on ARCH_RENESAS || COMPILE_TEST
> > + help
> > + RSPI driver for the Renesas RZ/V2H Serial Peripheral Interface (RSPI).
> > + RSPI supports both SPI host and SPI target roles. This option only
> > + enables the SPI host role.
> > +
> > config SPI_RZV2M_CSI
> > tristate "Renesas RZ/V2M CSI controller"
> > depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> > index 4ea89f6fc531..c19d02653b8a 100644
> > --- a/drivers/spi/Makefile
> > +++ b/drivers/spi/Makefile
> > @@ -126,6 +126,7 @@ obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
> > obj-$(CONFIG_SPI_REALTEK_SNAND) += spi-realtek-rtl-snand.o
> > obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
> > obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
> > +obj-$(CONFIG_SPI_RZV2H_RSPI) += spi-rzv2h-rspi.o
> > obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o
> > obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o
> > obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o
> > diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c new file mode 100644 index
> > 000000000000..9541f2c2ab2b
> > --- /dev/null
> > +++ b/drivers/spi/spi-rzv2h-rspi.c
> > @@ -0,0 +1,469 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Renesas RZ/V2H Renesas Serial Peripheral Interface (RSPI)
> > + *
> > + * Copyright (C) 2025 Renesas Electronics Corporation */
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/bits.h>
> > +#include <linux/clk.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/limits.h>
> > +#include <linux/log2.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/property.h>
> > +#include <linux/reset.h>
> > +#include <linux/spi/spi.h>
> > +
> > +/* Registers */
> > +#define RSPI_SPDR 0x00
> > +#define RSPI_SPCR 0x08
> > +#define RSPI_SSLP 0x10
> > +#define RSPI_SPBR 0x11
> > +#define RSPI_SPSCR 0x13
> > +#define RSPI_SPCMD 0x14
> > +#define RSPI_SPDCR2 0x44
> > +#define RSPI_SPSR 0x52
> > +#define RSPI_SPSRC 0x6a
> > +#define RSPI_SPFCR 0x6c
> > +
> > +/* Register SPCR */
> > +#define RSPI_SPCR_MSTR BIT(30)
> > +#define RSPI_SPCR_SPRIE BIT(17)
> > +#define RSPI_SPCR_SCKASE BIT(12)
> > +#define RSPI_SPCR_SPE BIT(0)
> > +
> > +/* Register SPBR */
> > +#define RSPI_SPBR_SPR_MIN 0
> > +#define RSPI_SPBR_SPR_MAX 255
> > +
> > +/* Register SPCMD */
> > +#define RSPI_SPCMD_SSLA GENMASK(25, 24)
> > +#define RSPI_SPCMD_SPB GENMASK(20, 16)
> > +#define RSPI_SPCMD_LSBF BIT(12)
> > +#define RSPI_SPCMD_SSLKP BIT(7)
> > +#define RSPI_SPCMD_BRDV GENMASK(3, 2)
> > +#define RSPI_SPCMD_CPOL BIT(1)
> > +#define RSPI_SPCMD_CPHA BIT(0)
> > +
> > +#define RSPI_SPCMD_BRDV_MIN 0
> > +#define RSPI_SPCMD_BRDV_MAX 3
> > +
> > +/* Register SPDCR2 */
> > +#define RSPI_SPDCR2_TTRG GENMASK(11, 8)
> > +#define RSPI_SPDCR2_RTRG GENMASK(3, 0)
> > +#define RSPI_FIFO_SIZE 16
> > +
> > +/* Register SPSR */
> > +#define RSPI_SPSR_SPRF BIT(15)
> > +
> > +/* Register RSPI_SPSRC */
> > +#define RSPI_SPSRC_CLEAR 0xfd80
> > +
> > +#define RSPI_RESET_NUM 2
> > +
> > +enum rspi_clocks {
> > + RSPI_CLK_PCLK,
> > + RSPI_CLK_PCLK_SFR,
> > + RSPI_CLK_TCLK,
> > + RSPI_CLK_NUM
> > +};
>
> Do we need this enum?
I can drop it if I switch to using devm_clk_bulk_get_all_enabled().
>
> > +
> > +struct rzv2h_rspi_priv {
> > + struct reset_control_bulk_data resets[RSPI_RESET_NUM];
> > + struct clk_bulk_data clks[RSPI_CLK_NUM];
>
>
> It is used only in probe/remove. By using devm_clk_bulk_get_all_enabled()
> this can be local??
Okay, I'll move it to rzv2h_rspi_probe().
>
> > + struct spi_controller *controller;
> > + void __iomem *base;
> > + wait_queue_head_t wait;
> > + unsigned int bytes_per_word;
> > + u32 freq;
> > + u16 status;
> > +};
> > +
> > +#define RZV2H_RSPI_TX(func, type) \
> > +static inline void rzv2h_rspi_tx_##type(struct rzv2h_rspi_priv *rspi, \
> > + const void *txbuf, \
> > + unsigned int index) { \
> > + type buf = 0; \
> > + \
> > + if (txbuf) \
> > + buf = ((type *)txbuf)[index]; \
> > + \
> > + func(buf, rspi->base + RSPI_SPDR); \
> > +}
> > +
> > +#define RZV2H_RSPI_RX(func, type) \
> > +static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
> > + void *rxbuf, \
> > + unsigned int index) { \
> > + type buf = func(rspi->base + RSPI_SPDR); \
> > + \
> > + if (rxbuf) \
> > + ((type *)rxbuf)[index] = buf; \
> > +}
> > +
> > +RZV2H_RSPI_TX(writel, u32)
> > +RZV2H_RSPI_TX(writew, u16)
> > +RZV2H_RSPI_TX(writeb, u8)
> > +RZV2H_RSPI_RX(readl, u32)
> > +RZV2H_RSPI_RX(readw, u16)
> > +RZV2H_RSPI_RX(readl, u8)
> > +
> > +static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
> > + int reg_offs, u32 bit_mask, u32 value) {
> > + u32 tmp;
> > +
> > + value <<= __ffs(bit_mask);
> > + tmp = (readl(rspi->base + reg_offs) & ~bit_mask) | value;
> > + writel(tmp, rspi->base + reg_offs);
> > +}
> > +
> > +static inline void rzv2h_rspi_spe_disable(const struct rzv2h_rspi_priv
> > +*rspi) {
> > + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 0); }
> > +
> > +static inline void rzv2h_rspi_spe_enable(const struct rzv2h_rspi_priv
> > +*rspi) {
> > + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 1); }
> > +
> > +static inline void rzv2h_rspi_clear_fifos(const struct rzv2h_rspi_priv
> > +*rspi) {
> > + writeb(1, rspi->base + RSPI_SPFCR);
> > +}
> > +
> > +static inline void rzv2h_rspi_clear_all_irqs(struct rzv2h_rspi_priv
> > +*rspi) {
> > + writew(RSPI_SPSRC_CLEAR, rspi->base + RSPI_SPSRC);
> > + rspi->status = 0;
> > +}
> > +
> > +static irqreturn_t rzv2h_rx_irq_handler(int irq, void *data) {
> > + struct rzv2h_rspi_priv *rspi = data;
> > +
> > + rspi->status = readw(rspi->base + RSPI_SPSR);
> > + wake_up(&rspi->wait);
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static inline int rzv2h_rspi_wait_for_interrupt(struct rzv2h_rspi_priv *rspi,
> > + u32 wait_mask)
> > +{
> > + return wait_event_timeout(rspi->wait, (rspi->status & wait_mask),
> > + HZ) == 0 ? -ETIMEDOUT : 0;
> > +}
> > +
> > +static void rzv2h_rspi_send(struct rzv2h_rspi_priv *rspi, const void *txbuf,
> > + unsigned int index)
> > +{
> > + switch (rspi->bytes_per_word) {
> > + case 4:
> > + rzv2h_rspi_tx_u32(rspi, txbuf, index);
> > + break;
> > + case 2:
> > + rzv2h_rspi_tx_u16(rspi, txbuf, index);
> > + break;
> > + default:
> > + rzv2h_rspi_tx_u8(rspi, txbuf, index);
> > + }
> > +}
> > +
> > +static int rzv2h_rspi_receive(struct rzv2h_rspi_priv *rspi, void *rxbuf,
> > + unsigned int index)
> > +{
> > + int ret;
> > +
> > + ret = rzv2h_rspi_wait_for_interrupt(rspi, RSPI_SPSR_SPRF);
> > + if (ret)
> > + return ret;
> > +
> > + switch (rspi->bytes_per_word) {
> > + case 4:
> > + rzv2h_rspi_rx_u32(rspi, rxbuf, index);
> > + break;
> > + case 2:
> > + rzv2h_rspi_rx_u16(rspi, rxbuf, index);
> > + break;
> > + default:
> > + rzv2h_rspi_rx_u8(rspi, rxbuf, index);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int rzv2h_rspi_transfer_one(struct spi_controller *controller,
> > + struct spi_device *spi,
> > + struct spi_transfer *transfer)
> > +{
> > + struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(controller);
> > + unsigned int words_to_transfer, i;
> > + int ret = 0;
> > +
> > + transfer->effective_speed_hz = rspi->freq;
> > + words_to_transfer = transfer->len / rspi->bytes_per_word;
> > +
> > + for (i = 0; i < words_to_transfer; i++) {
> > + rzv2h_rspi_clear_all_irqs(rspi);
> > +
> > + rzv2h_rspi_send(rspi, transfer->tx_buf, i);
> > +
> > + ret = rzv2h_rspi_receive(rspi, transfer->rx_buf, i);
> > + if (ret)
> > + break;
> > + }
> > +
> > + rzv2h_rspi_clear_all_irqs(rspi);
> > +
> > + if (ret)
> > + transfer->error = SPI_TRANS_FAIL_IO;
> > +
> > + spi_finalize_current_transfer(controller);
> > +
> > + return ret;
> > +}
> > +
> > +static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
> > + u8 brdv)
> > +{
> > + return DIV_ROUND_UP(tclk_rate, (2 * (spr + 1) * (1 << brdv))); }
> > +
> > +static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
> > +{
> > + unsigned long tclk_rate;
> > + int spr;
> > + u8 brdv;
> > +
> > + /*
> > + * From the manual:
> > + * Bit rate = f(RSPI_n_TCLK)/(2*(n+1)*2^(N))
> > + *
> > + * Where:
> > + * * RSPI_n_TCLK is fixed to 200MHz on V2H
> > + * * n = SPR - is RSPI_SPBR.SPR (from 0 to 255)
> > + * * N = BRDV - is RSPI_SPCMD.BRDV (from 0 to 3)
> > + */
> > + tclk_rate = clk_get_rate(rspi->clks[RSPI_CLK_TCLK].clk);
> > + for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
> > + spr = DIV_ROUND_UP(tclk_rate, hz * (1 << (brdv + 1)));
> > + spr--;
> > + if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
> > + goto clock_found;
> > + }
> > +
> > + return 0;
> > +
> > +clock_found:
> > + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_BRDV, brdv);
> > + writeb(spr, rspi->base + RSPI_SPBR);
> > +
> > + return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv); }
> > +
> > +static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
> > + struct spi_message *message)
> > +{
> > + struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
> > + const struct spi_device *spi = message->spi;
> > + struct spi_transfer *xfer;
> > + u32 speed_hz = U32_MAX;
> > + u8 bits_per_word;
> > + u32 conf32;
> > + u16 conf16;
> > +
> > + /* Make sure SPCR.SPE is 0 before amending the configuration */
> > + rzv2h_rspi_spe_disable(rspi);
> > +
> > + /* Configure the device to work in "host" mode */
> > + conf32 = RSPI_SPCR_MSTR;
> > +
> > + /* Auto-stop function */
> > + conf32 |= RSPI_SPCR_SCKASE;
> > +
> > + /* SPI receive buffer full interrupt enable */
> > + conf32 |= RSPI_SPCR_SPRIE;
> > +
> > + writel(conf32, rspi->base + RSPI_SPCR);
> > +
> > + /* Use SPCMD0 only */
> > + writeb(0x0, rspi->base + RSPI_SPSCR);
> > +
> > + /* Setup mode */
> > + conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL));
> > + conf32 |= FIELD_PREP(RSPI_SPCMD_CPHA, !!(spi->mode & SPI_CPHA));
> > + conf32 |= FIELD_PREP(RSPI_SPCMD_LSBF, !!(spi->mode & SPI_LSB_FIRST));
> > + conf32 |= FIELD_PREP(RSPI_SPCMD_SSLKP, 1);
> > + conf32 |= FIELD_PREP(RSPI_SPCMD_SSLA, spi_get_chipselect(spi, 0));
> > + writel(conf32, rspi->base + RSPI_SPCMD);
> > + if (spi->mode & SPI_CS_HIGH)
> > + writeb(BIT(spi_get_chipselect(spi, 0)), rspi->base + RSPI_SSLP);
> > + else
> > + writeb(0, rspi->base + RSPI_SSLP);
> > +
> > + /* Setup FIFO thresholds */
> > + conf16 = FIELD_PREP(RSPI_SPDCR2_TTRG, RSPI_FIFO_SIZE - 1);
> > + conf16 |= FIELD_PREP(RSPI_SPDCR2_RTRG, 0);
> > + writew(conf16, rspi->base + RSPI_SPDCR2);
> > +
> > + rzv2h_rspi_clear_fifos(rspi);
> > +
> > + list_for_each_entry(xfer, &message->transfers, transfer_list) {
> > + if (!xfer->speed_hz)
> > + continue;
> > +
> > + speed_hz = min(xfer->speed_hz, speed_hz);
> > + bits_per_word = xfer->bits_per_word;
> > + }
> > +
> > + if (speed_hz == U32_MAX)
> > + return -EINVAL;
> > +
> > + rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word));
> > + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_SPB, bits_per_word -
> > +1);
> > +
> > + rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
> > + if (!rspi->freq)
> > + return -EINVAL;
> > +
> > + rzv2h_rspi_spe_enable(rspi);
> > +
> > + return 0;
> > +}
> > +
> > +static int rzv2h_rspi_unprepare_message(struct spi_controller *ctlr,
> > + struct spi_message *message)
> > +{
> > + struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
> > +
> > + rzv2h_rspi_spe_disable(rspi);
> > + rzv2h_rspi_clear_fifos(rspi);
> > +
> > + return 0;
> > +}
> > +
> > +static int rzv2h_rspi_probe(struct platform_device *pdev) {
> > + struct spi_controller *controller;
> > + struct device *dev = &pdev->dev;
> > + struct rzv2h_rspi_priv *rspi;
> > + unsigned long tclk_rate;
> > + int irq_rx, ret;
> > +
> > + controller = devm_spi_alloc_host(dev, sizeof(*rspi));
> > + if (!controller)
> > + return -ENOMEM;
> > +
> > + rspi = spi_controller_get_devdata(controller);
> > + platform_set_drvdata(pdev, rspi);
> > +
> > + rspi->controller = controller;
> > +
> > + rspi->base = devm_platform_ioremap_resource(pdev, 0);
> > + if (IS_ERR(rspi->base))
> > + return PTR_ERR(rspi->base);
> > +
> > + rspi->clks[RSPI_CLK_PCLK].id = "pclk";
> > + rspi->clks[RSPI_CLK_PCLK_SFR].id = "pclk_sfr";
> > + rspi->clks[RSPI_CLK_TCLK].id = "tclk";
> > + ret = devm_clk_bulk_get(dev, RSPI_CLK_NUM, rspi->clks);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "cannot get clocks\n");
> > +
> > + rspi->resets[0].id = "presetn";
> > + rspi->resets[1].id = "tresetn";
> > + ret = devm_reset_control_bulk_get_exclusive(dev, RSPI_RESET_NUM,
> > + rspi->resets);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "cannot get resets\n");
> > +
> > + irq_rx = platform_get_irq_byname(pdev, "rx");
> > + if (irq_rx < 0)
> > + return dev_err_probe(dev, irq_rx, "cannot get IRQ 'rx'\n");
> > +
> > + ret = devm_request_irq(dev, irq_rx, rzv2h_rx_irq_handler, 0,
> > + dev_name(dev), rspi);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "cannot request `rx` IRQ\n");
> > +
> > + ret = clk_bulk_prepare_enable(RSPI_CLK_NUM, rspi->clks);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "failed to enable clocks\n");
>
> Can't we use devm_clk_bulk_get_all_enabled() instead that will fill struct clk_bulk_data??
Will do.
>
> > +
> > + ret = reset_control_bulk_deassert(RSPI_RESET_NUM, rspi->resets);
> > + if (ret) {
> > + dev_err(dev, "failed to deassert resets\n");
> > + goto quit_clocks;
> > + }
> > +
> > + init_waitqueue_head(&rspi->wait);
> > +
> > + tclk_rate = clk_get_rate(rspi->clks[RSPI_CLK_TCLK].clk);
>
> Is it not possible to get this clk from struct clk_bulk_data by using the id "tclk"??
It is, with a for loop looping over the data filled up by devm_clk_bulk_get_all_enabled().
I'll switch to using devm_clk_bulk_get_all_enabled().
Cheers,
Fab
>
> Cheers,
> Biju
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
2025-06-25 19:09 ` Mark Brown
@ 2025-07-04 14:17 ` Fabrizio Castro
0 siblings, 0 replies; 21+ messages in thread
From: Fabrizio Castro @ 2025-07-04 14:17 UTC (permalink / raw)
To: Mark Brown
Cc: Philipp Zabel, Geert Uytterhoeven, Magnus Damm,
linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, Biju Das,
Prabhakar Mahadev Lad
Hi Mark,
Thanks for your feedback.
> From: Mark Brown <broonie@kernel.org>
> Sent: 25 June 2025 20:09
> To: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>; Geert Uytterhoeven <geert+renesas@glider.be>; Magnus Damm
> <magnus.damm@gmail.com>; linux-kernel@vger.kernel.org; linux-spi@vger.kernel.org; linux-renesas-
> soc@vger.kernel.org; Biju Das <biju.das.jz@bp.renesas.com>; Prabhakar Mahadev Lad <prabhakar.mahadev-
> lad.rj@bp.renesas.com>
> Subject: Re: [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP
>
> On Tue, Jun 24, 2025 at 08:23:01PM +0100, Fabrizio Castro wrote:
>
> > +static int rzv2h_rspi_unprepare_message(struct spi_controller *ctlr,
> > + struct spi_message *message)
> > +{
> > + struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
> > +
> > + rzv2h_rspi_spe_disable(rspi);
> > + rzv2h_rspi_clear_fifos(rspi);
>
> A bit interesting that we need to clear the FIFOs, but it's just one
> register write so probably not worth worrying about.
I can surely take out rzv2h_rspi_clear_fifos() from
rzv2h_rspi_unprepare_message(), as rzv2h_rspi_prepare_message()
makes sure they are clear before we start transferring.
>
> > + ret = devm_clk_bulk_get(dev, RSPI_CLK_NUM, rspi->clks);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "cannot get clocks\n");
>
> > + ret = devm_request_irq(dev, irq_rx, rzv2h_rx_irq_handler, 0,
> > + dev_name(dev), rspi);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "cannot request `rx` IRQ\n");
> > +
> > + ret = clk_bulk_prepare_enable(RSPI_CLK_NUM, rspi->clks);
>
> Are you sure that the interrupt handler is safe with the IP in reset and
> clocks disabled...
>
> > + init_waitqueue_head(&rspi->wait);
>
> ...and the wakequeue head it wakes up not yet initialised? This is also
> a concern during unregistration where devm things will be unwound after
> the remove() function has run.
Good points, I'll move devm_request_irq() to after the clocks are ON,
the resets are deasserted, and the waitqueue has been initialized.
Thanks,
Fab
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2025-07-04 14:17 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-24 19:22 [PATCH 0/6] Add RSPI support for RZ/V2H Fabrizio Castro
2025-06-24 19:22 ` [PATCH 1/6] clk: renesas: r9a09g057: Add entries for the RSPIs Fabrizio Castro
2025-06-24 19:37 ` Biju Das
2025-07-01 13:17 ` Geert Uytterhoeven
2025-06-24 19:23 ` [PATCH 2/6] spi: dt-bindings: Document the RZ/V2H(P) RSPI Fabrizio Castro
2025-06-27 20:28 ` Rob Herring (Arm)
2025-07-01 13:29 ` Geert Uytterhoeven
2025-06-24 19:23 ` [PATCH 3/6] spi: Add driver for the RZ/V2H(P) RSPI IP Fabrizio Castro
2025-06-25 10:19 ` Biju Das
2025-07-04 14:14 ` Fabrizio Castro
2025-06-25 11:32 ` kernel test robot
2025-06-25 19:09 ` Mark Brown
2025-07-04 14:17 ` Fabrizio Castro
2025-06-24 19:23 ` [PATCH 4/6] MAINTAINERS: Add entries for the RZ/V2H(P) RSPI Fabrizio Castro
2025-07-01 13:30 ` Geert Uytterhoeven
2025-06-24 19:23 ` [PATCH 5/6] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver Fabrizio Castro
2025-07-01 13:31 ` Geert Uytterhoeven
2025-06-24 19:23 ` [PATCH 6/6] arm64: dts: renesas: r9a09g057: Add RSPI nodes Fabrizio Castro
2025-07-01 13:32 ` Geert Uytterhoeven
2025-06-25 7:59 ` [PATCH 0/6] Add RSPI support for RZ/V2H Chris Paterson
2025-06-25 8:21 ` Fabrizio Castro
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).