diff options
Diffstat (limited to 'sound/pci/emu10k1/irq.c')
| -rw-r--r-- | sound/pci/emu10k1/irq.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c index a8b31286b6d..3c5c5e3dc2d 100644 --- a/sound/pci/emu10k1/irq.c +++ b/sound/pci/emu10k1/irq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Creative Labs, Inc. * Routines for IRQ control of EMU10K1 chips * @@ -25,23 +25,28 @@ * */ -#include <sound/driver.h> #include <linux/time.h> #include <sound/core.h> #include <sound/emu10k1.h> -irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id) { struct snd_emu10k1 *emu = dev_id; unsigned int status, status2, orig_status, orig_status2; int handled = 0; + int timeout = 0; - while ((status = inl(emu->port + IPR)) != 0) { - //printk("emu10k1 irq - status = 0x%x\n", status); + while (((status = inl(emu->port + IPR)) != 0) && (timeout < 1000)) { + timeout++; orig_status = status; handled = 1; + if ((status & 0xffffffff) == 0xffffffff) { + dev_info(emu->card->dev, + "Suspected sound card removal\n"); + break; + } if (status & IPR_PCIERROR) { - snd_printk(KERN_ERR "interrupt: PCI error\n"); + dev_err(emu->card->dev, "interrupt: PCI error\n"); snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE); status &= ~IPR_PCIERROR; } @@ -153,19 +158,22 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct snd_emu10k1_voice *pvoice = &(emu->p16v_voices[0]); struct snd_emu10k1_voice *cvoice = &(emu->p16v_capture_voice); - //printk(KERN_INFO "status2=0x%x\n", status2); + /* dev_dbg(emu->card->dev, "status2=0x%x\n", status2); */ orig_status2 = status2; if(status2 & mask) { if(pvoice->use) { snd_pcm_period_elapsed(pvoice->epcm->substream); } else { - snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use); + dev_err(emu->card->dev, + "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", + status2, mask, pvoice, + pvoice->use); } } if(status2 & 0x110000) { - //printk(KERN_INFO "capture int found\n"); + /* dev_info(emu->card->dev, "capture int found\n"); */ if(cvoice->use) { - //printk(KERN_INFO "capture period_elapsed\n"); + /* dev_info(emu->card->dev, "capture period_elapsed\n"); */ snd_pcm_period_elapsed(cvoice->epcm->substream); } } @@ -176,7 +184,8 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (status) { unsigned int bits; - snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status); + dev_err(emu->card->dev, + "unhandled interrupt: 0x%08x\n", status); //make sure any interrupts we don't handle are disabled: bits = INTE_FXDSPENABLE | INTE_PCIERRORENABLE | @@ -197,5 +206,8 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) } outl(orig_status, emu->port + IPR); /* ack all */ } + if (timeout == 1000) + dev_info(emu->card->dev, "emu10k1 irq routine failure\n"); + return IRQ_RETVAL(handled); } |
