Ejemplo n.º 1
0
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);
	}
Ejemplo n.º 2
0
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);
	}