static irqreturn_t apci1032_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct apci1032_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned int ctrl; /* check interrupt is from this device */ if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & INTCSR_INTR_ASSERTED) == 0) return IRQ_NONE; /* check interrupt is enabled */ ctrl = inl(dev->iobase + APCI1032_CTRL_REG); if ((ctrl & APCI1032_CTRL_INT_ENA) == 0) return IRQ_HANDLED; /* disable the interrupt */ outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); /* enable the interrupt */ outl(ctrl, dev->iobase + APCI1032_CTRL_REG); return IRQ_HANDLED; }
static irqreturn_t dmm32at_isr(int irq, void *d) { struct comedi_device *dev = d; unsigned char intstat; unsigned int val; int i; if (!dev->attached) { dev_err(dev->class_dev, "spurious interrupt\n"); return IRQ_HANDLED; } intstat = inb(dev->iobase + DMM32AT_INTCLK_REG); if (intstat & DMM32AT_INTCLK_ADINT) { struct comedi_subdevice *s = dev->read_subdev; struct comedi_cmd *cmd = &s->async->cmd; for (i = 0; i < cmd->chanlist_len; i++) { val = dmm32at_ai_get_sample(dev, s); comedi_buf_write_samples(s, &val, 1); } if (cmd->stop_src == TRIG_COUNT && s->async->scans_done >= cmd->stop_arg) s->async->events |= COMEDI_CB_EOA; comedi_handle_events(dev, s); } /* reset the interrupt */ outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG); return IRQ_HANDLED; }
static irqreturn_t pc236_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct comedi_subdevice *s = dev->read_subdev; bool handled; handled = pc236_intr_check(dev); if (dev->attached && handled) { comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); } return IRQ_RETVAL(handled); }
static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subdevice *s) { const struct dio200_board *board = dev->board_ptr; struct dio200_subdev_intr *subpriv = s->private; unsigned triggered; unsigned intstat; unsigned cur_enabled; unsigned long flags; triggered = 0; spin_lock_irqsave(&subpriv->spinlock, flags); if (board->has_int_sce) { /* * Collect interrupt sources that have triggered and disable * them temporarily. Loop around until no extra interrupt * sources have triggered, at which point, the valid part of * the interrupt status register will read zero, clearing the * cause of the interrupt. * * Mask off interrupt sources already seen to avoid infinite * loop in case of misconfiguration. */ cur_enabled = subpriv->enabled_isns; while ((intstat = (dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns & ~triggered)) != 0) { triggered |= intstat; cur_enabled &= ~triggered; dio200_write8(dev, subpriv->ofs, cur_enabled); } } else { /* * No interrupt status register. Assume the single interrupt * source has triggered. */ triggered = subpriv->enabled_isns; } if (triggered) { /* * Some interrupt sources have triggered and have been * temporarily disabled to clear the cause of the interrupt. * * Reenable them NOW to minimize the time they are disabled. */ cur_enabled = subpriv->enabled_isns; if (board->has_int_sce) dio200_write8(dev, subpriv->ofs, cur_enabled); if (subpriv->active) { /* * The command is still active. * * Ignore interrupt sources that the command isn't * interested in (just in case there's a race * condition). */ if (triggered & subpriv->enabled_isns) /* Collect scan data. */ dio200_read_scan_intr(dev, s, triggered); } } spin_unlock_irqrestore(&subpriv->spinlock, flags); comedi_handle_events(dev, s); return (triggered != 0); }