aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-08-21 17:57:44 +0200
committerJaroslav Kysela <perex@suse.cz>2006-09-23 10:42:10 +0200
commite96224ae974844d3f4e84f927ca4b17f1a2079a3 (patch)
tree9b521d379b2ecae8506216ca5b11050d49046718 /sound
parent81d3dbde76eedcd3ede8a73eb72790d67fa254a9 (diff)
[ALSA] hda-intel - Switch to polling mode for CORB/RIRB communication
Automatically switch to polling mode for CORB/RIRB communication if the irq-driven mode seems not working well. If the polling mode still doesn't work, switch to single_cmd mode as fallback. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_intel.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 79d63c99f09..ce75e07aaa2 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -332,6 +332,7 @@ struct azx {
int position_fix;
unsigned int initialized: 1;
unsigned int single_cmd: 1;
+ unsigned int polling_mode: 1;
};
/* driver types */
@@ -518,8 +519,23 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
struct azx *chip = codec->bus->private_data;
int timeout = 50;
- while (chip->rirb.cmds) {
+ for (;;) {
+ if (chip->polling_mode) {
+ spin_lock_irq(&chip->reg_lock);
+ azx_update_rirb(chip);
+ spin_unlock_irq(&chip->reg_lock);
+ }
+ if (! chip->rirb.cmds)
+ break;
if (! --timeout) {
+ if (! chip->polling_mode) {
+ snd_printk(KERN_WARNING "hda_intel: "
+ "azx_get_response timeout, "
+ "switching to polling mode...\n");
+ chip->polling_mode = 1;
+ timeout = 50;
+ continue;
+ }
snd_printk(KERN_ERR
"hda_intel: azx_get_response timeout, "
"switching to single_cmd mode...\n");