From a1af0fbbbaac595b5bdf5495578d8ddbc6c17e6d Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 22 May 2010 23:53:45 +0100 Subject: [PATCH] ARM: OMAP: Cleanup OMAP FB SDRAM reservation The logic in this file is rather convoluted, but essentially: 1. region type 0 is SDRAM 2. referring to the code fragment if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SDRAM, sdram_start, sdram_size) < 0 || (rg.type != OMAPFB_MEMTYPE_SDRAM)) continue; - if rg.type is not OMAPFB_MEMTYPE_SDRAM, set_fbmem_region_type() returns zero immediately (since rg.type is non-zero), and so we 'continue'. - if rg.type is OMAPFB_MEMTYPE_SDRAM, and rg.paddr is zero, we fall through. - if rg.type is OMAPFB_MEMTYPE_SDRAM, and the region lies within SDRAM, we fall through. - if rg.type is OMAPFB_MEMTYPE_SDRAM, and the region is not within SDRAM, we 'continue'. 3. check_fbmem_region seems unnecessary. - we know rg.type is OMAPFB_MEMTYPE_SDRAM - we can check rg.size independently - bootmem_reserve() can check for overlapping reservations itself - we've already validated that the requested region lies within SDRAM. 4. avoid BUG()ing if the region entry is already set; print an error, and mark the configuration invalid - at least we'll continue booting so the error message has a chance of being logged/visible via serial console. With these changes in place, it makes the code much easier to understand and hence easier to convert to LMB. Signed-off-by: Russell King --- arch/arm/plat-omap/fb.c | 61 +++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c index d3eea4f47533..97db493904fa 100644 --- a/arch/arm/plat-omap/fb.c +++ b/arch/arm/plat-omap/fb.c @@ -171,49 +171,76 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg, return 0; } +static int valid_sdram(unsigned long addr, unsigned long size) +{ + struct bootmem_data *bdata = NODE_DATA(0)->bdata; + unsigned long sdram_start, sdram_end; + + sdram_start = bdata->node_min_pfn << PAGE_SHIFT; + sdram_end = bdata->node_low_pfn << PAGE_SHIFT; + + return addr >= sdram_start && sdram_end - addr >= size; +} + +static int reserve_sdram(unsigned long addr, unsigned long size) +{ + return reserve_bootmem(addr, size, BOOTMEM_EXCLUSIVE); +} + /* * Called from map_io. We need to call to this early enough so that we * can reserve the fixed SDRAM regions before VM could get hold of them. */ void __init omapfb_reserve_sdram(void) { - struct bootmem_data *bdata; - unsigned long sdram_start, sdram_size; - unsigned long reserved; - int i; + unsigned long reserved = 0; + int i; if (config_invalid) return; - bdata = NODE_DATA(0)->bdata; - sdram_start = bdata->node_min_pfn << PAGE_SHIFT; - sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start; - reserved = 0; for (i = 0; ; i++) { - struct omapfb_mem_region rg; + struct omapfb_mem_region rg; if (get_fbmem_region(i, &rg) < 0) break; + if (i == OMAPFB_PLANE_NUM) { - printk(KERN_ERR - "Extraneous FB mem configuration entries\n"); + pr_err("Extraneous FB mem configuration entries\n"); config_invalid = 1; return; } + /* Check if it's our memory type. */ - if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SDRAM, - sdram_start, sdram_size) < 0 || - (rg.type != OMAPFB_MEMTYPE_SDRAM)) + if (rg.type != OMAPFB_MEMTYPE_SDRAM) continue; - BUG_ON(omapfb_config.mem_desc.region[i].size); - if (check_fbmem_region(i, &rg, sdram_start, sdram_size) < 0) { + + /* Check if the region falls within SDRAM */ + if (rg.paddr && !valid_sdram(rg.paddr, rg.size)) + continue; + + if (rg.size == 0) { + pr_err("Zero size for FB region %d\n", i); config_invalid = 1; return; } + if (rg.paddr) { - reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT); + if (reserve_sdram(rg.paddr, rg.size)) { + pr_err("Trying to use reserved memory for FB region %d\n", + i); + config_invalid = 1; + return; + } reserved += rg.size; } + + if (omapfb_config.mem_desc.region[i].size) { + pr_err("FB region %d already set\n", i); + config_invalid = 1; + return; + } + omapfb_config.mem_desc.region[i] = rg; configured_regions++; }