~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/core/isadma.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  *  ISA DMA support functions
  4  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  5  */
  6 
  7 /*
  8  * Defining following add some delay. Maybe this helps for some broken
  9  * ISA DMA controllers.
 10  */
 11 
 12 #undef HAVE_REALLY_SLOW_DMA_CONTROLLER
 13 
 14 #include <linux/export.h>
 15 #include <linux/isa-dma.h>
 16 #include <sound/core.h>
 17 
 18 /**
 19  * snd_dma_program - program an ISA DMA transfer
 20  * @dma: the dma number
 21  * @addr: the physical address of the buffer
 22  * @size: the DMA transfer size
 23  * @mode: the DMA transfer mode, DMA_MODE_XXX
 24  *
 25  * Programs an ISA DMA transfer for the given buffer.
 26  */
 27 void snd_dma_program(unsigned long dma,
 28                      unsigned long addr, unsigned int size,
 29                      unsigned short mode)
 30 {
 31         unsigned long flags;
 32 
 33         flags = claim_dma_lock();
 34         disable_dma(dma);
 35         clear_dma_ff(dma);
 36         set_dma_mode(dma, mode);
 37         set_dma_addr(dma, addr);
 38         set_dma_count(dma, size);
 39         if (!(mode & DMA_MODE_NO_ENABLE))
 40                 enable_dma(dma);
 41         release_dma_lock(flags);
 42 }
 43 EXPORT_SYMBOL(snd_dma_program);
 44 
 45 /**
 46  * snd_dma_disable - stop the ISA DMA transfer
 47  * @dma: the dma number
 48  *
 49  * Stops the ISA DMA transfer.
 50  */
 51 void snd_dma_disable(unsigned long dma)
 52 {
 53         unsigned long flags;
 54 
 55         flags = claim_dma_lock();
 56         clear_dma_ff(dma);
 57         disable_dma(dma);
 58         release_dma_lock(flags);
 59 }
 60 EXPORT_SYMBOL(snd_dma_disable);
 61 
 62 /**
 63  * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes
 64  * @dma: the dma number
 65  * @size: the dma transfer size
 66  *
 67  * Return: The current pointer in DMA transfer buffer in bytes.
 68  */
 69 unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
 70 {
 71         unsigned long flags;
 72         unsigned int result, result1;
 73 
 74         flags = claim_dma_lock();
 75         clear_dma_ff(dma);
 76         if (!isa_dma_bridge_buggy)
 77                 disable_dma(dma);
 78         result = get_dma_residue(dma);
 79         /*
 80          * HACK - read the counter again and choose higher value in order to
 81          * avoid reading during counter lower byte roll over if the
 82          * isa_dma_bridge_buggy is set.
 83          */
 84         result1 = get_dma_residue(dma);
 85         if (!isa_dma_bridge_buggy)
 86                 enable_dma(dma);
 87         release_dma_lock(flags);
 88         if (unlikely(result < result1))
 89                 result = result1;
 90 #ifdef CONFIG_SND_DEBUG
 91         if (result > size)
 92                 pr_err("ALSA: pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
 93 #endif
 94         if (result >= size || result == 0)
 95                 return 0;
 96         else
 97                 return size - result;
 98 }
 99 EXPORT_SYMBOL(snd_dma_pointer);
100 
101 struct snd_dma_data {
102         int dma;
103 };
104 
105 static void __snd_release_dma(struct device *dev, void *data)
106 {
107         struct snd_dma_data *p = data;
108 
109         snd_dma_disable(p->dma);
110         free_dma(p->dma);
111 }
112 
113 /**
114  * snd_devm_request_dma - the managed version of request_dma()
115  * @dev: the device pointer
116  * @dma: the dma number
117  * @name: the name string of the requester
118  *
119  * The requested DMA will be automatically released at unbinding via devres.
120  *
121  * Return: zero on success, or a negative error code
122  */
123 int snd_devm_request_dma(struct device *dev, int dma, const char *name)
124 {
125         struct snd_dma_data *p;
126 
127         if (request_dma(dma, name))
128                 return -EBUSY;
129         p = devres_alloc(__snd_release_dma, sizeof(*p), GFP_KERNEL);
130         if (!p) {
131                 free_dma(dma);
132                 return -ENOMEM;
133         }
134         p->dma = dma;
135         devres_add(dev, p);
136         return 0;
137 }
138 EXPORT_SYMBOL_GPL(snd_devm_request_dma);
139 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php