Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b51d51a authored by Timur Tabi's avatar Timur Tabi Committed by Linus Torvalds
Browse files

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: default avatarTimur Tabi <timur@freescale.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c25826a7
Loading
Loading
Loading
Loading
+22 −38
Original line number Original line Diff line number Diff line
@@ -279,58 +279,42 @@ static struct diu_hw dr = {


static struct diu_pool pool;
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
 * fsl_diu_alloc - allocate memory for the DIU
 *	very large memory (more than 4MB). We don't want to allocate all memory
 * @size: number of bytes to allocate
 *	in rheap since small memory allocation/deallocation will fragment the
 * @param: returned physical address of memory
 *	rheap and make the furture large allocation fail.
 *
 * This function allocates a physically-contiguous block of memory.
 */
 */

static void *fsl_diu_alloc(size_t size, phys_addr_t *phys)
static void *fsl_diu_alloc(unsigned long size, phys_addr_t *phys)
{
{
	void *virt;
	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) {
	if (virt) {
		*phys = virt_to_phys(virt);
		*phys = virt_to_phys(virt);
		pr_debug("virt %p, phys=%llx\n", virt, (uint64_t) *phys);
		pr_debug("virt=%p phys=%llx\n", virt,
		return virt;
			(unsigned long long)*phys);
	}
	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("rh virt=%p phys=%llx\n", virt, (unsigned long long)*phys);

	return virt;
	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)
	if (virt && size)
		return;
		free_pages_exact(virt, size);

	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));
	}
}
}


static int fsl_diu_enable_panel(struct fb_info *info)
static int fsl_diu_enable_panel(struct fb_info *info)