[PATCH 17/37] staging: comedi: pcl818: introduce pcl818_alloc_dma()

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

 



DMA is optional with this driver. Introduce a helper function to request
the DMA channel and allocate the buffers. Don't fail the driver attach
if the user passed an invalid DMA channel or the channel cannot be
requested.

Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
Cc: Ian Abbott <abbotti@xxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/staging/comedi/drivers/pcl818.c | 57 ++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 8edea35..b25ff35 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -1054,13 +1054,40 @@ static void pcl818_set_ai_range_table(struct comedi_device *dev,
 	}
 }
 
+static int pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
+{
+	struct pcl818_private *devpriv = dev->private;
+	int i;
+
+	if (!(dma_chan == 3 || dma_chan == 1))
+		return 0;
+
+	if (request_dma(dma_chan, dev->board_name))
+		return 0;
+	devpriv->dma = dma_chan;
+
+	devpriv->dmapages = 2;	/* we need 16KB */
+	devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
+
+	for (i = 0; i < 2; i++) {
+		unsigned long dmabuf;
+
+		dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
+		if (!dmabuf)
+			return -ENOMEM;
+
+		devpriv->dmabuf[i] = dmabuf;
+		devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
+	}
+	return 0;
+}
+
 static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	const struct pcl818_board *board = dev->board_ptr;
 	struct pcl818_private *devpriv;
 	struct comedi_subdevice *s;
 	int ret;
-	int i;
 
 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 	if (!devpriv)
@@ -1084,30 +1111,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		devpriv->usefifo = 1;
 
 	/* we need an IRQ to do DMA on channel 3 or 1 */
-	if (dev->irq && board->has_dma &&
-	    (it->options[2] == 3 || it->options[2] == 1)) {
-		ret = request_dma(it->options[2], dev->board_name);
-		if (ret) {
-			dev_err(dev->class_dev,
-				"unable to request DMA channel %d\n",
-				it->options[2]);
-			return -EBUSY;
-		}
-		devpriv->dma = it->options[2];
-
-		devpriv->dmapages = 2;	/* we need 16KB */
-		devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
-
-		for (i = 0; i < 2; i++) {
-			unsigned long dmabuf;
-
-			dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
-			if (!dmabuf)
-				return -ENOMEM;
-
-			devpriv->dmabuf[i] = dmabuf;
-			devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
-		}
+	if (dev->irq && board->has_dma) {
+		ret = pcl818_alloc_dma(dev, it->options[2]);
+		if (ret)
+			return ret;
 	}
 
 	ret = comedi_alloc_subdevices(dev, 4);
-- 
2.0.3

_______________________________________________
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