Message ID | 20241210170953.2936724-5-claudiu.beznea.uj@bp.renesas.com (mailing list archive) |
---|---|
State | New |
Delegated to: | Kieran Bingham |
Headers | show |
Series | Add audio support for the Renesas RZ/G3S SoC | expand |
On Tue, Dec 10, 2024 at 6:10 PM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > The stop trigger invokes rz_ssi_stop() and rz_ssi_stream_quit(). > - The purpose of rz_ssi_stop() is to disable TX/RX, terminate DMA > transactions, and set the controller to idle. > - The purpose of rz_ssi_stream_quit() is to reset the substream-specific > software data by setting strm->running and strm->substream appropriately. > > The function rz_ssi_is_stream_running() checks if both strm->substream and > strm->running are valid and returns true if so. Its implementation is as > follows: > > static inline bool rz_ssi_is_stream_running(struct rz_ssi_stream *strm) > { > return strm->substream && strm->running; > } > > When the controller is configured in full-duplex mode (with both playback > and capture active), the rz_ssi_stop() function does not modify the > controller settings when called for the first substream in the full-duplex > setup. Instead, it simply sets strm->running = 0 and returns if the > companion substream is still running. The following code illustrates this: > > static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) > { > strm->running = 0; > > if (rz_ssi_is_stream_running(&ssi->playback) || > rz_ssi_is_stream_running(&ssi->capture)) > return 0; > > // ... > } > > The controller settings, along with the DMA termination (for the last > stopped substream), are only applied when the last substream in the > full-duplex setup is stopped. > > While applying the controller settings only when the last substream stops > is not problematic, terminating the DMA operations for only one substream > causes failures when starting and stopping full-duplex operations multiple > times in a loop. > > To address this issue, call dmaengine_terminate_async() for both substreams > involved in the full-duplex setup when the last substream in the setup is > stopped. > > Fixes: 4f8cd05a4305 ("ASoC: sh: rz-ssi: Add full duplex support") > Cc: stable@vger.kernel.org > Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com> > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v4: > - updated patch description Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Gr{oetje,eeting}s, Geert
diff --git a/sound/soc/renesas/rz-ssi.c b/sound/soc/renesas/rz-ssi.c index 6efd017aaa7f..2d8721156099 100644 --- a/sound/soc/renesas/rz-ssi.c +++ b/sound/soc/renesas/rz-ssi.c @@ -415,8 +415,12 @@ static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0); /* Cancel all remaining DMA transactions */ - if (rz_ssi_is_dma_enabled(ssi)) - dmaengine_terminate_async(strm->dma_ch); + if (rz_ssi_is_dma_enabled(ssi)) { + if (ssi->playback.dma_ch) + dmaengine_terminate_async(ssi->playback.dma_ch); + if (ssi->capture.dma_ch) + dmaengine_terminate_async(ssi->capture.dma_ch); + } rz_ssi_set_idle(ssi);