mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 04:09:18 -04:00
staging: comedi: addi_apci_1564: move apci1564_interrupt() into addi_apci_1564.c
On moving the function into the driver proper, also check the device is asserting the shared interrupt line. This patch also fixes the interrupt handling for the digital input change-of-state interrupts. Signed-off-by: Chase Southwood <chase.southwood@gmail.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Cc: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
1e15687ea4
commit
860ba36cbe
@@ -357,149 +357,3 @@ static int apci1564_do_read(struct comedi_device *dev,
|
||||
*data = devpriv->do_int_type;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handler for the interruptible digital inputs
|
||||
*/
|
||||
static void apci1564_interrupt(int irq, void *d)
|
||||
{
|
||||
struct comedi_device *dev = d;
|
||||
struct apci1564_private *devpriv = dev->private;
|
||||
unsigned int ui_DO, ui_DI;
|
||||
unsigned int ui_Timer;
|
||||
unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
|
||||
unsigned int ul_Command2 = 0;
|
||||
|
||||
ui_DI = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG) & 0x01;
|
||||
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) {
|
||||
dev_err(dev->class_dev, "Interrupt from unknown source.\n");
|
||||
}
|
||||
|
||||
if (ui_DI == 1) {
|
||||
ui_DI = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
|
||||
outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
|
||||
/* send signal to the sample */
|
||||
send_sig(SIGIO, devpriv->tsk_current, 0);
|
||||
/* enable the interrupt */
|
||||
outl(ui_DI, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ui_DO == 1) {
|
||||
/* Check for Digital Output interrupt Type */
|
||||
/* 1: VCC interrupt */
|
||||
/* 2: CC interrupt */
|
||||
devpriv->do_int_type = inl(devpriv->amcc_iobase +
|
||||
APCI1564_DO_INT_STATUS_REG) & 0x3;
|
||||
/* Disable the Interrupt */
|
||||
outl(0x0, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG);
|
||||
|
||||
/* Sends signal to user space */
|
||||
send_sig(SIGIO, devpriv->tsk_current, 0);
|
||||
}
|
||||
|
||||
if (ui_Timer == 1) {
|
||||
devpriv->timer_select_mode = ADDIDATA_TIMER;
|
||||
if (devpriv->timer_select_mode) {
|
||||
|
||||
/* Disable Timer Interrupt */
|
||||
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 */
|
||||
ul_Command2 =
|
||||
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 */
|
||||
outl(ul_Command2,
|
||||
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
|
||||
}
|
||||
}
|
||||
|
||||
if (ui_C3 == 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_COUNTER3));
|
||||
outl(0x0,
|
||||
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
|
||||
|
||||
/* 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_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;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include "comedi_fc.h"
|
||||
#include "amcc_s5933.h"
|
||||
|
||||
#include "addi-data/addi_common.h"
|
||||
|
||||
@@ -51,10 +52,158 @@ static int apci1564_reset(struct comedi_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
|
||||
static irqreturn_t apci1564_interrupt(int irq, void *d)
|
||||
{
|
||||
apci1564_interrupt(irq, d);
|
||||
return IRQ_RETVAL(1);
|
||||
struct comedi_device *dev = d;
|
||||
struct apci1564_private *devpriv = dev->private;
|
||||
struct comedi_subdevice *s = dev->read_subdev;
|
||||
unsigned int ui_DO, ui_DI;
|
||||
unsigned int ui_Timer;
|
||||
unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
|
||||
unsigned int ul_Command2 = 0;
|
||||
|
||||
/* check interrupt is from this device */
|
||||
if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) &
|
||||
INTCSR_INTR_ASSERTED) == 0)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* check which interrupt was triggered */
|
||||
ui_DI = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG) &
|
||||
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 */
|
||||
outl(ui_DI & APCI1564_DI_INT_DISABLE, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
|
||||
|
||||
s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG) & 0xffff;
|
||||
comedi_buf_put(s, s->state);
|
||||
s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
|
||||
comedi_event(dev, s);
|
||||
|
||||
/* enable the interrupt */
|
||||
outl(ui_DI, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
|
||||
}
|
||||
|
||||
if (ui_DO == 1) {
|
||||
/* Check for Digital Output interrupt Type */
|
||||
/* 1: VCC interrupt */
|
||||
/* 2: CC interrupt */
|
||||
devpriv->do_int_type = inl(devpriv->amcc_iobase +
|
||||
APCI1564_DO_INT_STATUS_REG) & 0x3;
|
||||
/* Disable the Interrupt */
|
||||
outl(0x0, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG);
|
||||
|
||||
/* Sends signal to user space */
|
||||
send_sig(SIGIO, devpriv->tsk_current, 0);
|
||||
}
|
||||
|
||||
if (ui_Timer == 1) {
|
||||
devpriv->timer_select_mode = ADDIDATA_TIMER;
|
||||
if (devpriv->timer_select_mode) {
|
||||
|
||||
/* Disable Timer Interrupt */
|
||||
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 */
|
||||
ul_Command2 =
|
||||
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 */
|
||||
outl(ul_Command2,
|
||||
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
|
||||
}
|
||||
}
|
||||
|
||||
if (ui_C3 == 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_COUNTER3));
|
||||
outl(0x0,
|
||||
dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
|
||||
|
||||
/* 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_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;
|
||||
}
|
||||
|
||||
static int apci1564_di_insn_bits(struct comedi_device *dev,
|
||||
@@ -295,7 +444,7 @@ static int apci1564_auto_attach(struct comedi_device *dev,
|
||||
apci1564_reset(dev);
|
||||
|
||||
if (pcidev->irq > 0) {
|
||||
ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
|
||||
ret = request_irq(pcidev->irq, apci1564_interrupt, IRQF_SHARED,
|
||||
dev->board_name, dev);
|
||||
if (ret == 0)
|
||||
dev->irq = pcidev->irq;
|
||||
|
||||
Reference in New Issue
Block a user