Skip to content

Commit 0e6e01f

Browse files
Zhao QiangScott Wood
Zhao Qiang
authored and
Scott Wood
committed
CPM/QE: use genalloc to manage CPM/QE muram
Use genalloc to manage CPM/QE muram instead of rheap. Signed-off-by: Zhao Qiang <[email protected]> Signed-off-by: Scott Wood <[email protected]>
1 parent b26981c commit 0e6e01f

File tree

4 files changed

+94
-41
lines changed

4 files changed

+94
-41
lines changed

arch/powerpc/include/asm/cpm.h

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define __CPM_H
33

44
#include <linux/compiler.h>
5+
#include <linux/genalloc.h>
56
#include <linux/types.h>
67
#include <linux/errno.h>
78
#include <linux/of.h>
@@ -161,6 +162,8 @@ int cpm_muram_init(void);
161162
unsigned long cpm_muram_alloc(unsigned long size, unsigned long align);
162163
int cpm_muram_free(unsigned long offset);
163164
unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
165+
unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo,
166+
void *data);
164167
void __iomem *cpm_muram_addr(unsigned long offset);
165168
unsigned long cpm_muram_offset(void __iomem *addr);
166169
dma_addr_t cpm_muram_dma(void __iomem *addr);

arch/powerpc/platforms/Kconfig

+2-2
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ config TAU_AVERAGE
275275
config QUICC_ENGINE
276276
bool "Freescale QUICC Engine (QE) Support"
277277
depends on FSL_SOC && PPC32
278-
select PPC_LIB_RHEAP
278+
select GENERIC_ALLOCATOR
279279
select CRC32
280280
help
281281
The QUICC Engine (QE) is a new generation of communications
@@ -295,7 +295,6 @@ config CPM2
295295
bool "Enable support for the CPM2 (Communications Processor Module)"
296296
depends on (FSL_SOC_BOOKE && PPC32) || 8260
297297
select CPM
298-
select PPC_LIB_RHEAP
299298
select PPC_PCI_CHOICE
300299
select ARCH_REQUIRE_GPIOLIB
301300
help
@@ -325,6 +324,7 @@ config FSL_ULI1575
325324

326325
config CPM
327326
bool
327+
select GENERIC_ALLOCATOR
328328

329329
config OF_RTC
330330
bool

arch/powerpc/sysdev/cpm_common.c

+88-38
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* published by the Free Software Foundation.
1818
*/
1919

20+
#include <linux/genalloc.h>
2021
#include <linux/init.h>
2122
#include <linux/of_device.h>
2223
#include <linux/spinlock.h>
@@ -27,7 +28,6 @@
2728

2829
#include <asm/udbg.h>
2930
#include <asm/io.h>
30-
#include <asm/rheap.h>
3131
#include <asm/cpm.h>
3232

3333
#include <mm/mmu_decl.h>
@@ -65,14 +65,22 @@ void __init udbg_init_cpm(void)
6565
}
6666
#endif
6767

68+
static struct gen_pool *muram_pool;
6869
static spinlock_t cpm_muram_lock;
69-
static rh_block_t cpm_boot_muram_rh_block[16];
70-
static rh_info_t cpm_muram_info;
7170
static u8 __iomem *muram_vbase;
7271
static phys_addr_t muram_pbase;
7372

74-
/* Max address size we deal with */
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 */
7582
#define OF_MAX_ADDR_CELLS 4
83+
#define GENPOOL_OFFSET (4096 * 8)
7684

7785
int cpm_muram_init(void)
7886
{
@@ -87,50 +95,51 @@ int cpm_muram_init(void)
8795
return 0;
8896

8997
spin_lock_init(&cpm_muram_lock);
90-
/* initialize the info header */
91-
rh_init(&cpm_muram_info, 1,
92-
sizeof(cpm_boot_muram_rh_block) /
93-
sizeof(cpm_boot_muram_rh_block[0]),
94-
cpm_boot_muram_rh_block);
95-
9698
np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data");
9799
if (!np) {
98100
/* try legacy bindings */
99101
np = of_find_node_by_name(NULL, "data-only");
100102
if (!np) {
101-
printk(KERN_ERR "Cannot find CPM muram data node");
103+
pr_err("Cannot find CPM muram data node");
102104
ret = -ENODEV;
103-
goto out;
105+
goto out_muram;
104106
}
105107
}
106108

109+
muram_pool = gen_pool_create(0, -1);
107110
muram_pbase = of_translate_address(np, zero);
108111
if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) {
109-
printk(KERN_ERR "Cannot translate zero through CPM muram node");
112+
pr_err("Cannot translate zero through CPM muram node");
110113
ret = -ENODEV;
111-
goto out;
114+
goto out_pool;
112115
}
113116

