The DMA and EOC interrupt handler functions, that are called by the _real_ interrupt function, always return IRQ_HANDLED. Change the return type for these functions to void and move the final return to the real interrupt function. Change the parameters to the handler functions to the comedi_device and comedi_subdevice pointers. At some point in the handler functions the interrupt request is cleared. Move this to the real interrupt function. Also at some point in the handlers, comedi_event() is called to pass any events to the comedi subsystem. Move this to the real interrupt function also. Add a comedi_event() call to pcl816_ai_poll() due to the removal of the call from transfer_from_dma_buf(). For aesthetics, and to clarify the code, rename the interrupt function and the handler functions. Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/staging/comedi/drivers/pcl816.c | 45 +++++++++++++-------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index ffc2c12..3c0431e 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -286,36 +286,25 @@ static bool pcl816_ai_next_chan(struct comedi_device *dev, /* all data sampled */ s->cancel(dev, s); s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); return false; } return true; } -static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) +static void pcl816_handle_eoc(struct comedi_device *dev, + struct comedi_subdevice *s) { - struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->read_subdev; - if (pcl816_ai_eoc(dev, s, NULL, 0)) { - outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */ comedi_error(dev, "A/D mode1/3 IRQ without DRDY!"); s->cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - comedi_event(dev, s); - return IRQ_HANDLED; + return; } comedi_buf_put(s->async, pcl816_ai_get_sample(dev, s)); - outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */ - - if (!pcl816_ai_next_chan(dev, s)) - return IRQ_HANDLED; - - comedi_event(dev, s); - return IRQ_HANDLED; + pcl816_ai_next_chan(dev, s); } static void transfer_from_dma_buf(struct comedi_device *dev, @@ -331,15 +320,12 @@ static void transfer_from_dma_buf(struct comedi_device *dev, if (!pcl816_ai_next_chan(dev, s)) return; } - - comedi_event(dev, s); } -static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) +static void pcl816_handle_dma(struct comedi_device *dev, + struct comedi_subdevice *s) { - struct comedi_device *dev = d; struct pcl816_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; int len, bufptr, this_dma_buf; unsigned short *ptr; @@ -347,8 +333,6 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) pcl816_ai_setup_next_dma(dev, s); - outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */ - ptr = (unsigned short *)devpriv->dmabuf[this_dma_buf]; len = (devpriv->hwdmasize >> 1) - devpriv->ai_poll_ptr; @@ -356,12 +340,12 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) devpriv->ai_poll_ptr = 0; transfer_from_dma_buf(dev, s, ptr, bufptr, len); - return IRQ_HANDLED; } -static irqreturn_t interrupt_pcl816(int irq, void *d) +static irqreturn_t pcl816_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct comedi_subdevice *s = dev->read_subdev; struct pcl816_private *devpriv = dev->private; if (!dev->attached || !devpriv->ai_cmd_running) { @@ -376,9 +360,14 @@ static irqreturn_t interrupt_pcl816(int irq, void *d) } if (devpriv->dma) - return interrupt_pcl816_ai_mode13_dma(irq, d); + pcl816_handle_dma(dev, s); else - return interrupt_pcl816_ai_mode13_int(irq, d); + pcl816_handle_eoc(dev, s); + + outb(0, dev->iobase + PCL816_CLRINT); + + comedi_event(dev, s); + return IRQ_HANDLED; } static int pcl816_ai_cmdtest(struct comedi_device *dev, @@ -549,6 +538,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_poll_ptr = top1; /* new buffer position */ spin_unlock_irqrestore(&dev->spinlock, flags); + comedi_event(dev, s); + return s->async->buf_write_count - s->async->buf_read_count; } @@ -706,7 +697,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* we can use IRQ 2-7 for async command support */ if (it->options[1] >= 2 && it->options[1] <= 7) { - ret = request_irq(it->options[1], interrupt_pcl816, 0, + ret = request_irq(it->options[1], pcl816_interrupt, 0, dev->board_name, dev); if (ret == 0) dev->irq = it->options[1]; -- 1.8.5.2 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel