[PATCH 04/12] staging: comedi: ni_labpc: migrate DMA channel init & free

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 drivers/staging/comedi/drivers/ni_labpc.c        | 35 +++------------
 drivers/staging/comedi/drivers/ni_labpc_isadma.c | 54 ++++++++++++++++++++++++
 drivers/staging/comedi/drivers/ni_labpc_isadma.h | 13 ++++++
 3 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 41f1674..301b532 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -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);
 }
 
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
index 586ea54..e6c8437 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
@@ -18,9 +18,63 @@
  */
 
 #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;
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.h b/drivers/staging/comedi/drivers/ni_labpc_isadma.h
index ac644f0..144f4ba 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.h
+++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.h
@@ -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 */
-- 
1.8.2.1

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux