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 {
#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 = {
......
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