diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-08-11 04:18:39 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-10-20 10:02:28 -0400 |
commit | 1083206ff44af4baa03573b4a6bac430d9d70404 (patch) | |
tree | d52cdadd16dcc621d14fc5a5d24d650a1bea8cee /sound/pci/ice1712 | |
parent | c872e8cab5b7cab0696bcf09c6f03c972edc1c49 (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/pci/ice1712')
-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 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 | */ |