diff options
Diffstat (limited to 'sound/pci/emu10k1/irq.c')
| -rw-r--r-- | sound/pci/emu10k1/irq.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c index cd8460d5675..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) { - emu10k1_t *emu = 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("interrupt: PCI error\n"); + dev_err(emu->card->dev, "interrupt: PCI error\n"); snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE); status &= ~IPR_PCIERROR; } @@ -56,7 +61,7 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) int voice; int voice_max = status & IPR_CHANNELNUMBERMASK; u32 val; - emu10k1_voice_t *pvoice = emu->voices; + struct snd_emu10k1_voice *pvoice = emu->voices; val = snd_emu10k1_ptr_read(emu, CLIPL, 0); for (voice = 0; voice <= voice_max; voice++) { @@ -150,22 +155,25 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (status & IPR_P16V) { while ((status2 = inl(emu->port + IPR2)) != 0) { u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */ - emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]); - emu10k1_voice_t *cvoice = &(emu->p16v_capture_voice); + 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); } |
