mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
ALSA: hda: Use waitqueue for RIRB in HDA-core helper, too
This patch implements the same logic that was done for the legacy
HD-audio controller driver by the commit 88452da92b
("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.
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20191212191101.19517-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
341a79ee8b
commit
89698ed5cc
1 changed files with 14 additions and 2 deletions
|
@ -241,30 +241,42 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
|
||||||
{
|
{
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
unsigned long loopcounter;
|
unsigned long loopcounter;
|
||||||
|
wait_queue_entry_t wait;
|
||||||
|
|
||||||
|
init_wait_entry(&wait, 0);
|
||||||
timeout = jiffies + msecs_to_jiffies(1000);
|
timeout = jiffies + msecs_to_jiffies(1000);
|
||||||
|
|
||||||
for (loopcounter = 0;; loopcounter++) {
|
for (loopcounter = 0;; loopcounter++) {
|
||||||
spin_lock_irq(&bus->reg_lock);
|
spin_lock_irq(&bus->reg_lock);
|
||||||
|
if (!bus->polling_mode)
|
||||||
|
prepare_to_wait(&bus->rirb_wq, &wait,
|
||||||
|
TASK_UNINTERRUPTIBLE);
|
||||||
if (bus->polling_mode)
|
if (bus->polling_mode)
|
||||||
snd_hdac_bus_update_rirb(bus);
|
snd_hdac_bus_update_rirb(bus);
|
||||||
if (!bus->rirb.cmds[addr]) {
|
if (!bus->rirb.cmds[addr]) {
|
||||||
if (res)
|
if (res)
|
||||||
*res = bus->rirb.res[addr]; /* the last value */
|
*res = bus->rirb.res[addr]; /* the last value */
|
||||||
|
if (!bus->polling_mode)
|
||||||
|
finish_wait(&bus->rirb_wq, &wait);
|
||||||
spin_unlock_irq(&bus->reg_lock);
|
spin_unlock_irq(&bus->reg_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&bus->reg_lock);
|
spin_unlock_irq(&bus->reg_lock);
|
||||||
if (time_after(jiffies, timeout))
|
if (time_after(jiffies, timeout))
|
||||||
break;
|
break;
|
||||||
if (loopcounter > 3000)
|
if (!bus->polling_mode) {
|
||||||
|
schedule_timeout(msecs_to_jiffies(2));
|
||||||
|
} else if (loopcounter > 3000) {
|
||||||
msleep(2); /* temporary workaround */
|
msleep(2); /* temporary workaround */
|
||||||
else {
|
} else {
|
||||||
udelay(10);
|
udelay(10);
|
||||||
cond_resched();
|
cond_resched();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!bus->polling_mode)
|
||||||
|
finish_wait(&bus->rirb_wq, &wait);
|
||||||
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
|
EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue