Commit 1b90779b authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c3e17158
...@@ -61,6 +61,51 @@ struct apci3120_private { ...@@ -61,6 +61,51 @@ struct apci3120_private {
#include "addi-data/hwdrv_apci3120.c" #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, static int apci3120_auto_attach(struct comedi_device *dev,
unsigned long context) unsigned long context)
{ {
...@@ -68,7 +113,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, ...@@ -68,7 +113,7 @@ static int apci3120_auto_attach(struct comedi_device *dev,
const struct apci3120_board *this_board = NULL; const struct apci3120_board *this_board = NULL;
struct apci3120_private *devpriv; struct apci3120_private *devpriv;
struct comedi_subdevice *s; struct comedi_subdevice *s;
int ret, order, i; int ret;
if (context < ARRAY_SIZE(apci3120_boardtypes)) if (context < ARRAY_SIZE(apci3120_boardtypes))
this_board = &apci3120_boardtypes[context]; this_board = &apci3120_boardtypes[context];
...@@ -95,30 +140,12 @@ static int apci3120_auto_attach(struct comedi_device *dev, ...@@ -95,30 +140,12 @@ static int apci3120_auto_attach(struct comedi_device *dev,
if (pcidev->irq > 0) { if (pcidev->irq > 0) {
ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED, ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
dev->board_name, dev); dev->board_name, dev);
if (ret == 0) if (ret == 0) {
dev->irq = pcidev->irq; 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]) apci3120_dma_alloc(dev);
break;
} }
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); ret = comedi_alloc_subdevices(dev, 5);
if (ret) if (ret)
...@@ -193,24 +220,10 @@ static int apci3120_auto_attach(struct comedi_device *dev, ...@@ -193,24 +220,10 @@ static int apci3120_auto_attach(struct comedi_device *dev,
static void apci3120_detach(struct comedi_device *dev) static void apci3120_detach(struct comedi_device *dev)
{ {
struct apci3120_private *devpriv = dev->private;
if (dev->iobase) if (dev->iobase)
apci3120_reset(dev); apci3120_reset(dev);
comedi_pci_detach(dev); comedi_pci_detach(dev);
if (devpriv) { apci3120_dma_free(dev);
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]);
}
}
}
} }
static struct comedi_driver apci3120_driver = { static struct comedi_driver apci3120_driver = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment