aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2007-03-21 11:16:50 -0400
committerHaavard Skinnemoen <hskinnemoen@atmel.com>2007-04-27 07:44:14 -0400
commitf9692b9501c339ec90647d8cd6ee5c106f072f9f (patch)
tree3a11d55a0383d10cb712b31bc18e57585cdeed4c /arch
parentd8011768e6bdd0d9de5cc7bdbd3077b4b4fab8c7 (diff)
[AVR32] Reserve framebuffer memory in early_parse_fbmem()
With the current strategy of using the bootmem allocator to allocate or reserve framebuffer memory, there's a slight chance that the requested area has been taken by the boot allocator bitmap before we get around to reserving it. By inserting the framebuffer region as a reserved region as early as possible, we improve our chances for success and we make the region visible as a reserved region in dmesg and /proc/iomem without any extra work. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/avr32/kernel/setup.c68
1 files changed, 61 insertions, 7 deletions
diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c
index d0a35a1b6a66..1682e2d61cf3 100644
--- a/arch/avr32/kernel/setup.c
+++ b/arch/avr32/kernel/setup.c
@@ -191,21 +191,45 @@ find_free_region(const struct resource *mem, resource_size_t size,
191 return target; 191 return target;
192} 192}
193 193
194static int __init
195alloc_reserved_region(resource_size_t *start, resource_size_t size,
196 resource_size_t align, const char *name)
197{
198 struct resource *mem;
199 resource_size_t target;
200 int ret;
201
202 for (mem = system_ram; mem; mem = mem->sibling) {
203 target = find_free_region(mem, size, align);
204 if (target <= mem->end) {
205 ret = add_reserved_region(target, target + size - 1,
206 name);
207 if (!ret)
208 *start = target;
209 return ret;
210 }
211 }
212
213 return -ENOMEM;
214}
215
194/* 216/*
195 * Early framebuffer allocation. Works as follows: 217 * Early framebuffer allocation. Works as follows:
196 * - If fbmem_size is zero, nothing will be allocated or reserved. 218 * - If fbmem_size is zero, nothing will be allocated or reserved.
197 * - If fbmem_start is zero when setup_bootmem() is called, 219 * - If fbmem_start is zero when setup_bootmem() is called,
198 * fbmem_size bytes will be allocated from the bootmem allocator. 220 * a block of fbmem_size bytes will be reserved before bootmem
221 * initialization. It will be aligned to the largest page size
222 * that fbmem_size is a multiple of.
199 * - If fbmem_start is nonzero, an area of size fbmem_size will be 223 * - If fbmem_start is nonzero, an area of size fbmem_size will be
200 * reserved at the physical address fbmem_start if necessary. If 224 * reserved at the physical address fbmem_start if possible. If
201 * the area isn't in a memory region known to the kernel, it will 225 * it collides with other reserved memory, a different block of
202 * be left alone. 226 * same size will be allocated, just as if fbmem_start was zero.
203 * 227 *
204 * Board-specific code may use these variables to set up platform data 228 * Board-specific code may use these variables to set up platform data
205 * for the framebuffer driver if fbmem_size is nonzero. 229 * for the framebuffer driver if fbmem_size is nonzero.
206 */ 230 */
207static unsigned long __initdata fbmem_start; 231static resource_size_t __initdata fbmem_start;
208static unsigned long __initdata fbmem_size; 232static resource_size_t __initdata fbmem_size;
209 233
210/* 234/*
211 * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for 235 * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
@@ -219,9 +243,39 @@ static unsigned long __initdata fbmem_size;
219 */ 243 */
220static int __init early_parse_fbmem(char *p) 244static int __init early_parse_fbmem(char *p)
221{ 245{
246 int ret;
247 unsigned long align;
248
222 fbmem_size = memparse(p, &p); 249 fbmem_size = memparse(p, &p);
223 if (*p == '@') 250 if (*p == '@') {
224 fbmem_start = memparse(p, &p); 251 fbmem_start = memparse(p, &p);
252 ret = add_reserved_region(fbmem_start,
253 fbmem_start + fbmem_size - 1,
254 "Framebuffer");
255 if (ret) {
256 printk(KERN_WARNING
257 "Failed to reserve framebuffer memory\n");
258 fbmem_start = 0;
259 }
260 }
261
262 if (!fbmem_start) {
263 if ((fbmem_size & 0x000fffffUL) == 0)
264 align = 0x100000; /* 1 MiB */
265 else if ((fbmem_size & 0x0000ffffUL) == 0)
266 align = 0x10000; /* 64 KiB */
267 else
268 align = 0x1000; /* 4 KiB */
269
270 ret = alloc_reserved_region(&fbmem_start, fbmem_size,
271 align, "Framebuffer");
272 if (ret) {
273 printk(KERN_WARNING
274 "Failed to allocate framebuffer memory\n");
275 fbmem_size = 0;
276 }
277 }
278
225 return 0; 279 return 0;
226} 280}
227early_param("fbmem", early_parse_fbmem); 281early_param("fbmem", early_parse_fbmem);