From: Nico Nell Date: Thu, 18 Aug 2011 17:14:30 +0000 (-0600) Subject: Added comedi_poll support to ni_pcidio X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a5d38ab9f2428a9f9639e9b8069427effc5c2a62;p=comedi.git Added comedi_poll support to ni_pcidio --- diff --git a/comedi/drivers/ni_pcidio.c b/comedi/drivers/ni_pcidio.c index 69727789..dded484b 100644 --- a/comedi/drivers/ni_pcidio.c +++ b/comedi/drivers/ni_pcidio.c @@ -478,6 +478,26 @@ void ni_pcidio_event(comedi_device * dev, comedi_subdevice * s) comedi_event(dev, s); } +static int ni_pcidio_poll(comedi_device * dev, comedi_subdevice * s) +{ + unsigned long flags_dev, flags_mite; + int count; + + comedi_spin_lock_irqsave(&dev->spinlock, flags_dev); + comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags_mite); + + if (devpriv->di_mite_chan) + mite_sync_input_dma(devpriv->di_mite_chan, s->async); + + comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, + flags_mite); + + count = s->async->buf_write_count - s->async->buf_read_count; + comedi_spin_unlock_irqrestore(&dev->spinlock, flags_dev); + + return count; +} + static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG) { comedi_device *dev = d; @@ -494,6 +514,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG) int work = 0; unsigned int m_status = 0; unsigned long irq_flags; + unsigned long flags_dev; //interrupcions parasites if (dev->attached == 0) { @@ -501,6 +522,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG) return IRQ_NONE; } + /* Lock to avoid race with comedi_poll */ + comedi_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); @@ -635,6 +659,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG) Master_DMA_And_Interrupt_Control); } #endif + + comedi_spin_unlock_irqrestore(&dev->spinlock, flags_dev); + return IRQ_HANDLED; } @@ -1234,6 +1261,7 @@ static int nidio_attach(comedi_device * dev, 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));