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>
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 */
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;
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);
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);
{
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;
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);
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) {
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)
* 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);