* [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock
@ 2026-06-05 12:19 phucduc.bui
2026-06-05 12:19 ` [PATCH v4 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
` (9 more replies)
0 siblings, 10 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, 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 v4:
- use fsi_stream_is_working() for Fixed a race where in-flight IRQ
handlers following Morimoto-san's suggestions
- Handle the return value of fsi_clk_init() to properly support deferred
probe, as suggested by Mark.
- Split the clock refactoring into a devm cleanup patch and a refactor
patch, as suggested by Morimoto-san.
- Update dt-bindings based on feedback from Krzysztof, Rob, and Geert.
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.
v3 links:
https://lore.kernel.org/all/20260510084303.122426-1-phucduc.bui@gmail.com/
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).
- FSI master mode is currently compile-tested only. Full verification
requires a dedicated HDMI driver (FSIB) or hardware modifications
(resoldering board resistors) (FSIA).
- Youtube video link of the test process (from v3 verification):
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: Move fsi_stream_is_working()
ASoC: renesas: fsi: Fix register access from in-flight IRQ after
shutdown
ASoC: renesas: fsi: Move fsi_clk_init()
ASoC: renesas: fsi: Use devm_clk_get_optional() for optional clocks
ASoC: renesas: fsi: refactor clock initialization
ASoC: renesas: fsi: add fsi_clk_prepare/unprepare()
ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown
.../bindings/sound/renesas,fsi.yaml | 61 +++-
arch/arm/boot/dts/renesas/r8a7740.dtsi | 12 +-
sound/soc/renesas/fsi.c | 272 +++++++++++++-----
3 files changed, 260 insertions(+), 85 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 12:19 ` [PATCH v4 02/10] ARM: dts: renesas: r8a7740: Add clocks for FSI phucduc.bui
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, bui duc phuc
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.
- FSI dividers (diva/b) for audio clock generation.
- External clock inputs (xcka/b) provided by the board.
Both sh73a0 and r8a7740 define the SPU DIV6 clock control register at
0xe6150084. The binding therefore documents the clocks supported by the
FSI driver for these variants.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Changes in v4:
- Update dt-bindings based on feedback from Krzysztof, Rob, and Geert.
.../bindings/sound/renesas,fsi.yaml | 61 +++++++++++++++++--
1 file changed, 56 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/renesas,fsi.yaml b/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
index df91991699a7..b966b55ff772 100644
--- a/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
+++ b/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
@@ -9,9 +9,6 @@ title: Renesas FIFO-buffered Serial Interface (FSI)
maintainers:
- Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
-allOf:
- - $ref: dai-common.yaml#
-
properties:
$nodename:
pattern: "^sound@.*"
@@ -38,7 +35,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: FSI dividers for port A used for audio clock generation
+ - description: 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 FSI dividers for port A used for audio clock generation
+ - divb # optional 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
@@ -69,6 +91,31 @@ required:
unevaluatedProperties: false
+allOf:
+ - $ref: dai-common.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,fsi2-r8a7740
+ then:
+ required:
+ - clock-names
+
+ properties:
+ clock-names:
+ minItems: 2
+ uniqueItems: true
+ items:
+ - const: fck
+ - const: spu
+ - enum: [icka, ickb, diva, divb, xcka, xckb]
+ - enum: [icka, ickb, diva, divb, xcka, xckb]
+ - enum: [icka, ickb, diva, divb, xcka, xckb]
+ - enum: [icka, ickb, diva, divb, xcka, xckb]
+ - enum: [icka, ickb, diva, divb, xcka, xckb]
+ - enum: [icka, ickb, diva, divb, xcka, xckb]
+
examples:
- |
#include <dt-bindings/clock/r8a7740-clock.h>
@@ -77,7 +124,11 @@ examples:
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>, <&fsiack_clk>, <&fsidiva_clk>,
+ <&fsib_clk>, <&fsibck_clk>, <&fsidivb_clk>;
+ clock-names = "fck", "spu", "icka", "xcka", "diva",
+ "ickb", "xckb", "divb";
power-domains = <&pd_a4mp>;
#sound-dai-cells = <1>;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 02/10] ARM: dts: renesas: r8a7740: Add clocks for FSI
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
2026-06-05 12:19 ` [PATCH v4 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 12:19 ` [PATCH v4 03/10] ASoC: renesas: fsi: Fix trigger stop ordering phucduc.bui
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Add the SPU bus clock, icka/b functional clocks, and xcka/b external
clock inputs to the FSI device node.
This prepares for subsequent driver changes that explicitly manage the
SPU clock required for FSI register access on the r8a7740.
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] 16+ messages in thread
* [PATCH v4 03/10] ASoC: renesas: fsi: Fix trigger stop ordering
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
2026-06-05 12:19 ` [PATCH v4 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
2026-06-05 12:19 ` [PATCH v4 02/10] ARM: dts: renesas: r8a7740: Add clocks for FSI phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 12:19 ` [PATCH v4 04/10] ASoC: renesas: fsi: Move fsi_stream_is_working() phucduc.bui
` (6 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Call fsi_stream_stop() before fsi_hw_shutdown(). This matches the existing
order in the suspend path.
This change ensures all register accesses during stream shutdown are fully
completed before disabling the clocks.
Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Changes in v4:
- update commit messages
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] 16+ messages in thread
* [PATCH v4 04/10] ASoC: renesas: fsi: Move fsi_stream_is_working()
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
` (2 preceding siblings ...)
2026-06-05 12:19 ` [PATCH v4 03/10] ASoC: renesas: fsi: Fix trigger stop ordering phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 12:19 ` [PATCH v4 05/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Move fsi_stream_is_working() before fsi_count_fifo_err().
This prepares for a subsequent patch that needs to check stream status
when handling in-flight IRQ handlers. No functional changwqes intended.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/renesas/fsi.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 94ab2e490810..429c3c9b6ede 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -442,6 +442,16 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
return samples / fsi->chan_num;
}
+static int fsi_stream_is_working(struct fsi_priv *fsi,
+ struct fsi_stream *io)
+{
+ struct fsi_master *master = fsi_get_master(fsi);
+
+ guard(spinlock_irqsave)(&master->lock);
+
+ return !!(io->substream && io->substream->runtime);
+}
+
static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
struct fsi_stream *io)
{
@@ -488,16 +498,6 @@ static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
return fsi_is_play(substream) ? &fsi->playback : &fsi->capture;
}
-static int fsi_stream_is_working(struct fsi_priv *fsi,
- struct fsi_stream *io)
-{
- struct fsi_master *master = fsi_get_master(fsi);
-
- guard(spinlock_irqsave)(&master->lock);
-
- return !!(io->substream && io->substream->runtime);
-}
-
static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
{
return io->priv;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 05/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
` (3 preceding siblings ...)
2026-06-05 12:19 ` [PATCH v4 04/10] ASoC: renesas: fsi: Move fsi_stream_is_working() phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 12:19 ` [PATCH v4 06/10] ASoC: renesas: fsi: Move fsi_clk_init() phucduc.bui
` (4 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
In-flight IRQs may still be running when the SPU clock is disabled,
leading to register access after shutdown and causing system hangs.
Fix this to use fsi_stream_is_working() when handling in-flight IRQ
handlers. If no streams are active, the handler now returns immediately
to prevent hardware access.
Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Changes in v4:
- use fsi_stream_is_working instead of running_streams.
sound/soc/renesas/fsi.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 429c3c9b6ede..0f350bddeb1d 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -470,6 +470,10 @@ static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
static void fsi_count_fifo_err(struct fsi_priv *fsi)
{
+ if (!fsi_stream_is_working(fsi, &fsi->playback) &&
+ !fsi_stream_is_working(fsi, &fsi->capture))
+ return;
+
u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
u32 istatus = fsi_reg_read(fsi, DIFF_ST);
@@ -681,6 +685,10 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
u32 data = 0;
struct fsi_master *master = fsi_get_master(fsi);
+ if (!fsi_stream_is_working(fsi, &fsi->playback) &&
+ !fsi_stream_is_working(fsi, &fsi->capture))
+ return;
+
data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback));
data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture));
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 06/10] ASoC: renesas: fsi: Move fsi_clk_init()
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
` (4 preceding siblings ...)
2026-06-05 12:19 ` [PATCH v4 05/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 12:19 ` [PATCH v4 07/10] ASoC: renesas: fsi: Use devm_clk_get_optional() for optional clocks phucduc.bui
` (3 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, 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 0f350bddeb1d..43e6772c06d5 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -717,70 +717,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)
{
@@ -1034,6 +970,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] 16+ messages in thread
* [PATCH v4 07/10] ASoC: renesas: fsi: Use devm_clk_get_optional() for optional clocks
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
` (5 preceding siblings ...)
2026-06-05 12:19 ` [PATCH v4 06/10] ASoC: renesas: fsi: Move fsi_clk_init() phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 12:19 ` [PATCH v4 08/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
The xck, ick and div clocks are optional resources. Use
devm_clk_get_optional() instead of devm_clk_get() when acquiring these
clocks and switch to dev_err_probe() for error reporting.
Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/renesas/fsi.c | 26 ++++++++++----------------
1 file changed, 10 insertions(+), 16 deletions(-)
diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 43e6772c06d5..a2d7d17dd2bb 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -990,15 +990,13 @@ static int fsi_clk_init(struct device *dev,
clock->own = devm_clk_get(dev, NULL);
if (IS_ERR(clock->own))
- return -EINVAL;
+ return dev_err_probe(dev, PTR_ERR(clock->own), "Can't get fck clock\n");
/* 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;
@@ -1007,11 +1005,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;
@@ -1020,11 +1016,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;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 08/10] ASoC: renesas: fsi: refactor clock initialization
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
` (6 preceding siblings ...)
2026-06-05 12:19 ` [PATCH v4 07/10] ASoC: renesas: fsi: Use devm_clk_get_optional() for optional clocks phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-08 0:06 ` Kuninori Morimoto
2026-06-05 12:19 ` [PATCH v4 09/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
2026-06-05 12:19 ` [PATCH v4 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui
9 siblings, 1 reply; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Move fsi_clk_init() from set_fmt() to probe.
This moves clock resource lookup from fsi_dai_set_fmt() to the probe
path. The set_rate() callbacks validate that the required clock
resources are available before they are used for hardware
configuration.
Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Changes in v4:
- Handle the return value of fsi_clk_init() to properly support deferred
probe, as suggested by Mark.
sound/soc/renesas/fsi.c | 52 +++++++++++++++++++++++++++--------------
1 file changed, 35 insertions(+), 17 deletions(-)
diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index a2d7d17dd2bb..3f303e15e835 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -292,6 +292,7 @@ struct fsi_master {
void __iomem *base;
struct fsi_priv fsia;
struct fsi_priv fsib;
+ struct clk *clk_spu;
const struct fsi_core *core;
spinlock_t lock;
};
@@ -862,6 +863,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) {
@@ -898,6 +904,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))
@@ -970,28 +981,38 @@ 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 dev_err_probe(dev, PTR_ERR(clock->own), "Can't get fck clock\n");
+ if (!master->clk_spu) {
+ master->clk_spu = devm_clk_get_optional(dev, "spu");
+ if (IS_ERR(master->clk_spu))
+ return dev_err_probe(dev, PTR_ERR(master->clk_spu),
+ "Can't get spu clock\n");
+ }
+
/* external clock */
if (xck) {
clock->xck = devm_clk_get_optional(dev, is_porta ? "xcka" : "xckb");
@@ -1666,15 +1687,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);
@@ -1972,6 +1984,9 @@ static int fsi_probe(struct platform_device *pdev)
fsi->master = master;
fsi_port_info_init(fsi, &info.port_a);
fsi_handler_init(fsi, &info.port_a);
+ ret = fsi_clk_init(&pdev->dev, fsi);
+ if (ret)
+ return ret;
ret = fsi_stream_probe(fsi, &pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "FSIA stream probe failed\n");
@@ -1985,6 +2000,9 @@ static int fsi_probe(struct platform_device *pdev)
fsi->master = master;
fsi_port_info_init(fsi, &info.port_b);
fsi_handler_init(fsi, &info.port_b);
+ ret = fsi_clk_init(&pdev->dev, fsi);
+ if (ret)
+ return ret;
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] 16+ messages in thread
* [PATCH v4 09/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare()
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
` (7 preceding siblings ...)
2026-06-05 12:19 ` [PATCH v4 08/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 12:19 ` [PATCH v4 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui
9 siblings, 0 replies; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Add fsi_clk_prepare() and fsi_clk_unprepare() helpers and call them
from fsi_dai_startup() and fsi_dai_shutdown().
This ensures clk_prepare() and clk_unprepare() are executed from
sleepable contexts and keeps clocks prepared only while audio streams
are active.
Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Changes in v4:
- Move clock->count early return check to the beginning of
fsi_clk_[un]prepare() to simplify the code.
sound/soc/renesas/fsi.c | 77 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 76 insertions(+), 1 deletion(-)
diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 3f303e15e835..6537321242c0 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -294,6 +294,7 @@ struct fsi_master {
struct fsi_priv fsib;
struct clk *clk_spu;
const struct fsi_core *core;
+ int spu_count;
spinlock_t lock;
};
@@ -730,6 +731,78 @@ 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 (clock->count != 0)
+ return 0;
+
+ 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 (clock->count != 0)
+ return;
+
+ 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)
{
@@ -1580,7 +1653,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
fsi_clk_invalid(fsi);
- return 0;
+ return fsi_clk_prepare(fsi);
}
static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
@@ -1588,6 +1661,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
+ fsi_clk_unprepare(fsi);
fsi_clk_invalid(fsi);
}
@@ -1975,6 +2049,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] 16+ messages in thread
* [PATCH v4 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
` (8 preceding siblings ...)
2026-06-05 12:19 ` [PATCH v4 09/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
@ 2026-06-05 12:19 ` phucduc.bui
2026-06-05 14:21 ` Mark Brown
9 siblings, 1 reply; 16+ messages in thread
From: phucduc.bui @ 2026-06-05 12:19 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Geert Uytterhoeven
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Jaroslav Kysela, Takashi Iwai, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, 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.
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 6537321242c0..d7cc5a14a099 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -1585,6 +1585,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))
@@ -1642,6 +1655,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] 16+ messages in thread
* Re: [PATCH v4 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown
2026-06-05 12:19 ` [PATCH v4 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui
@ 2026-06-05 14:21 ` Mark Brown
2026-06-05 22:29 ` Bui Duc Phuc
0 siblings, 1 reply; 16+ messages in thread
From: Mark Brown @ 2026-06-05 14:21 UTC (permalink / raw)
To: phucduc.bui
Cc: Kuninori Morimoto, Geert Uytterhoeven, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Jaroslav Kysela,
Takashi Iwai, linux-sound, linux-renesas-soc, devicetree,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 724 bytes --]
On Fri, Jun 05, 2026 at 07:19:54PM +0700, phucduc.bui@gmail.com wrote:
> 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.
> + /* 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++;
The indentation here seems wrong. We're also using spu_count to
separately guard the clk_prepare() in fsi_clk_prepare() which seems
problematic, I'm having to think too hard about how this might be
robust.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown
2026-06-05 14:21 ` Mark Brown
@ 2026-06-05 22:29 ` Bui Duc Phuc
2026-06-08 0:08 ` Kuninori Morimoto
0 siblings, 1 reply; 16+ messages in thread
From: Bui Duc Phuc @ 2026-06-05 22:29 UTC (permalink / raw)
To: Mark Brown
Cc: Kuninori Morimoto, Geert Uytterhoeven, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Jaroslav Kysela,
Takashi Iwai, linux-sound, linux-renesas-soc, devicetree,
linux-kernel
Hi Mark, Morimoto-san,
>
> The indentation here seems wrong. We're also using spu_count to
> separately guard the clk_prepare() in fsi_clk_prepare() which seems
> problematic, I'm having to think too hard about how this might be
> robust.
Thank you for your reviews.
I think we can just drop spu_count and let the clk core handle it,
since the core already refcounts via enable_count/prepare_count.
What do you think, Morimoto-san?
Best regards,
Phuc
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 08/10] ASoC: renesas: fsi: refactor clock initialization
2026-06-05 12:19 ` [PATCH v4 08/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
@ 2026-06-08 0:06 ` Kuninori Morimoto
2026-06-08 11:01 ` Bui Duc Phuc
0 siblings, 1 reply; 16+ messages in thread
From: Kuninori Morimoto @ 2026-06-08 0:06 UTC (permalink / raw)
To: phucduc.bui
Cc: Mark Brown, Geert Uytterhoeven, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Jaroslav Kysela,
Takashi Iwai, linux-sound, linux-renesas-soc, devicetree,
linux-kernel
Hi Bui
Thank you for the patch
> Move fsi_clk_init() from set_fmt() to probe.
> This moves clock resource lookup from fsi_dai_set_fmt() to the probe
> path. The set_rate() callbacks validate that the required clock
> resources are available before they are used for hardware
> configuration.
>
> Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> ---
In my understanding,
[07/10] patch
(A) - devm_clk_get() -> devm_clk_get_optional()
(B) - use dev_err_probe()
[08/10] patch
(C) - add clk_spu
(D) - call fsi_clk_init() from probe()
I think...
(A) should be 1 patch
(B) and (D) can be merged into 1 patch
(C) should be 1 patch
Thank you for your help !!
Best regards
---
Kuninori Morimoto
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown
2026-06-05 22:29 ` Bui Duc Phuc
@ 2026-06-08 0:08 ` Kuninori Morimoto
0 siblings, 0 replies; 16+ messages in thread
From: Kuninori Morimoto @ 2026-06-08 0:08 UTC (permalink / raw)
To: Bui Duc Phuc
Cc: Mark Brown, Geert Uytterhoeven, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Jaroslav Kysela,
Takashi Iwai, linux-sound, linux-renesas-soc, devicetree,
linux-kernel
Hi Bui
> > The indentation here seems wrong. We're also using spu_count to
> > separately guard the clk_prepare() in fsi_clk_prepare() which seems
> > problematic, I'm having to think too hard about how this might be
> > robust.
>
> Thank you for your reviews.
> I think we can just drop spu_count and let the clk core handle it,
> since the core already refcounts via enable_count/prepare_count.
>
> What do you think, Morimoto-san?
Yeah, maybe
Thank you for your help !!
Best regards
---
Kuninori Morimoto
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 08/10] ASoC: renesas: fsi: refactor clock initialization
2026-06-08 0:06 ` Kuninori Morimoto
@ 2026-06-08 11:01 ` Bui Duc Phuc
0 siblings, 0 replies; 16+ messages in thread
From: Bui Duc Phuc @ 2026-06-08 11:01 UTC (permalink / raw)
To: Kuninori Morimoto
Cc: Mark Brown, Geert Uytterhoeven, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Jaroslav Kysela,
Takashi Iwai, linux-sound, linux-renesas-soc, devicetree,
linux-kernel
Hi Morimoto-san,
Thank you for the review.
> In my understanding,
>
> [07/10] patch
> (A) - devm_clk_get() -> devm_clk_get_optional()
> (B) - use dev_err_probe()
>
> [08/10] patch
> (C) - add clk_spu
> (D) - call fsi_clk_init() from probe()
>
> I think...
> (A) should be 1 patch
> (B) and (D) can be merged into 1 patch
> (C) should be 1 patch
I understand your suggestion regarding the patch split and will
rework the series accordingly. I will send the next version soon.
Thank you for your help !
Best regards,
Phuc
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-06-08 11:01 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-05 12:19 [PATCH v4 00/10] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
2026-06-05 12:19 ` [PATCH v4 01/10] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
2026-06-05 12:19 ` [PATCH v4 02/10] ARM: dts: renesas: r8a7740: Add clocks for FSI phucduc.bui
2026-06-05 12:19 ` [PATCH v4 03/10] ASoC: renesas: fsi: Fix trigger stop ordering phucduc.bui
2026-06-05 12:19 ` [PATCH v4 04/10] ASoC: renesas: fsi: Move fsi_stream_is_working() phucduc.bui
2026-06-05 12:19 ` [PATCH v4 05/10] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
2026-06-05 12:19 ` [PATCH v4 06/10] ASoC: renesas: fsi: Move fsi_clk_init() phucduc.bui
2026-06-05 12:19 ` [PATCH v4 07/10] ASoC: renesas: fsi: Use devm_clk_get_optional() for optional clocks phucduc.bui
2026-06-05 12:19 ` [PATCH v4 08/10] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
2026-06-08 0:06 ` Kuninori Morimoto
2026-06-08 11:01 ` Bui Duc Phuc
2026-06-05 12:19 ` [PATCH v4 09/10] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
2026-06-05 12:19 ` [PATCH v4 10/10] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui
2026-06-05 14:21 ` Mark Brown
2026-06-05 22:29 ` Bui Duc Phuc
2026-06-08 0:08 ` Kuninori Morimoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox