staging: comedi: ni_labpc: migrate DMA channel init & free
authorIan Abbott <abbotti@mev.co.uk>
Fri, 28 Jun 2013 16:09:20 +0000 (17:09 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2013 21:27:51 +0000 (14:27 -0700)
Migrate the code for requesting an ISA DMA channel and a DMA buffer, and
the code for freeing them into two new functions in the
"ni_labpc_isadma" module: `labpc_init_dma_chan()` and
`labpc_free_dma_chan()`.  Dummy inline functions are provided in
"ni_labpc_isadma.h" if the "ni_labpc_isadma" module is not being built.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/comedi/drivers/ni_labpc_isadma.c
drivers/staging/comedi/drivers/ni_labpc_isadma.h

index d1d22a19f022a14bcfac8a4f046c8b2923888206..ab1773e1fbccb1e80955af3439a2e09b32ef6a66 100644 (file)
@@ -1708,31 +1708,8 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        if (ret)
                return ret;
 
-#ifdef CONFIG_ISA_DMA_API
-       if (dev->irq && (dma_chan == 1 || dma_chan == 3)) {
-               void *dma_buffer = kmalloc(dma_buffer_size,
-                                          GFP_KERNEL | GFP_DMA);
-
-               if (dma_buffer) {
-                       ret = request_dma(dma_chan, dev->board_name);
-                       if (ret == 0) {
-                               unsigned long dma_flags;
-
-                               devpriv->dma_buffer = dma_buffer;
-                               devpriv->dma_chan = dma_chan;
-                               devpriv->dma_addr =
-                                       virt_to_bus(devpriv->dma_buffer);
-
-                               dma_flags = claim_dma_lock();
-                               disable_dma(devpriv->dma_chan);
-                               set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
-                               release_dma_lock(dma_flags);
-                       } else {
-                               kfree(dma_buffer);
-                       }
-               }
-       }
-#endif
+       if (dev->irq)
+               labpc_init_dma_chan(dev, dma_chan);
 
        return 0;
 }
@@ -1741,11 +1718,9 @@ static void labpc_detach(struct comedi_device *dev)
 {
        struct labpc_private *devpriv = dev->private;
 
-       if (devpriv) {
-               kfree(devpriv->dma_buffer);
-               if (devpriv->dma_chan)
-                       free_dma(devpriv->dma_chan);
-       }
+       if (devpriv)
+               labpc_free_dma_chan(dev);
+
        comedi_legacy_detach(dev);
 }
 
index 586ea54b8d79b99c10907265d230084de1a3e97f..e6c8437f573c7d143174261dd79859a2f1ae3e56 100644 (file)
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
+#include "../comedidev.h"
 
+#include <asm/dma.h>
+
+#include "ni_labpc.h"
 #include "ni_labpc_isadma.h"
 
+/* size in bytes of dma buffer */
+static const int dma_buffer_size = 0xff00;
+
+int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan)
+{
+       struct labpc_private *devpriv = dev->private;
+       void *dma_buffer;
+       unsigned long dma_flags;
+       int ret;
+
+       if (dma_chan != 1 && dma_chan != 3)
+               return -EINVAL;
+
+       dma_buffer = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
+       if (!dma_buffer)
+               return -ENOMEM;
+
+       ret = request_dma(dma_chan, dev->board_name);
+       if (ret) {
+               kfree(dma_buffer);
+               return ret;
+       }
+
+       devpriv->dma_buffer = dma_buffer;
+       devpriv->dma_chan = dma_chan;
+       devpriv->dma_addr = virt_to_bus(devpriv->dma_buffer);
+
+       dma_flags = claim_dma_lock();
+       disable_dma(devpriv->dma_chan);
+       set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
+       release_dma_lock(dma_flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(labpc_init_dma_chan);
+
+void labpc_free_dma_chan(struct comedi_device *dev)
+{
+       struct labpc_private *devpriv = dev->private;
+
+       kfree(devpriv->dma_buffer);
+       devpriv->dma_buffer = NULL;
+       if (devpriv->dma_chan) {
+               free_dma(devpriv->dma_chan);
+               devpriv->dma_chan = 0;
+       }
+}
+EXPORT_SYMBOL_GPL(labpc_free_dma_chan);
+
 static int __init ni_labpc_isadma_init_module(void)
 {
        return 0;
index ac644f0d9fc95cd76149b6e0d0036326969393aa..144f4bafdbd1b61e3b369fe6fc50b6da1956867d 100644 (file)
@@ -9,8 +9,21 @@
 
 #if NI_LABPC_HAVE_ISA_DMA
 
+int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan);
+void labpc_free_dma_chan(struct comedi_device *dev);
+
 #else
 
+static inline int labpc_init_dma_chan(struct comedi_device *dev,
+                                     unsigned int dma_chan)
+{
+       return -ENOTSUPP;
+}
+
+static inline void labpc_free_dma_chan(struct comedi_device *dev)
+{
+}
+
 #endif
 
 #endif /* _NI_LABPC_ISADMA_H */