From: H Hartley Sweeten Date: Tue, 23 Apr 2013 01:37:29 +0000 (-0700) Subject: staging: comedi: das800: tidy up das800_interrupt() X-Git-Tag: v3.10-rc1~192^2~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7f340859f26e6de7069d0c4f234d948820c4fd47;p=platform%2Fkernel%2Flinux-3.10.git staging: comedi: das800: tidy up das800_interrupt() Rename the CamelCase variable 'dataPoint'. Cleanup some of the comments and fix the > 80 char lines. Use the das800_ai_get_sample() helper to get the analog input data. Change the fifo flags into bools and make sure to check for the fifo overflow while reading the samples. This also fixes the overflow detection for 12-bit resolutions. In the current code the 'dataPoint' value has been shifted and masked. This could result in fifo_overflow being invalidly true. Remove the need for the 'thisboard' pointer by using the subdevice 'maxdata' to determine the sample size. The devpriv->forever flag is really a bool. Treat it as such. Remove the comedi_error() messages. The user will get the error condition back in the async event. The message is just added noise. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index c30309c..b72bbe9 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -107,6 +107,8 @@ cmd triggers supported: #define STATUS2_INTE 0X20 #define DAS800_ID 7 +#define DAS802_16_HALF_FIFO_SZ 128 + struct das800_board { const char *name; int ai_speed; @@ -483,92 +485,79 @@ static unsigned int das800_ai_get_sample(struct comedi_device *dev) static irqreturn_t das800_interrupt(int irq, void *d) { - short i; /* loop index */ - short dataPoint = 0; struct comedi_device *dev = d; - const struct das800_board *thisboard = comedi_board(dev); struct das800_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */ - struct comedi_async *async; - int status; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s ? s->async : NULL; unsigned long irq_flags; - static const int max_loops = 128; /* half-fifo size for cio-das802/16 */ - /* flags */ - int fifo_empty = 0; - int fifo_overflow = 0; + unsigned int status; + unsigned int val; + bool fifo_empty; + bool fifo_overflow; + int i; status = inb(dev->iobase + DAS800_STATUS); - /* if interrupt was not generated by board or driver not attached, quit */ if (!(status & IRQ)) return IRQ_NONE; - if (!(dev->attached)) + if (!dev->attached) return IRQ_HANDLED; - /* wait until here to initialize async, since we will get null dereference - * if interrupt occurs before driver is fully attached! - */ - async = s->async; - - /* if hardware conversions are not enabled, then quit */ spin_lock_irqsave(&dev->spinlock, irq_flags); status = das800_ind_read(dev, CONTROL1) & STATUS2_HCEN; - /* don't release spinlock yet since we want to make sure no one else disables hardware conversions */ + /* + * Don't release spinlock yet since we want to make sure + * no one else disables hardware conversions. + */ + + /* if hardware conversions are not enabled, then quit */ if (status == 0) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); return IRQ_HANDLED; } - /* loop while card's fifo is not empty (and limit to half fifo for cio-das802/16) */ - for (i = 0; i < max_loops; i++) { - /* read 16 bits from dev->iobase and dev->iobase + 1 */ - dataPoint = inb(dev->iobase + DAS800_LSB); - dataPoint += inb(dev->iobase + DAS800_MSB) << 8; - if (thisboard->resolution == 12) { - fifo_empty = dataPoint & FIFO_EMPTY; - fifo_overflow = dataPoint & FIFO_OVF; - if (fifo_overflow) - break; + for (i = 0; i < DAS802_16_HALF_FIFO_SZ; i++) { + val = das800_ai_get_sample(dev); + if (s->maxdata == 0x0fff) { + fifo_empty = !!(val & FIFO_EMPTY); + fifo_overflow = !!(val & FIFO_OVF); } else { - fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */ + /* cio-das802/16 has no fifo empty status bit */ + fifo_empty = false; + fifo_overflow = !!(inb(dev->iobase + DAS800_GAIN) & + CIO_FFOV); } - if (fifo_empty) + if (fifo_empty || fifo_overflow) break; - /* strip off extraneous bits for 12 bit cards */ - if (thisboard->resolution == 12) - dataPoint = (dataPoint >> 4) & 0xfff; + + if (s->maxdata == 0x0fff) + val >>= 4; /* 12-bit sample */ + /* if there are more data points to collect */ - if (devpriv->count > 0 || devpriv->forever == 1) { + if (devpriv->count > 0 || devpriv->forever) { /* write data point to buffer */ - cfc_write_to_buffer(s, dataPoint); - if (devpriv->count > 0) - devpriv->count--; + cfc_write_to_buffer(s, val & s->maxdata); + devpriv->count--; } } async->events |= COMEDI_CB_BLOCK; - /* check for fifo overflow */ - if (thisboard->resolution == 12) { - fifo_overflow = dataPoint & FIFO_OVF; - /* else cio-das802/16 */ - } else { - fifo_overflow = inb(dev->iobase + DAS800_GAIN) & CIO_FFOV; - } + if (fifo_overflow) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); - comedi_error(dev, "DAS800 FIFO overflow"); das800_cancel(dev, s); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; comedi_event(dev, s); async->events = 0; return IRQ_HANDLED; } - if (devpriv->count > 0 || devpriv->forever == 1) { + + if (devpriv->count > 0 || devpriv->forever) { /* Re-enable card's interrupt. * We already have spinlock, so indirect addressing is safe */ das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1); spin_unlock_irqrestore(&dev->spinlock, irq_flags); - /* otherwise, stop taking data */ } else { + /* otherwise, stop taking data */ spin_unlock_irqrestore(&dev->spinlock, irq_flags); das800_disable(dev); async->events |= COMEDI_CB_EOA;