All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
To: alsa-devel@alsa-project.org
Cc: tiwai@suse.de, broonie@kernel.org,
	Ranjani Sridharan <ranjani.sridharan@linux.intel.com>,
	Kai Vehmanen <kai.vehmanen@linux.intel.com>,
	Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Subject: [PATCH 08/15] ASoC: SOF: Intel: hda: modify stream interrupt handler
Date: Wed, 12 Jun 2019 12:23:40 -0500	[thread overview]
Message-ID: <20190612172347.22338-9-pierre-louis.bossart@linux.intel.com> (raw)
In-Reply-To: <20190612172347.22338-1-pierre-louis.bossart@linux.intel.com>

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

Modify the stream interrupt handler to always wake up the
IRQ thread if the status register is valid. The IRQ thread
performs the check for stream interrupts and RIRB interrupts
in a loop to handle the case of missed interrupts when an
unsolicited response from the codec is received just before the
stream interrupt handler is completed.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/sof/intel/hda-stream.c | 79 +++++++++++++++++++++-----------
 1 file changed, 51 insertions(+), 28 deletions(-)

diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index ff6ab0c45d8e..d44318040948 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -461,57 +461,40 @@ int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
 irqreturn_t hda_dsp_stream_interrupt(int irq, void *context)
 {
 	struct hdac_bus *bus = context;
-	struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
-	u32 stream_mask;
+	int ret = IRQ_WAKE_THREAD;
 	u32 status;
 
-	if (!pm_runtime_active(bus->dev))
-		return IRQ_NONE;
-
 	spin_lock(&bus->reg_lock);
 
 	status = snd_hdac_chip_readl(bus, INTSTS);
-	stream_mask = GENMASK(sof_hda->stream_max - 1, 0) | AZX_INT_CTRL_EN;
-
-	/* Not stream interrupt or register inaccessible, ignore it.*/
-	if (!(status & stream_mask) || status == 0xffffffff) {
-		spin_unlock(&bus->reg_lock);
-		return IRQ_NONE;
-	}
+	dev_vdbg(bus->dev, "stream irq, INTSTS status: 0x%x\n", status);
 
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
-	/* clear rirb int */
-	status = snd_hdac_chip_readb(bus, RIRBSTS);
-	if (status & RIRB_INT_MASK) {
-		if (status & RIRB_INT_RESPONSE)
-			snd_hdac_bus_update_rirb(bus);
-		snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
-	}
-#endif
+	/* Register inaccessible, ignore it.*/
+	if (status == 0xffffffff)
+		ret = IRQ_NONE;
 
 	spin_unlock(&bus->reg_lock);
 
-	return snd_hdac_chip_readl(bus, INTSTS) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
+	return ret;
 }
 
-irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
+static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status)
 {
-	struct hdac_bus *bus = context;
 	struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
-	u32 status = snd_hdac_chip_readl(bus, INTSTS);
 	struct hdac_stream *s;
+	bool active = false;
 	u32 sd_status;
 
-	/* check streams */
 	list_for_each_entry(s, &bus->stream_list, list) {
-		if (status & (1 << s->index) && s->opened) {
+		if (status & BIT(s->index) && s->opened) {
 			sd_status = snd_hdac_stream_readb(s, SD_STS);
 
 			dev_vdbg(bus->dev, "stream %d status 0x%x\n",
 				 s->index, sd_status);
 
-			snd_hdac_stream_writeb(s, SD_STS, SD_INT_MASK);
+			snd_hdac_stream_writeb(s, SD_STS, sd_status);
 
+			active = true;
 			if (!s->substream ||
 			    !s->running ||
 			    (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0)
@@ -520,8 +503,48 @@ irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
 			/* Inform ALSA only in case not do that with IPC */
 			if (sof_hda->no_ipc_position)
 				snd_sof_pcm_period_elapsed(s->substream);
+		}
+	}
+
+	return active;
+}
 
+irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
+{
+	struct hdac_bus *bus = context;
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+	u32 rirb_status;
+#endif
+	bool active;
+	u32 status;
+	int i;
+
+	/*
+	 * Loop 10 times to handle missed interrupts caused by
+	 * unsolicited responses from the codec
+	 */
+	for (i = 0, active = true; i < 10 && active; i++) {
+		spin_lock_irq(&bus->reg_lock);
+
+		status = snd_hdac_chip_readl(bus, INTSTS);
+
+		/* check streams */
+		active = hda_dsp_stream_check(bus, status);
+
+		/* check and clear RIRB interrupt */
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+		if (status & AZX_INT_CTRL_EN) {
+			rirb_status = snd_hdac_chip_readb(bus, RIRBSTS);
+			if (rirb_status & RIRB_INT_MASK) {
+				active = true;
+				if (rirb_status & RIRB_INT_RESPONSE)
+					snd_hdac_bus_update_rirb(bus);
+				snd_hdac_chip_writeb(bus, RIRBSTS,
+						     RIRB_INT_MASK);
+			}
 		}
+#endif
+		spin_unlock_irq(&bus->reg_lock);
 	}
 
 	return IRQ_HANDLED;
-- 
2.20.1

  parent reply	other threads:[~2019-06-12 17:24 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-12 17:23 [PATCH 00/15] ASoC: SOF: Intel: HDaudio fixes and improvements Pierre-Louis Bossart
2019-06-12 17:23 ` [PATCH 01/15] ASoC: SOF: Intel: hda: save handle to sdev in sof_intel_hda_stream Pierre-Louis Bossart
2019-06-13  8:00   ` Amadeusz Sławiński
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: save handle to sdev in sof_intel_hda_stream" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 02/15] ASoC: SOF: Intel: hda: add new macro hstream_to_sof_hda_stream() Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: add new macro hstream_to_sof_hda_stream()" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 03/15] ASoC: SOF: topology: add cpu_dai_name for DAIs Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: topology: add cpu_dai_name for DAIs" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 04/15] ASoC: SOF: Intel: hda: assign link DMA channel at run-time Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: assign link DMA channel at run-time" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 05/15] ASoC: SOF: Intel: hda: reserve host DMA channel for hostless streams Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: reserve host DMA channel for hostless streams" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 06/15] ASoC: SOF: Intel: hda: release link DMA for paused streams during suspend Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: release link DMA for paused streams during suspend" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 07/15] ASoC: SOF: Intel: hda: couple host and link DMA during FE hw_free Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: couple host and link DMA during FE hw_free" to the asoc tree Mark Brown
2019-06-12 17:23 ` Pierre-Louis Bossart [this message]
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: modify stream interrupt handler" " Mark Brown
2019-06-12 17:23 ` [PATCH 09/15] ASoC: SOF: Intel: hda-stream: fix a deadlock with bus->reg_lock Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda-stream: fix a deadlock with bus->reg_lock" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 10/15] ASoC: SOF: Intel: hda: use the SOF defined ppcap functions Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: use the SOF defined ppcap functions" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 11/15] ASoC: SOF: Intel: hda: add function for hda stop chip Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: add function for hda stop chip" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 12/15] ASoC: SOF: Intel: hda: use the defined stop chip in suspend Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: use the defined stop chip in suspend" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 13/15] ASoC: SOF: Intel: hda: clear stream status and wakests properly Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: clear stream status and wakests properly" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 14/15] ASoC: SOF: Intel: hda: make sure DMA is start/stop by read the RUN bit Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: make sure DMA is start/stop by read the RUN bit" to the asoc tree Mark Brown
2019-06-12 17:23 ` [PATCH 15/15] ASoC: SOF: Intel: hda: make sure RUN bit setting to 0 during clear stream status Pierre-Louis Bossart
2019-06-17 15:24   ` Applied "ASoC: SOF: Intel: hda: make sure RUN bit setting to 0 during clear stream status" to the asoc tree Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190612172347.22338-9-pierre-louis.bossart@linux.intel.com \
    --to=pierre-louis.bossart@linux.intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=kai.vehmanen@linux.intel.com \
    --cc=ranjani.sridharan@linux.intel.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.