From 1b90779b238a8554a465fb99b3828a9e0500ff2a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:08 -0700 Subject: [PATCH] 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 Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 85 ++++++++++++++----------- 1 file 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 2f0b642..08ac390 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 = { -- 2.7.4