Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
[linux-2.6-microblaze.git] / sound / core / memalloc.c
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);