diff options
Diffstat (limited to 'drivers/video/fsl-diu-fb.c')
| -rw-r--r-- | drivers/video/fsl-diu-fb.c | 60 |
1 files changed, 22 insertions, 38 deletions
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 09d7e22c6fe..9cd36c223d3 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 | ||
| 280 | static struct diu_pool pool; | 280 | static 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 | 289 | static void *fsl_diu_alloc(size_t size, phys_addr_t *phys) | |
| 289 | static 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 | ||
| 319 | static 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 | */ | ||
| 312 | static 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 | ||
| 336 | static int fsl_diu_enable_panel(struct fb_info *info) | 320 | static int fsl_diu_enable_panel(struct fb_info *info) |
