Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 77f17d37 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6b79db38
Loading
Loading
Loading
Loading
+44 −2
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct pci_8255_boardinfo {
	unsigned short vendor;
	unsigned short device;
	int dio_badr;
	int is_mmio;
	int n_8255;
};

@@ -120,6 +121,22 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = {
	},
};

struct pci_8255_private {
	void __iomem *mmio_base;
};

static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase)
{
	void __iomem *mmio_base = (void __iomem *)iobase;

	if (dir) {
		writeb(data, mmio_base + port);
		return 0;
	} else {
		return readb(mmio_base  + port);
	}
}

static const void *pci_8255_find_boardinfo(struct comedi_device *dev,
					      struct pci_dev *pcidev)
{
@@ -139,7 +156,10 @@ static int pci_8255_attach_pci(struct comedi_device *dev,
			       struct pci_dev *pcidev)
{
	const struct pci_8255_boardinfo *board;
	struct pci_8255_private *devpriv;
	struct comedi_subdevice *s;
	resource_size_t iobase;
	unsigned long len;
	int ret;
	int i;

@@ -151,10 +171,23 @@ static int pci_8255_attach_pci(struct comedi_device *dev,
	dev->board_ptr = board;
	dev->board_name = board->name;

	ret = alloc_private(dev, sizeof(*devpriv));
	if (ret < 0)
		return ret;
	devpriv = dev->private;

	ret = comedi_pci_enable(pcidev, dev->board_name);
	if (ret)
		return ret;
	dev->iobase = pci_resource_start(pcidev, board->dio_badr);
	iobase = pci_resource_start(pcidev, board->dio_badr);
	len = pci_resource_len(pcidev, board->dio_badr);

	if (board->is_mmio) {
		devpriv->mmio_base = ioremap(iobase, len);
		if (!devpriv->mmio_base)
			return -ENOMEM;
	}
	dev->iobase = iobase;

	/*
	 * One, two, or four subdevices are setup by this driver depending
@@ -167,7 +200,13 @@ static int pci_8255_attach_pci(struct comedi_device *dev,

	for (i = 0; i < board->n_8255; i++) {
		s = &dev->subdevices[i];
		ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4));
		if (board->is_mmio) {
			iobase = (unsigned long)(devpriv->mmio_base + (i * 4));
			ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase);
		} else {
			iobase = dev->iobase + (i * 4);
			ret = subdev_8255_init(dev, s, NULL, iobase);
		}
		if (ret)
			return ret;
	}
@@ -182,6 +221,7 @@ static void pci_8255_detach(struct comedi_device *dev)
{
	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
	const struct pci_8255_boardinfo *board = comedi_board(dev);
	struct pci_8255_private *devpriv = dev->private;
	struct comedi_subdevice *s;
	int i;

@@ -192,6 +232,8 @@ static void pci_8255_detach(struct comedi_device *dev)
		}
	}
	if (pcidev) {
		if (devpriv->mmio_base)
			iounmap(devpriv->mmio_base);
		if (dev->iobase)
			comedi_pci_disable(pcidev);
	}