diff options
| author | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2007-03-21 11:16:50 -0400 |
|---|---|---|
| committer | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2007-04-27 07:44:14 -0400 |
| commit | f9692b9501c339ec90647d8cd6ee5c106f072f9f (patch) | |
| tree | 3a11d55a0383d10cb712b31bc18e57585cdeed4c | |
| parent | d8011768e6bdd0d9de5cc7bdbd3077b4b4fab8c7 (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>
| -rw-r--r-- | arch/avr32/kernel/setup.c | 68 |
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 | ||
| 194 | static int __init | ||
| 195 | alloc_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 | */ |
| 207 | static unsigned long __initdata fbmem_start; | 231 | static resource_size_t __initdata fbmem_start; |
| 208 | static unsigned long __initdata fbmem_size; | 232 | static 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 | */ |
| 220 | static int __init early_parse_fbmem(char *p) | 244 | static 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 | } |
| 227 | early_param("fbmem", early_parse_fbmem); | 281 | early_param("fbmem", early_parse_fbmem); |
