staging: comedi: 8255_pci: initialize MITE data window
authorIan Abbott <abbotti@mev.co.uk>
Thu, 13 Mar 2014 15:30:39 +0000 (15:30 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 17 Mar 2014 21:14:22 +0000 (14:14 -0700)
According to National Instruments' PCI-DIO-96/PXI-6508/PCI-6503 User
Manual, the physical address in PCI BAR1 needs to be OR'ed with 0x80 and
written to register offset 0xC0 in the "MITE" registers (BAR0).  Do so
during initialization of the National Instruments boards handled by the
"8255_pci" driver.  The boards were previously handled by the
"ni_pcidio" driver, where the initialization was done by `mite_setup()`
in the "mite" module.  The "mite" module comes with too much extra
baggage for the "8255_pci" driver to deal with so use a local, simpler
initialization function.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Cc: <stable@vger.kernel.org> # 3.10.y, 3.11.y, 3.12.y, 3.13.y, 3.14.y
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/8255_pci.c

index 47321de629a790ab71282d45e753188416820061..46a385c29ba82c3806af186fe035fd20742a19c7 100644 (file)
@@ -56,6 +56,7 @@ Configuration Options: not applicable, uses PCI auto config
 #include "../comedidev.h"
 
 #include "8255.h"
+#include "mite.h"
 
 enum pci_8255_boardid {
        BOARD_ADLINK_PCI7224,
@@ -79,6 +80,7 @@ struct pci_8255_boardinfo {
        const char *name;
        int dio_badr;
        int n_8255;
+       unsigned int has_mite:1;
 };
 
 static const struct pci_8255_boardinfo pci_8255_boards[] = {
@@ -126,36 +128,43 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = {
                .name           = "ni_pci-dio-96",
                .dio_badr       = 1,
                .n_8255         = 4,
+               .has_mite       = 1,
        },
        [BOARD_NI_PCIDIO96B] = {
                .name           = "ni_pci-dio-96b",
                .dio_badr       = 1,
                .n_8255         = 4,
+               .has_mite       = 1,
        },
        [BOARD_NI_PXI6508] = {
                .name           = "ni_pxi-6508",
                .dio_badr       = 1,
                .n_8255         = 4,
+               .has_mite       = 1,
        },
        [BOARD_NI_PCI6503] = {
                .name           = "ni_pci-6503",
                .dio_badr       = 1,
                .n_8255         = 1,
+               .has_mite       = 1,
        },
        [BOARD_NI_PCI6503B] = {
                .name           = "ni_pci-6503b",
                .dio_badr       = 1,
                .n_8255         = 1,
+               .has_mite       = 1,
        },
        [BOARD_NI_PCI6503X] = {
                .name           = "ni_pci-6503x",
                .dio_badr       = 1,
                .n_8255         = 1,
+               .has_mite       = 1,
        },
        [BOARD_NI_PXI_6503] = {
                .name           = "ni_pxi-6503",
                .dio_badr       = 1,
                .n_8255         = 1,
+               .has_mite       = 1,
        },
 };
 
@@ -163,6 +172,25 @@ struct pci_8255_private {
        void __iomem *mmio_base;
 };
 
+static int pci_8255_mite_init(struct pci_dev *pcidev)
+{
+       void __iomem *mite_base;
+       u32 main_phys_addr;
+
+       /* ioremap the MITE registers (BAR 0) temporarily */
+       mite_base = pci_ioremap_bar(pcidev, 0);
+       if (!mite_base)
+               return -ENOMEM;
+
+       /* set data window to main registers (BAR 1) */
+       main_phys_addr = pci_resource_start(pcidev, 1);
+       writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
+
+       /* finished with MITE registers */
+       iounmap(mite_base);
+       return 0;
+}
+
 static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase)
 {
        void __iomem *mmio_base = (void __iomem *)iobase;
@@ -201,6 +229,12 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
        if (ret)
                return ret;
 
+       if (board->has_mite) {
+               ret = pci_8255_mite_init(pcidev);
+               if (ret)
+                       return ret;
+       }
+
        is_mmio = (pci_resource_flags(pcidev, board->dio_badr) &
                   IORESOURCE_MEM) != 0;
        if (is_mmio) {