|
17 | 17 | * published by the Free Software Foundation. |
18 | 18 | */ |
19 | 19 |
|
20 | | -#include <linux/genalloc.h> |
21 | 20 | #include <linux/init.h> |
22 | 21 | #include <linux/of_device.h> |
23 | 22 | #include <linux/spinlock.h> |
|
29 | 28 | #include <asm/udbg.h> |
30 | 29 | #include <asm/io.h> |
31 | 30 | #include <asm/cpm.h> |
| 31 | +#include <asm/qe.h> |
32 | 32 |
|
33 | 33 | #include <mm/mmu_decl.h> |
34 | 34 |
|
@@ -65,212 +65,6 @@ void __init udbg_init_cpm(void) |
65 | 65 | } |
66 | 66 | #endif |
67 | 67 |
|
68 | | -static struct gen_pool *muram_pool; |
69 | | -static spinlock_t cpm_muram_lock; |
70 | | -static u8 __iomem *muram_vbase; |
71 | | -static phys_addr_t muram_pbase; |
72 | | - |
73 | | -struct muram_block { |
74 | | - struct list_head head; |
75 | | - unsigned long start; |
76 | | - int size; |
77 | | -}; |
78 | | - |
79 | | -static LIST_HEAD(muram_block_list); |
80 | | - |
81 | | -/* max address size we deal with */ |
82 | | -#define OF_MAX_ADDR_CELLS 4 |
83 | | -#define GENPOOL_OFFSET (4096 * 8) |
84 | | - |
85 | | -int cpm_muram_init(void) |
86 | | -{ |
87 | | - struct device_node *np; |
88 | | - struct resource r; |
89 | | - u32 zero[OF_MAX_ADDR_CELLS] = {}; |
90 | | - resource_size_t max = 0; |
91 | | - int i = 0; |
92 | | - int ret = 0; |
93 | | - |
94 | | - if (muram_pbase) |
95 | | - return 0; |
96 | | - |
97 | | - spin_lock_init(&cpm_muram_lock); |
98 | | - np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data"); |
99 | | - if (!np) { |
100 | | - /* try legacy bindings */ |
101 | | - np = of_find_node_by_name(NULL, "data-only"); |
102 | | - if (!np) { |
103 | | - pr_err("Cannot find CPM muram data node"); |
104 | | - ret = -ENODEV; |
105 | | - goto out_muram; |
106 | | - } |
107 | | - } |
108 | | - |
109 | | - muram_pool = gen_pool_create(0, -1); |
110 | | - muram_pbase = of_translate_address(np, zero); |
111 | | - if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) { |
112 | | - pr_err("Cannot translate zero through CPM muram node"); |
113 | | - ret = -ENODEV; |
114 | | - goto out_pool; |
115 | | - } |
116 | | - |
117 | | - while (of_address_to_resource(np, i++, &r) == 0) { |
118 | | - if (r.end > max) |
119 | | - max = r.end; |
120 | | - ret = gen_pool_add(muram_pool, r.start - muram_pbase + |
121 | | - GENPOOL_OFFSET, resource_size(&r), -1); |
122 | | - if (ret) { |
123 | | - pr_err("QE: couldn't add muram to pool!\n"); |
124 | | - goto out_pool; |
125 | | - } |
126 | | - } |
127 | | - |
128 | | - muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1); |
129 | | - if (!muram_vbase) { |
130 | | - pr_err("Cannot map QE muram"); |
131 | | - ret = -ENOMEM; |
132 | | - goto out_pool; |
133 | | - } |
134 | | - goto out_muram; |
135 | | -out_pool: |
136 | | - gen_pool_destroy(muram_pool); |
137 | | -out_muram: |
138 | | - of_node_put(np); |
139 | | - return ret; |
140 | | -} |
141 | | - |
142 | | -/* |
143 | | - * cpm_muram_alloc - allocate the requested size worth of multi-user ram |
144 | | - * @size: number of bytes to allocate |
145 | | - * @align: requested alignment, in bytes |
146 | | - * |
147 | | - * This function returns an offset into the muram area. |
148 | | - * Use cpm_dpram_addr() to get the virtual address of the area. |
149 | | - * Use cpm_muram_free() to free the allocation. |
150 | | - */ |
151 | | -unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) |
152 | | -{ |
153 | | - unsigned long start; |
154 | | - unsigned long flags; |
155 | | - struct genpool_data_align muram_pool_data; |
156 | | - |
157 | | - spin_lock_irqsave(&cpm_muram_lock, flags); |
158 | | - muram_pool_data.align = align; |
159 | | - start = cpm_muram_alloc_common(size, gen_pool_first_fit_align, |
160 | | - &muram_pool_data); |
161 | | - spin_unlock_irqrestore(&cpm_muram_lock, flags); |
162 | | - return start; |
163 | | -} |
164 | | -EXPORT_SYMBOL(cpm_muram_alloc); |
165 | | - |
166 | | -/** |
167 | | - * cpm_muram_free - free a chunk of multi-user ram |
168 | | - * @offset: The beginning of the chunk as returned by cpm_muram_alloc(). |
169 | | - */ |
170 | | -int cpm_muram_free(unsigned long offset) |
171 | | -{ |
172 | | - unsigned long flags; |
173 | | - int size; |
174 | | - struct muram_block *tmp; |
175 | | - |
176 | | - size = 0; |
177 | | - spin_lock_irqsave(&cpm_muram_lock, flags); |
178 | | - list_for_each_entry(tmp, &muram_block_list, head) { |
179 | | - if (tmp->start == offset) { |
180 | | - size = tmp->size; |
181 | | - list_del(&tmp->head); |
182 | | - kfree(tmp); |
183 | | - break; |
184 | | - } |
185 | | - } |
186 | | - gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size); |
187 | | - spin_unlock_irqrestore(&cpm_muram_lock, flags); |
188 | | - return size; |
189 | | -} |
190 | | -EXPORT_SYMBOL(cpm_muram_free); |
191 | | - |
192 | | -/* |
193 | | - * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram |
194 | | - * @offset: offset of allocation start address |
195 | | - * @size: number of bytes to allocate |
196 | | - * This function returns an offset into the muram area |
197 | | - * Use cpm_dpram_addr() to get the virtual address of the area. |
198 | | - * Use cpm_muram_free() to free the allocation. |
199 | | - */ |
200 | | -unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size) |
201 | | -{ |
202 | | - unsigned long start; |
203 | | - unsigned long flags; |
204 | | - struct genpool_data_fixed muram_pool_data_fixed; |
205 | | - |
206 | | - spin_lock_irqsave(&cpm_muram_lock, flags); |
207 | | - muram_pool_data_fixed.offset = offset + GENPOOL_OFFSET; |
208 | | - start = cpm_muram_alloc_common(size, gen_pool_fixed_alloc, |
209 | | - &muram_pool_data_fixed); |
210 | | - spin_unlock_irqrestore(&cpm_muram_lock, flags); |
211 | | - return start; |
212 | | -} |
213 | | -EXPORT_SYMBOL(cpm_muram_alloc_fixed); |
214 | | - |
215 | | -/* |
216 | | - * cpm_muram_alloc_common - cpm_muram_alloc common code |
217 | | - * @size: number of bytes to allocate |
218 | | - * @algo: algorithm for alloc. |
219 | | - * @data: data for genalloc's algorithm. |
220 | | - * |
221 | | - * This function returns an offset into the muram area. |
222 | | - */ |
223 | | -unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, |
224 | | - void *data) |
225 | | -{ |
226 | | - struct muram_block *entry; |
227 | | - unsigned long start; |
228 | | - |
229 | | - start = gen_pool_alloc_algo(muram_pool, size, algo, data); |
230 | | - if (!start) |
231 | | - goto out2; |
232 | | - start = start - GENPOOL_OFFSET; |
233 | | - memset_io(cpm_muram_addr(start), 0, size); |
234 | | - entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
235 | | - if (!entry) |
236 | | - goto out1; |
237 | | - entry->start = start; |
238 | | - entry->size = size; |
239 | | - list_add(&entry->head, &muram_block_list); |
240 | | - |
241 | | - return start; |
242 | | -out1: |
243 | | - gen_pool_free(muram_pool, start, size); |
244 | | -out2: |
245 | | - return (unsigned long)-ENOMEM; |
246 | | -} |
247 | | - |
248 | | -/** |
249 | | - * cpm_muram_addr - turn a muram offset into a virtual address |
250 | | - * @offset: muram offset to convert |
251 | | - */ |
252 | | -void __iomem *cpm_muram_addr(unsigned long offset) |
253 | | -{ |
254 | | - return muram_vbase + offset; |
255 | | -} |
256 | | -EXPORT_SYMBOL(cpm_muram_addr); |
257 | | - |
258 | | -unsigned long cpm_muram_offset(void __iomem *addr) |
259 | | -{ |
260 | | - return addr - (void __iomem *)muram_vbase; |
261 | | -} |
262 | | -EXPORT_SYMBOL(cpm_muram_offset); |
263 | | - |
264 | | -/** |
265 | | - * cpm_muram_dma - turn a muram virtual address into a DMA address |
266 | | - * @offset: virtual address from cpm_muram_addr() to convert |
267 | | - */ |
268 | | -dma_addr_t cpm_muram_dma(void __iomem *addr) |
269 | | -{ |
270 | | - return muram_pbase + ((u8 __iomem *)addr - muram_vbase); |
271 | | -} |
272 | | -EXPORT_SYMBOL(cpm_muram_dma); |
273 | | - |
274 | 68 | #if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO) |
275 | 69 |
|
276 | 70 | struct cpm2_ioports { |
|
0 commit comments