summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2012-10-24 16:48:06 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-24 15:25:22 -0700
commitc5f68d79259ee61b58197b0f751411e0196560f2 (patch)
tree17a1f8a332eb0bde7f23e264be7df01e627faccd /drivers
parent2421a0242e17445ab35f7b450d0768518f0f63e6 (diff)
downloadlwn-c5f68d79259ee61b58197b0f751411e0196560f2.tar.gz
lwn-c5f68d79259ee61b58197b0f751411e0196560f2.zip
staging: comedi: amplc_dio200: allow generation of PCIe interrupts
The new PCIe boards PCIe215, PCIe236 and PCIe296 need a special register setting to allow generation of interrupts on the PCIe bus. Add `dio200_pcie_board_setup()` to do this and call it from `dio200_attach_pci()` for those boards. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index a7a1be9ad728..cf53e84c3bc4 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -1538,6 +1538,42 @@ static void dio200_subdev_8255_cleanup(struct comedi_device *dev,
kfree(subpriv);
}
+/*
+ * This function does some special set-up for the PCIe boards
+ * PCIe215, PCIe236, PCIe296.
+ */
+static int dio200_pcie_board_setup(struct comedi_device *dev)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ void __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(pcidev, 0);
+ if (brlen < 0x4000 ||
+ !(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) {
+ dev_err(dev->class_dev, "error! bad PCI region!\n");
+ return -EINVAL;
+ }
+ brbase = ioremap_nocache(pci_resource_start(pcidev, 0), brlen);
+ if (!brbase) {
+ dev_err(dev->class_dev, "error! failed to map registers!\n");
+ return -ENOMEM;
+ }
+ writel(0x80, brbase + 0x50);
+ iounmap(brbase);
+ return 0;
+}
+
static void dio200_report_attach(struct comedi_device *dev, unsigned int irq)
{
const struct dio200_board *thisboard = comedi_board(dev);
@@ -1736,6 +1772,18 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev,
devpriv->io.u.iobase = (unsigned long)base;
devpriv->io.regtype = io_regtype;
}
+ switch (thisboard->model)
+ {
+ case pcie215_model:
+ case pcie236_model:
+ case pcie296_model:
+ ret = dio200_pcie_board_setup(dev);
+ if (ret < 0)
+ return ret;
+ break;
+ default:
+ break;
+ }
return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED);
}