summaryrefslogtreecommitdiffstats
path: root/sound/pci/ice1712/ice1724.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-08-11 10:18:39 +0200
committerTakashi Iwai <tiwai@suse.de>2008-10-20 16:02:28 +0200
commit1083206ff44af4baa03573b4a6bac430d9d70404 (patch)
treed52cdadd16dcc621d14fc5a5d24d650a1bea8cee /sound/pci/ice1712/ice1724.c
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/pci/ice1712/ice1724.c')
-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)
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
*/