aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2008-07-24 00:31:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:40 -0400
commit6b51d51a9d24719f905ba9657b29e04efd82a7ea (patch)
treed941de4b541320f0b89f265fb6acbee2607e0081 /drivers/video
parentc25826a7cf1c61b5c6e6db8365172eb97ef39ef3 (diff)
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 <timur@freescale.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fsl-diu-fb.c60
1 files 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 = {
279 279
280static struct diu_pool pool; 280static struct diu_pool pool;
281 281
282/* To allocate memory for framebuffer. First try __get_free_pages(). If it 282/**
283 * fails, try rh_alloc. The reason is __get_free_pages() cannot allocate 283 * fsl_diu_alloc - allocate memory for the DIU
284 * very large memory (more than 4MB). We don't want to allocate all memory 284 * @size: number of bytes to allocate
285 * in rheap since small memory allocation/deallocation will fragment the 285 * @param: returned physical address of memory
286 * rheap and make the furture large allocation fail. 286 *
287 * This function allocates a physically-contiguous block of memory.
287 */ 288 */
288 289static void *fsl_diu_alloc(size_t size, phys_addr_t *phys)
289static void *fsl_diu_alloc(unsigned long size, phys_addr_t *phys)
290{ 290{
291 void *virt; 291 void *virt;
292 292
293 pr_debug("size=%lu\n", size); 293 pr_debug("size=%zu\n", size);
294 294
295 virt = (void *)__get_free_pages(GFP_DMA | __GFP_ZERO, get_order(size)); 295 virt = alloc_pages_exact(size, GFP_DMA | __GFP_ZERO);
296 if (virt) { 296 if (virt) {
297 *phys = virt_to_phys(virt); 297 *phys = virt_to_phys(virt);
298 pr_debug("virt %p, phys=%llx\n", virt, (uint64_t) *phys); 298 pr_debug("virt=%p phys=%llx\n", virt,
299 return virt; 299 (unsigned long long)*phys);
300 }
301 if (!diu_ops.diu_mem) {
302 printk(KERN_INFO "%s: no diu_mem."
303 " To reserve more memory, put 'diufb=15M' "
304 "in the command line\n", __func__);
305 return NULL;
306 }
307
308 virt = (void *)rh_alloc(&diu_ops.diu_rh_info, size, "DIU");
309 if (virt) {
310 *phys = virt_to_bus(virt);
311 memset(virt, 0, size);
312 } 300 }
313 301
314 pr_debug("rh virt=%p phys=%llx\n", virt, (unsigned long long)*phys);
315
316 return virt; 302 return virt;
317} 303}
318 304
319static void fsl_diu_free(void *p, unsigned long size) 305/**
306 * fsl_diu_free - release DIU memory
307 * @virt: pointer returned by fsl_diu_alloc()
308 * @size: number of bytes allocated by fsl_diu_alloc()
309 *
310 * This function releases memory allocated by fsl_diu_alloc().
311 */
312static void fsl_diu_free(void *virt, size_t size)
320{ 313{
321 pr_debug("p=%p size=%lu\n", p, size); 314 pr_debug("virt=%p size=%zu\n", virt, size);
322 315
323 if (!p) 316 if (virt && size)
324 return; 317 free_pages_exact(virt, size);
325
326 if ((p >= diu_ops.diu_mem) &&
327 (p < (diu_ops.diu_mem + diu_ops.diu_size))) {
328 pr_debug("rh\n");
329 rh_free(&diu_ops.diu_rh_info, (unsigned long) p);
330 } else {
331 pr_debug("dma\n");
332 free_pages((unsigned long)p, get_order(size));
333 }
334} 318}
335 319
336static int fsl_diu_enable_panel(struct fb_info *info) 320static int fsl_diu_enable_panel(struct fb_info *info)