diff options
author | Zhao Qiang <qiang.zhao@freescale.com> | 2015-11-29 21:48:55 -0500 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2015-12-22 18:10:18 -0500 |
commit | 1291e49e893703e04e129fe2e17e87af40757bf1 (patch) | |
tree | a256a6a6e4b3a1ded6d08afe17ce19ee20aac5dd /arch/powerpc/sysdev/cpm_common.c | |
parent | 0e6e01ff694ee222acc5a9184211678473c948e3 (diff) |
QE/CPM: move muram management functions to qe_common
QE and CPM have the same muram, they use the same management
functions. Now QE support both ARM and PowerPC, it is necessary
to move QE to "driver/soc", so move the muram management functions
from cpm_common to qe_common for preparing to move QE code to "driver/soc"
Signed-off-by: Zhao Qiang <qiang.zhao@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch/powerpc/sysdev/cpm_common.c')
-rw-r--r-- | arch/powerpc/sysdev/cpm_common.c | 208 |
1 files changed, 1 insertions, 207 deletions
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index fcc83cd9cc2f..6993aa8e7242 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
@@ -17,7 +17,6 @@ | |||
17 | * published by the Free Software Foundation. | 17 | * published by the Free Software Foundation. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/genalloc.h> | ||
21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
22 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
23 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
@@ -29,6 +28,7 @@ | |||
29 | #include <asm/udbg.h> | 28 | #include <asm/udbg.h> |
30 | #include <asm/io.h> | 29 | #include <asm/io.h> |
31 | #include <asm/cpm.h> | 30 | #include <asm/cpm.h> |
31 | #include <asm/qe.h> | ||
32 | 32 | ||
33 | #include <mm/mmu_decl.h> | 33 | #include <mm/mmu_decl.h> |
34 | 34 | ||
@@ -65,212 +65,6 @@ void __init udbg_init_cpm(void) | |||
65 | } | 65 | } |
66 | #endif | 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 | #if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO) | 68 | #if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO) |
275 | 69 | ||
276 | struct cpm2_ioports { | 70 | struct cpm2_ioports { |