aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/hda/hdac_controller.c16
1 files changed, 14 insertions, 2 deletions
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);