[PATCH 3/9] staging: comedi: addi_apci_1564: fix counter register access

H Hartley Sweeten hsweeten at visionengravers.com
Mon Oct 20 17:57:59 UTC 2014


According to the I/O map information from ADDI-DATA, the counters are accessed
using the base address found in PCI BAR 2 not the one in PCI BAR 1.

Add a new member to the private data for this base address and fix all the
counter I/O.

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 .../comedi/drivers/addi-data/hwdrv_apci1564.c      | 60 ++++++++++------------
 drivers/staging/comedi/drivers/addi_apci_1564.c    | 25 +++++----
 2 files changed, 42 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index fece17f..a025c60 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -47,7 +47,7 @@
 #define APCI1564_TIMER_WARN_TIMEBASE_REG		0x64
 
 /*
- * dev->iobase Register Map
+ * PCI BAR 2 Register Map (devpriv->counters)
  */
 #define APCI1564_COUNTER_REG(x)				(0x00 + ((x) * 0x20))
 #define APCI1564_COUNTER_RELOAD_REG(x)			(0x04 + ((x) * 0x20))
@@ -93,14 +93,14 @@ static int apci1564_timer_config(struct comedi_device *dev,
 			outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
 			outl(0x0, devpriv->amcc_iobase + APCI1564_DO_IRQ_REG);
 			outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_IRQ_REG);
-			outl(0x0, dev->iobase +
-			    APCI1564_COUNTER_IRQ_REG(0));
-			outl(0x0, dev->iobase +
-			    APCI1564_COUNTER_IRQ_REG(1));
-			outl(0x0, dev->iobase +
-			    APCI1564_COUNTER_IRQ_REG(2));
-			outl(0x0, dev->iobase +
-			    APCI1564_COUNTER_IRQ_REG(3));
+			outl(0x0,
+			     devpriv->counters + APCI1564_COUNTER_IRQ_REG(0));
+			outl(0x0,
+			     devpriv->counters + APCI1564_COUNTER_IRQ_REG(1));
+			outl(0x0,
+			     devpriv->counters + APCI1564_COUNTER_IRQ_REG(2));
+			outl(0x0,
+			     devpriv->counters + APCI1564_COUNTER_IRQ_REG(3));
 		} else {
 			/* disable Timer interrupt */
 			outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
@@ -120,16 +120,16 @@ static int apci1564_timer_config(struct comedi_device *dev,
 		devpriv->timer_select_mode = ADDIDATA_COUNTER;
 
 		/* First Stop The Counter */
-		ul_Command1 = inl(dev->iobase +
-				 APCI1564_COUNTER_CTRL_REG(chan));
+		ul_Command1 = inl(devpriv->counters +
+				  APCI1564_COUNTER_CTRL_REG(chan));
 		ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
 		/* Stop The Timer */
-		outl(ul_Command1, dev->iobase +
-					APCI1564_COUNTER_CTRL_REG(chan));
+		outl(ul_Command1,
+		     devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
 
 		/* Set the reload value */
-		outl(data[3], dev->iobase +
-					APCI1564_COUNTER_RELOAD_REG(chan));
+		outl(data[3],
+		     devpriv->counters + APCI1564_COUNTER_RELOAD_REG(chan));
 
 		/* Set the mode :             */
 		/* - Disable the hardware     */
@@ -142,18 +142,18 @@ static int apci1564_timer_config(struct comedi_device *dev,
 		ul_Command1 =
 			(ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
 			(unsigned int) ((unsigned int) data[4] << 16UL);
-		outl(ul_Command1, dev->iobase +
-					APCI1564_COUNTER_CTRL_REG(chan));
+		outl(ul_Command1,
+		     devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
 
 		/*  Enable or Disable Interrupt */
 		ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
-		outl(ul_Command1, dev->iobase +
-					APCI1564_COUNTER_CTRL_REG(chan));
+		outl(ul_Command1,
+		     devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
 
 		/* Set the Up/Down selection */
 		ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
-		outl(ul_Command1, dev->iobase +
-					APCI1564_COUNTER_CTRL_REG(chan));
+		outl(ul_Command1,
+		     devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
 	} else {
 		dev_err(dev->class_dev, "Invalid subdevice.\n");
 	}
@@ -190,9 +190,8 @@ static int apci1564_timer_write(struct comedi_device *dev,
 			outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
 		}
 	} else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) {
-		ul_Command1 =
-			inl(dev->iobase +
-			   APCI1564_COUNTER_CTRL_REG(chan));
+		ul_Command1 = inl(devpriv->counters +
+				  APCI1564_COUNTER_CTRL_REG(chan));
 		if (data[1] == 1) {
 			/* Start the Counter subdevice */
 			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
@@ -204,8 +203,8 @@ static int apci1564_timer_write(struct comedi_device *dev,
 			/*  Clears the Counter subdevice */
 			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
 		}
-		outl(ul_Command1, dev->iobase +
-		     APCI1564_COUNTER_CTRL_REG(chan));
+		outl(ul_Command1,
+		     devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
 	} else {
 		dev_err(dev->class_dev, "Invalid subdevice.\n");
 	}
@@ -232,12 +231,9 @@ static int apci1564_timer_read(struct comedi_device *dev,
 		data[1] = inl(devpriv->amcc_iobase + APCI1564_TIMER_REG);
 	} else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) {
 		/*  Read the Counter Actual Value. */
-		data[0] =
-			inl(dev->iobase +
-			    APCI1564_COUNTER_REG(chan));
-		ul_Command1 =
-			inl(dev->iobase +
-			    APCI1564_COUNTER_STATUS_REG(chan));
+		data[0] = inl(devpriv->counters + APCI1564_COUNTER_REG(chan));
+		ul_Command1 = inl(devpriv->counters +
+				  APCI1564_COUNTER_STATUS_REG(chan));
 
 		/* Get the software trigger status */
 		data[1] = (unsigned char) ((ul_Command1 >> 1) & 1);
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
index 2b96ef6..53f630b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1564.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -32,6 +32,7 @@
 #include "addi_watchdog.h"
 
 struct apci1564_private {
+	unsigned long counters;
 	unsigned int amcc_iobase;	/* base of AMCC I/O registers */
 	unsigned int mode1;		/* riding-edge/high level channels */
 	unsigned int mode2;		/* falling-edge/low level channels */
@@ -64,10 +65,10 @@ static int apci1564_reset(struct comedi_device *dev)
 	outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG);
 
 	/* Reset the counter registers */
-	outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(0));
-	outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(1));
-	outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(2));
-	outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(3));
+	outl(0x0, devpriv->counters + APCI1564_COUNTER_CTRL_REG(0));
+	outl(0x0, devpriv->counters + APCI1564_COUNTER_CTRL_REG(1));
+	outl(0x0, devpriv->counters + APCI1564_COUNTER_CTRL_REG(2));
+	outl(0x0, devpriv->counters + APCI1564_COUNTER_CTRL_REG(3));
 
 	return 0;
 }
@@ -116,20 +117,21 @@ static irqreturn_t apci1564_interrupt(int irq, void *d)
 	}
 
 	for (chan = 0; chan < 4; chan++) {
-		status = inl(dev->iobase + APCI1564_COUNTER_IRQ_REG(chan));
+		status = inl(devpriv->counters +
+			     APCI1564_COUNTER_IRQ_REG(chan));
 		if (status & 0x01) {
 			/*  Disable Counter Interrupt */
-			ctrl = inl(dev->iobase +
-				  APCI1564_COUNTER_CTRL_REG(chan));
-			outl(0x0, dev->iobase +
-			    APCI1564_COUNTER_CTRL_REG(chan));
+			ctrl = inl(devpriv->counters +
+				   APCI1564_COUNTER_CTRL_REG(chan));
+			outl(0x0, devpriv->counters +
+			     APCI1564_COUNTER_CTRL_REG(chan));
 
 			/* Send a signal to from kernel to user space */
 			send_sig(SIGIO, devpriv->tsk_current, 0);
 
 			/*  Enable Counter Interrupt */
-			outl(ctrl, dev->iobase +
-			    APCI1564_COUNTER_CTRL_REG(chan));
+			outl(ctrl, devpriv->counters +
+			     APCI1564_COUNTER_CTRL_REG(chan));
 		}
 	}
 
@@ -379,6 +381,7 @@ static int apci1564_auto_attach(struct comedi_device *dev,
 
 	dev->iobase = pci_resource_start(pcidev, 1);
 	devpriv->amcc_iobase = pci_resource_start(pcidev, 0);
+	devpriv->counters = pci_resource_start(pcidev, 2);
 
 	apci1564_reset(dev);
 
-- 
2.0.3



More information about the devel mailing list