diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-08-11 08:18:39 (GMT) |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-10-20 14:02:28 (GMT) |
commit | 1083206ff44af4baa03573b4a6bac430d9d70404 (patch) | |
tree | d52cdadd16dcc621d14fc5a5d24d650a1bea8cee | |
parent | c872e8cab5b7cab0696bcf09c6f03c972edc1c49 (diff) | |
download | linux-1083206ff44af4baa03573b4a6bac430d9d70404.tar.xz |
ALSA: ice1724 - Fix TX IRQ lockup
MPU TX causes IRQ floods on VT172x devices mysteriously.
Disable TX IRQ if the IRQ flood is detected.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/ice1712/ice1724.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 1b3f117..79a9cd0 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -382,23 +382,25 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) unsigned char status_mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM; int handled = 0; -#ifdef CONFIG_SND_DEBUG int timeout = 0; -#endif while (1) { status = inb(ICEREG1724(ice, IRQSTAT)); status &= status_mask; if (status == 0) break; -#ifdef CONFIG_SND_DEBUG if (++timeout > 10) { - printk(KERN_ERR - "ice1724: Too long irq loop, status = 0x%x\n", - status); + status = inb(ICEREG1724(ice, IRQSTAT)); + printk(KERN_ERR "ice1724: Too long irq loop, " + "status = 0x%x\n", status); + if (status & VT1724_IRQ_MPU_TX) { + printk(KERN_ERR "ice1724: Disabling MPU_TX\n"); + outb(inb(ICEREG1724(ice, IRQMASK)) & + ~VT1724_IRQ_MPU_TX, + ICEREG1724(ice, IRQMASK)); + } break; } -#endif handled = 1; if (status & VT1724_IRQ_MPU_TX) { spin_lock(&ice->reg_lock); @@ -2351,7 +2353,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card, { struct snd_ice1712 *ice; int err; - unsigned char mask; + /* unsigned char mask; */ static struct snd_device_ops ops = { .dev_free = snd_vt1724_dev_free, }; @@ -2413,8 +2415,10 @@ static int __devinit snd_vt1724_create(struct snd_card *card, } /* unmask used interrupts */ +#if 0 /* these are enabled/disabled dynamically */ mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX; outb(mask, ICEREG1724(ice, IRQMASK)); +#endif /* don't handle FIFO overrun/underruns (just yet), * since they cause machine lockups */ |