aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-06-02 01:16:07 +0200
committerTakashi Iwai <tiwai@suse.de>2009-06-02 01:21:23 +0200
commit8dd783304e6d0f7c2830365d63f75f08aa343e10 (patch)
tree1f678835b512020cca26d26f58b7dc18194762bf /sound/pci/hda/hda_codec.c
parent8871e5b91518a47284b6bc2603b44dbc79c85446 (diff)
ALSA: hda - Add codec bus reset and verb-retry at critical errors
Some machines machine cause a severe CORB/RIRB stall in certain weird conditions, such as PA access at the start up together with fglrx driver. This seems unable to be recovered without the controller reset. This patch allows the bus controller reset at critical errors so that the communication gets recovered again. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index d1d5fb9d7af..aa0e1c18b60 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -165,28 +165,29 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
unsigned int *res)
{
struct hda_bus *bus = codec->bus;
- int err, repeated = 0;
+ int err;
if (res)
*res = -1;
+ again:
snd_hda_power_up(codec);
mutex_lock(&bus->cmd_mutex);
- again:
err = bus->ops.command(bus, cmd);
- if (!err) {
- if (res) {
- *res = bus->ops.get_response(bus);
- if (*res == -1 && bus->rirb_error) {
- if (repeated++ < 1) {
- snd_printd(KERN_WARNING "hda_codec: "
- "Trying verb 0x%08x again\n", cmd);
- goto again;
- }
- }
- }
- }
+ if (!err && res)
+ *res = bus->ops.get_response(bus);
mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec);
+ if (res && *res == -1 && bus->rirb_error) {
+ if (bus->response_reset) {
+ snd_printd("hda_codec: resetting BUS due to "
+ "fatal communication error\n");
+ bus->ops.bus_reset(bus);
+ }
+ goto again;
+ }
+ /* clear reset-flag when the communication gets recovered */
+ if (!err)
+ bus->response_reset = 0;
return err;
}
@@ -3894,11 +3895,10 @@ EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
/**
* snd_hda_suspend - suspend the codecs
* @bus: the HDA bus
- * @state: suspsend state
*
* Returns 0 if successful.
*/
-int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
+int snd_hda_suspend(struct hda_bus *bus)
{
struct hda_codec *codec;