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 * Generic memory allocators 36 * 37 */ 38 39 /** 40 * snd_malloc_pages - allocate pages with the given size 41 * @size: the size to allocate in bytes 42 * @gfp_flags: the allocation conditions, GFP_XXX 43 * 44 * Allocates the physically contiguous pages with the given size. 45 * 46 * Return: The pointer of the buffer, or %NULL if no enough memory. 47 */ 48 void *snd_malloc_pages(size_t size, gfp_t gfp_flags) 49 { 50 int pg; 51 52 if (WARN_ON(!size)) 53 return NULL; 54 if (WARN_ON(!gfp_flags)) 55 return NULL; 56 gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */ 57 pg = get_order(size); 58 return (void *) __get_free_pages(gfp_flags, pg); 59 } 60 EXPORT_SYMBOL(snd_malloc_pages); 61 62 /** 63 * snd_free_pages - release the pages 64 * @ptr: the buffer pointer to release 65 * @size: the allocated buffer size 66 * 67 * Releases the buffer allocated via snd_malloc_pages(). 68 */ 69 void snd_free_pages(void *ptr, size_t size) 70 { 71 int pg; 72 73 if (ptr == NULL) 74 return; 75 pg = get_order(size); 76 free_pages((unsigned long) ptr, pg); 77 } 78 EXPORT_SYMBOL(snd_free_pages); 79 80 /* 81 * 82 * Bus-specific memory allocators 83 * 84 */ 85 86 #ifdef CONFIG_HAS_DMA 87 /* allocate the coherent DMA pages */ 88 static void snd_malloc_dev_pages(struct snd_dma_buffer *dmab, size_t size) 89 { 90 gfp_t gfp_flags; 91 92 gfp_flags = GFP_KERNEL 93 | __GFP_COMP /* compound page lets parts be mapped */ 94 | __GFP_NORETRY /* don't trigger OOM-killer */ 95 | __GFP_NOWARN; /* no stack trace print - this call is non-critical */ 96 dmab->area = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr, 97 gfp_flags); 98 #ifdef CONFIG_X86 99 if (dmab->area && dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC) 100 set_memory_wc((unsigned long)dmab->area, 101 PAGE_ALIGN(size) >> PAGE_SHIFT); 102 #endif 103 } 104 105 /* free the coherent DMA pages */ 106 static void snd_free_dev_pages(struct snd_dma_buffer *dmab) 107 { 108 #ifdef CONFIG_X86 109 if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC) 110 set_memory_wb((unsigned long)dmab->area, 111 PAGE_ALIGN(dmab->bytes) >> PAGE_SHIFT); 112 #endif 113 dma_free_coherent(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); 114 } 115 116 #ifdef CONFIG_GENERIC_ALLOCATOR 117 /** 118 * snd_malloc_dev_iram - allocate memory from on-chip internal ram 119 * @dmab: buffer allocation record to store the allocated data 120 * @size: number of bytes to allocate from the iram 121 * 122 * This function requires iram phandle provided via of_node 123 */ 124 static void snd_malloc_dev_iram(struct snd_dma_buffer *dmab, size_t size) 125 { 126 struct device *dev = dmab->dev.dev; 127 struct gen_pool *pool = NULL; 128 129 dmab->area = NULL; 130 dmab->addr = 0; 131 132 if (dev->of_node) 133 pool = of_gen_pool_get(dev->of_node, "iram", 0); 134 135 if (!pool) 136 return; 137 138 /* Assign the pool into private_data field */ 139 dmab->private_data = pool; 140 141 dmab->area = gen_pool_dma_alloc(pool, size, &dmab->addr); 142 } 143 144 /** 145 * snd_free_dev_iram - free allocated specific memory from on-chip internal ram 146 * @dmab: buffer allocation record to store the allocated data 147 */ 148 static void snd_free_dev_iram(struct snd_dma_buffer *dmab) 149 { 150 struct gen_pool *pool = dmab->private_data; 151 152 if (pool && dmab->area) 153 gen_pool_free(pool, (unsigned long)dmab->area, dmab->bytes); 154 } 155 #endif /* CONFIG_GENERIC_ALLOCATOR */ 156 #endif /* CONFIG_HAS_DMA */ 157 158 /* 159 * 160 * ALSA generic memory management 161 * 162 */ 163 164 165 /** 166 * snd_dma_alloc_pages - allocate the buffer area according to the given type 167 * @type: the DMA buffer type 168 * @device: the device pointer 169 * @size: the buffer size to allocate 170 * @dmab: buffer allocation record to store the allocated data 171 * 172 * Calls the memory-allocator function for the corresponding 173 * buffer type. 174 * 175 * Return: Zero if the buffer with the given size is allocated successfully, 176 * otherwise a negative value on error. 177 */ 178 int snd_dma_alloc_pages(int type, struct device *device, size_t size, 179 struct snd_dma_buffer *dmab) 180 { 181 if (WARN_ON(!size)) 182 return -ENXIO; 183 if (WARN_ON(!dmab)) 184 return -ENXIO; 185 if (WARN_ON(!device)) 186 return -EINVAL; 187 188 dmab->dev.type = type; 189 dmab->dev.dev = device; 190 dmab->bytes = 0; 191 switch (type) { 192 case SNDRV_DMA_TYPE_CONTINUOUS: 193 dmab->area = snd_malloc_pages(size, 194 (__force gfp_t)(unsigned long)device); 195 dmab->addr = 0; 196 break; 197 #ifdef CONFIG_HAS_DMA 198 #ifdef CONFIG_GENERIC_ALLOCATOR 199 case SNDRV_DMA_TYPE_DEV_IRAM: 200 snd_malloc_dev_iram(dmab, size); 201 if (dmab->area) 202 break; 203 /* Internal memory might have limited size and no enough space, 204 * so if we fail to malloc, try to fetch memory traditionally. 205 */ 206 dmab->dev.type = SNDRV_DMA_TYPE_DEV; 207 #endif /* CONFIG_GENERIC_ALLOCATOR */ 208 /* fall through */ 209 case SNDRV_DMA_TYPE_DEV: 210 case SNDRV_DMA_TYPE_DEV_UC: 211 snd_malloc_dev_pages(dmab, size); 212 break; 213 #endif 214 #ifdef CONFIG_SND_DMA_SGBUF 215 case SNDRV_DMA_TYPE_DEV_SG: 216 case SNDRV_DMA_TYPE_DEV_UC_SG: 217 snd_malloc_sgbuf_pages(device, size, dmab, NULL); 218 break; 219 #endif 220 default: 221 pr_err("snd-malloc: invalid device type %d\n", type); 222 dmab->area = NULL; 223 dmab->addr = 0; 224 return -ENXIO; 225 } 226 if (! dmab->area) 227 return -ENOMEM; 228 dmab->bytes = size; 229 return 0; 230 } 231 EXPORT_SYMBOL(snd_dma_alloc_pages); 232 233 /** 234 * snd_dma_alloc_pages_fallback - allocate the buffer area according to the given type with fallback 235 * @type: the DMA buffer type 236 * @device: the device pointer 237 * @size: the buffer size to allocate 238 * @dmab: buffer allocation record to store the allocated data 239 * 240 * Calls the memory-allocator function for the corresponding 241 * buffer type. When no space is left, this function reduces the size and 242 * tries to allocate again. The size actually allocated is stored in 243 * res_size argument. 244 * 245 * Return: Zero if the buffer with the given size is allocated successfully, 246 * otherwise a negative value on error. 247 */ 248 int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size, 249 struct snd_dma_buffer *dmab) 250 { 251 int err; 252 253 while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) { 254 if (err != -ENOMEM) 255 return err; 256 if (size <= PAGE_SIZE) 257 return -ENOMEM; 258 size >>= 1; 259 size = PAGE_SIZE << get_order(size); 260 } 261 if (! dmab->area) 262 return -ENOMEM; 263 return 0; 264 } 265 EXPORT_SYMBOL(snd_dma_alloc_pages_fallback); 266 267 268 /** 269 * snd_dma_free_pages - release the allocated buffer 270 * @dmab: the buffer allocation record to release 271 * 272 * Releases the allocated buffer via snd_dma_alloc_pages(). 273 */ 274 void snd_dma_free_pages(struct snd_dma_buffer *dmab) 275 { 276 switch (dmab->dev.type) { 277 case SNDRV_DMA_TYPE_CONTINUOUS: 278 snd_free_pages(dmab->area, dmab->bytes); 279 break; 280 #ifdef CONFIG_HAS_DMA 281 #ifdef CONFIG_GENERIC_ALLOCATOR 282 case SNDRV_DMA_TYPE_DEV_IRAM: 283 snd_free_dev_iram(dmab); 284 break; 285 #endif /* CONFIG_GENERIC_ALLOCATOR */ 286 case SNDRV_DMA_TYPE_DEV: 287 case SNDRV_DMA_TYPE_DEV_UC: 288 snd_free_dev_pages(dmab); 289 break; 290 #endif 291 #ifdef CONFIG_SND_DMA_SGBUF 292 case SNDRV_DMA_TYPE_DEV_SG: 293 case SNDRV_DMA_TYPE_DEV_UC_SG: 294 snd_free_sgbuf_pages(dmab); 295 break; 296 #endif 297 default: 298 pr_err("snd-malloc: invalid device type %d\n", dmab->dev.type); 299 } 300 } 301 EXPORT_SYMBOL(snd_dma_free_pages); 302