ALSA: ice1724 - Fix TX IRQ lockup
authorTakashi Iwai <tiwai@suse.de>
Mon, 11 Aug 2008 08:18:39 +0000 (10:18 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 20 Oct 2008 14:02:28 +0000 (16:02 +0200)
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>
sound/pci/ice1712/ice1724.c

index 1b3f11702713624b3cc5f344e598fcce7f5af70c..79a9cd0881f70931fa5b7efe1823282a22499b98 100644 (file)
@@ -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
         */