ALSA: hda: Unify get_response handling
authorTakashi Iwai <tiwai@suse.de>
Thu, 12 Dec 2019 19:11:01 +0000 (20:11 +0100)
committerTakashi Iwai <tiwai@suse.de>
Fri, 13 Dec 2019 13:36:52 +0000 (14:36 +0100)
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>
include/sound/hda_codec.h
include/sound/hdaudio.h
sound/hda/hdac_controller.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_tegra.c
sound/pci/hda/patch_ca0110.c
sound/pci/hda/patch_sigmatel.c

index ac18f428eda6ce2991625d543f7714f354028e93..3ee8036f5436d31912bb60b8ed68821b468ad338 100644 (file)
@@ -51,7 +51,6 @@ struct hda_bus {
        DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
 
        /* misc op flags */
-       unsigned int needs_damn_long_delay :1;
        unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */
        /* status for codec/controller */
        unsigned int shutdown :1;       /* being unloaded */
index 81373a2efd96b04f3c0e5394adf7fd8867e03c31..bc2f77a6f17bf71acd6cf9cbd9c05f2172172c06 100644 (file)
@@ -338,6 +338,7 @@ struct hdac_bus {
        bool reverse_assign:1;          /* assign devices in reverse order */
        bool corbrp_self_clear:1;       /* CORBRP clears itself after reset */
        bool polling_mode:1;
+       bool needs_damn_long_delay:1;
 
        int poll_count;
 
index 61950b83b8c9f86bf12260bb331da8d660145adb..01787081552de7ba6a943e95676d7236a6855732 100644 (file)
@@ -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);
index 870102f00efdd6676af332f654f3eed4daef1c9e..d6a7bda28925268c2151795a3b9f63a2d273b6da 100644 (file)
@@ -784,53 +784,12 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
 {
        struct azx *chip = bus_to_azx(bus);
        struct hda_bus *hbus = &chip->bus;
-       unsigned long timeout;
-       unsigned long loopcounter;
-       wait_queue_entry_t wait;
-       bool warned = false;
+       int err;
 
-       init_wait_entry(&wait, 0);
  again:
-       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;
-#define LOOP_COUNT_MAX 3000
-               if (!bus->polling_mode) {
-                       schedule_timeout(msecs_to_jiffies(2));
-               } else if (hbus->needs_damn_long_delay ||
-                   loopcounter > LOOP_COUNT_MAX) {
-                       if (loopcounter > LOOP_COUNT_MAX && !warned) {
-                               dev_dbg_ratelimited(chip->card->dev,
-                                                   "too slow response, last cmd=%#08x\n",
-                                                   bus->last_cmd[addr]);
-                               warned = true;
-                       }
-                       msleep(2); /* temporary workaround */
-               } else {
-                       udelay(10);
-                       cond_resched();
-               }
-       }
-
-       if (!bus->polling_mode)
-               finish_wait(&bus->rirb_wq, &wait);
+       err = snd_hdac_bus_get_response(bus, addr, res);
+       if (!err)
+               return 0;
 
        if (hbus->no_response_fallback)
                return -EIO;
index c86539cdbd4bb6c51b0df764e1a34ad70f398a4c..c7efb6f66bdc74ad45f6af469494b136c2f11bcb 100644 (file)
@@ -1809,7 +1809,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
 
        if (chip->driver_type == AZX_DRIVER_NVIDIA) {
                dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
-               chip->bus.needs_damn_long_delay = 1;
+               chip->bus.core.needs_damn_long_delay = 1;
        }
 
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
index 269f242fcbfdf730c4285d923069963503c7e241..9d0784aed9e47fb903b3fb9c854f8038f9031cd2 100644 (file)
@@ -394,7 +394,7 @@ static int hda_tegra_create(struct snd_card *card,
        if (err < 0)
                return err;
 
-       chip->bus.needs_damn_long_delay = 1;
+       chip->bus.core.needs_damn_long_delay = 1;
 
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
        if (err < 0) {
index e780922a1190975fae9fbd73982773009e86ebba..1818ce67f7613d862f8ef1d01b6e50396e226f59 100644 (file)
@@ -53,7 +53,7 @@ static int patch_ca0110(struct hda_codec *codec)
        codec->patch_ops = ca0110_patch_ops;
 
        spec->multi_cap_vol = 1;
-       codec->bus->needs_damn_long_delay = 1;
+       codec->bus->core.needs_damn_long_delay = 1;
 
        err = ca0110_parse_auto_config(codec);
        if (err < 0)
index 894f3f509e767635b4f0aef6507a1bbddc551c15..8ecb53bce509cba9df073e338fb7fb7d5a739144 100644 (file)
@@ -4908,7 +4908,7 @@ static int patch_stac927x(struct hda_codec *codec)
         * The below flag enables the longer delay (see get_response
         * in hda_intel.c).
         */
-       codec->bus->needs_damn_long_delay = 1;
+       codec->bus->core.needs_damn_long_delay = 1;
 
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);