staging: comedi: ni_mio_common: tidy up mite dma channel requests
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Thu, 14 Apr 2016 16:57:50 +0000 (09:57 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Apr 2016 05:17:28 +0000 (22:17 -0700)
Tidy up the functions that request the mite dma channels by absorbing the
inline helper functions that call ni_set_bitfield() to set the channel
selection bits.

Add support for the NI_M_CDIO_DMA_SEL_REG register to ni_set_bitfield()
so that all the soft_reg_copy_lock spinlocking is done in one place.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/ni_mio_common.c

index 7a326058965c0de7427924c93fa455a100a98c81..231cd2c3b6eb55286e14ae5a816751b14d80d9a2 100644 (file)
@@ -556,6 +556,11 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
                devpriv->g0_g1_select_reg |= bit_values & bit_mask;
                ni_writeb(dev, devpriv->g0_g1_select_reg, reg);
                break;
+       case NI_M_CDIO_DMA_SEL_REG:
+               devpriv->cdio_dma_select_reg &= ~bit_mask;
+               devpriv->cdio_dma_select_reg |= bit_values & bit_mask;
+               ni_writeb(dev, devpriv->cdio_dma_select_reg, reg);
+               break;
        default:
                dev_err(dev->class_dev, "called with invalid register %d\n",
                        reg);
@@ -579,45 +584,16 @@ static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel)
        return 0;
 }
 
-static inline void ni_set_ai_dma_channel(struct comedi_device *dev,
-                                        unsigned channel)
-{
-       unsigned bits = ni_stc_dma_channel_select_bitfield(channel);
-
-       ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
-                       NI_E_DMA_AI_SEL_MASK, NI_E_DMA_AI_SEL(bits));
-}
-
 static inline void ni_set_ai_dma_no_channel(struct comedi_device *dev)
 {
        ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, NI_E_DMA_AI_SEL_MASK, 0);
 }
 
-static inline void ni_set_ao_dma_channel(struct comedi_device *dev,
-                                        unsigned channel)
-{
-       unsigned bits = ni_stc_dma_channel_select_bitfield(channel);
-
-       ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
-                       NI_E_DMA_AO_SEL_MASK, NI_E_DMA_AO_SEL(bits));
-}
-
 static inline void ni_set_ao_dma_no_channel(struct comedi_device *dev)
 {
        ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, NI_E_DMA_AO_SEL_MASK, 0);
 }
 
-static inline void ni_set_gpct_dma_channel(struct comedi_device *dev,
-                                          unsigned gpct_index,
-                                          unsigned channel)
-{
-       unsigned bits = ni_stc_dma_channel_select_bitfield(channel);
-
-       ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG,
-                       NI_E_DMA_G0_G1_SEL_MASK(gpct_index),
-                       NI_E_DMA_G0_G1_SEL(gpct_index, bits));
-}
-
 static inline void ni_set_gpct_dma_no_channel(struct comedi_device *dev,
                                              unsigned gpct_index)
 {
@@ -625,56 +601,34 @@ static inline void ni_set_gpct_dma_no_channel(struct comedi_device *dev,
                        NI_E_DMA_G0_G1_SEL_MASK(gpct_index), 0);
 }
 
-static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
-                                         unsigned mite_channel)
-{
-       struct ni_private *devpriv = dev->private;
-       unsigned long flags;
-       unsigned bits;
-
-       spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
-       devpriv->cdio_dma_select_reg &= ~NI_M_CDIO_DMA_SEL_CDO_MASK;
-       /*
-        * XXX just guessing ni_stc_dma_channel_select_bitfield()
-        * returns the right bits, under the assumption the cdio dma
-        * selection works just like ai/ao/gpct.
-        * Definitely works for dma channels 0 and 1.
-        */
-       bits = ni_stc_dma_channel_select_bitfield(mite_channel);
-       devpriv->cdio_dma_select_reg |= NI_M_CDIO_DMA_SEL_CDO(bits);
-       ni_writeb(dev, devpriv->cdio_dma_select_reg, NI_M_CDIO_DMA_SEL_REG);
-       mmiowb();
-       spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
-}
-
 static inline void ni_set_cdo_dma_no_channel(struct comedi_device *dev)
 {
-       struct ni_private *devpriv = dev->private;
-       unsigned long flags;
-
-       spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
-       devpriv->cdio_dma_select_reg &= ~NI_M_CDIO_DMA_SEL_CDO_MASK;
-       ni_writeb(dev, devpriv->cdio_dma_select_reg, NI_M_CDIO_DMA_SEL_REG);
-       mmiowb();
-       spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
+       ni_set_bitfield(dev, NI_M_CDIO_DMA_SEL_REG,
+                       NI_M_CDIO_DMA_SEL_CDO_MASK, 0);
 }
 
 static int ni_request_ai_mite_channel(struct comedi_device *dev)
 {
        struct ni_private *devpriv = dev->private;
+       struct mite_channel *mite_chan;
        unsigned long flags;
+       unsigned int bits;
 
        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
-       devpriv->ai_mite_chan =
-           mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
-       if (!devpriv->ai_mite_chan) {
+       mite_chan = mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
+       if (!mite_chan) {
                spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
                dev_err(dev->class_dev,
                        "failed to reserve mite dma channel for analog input\n");
                return -EBUSY;
        }
-       devpriv->ai_mite_chan->dir = COMEDI_INPUT;
-       ni_set_ai_dma_channel(dev, devpriv->ai_mite_chan->channel);
+       mite_chan->dir = COMEDI_INPUT;
+       devpriv->ai_mite_chan = mite_chan;
+
+       bits = ni_stc_dma_channel_select_bitfield(mite_chan->channel);
+       ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
+                       NI_E_DMA_AI_SEL_MASK, NI_E_DMA_AI_SEL(bits));
+
        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
        return 0;
 }
