static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id) { struct snd_bt87x *chip = dev_id; unsigned int status, irq_status; status = snd_bt87x_readl(chip, REG_INT_STAT); irq_status = status & chip->interrupt_mask; if (!irq_status) return IRQ_NONE; snd_bt87x_writel(chip, REG_INT_STAT, irq_status); if (irq_status & ERROR_INTERRUPTS) { if (irq_status & (INT_FBUS | INT_FTRGT)) snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status); if (irq_status & INT_OCERR) snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status); if (irq_status & (INT_PPERR | INT_RIPERR | INT_PABORT)) snd_bt87x_pci_error(chip, irq_status); } if ((irq_status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) { int current_block, irq_block; /* assume that exactly one line has been recorded */ chip->current_line = (chip->current_line + 1) % chip->lines; /* but check if some interrupts have been skipped */ current_block = chip->current_line * 16 / chip->lines; irq_block = status >> INT_RISCS_SHIFT; if (current_block != irq_block) chip->current_line = (irq_block * chip->lines + 15) / 16; snd_pcm_period_elapsed(chip->substream); }
static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs) { bt87x_t *chip = dev_id; unsigned int status; status = snd_bt87x_readl(chip, REG_INT_STAT); if (!(status & MY_INTERRUPTS)) return IRQ_NONE; snd_bt87x_writel(chip, REG_INT_STAT, status & MY_INTERRUPTS); if (status & ERROR_INTERRUPTS) { if (status & (INT_FBUS | INT_FTRGT)) snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status); if (status & INT_OCERR) snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status); if (status & (INT_PPERR | INT_RIPERR | INT_PABORT)) { u16 pci_status; pci_read_config_word(chip->pci, PCI_STATUS, &pci_status); pci_write_config_word(chip->pci, PCI_STATUS, pci_status & (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)); snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n", status, pci_status); } } if ((status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) { int current_block, irq_block; /* assume that exactly one line has been recorded */ chip->current_line = (chip->current_line + 1) % chip->lines; /* but check if some interrupts have been skipped */ current_block = chip->current_line * 16 / chip->lines; irq_block = status >> INT_RISCS_SHIFT; if (current_block != irq_block) chip->current_line = (irq_block * chip->lines + 15) / 16; snd_pcm_period_elapsed(chip->substream); }