amplc_dio200: Allow generation of PCIe interrupts.
authorIan Abbott <abbotti@mev.co.uk>
Mon, 28 May 2012 09:40:41 +0000 (10:40 +0100)
committerIan Abbott <abbotti@mev.co.uk>
Mon, 28 May 2012 09:40:41 +0000 (10:40 +0100)
The new PCIe boards need a special register setting to allow generation
of interrupts.  Add function dio200_pcie_board_setup() to do this
special set-up for the new PCIe boards.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
comedi/drivers/amplc_dio200.c

index cee61e958f66c306924b0034f210e4cd99eb15ca..ae06b6ff6177cb772f4df40fd8d32a76f6c181ef 100644 (file)
@@ -1667,6 +1667,47 @@ dio200_subdev_8255_cleanup(comedi_device * dev, comedi_subdevice * s)
        }
 }
 
+#ifdef CONFIG_COMEDI_PCI
+/*
+ * This function does some special set-up for the PCIe boards
+ * PCIe215, PCIe236, PCIe296.
+ */
+static int
+dio200_pcie_board_setup(comedi_device * dev)
+{
+       struct pci_dev *pci_dev = devpriv->pci_dev;
+       unsigned char __iomem *brbase;
+       resource_size_t brlen;
+
+       /*
+        * The board uses Altera Cyclone IV with PCI-Express hard IP.
+        * The FPGA configuration has the PCI-Express Avalon-MM Bridge
+        * Control registers in PCI BAR 0, offset 0, and the length of
+        * these registers is 0x4000.
+        *
+        * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
+        * Enable" register at offset 0x50 to allow generation of PCIe
+        * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
+        */
+       brlen = pci_resource_len(pci_dev, 0);
+       if (brlen < 0x4000 ||
+                       !(pci_resource_flags(pci_dev, 0) & IORESOURCE_MEM)) {
+               printk(KERN_ERR "comedi%d: error! bad PCI region!\n",
+                       dev->minor);
+               return -EINVAL;
+       }
+       brbase = ioremap_nocache(pci_resource_start(pci_dev, 0), brlen);
+       if (!brbase) {
+               printk(KERN_ERR "comedi%d: error! failed to map registers!\n",
+                       dev->minor);
+               return -ENOMEM;
+       }
+       writel(0x80, brbase + 0x50);
+       iounmap(brbase);
+       return 0;
+}
+#endif
+
 /*
  * Attach is called by the Comedi core to configure the driver
  * for a particular board.  If you specified a board_name array
@@ -1775,6 +1816,21 @@ static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
                devpriv->io.regtype = io_regtype;
        }
 
+       switch (thisboard->model) {
+#ifdef CONFIG_COMEDI_PCI
+       case pcie215_model:
+       case pcie236_model:
+       case pcie296_model:
+               ret = dio200_pcie_board_setup(dev);
+               if (ret < 0) {
+                       return ret;
+               }
+               break;
+#endif
+       default:
+               break;
+       }
+
        layout = thislayout;
        if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
                printk(KERN_ERR "comedi%d: error! out of memory!\n",