[PATCH 3/4] staging: comedi: ni_pcidio: Add comedi_poll support
Ian Abbott
abbotti at mev.co.uk
Mon Jan 9 07:47:32 PST 2012
This patch is ported over by me (Ian Abbott) from the out-of-tree Comedi
git repository at "git://comedi.org/git/comedi/comedi.git".
The original patch is by Nicholas Nell.
The patch adds support for the COMEDI_POLL ioctl to the ni_pcidio
driver.
Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
Cc: Nicholas Nell <nicholas.nell at colorado.edu>
---
drivers/staging/comedi/drivers/ni_pcidio.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 5145bf1..c258059 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -483,12 +483,28 @@ void ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s)
comedi_event(dev, s);
}
+static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ unsigned long flags_dev, flags_mite;
+ int count;
+
+ spin_lock_irqsave(&dev->spinlock, flags_dev);
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags_mite);
+ if (devpriv->di_mite_chan)
+ mite_sync_input_dma(devpriv->di_mite_chan, s->async);
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_mite);
+ count = s->async->buf_write_count - s->async->buf_read_count;
+ spin_unlock_irqrestore(&dev->spinlock, flags_dev);
+ return count;
+}
+
static irqreturn_t nidio_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
struct comedi_subdevice *s = dev->subdevices;
struct comedi_async *async = s->async;
struct mite_struct *mite = devpriv->mite;
+ unsigned long flags_dev;
/* int i, j; */
long int AuxData = 0;
@@ -506,6 +522,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
return IRQ_NONE;
}
+ /* Lock to avoid race with comedi_poll */
+ spin_lock_irqsave(&dev->spinlock, flags_dev);
+
status = readb(devpriv->mite->daq_io_addr +
Interrupt_And_Window_Status);
flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
@@ -646,6 +665,8 @@ out:
Master_DMA_And_Interrupt_Control);
}
#endif
+
+ spin_unlock_irqrestore(&dev->spinlock, flags_dev);
return IRQ_HANDLED;
}
@@ -1252,6 +1273,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->len_chanlist = 32; /* XXX */
s->buf_change = &ni_pcidio_change;
s->async_dma_dir = DMA_BIDIRECTIONAL;
+ s->poll = &ni_pcidio_poll;
writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
--
1.7.8.2
More information about the devel
mailing list