114117
while (of_address_to_resource(np, i++, &r) == 0) {
115118
if (r.end > max)
116119
max = r.end;
117-
118-
rh_attach_region(&cpm_muram_info, r.start - muram_pbase,
119-
resource_size(&r));
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+
}
120126
}
121127

122128
muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1);
123129
if (!muram_vbase) {
124-
printk(KERN_ERR "Cannot map CPM muram");
130+
pr_err("Cannot map QE muram");
125131
ret = -ENOMEM;
132+
goto out_pool;
126133
}
127-
128-
out:
134+
goto out_muram;
135+
out_pool:
136+
gen_pool_destroy(muram_pool);
137+
out_muram:
129138
of_node_put(np);
130139
return ret;
131140
}
132141

133-
/**
142+
/*
134143
* cpm_muram_alloc - allocate the requested size worth of multi-user ram
135144
* @size: number of bytes to allocate
136145
* @align: requested alignment, in bytes
@@ -143,14 +152,13 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)
143152
{
144153
unsigned long start;
145154
unsigned long flags;
155+
struct genpool_data_align muram_pool_data;
146156

147157
spin_lock_irqsave(&cpm_muram_lock, flags);
148-
cpm_muram_info.alignment = align;
149-
start = rh_alloc(&cpm_muram_info, size, "commproc");
150-
if (!IS_ERR_VALUE(start))
151-
memset_io(cpm_muram_addr(start), 0, size);
158+
muram_pool_data.align = align;
159+
start = cpm_muram_alloc_common(size, gen_pool_first_fit_align,
160+
&muram_pool_data);
152161
spin_unlock_irqrestore(&cpm_muram_lock, flags);
153-
154162
return start;
155163
}
156164
EXPORT_SYMBOL(cpm_muram_alloc);
@@ -161,40 +169,82 @@ EXPORT_SYMBOL(cpm_muram_alloc);
161169
*/
162170
int cpm_muram_free(unsigned long offset)
163171
{
164-
int ret;
165172
unsigned long flags;
173+
int size;
174+
struct muram_block *tmp;
166175

176+
size = 0;
167177
spin_lock_irqsave(&cpm_muram_lock, flags);
168-
ret = rh_free(&cpm_muram_info, offset);
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);
169187
spin_unlock_irqrestore(&cpm_muram_lock, flags);
170-
171-
return ret;
188+
return size;
172189
}
173190
EXPORT_SYMBOL(cpm_muram_free);
174191

175-
/**
192+
/*
176193
* cpm_muram_alloc_fixed - reserve a specific region of multi-user ram
177-
* @offset: the offset into the muram area to reserve
178-
* @size: the number of bytes to reserve
179-
*
180-
* This function returns "start" on success, -ENOMEM on failure.
194+
* @offset: offset of allocation start address
195+
* @size: number of bytes to allocate
196+
* This function returns an offset into the muram area
181197
* Use cpm_dpram_addr() to get the virtual address of the area.
182198
* Use cpm_muram_free() to free the allocation.
183199
*/
184200
unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size)
185201
{
186202
unsigned long start;
187203
unsigned long flags;
204+
struct genpool_data_fixed muram_pool_data_fixed;
188205

189206
spin_lock_irqsave(&cpm_muram_lock, flags);
190-
cpm_muram_info.alignment = 1;
191-
start = rh_alloc_fixed(&cpm_muram_info, offset, size, "commproc");
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);
192210
spin_unlock_irqrestore(&cpm_muram_lock, flags);
193-
194211
return start;
195212
}
196213
EXPORT_SYMBOL(cpm_muram_alloc_fixed);
197214

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+
198248
/**
199249
* cpm_muram_addr - turn a muram offset into a virtual address
200250
* @offset: muram offset to convert

lib/genalloc.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size,
576576
fixed_data = data;
577577
order = pool->min_alloc_order;
578578
offset_bit = fixed_data->offset >> order;
579-
if (WARN_ON(fixed_data->offset & (1UL << order - 1)))
579+
if (WARN_ON(fixed_data->offset & ((1UL << order) - 1)))
580580
return size;
581581

582582
start_bit = bitmap_find_next_zero_area(map, size,

0 commit comments

Comments
 (0)