summaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/drivers/pcl812.c
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2015-01-12 10:56:05 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-17 14:25:21 -0800
commit075400af763d1a16bbbaa7e5963b9ede9765e2ad (patch)
treea80040cee0caffcc66fc8653f7f6e33632dd162b /drivers/staging/comedi/drivers/pcl812.c
parentceb41be712b68fac4ac834120a80fc3cb8e5ac37 (diff)
staging: comedi: pcl812: introduce pcl812_alloc_dma()
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@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/drivers/pcl812.c')
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index ac243ca5e0f8..38cf14efdeb9 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -1192,6 +1192,34 @@ static void pcl812_set_ai_range_table(struct comedi_device *dev,
}
}
+static int pcl812_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
+{
+ struct pcl812_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 = 1; /* we want 8KB */
+ 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 pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcl812_board *board = dev->board_ptr;
@@ -1200,7 +1228,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int n_subdevices;
int subdev;
int ret;
- int i;
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
@@ -1218,30 +1245,10 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
/* 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 = 1; /* we want 8KB */
- 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 = pcl812_alloc_dma(dev, it->options[2]);
+ if (ret)
+ return ret;
}
/* differential analog inputs? */