diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 503869aad7f9..35090b3acbac 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -221,6 +221,8 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, again: snd_hda_power_up(codec); mutex_lock(&bus->cmd_mutex); + if (flags & HDA_RW_NO_RESPONSE_FALLBACK) + bus->no_response_fallback = 1; for (;;) { trace_hda_send_cmd(codec, cmd); err = bus->ops.command(bus, cmd); @@ -233,6 +235,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, *res = bus->ops.get_response(bus, codec->addr); trace_hda_get_response(codec, *res); } + bus->no_response_fallback = 0; mutex_unlock(&bus->cmd_mutex); snd_hda_power_down(codec); if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) { @@ -3805,11 +3808,13 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, hda_nid_t fg = codec->afg ? codec->afg : codec->mfg; int count; unsigned int state; + int flags = 0; /* this delay seems necessary to avoid click noise at power-down */ if (power_state == AC_PWRST_D3) { /* transition time less than 10ms for power down */ msleep(codec->epss ? 10 : 100); + flags = HDA_RW_NO_RESPONSE_FALLBACK; } /* repeat power states setting at most 10 times*/ @@ -3818,7 +3823,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, codec->patch_ops.set_power_state(codec, fg, power_state); else { - snd_hda_codec_read(codec, fg, 0, + snd_hda_codec_read(codec, fg, flags, AC_VERB_SET_POWER_STATE, power_state); snd_hda_codec_set_power_to_all(codec, fg, power_state); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 39a658e02988..701c2e069b10 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -679,6 +679,7 @@ struct hda_bus { unsigned int response_reset:1; /* controller was reset */ unsigned int in_reset:1; /* during reset operation */ unsigned int power_keep_link_on:1; /* don't power off HDA link */ + unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ int primary_dig_out_type; /* primary digital out PCM type */ }; @@ -930,6 +931,8 @@ enum { HDA_INPUT, HDA_OUTPUT }; +/* snd_hda_codec_read/write optional flags */ +#define HDA_RW_NO_RESPONSE_FALLBACK (1 << 0) /* * constructors diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 49dfad4a099e..f089fa0aa03d 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -942,6 +942,9 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, } } + if (!bus->no_response_fallback) + return -1; + if (!chip->polling_mode && chip->poll_count < 2) { snd_printdd(SFX "%s: azx_get_response timeout, " "polling the codec once: last cmd=0x%08x\n",