diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/comedi_isadma.c')
-rw-r--r-- | drivers/staging/comedi/drivers/comedi_isadma.c | 267 |
1 files changed, 0 insertions, 267 deletions
diff --git a/drivers/staging/comedi/drivers/comedi_isadma.c b/drivers/staging/comedi/drivers/comedi_isadma.c deleted file mode 100644 index c729094298c2..000000000000 --- a/drivers/staging/comedi/drivers/comedi_isadma.c +++ /dev/null @@ -1,267 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * COMEDI ISA DMA support functions - * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com> - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/dma-mapping.h> -#include <asm/dma.h> - -#include "../comedidev.h" - -#include "comedi_isadma.h" - -/** - * comedi_isadma_program - program and enable an ISA DMA transfer - * @desc: the ISA DMA cookie to program and enable - */ -void comedi_isadma_program(struct comedi_isadma_desc *desc) -{ - unsigned long flags; - - flags = claim_dma_lock(); - clear_dma_ff(desc->chan); - set_dma_mode(desc->chan, desc->mode); - set_dma_addr(desc->chan, desc->hw_addr); - set_dma_count(desc->chan, desc->size); - enable_dma(desc->chan); - release_dma_lock(flags); -} -EXPORT_SYMBOL_GPL(comedi_isadma_program); - -/** - * comedi_isadma_disable - disable the ISA DMA channel - * @dma_chan: the DMA channel to disable - * - * Returns the residue (remaining bytes) left in the DMA transfer. - */ -unsigned int comedi_isadma_disable(unsigned int dma_chan) -{ - unsigned long flags; - unsigned int residue; - - flags = claim_dma_lock(); - disable_dma(dma_chan); - residue = get_dma_residue(dma_chan); - release_dma_lock(flags); - - return residue; -} -EXPORT_SYMBOL_GPL(comedi_isadma_disable); - -/** - * comedi_isadma_disable_on_sample - disable the ISA DMA channel - * @dma_chan: the DMA channel to disable - * @size: the sample size (in bytes) - * - * Returns the residue (remaining bytes) left in the DMA transfer. - */ -unsigned int comedi_isadma_disable_on_sample(unsigned int dma_chan, - unsigned int size) -{ - int stalled = 0; - unsigned long flags; - unsigned int residue; - unsigned int new_residue; - - residue = comedi_isadma_disable(dma_chan); - while (residue % size) { - /* residue is a partial sample, enable DMA to allow more data */ - flags = claim_dma_lock(); - enable_dma(dma_chan); - release_dma_lock(flags); - - udelay(2); - new_residue = comedi_isadma_disable(dma_chan); - - /* is DMA stalled? */ - if (new_residue == residue) { - stalled++; - if (stalled > 10) - break; - } else { - residue = new_residue; - stalled = 0; - } - } - return residue; -} -EXPORT_SYMBOL_GPL(comedi_isadma_disable_on_sample); - -/** - * comedi_isadma_poll - poll the current DMA transfer - * @dma: the ISA DMA to poll - * - * Returns the position (in bytes) of the current DMA transfer. - */ -unsigned int comedi_isadma_poll(struct comedi_isadma *dma) -{ - struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma]; - unsigned long flags; - unsigned int result; - unsigned int result1; - - flags = claim_dma_lock(); - clear_dma_ff(desc->chan); - if (!isa_dma_bridge_buggy) - disable_dma(desc->chan); - result = get_dma_residue(desc->chan); - /* - * Read the counter again and choose higher value in order to - * avoid reading during counter lower byte roll over if the - * isa_dma_bridge_buggy is set. - */ - result1 = get_dma_residue(desc->chan); - if (!isa_dma_bridge_buggy) - enable_dma(desc->chan); - release_dma_lock(flags); - - if (result < result1) - result = result1; - if (result >= desc->size || result == 0) - return 0; - return desc->size - result; -} -EXPORT_SYMBOL_GPL(comedi_isadma_poll); - -/** - * comedi_isadma_set_mode - set the ISA DMA transfer direction - * @desc: the ISA DMA cookie to set - * @dma_dir: the DMA direction - */ -void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir) -{ - desc->mode = (dma_dir == COMEDI_ISADMA_READ) ? DMA_MODE_READ - : DMA_MODE_WRITE; -} -EXPORT_SYMBOL_GPL(comedi_isadma_set_mode); - -/** - * comedi_isadma_alloc - allocate and initialize the ISA DMA - * @dev: comedi_device struct - * @n_desc: the number of cookies to allocate - * @dma_chan: DMA channel for the first cookie - * @dma_chan2: DMA channel for the second cookie - * @maxsize: the size of the buffer to allocate for each cookie - * @dma_dir: the DMA direction - * - * Returns the allocated and initialized ISA DMA or NULL if anything fails. - */ -struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev, - int n_desc, unsigned int dma_chan1, - unsigned int dma_chan2, - unsigned int maxsize, char dma_dir) -{ - struct comedi_isadma *dma = NULL; - struct comedi_isadma_desc *desc; - unsigned int dma_chans[2]; - int i; - - if (n_desc < 1 || n_desc > 2) - goto no_dma; - - dma = kzalloc(sizeof(*dma), GFP_KERNEL); - if (!dma) - goto no_dma; - - desc = kcalloc(n_desc, sizeof(*desc), GFP_KERNEL); - if (!desc) - goto no_dma; - dma->desc = desc; - dma->n_desc = n_desc; - if (dev->hw_dev) { - dma->dev = dev->hw_dev; - } else { - /* Fall back to using the "class" device. */ - if (!dev->class_dev) - goto no_dma; - /* Need 24-bit mask for ISA DMA. */ - if (dma_coerce_mask_and_coherent(dev->class_dev, - DMA_BIT_MASK(24))) { - goto no_dma; - } - dma->dev = dev->class_dev; - } - - dma_chans[0] = dma_chan1; - if (dma_chan2 == 0 || dma_chan2 == dma_chan1) - dma_chans[1] = dma_chan1; - else - dma_chans[1] = dma_chan2; - - if (request_dma(dma_chans[0], dev->board_name)) - goto no_dma; - dma->chan = dma_chans[0]; - if (dma_chans[1] != dma_chans[0]) { - if (request_dma(dma_chans[1], dev->board_name)) - goto no_dma; - } - dma->chan2 = dma_chans[1]; - - for (i = 0; i < n_desc; i++) { - desc = &dma->desc[i]; - desc->chan = dma_chans[i]; - desc->maxsize = maxsize; - desc->virt_addr = dma_alloc_coherent(dma->dev, desc->maxsize, - &desc->hw_addr, - GFP_KERNEL); - if (!desc->virt_addr) - goto no_dma; - comedi_isadma_set_mode(desc, dma_dir); - } - - return dma; - -no_dma: - comedi_isadma_free(dma); - return NULL; -} -EXPORT_SYMBOL_GPL(comedi_isadma_alloc); - -/** - * comedi_isadma_free - free the ISA DMA - * @dma: the ISA DMA to free - */ -void comedi_isadma_free(struct comedi_isadma *dma) -{ - struct comedi_isadma_desc *desc; - int i; - - if (!dma) - return; - - if (dma->desc) { - for (i = 0; i < dma->n_desc; i++) { - desc = &dma->desc[i]; - if (desc->virt_addr) - dma_free_coherent(dma->dev, desc->maxsize, - desc->virt_addr, - desc->hw_addr); - } - kfree(dma->desc); - } - if (dma->chan2 && dma->chan2 != dma->chan) - free_dma(dma->chan2); - if (dma->chan) - free_dma(dma->chan); - kfree(dma); -} -EXPORT_SYMBOL_GPL(comedi_isadma_free); - -static int __init comedi_isadma_init(void) -{ - return 0; -} -module_init(comedi_isadma_init); - -static void __exit comedi_isadma_exit(void) -{ -} -module_exit(comedi_isadma_exit); - -MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); -MODULE_DESCRIPTION("Comedi ISA DMA support"); -MODULE_LICENSE("GPL"); |