Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: comedi: 8255_pci: support memory mapped i/o boards

Some of the PCI based 8255 boards that can be supported by this driver
use memory mapped i/o. Add the code needed to support these boards.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

H Hartley Sweeten and committed by
Greg Kroah-Hartman
77f17d37 6b79db38

+44 -2
+44 -2
drivers/staging/comedi/drivers/8255_pci.c
··· 71 71 unsigned short vendor; 72 72 unsigned short device; 73 73 int dio_badr; 74 + int is_mmio; 74 75 int n_8255; 75 76 }; 76 77 ··· 121 120 }, 122 121 }; 123 122 123 + struct pci_8255_private { 124 + void __iomem *mmio_base; 125 + }; 126 + 127 + static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase) 128 + { 129 + void __iomem *mmio_base = (void __iomem *)iobase; 130 + 131 + if (dir) { 132 + writeb(data, mmio_base + port); 133 + return 0; 134 + } else { 135 + return readb(mmio_base + port); 136 + } 137 + } 138 + 124 139 static const void *pci_8255_find_boardinfo(struct comedi_device *dev, 125 140 struct pci_dev *pcidev) 126 141 { ··· 156 139 struct pci_dev *pcidev) 157 140 { 158 141 const struct pci_8255_boardinfo *board; 142 + struct pci_8255_private *devpriv; 159 143 struct comedi_subdevice *s; 144 + resource_size_t iobase; 145 + unsigned long len; 160 146 int ret; 161 147 int i; 162 148 ··· 171 151 dev->board_ptr = board; 172 152 dev->board_name = board->name; 173 153 154 + ret = alloc_private(dev, sizeof(*devpriv)); 155 + if (ret < 0) 156 + return ret; 157 + devpriv = dev->private; 158 + 174 159 ret = comedi_pci_enable(pcidev, dev->board_name); 175 160 if (ret) 176 161 return ret; 177 - dev->iobase = pci_resource_start(pcidev, board->dio_badr); 162 + iobase = pci_resource_start(pcidev, board->dio_badr); 163 + len = pci_resource_len(pcidev, board->dio_badr); 164 + 165 + if (board->is_mmio) { 166 + devpriv->mmio_base = ioremap(iobase, len); 167 + if (!devpriv->mmio_base) 168 + return -ENOMEM; 169 + } 170 + dev->iobase = iobase; 178 171 179 172 /* 180 173 * One, two, or four subdevices are setup by this driver depending ··· 200 167 201 168 for (i = 0; i < board->n_8255; i++) { 202 169 s = &dev->subdevices[i]; 203 - ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); 170 + if (board->is_mmio) { 171 + iobase = (unsigned long)(devpriv->mmio_base + (i * 4)); 172 + ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase); 173 + } else { 174 + iobase = dev->iobase + (i * 4); 175 + ret = subdev_8255_init(dev, s, NULL, iobase); 176 + } 204 177 if (ret) 205 178 return ret; 206 179 } ··· 221 182 { 222 183 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 223 184 const struct pci_8255_boardinfo *board = comedi_board(dev); 185 + struct pci_8255_private *devpriv = dev->private; 224 186 struct comedi_subdevice *s; 225 187 int i; 226 188 ··· 232 192 } 233 193 } 234 194 if (pcidev) { 195 + if (devpriv->mmio_base) 196 + iounmap(devpriv->mmio_base); 235 197 if (dev->iobase) 236 198 comedi_pci_disable(pcidev); 237 199 }