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