xref: /openbmc/linux/sound/core/memalloc.c (revision 423997ff)
1 /*
2  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3  *                   Takashi Iwai <tiwai@suse.de>
4  *
5  *  Generic memory allocators
6  *
7  *
8  *   This program is free software; you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  *
22  */
23 
24 #include <linux/slab.h>
25 #include <linux/mm.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/genalloc.h>
28 #ifdef CONFIG_X86
29 #include <asm/set_memory.h>
30 #endif
31 #include <sound/memalloc.h>
32 
33 /*
34  *
35  *  Bus-specific memory allocators
36  *
37  */
38 
39 #ifdef CONFIG_HAS_DMA
40 /* allocate the coherent DMA pages */
41 static void snd_malloc_dev_pages(struct snd_dma_buffer *dmab, size_t size)
42 {
43 	gfp_t gfp_flags;
44 
45 	gfp_flags = GFP_KERNEL
46 		| __GFP_COMP	/* compound page lets parts be mapped */
47 		| __GFP_NORETRY /* don't trigger OOM-killer */
48 		| __GFP_NOWARN; /* no stack trace print - this call is non-critical */
49 	dmab->area = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr,
50 					gfp_flags);
51 #ifdef CONFIG_X86
52 	if (dmab->area && dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
53 		set_memory_wc((unsigned long)dmab->area,
54 			      PAGE_ALIGN(size) >> PAGE_SHIFT);
55 #endif
56 }
57 
58 /* free the coherent DMA pages */
59 static void snd_free_dev_pages(struct snd_dma_buffer *dmab)
60 {
61 #ifdef CONFIG_X86
62 	if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
63 		set_memory_wb((unsigned long)dmab->area,
64 			      PAGE_ALIGN(dmab->bytes) >> PAGE_SHIFT);
65 #endif
66 	dma_free_coherent(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
67 }
68 
69 #ifdef CONFIG_GENERIC_ALLOCATOR
70 /**
71  * snd_malloc_dev_iram - allocate memory from on-chip internal ram
72  * @dmab: buffer allocation record to store the allocated data
73  * @size: number of bytes to allocate from the iram
74  *
75  * This function requires iram phandle provided via of_node
76  */
77 static void snd_malloc_dev_iram(struct snd_dma_buffer *dmab, size_t size)
78 {
79 	struct device *dev = dmab->dev.dev;
80 	struct gen_pool *pool = NULL;
81 
82 	dmab->area = NULL;
83 	dmab->addr = 0;
84 
85 	if (dev->of_node)
86 		pool = of_gen_pool_get(dev->of_node, "iram", 0);
87 
88 	if (!pool)
89 		return;
90 
91 	/* Assign the pool into private_data field */
92 	dmab->private_data = pool;
93 
94 	dmab->area = gen_pool_dma_alloc(pool, size, &dmab->addr);
95 }
96 
97 /**
98  * snd_free_dev_iram - free allocated specific memory from on-chip internal ram
99  * @dmab: buffer allocation record to store the allocated data
100  */
101 static void snd_free_dev_iram(struct snd_dma_buffer *dmab)
102 {
103 	struct gen_pool *pool = dmab->private_data;
104 
105 	if (pool && dmab->area)
106 		gen_pool_free(pool, (unsigned long)dmab->area, dmab->bytes);
107 }
108 #endif /* CONFIG_GENERIC_ALLOCATOR */
109 #endif /* CONFIG_HAS_DMA */
110 
111 /*
112  *
113  *  ALSA generic memory management
114  *
115  */
116 
117 
118 /**
119  * snd_dma_alloc_pages - allocate the buffer area according to the given type
120  * @type: the DMA buffer type
121  * @device: the device pointer
122  * @size: the buffer size to allocate
123  * @dmab: buffer allocation record to store the allocated data
124  *
125  * Calls the memory-allocator function for the corresponding
126  * buffer type.
127  *
128  * Return: Zero if the buffer with the given size is allocated successfully,
129  * otherwise a negative value on error.
130  */
131 int snd_dma_alloc_pages(int type, struct device *device, size_t size,
132 			struct snd_dma_buffer *dmab)
133 {
134 	if (WARN_ON(!size))
135 		return -ENXIO;
136 	if (WARN_ON(!dmab))
137 		return -ENXIO;
138 	if (WARN_ON(!device))
139 		return -EINVAL;
140 
141 	dmab->dev.type = type;
142 	dmab->dev.dev = device;
143 	dmab->bytes = 0;
144 	switch (type) {
145 	case SNDRV_DMA_TYPE_CONTINUOUS:
146 		dmab->area = alloc_pages_exact(size,
147 					       (__force gfp_t)(unsigned long)device);
148 		dmab->addr = 0;
149 		break;
150 #ifdef CONFIG_HAS_DMA
151 #ifdef CONFIG_GENERIC_ALLOCATOR
152 	case SNDRV_DMA_TYPE_DEV_IRAM:
153 		snd_malloc_dev_iram(dmab, size);
154 		if (dmab->area)
155 			break;
156 		/* Internal memory might have limited size and no enough space,
157 		 * so if we fail to malloc, try to fetch memory traditionally.
158 		 */
159 		dmab->dev.type = SNDRV_DMA_TYPE_DEV;
160 #endif /* CONFIG_GENERIC_ALLOCATOR */
161 		/* fall through */
162 	case SNDRV_DMA_TYPE_DEV:
163 	case SNDRV_DMA_TYPE_DEV_UC:
164 		snd_malloc_dev_pages(dmab, size);
165 		break;
166 #endif
167 #ifdef CONFIG_SND_DMA_SGBUF
168 	case SNDRV_DMA_TYPE_DEV_SG:
169 	case SNDRV_DMA_TYPE_DEV_UC_SG:
170 		snd_malloc_sgbuf_pages(device, size, dmab, NULL);
171 		break;
172 #endif
173 	default:
174 		pr_err("snd-malloc: invalid device type %d\n", type);
175 		dmab->area = NULL;
176 		dmab->addr = 0;
177 		return -ENXIO;
178 	}
179 	if (! dmab->area)
180 		return -ENOMEM;
181 	dmab->bytes = size;
182 	return 0;
183 }
184 EXPORT_SYMBOL(snd_dma_alloc_pages);
185 
186 /**
187  * snd_dma_alloc_pages_fallback - allocate the buffer area according to the given type with fallback
188  * @type: the DMA buffer type
189  * @device: the device pointer
190  * @size: the buffer size to allocate
191  * @dmab: buffer allocation record to store the allocated data
192  *
193  * Calls the memory-allocator function for the corresponding
194  * buffer type.  When no space is left, this function reduces the size and
195  * tries to allocate again.  The size actually allocated is stored in
196  * res_size argument.
197  *
198  * Return: Zero if the buffer with the given size is allocated successfully,
199  * otherwise a negative value on error.
200  */
201 int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size,
202 				 struct snd_dma_buffer *dmab)
203 {
204 	int err;
205 
206 	while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) {
207 		if (err != -ENOMEM)
208 			return err;
209 		if (size <= PAGE_SIZE)
210 			return -ENOMEM;
211 		size >>= 1;
212 		size = PAGE_SIZE << get_order(size);
213 	}
214 	if (! dmab->area)
215 		return -ENOMEM;
216 	return 0;
217 }
218 EXPORT_SYMBOL(snd_dma_alloc_pages_fallback);
219 
220 
221 /**
222  * snd_dma_free_pages - release the allocated buffer
223  * @dmab: the buffer allocation record to release
224  *
225  * Releases the allocated buffer via snd_dma_alloc_pages().
226  */
227 void snd_dma_free_pages(struct snd_dma_buffer *dmab)
228 {
229 	switch (dmab->dev.type) {
230 	case SNDRV_DMA_TYPE_CONTINUOUS:
231 		free_pages_exact(dmab->area, dmab->bytes);
232 		break;
233 #ifdef CONFIG_HAS_DMA
234 #ifdef CONFIG_GENERIC_ALLOCATOR
235 	case SNDRV_DMA_TYPE_DEV_IRAM:
236 		snd_free_dev_iram(dmab);
237 		break;
238 #endif /* CONFIG_GENERIC_ALLOCATOR */
239 	case SNDRV_DMA_TYPE_DEV:
240 	case SNDRV_DMA_TYPE_DEV_UC:
241 		snd_free_dev_pages(dmab);
242 		break;
243 #endif
244 #ifdef CONFIG_SND_DMA_SGBUF
245 	case SNDRV_DMA_TYPE_DEV_SG:
246 	case SNDRV_DMA_TYPE_DEV_UC_SG:
247 		snd_free_sgbuf_pages(dmab);
248 		break;
249 #endif
250 	default:
251 		pr_err("snd-malloc: invalid device type %d\n", dmab->dev.type);
252 	}
253 }
254 EXPORT_SYMBOL(snd_dma_free_pages);
255