[1/2] ALSA: hda: Use waitqueue for RIRB in HDA-core helper, too
diff mbox series

Message ID 20191212191101.19517-2-tiwai@suse.de
State New
Headers show
Series
  • ALSA: hda: Use RIRB waitq commonly
Related show

Commit Message

Takashi Iwai Dec. 12, 2019, 7:11 p.m. UTC
This patch implements the same logic that was done for the legacy
HD-audio controller driver by the commit 88452da92ba2 ("ALSA: hda: Use
standard waitqueue for RIRB wakeup") to the HDA-core helper code,
too.  This makes snd_hdac_bus_get_response() waiting for the response
with bus->rirb_wq instead of polling when bus->polling is false.
It'll save both CPU time and response latency.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/hda/hdac_controller.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Comments

Kai Vehmanen Dec. 13, 2019, 1:03 p.m. UTC | #1
Hi,

On Thu, 12 Dec 2019, Takashi Iwai wrote:

> This patch implements the same logic that was done for the legacy
> HD-audio controller driver by the commit 88452da92ba2 ("ALSA: hda: Use

looks good to me. Code review ok, SOF CI shows no regressions [1] and I 
did a local test with a large amount of suspend/resyme cycles on a HDA machine 
and no errors seen. So for these two patches:

Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>

[1] https://github.com/thesofproject/linux/pull/1625
     -> https://sof-ci.01.org/linuxpr/PR1625/build2716/devicetest/

Br, Kai
Takashi Iwai Dec. 13, 2019, 1:37 p.m. UTC | #2
On Fri, 13 Dec 2019 14:03:50 +0100,
Kai Vehmanen wrote:
> 
> Hi,
> 
> On Thu, 12 Dec 2019, Takashi Iwai wrote:
> 
> > This patch implements the same logic that was done for the legacy
> > HD-audio controller driver by the commit 88452da92ba2 ("ALSA: hda: Use
> 
> looks good to me. Code review ok, SOF CI shows no regressions [1] and I 
> did a local test with a large amount of suspend/resyme cycles on a HDA machine 
> and no errors seen. So for these two patches:
> 
> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
> 
> [1] https://github.com/thesofproject/linux/pull/1625
>      -> https://sof-ci.01.org/linuxpr/PR1625/build2716/devicetest/

Thanks for quick testing!  Now queued these patches.


Takashi

Patch
diff mbox series

diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index cd1c3b282657..61950b83b8c9 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -241,30 +241,42 @@  int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
 {
 	unsigned long timeout;
 	unsigned long loopcounter;
+	wait_queue_entry_t wait;
 
+	init_wait_entry(&wait, 0);
 	timeout = jiffies + msecs_to_jiffies(1000);
 
 	for (loopcounter = 0;; loopcounter++) {
 		spin_lock_irq(&bus->reg_lock);
+		if (!bus->polling_mode)
+			prepare_to_wait(&bus->rirb_wq, &wait,
+					TASK_UNINTERRUPTIBLE);
 		if (bus->polling_mode)
 			snd_hdac_bus_update_rirb(bus);
 		if (!bus->rirb.cmds[addr]) {
 			if (res)
 				*res = bus->rirb.res[addr]; /* the last value */
+			if (!bus->polling_mode)
+				finish_wait(&bus->rirb_wq, &wait);
 			spin_unlock_irq(&bus->reg_lock);
 			return 0;
 		}
 		spin_unlock_irq(&bus->reg_lock);
 		if (time_after(jiffies, timeout))
 			break;
-		if (loopcounter > 3000)
+		if (!bus->polling_mode) {
+			schedule_timeout(msecs_to_jiffies(2));
+		} else if (loopcounter > 3000) {
 			msleep(2); /* temporary workaround */
-		else {
+		} else {
 			udelay(10);
 			cond_resched();
 		}
 	}
 
+	if (!bus->polling_mode)
+		finish_wait(&bus->rirb_wq, &wait);
+
 	return -EIO;
 }
 EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);