@@ -682,19 +636,25 @@ static int ni_request_ai_mite_channel(struct comedi_device *dev)
 static int ni_request_ao_mite_channel(struct comedi_device *dev)
 {
        struct ni_private *devpriv = dev->private;
+       struct mite_channel *mite_chan;
        unsigned long flags;
+       unsigned int bits;
 
        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
-       devpriv->ao_mite_chan =
-           mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
-       if (!devpriv->ao_mite_chan) {
+       mite_chan = mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
+       if (!mite_chan) {
                spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
                dev_err(dev->class_dev,
                        "failed to reserve mite dma channel for analog outut\n");
                return -EBUSY;
        }
-       devpriv->ao_mite_chan->dir = COMEDI_OUTPUT;
-       ni_set_ao_dma_channel(dev, devpriv->ao_mite_chan->channel);
+       mite_chan->dir = COMEDI_OUTPUT;
+       devpriv->ao_mite_chan = mite_chan;
+
+       bits = ni_stc_dma_channel_select_bitfield(mite_chan->channel);
+       ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
+                       NI_E_DMA_AO_SEL_MASK, NI_E_DMA_AO_SEL(bits));
+
        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
        return 0;
 }
@@ -704,13 +664,14 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev,
                                        enum comedi_io_direction direction)
 {
        struct ni_private *devpriv = dev->private;
-       unsigned long flags;
+       struct ni_gpct *counter = &devpriv->counter_dev->counters[gpct_index];
        struct mite_channel *mite_chan;
+       unsigned long flags;
+       unsigned int bits;
 
        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
-       mite_chan =
-           mite_request_channel(devpriv->mite,
-                                devpriv->gpct_mite_ring[gpct_index]);
+       mite_chan = mite_request_channel(devpriv->mite,
+                                        devpriv->gpct_mite_ring[gpct_index]);
        if (!mite_chan) {
                spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
                dev_err(dev->class_dev,
@@ -718,9 +679,13 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev,
                return -EBUSY;
        }
        mite_chan->dir = direction;
-       ni_tio_set_mite_channel(&devpriv->counter_dev->counters[gpct_index],
-                               mite_chan);
-       ni_set_gpct_dma_channel(dev, gpct_index, mite_chan->channel);
+       ni_tio_set_mite_channel(counter, mite_chan);
+
+       bits = ni_stc_dma_channel_select_bitfield(mite_chan->channel);
+       ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG,
+                       NI_E_DMA_G0_G1_SEL_MASK(gpct_index),
+                       NI_E_DMA_G0_G1_SEL(gpct_index, bits));
+
        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
        return 0;
 }
@@ -731,19 +696,32 @@ static int ni_request_cdo_mite_channel(struct comedi_device *dev)
 {
 #ifdef PCIDMA
        struct ni_private *devpriv = dev->private;
+       struct mite_channel *mite_chan;
        unsigned long flags;
+       unsigned int bits;
 
        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
-       devpriv->cdo_mite_chan =
-           mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
-       if (!devpriv->cdo_mite_chan) {
+       mite_chan = mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
+       if (!mite_chan) {
                spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
                dev_err(dev->class_dev,
                        "failed to reserve mite dma channel for correlated digital output\n");
                return -EBUSY;
        }
-       devpriv->cdo_mite_chan->dir = COMEDI_OUTPUT;
-       ni_set_cdo_dma_channel(dev, devpriv->cdo_mite_chan->channel);
+       mite_chan->dir = COMEDI_OUTPUT;
+       devpriv->cdo_mite_chan = mite_chan;
+
+       /*
+        * XXX just guessing ni_stc_dma_channel_select_bitfield()
+        * returns the right bits, under the assumption the cdio dma
+        * selection works just like ai/ao/gpct.
+        * Definitely works for dma channels 0 and 1.
+        */
+       bits = ni_stc_dma_channel_select_bitfield(mite_chan->channel);
+       ni_set_bitfield(dev, NI_M_CDIO_DMA_SEL_REG,
+                       NI_M_CDIO_DMA_SEL_CDO_MASK,
+                       NI_M_CDIO_DMA_SEL_CDO(bits));
+
        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 #endif /*  PCIDMA */
        return 0;