aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-06-01 19:16:07 -0400
committerTakashi Iwai <tiwai@suse.de>2009-06-01 19:21:23 -0400
commit8dd783304e6d0f7c2830365d63f75f08aa343e10 (patch)
tree1f678835b512020cca26d26f58b7dc18194762bf /sound/pci/hda/hda_intel.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_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index b063d0e3d325..44f9a0aa20c5 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -661,14 +661,23 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
661 return -1; 661 return -1;
662 } 662 }
663 663
664 snd_printk(KERN_ERR SFX "azx_get_response timeout (ERROR): " 664 /* a fatal communication error; need either to reset or to fallback
665 "last cmd=0x%08x\n", chip->last_cmd); 665 * to the single_cmd mode
666 /* re-initialize CORB/RIRB */ 666 */
667 spin_lock_irq(&chip->reg_lock);
668 bus->rirb_error = 1; 667 bus->rirb_error = 1;
668 if (!bus->response_reset && !bus->in_reset) {
669 bus->response_reset = 1;
670 return -1; /* give a chance to retry */
671 }
672
673 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
674 "switching to single_cmd mode: last cmd=0x%08x\n",
675 chip->last_cmd);
676 chip->single_cmd = 1;
677 bus->response_reset = 0;
678 /* re-initialize CORB/RIRB */
669 azx_free_cmd_io(chip); 679 azx_free_cmd_io(chip);
670 azx_init_cmd_io(chip); 680 azx_init_cmd_io(chip);
671 spin_unlock_irq(&chip->reg_lock);
672 return -1; 681 return -1;
673} 682}
674 683
@@ -709,6 +718,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
709 struct azx *chip = bus->private_data; 718 struct azx *chip = bus->private_data;
710 int timeout = 50; 719 int timeout = 50;
711 720
721 bus->rirb_error = 0;
712 while (timeout--) { 722 while (timeout--) {
713 /* check ICB busy bit */ 723 /* check ICB busy bit */
714 if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) { 724 if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
@@ -1247,6 +1257,23 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1247 struct hda_pcm *cpcm); 1257 struct hda_pcm *cpcm);
1248static void azx_stop_chip(struct azx *chip); 1258static void azx_stop_chip(struct azx *chip);
1249 1259
1260static void azx_bus_reset(struct hda_bus *bus)
1261{
1262 struct azx *chip = bus->private_data;
1263 int i;
1264
1265 bus->in_reset = 1;
1266 azx_stop_chip(chip);
1267 azx_init_chip(chip);
1268 if (chip->initialized) {
1269 for (i = 0; i < AZX_MAX_PCMS; i++)
1270 snd_pcm_suspend_all(chip->pcm[i]);
1271 snd_hda_suspend(chip->bus);
1272 snd_hda_resume(chip->bus);
1273 }
1274 bus->in_reset = 0;
1275}
1276
1250/* 1277/*
1251 * Codec initialization 1278 * Codec initialization
1252 */ 1279 */
@@ -1270,6 +1297,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1270 bus_temp.ops.command = azx_send_cmd; 1297 bus_temp.ops.command = azx_send_cmd;
1271 bus_temp.ops.get_response = azx_get_response; 1298 bus_temp.ops.get_response = azx_get_response;
1272 bus_temp.ops.attach_pcm = azx_attach_pcm_stream; 1299 bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
1300 bus_temp.ops.bus_reset = azx_bus_reset;
1273#ifdef CONFIG_SND_HDA_POWER_SAVE 1301#ifdef CONFIG_SND_HDA_POWER_SAVE
1274 bus_temp.power_save = &power_save; 1302 bus_temp.power_save = &power_save;
1275 bus_temp.ops.pm_notify = azx_power_notify; 1303 bus_temp.ops.pm_notify = azx_power_notify;
@@ -1997,7 +2025,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1997 for (i = 0; i < AZX_MAX_PCMS; i++) 2025 for (i = 0; i < AZX_MAX_PCMS; i++)
1998 snd_pcm_suspend_all(chip->pcm[i]); 2026 snd_pcm_suspend_all(chip->pcm[i]);
1999 if (chip->initialized) 2027 if (chip->initialized)
2000 snd_hda_suspend(chip->bus, state); 2028 snd_hda_suspend(chip->bus);
2001 azx_stop_chip(chip); 2029 azx_stop_chip(chip);
2002 if (chip->irq >= 0) { 2030 if (chip->irq >= 0) {
2003 free_irq(chip->irq, chip); 2031 free_irq(chip->irq, chip);