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