From 6b51d51a9d24719f905ba9657b29e04efd82a7ea Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Wed, 23 Jul 2008 21:31:39 -0700 Subject: [PATCH] fsl-diu-fb: update Freescale DIU driver to use page_alloc_exact() Update the Freescale DIU driver to use page_alloc_exact() to allocate a DMA buffer. This also eliminates the rheap-based memory allocator. We can do this now because commit 6ccf61f9 allows us to allocate 8MB physically- contiguous memory blocks. [akpm@linux-foundation.org: fix printk warnings] Signed-off-by: Timur Tabi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fsl-diu-fb.c | 60 ++++++++++++++------------------------ 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 09d7e22c6fef..9cd36c223d33 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -279,58 +279,42 @@ static struct diu_hw dr = { static struct diu_pool pool; -/* To allocate memory for framebuffer. First try __get_free_pages(). If it - * fails, try rh_alloc. The reason is __get_free_pages() cannot allocate - * very large memory (more than 4MB). We don't want to allocate all memory - * in rheap since small memory allocation/deallocation will fragment the - * rheap and make the furture large allocation fail. +/** + * fsl_diu_alloc - allocate memory for the DIU + * @size: number of bytes to allocate + * @param: returned physical address of memory + * + * This function allocates a physically-contiguous block of memory. */ - -static void *fsl_diu_alloc(unsigned long size, phys_addr_t *phys) +static void *fsl_diu_alloc(size_t size, phys_addr_t *phys) { void *virt; - pr_debug("size=%lu\n", size); + pr_debug("size=%zu\n", size); - virt = (void *)__get_free_pages(GFP_DMA | __GFP_ZERO, get_order(size)); + virt = alloc_pages_exact(size, GFP_DMA | __GFP_ZERO); if (virt) { *phys = virt_to_phys(virt); - pr_debug("virt %p, phys=%llx\n", virt, (uint64_t) *phys); - return virt; - } - if (!diu_ops.diu_mem) { - printk(KERN_INFO "%s: no diu_mem." - " To reserve more memory, put 'diufb=15M' " - "in the command line\n", __func__); - return NULL; - } - - virt = (void *)rh_alloc(&diu_ops.diu_rh_info, size, "DIU"); - if (virt) { - *phys = virt_to_bus(virt); - memset(virt, 0, size); + pr_debug("virt=%p phys=%llx\n", virt, + (unsigned long long)*phys); } - pr_debug("rh virt=%p phys=%llx\n", virt, (unsigned long long)*phys); - return virt; } -static void fsl_diu_free(void *p, unsigned long size) +/** + * fsl_diu_free - release DIU memory + * @virt: pointer returned by fsl_diu_alloc() + * @size: number of bytes allocated by fsl_diu_alloc() + * + * This function releases memory allocated by fsl_diu_alloc(). + */ +static void fsl_diu_free(void *virt, size_t size) { - pr_debug("p=%p size=%lu\n", p, size); + pr_debug("virt=%p size=%zu\n", virt, size); - if (!p) - return; - - if ((p >= diu_ops.diu_mem) && - (p < (diu_ops.diu_mem + diu_ops.diu_size))) { - pr_debug("rh\n"); - rh_free(&diu_ops.diu_rh_info, (unsigned long) p); - } else { - pr_debug("dma\n"); - free_pages((unsigned long)p, get_order(size)); - } + if (virt && size) + free_pages_exact(virt, size); } static int fsl_diu_enable_panel(struct fb_info *info) -- 2.20.1