linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
       [not found] <20220110094711.8574-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
@ 2022-01-10  9:47 ` Lad Prabhakar
  2022-01-10 15:48   ` Cezary Rojewski
  2022-01-10  9:47 ` [PATCH 2/5] ASoC: sh: rz-ssi: Make the data structures available before registering the handlers Lad Prabhakar
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Lad Prabhakar @ 2022-01-10  9:47 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lad Prabhakar, Biju Das
  Cc: Pavel Machek, linux-renesas-soc, Prabhakar, alsa-devel, linux-kernel

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>
---
 sound/soc/sh/rz-ssi.c | 68 ++++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 33 deletions(-)

diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
index fa0cc08f70ec..37466f65c2b0 100644
--- a/sound/soc/sh/rz-ssi.c
+++ b/sound/soc/sh/rz-ssi.c
@@ -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;
 }
-- 
2.17.1


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

* [PATCH 2/5] ASoC: sh: rz-ssi: Make the data structures available before registering the handlers
       [not found] <20220110094711.8574-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
  2022-01-10  9:47 ` [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively Lad Prabhakar
@ 2022-01-10  9:47 ` Lad Prabhakar
  2022-01-10  9:47 ` [PATCH 3/5] ASoC: sh: rz-ssi: Drop ssi parameter from rz_ssi_stream_init() Lad Prabhakar
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Lad Prabhakar @ 2022-01-10  9:47 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
  Cc: Biju Das, Pavel Machek, linux-renesas-soc, Prabhakar,
	Lad Prabhakar, alsa-devel, linux-kernel

Initialize the spinlock and make the data structures available before
registering the interrupt handlers.

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>
---
 sound/soc/sh/rz-ssi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
index 37466f65c2b0..16de2633a873 100644
--- a/sound/soc/sh/rz-ssi.c
+++ b/sound/soc/sh/rz-ssi.c
@@ -977,6 +977,9 @@ static int rz_ssi_probe(struct platform_device *pdev)
 	ssi->playback.priv = ssi;
 	ssi->capture.priv = ssi;
 
+	spin_lock_init(&ssi->lock);
+	dev_set_drvdata(&pdev->dev, ssi);
+
 	/* Error Interrupt */
 	ssi->irq_int = platform_get_irq_byname(pdev, "int_req");
 	if (ssi->irq_int < 0)
@@ -1024,8 +1027,6 @@ static int rz_ssi_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_resume_and_get(&pdev->dev);
 
-	spin_lock_init(&ssi->lock);
-	dev_set_drvdata(&pdev->dev, ssi);
 	ret = devm_snd_soc_register_component(&pdev->dev, &rz_ssi_soc_component,
 					      rz_ssi_soc_dai,
 					      ARRAY_SIZE(rz_ssi_soc_dai));
-- 
2.17.1


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

* [PATCH 3/5] ASoC: sh: rz-ssi: Drop ssi parameter from rz_ssi_stream_init()
       [not found] <20220110094711.8574-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
  2022-01-10  9:47 ` [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively Lad Prabhakar
  2022-01-10  9:47 ` [PATCH 2/5] ASoC: sh: rz-ssi: Make the data structures available before registering the handlers Lad Prabhakar
@ 2022-01-10  9:47 ` Lad Prabhakar
  2022-01-10  9:47 ` [PATCH 4/5] ASoC: sh: rz-ssi: Make return type of rz_ssi_stream_is_valid() to bool Lad Prabhakar
  2022-01-10  9:47 ` [PATCH 5/5] ASoC: sh: rz-ssi: Add functions to get/set substream pointer Lad Prabhakar
  4 siblings, 0 replies; 13+ messages in thread
From: Lad Prabhakar @ 2022-01-10  9:47 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
  Cc: Biju Das, Pavel Machek, linux-renesas-soc, Prabhakar,
	Lad Prabhakar, alsa-devel, linux-kernel

ssi parameter is unused in rz_ssi_stream_init() so just drop it.

While at it, change the return type of rz_ssi_stream_init() to void
instead of int.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 sound/soc/sh/rz-ssi.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
index 16de2633a873..fa68d3a0bd62 100644
--- a/sound/soc/sh/rz-ssi.c
+++ b/sound/soc/sh/rz-ssi.c
@@ -201,9 +201,8 @@ static int rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi,
 	return ret;
 }
 
-static int rz_ssi_stream_init(struct rz_ssi_priv *ssi,
-			      struct rz_ssi_stream *strm,
-			      struct snd_pcm_substream *substream)
+static void rz_ssi_stream_init(struct rz_ssi_stream *strm,
+			       struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
@@ -219,8 +218,6 @@ static int rz_ssi_stream_init(struct rz_ssi_priv *ssi,
 
 	/* fifo init */
 	strm->fifo_sample_size = SSI_FIFO_DEPTH;
-
-	return 0;
 }
 
 static void rz_ssi_stream_quit(struct rz_ssi_priv *ssi,
@@ -728,9 +725,7 @@ static int rz_ssi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 		rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0);
 		udelay(5);
 
-		ret = rz_ssi_stream_init(ssi, strm, substream);
-		if (ret)
-			goto done;
+		rz_ssi_stream_init(strm, substream);
 
 		if (ssi->dma_rt) {
 			bool is_playback;
-- 
2.17.1


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

* [PATCH 4/5] ASoC: sh: rz-ssi: Make return type of rz_ssi_stream_is_valid() to bool
       [not found] <20220110094711.8574-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
                   ` (2 preceding siblings ...)
  2022-01-10  9:47 ` [PATCH 3/5] ASoC: sh: rz-ssi: Drop ssi parameter from rz_ssi_stream_init() Lad Prabhakar
@ 2022-01-10  9:47 ` Lad Prabhakar
  2022-01-10  9:47 ` [PATCH 5/5] ASoC: sh: rz-ssi: Add functions to get/set substream pointer Lad Prabhakar
  4 siblings, 0 replies; 13+ messages in thread
From: Lad Prabhakar @ 2022-01-10  9:47 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
  Cc: Biju Das, Pavel Machek, linux-renesas-soc, Prabhakar,
	Lad Prabhakar, alsa-devel, linux-kernel

rz_ssi_stream_is_valid() never returns an int, it returns the result of
a condition which is either true or false.

While at it, drop "!!" as the expression is boolean.

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>
---
 sound/soc/sh/rz-ssi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
index fa68d3a0bd62..aabd15e9d515 100644
--- a/sound/soc/sh/rz-ssi.c
+++ b/sound/soc/sh/rz-ssi.c
@@ -188,14 +188,14 @@ static inline bool rz_ssi_is_dma_enabled(struct rz_ssi_priv *ssi)
 	return (ssi->playback.dma_ch && (ssi->dma_rt || ssi->capture.dma_ch));
 }
 
-static int rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi,
-				  struct rz_ssi_stream *strm)
+static bool rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi,
+				   struct rz_ssi_stream *strm)
 {
 	unsigned long flags;
-	int ret;
+	bool ret;
 
 	spin_lock_irqsave(&ssi->lock, flags);
-	ret = !!(strm->substream && strm->substream->runtime);
+	ret = strm->substream && strm->substream->runtime;
 	spin_unlock_irqrestore(&ssi->lock, flags);
 
 	return ret;
-- 
2.17.1


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

* [PATCH 5/5] ASoC: sh: rz-ssi: Add functions to get/set substream pointer
       [not found] <20220110094711.8574-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
                   ` (3 preceding siblings ...)
  2022-01-10  9:47 ` [PATCH 4/5] ASoC: sh: rz-ssi: Make return type of rz_ssi_stream_is_valid() to bool Lad Prabhakar
@ 2022-01-10  9:47 ` Lad Prabhakar
  2022-01-10 15:10   ` Mark Brown
  4 siblings, 1 reply; 13+ messages in thread
From: Lad Prabhakar @ 2022-01-10  9:47 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
  Cc: Biju Das, Pavel Machek, linux-renesas-soc, Prabhakar,
	Lad Prabhakar, alsa-devel, linux-kernel

A copy of substream pointer is stored in priv structure during
rz_ssi_dai_trigger() callback ie in SNDRV_PCM_TRIGGER_START case
and the pointer is assigned to NULL in case of SNDRV_PCM_TRIGGER_STOP.

The driver used the locks only in rz_ssi_stream_is_valid() and assigned
the local substream pointer to NULL in rz_ssi_dai_trigger() callback and
in rest of the driver no locking was used while assigning substream
pointer.

This patch adds functions to get/set substream pointer with locks acquired
and replaces the instances of access to substream pointer with the
get/set functions.

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>
---
 sound/soc/sh/rz-ssi.c | 55 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 14 deletions(-)

diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
index aabd15e9d515..057aedacedec 100644
--- a/sound/soc/sh/rz-ssi.c
+++ b/sound/soc/sh/rz-ssi.c
@@ -201,12 +201,36 @@ static bool rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi,
 	return ret;
 }
 
+static struct snd_pcm_substream *rz_ssi_get_substream(struct rz_ssi_stream *strm)
+{
+	struct rz_ssi_priv *ssi = strm->priv;
+	struct snd_pcm_substream *substream;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ssi->lock, flags);
+	substream = strm->substream;
+	spin_unlock_irqrestore(&ssi->lock, flags);
+
+	return substream;
+}
+
+static void rz_ssi_set_substream(struct rz_ssi_stream *strm,
+				 struct snd_pcm_substream *substream)
+{
+	struct rz_ssi_priv *ssi = strm->priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ssi->lock, flags);
+	strm->substream = substream;
+	spin_unlock_irqrestore(&ssi->lock, flags);
+}
+
 static void rz_ssi_stream_init(struct rz_ssi_stream *strm,
 			       struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
-	strm->substream = substream;
+	rz_ssi_set_substream(strm, substream);
 	strm->sample_width = samples_to_bytes(runtime, 1);
 	strm->dma_buffer_pos = 0;
 	strm->period_counter = 0;
@@ -223,12 +247,13 @@ static void rz_ssi_stream_init(struct rz_ssi_stream *strm,
 static void rz_ssi_stream_quit(struct rz_ssi_priv *ssi,
 			       struct rz_ssi_stream *strm)
 {
-	struct snd_soc_dai *dai = rz_ssi_get_dai(strm->substream);
-	unsigned long flags;
+	struct snd_pcm_substream *substream;
+	struct snd_soc_dai *dai;
 
-	spin_lock_irqsave(&ssi->lock, flags);
-	strm->substream = NULL;
-	spin_unlock_irqrestore(&ssi->lock, flags);
+	substream = rz_ssi_get_substream(strm);
+	rz_ssi_set_substream(strm, NULL);
+
+	dai = rz_ssi_get_dai(substream);
 
 	if (strm->oerr_num > 0)
 		dev_info(dai->dev, "overrun = %d\n", strm->oerr_num);
@@ -301,7 +326,8 @@ static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate,
 
 static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
 {
-	bool is_play = rz_ssi_stream_is_play(ssi, strm->substream);
+	struct snd_pcm_substream *substream = rz_ssi_get_substream(strm);
+	bool is_play = rz_ssi_stream_is_play(ssi, substream);
 	u32 ssicr, ssifcr;
 
 	ssicr = rz_ssi_reg_readl(ssi, SSICR);
@@ -382,7 +408,7 @@ static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
 
 static void rz_ssi_pointer_update(struct rz_ssi_stream *strm, int frames)
 {
-	struct snd_pcm_substream *substream = strm->substream;
+	struct snd_pcm_substream *substream = rz_ssi_get_substream(strm);
 	struct snd_pcm_runtime *runtime;
 	int current_period;
 
@@ -399,14 +425,14 @@ static void rz_ssi_pointer_update(struct rz_ssi_stream *strm, int frames)
 
 	current_period = strm->buffer_pos / runtime->period_size;
 	if (strm->period_counter != current_period) {
-		snd_pcm_period_elapsed(strm->substream);
+		snd_pcm_period_elapsed(substream);
 		strm->period_counter = current_period;
 	}
 }
 
 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_substream *substream = rz_ssi_get_substream(strm);
 	struct snd_pcm_runtime *runtime;
 	bool done = false;
 	u16 *buf;
@@ -464,7 +490,7 @@ static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
 
 static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
 {
-	struct snd_pcm_substream *substream = strm->substream;
+	struct snd_pcm_substream *substream = rz_ssi_get_substream(strm);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int sample_space;
 	int samples = 0;
@@ -588,7 +614,7 @@ static int rz_ssi_dma_slave_config(struct rz_ssi_priv *ssi,
 static int rz_ssi_dma_transfer(struct rz_ssi_priv *ssi,
 			       struct rz_ssi_stream *strm)
 {
-	struct snd_pcm_substream *substream = strm->substream;
+	struct snd_pcm_substream *substream = rz_ssi_get_substream(strm);
 	struct dma_async_tx_descriptor *desc;
 	struct snd_pcm_runtime *runtime;
 	enum dma_transfer_direction dir;
@@ -646,12 +672,13 @@ static int rz_ssi_dma_transfer(struct rz_ssi_priv *ssi,
 static void rz_ssi_dma_complete(void *data)
 {
 	struct rz_ssi_stream *strm = (struct rz_ssi_stream *)data;
+	struct snd_pcm_substream *substream = rz_ssi_get_substream(strm);
 
-	if (!strm->running || !strm->substream || !strm->substream->runtime)
+	if (!strm->running || !substream || !substream->runtime)
 		return;
 
 	/* Note that next DMA transaction has probably already started */
-	rz_ssi_pointer_update(strm, strm->substream->runtime->period_size);
+	rz_ssi_pointer_update(strm, substream->runtime->period_size);
 
 	/* Queue up another DMA transaction */
 	rz_ssi_dma_transfer(strm->priv, strm);
-- 
2.17.1


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

* Re: [PATCH 5/5] ASoC: sh: rz-ssi: Add functions to get/set substream pointer
  2022-01-10  9:47 ` [PATCH 5/5] ASoC: sh: rz-ssi: Add functions to get/set substream pointer Lad Prabhakar
@ 2022-01-10 15:10   ` Mark Brown
  2022-01-10 16:14     ` Lad, Prabhakar
  0 siblings, 1 reply; 13+ messages in thread
From: Mark Brown @ 2022-01-10 15:10 UTC (permalink / raw)
  To: Lad Prabhakar
  Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Biju Das,
	Pavel Machek, linux-renesas-soc, Prabhakar, alsa-devel,
	linux-kernel

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

On Mon, Jan 10, 2022 at 09:47:11AM +0000, Lad Prabhakar wrote:

> +static struct snd_pcm_substream *rz_ssi_get_substream(struct rz_ssi_stream *strm)
> +{
> +	struct rz_ssi_priv *ssi = strm->priv;
> +	struct snd_pcm_substream *substream;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&ssi->lock, flags);
> +	substream = strm->substream;
> +	spin_unlock_irqrestore(&ssi->lock, flags);

This locking doesn't seem useful, we just take a copy of the lock and
then immediately return so the lock isn't protecting anything in
particular - the caller can happily continue using the substream after
the variable has been updated.

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

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

* Re: [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
  2022-01-10  9:47 ` [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively Lad Prabhakar
@ 2022-01-10 15:48   ` Cezary Rojewski
  2022-01-10 16:03     ` Lad, Prabhakar
  0 siblings, 1 reply; 13+ messages in thread
From: Cezary Rojewski @ 2022-01-10 15:48 UTC (permalink / raw)
  To: Lad Prabhakar, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Biju Das
  Cc: Pavel Machek, linux-renesas-soc, Prabhakar, alsa-devel, linux-kernel

On 2022-01-10 10:47 AM, Lad Prabhakar wrote:
> Instead of recursively calling rz_ssi_pio_recv() use a while loop
> to read the samples from RX fifo.

Recursion and loops are means for doing something repeatedly. Could you 
specify _why_ such change was made i.e. the conversion from one method 
into the other? I bet the code is not being changed for the sake of 
changing it, the reason is simply missing in the commit message.

Please note that refactoring below function into while-loop has a side 
effect: everything had to be indented by additional tab. Generally, 
readability increases if function is shaped 'linearly'.

> 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>
> ---
>   sound/soc/sh/rz-ssi.c | 68 ++++++++++++++++++++++---------------------
>   1 file changed, 35 insertions(+), 33 deletions(-)
> 
> diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
> index fa0cc08f70ec..37466f65c2b0 100644
> --- a/sound/soc/sh/rz-ssi.c
> +++ b/sound/soc/sh/rz-ssi.c
> @@ -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) {

I wonder if converting this into do-while isn't a better option. Maybe 
I'm missing something but 'done' flag seems to be changed only as an 
outcome of the last if-statement (last step) in this entire procedure. 
Perhaps condition from said if-statement could also be moved into 
'while' portion of do-while loop.

> +		/* 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);

Is the second pair of brackets needed?

> +		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;
>   }
> 

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

* Re: [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
  2022-01-10 15:48   ` Cezary Rojewski
@ 2022-01-10 16:03     ` Lad, Prabhakar
  2022-01-10 17:48       ` Cezary Rojewski
  2022-01-10 18:44       ` Pavel Machek
  0 siblings, 2 replies; 13+ messages in thread
From: Lad, Prabhakar @ 2022-01-10 16:03 UTC (permalink / raw)
  To: Cezary Rojewski, Biju Das, Pavel Machek
  Cc: Lad Prabhakar, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Linux-Renesas, alsa-devel, LKML

Hi Cezary,

Thank you for the review.

On Mon, Jan 10, 2022 at 3:48 PM Cezary Rojewski
<cezary.rojewski@intel.com> wrote:
>
> On 2022-01-10 10:47 AM, Lad Prabhakar wrote:
> > Instead of recursively calling rz_ssi_pio_recv() use a while loop
> > to read the samples from RX fifo.
>
> Recursion and loops are means for doing something repeatedly. Could you
> specify _why_ such change was made i.e. the conversion from one method
> into the other? I bet the code is not being changed for the sake of
> changing it, the reason is simply missing in the commit message.
>
I had feedback from Pavel "recursion is unwelcome in kernel due to
limited stack use." which I did agree with as a result I have come up
with this patch. Also to add this driver will later be used on Renesas
RZ/A2 SoC's which runs with limited memory.

> Please note that refactoring below function into while-loop has a side
> effect: everything had to be indented by additional tab. Generally,
> readability increases if function is shaped 'linearly'.
>
I do agree, my initial patch just added a jump back to the start of
the function if there are more samples, but Biju suggested to use a
while loop instead.

> > 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>
> > ---
> >   sound/soc/sh/rz-ssi.c | 68 ++++++++++++++++++++++---------------------
> >   1 file changed, 35 insertions(+), 33 deletions(-)
> >
> > diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
> > index fa0cc08f70ec..37466f65c2b0 100644
> > --- a/sound/soc/sh/rz-ssi.c
> > +++ b/sound/soc/sh/rz-ssi.c
> > @@ -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) {
>
> I wonder if converting this into do-while isn't a better option. Maybe
> I'm missing something but 'done' flag seems to be changed only as an
> outcome of the last if-statement (last step) in this entire procedure.
> Perhaps condition from said if-statement could also be moved into
> 'while' portion of do-while loop.
>
Agreed.

> > +             /* 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);
>
> Is the second pair of brackets needed?
>
Nope can be dropped.

Cheers,
Prabhakar

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

* Re: [PATCH 5/5] ASoC: sh: rz-ssi: Add functions to get/set substream pointer
  2022-01-10 15:10   ` Mark Brown
@ 2022-01-10 16:14     ` Lad, Prabhakar
  0 siblings, 0 replies; 13+ messages in thread
From: Lad, Prabhakar @ 2022-01-10 16:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: Lad Prabhakar, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Biju Das, Pavel Machek, Linux-Renesas, alsa-devel, LKML

Hi Mark,

Thank you for the review.

On Mon, Jan 10, 2022 at 3:10 PM Mark Brown <broonie@kernel.org> wrote:
>
> On Mon, Jan 10, 2022 at 09:47:11AM +0000, Lad Prabhakar wrote:
>
> > +static struct snd_pcm_substream *rz_ssi_get_substream(struct rz_ssi_stream *strm)
> > +{
> > +     struct rz_ssi_priv *ssi = strm->priv;
> > +     struct snd_pcm_substream *substream;
> > +     unsigned long flags;
> > +
> > +     spin_lock_irqsave(&ssi->lock, flags);
> > +     substream = strm->substream;
> > +     spin_unlock_irqrestore(&ssi->lock, flags);
>
> This locking doesn't seem useful, we just take a copy of the lock and
> then immediately return so the lock isn't protecting anything in
> particular - the caller can happily continue using the substream after
> the variable has been updated.
>
Ok will drop the locking from get function.

Cheers,
Prabhakar

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

* Re: [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
  2022-01-10 16:03     ` Lad, Prabhakar
@ 2022-01-10 17:48       ` Cezary Rojewski
  2022-01-10 20:16         ` Lad, Prabhakar
  2022-01-10 18:44       ` Pavel Machek
  1 sibling, 1 reply; 13+ messages in thread
From: Cezary Rojewski @ 2022-01-10 17:48 UTC (permalink / raw)
  To: Lad, Prabhakar, Biju Das, Pavel Machek
  Cc: Lad Prabhakar, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Linux-Renesas, alsa-devel, LKML

On 2022-01-10 5:03 PM, Lad, Prabhakar wrote:
> Hi Cezary,
> 
> Thank you for the review.
> 

...

>> Recursion and loops are means for doing something repeatedly. Could you
>> specify _why_ such change was made i.e. the conversion from one method
>> into the other? I bet the code is not being changed for the sake of
>> changing it, the reason is simply missing in the commit message.
>>
> I had feedback from Pavel "recursion is unwelcome in kernel due to
> limited stack use." which I did agree with as a result I have come up
> with this patch. Also to add this driver will later be used on Renesas
> RZ/A2 SoC's which runs with limited memory.

Adding that reasoning to the commits message will prevent questions 
(such as mine) in the future. Thank you for a quick reply and a 
transparent answer.


Regards,
Czarek

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

* Re: [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
  2022-01-10 16:03     ` Lad, Prabhakar
  2022-01-10 17:48       ` Cezary Rojewski
@ 2022-01-10 18:44       ` Pavel Machek
  2022-01-10 18:58         ` Cezary Rojewski
  1 sibling, 1 reply; 13+ messages in thread
From: Pavel Machek @ 2022-01-10 18:44 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Cezary Rojewski, Biju Das, Pavel Machek, Lad Prabhakar,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Linux-Renesas, alsa-devel, LKML

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

Hi!

> > On 2022-01-10 10:47 AM, Lad Prabhakar wrote:
> > > Instead of recursively calling rz_ssi_pio_recv() use a while loop
> > > to read the samples from RX fifo.
> >
> > Recursion and loops are means for doing something repeatedly. Could you
> > specify _why_ such change was made i.e. the conversion from one method
> > into the other? I bet the code is not being changed for the sake of
> > changing it, the reason is simply missing in the commit message.
> >
> I had feedback from Pavel "recursion is unwelcome in kernel due to
> limited stack use." which I did agree with as a result I have come up
> with this patch. Also to add this driver will later be used on Renesas
> RZ/A2 SoC's which runs with limited memory.
> 
> > Please note that refactoring below function into while-loop has a side
> > effect: everything had to be indented by additional tab. Generally,
> > readability increases if function is shaped 'linearly'.
> >
> I do agree, my initial patch just added a jump back to the start of
> the function if there are more samples, but Biju suggested to use a
> while loop instead.

Yes, loop is better.

I'd actually do while(true) and avoid using the done variable.

    if (!(!frames_left && fifo_samples >= runtime->channels))
              break;

will do the trick. Better yet, do

    if (frames_left || fifo_samples < runtime->channels)
              break;

because double negation is quite confusing and looks like typo.

Best regards,
								Pavel

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

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

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

* Re: [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
  2022-01-10 18:44       ` Pavel Machek
@ 2022-01-10 18:58         ` Cezary Rojewski
  0 siblings, 0 replies; 13+ messages in thread
From: Cezary Rojewski @ 2022-01-10 18:58 UTC (permalink / raw)
  To: Pavel Machek, Lad, Prabhakar
  Cc: Biju Das, Lad Prabhakar, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Linux-Renesas, alsa-devel, LKML

On 2022-01-10 7:44 PM, Pavel Machek wrote:
> Hi!
> 
>>> On 2022-01-10 10:47 AM, Lad Prabhakar wrote:
>>>> Instead of recursively calling rz_ssi_pio_recv() use a while loop
>>>> to read the samples from RX fifo.
>>>
>>> Recursion and loops are means for doing something repeatedly. Could you
>>> specify _why_ such change was made i.e. the conversion from one method
>>> into the other? I bet the code is not being changed for the sake of
>>> changing it, the reason is simply missing in the commit message.
>>>
>> I had feedback from Pavel "recursion is unwelcome in kernel due to
>> limited stack use." which I did agree with as a result I have come up
>> with this patch. Also to add this driver will later be used on Renesas
>> RZ/A2 SoC's which runs with limited memory.

...

> 
> Yes, loop is better.
> 
> I'd actually do while(true) and avoid using the done variable.
> 
>      if (!(!frames_left && fifo_samples >= runtime->channels))
>                break;
> 
> will do the trick. Better yet, do
> 
>      if (frames_left || fifo_samples < runtime->channels)
>                break;
> 
> because double negation is quite confusing and looks like typo.

You could achieve similar results by enlisting do-while loop. That's my 
proposal.


Regards,
Czarek

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

* Re: [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
  2022-01-10 17:48       ` Cezary Rojewski
@ 2022-01-10 20:16         ` Lad, Prabhakar
  0 siblings, 0 replies; 13+ messages in thread
From: Lad, Prabhakar @ 2022-01-10 20:16 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: Biju Das, Pavel Machek, Lad Prabhakar, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Linux-Renesas, alsa-devel, LKML

On Mon, Jan 10, 2022 at 5:48 PM Cezary Rojewski
<cezary.rojewski@intel.com> wrote:
>
> On 2022-01-10 5:03 PM, Lad, Prabhakar wrote:
> > Hi Cezary,
> >
> > Thank you for the review.
> >
>
> ...
>
> >> Recursion and loops are means for doing something repeatedly. Could you
> >> specify _why_ such change was made i.e. the conversion from one method
> >> into the other? I bet the code is not being changed for the sake of
> >> changing it, the reason is simply missing in the commit message.
> >>
> > I had feedback from Pavel "recursion is unwelcome in kernel due to
> > limited stack use." which I did agree with as a result I have come up
> > with this patch. Also to add this driver will later be used on Renesas
> > RZ/A2 SoC's which runs with limited memory.
>
> Adding that reasoning to the commits message will prevent questions
> (such as mine) in the future. Thank you for a quick reply and a
> transparent answer.
>
My bad! I'll update the commit message.

CHeers,
Prabhakar

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

end of thread, other threads:[~2022-01-10 20:16 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20220110094711.8574-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
2022-01-10  9:47 ` [PATCH 1/5] ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively Lad Prabhakar
2022-01-10 15:48   ` Cezary Rojewski
2022-01-10 16:03     ` Lad, Prabhakar
2022-01-10 17:48       ` Cezary Rojewski
2022-01-10 20:16         ` Lad, Prabhakar
2022-01-10 18:44       ` Pavel Machek
2022-01-10 18:58         ` Cezary Rojewski
2022-01-10  9:47 ` [PATCH 2/5] ASoC: sh: rz-ssi: Make the data structures available before registering the handlers Lad Prabhakar
2022-01-10  9:47 ` [PATCH 3/5] ASoC: sh: rz-ssi: Drop ssi parameter from rz_ssi_stream_init() Lad Prabhakar
2022-01-10  9:47 ` [PATCH 4/5] ASoC: sh: rz-ssi: Make return type of rz_ssi_stream_is_valid() to bool Lad Prabhakar
2022-01-10  9:47 ` [PATCH 5/5] ASoC: sh: rz-ssi: Add functions to get/set substream pointer Lad Prabhakar
2022-01-10 15:10   ` Mark Brown
2022-01-10 16:14     ` Lad, Prabhakar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).