Merge branch 'next/dt2' into HEAD
[cascardo/linux.git] / drivers / staging / comedi / drivers / amplc_pc236.c
index f502879..eacb5e4 100644 (file)
@@ -56,11 +56,15 @@ unused.
 
 #include "../comedidev.h"
 
+#include "comedi_fc.h"
 #include "8255.h"
 #include "plx9052.h"
 
 #define PC236_DRIVER_NAME      "amplc_pc236"
 
+#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA)
+#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI)
+
 /* PCI236 PCI configuration register information */
 #define PCI_VENDOR_ID_AMPLICON 0x14dc
 #define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009
@@ -103,14 +107,14 @@ struct pc236_board {
        enum pc236_model model;
 };
 static const struct pc236_board pc236_boards[] = {
-#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA)
+#if DO_ISA
        {
                .name = "pc36at",
                .bustype = isa_bustype,
                .model = pc36at_model,
        },
 #endif
-#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI)
+#if DO_PCI
        {
                .name = "pci236",
                .devid = PCI_DEVICE_ID_AMPLICON_PCI236,
@@ -135,6 +139,18 @@ struct pc236_private {
        int enable_irq;
 };
 
+/* test if ISA supported and this is an ISA board */
+static inline bool is_isa_board(const struct pc236_board *board)
+{
+       return DO_ISA && board->bustype == isa_bustype;
+}
+
+/* test if PCI supported and this is a PCI board */
+static inline bool is_pci_board(const struct pc236_board *board)
+{
+       return DO_PCI && board->bustype == pci_bustype;
+}
+
 /*
  * This function looks for a board matching the supplied PCI device.
  */
@@ -143,7 +159,7 @@ static const struct pc236_board *pc236_find_pci_board(struct pci_dev *pci_dev)
        unsigned int i;
 
        for (i = 0; i < ARRAY_SIZE(pc236_boards); i++)
-               if (pc236_boards[i].bustype == pci_bustype &&
+               if (is_pci_board(&pc236_boards[i]) &&
                    pci_dev->device == pc236_boards[i].devid)
                        return &pc236_boards[i];
        return NULL;
@@ -214,12 +230,13 @@ static int pc236_request_region(struct comedi_device *dev, unsigned long from,
  */
 static void pc236_intr_disable(struct comedi_device *dev)
 {
+       const struct pc236_board *thisboard = comedi_board(dev);
        struct pc236_private *devpriv = dev->private;
        unsigned long flags;
 
        spin_lock_irqsave(&dev->spinlock, flags);
        devpriv->enable_irq = 0;
-       if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && devpriv->lcr_iobase)
+       if (is_pci_board(thisboard))
                outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
        spin_unlock_irqrestore(&dev->spinlock, flags);
 }
@@ -231,12 +248,13 @@ static void pc236_intr_disable(struct comedi_device *dev)
  */
 static void pc236_intr_enable(struct comedi_device *dev)
 {
+       const struct pc236_board *thisboard = comedi_board(dev);
        struct pc236_private *devpriv = dev->private;
        unsigned long flags;
 
        spin_lock_irqsave(&dev->spinlock, flags);
        devpriv->enable_irq = 1;
-       if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && devpriv->lcr_iobase)
+       if (is_pci_board(thisboard))
                outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
        spin_unlock_irqrestore(&dev->spinlock, flags);
 }
@@ -250,6 +268,7 @@ static void pc236_intr_enable(struct comedi_device *dev)
  */
 static int pc236_intr_check(struct comedi_device *dev)
 {
+       const struct pc236_board *thisboard = comedi_board(dev);
        struct pc236_private *devpriv = dev->private;
        int retval = 0;
        unsigned long flags;
@@ -257,8 +276,7 @@ static int pc236_intr_check(struct comedi_device *dev)
        spin_lock_irqsave(&dev->spinlock, flags);
        if (devpriv->enable_irq) {
                retval = 1;
-               if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) &&
-                   devpriv->lcr_iobase) {
+               if (is_pci_board(thisboard)) {
                        if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR)
                             & PLX9052_INTCSR_LI1STAT_MASK)
                            == PLX9052_INTCSR_LI1STAT_INACTIVE) {
@@ -296,39 +314,20 @@ static int pc236_intr_cmdtest(struct comedi_device *dev,
                              struct comedi_cmd *cmd)
 {
        int err = 0;
-       int tmp;
 
-       /* step 1 */
+       /* Step 1 : check if triggers are trivially valid */
 
-       tmp = cmd->start_src;
-       cmd->start_src &= TRIG_NOW;
-       if (!cmd->start_src || tmp != cmd->start_src)
-               err++;
-
-       tmp = cmd->scan_begin_src;
-       cmd->scan_begin_src &= TRIG_EXT;
-       if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
-               err++;
-
-       tmp = cmd->convert_src;
-       cmd->convert_src &= TRIG_FOLLOW;
-       if (!cmd->convert_src || tmp != cmd->convert_src)
-               err++;
-
-       tmp = cmd->scan_end_src;
-       cmd->scan_end_src &= TRIG_COUNT;
-       if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
-               err++;
-
-       tmp = cmd->stop_src;
-       cmd->stop_src &= TRIG_NONE;
-       if (!cmd->stop_src || tmp != cmd->stop_src)
-               err++;
+       err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+       err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+       err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+       err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+       err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
 
        if (err)
                return 1;
 
-       /* step 2: ignored */
+       /* Step 2a : make sure trigger sources are unique */
+       /* Step 2b : and mutually compatible */
 
        if (err)
                return 2;
@@ -395,7 +394,7 @@ static int pc236_intr_cancel(struct comedi_device *dev,
 static irqreturn_t pc236_interrupt(int irq, void *d)
 {
        struct comedi_device *dev = d;
-       struct comedi_subdevice *s = dev->subdevices + 1;
+       struct comedi_subdevice *s = &dev->subdevices[1];
        int handled;
 
        handled = pc236_intr_check(dev);
@@ -414,15 +413,13 @@ static void pc236_report_attach(struct comedi_device *dev, unsigned int irq)
        char tmpbuf[60];
        int tmplen;
 
-       if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) &&
-           thisboard->bustype == isa_bustype)
+       if (is_isa_board(thisboard))
                tmplen = scnprintf(tmpbuf, sizeof(tmpbuf),
                                   "(base %#lx) ", dev->iobase);
-       else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) &&
-                thisboard->bustype == pci_bustype) {
+       else if (is_pci_board(thisboard))
                tmplen = scnprintf(tmpbuf, sizeof(tmpbuf),
                                   "(pci %s) ", pci_name(pcidev));
-       else
+       else
                tmplen = 0;
        if (irq)
                tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen,
@@ -449,14 +446,14 @@ static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
        if (ret)
                return ret;
 
-       s = dev->subdevices + 0;
+       s = &dev->subdevices[0];
        /* digital i/o subdevice (8255) */
        ret = subdev_8255_init(dev, s, NULL, iobase);
        if (ret < 0) {
                dev_err(dev->class_dev, "error! out of memory!\n");
                return ret;
        }
-       s = dev->subdevices + 1;
+       s = &dev->subdevices[1];
        dev->read_subdev = s;
        s->type = COMEDI_SUBD_UNUSED;
        pc236_intr_disable(dev);
@@ -517,16 +514,14 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                return ret;
        }
        /* Process options according to bus type. */
-       if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) &&
-           thisboard->bustype == isa_bustype) {
+       if (is_isa_board(thisboard)) {
                unsigned long iobase = it->options[0];
                unsigned int irq = it->options[1];
                ret = pc236_request_region(dev, iobase, PC236_IO_SIZE);
                if (ret < 0)
                        return ret;
                return pc236_common_attach(dev, iobase, irq, 0);
-       } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) &&
-                  thisboard->bustype == pci_bustype) {
+       } else if (is_pci_board(thisboard)) {
                struct pci_dev *pci_dev;
 
                pci_dev = pc236_find_pci_dev(dev, it);
@@ -550,7 +545,7 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev,
 {
        int ret;
 
-       if (!IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI))
+       if (!DO_PCI)
                return -EINVAL;
 
        dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n",
@@ -577,22 +572,25 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev,
 
 static void pc236_detach(struct comedi_device *dev)
 {
+       const struct pc236_board *thisboard = comedi_board(dev);
        struct pc236_private *devpriv = dev->private;
-       struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 
        if (devpriv)
                pc236_intr_disable(dev);
        if (dev->irq)
                free_irq(dev->irq, dev);
        if (dev->subdevices)
-               subdev_8255_cleanup(dev, dev->subdevices + 0);
-       if (pcidev) {
-               if (dev->iobase)
-                       comedi_pci_disable(pcidev);
-               pci_dev_put(pcidev);
-       } else {
+               subdev_8255_cleanup(dev, &dev->subdevices[0]);
+       if (is_isa_board(thisboard)) {
                if (dev->iobase)
                        release_region(dev->iobase, PC236_IO_SIZE);
+       } else if (is_pci_board(thisboard)) {
+               struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+               if (pcidev) {
+                       if (dev->iobase)
+                               comedi_pci_disable(pcidev);
+                       pci_dev_put(pcidev);
+               }
        }
 }
 
@@ -613,7 +611,7 @@ static struct comedi_driver amplc_pc236_driver = {
        .num_names = ARRAY_SIZE(pc236_boards),
 };
 
-#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI)
+#if DO_PCI
 static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
        { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) },
        {0}