Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f9692b9501c339ec90647d8cd6ee5c106f072f9f
Commit:     f9692b9501c339ec90647d8cd6ee5c106f072f9f
Parent:     d8011768e6bdd0d9de5cc7bdbd3077b4b4fab8c7
Author:     Haavard Skinnemoen <[EMAIL PROTECTED]>
AuthorDate: Wed Mar 21 16:16:50 2007 +0100
Committer:  Haavard Skinnemoen <[EMAIL PROTECTED]>
CommitDate: Fri Apr 27 13:44:14 2007 +0200

    [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 <[EMAIL PROTECTED]>
---
 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 d0a35a1..1682e2d 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,
        return target;
 }
 
+static int __init
+alloc_reserved_region(resource_size_t *start, resource_size_t size,
+                     resource_size_t align, const char *name)
+{
+       struct resource *mem;
+       resource_size_t target;
+       int ret;
+
+       for (mem = system_ram; mem; mem = mem->sibling) {
+               target = find_free_region(mem, size, align);
+               if (target <= mem->end) {
+                       ret = add_reserved_region(target, target + size - 1,
+                                                 name);
+                       if (!ret)
+                               *start = target;
+                       return ret;
+               }
+       }
+
+       return -ENOMEM;
+}
+
 /*
  * Early framebuffer allocation. Works as follows:
  *   - If fbmem_size is zero, nothing will be allocated or reserved.
  *   - If fbmem_start is zero when setup_bootmem() is called,
- *     fbmem_size bytes will be allocated from the bootmem allocator.
+ *     a block of fbmem_size bytes will be reserved before bootmem
+ *     initialization. It will be aligned to the largest page size
+ *     that fbmem_size is a multiple of.
  *   - If fbmem_start is nonzero, an area of size fbmem_size will be
- *     reserved at the physical address fbmem_start if necessary. If
- *     the area isn't in a memory region known to the kernel, it will
- *     be left alone.
+ *     reserved at the physical address fbmem_start if possible. If
+ *     it collides with other reserved memory, a different block of
+ *     same size will be allocated, just as if fbmem_start was zero.
  *
  * Board-specific code may use these variables to set up platform data
  * for the framebuffer driver if fbmem_size is nonzero.
  */
-static unsigned long __initdata fbmem_start;
-static unsigned long __initdata fbmem_size;
+static resource_size_t __initdata fbmem_start;
+static resource_size_t __initdata fbmem_size;
 
 /*
  * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
@@ -219,9 +243,39 @@ static unsigned long __initdata fbmem_size;
  */
 static int __init early_parse_fbmem(char *p)
 {
+       int ret;
+       unsigned long align;
+
        fbmem_size = memparse(p, &p);
-       if (*p == '@')
+       if (*p == '@') {
                fbmem_start = memparse(p, &p);
+               ret = add_reserved_region(fbmem_start,
+                                         fbmem_start + fbmem_size - 1,
+                                         "Framebuffer");
+               if (ret) {
+                       printk(KERN_WARNING
+                              "Failed to reserve framebuffer memory\n");
+                       fbmem_start = 0;
+               }
+       }
+
+       if (!fbmem_start) {
+               if ((fbmem_size & 0x000fffffUL) == 0)
+                       align = 0x100000;       /* 1 MiB */
+               else if ((fbmem_size & 0x0000ffffUL) == 0)
+                       align = 0x10000;        /* 64 KiB */
+               else
+                       align = 0x1000;         /* 4 KiB */
+
+               ret = alloc_reserved_region(&fbmem_start, fbmem_size,
+                                           align, "Framebuffer");
+               if (ret) {
+                       printk(KERN_WARNING
+                              "Failed to allocate framebuffer memory\n");
+                       fbmem_size = 0;
+               }
+       }
+
        return 0;
 }
 early_param("fbmem", early_parse_fbmem);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to