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, };