]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
authorLad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Mon, 10 Jan 2022 09:47:07 +0000 (09:47 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 24 Jan 2022 13:31:27 +0000 (13:31 +0000)
Instead of recursively calling rz_ssi_pio_recv() use a while loop
to read the samples from RX fifo.

This also fixes an issue where the return value of rz_ssi_pio_recv()
was ignored when called recursively.

Fixes: 03e786bd4341 ("ASoC: sh: Add RZ/G2L SSIF-2 driver")
Reported-by: Pavel Machek <pavel@denx.de>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20220110094711.8574-2-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sh/rz-ssi.c

index e8d98b362f9db7f3fdc306a2e5839480220846c4..2ac2c9722b3b34df51f9db2a290f8bce13df6191 100644 (file)
@@ -411,54 +411,56 @@ static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
 {
        struct snd_pcm_substream *substream = strm->substream;
        struct snd_pcm_runtime *runtime;
+       bool done = false;
        u16 *buf;
        int fifo_samples;
        int frames_left;
-       int samples = 0;
+       int samples;
        int i;
 
        if (!rz_ssi_stream_is_valid(ssi, strm))
                return -EINVAL;
 
        runtime = substream->runtime;
-       /* frames left in this period */
-       frames_left = runtime->period_size - (strm->buffer_pos %
-                                             runtime->period_size);
-       if (frames_left == 0)
-               frames_left = runtime->period_size;
 
-       /* Samples in RX FIFO */
-       fifo_samples = (rz_ssi_reg_readl(ssi, SSIFSR) >>
-                       SSIFSR_RDC_SHIFT) & SSIFSR_RDC_MASK;
-
-       /* Only read full frames at a time */
-       while (frames_left && (fifo_samples >= runtime->channels)) {
-               samples += runtime->channels;
-               fifo_samples -= runtime->channels;
-               frames_left--;
-       }
+       while (!done) {
+               /* frames left in this period */
+               frames_left = runtime->period_size -
+                             (strm->buffer_pos % runtime->period_size);
+               if (!frames_left)
+                       frames_left = runtime->period_size;
+
+               /* Samples in RX FIFO */
+               fifo_samples = (rz_ssi_reg_readl(ssi, SSIFSR) >>
+                               SSIFSR_RDC_SHIFT) & SSIFSR_RDC_MASK;
+
+               /* Only read full frames at a time */
+               samples = 0;
+               while (frames_left && (fifo_samples >= runtime->channels)) {
+                       samples += runtime->channels;
+                       fifo_samples -= runtime->channels;
+                       frames_left--;
+               }
 
-       /* not enough samples yet */
-       if (samples == 0)
-               return 0;
+               /* not enough samples yet */
+               if (!samples)
+                       break;
 
-       /* calculate new buffer index */
-       buf = (u16 *)(runtime->dma_area);
-       buf += strm->buffer_pos * runtime->channels;
+               /* calculate new buffer index */
+               buf = (u16 *)(runtime->dma_area);
+               buf += strm->buffer_pos * runtime->channels;
 
-       /* Note, only supports 16-bit samples */
-       for (i = 0; i < samples; i++)
-               *buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16);
+               /* Note, only supports 16-bit samples */
+               for (i = 0; i < samples; i++)
+                       *buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16);
 
-       rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
-       rz_ssi_pointer_update(strm, samples / runtime->channels);
+               rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
+               rz_ssi_pointer_update(strm, samples / runtime->channels);
 
-       /*
-        * If we finished this period, but there are more samples in
-        * the RX FIFO, call this function again
-        */
-       if (frames_left == 0 && fifo_samples >= runtime->channels)
-               rz_ssi_pio_recv(ssi, strm);
+               /* check if there are no more samples in the RX FIFO */
+               if (!(!frames_left && fifo_samples >= runtime->channels))
+                       done = true;
+       }
 
        return 0;
 }