aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-08-11 04:18:39 -0400
committerTakashi Iwai <tiwai@suse.de>2008-10-20 10:02:28 -0400
commit1083206ff44af4baa03573b4a6bac430d9d70404 (patch)
treed52cdadd16dcc621d14fc5a5d24d650a1bea8cee /sound
parentc872e8cab5b7cab0696bcf09c6f03c972edc1c49 (diff)
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>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/ice1712/ice1724.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 1b3f1170271..79a9cd0881f 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)
382 unsigned char status_mask = 382 unsigned char status_mask =
383 VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM; 383 VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM;
384 int handled = 0; 384 int handled = 0;
385#ifdef CONFIG_SND_DEBUG
386 int timeout = 0; 385 int timeout = 0;
387#endif
388 386
389 while (1) { 387 while (1) {
390 status = inb(ICEREG1724(ice, IRQSTAT)); 388 status = inb(ICEREG1724(ice, IRQSTAT));
391 status &= status_mask; 389 status &= status_mask;
392 if (status == 0) 390 if (status == 0)
393 break; 391 break;
394#ifdef CONFIG_SND_DEBUG
395 if (++timeout > 10) { 392 if (++timeout > 10) {
396 printk(KERN_ERR 393 status = inb(ICEREG1724(ice, IRQSTAT));
397 "ice1724: Too long irq loop, status = 0x%x\n", 394 printk(KERN_ERR "ice1724: Too long irq loop, "
398 status); 395 "status = 0x%x\n", status);
396 if (status & VT1724_IRQ_MPU_TX) {
397 printk(KERN_ERR "ice1724: Disabling MPU_TX\n");
398 outb(inb(ICEREG1724(ice, IRQMASK)) &
399 ~VT1724_IRQ_MPU_TX,
400 ICEREG1724(ice, IRQMASK));
401 }
399 break; 402 break;
400 } 403 }
401#endif
402 handled = 1; 404 handled = 1;
403 if (status & VT1724_IRQ_MPU_TX) { 405 if (status & VT1724_IRQ_MPU_TX) {
404 spin_lock(&ice->reg_lock); 406 spin_lock(&ice->reg_lock);
@@ -2351,7 +2353,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2351{ 2353{
2352 struct snd_ice1712 *ice; 2354 struct snd_ice1712 *ice;
2353 int err; 2355 int err;
2354 unsigned char mask; 2356 /* unsigned char mask; */
2355 static struct snd_device_ops ops = { 2357 static struct snd_device_ops ops = {
2356 .dev_free = snd_vt1724_dev_free, 2358 .dev_free = snd_vt1724_dev_free,
2357 }; 2359 };
@@ -2413,8 +2415,10 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2413 } 2415 }
2414 2416
2415 /* unmask used interrupts */ 2417 /* unmask used interrupts */
2418#if 0 /* these are enabled/disabled dynamically */
2416 mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX; 2419 mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX;
2417 outb(mask, ICEREG1724(ice, IRQMASK)); 2420 outb(mask, ICEREG1724(ice, IRQMASK));
2421#endif
2418 /* don't handle FIFO overrun/underruns (just yet), 2422 /* don't handle FIFO overrun/underruns (just yet),
2419 * since they cause machine lockups 2423 * since they cause machine lockups
2420 */ 2424 */