Devicetree
 help / color / mirror / Atom feed
* [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock
@ 2026-05-10  8:42 phucduc.bui
  2026-05-10  8:42 ` [PATCH v3 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
                   ` (9 more replies)
  0 siblings, 10 replies; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:42 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Hi all,

The FSI on r8a7740 requires the SPU clock to be enabled before accessing
its internal registers. Without it, register accesses may hang the system
even when the FSI functional clock is enabled.

Previously, the SPU clock remained enabled because it was left running by
the bootloader. After adding the SPU clock to the device tree, it is
automatically disabled once system initialization completes.

This series adds the missing clocks and aligns their names with those used
by the driver.

Following feedback from Morimoto-san, the driver is also refactored to
improve stability. Clock initialization is moved from the runtime path to
the probe function to simplify the flow and avoid redundant setup.
Additionally, the shutdown sequence is reordered to ensure the stream is
stopped before the hardware is shut down.

The driver currently uses clk_enable()/clk_disable() without matching
clk_prepare()/clk_unprepare() handling. This series adds the missing
prepare/unprepare operations and moves them into startup/shutdown paths,
since clk_prepare() may sleep and therefore must not be called from 
atomic contexts.

The series also fixes a race where in-flight IRQ handlers may continue
accessing registers after the SPU clock has been disabled during shutdown.

Changes in v3:
 - Reordered the patches following Morimoto-san's suggestions
 - Updated the DT bindings based on Geert's feedback and renamed the
   "own" clock to "fck"
 - Added fsi_clk_prepare()/fsi_clk_unprepare() and moved them into
   dai_startup()/dai_shutdown()
 - Fixed a race where in-flight IRQ handlers could continue accessing
   registers after the SPU clock had been disabled

Changes in v2:
 - DT Bindings:
   Define "own" clock and add "spu", "icka/b", "diva/b", "xcka/b" to the 
   clock tree.
   Use YAML anchors and "if" rules to enforce clock-names and r8a7740 
   requirements.
   Relocate allOf block and update example with full 8-clock configuration.

 - DTS:
   Rename "fsi" clock to "own" to match driver implementation.
   Add missing clock names: "icka", "ickb", "diva", "divb", "xcka", "xckb".
 
 - In the driver:
   Refactor clock initialization.
   Reorder shutdown: stop stream before hardware shutdown.
   Move SPU clock enable/disable handling to fsi_hw_startup/shutdown.


v2 links: 
   https://lore.kernel.org/all/20260413100700.30995-1-phucduc.bui@gmail.com/
v1 links : 
   https://lore.kernel.org/all/20260403112655.167593-1-phucduc.bui@gmail.com/

Testing:
  - Verified on r8a7740 (Armadillo-800EVA): FSI slave / Codec master mode.
    The system no longer hangs. aplay works correctly, while arecord has 
    some noise in the recorded file (this likely needs further tuning, but
    it is not part of this patch series). 
    The test video link is provided below.
  - FSI master mode is currently compile-tested only. Full verification
    requires a dedicated HDMI driver (FSIB) or hardware modifications 
    (resoldering board resistors) (FSIA).
  - Kernel config gist link : 
    https://gist.github.com/BuiDucPhuc/fc9e5c3ab7a14766eecb4ce568f1cf17
  - Youtube video link of the test process
    https://youtu.be/w3H4v5djr7M

Best regards,
Phuc

bui duc phuc (10):
  ASoC: dt-bindings: renesas,fsi: add support multiple clocks
  arm: dts: renesas: r8a7740: Add clocks for FSI
  ASoC: renesas: fsi: Fix trigger stop ordering
  ASoC: renesas: fsi: Fix register access from in-flight IRQ after
    shutdown
  ASoC: renesas: fsi: Move fsi_clk_init()
  ASoC: renesas: fsi: Add shared SPU clock support
  ASoC: renesas: fsi: refactor clock initialization
  ASoC: renesas: fsi: add fsi_clk_prepare/unprepare()
  ASoC: renesas: fsi: Use clock prepare handling in startup/shutdown
  ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown

 .../bindings/sound/renesas,fsi.yaml           |  27 +-
 arch/arm/boot/dts/renesas/r8a7740.dtsi        |  12 +-
 sound/soc/renesas/fsi.c                       | 268 +++++++++++++-----
 3 files changed, 235 insertions(+), 72 deletions(-)

-- 
2.43.0


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

* [PATCH v3 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
@ 2026-05-10  8:42 ` phucduc.bui
  2026-05-10  8:42 ` [PATCH v3 02/10] arm: dts: renesas: r8a7740: Add clocks for FSI phucduc.bui
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:42 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc, Geert Uytterhoeven

From: bui duc phuc <phucduc.bui@gmail.com>

The FSI on r8a7740 requires the SPU bus/bridge clock to be enabled before
accessing its registers. Without this clock, any register access leads to
a system hang as the FSI block sits behind the SPU bus.
Update the binding to support multiple clocks to properly describe the
hardware clock tree, including:
  - SPU bus/bridge clock (spu) for register access.
  - CPG DIV6 clocks (icka/b) as functional clock parents.
  - FSI internal dividers (diva/b) for audio clock generation.
  - External clock inputs (xcka/b) provided by the board.

Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 .../bindings/sound/renesas,fsi.yaml           | 27 ++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/renesas,fsi.yaml b/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
index df91991699a7..c50e7115b21a 100644
--- a/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
+++ b/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
@@ -38,7 +38,32 @@ properties:
     maxItems: 1
 
   clocks:
-    maxItems: 1
+    minItems: 1
+    items:
+      - description: Main FSI module clock
+      - description: |
+          SPU bus/bridge clock. On R8A7740, this clock must be enabled to allow
+          register access as the FSI block is connected behind the SPU bus.
+      - description: CPG DIV6 functional clocks for FSI port A
+      - description: CPG DIV6 functional clocks for FSI port B
+      - description: Internal FSI dividers for port A used for audio clock generation
+      - description: Internal FSI dividers for port B used for audio clock generation
+      - description: External clock inputs for FSI port A provided by the board
+      - description: External clock inputs for FSI port B provided by the board
+
+  clock-names:
+    minItems: 1
+    maxItems: 8
+    items:
+      enum:
+        - fck  # Main FSI module clock
+        - spu  # optional SPU bus/bridge clock
+        - icka # optional CPG DIV6 functional clocks for FSI port A
+        - ickb # optional CPG DIV6 functional clocks for FSI port B
+        - diva # optional Internal FSI dividers for port A used for audio clock generation
+        - divb # optional Internal FSI dividers for port B used for audio clock generation
+        - xcka # optional External clock inputs for FSI port A provided by the board
+        - xckb # optional External clock inputs for FSI port B provided by the board
 
   power-domains:
     maxItems: 1
-- 
2.43.0


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

* [PATCH v3 02/10] arm: dts: renesas: r8a7740: Add clocks for FSI
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
  2026-05-10  8:42 ` [PATCH v3 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
@ 2026-05-10  8:42 ` phucduc.bui
  2026-05-10  8:42 ` [PATCH v3 03/10] ASoC: renesas: fsi: Fix trigger stop ordering phucduc.bui
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:42 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Add the SPU clock to the FSI node to ensure it is enabled before register
access, preventing potential system hangs.
Add missing clocks for FSI (icka/b, xcka/b).

Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 arch/arm/boot/dts/renesas/r8a7740.dtsi | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/renesas/r8a7740.dtsi b/arch/arm/boot/dts/renesas/r8a7740.dtsi
index d13ab86c3ab4..6f9d9bbfd159 100644
--- a/arch/arm/boot/dts/renesas/r8a7740.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7740.dtsi
@@ -393,7 +393,11 @@ sh_fsi2: sound@fe1f0000 {
 		compatible = "renesas,fsi2-r8a7740", "renesas,sh_fsi2";
 		reg = <0xfe1f0000 0x400>;
 		interrupts = <GIC_SPI 9 0x4>;
-		clocks = <&mstp3_clks R8A7740_CLK_FSI>;
+		clocks = <&mstp3_clks R8A7740_CLK_FSI>, <&spu_clk>,
+			<&fsia_clk>, <&fsib_clk>, <&fsiack_clk>,
+			<&fsibck_clk>;
+		clock-names = "fck", "spu", "icka", "ickb", "xcka",
+				"xckb";
 		power-domains = <&pd_a4mp>;
 		status = "disabled";
 	};
@@ -614,6 +618,12 @@ vou_clk: vou@e6150088 {
 				 <0>;
 			#clock-cells = <0>;
 		};
+		fsib_clk: fsib@e6150090 {
+			compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0xe6150090 4>;
+			clocks = <&pllc1_div2_clk>, <&fsibck_clk>, <0>, <0>;
+			#clock-cells = <0>;
+		};
 		stpro_clk: stpro@e615009c {
 			compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
 			reg = <0xe615009c 4>;
-- 
2.43.0


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

* [PATCH v3 03/10] ASoC: renesas: fsi: Fix trigger stop ordering
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
  2026-05-10  8:42 ` [PATCH v3 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
  2026-05-10  8:42 ` [PATCH v3 02/10] arm: dts: renesas: r8a7740: Add clocks for FSI phucduc.bui
@ 2026-05-10  8:42 ` phucduc.bui
  2026-05-10  8:42 ` [PATCH v3 04/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:42 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Reorder calls to execute fsi_stream_stop() before fsi_hw_shutdown().
This ensures that all register accesses are completed before the clock is
disabled, preventing the system hang observed on r8a7740.

Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/renesas/fsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 8cbd7acc26f4..94ab2e490810 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -1586,9 +1586,9 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 			ret = fsi_stream_transfer(io);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+		fsi_stream_stop(fsi, io);
 		if (!ret)
 			ret = fsi_hw_shutdown(fsi, dai->dev);
-		fsi_stream_stop(fsi, io);
 		fsi_stream_quit(fsi, io);
 		break;
 	}
-- 
2.43.0


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

* [PATCH v3 04/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
                   ` (2 preceding siblings ...)
  2026-05-10  8:42 ` [PATCH v3 03/10] ASoC: renesas: fsi: Fix trigger stop ordering phucduc.bui
@ 2026-05-10  8:42 ` phucduc.bui
  2026-05-11  1:52   ` Kuninori Morimoto
  2026-05-10  8:42 ` [PATCH v3 05/10] ASoC: renesas: fsi: Move fsi_clk_init() phucduc.bui
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:42 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Ensure that in-flight IRQ handlers do not access hardware registers
after SNDRV_PCM_TRIGGER_STOP and fsi_hw_shutdown().

An IRQ handler may still be running when the SPU clock is disabled,
leading to register access after clock shutdown and causing system
hangs.

Prevent register access in the IRQ path once the hardware has been
shut down.

Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/renesas/fsi.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 94ab2e490810..fc8428cb1ba7 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -211,6 +211,7 @@ struct fsi_stream {
 	int sample_width;	/* sample width */
 	int uerr_num;
 	int oerr_num;
+	bool running;
 
 	/*
 	 * bus options
@@ -255,6 +256,8 @@ struct fsi_priv {
 
 	u32 fmt;
 
+	int running_streams;
+
 	int chan_num:16;
 	unsigned int clk_master:1;
 	unsigned int clk_cpg:1;
@@ -460,6 +463,9 @@ static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
 
 static void fsi_count_fifo_err(struct fsi_priv *fsi)
 {
+	if (fsi->running_streams == 0)
+		return;
+
 	u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
 	u32 istatus = fsi_reg_read(fsi, DIFF_ST);
 
@@ -681,6 +687,9 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
 	u32 data = 0;
 	struct fsi_master *master = fsi_get_master(fsi);
 
+	if (fsi->running_streams == 0)
+		return;
+
 	data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback));
 	data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture));
 
@@ -1573,10 +1582,17 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
 	struct fsi_stream *io = fsi_stream_get(fsi, substream);
+	bool need_shutdown = false;
 	int ret = 0;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+		scoped_guard(spinlock_irqsave, &fsi->master->lock) {
+			if (!io->running) {
+				io->running = true;
+				fsi->running_streams++;
+			}
+		}
 		fsi_stream_init(fsi, io, substream);
 		if (!ret)
 			ret = fsi_hw_startup(fsi, io, dai->dev);
@@ -1586,8 +1602,15 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 			ret = fsi_stream_transfer(io);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+		scoped_guard(spinlock_irqsave, &fsi->master->lock) {
+			if (io->running) {
+				io->running = false;
+				if (--fsi->running_streams == 0)
+					need_shutdown = true;
+			}
+		}
 		fsi_stream_stop(fsi, io);
-		if (!ret)
+		if (!ret && need_shutdown)
 			ret = fsi_hw_shutdown(fsi, dai->dev);
 		fsi_stream_quit(fsi, io);
 		break;
@@ -1968,6 +1991,7 @@ static int fsi_probe(struct platform_device *pdev)
 	fsi->base	= master->base;
 	fsi->phys	= res->start;
 	fsi->master	= master;
+	fsi->running_streams = 0;
 	fsi_port_info_init(fsi, &info.port_a);
 	fsi_handler_init(fsi, &info.port_a);
 	ret = fsi_stream_probe(fsi, &pdev->dev);
@@ -1981,6 +2005,7 @@ static int fsi_probe(struct platform_device *pdev)
 	fsi->base	= master->base + 0x40;
 	fsi->phys	= res->start + 0x40;
 	fsi->master	= master;
+	fsi->running_streams = 0;
 	fsi_port_info_init(fsi, &info.port_b);
 	fsi_handler_init(fsi, &info.port_b);
 	ret = fsi_stream_probe(fsi, &pdev->dev);
-- 
2.43.0


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

* [PATCH v3 05/10] ASoC: renesas: fsi: Move fsi_clk_init()
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
                   ` (3 preceding siblings ...)
  2026-05-10  8:42 ` [PATCH v3 04/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
@ 2026-05-10  8:42 ` phucduc.bui
  2026-05-10  8:42 ` [PATCH v3 06/10] ASoC: renesas: fsi: Add shared SPU clock support phucduc.bui
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:42 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Move fsi_clk_init() after set_rate() functions to prepare for subsequent
refactoring.

Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/renesas/fsi.c | 128 ++++++++++++++++++++--------------------
 1 file changed, 64 insertions(+), 64 deletions(-)

diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index fc8428cb1ba7..06ec5709216b 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -718,70 +718,6 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
 /*
  *		clock function
  */
-static int fsi_clk_init(struct device *dev,
-			struct fsi_priv *fsi,
-			int xck,
-			int ick,
-			int div,
-			int (*set_rate)(struct device *dev,
-					struct fsi_priv *fsi))
-{
-	struct fsi_clk *clock = &fsi->clock;
-	int is_porta = fsi_is_port_a(fsi);
-
-	clock->xck	= NULL;
-	clock->ick	= NULL;
-	clock->div	= NULL;
-	clock->rate	= 0;
-	clock->count	= 0;
-	clock->set_rate	= set_rate;
-
-	clock->own = devm_clk_get(dev, NULL);
-	if (IS_ERR(clock->own))
-		return -EINVAL;
-
-	/* external clock */
-	if (xck) {
-		clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb");
-		if (IS_ERR(clock->xck)) {
-			dev_err(dev, "can't get xck clock\n");
-			return -EINVAL;
-		}
-		if (clock->xck == clock->own) {
-			dev_err(dev, "cpu doesn't support xck clock\n");
-			return -EINVAL;
-		}
-	}
-
-	/* FSIACLK/FSIBCLK */
-	if (ick) {
-		clock->ick = devm_clk_get(dev,  is_porta ? "icka" : "ickb");
-		if (IS_ERR(clock->ick)) {
-			dev_err(dev, "can't get ick clock\n");
-			return -EINVAL;
-		}
-		if (clock->ick == clock->own) {
-			dev_err(dev, "cpu doesn't support ick clock\n");
-			return -EINVAL;
-		}
-	}
-
-	/* FSI-DIV */
-	if (div) {
-		clock->div = devm_clk_get(dev,  is_porta ? "diva" : "divb");
-		if (IS_ERR(clock->div)) {
-			dev_err(dev, "can't get div clock\n");
-			return -EINVAL;
-		}
-		if (clock->div == clock->own) {
-			dev_err(dev, "cpu doesn't support div clock\n");
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
 #define fsi_clk_invalid(fsi) fsi_clk_valid(fsi, 0)
 static void fsi_clk_valid(struct fsi_priv *fsi, unsigned long rate)
 {
@@ -1035,6 +971,70 @@ static int fsi_clk_set_rate_cpg(struct device *dev,
 	return ret;
 }
 
+static int fsi_clk_init(struct device *dev,
+			struct fsi_priv *fsi,
+			int xck,
+			int ick,
+			int div,
+			int (*set_rate)(struct device *dev,
+					struct fsi_priv *fsi))
+{
+	struct fsi_clk *clock = &fsi->clock;
+	int is_porta = fsi_is_port_a(fsi);
+
+	clock->xck	= NULL;
+	clock->ick	= NULL;
+	clock->div	= NULL;
+	clock->rate	= 0;
+	clock->count	= 0;
+	clock->set_rate	= set_rate;
+
+	clock->own = devm_clk_get(dev, NULL);
+	if (IS_ERR(clock->own))
+		return -EINVAL;
+
+	/* external clock */
+	if (xck) {
+		clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb");
+		if (IS_ERR(clock->xck)) {
+			dev_err(dev, "can't get xck clock\n");
+			return -EINVAL;
+		}
+		if (clock->xck == clock->own) {
+			dev_err(dev, "cpu doesn't support xck clock\n");
+			return -EINVAL;
+		}
+	}
+
+	/* FSIACLK/FSIBCLK */
+	if (ick) {
+		clock->ick = devm_clk_get(dev,  is_porta ? "icka" : "ickb");
+		if (IS_ERR(clock->ick)) {
+			dev_err(dev, "can't get ick clock\n");
+			return -EINVAL;
+		}
+		if (clock->ick == clock->own) {
+			dev_err(dev, "cpu doesn't support ick clock\n");
+			return -EINVAL;
+		}
+	}
+
+	/* FSI-DIV */
+	if (div) {
+		clock->div = devm_clk_get(dev,  is_porta ? "diva" : "divb");
+		if (IS_ERR(clock->div)) {
+			dev_err(dev, "can't get div clock\n");
+			return -EINVAL;
+		}
+		if (clock->div == clock->own) {
+			dev_err(dev, "cpu doesn't support div clock\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static void fsi_pointer_update(struct fsi_stream *io, int size)
 {
 	io->buff_sample_pos += size;
-- 
2.43.0


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

* [PATCH v3 06/10] ASoC: renesas: fsi: Add shared SPU clock support
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
                   ` (4 preceding siblings ...)
  2026-05-10  8:42 ` [PATCH v3 05/10] ASoC: renesas: fsi: Move fsi_clk_init() phucduc.bui
@ 2026-05-10  8:42 ` phucduc.bui
  2026-05-11  1:56   ` Kuninori Morimoto
  2026-05-10  8:43 ` [PATCH v3 07/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:42 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Add SPU clock pointer and reference count for shared FSIA/FSIB usage,
and initialize it in fsi_probe().

Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/renesas/fsi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 06ec5709216b..55a11f1fe8aa 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -295,7 +295,9 @@ struct fsi_master {
 	void __iomem *base;
 	struct fsi_priv fsia;
 	struct fsi_priv fsib;
+	struct clk *clk_spu;
 	const struct fsi_core *core;
+	int spu_count;
 	spinlock_t lock;
 };
 
@@ -1984,6 +1986,7 @@ static int fsi_probe(struct platform_device *pdev)
 
 	/* master setting */
 	master->core		= core;
+	master->spu_count	= 0;
 	spin_lock_init(&master->lock);
 
 	/* FSI A setting */
-- 
2.43.0


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

* [PATCH v3 07/10] ASoC: renesas: fsi: refactor clock initialization
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
                   ` (5 preceding siblings ...)
  2026-05-10  8:42 ` [PATCH v3 06/10] ASoC: renesas: fsi: Add shared SPU clock support phucduc.bui
@ 2026-05-10  8:43 ` phucduc.bui
  2026-05-10 12:30   ` Mark Brown
  2026-05-11  1:59   ` Kuninori Morimoto
  2026-05-10  8:43 ` [PATCH v3 08/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
                   ` (2 subsequent siblings)
  9 siblings, 2 replies; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:43 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Move fsi_clk_init() to probe and use devm_clk_get_optional() for optional
clocks. This allows probe to succeed even when some optional clocks are
missing, while set_rate() performs strict validation to ensure all required
clocks are available for hardware configuration during audio setup.

Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/renesas/fsi.c | 70 ++++++++++++++++++++++-------------------
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 55a11f1fe8aa..8c46d6806958 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -865,6 +865,11 @@ static int fsi_clk_set_rate_external(struct device *dev,
 	int ackmd, bpfmd;
 	int ret = 0;
 
+	if (!xck || !ick) {
+		dev_err(dev, "xck clock or ick clock is missing\n");
+		return -EINVAL;
+	}
+
 	/* check clock rate */
 	xrate = clk_get_rate(xck);
 	if (xrate % rate) {
@@ -901,6 +906,11 @@ static int fsi_clk_set_rate_cpg(struct device *dev,
 	int ackmd, bpfmd;
 	int ret = -EINVAL;
 
+	if (!ick || !div) {
+		dev_err(dev, "ick clock or div clock is missing\n");
+		return -EINVAL;
+	}
+
 	if (!(12288000 % rate))
 		target = 12288000;
 	if (!(11289600 % rate))
@@ -973,35 +983,42 @@ static int fsi_clk_set_rate_cpg(struct device *dev,
 	return ret;
 }
 
-static int fsi_clk_init(struct device *dev,
-			struct fsi_priv *fsi,
-			int xck,
-			int ick,
-			int div,
-			int (*set_rate)(struct device *dev,
-					struct fsi_priv *fsi))
+static int fsi_clk_init(struct device *dev, struct fsi_priv *fsi)
 {
 	struct fsi_clk *clock = &fsi->clock;
+	struct fsi_master *master = fsi->master;
 	int is_porta = fsi_is_port_a(fsi);
+	int xck, ick, div;
+
+	if (fsi->clk_cpg) {
+		xck = 0; ick = 1; div = 1;
+		clock->set_rate = fsi_clk_set_rate_cpg;
+	} else {
+		xck = 1; ick = 1; div = 0;
+		clock->set_rate = fsi_clk_set_rate_external;
+	}
 
 	clock->xck	= NULL;
 	clock->ick	= NULL;
 	clock->div	= NULL;
 	clock->rate	= 0;
 	clock->count	= 0;
-	clock->set_rate	= set_rate;
 
 	clock->own = devm_clk_get(dev, NULL);
 	if (IS_ERR(clock->own))
 		return -EINVAL;
 
+	if (!master->clk_spu) {
+		master->clk_spu = devm_clk_get_optional(dev, "spu");
+		if (IS_ERR(master->clk_spu))
+			return PTR_ERR(master->clk_spu);
+	}
+
 	/* external clock */
 	if (xck) {
-		clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb");
-		if (IS_ERR(clock->xck)) {
-			dev_err(dev, "can't get xck clock\n");
-			return -EINVAL;
-		}
+		clock->xck = devm_clk_get_optional(dev, is_porta ? "xcka" : "xckb");
+		if (IS_ERR(clock->xck))
+			return dev_err_probe(dev, PTR_ERR(clock->xck), "Can't get xck clock\n");
 		if (clock->xck == clock->own) {
 			dev_err(dev, "cpu doesn't support xck clock\n");
 			return -EINVAL;
@@ -1010,11 +1027,9 @@ static int fsi_clk_init(struct device *dev,
 
 	/* FSIACLK/FSIBCLK */
 	if (ick) {
-		clock->ick = devm_clk_get(dev,  is_porta ? "icka" : "ickb");
-		if (IS_ERR(clock->ick)) {
-			dev_err(dev, "can't get ick clock\n");
-			return -EINVAL;
-		}
+		clock->ick = devm_clk_get_optional(dev,  is_porta ? "icka" : "ickb");
+		if (IS_ERR(clock->ick))
+			return dev_err_probe(dev, PTR_ERR(clock->ick), "Can't get ick clock\n");
 		if (clock->ick == clock->own) {
 			dev_err(dev, "cpu doesn't support ick clock\n");
 			return -EINVAL;
@@ -1023,11 +1038,9 @@ static int fsi_clk_init(struct device *dev,
 
 	/* FSI-DIV */
 	if (div) {
-		clock->div = devm_clk_get(dev,  is_porta ? "diva" : "divb");
-		if (IS_ERR(clock->div)) {
-			dev_err(dev, "can't get div clock\n");
-			return -EINVAL;
-		}
+		clock->div = devm_clk_get_optional(dev,  is_porta ? "diva" : "divb");
+		if (IS_ERR(clock->div))
+			return dev_err_probe(dev, PTR_ERR(clock->div), "Can't get div clock\n");
 		if (clock->div == clock->own) {
 			dev_err(dev, "cpu doesn't support div clock\n");
 			return -EINVAL;
@@ -1689,15 +1702,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		break;
 	}
 
-	if (fsi_is_clk_master(fsi)) {
-		if (fsi->clk_cpg)
-			fsi_clk_init(dai->dev, fsi, 0, 1, 1,
-				     fsi_clk_set_rate_cpg);
-		else
-			fsi_clk_init(dai->dev, fsi, 1, 1, 0,
-				     fsi_clk_set_rate_external);
-	}
-
 	/* set format */
 	if (fsi_is_spdif(fsi))
 		ret = fsi_set_fmt_spdif(fsi);
@@ -1997,6 +2001,7 @@ static int fsi_probe(struct platform_device *pdev)
 	fsi->running_streams = 0;
 	fsi_port_info_init(fsi, &info.port_a);
 	fsi_handler_init(fsi, &info.port_a);
+	fsi_clk_init(&pdev->dev, fsi);
 	ret = fsi_stream_probe(fsi, &pdev->dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "FSIA stream probe failed\n");
@@ -2011,6 +2016,7 @@ static int fsi_probe(struct platform_device *pdev)
 	fsi->running_streams = 0;
 	fsi_port_info_init(fsi, &info.port_b);
 	fsi_handler_init(fsi, &info.port_b);
+	fsi_clk_init(&pdev->dev, fsi);
 	ret = fsi_stream_probe(fsi, &pdev->dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "FSIB stream probe failed\n");
-- 
2.43.0


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

* [PATCH v3 08/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare()
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
                   ` (6 preceding siblings ...)
  2026-05-10  8:43 ` [PATCH v3 07/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
@ 2026-05-10  8:43 ` phucduc.bui
  2026-05-11  2:03   ` Kuninori Morimoto
  2026-05-10  8:43 ` [PATCH v3 09/10] ASoC: renesas: fsi: Use clock prepare handling in startup/shutdown phucduc.bui
  2026-05-10  8:43 ` [PATCH v3 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui
  9 siblings, 1 reply; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:43 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Add helper functions for preparing and unpreparing FSI clocks.

These helpers centralize clock prepare/unprepare handling and
will be used by subsequent patches to move clock management
into sleepable contexts.

Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/renesas/fsi.c | 66 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 8c46d6806958..b93809b5da15 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -732,6 +732,72 @@ static int fsi_clk_is_valid(struct fsi_priv *fsi)
 		fsi->clock.rate;
 }
 
+static int fsi_clk_prepare(struct fsi_priv *fsi)
+{
+	struct fsi_clk *clock = &fsi->clock;
+	struct clk *spu = fsi->master->clk_spu;
+	struct clk *xck = clock->xck;
+	struct clk *ick = clock->ick;
+	struct clk *div = clock->div;
+	int ret;
+
+	if (!IS_ERR_OR_NULL(spu) && fsi->master->spu_count == 0) {
+		ret = clk_prepare(spu);
+		if (ret)
+			return ret;
+	}
+
+	if (!IS_ERR_OR_NULL(xck)) {
+		ret = clk_prepare(xck);
+		if (ret)
+			goto err_spu;
+	}
+
+	if (!IS_ERR_OR_NULL(ick)) {
+		ret = clk_prepare(ick);
+		if (ret)
+			goto err_xck;
+	}
+
+	if (!IS_ERR_OR_NULL(div)) {
+		ret = clk_prepare(div);
+		if (ret)
+			goto err_ick;
+	}
+
+	return 0;
+
+err_ick:
+	clk_unprepare(ick);
+err_xck:
+	clk_unprepare(xck);
+err_spu:
+	clk_unprepare(spu);
+
+	return ret;
+}
+
+static void fsi_clk_unprepare(struct fsi_priv *fsi)
+{
+	struct fsi_clk *clock = &fsi->clock;
+	struct clk *spu = fsi->master->clk_spu;
+	struct clk *xck = clock->xck;
+	struct clk *ick = clock->ick;
+	struct clk *div = clock->div;
+
+	if (!IS_ERR_OR_NULL(div))
+		clk_unprepare(div);
+
+	if (!IS_ERR_OR_NULL(ick))
+		clk_unprepare(ick);
+
+	if (!IS_ERR_OR_NULL(xck))
+		clk_unprepare(xck);
+
+	if (!IS_ERR_OR_NULL(spu) && fsi->master->spu_count == 0)
+		clk_unprepare(spu);
+}
+
 static int fsi_clk_enable(struct device *dev,
 			  struct fsi_priv *fsi)
 {
-- 
2.43.0


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

* [PATCH v3 09/10] ASoC: renesas: fsi: Use clock prepare handling in startup/shutdown
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
                   ` (7 preceding siblings ...)
  2026-05-10  8:43 ` [PATCH v3 08/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
@ 2026-05-10  8:43 ` phucduc.bui
  2026-05-11  2:04   ` Kuninori Morimoto
  2026-05-10  8:43 ` [PATCH v3 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui
  9 siblings, 1 reply; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:43 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Use fsi_clk_prepare() and fsi_clk_unprepare() in dai_startup()
and dai_shutdown().

Prepare clocks only during active audio streams to reduce
unnecessary power usage, and ensure clk_prepare() and
related operations run in non-atomic contexts.

Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/renesas/fsi.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index b93809b5da15..c3ac8b30f342 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -1644,9 +1644,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
+	int ret;
 
 	fsi_clk_invalid(fsi);
 
+	if (fsi->clock.count == 0) {
+		ret = fsi_clk_prepare(fsi);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -1655,6 +1662,8 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
 
+	if (fsi->clock.count == 0)
+		fsi_clk_unprepare(fsi);
 	fsi_clk_invalid(fsi);
 }
 
-- 
2.43.0


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

* [PATCH v3 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown
  2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
                   ` (8 preceding siblings ...)
  2026-05-10  8:43 ` [PATCH v3 09/10] ASoC: renesas: fsi: Use clock prepare handling in startup/shutdown phucduc.bui
@ 2026-05-10  8:43 ` phucduc.bui
  9 siblings, 0 replies; 17+ messages in thread
From: phucduc.bui @ 2026-05-10  8:43 UTC (permalink / raw)
  To: kuninori.morimoto.gx
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

Enable and disable the SPU clock in fsi_hw_startup() and
fsi_hw_shutdown() to ensure the clock is active while the
driver accesses hardware registers.

Previously, the SPU clock was enabled by the bootloader and
remained active during operation. However, after adding the
SPU clock to the device tree, it is disabled automatically
once the system initialization completes.

As a result, register accesses may occur while the clock is
disabled, which can lead to system hangs. Manage the SPU
clock explicitly in the driver to ensure correct behavior.

Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/renesas/fsi.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index c3ac8b30f342..5307085c0615 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -1579,6 +1579,19 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
 			  struct device *dev)
 {
 	u32 data = 0;
+	int ret;
+
+	/* enable spu clock */
+	if (fsi->master->clk_spu) {
+		scoped_guard(spinlock_irqsave, &fsi->master->lock) {
+			if (fsi->master->spu_count == 0) {
+				ret = clk_enable(fsi->master->clk_spu);
+				if (ret < 0)
+					return ret;
+			}
+				fsi->master->spu_count++;
+		}
+	}
 
 	/* clock setting */
 	if (fsi_is_clk_master(fsi))
@@ -1636,6 +1649,12 @@ static int fsi_hw_shutdown(struct fsi_priv *fsi,
 	/* stop master clock */
 	if (fsi_is_clk_master(fsi))
 		return fsi_clk_disable(dev, fsi);
+	if (fsi->master->clk_spu) {
+		scoped_guard(spinlock_irqsave, &fsi->master->lock) {
+			if (--fsi->master->spu_count == 0)
+				clk_disable(fsi->master->clk_spu);
+		}
+	}
 
 	return 0;
 }
-- 
2.43.0


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

* Re: [PATCH v3 07/10] ASoC: renesas: fsi: refactor clock initialization
  2026-05-10  8:43 ` [PATCH v3 07/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
@ 2026-05-10 12:30   ` Mark Brown
  2026-05-11  1:59   ` Kuninori Morimoto
  1 sibling, 0 replies; 17+ messages in thread
From: Mark Brown @ 2026-05-10 12:30 UTC (permalink / raw)
  To: phucduc.bui
  Cc: kuninori.morimoto.gx, conor+dt, devicetree, geert+renesas,
	krzk+dt, lgirdwood, linux-kernel, linux-renesas-soc, linux-sound,
	magnus.damm, perex, robh, tiwai

[-- Attachment #1: Type: text/plain, Size: 948 bytes --]

On Sun, May 10, 2026 at 03:43:00PM +0700, phucduc.bui@gmail.com wrote:

> Move fsi_clk_init() to probe and use devm_clk_get_optional() for optional
> clocks. This allows probe to succeed even when some optional clocks are
> missing, while set_rate() performs strict validation to ensure all required
> clocks are available for hardware configuration during audio setup.

> +static int fsi_clk_init(struct device *dev, struct fsi_priv *fsi)

> +	if (!master->clk_spu) {
> +		master->clk_spu = devm_clk_get_optional(dev, "spu");
> +		if (IS_ERR(master->clk_spu))
> +			return PTR_ERR(master->clk_spu);
> +	}
> +

> @@ -1997,6 +2001,7 @@ static int fsi_probe(struct platform_device *pdev)
>  	fsi->running_streams = 0;
>  	fsi_port_info_init(fsi, &info.port_a);
>  	fsi_handler_init(fsi, &info.port_a);
> +	fsi_clk_init(&pdev->dev, fsi);

We ignore the return value from fsi_clk_init() which means deferred
probe won't work (as well as fatal errors).

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v3 04/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown
  2026-05-10  8:42 ` [PATCH v3 04/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
@ 2026-05-11  1:52   ` Kuninori Morimoto
  0 siblings, 0 replies; 17+ messages in thread
From: Kuninori Morimoto @ 2026-05-11  1:52 UTC (permalink / raw)
  To: phucduc.bui
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai


Hi

Sorry for my late response. It was long holiday in Japan.

> Ensure that in-flight IRQ handlers do not access hardware registers
> after SNDRV_PCM_TRIGGER_STOP and fsi_hw_shutdown().
> 
> An IRQ handler may still be running when the SPU clock is disabled,
> leading to register access after clock shutdown and causing system
> hangs.
> 
> Prevent register access in the IRQ path once the hardware has been
> shut down.
> 
> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> ---

fsi_stream_is_working() can handle that ?

Thank you for your help !!

Best regards
---
Kuninori Morimoto

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

* Re: [PATCH v3 06/10] ASoC: renesas: fsi: Add shared SPU clock support
  2026-05-10  8:42 ` [PATCH v3 06/10] ASoC: renesas: fsi: Add shared SPU clock support phucduc.bui
@ 2026-05-11  1:56   ` Kuninori Morimoto
  0 siblings, 0 replies; 17+ messages in thread
From: Kuninori Morimoto @ 2026-05-11  1:56 UTC (permalink / raw)
  To: phucduc.bui
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai


Hi

> Add SPU clock pointer and reference count for shared FSIA/FSIB usage,
> and initialize it in fsi_probe().
> 
> Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> ---

Am I suggested this ?
clk_spu   should be merged into [07/10], and
spu_count should be merged into [08/10]

Thank you for your help !!

Best regards
---
Kuninori Morimoto

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

* Re: [PATCH v3 07/10] ASoC: renesas: fsi: refactor clock initialization
  2026-05-10  8:43 ` [PATCH v3 07/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
  2026-05-10 12:30   ` Mark Brown
@ 2026-05-11  1:59   ` Kuninori Morimoto
  1 sibling, 0 replies; 17+ messages in thread
From: Kuninori Morimoto @ 2026-05-11  1:59 UTC (permalink / raw)
  To: phucduc.bui
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai


Hi

> Move fsi_clk_init() to probe and use devm_clk_get_optional() for optional
> clocks. This allows probe to succeed even when some optional clocks are
> missing, while set_rate() performs strict validation to ensure all required
> clocks are available for hardware configuration during audio setup.
> 
> Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> ---

Below parts are clock->xxx cleanup code, not refactor clocks initialization ?
Please separate it into cleanup part and refactor part.

> 	/* external clock */
> 	if (xck) {
> -		clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb");
> -		if (IS_ERR(clock->xck)) {
> -			dev_err(dev, "can't get xck clock\n");
> -			return -EINVAL;
> -		}
> +		clock->xck = devm_clk_get_optional(dev, is_porta ? "xcka" : "xckb");
> +		if (IS_ERR(clock->xck))
> +			return dev_err_probe(dev, PTR_ERR(clock->xck), "Can't get xck clock\n");
>  		if (clock->xck == clock->own) {
>  			dev_err(dev, "cpu doesn't support xck clock\n");
> 			return -EINVAL;
> @@ -1010,11 +1027,9 @@ static int fsi_clk_init(struct device *dev,
>  
>  	/* FSIACLK/FSIBCLK */
>  	if (ick) {
> -		clock->ick = devm_clk_get(dev,  is_porta ? "icka" : "ickb");
> -		if (IS_ERR(clock->ick)) {
> -			dev_err(dev, "can't get ick clock\n");
> -			return -EINVAL;
> -		}
> +		clock->ick = devm_clk_get_optional(dev,  is_porta ? "icka" : "ickb");
> +		if (IS_ERR(clock->ick))
> +			return dev_err_probe(dev, PTR_ERR(clock->ick), "Can't get ick clock\n");
>  		if (clock->ick == clock->own) {
>  			dev_err(dev, "cpu doesn't support ick clock\n");
>  			return -EINVAL;
> @@ -1023,11 +1038,9 @@ static int fsi_clk_init(struct device *dev,
>  
>  	/* FSI-DIV */
>  	if (div) {
> -		clock->div = devm_clk_get(dev,  is_porta ? "diva" : "divb");
> -		if (IS_ERR(clock->div)) {
> -			dev_err(dev, "can't get div clock\n");
> -			return -EINVAL;
> -		}
> +		clock->div = devm_clk_get_optional(dev,  is_porta ? "diva" : "divb");
> +		if (IS_ERR(clock->div))
> +			return dev_err_probe(dev, PTR_ERR(clock->div), "Can't get div clock\n");
>  		if (clock->div == clock->own) {
>  			dev_err(dev, "cpu doesn't support div clock\n");
>  			return -EINVAL;

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

* Re: [PATCH v3 08/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare()
  2026-05-10  8:43 ` [PATCH v3 08/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
@ 2026-05-11  2:03   ` Kuninori Morimoto
  0 siblings, 0 replies; 17+ messages in thread
From: Kuninori Morimoto @ 2026-05-11  2:03 UTC (permalink / raw)
  To: phucduc.bui
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai


Hi

> From: bui duc phuc <phucduc.bui@gmail.com>
> 
> Add helper functions for preparing and unpreparing FSI clocks.
> 
> These helpers centralize clock prepare/unprepare handling and
> will be used by subsequent patches to move clock management
> into sleepable contexts.
> 
> Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> ---

[08/10] and [09/10] should be merged.

Thank you for your help !!

Best regards
---
Kuninori Morimoto

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

* Re: [PATCH v3 09/10] ASoC: renesas: fsi: Use clock prepare handling in startup/shutdown
  2026-05-10  8:43 ` [PATCH v3 09/10] ASoC: renesas: fsi: Use clock prepare handling in startup/shutdown phucduc.bui
@ 2026-05-11  2:04   ` Kuninori Morimoto
  0 siblings, 0 replies; 17+ messages in thread
From: Kuninori Morimoto @ 2026-05-11  2:04 UTC (permalink / raw)
  To: phucduc.bui
  Cc: broonie, conor+dt, devicetree, geert+renesas, krzk+dt, lgirdwood,
	linux-kernel, linux-renesas-soc, linux-sound, magnus.damm, perex,
	robh, tiwai


Hi

> From: bui duc phuc <phucduc.bui@gmail.com>
> 
> Use fsi_clk_prepare() and fsi_clk_unprepare() in dai_startup()
> and dai_shutdown().
> 
> Prepare clocks only during active audio streams to reduce
> unnecessary power usage, and ensure clk_prepare() and
> related operations run in non-atomic contexts.
> 
> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> ---
(snip)
> +	if (fsi->clock.count == 0) {
> +		ret = fsi_clk_prepare(fsi);
> +		if (ret)
> +			return ret;
(snip)
> +	if (fsi->clock.count == 0)
> +		fsi_clk_unprepare(fsi);

fsi->clock.count check can be done on fsi_clk_[un]prepare() ?

Thank you for your help !!

Best regards
---
Kuninori Morimoto

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

end of thread, other threads:[~2026-05-11  2:04 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-10  8:42 [PATCH v3 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
2026-05-10  8:42 ` [PATCH v3 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
2026-05-10  8:42 ` [PATCH v3 02/10] arm: dts: renesas: r8a7740: Add clocks for FSI phucduc.bui
2026-05-10  8:42 ` [PATCH v3 03/10] ASoC: renesas: fsi: Fix trigger stop ordering phucduc.bui
2026-05-10  8:42 ` [PATCH v3 04/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
2026-05-11  1:52   ` Kuninori Morimoto
2026-05-10  8:42 ` [PATCH v3 05/10] ASoC: renesas: fsi: Move fsi_clk_init() phucduc.bui
2026-05-10  8:42 ` [PATCH v3 06/10] ASoC: renesas: fsi: Add shared SPU clock support phucduc.bui
2026-05-11  1:56   ` Kuninori Morimoto
2026-05-10  8:43 ` [PATCH v3 07/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
2026-05-10 12:30   ` Mark Brown
2026-05-11  1:59   ` Kuninori Morimoto
2026-05-10  8:43 ` [PATCH v3 08/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
2026-05-11  2:03   ` Kuninori Morimoto
2026-05-10  8:43 ` [PATCH v3 09/10] ASoC: renesas: fsi: Use clock prepare handling in startup/shutdown phucduc.bui
2026-05-11  2:04   ` Kuninori Morimoto
2026-05-10  8:43 ` [PATCH v3 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox