[PATCH 42/48] staging: comedi: pcl816: use comedi_timeout()

H Hartley Sweeten hsweeten at visionengravers.com
Thu Feb 6 23:49:17 UTC 2014


Use comedi_timeout() to wait for the analog input end-of-conversion.

The interrupt routine also uses the timeout check to make sure data
is actually available. Using NULL here for the 'insn' is safe since
nothing uses it.

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>
---
 drivers/staging/comedi/drivers/pcl816.c | 57 +++++++++++++++------------------
 1 file changed, 25 insertions(+), 32 deletions(-)

diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index e9d4704..b3a2af3 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -160,16 +160,25 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
 			     struct comedi_cmd *cmd);
 static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
 
-/*
-==============================================================================
-   ANALOG INPUT MODE0, 816 cards, slow version
-*/
+static int pcl816_ai_eoc(struct comedi_device *dev,
+			 struct comedi_subdevice *s,
+			 struct comedi_insn *insn,
+			 unsigned long context)
+{
+	unsigned int status;
+
+	status = inb(dev->iobase + PCL816_STATUS);
+	if ((status & PCL816_STATUS_DRDY_MASK) == 0)
+		return 0;
+	return -EBUSY;
+}
+
 static int pcl816_ai_insn_read(struct comedi_device *dev,
 			       struct comedi_subdevice *s,
 			       struct comedi_insn *insn, unsigned int *data)
 {
+	int ret;
 	int n;
-	int timeout;
 
 	/*  software trigger, DMA and INT off */
 	outb(0, dev->iobase + PCL816_CONTROL);
@@ -185,30 +194,20 @@ static int pcl816_ai_insn_read(struct comedi_device *dev,
 
 		outb(0, dev->iobase + PCL816_AD_LO);	/* start conversion */
 
-		timeout = 100;
-		while (timeout--) {
-			if (!(inb(dev->iobase + PCL816_STATUS) &
-			      PCL816_STATUS_DRDY_MASK)) {
-				/*  return read value */
-				data[n] =
-				    ((inb(dev->iobase +
-					  PCL816_AD_HI) << 8) |
-				     (inb(dev->iobase + PCL816_AD_LO)));
-				/* clear INT (conversion end) flag */
-				outb(0, dev->iobase + PCL816_CLRINT);
-				break;
-			}
-			udelay(1);
-		}
-		/*  Return timeout error */
-		if (!timeout) {
+		ret = comedi_timeout(dev, s, insn, pcl816_ai_eoc, 0);
+		if (ret) {
 			comedi_error(dev, "A/D insn timeout\n");
 			data[0] = 0;
 			/* clear INT (conversion end) flag */
 			outb(0, dev->iobase + PCL816_CLRINT);
-			return -EIO;
+			return ret;
 		}
 
+		/*  return read value */
+		data[n] = ((inb(dev->iobase + PCL816_AD_HI) << 8) |
+			  (inb(dev->iobase + PCL816_AD_LO)));
+		/* clear INT (conversion end) flag */
+		outb(0, dev->iobase + PCL816_CLRINT);
 	}
 	return n;
 }
@@ -224,22 +223,16 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
 	struct pcl816_private *devpriv = dev->private;
 	struct comedi_subdevice *s = dev->read_subdev;
 	unsigned char low, hi;
-	int timeout = 50;	/* wait max 50us */
+	int ret;
 
-	while (timeout--) {
-		if (!(inb(dev->iobase + PCL816_STATUS) &
-		      PCL816_STATUS_DRDY_MASK))
-			break;
-		udelay(1);
-	}
-	if (!timeout) {		/*  timeout, bail error */
+	ret = comedi_timeout(dev, s, NULL, pcl816_ai_eoc, 0);
+	if (ret) {
 		outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
 		comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
 		pcl816_ai_cancel(dev, s);
 		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 		comedi_event(dev, s);
 		return IRQ_HANDLED;
-
 	}
 
 	/*  get the sample */
-- 
1.8.5.2



More information about the devel mailing list