Commit b11771aa authored by Chase Southwood's avatar Chase Southwood Committed by Greg Kroah-Hartman

staging: comedi: addi_apci_1564: clean up apci1564_interrupt()

Remove the checks for interrupts from unknown sources.  This situation
should never occur and the checks were doing nothing to help the
situation.

Also, the portion of the function for handling counter interrupts is
reapeated four times (once for each counter), but is completely identical
save for the register is is accessing, so we can handle all four counters
with a for loop.

Finally, the interrupt handler is incorrectly setting and then checking
devpriv->timer_select_mode before processing some of the triggered
interrupts, so just remove all occurrences of this.
Signed-off-by: default avatarChase Southwood <chase.southwood@gmail.com>
Cc: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk.>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f89ced89
...@@ -58,48 +58,33 @@ static irqreturn_t apci1564_interrupt(int irq, void *d) ...@@ -58,48 +58,33 @@ static irqreturn_t apci1564_interrupt(int irq, void *d)
struct comedi_device *dev = d; struct comedi_device *dev = d;
struct apci1564_private *devpriv = dev->private; struct apci1564_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; struct comedi_subdevice *s = dev->read_subdev;
unsigned int ui_DO, ui_DI; unsigned int status;
unsigned int ui_Timer; unsigned int ctrl;
unsigned int ui_C1, ui_C2, ui_C3, ui_C4; unsigned int chan;
unsigned int ul_Command2 = 0;
/* check interrupt is from this device */ /* check interrupt is from this device */
if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) &
INTCSR_INTR_ASSERTED) == 0) INTCSR_INTR_ASSERTED) == 0)
return IRQ_NONE; return IRQ_NONE;
/* check which interrupt was triggered */ status = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
ui_DI = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG) & if (status & APCI1564_DI_INT_ENABLE) {
APCI1564_DI_INT_ENABLE;
ui_DO = inl(devpriv->amcc_iobase + APCI1564_DO_IRQ_REG) & 0x01;
ui_Timer = inl(devpriv->amcc_iobase + APCI1564_TIMER_IRQ_REG) & 0x01;
ui_C1 =
inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)) & 0x1;
ui_C2 =
inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)) & 0x1;
ui_C3 =
inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)) & 0x1;
ui_C4 =
inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)) & 0x1;
if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
&& ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
return IRQ_HANDLED;
}
if (ui_DI) {
/* disable the interrupt */ /* disable the interrupt */
outl(ui_DI & APCI1564_DI_INT_DISABLE, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); outl(status & APCI1564_DI_INT_DISABLE,
devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG) & 0xffff; s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG)
& 0xffff;
comedi_buf_put(s, s->state); comedi_buf_put(s, s->state);
s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
comedi_event(dev, s); comedi_event(dev, s);
/* enable the interrupt */ /* enable the interrupt */
outl(ui_DI, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); outl(status, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
} }
if (ui_DO == 1) { status = inl(devpriv->amcc_iobase + APCI1564_DO_IRQ_REG);
if (status & 0x01) {
/* Check for Digital Output interrupt Type */ /* Check for Digital Output interrupt Type */
/* 1: VCC interrupt */ /* 1: VCC interrupt */
/* 2: CC interrupt */ /* 2: CC interrupt */
...@@ -112,98 +97,34 @@ static irqreturn_t apci1564_interrupt(int irq, void *d) ...@@ -112,98 +97,34 @@ static irqreturn_t apci1564_interrupt(int irq, void *d)
send_sig(SIGIO, devpriv->tsk_current, 0); send_sig(SIGIO, devpriv->tsk_current, 0);
} }
if (ui_Timer == 1) { status = inl(devpriv->amcc_iobase + APCI1564_TIMER_IRQ_REG);
devpriv->timer_select_mode = ADDIDATA_TIMER; if (status & 0x01) {
if (devpriv->timer_select_mode) { /* Disable Timer Interrupt */
ctrl = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
/* Disable Timer Interrupt */ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command2 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
/* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_current, 0);
/* Enable Timer Interrupt */
outl(ul_Command2, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
}
}
if (ui_C1 == 1) {
devpriv->timer_select_mode = ADDIDATA_COUNTER;
if (devpriv->timer_select_mode) {
/* Disable Counter Interrupt */
ul_Command2 =
inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
outl(0x0,
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
/* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_current, 0);
/* Enable Counter Interrupt */
outl(ul_Command2,
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
}
}
if (ui_C2 == 1) {
devpriv->timer_select_mode = ADDIDATA_COUNTER;
if (devpriv->timer_select_mode) {
/* Disable Counter Interrupt */ /* Send a signal to from kernel to user space */
ul_Command2 = send_sig(SIGIO, devpriv->tsk_current, 0);
inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
outl(0x0,
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
/* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_current, 0);
/* Enable Counter Interrupt */ /* Enable Timer Interrupt */
outl(ul_Command2, outl(ctrl, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
}
} }
if (ui_C3 == 1) { for (chan = 0; chan < 4; chan++) {
devpriv->timer_select_mode = ADDIDATA_COUNTER; status = inl(dev->iobase + APCI1564_TCW_IRQ_REG(chan));
if (devpriv->timer_select_mode) { if (status & 0x01) {
/* Disable Counter Interrupt */ /* Disable Counter Interrupt */
ul_Command2 = ctrl = inl(dev->iobase + APCI1564_TCW_CTRL_REG(chan));
inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3)); outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(chan));
outl(0x0,
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
/* Send a signal to from kernel to user space */ /* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_current, 0); send_sig(SIGIO, devpriv->tsk_current, 0);
/* Enable Counter Interrupt */ /* Enable Counter Interrupt */
outl(ul_Command2, outl(ctrl, dev->iobase + APCI1564_TCW_CTRL_REG(chan));
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
} }
} }
if (ui_C4 == 1) {
devpriv->timer_select_mode = ADDIDATA_COUNTER;
if (devpriv->timer_select_mode) {
/* Disable Counter Interrupt */
ul_Command2 =
inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
outl(0x0,
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
/* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_current, 0);
/* Enable Counter Interrupt */
outl(ul_Command2,
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
}
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment