summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2014-10-20 11:34:08 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-10-29 15:58:35 +0800
commit1b90779b238a8554a465fb99b3828a9e0500ff2a (patch)
tree77364b4ddca82fc861862c19c918e17ad991d849
parentc3e1715890b2c3009155e8865d5c6d649a16a4b5 (diff)
staging: comedi: addi_apci_3120: DMA requires an interrupt
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>
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
index 2f0b642cfbff..08ac390edc3f 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3120.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -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 = {