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>
This commit is contained in:
parent
2421a0242e
commit
c5f68d7925
@ -1538,6 +1538,42 @@ static void dio200_subdev_8255_cleanup(struct comedi_device *dev,
|
|||||||
kfree(subpriv);
|
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)
|
static void dio200_report_attach(struct comedi_device *dev, unsigned int irq)
|
||||||
{
|
{
|
||||||
const struct dio200_board *thisboard = comedi_board(dev);
|
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.u.iobase = (unsigned long)base;
|
||||||
devpriv->io.regtype = io_regtype;
|
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);
|
return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user