From 55901d15b6f816af5bff9efd55b6400121dbc04a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 28 Jul 2014 13:09:33 +0100 Subject: [PATCH] staging: comedi: amplc_pc236: add callback to check and clear interrupt Add an optional callback function pointer to the board data to be called when checking if an interrupt has occurred and to clear it if it has. Since the callback returns `bool`, change a few other `int` values to `bool` to match. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 40 ++++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index c69aa2d2056f..677911b0f7c0 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -83,6 +83,7 @@ struct pc236_board { const char *name; enum pc236_bustype bustype; void (*intr_update_cb)(struct comedi_device *dev, bool enable); + bool (*intr_chk_clr_cb)(struct comedi_device *dev); }; struct pc236_private { @@ -120,29 +121,21 @@ static void pc236_intr_update(struct comedi_device *dev, bool enable) * the interrupt has been marked as enabled and was generated by the * board. If so, the function prepares the hardware for the next * interrupt. - * Returns 0 if the interrupt should be ignored. + * Returns false if the interrupt should be ignored. */ -static int pc236_intr_check(struct comedi_device *dev) +static bool pc236_intr_check(struct comedi_device *dev) { const struct pc236_board *thisboard = comedi_board(dev); struct pc236_private *devpriv = dev->private; - int retval = 0; + bool retval = false; unsigned long flags; - unsigned int intcsr; spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->enable_irq) { - retval = 1; - if (is_pci_board(thisboard)) { - intcsr = inl(devpriv->lcr_iobase + PLX9052_INTCSR); - if (!(intcsr & PLX9052_INTCSR_LI1STAT)) { - retval = 0; - } else { - /* Clear interrupt and keep it enabled. */ - outl(PCI236_INTR_ENABLE, - devpriv->lcr_iobase + PLX9052_INTCSR); - } - } + if (thisboard->intr_chk_clr_cb) + retval = thisboard->intr_chk_clr_cb(dev); + else + retval = true; } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -236,7 +229,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct comedi_subdevice *s = dev->read_subdev; - int handled; + bool handled; handled = pc236_intr_check(dev); if (dev->attached && handled) { @@ -312,13 +305,28 @@ static void pci236_intr_update_cb(struct comedi_device *dev, bool enable) { struct pc236_private *devpriv = dev->private; + /* this will also clear the "local interrupt 1" latch */ outl(enable ? PCI236_INTR_ENABLE : PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR); } +static bool pci236_intr_chk_clr_cb(struct comedi_device *dev) +{ + struct pc236_private *devpriv = dev->private; + + /* check if interrupt occurred */ + if (!(inl(devpriv->lcr_iobase + PLX9052_INTCSR) & + PLX9052_INTCSR_LI1STAT)) + return false; + /* clear the interrupt */ + pci236_intr_update_cb(dev, devpriv->enable_irq); + return true; +} + static const struct pc236_board pc236_pci_board = { .name = "pci236", .intr_update_cb = pci236_intr_update_cb, + .intr_chk_clr_cb = pci236_intr_chk_clr_cb, .bustype = pci_bustype, }; -- 2.34.1