From 86aff4bb11eb721b9be40dcd51f7571fb00edcde Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 28 Jun 2013 17:09:20 +0100 Subject: [PATCH] staging: comedi: ni_labpc: migrate DMA channel init & free Migrate the code for requesting an ISA DMA channel and a DMA buffer, and the code for freeing them into two new functions in the "ni_labpc_isadma" module: `labpc_init_dma_chan()` and `labpc_free_dma_chan()`. Dummy inline functions are provided in "ni_labpc_isadma.h" if the "ni_labpc_isadma" module is not being built. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.c | 35 +++------------ drivers/staging/comedi/drivers/ni_labpc_isadma.c | 54 ++++++++++++++++++++++++ drivers/staging/comedi/drivers/ni_labpc_isadma.h | 13 ++++++ 3 files changed, 72 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index d1d22a1..ab1773e 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1708,31 +1708,8 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; -#ifdef CONFIG_ISA_DMA_API - if (dev->irq && (dma_chan == 1 || dma_chan == 3)) { - void *dma_buffer = kmalloc(dma_buffer_size, - GFP_KERNEL | GFP_DMA); - - if (dma_buffer) { - ret = request_dma(dma_chan, dev->board_name); - if (ret == 0) { - unsigned long dma_flags; - - devpriv->dma_buffer = dma_buffer; - devpriv->dma_chan = dma_chan; - devpriv->dma_addr = - virt_to_bus(devpriv->dma_buffer); - - dma_flags = claim_dma_lock(); - disable_dma(devpriv->dma_chan); - set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); - release_dma_lock(dma_flags); - } else { - kfree(dma_buffer); - } - } - } -#endif + if (dev->irq) + labpc_init_dma_chan(dev, dma_chan); return 0; } @@ -1741,11 +1718,9 @@ static void labpc_detach(struct comedi_device *dev) { struct labpc_private *devpriv = dev->private; - if (devpriv) { - kfree(devpriv->dma_buffer); - if (devpriv->dma_chan) - free_dma(devpriv->dma_chan); - } + if (devpriv) + labpc_free_dma_chan(dev); + comedi_legacy_detach(dev); } diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c index 586ea54..e6c8437 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c @@ -18,9 +18,63 @@ */ #include +#include +#include "../comedidev.h" +#include + +#include "ni_labpc.h" #include "ni_labpc_isadma.h" +/* size in bytes of dma buffer */ +static const int dma_buffer_size = 0xff00; + +int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan) +{ + struct labpc_private *devpriv = dev->private; + void *dma_buffer; + unsigned long dma_flags; + int ret; + + if (dma_chan != 1 && dma_chan != 3) + return -EINVAL; + + dma_buffer = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA); + if (!dma_buffer) + return -ENOMEM; + + ret = request_dma(dma_chan, dev->board_name); + if (ret) { + kfree(dma_buffer); + return ret; + } + + devpriv->dma_buffer = dma_buffer; + devpriv->dma_chan = dma_chan; + devpriv->dma_addr = virt_to_bus(devpriv->dma_buffer); + + dma_flags = claim_dma_lock(); + disable_dma(devpriv->dma_chan); + set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); + release_dma_lock(dma_flags); + + return 0; +} +EXPORT_SYMBOL_GPL(labpc_init_dma_chan); + +void labpc_free_dma_chan(struct comedi_device *dev) +{ + struct labpc_private *devpriv = dev->private; + + kfree(devpriv->dma_buffer); + devpriv->dma_buffer = NULL; + if (devpriv->dma_chan) { + free_dma(devpriv->dma_chan); + devpriv->dma_chan = 0; + } +} +EXPORT_SYMBOL_GPL(labpc_free_dma_chan); + static int __init ni_labpc_isadma_init_module(void) { return 0; diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.h b/drivers/staging/comedi/drivers/ni_labpc_isadma.h index ac644f0..144f4ba 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.h +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.h @@ -9,8 +9,21 @@ #if NI_LABPC_HAVE_ISA_DMA +int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan); +void labpc_free_dma_chan(struct comedi_device *dev); + #else +static inline int labpc_init_dma_chan(struct comedi_device *dev, + unsigned int dma_chan) +{ + return -ENOTSUPP; +} + +static inline void labpc_free_dma_chan(struct comedi_device *dev) +{ +} + #endif #endif /* _NI_LABPC_ISADMA_H */ -- 2.7.4