staging: comedi: addi_apci_3120: DMA requires an interrupt
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Mon, 20 Oct 2014 18:34:08 +0000 (11:34 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2014 07:58:35 +0000 (15:58 +0800)
An interrupt is required for DMA to work.

Factor out the DMA buffer allocation from the (*auto_attach) and only
allocate the buffers if the interrupt is available.

For aesthetics, also factor the DMA buffer free from the (*detach).

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/addi_apci_3120.c

index 2f0b642cfbfff47b99ce51820c5e52b5aefec077..08ac390edc3fb4e18e166d0acec025fa12c27e8b 100644 (file)
@@ -61,6 +61,51 @@ struct apci3120_private {
 
 #include "addi-data/hwdrv_apci3120.c"
 
+static void apci3120_dma_alloc(struct comedi_device *dev)
+{
+       struct apci3120_private *devpriv = dev->private;
+       int order;
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               for (order = 2; order >= 0; order--) {
+                       devpriv->ul_DmaBufferVirtual[i] =
+                           dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order,
+                                              &devpriv->ul_DmaBufferHw[i],
+                                              GFP_KERNEL);
+
+                       if (devpriv->ul_DmaBufferVirtual[i])
+                               break;
+               }
+               if (!devpriv->ul_DmaBufferVirtual[i])
+                       break;
+               devpriv->ui_DmaBufferSize[i] = PAGE_SIZE << order;
+
+               if (i == 0)
+                       devpriv->us_UseDma = 1;
+               if (i == 1)
+                       devpriv->b_DmaDoubleBuffer = 1;
+       }
+}
+
+static void apci3120_dma_free(struct comedi_device *dev)
+{
+       struct apci3120_private *devpriv = dev->private;
+       int i;
+
+       if (!devpriv)
+               return;
+
+       for (i = 0; i < 2; i++) {
+               if (devpriv->ul_DmaBufferVirtual[i]) {
+                       dma_free_coherent(dev->hw_dev,
+                                         devpriv->ui_DmaBufferSize[i],
+                                         devpriv->ul_DmaBufferVirtual[i],
+                                         devpriv->ul_DmaBufferHw[i]);
+               }
+       }
+}
+
 static int apci3120_auto_attach(struct comedi_device *dev,
                                unsigned long context)
 {
@@ -68,7 +113,7 @@ static int apci3120_auto_attach(struct comedi_device *dev,
        const struct apci3120_board *this_board = NULL;
        struct apci3120_private *devpriv;
        struct comedi_subdevice *s;
-       int ret, order, i;
+       int ret;
 
        if (context < ARRAY_SIZE(apci3120_boardtypes))
                this_board = &apci3120_boardtypes[context];
@@ -95,30 +140,12 @@ static int apci3120_auto_attach(struct comedi_device *dev,
        if (pcidev->irq > 0) {
                ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
                                  dev->board_name, dev);
-               if (ret == 0)
+               if (ret == 0) {
                        dev->irq = pcidev->irq;
-       }
-
-       /* Allocate DMA buffers */
-       for (i = 0; i < 2; i++) {
-               for (order = 2; order >= 0; order--) {
-                       devpriv->ul_DmaBufferVirtual[i] =
-                           dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order,
-                                              &devpriv->ul_DmaBufferHw[i],
-                                              GFP_KERNEL);
 
-                       if (devpriv->ul_DmaBufferVirtual[i])
-                               break;
+                       apci3120_dma_alloc(dev);
                }
-               if (!devpriv->ul_DmaBufferVirtual[i])
-                       break;
-               devpriv->ui_DmaBufferSize[i] = PAGE_SIZE << order;
        }
-       if (devpriv->ul_DmaBufferVirtual[0])
-               devpriv->us_UseDma = 1;
-
-       if (devpriv->ul_DmaBufferVirtual[1])
-               devpriv->b_DmaDoubleBuffer = 1;
 
        ret = comedi_alloc_subdevices(dev, 5);
        if (ret)
@@ -193,24 +220,10 @@ static int apci3120_auto_attach(struct comedi_device *dev,
 
 static void apci3120_detach(struct comedi_device *dev)
 {
-       struct apci3120_private *devpriv = dev->private;
-
        if (dev->iobase)
                apci3120_reset(dev);
        comedi_pci_detach(dev);
-       if (devpriv) {
-               unsigned int i;
-
-               for (i = 0; i < 2; i++) {
-                       if (devpriv->ul_DmaBufferVirtual[i]) {
-                               dma_free_coherent(dev->hw_dev,
-                                                 devpriv->ui_DmaBufferSize[i],
-                                                 devpriv->
-                                                 ul_DmaBufferVirtual[i],
-                                                 devpriv->ul_DmaBufferHw[i]);
-                       }
-               }
-       }
+       apci3120_dma_free(dev);
 }
 
 static struct comedi_driver apci3120_driver = {