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