Commit a1af0fbb authored by Russell King's avatar Russell King

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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 98c672cf
...@@ -171,49 +171,76 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg, ...@@ -171,49 +171,76 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
return 0; 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 * 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. * can reserve the fixed SDRAM regions before VM could get hold of them.
*/ */
void __init omapfb_reserve_sdram(void) void __init omapfb_reserve_sdram(void)
{ {
struct bootmem_data *bdata; unsigned long reserved = 0;
unsigned long sdram_start, sdram_size; int i;
unsigned long reserved;
int i;
if (config_invalid) if (config_invalid)
return; 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++) { for (i = 0; ; i++) {
struct omapfb_mem_region rg; struct omapfb_mem_region rg;
if (get_fbmem_region(i, &rg) < 0) if (get_fbmem_region(i, &rg) < 0)
break; break;
if (i == OMAPFB_PLANE_NUM) { if (i == OMAPFB_PLANE_NUM) {
printk(KERN_ERR pr_err("Extraneous FB mem configuration entries\n");
"Extraneous FB mem configuration entries\n");
config_invalid = 1; config_invalid = 1;
return; return;
} }
/* Check if it's our memory type. */ /* Check if it's our memory type. */
if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SDRAM, if (rg.type != OMAPFB_MEMTYPE_SDRAM)
sdram_start, sdram_size) < 0 ||
(rg.type != OMAPFB_MEMTYPE_SDRAM))
continue; 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; config_invalid = 1;
return; return;
} }
if (rg.paddr) { 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; 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; omapfb_config.mem_desc.region[i] = rg;
configured_regions++; configured_regions++;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment