summary refs log tree commit diff
path: root/sound/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-12-12 20:11:01 +0100
committerTakashi Iwai <tiwai@suse.de>2019-12-13 14:36:52 +0100
commit5f2cb361d798fb39adb79fab4e5235e307c70e9a (patch)
tree20a03fd52f24fc2d67b792c8b34ffac27e78ab83 /sound/hda
parent89698ed5cc76d8de6c2b51d132c06bf4cd930314 (diff)
downloadlinux-5f2cb361d798fb39adb79fab4e5235e307c70e9a.tar.gz
ALSA: hda: Unify get_response handling
Now most of the get_response handling became quite similar between
HDA-core and legacy drivers, and the only differences are:

- the handling of extra-long polling delay for some codecs
- the debug message for the stalled communication

and both are worth to share in the common code.

This patch unifies the code into snd_hdac_bus_get_response(), and use
this from the legacy get_response callback.  It results in a good
amount of code reduction in the end.

Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20191212191101.19517-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/hda')
-rw-r--r--sound/hda/hdac_controller.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 61950b83b8c9..01787081552d 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -242,6 +242,7 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
 	unsigned long timeout;
 	unsigned long loopcounter;
 	wait_queue_entry_t wait;
+	bool warned = false;
 
 	init_wait_entry(&wait, 0);
 	timeout = jiffies + msecs_to_jiffies(1000);
@@ -264,9 +265,17 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
 		spin_unlock_irq(&bus->reg_lock);
 		if (time_after(jiffies, timeout))
 			break;
+#define LOOP_COUNT_MAX	3000
 		if (!bus->polling_mode) {
 			schedule_timeout(msecs_to_jiffies(2));
-		} else if (loopcounter > 3000) {
+		} else if (bus->needs_damn_long_delay ||
+			   loopcounter > LOOP_COUNT_MAX) {
+			if (loopcounter > LOOP_COUNT_MAX && !warned) {
+				dev_dbg_ratelimited(bus->dev,
+						    "too slow response, last cmd=%#08x\n",
+						    bus->last_cmd[addr]);
+				warned = true;
+			}
 			msleep(2); /* temporary workaround */
 		} else {
 			udelay(10);