All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] Initial attempt to make ARM use LMB
@ 2010-03-25 23:32 ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-03-25 23:32 UTC (permalink / raw)
  To: linux-arm-kernel, Tony Lindgren; +Cc: linux-omap

LMB... logical memory blocks.

LM is a different method of managing memory regions during the early
boot period when the usual kernel memory allocators are not up and
running.  LMB has been in the kernel for quite some time, and is
already being used by Microblaze, PPC, SH and Sparc.  Maybe soon x86
as well.

The motivation for this is that there appears to be plans to kill off
the other method - bootmem.  (see discussions on the linux-arch ml.)

Plus points:
1. LMB can be told about all memory areas, and all reserved areas.

2. As a result, we get rid of the "guess where to put the bootmem bitmap"
   code which can sometimes end up overwriting initrds by asking lmb to
   find a suitable place which doesn't conflict with reserved areas.

3. Overall reduction in arch code.

Minus points:
1. breaks OMAP2,3,4 since it fiddles with bootmem in its map_io function
   for framebuffer stuff.  This needs reworking.

2. highmem is probably broken by this.

3. the highmem boundary (as far as lowmem lmb allocations are concerned)
   is set at PHYS_OFFSET + 32MB

4. sparsemem requires bootmem, so we can't get away from bootmem at the
   moment.

The patch below is the combined patch; individual patches can be found
in the arm:lmb patches on the website or the lmb branch of my git tree;
this should be considered unstable.

 arch/arm/Kconfig                         |    1 +
 arch/arm/include/asm/lmb.h               |   13 ++
 arch/arm/include/asm/mach/arch.h         |    1 +
 arch/arm/kernel/setup.c                  |   12 ++
 arch/arm/mach-clps711x/edb7211-arch.c    |    8 ++
 arch/arm/mach-clps711x/mm.c              |    1 -
 arch/arm/mach-integrator/common.h        |    1 +
 arch/arm/mach-integrator/core.c          |   11 ++
 arch/arm/mach-integrator/integrator_ap.c |    1 +
 arch/arm/mach-integrator/integrator_cp.c |    1 +
 arch/arm/mach-ixp4xx/common.c            |    1 -
 arch/arm/mach-omap1/board-htcherald.c    |    1 -
 arch/arm/mach-omap2/omap_hwmod.c         |    1 -
 arch/arm/mach-pxa/palmt5.c               |    7 +
 arch/arm/mach-pxa/palmtreo.c             |    9 ++
 arch/arm/mach-s3c2410/mach-h1940.c       |    9 ++
 arch/arm/mach-s3c2440/mach-rx3715.c      |    9 ++
 arch/arm/mach-u300/u300.c                |   17 +++
 arch/arm/mm/init.c                       |  184 +++++------------------------
 arch/arm/mm/mm.h                         |    8 +-
 arch/arm/mm/mmu.c                        |  153 ++++++++++---------------
 arch/arm/mm/nommu.c                      |   22 +---
 22 files changed, 198 insertions(+), 273 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c5408bf..48254a4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -10,6 +10,7 @@ config ARM
 	default y
 	select HAVE_AOUT
 	select HAVE_IDE
+	select HAVE_LMB
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select GENERIC_ATOMIC64 if (!CPU_32v6K)
diff --git a/arch/arm/include/asm/lmb.h b/arch/arm/include/asm/lmb.h
new file mode 100644
index 0000000..df083f1
--- /dev/null
+++ b/arch/arm/include/asm/lmb.h
@@ -0,0 +1,13 @@
+#ifndef _ASM_ARM_LMB_H
+#define _ASM_ARM_LMB_H
+
+#ifdef CONFIG_MMU
+extern phys_addr_t lowmem_end_addr;
+#define LMB_REAL_LIMIT	lowmem_end_addr
+#else
+#define LMB_REAL_LIMIT	0
+#endif
+
+extern void arm_lmb_reserve(void);
+
+#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index c59842d..f634dbe 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -37,6 +37,7 @@ struct machine_desc {
 	void			(*fixup)(struct machine_desc *,
 					 struct tag *, char **,
 					 struct meminfo *);
+	void			(*reserve)(void);/* reserve lmb blocks	*/
 	void			(*map_io)(void);/* IO mapping function	*/
 	void			(*init_irq)(void);
 	struct sys_timer	*timer;		/* system tick timer	*/
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c91c77b..23633ee 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -25,6 +25,7 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/lmb.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -666,6 +667,7 @@ void __init setup_arch(char **cmdline_p)
 	struct tag *tags = (struct tag *)&init_tags;
 	struct machine_desc *mdesc;
 	char *from = default_command_line;
+	int i;
 
 	unwind_init();
 
@@ -714,6 +716,16 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+	lmb_init();
+	for (i = 0; i < meminfo.nr_banks; i++)
+		lmb_add(meminfo.bank[i].start, meminfo.bank[i].size);
+
+	arm_lmb_reserve();
+
+	/* reserve any lmb areas */
+	if (mdesc->reserve)
+		mdesc->reserve();
+
 	paging_init(mdesc);
 	request_standard_resources(&meminfo, mdesc);
 
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index dc81cc6..aba952c 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/lmb.h>
 #include <linux/types.h>
 #include <linux/string.h>
 
@@ -29,6 +30,12 @@
 
 extern void edb7211_map_io(void);
 
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+	lmb_reserve(PHYS_OFFSET, 0x00020000);
+}
+
 static void __init
 fixup_edb7211(struct machine_desc *desc, struct tag *tags,
 	      char **cmdline, struct meminfo *mi)
@@ -57,6 +64,7 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
 	.boot_params	= 0xc0020100,	/* 0xc0000000 - 0xc001ffff can be video RAM */
 	.fixup		= fixup_edb7211,
 	.map_io		= edb7211_map_io,
+	.reserve	= edb7211_reserve,
 	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
index a7b4591..9865921 100644
--- a/arch/arm/mach-clps711x/mm.c
+++ b/arch/arm/mach-clps711x/mm.c
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index 609c49d..87cfeed 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1,2 +1,3 @@
 extern void integrator_time_init(unsigned long, unsigned int);
 extern unsigned long integrator_gettimeoffset(void);
+void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8b390e3..417c772 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/lmb.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/termios.h>
@@ -334,3 +335,13 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
 	 */
 	setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
 }
+
+/*
+ * We need to stop things allocating the low memory; ideally we need a
+ * better implementation of GFP_DMA which does not assume that DMA-able
+ * memory starts at zero.
+ */
+void __init integrator_reserve(void)
+{
+	lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 8138a7e..9fbde0d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -350,6 +350,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= ap_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= ap_init_irq,
 	.timer		= &ap_timer,
 	.init_machine	= ap_init,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 66ef86d..8de5f35 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -585,6 +585,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= intcp_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= intcp_init_irq,
 	.timer		= &cp_timer,
 	.init_machine	= intcp_init,
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71728d3..0bce097 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -21,7 +21,6 @@
 #include <linux/tty.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
-#include <linux/bootmem.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/time.h>
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index e36639f..8e313b4 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index c664947..aa3e209 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -43,7 +43,6 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/bootmem.h>
 
 #include <plat/common.h>
 #include <plat/cpu.h>
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index d902a81..b33fbe3 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/lmb.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -396,6 +397,11 @@ static void __init palmt5_udc_init(void)
 	}
 }
 
+static void __init palmt5_reserve(void)
+{
+	lmb_reserve(0xa0200000, 0x1000);
+}
+
 static void __init palmt5_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
@@ -421,6 +427,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5")
 	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
 	.boot_params	= 0xa0000100,
 	.map_io		= pxa_map_io,
+	.reserve	= palmt5_reserve,
 	.init_irq	= pxa27x_init_irq,
 	.timer		= &pxa_timer,
 	.init_machine	= palmt5_init
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index d8b4469..e712b86 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/lmb.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -633,6 +634,12 @@ static void __init treo_lcd_power_init(void)
 	treo_lcd_screen.pxafb_lcd_power = treo_lcd_power;
 }
 
+static void __init treo_reserve(void)
+{
+	lmb_reserve(0xa0000000, 0x1000);
+	lmb_reserve(0xa2000000, 0x1000);
+}
+
 static void __init treo_init(void)
 {
 	pxa_set_ffuart_info(NULL);
@@ -668,6 +675,7 @@ MACHINE_START(TREO680, "Palm Treo 680")
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
 	.init_machine   = treo680_init,
@@ -691,6 +699,7 @@ MACHINE_START(CENTRO, "Palm Centro 685")
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
        .init_machine   = centro_init,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index fbedd07..bfbcdd0 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/lmb.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
@@ -301,6 +302,13 @@ static void __init h1940_map_io(void)
 	s3c_pm_init();
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init h1940_reserve(void)
+{
+	lmb_reserve(0x30003000, 0x1000);
+	lmb_reserve(0x30081000, 0x1000);
+}
+
 static void __init h1940_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -342,6 +350,7 @@ MACHINE_START(H1940, "IPAQ-H1940")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= h1940_map_io,
+	.reserve	= h1940_reserve,
 	.init_irq	= h1940_init_irq,
 	.init_machine	= h1940_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 1e836e5..76aa734 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/lmb.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/tty.h>
@@ -191,6 +192,13 @@ static void __init rx3715_map_io(void)
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx3715_reserve(void)
+{
+	lmb_reserve(0x30003000, 0x1000);
+	lmb_reserve(0x30081000, 0x1000);
+}
+
 static void __init rx3715_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -214,6 +222,7 @@ MACHINE_START(RX3715, "IPAQ-RX3715")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= rx3715_map_io,
+	.reserve	= rx3715_reserve,
 	.init_irq	= rx3715_init_irq,
 	.init_machine	= rx3715_init_machine,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index d2a0b88..4fb8660 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/lmb.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <mach/hardware.h>
@@ -22,6 +23,21 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+static void __init u300_reserve(void)
+{
+	/*
+	 * U300 - This platform family can share physical memory
+	 * between two ARM cpus, one running Linux and the other
+	 * running another OS.
+	 */
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+        lmb_reserve(PHYS_OFFSET, 0x00100000);
+#endif
+#endif
+}
+
 static void __init u300_init_machine(void)
 {
 	u300_init_devices();
@@ -49,6 +65,7 @@ MACHINE_START(U300, MACH_U300_STRING)
 	.io_pg_offst	= ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
 	.boot_params	= BOOT_PARAMS_OFFSET,
 	.map_io		= u300_map_io,
+	.reserve	= u300_reserve,
 	.init_irq	= u300_init_irq,
 	.timer		= &u300_timer,
 	.init_machine	= u300_init_machine,
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7829cb5..e714bb2 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,8 +15,8 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
-#include <linux/sort.h>
 #include <linux/highmem.h>
+#include <linux/lmb.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -150,119 +150,21 @@ static void __init find_node_limits(int node, struct meminfo *mi,
 	}
 }
 
-/*
- * FIXME: We really want to avoid allocating the bootmap bitmap
- * over the top of the initrd.  Hopefully, this is located towards
- * the start of a bank, so if we allocate the bootmap bitmap at
- * the end, we won't clash.
- */
-static unsigned int __init
-find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
-{
-	unsigned int start_pfn, i, bootmap_pfn;
-
-	start_pfn   = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT;
-	bootmap_pfn = 0;
-
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-		unsigned int start, end;
-
-		start = bank_pfn_start(bank);
-		end   = bank_pfn_end(bank);
-
-		if (end < start_pfn)
-			continue;
-
-		if (start < start_pfn)
-			start = start_pfn;
-
-		if (end <= start)
-			continue;
-
-		if (end - start >= bootmap_pages) {
-			bootmap_pfn = start;
-			break;
-		}
-	}
-
-	if (bootmap_pfn == 0)
-		BUG();
-
-	return bootmap_pfn;
-}
-
-static int __init check_initrd(struct meminfo *mi)
-{
-	int initrd_node = -2;
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long end = phys_initrd_start + phys_initrd_size;
-
-	/*
-	 * Make sure that the initrd is within a valid area of
-	 * memory.
-	 */
-	if (phys_initrd_size) {
-		unsigned int i;
-
-		initrd_node = -1;
-
-		for (i = 0; i < mi->nr_banks; i++) {
-			struct membank *bank = &mi->bank[i];
-			if (bank_phys_start(bank) <= phys_initrd_start &&
-			    end <= bank_phys_end(bank))
-				initrd_node = bank->node;
-		}
-	}
-
-	if (initrd_node == -1) {
-		printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
-		       "physical memory - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
-		phys_initrd_start = phys_initrd_size = 0;
-	}
-#endif
-
-	return initrd_node;
-}
-
-static inline void map_memory_bank(struct membank *bank)
-{
-#ifdef CONFIG_MMU
-	struct map_desc map;
-
-	map.pfn = bank_pfn_start(bank);
-	map.virtual = __phys_to_virt(bank_phys_start(bank));
-	map.length = bank_phys_size(bank);
-	map.type = MT_MEMORY;
-
-	create_mapping(&map);
-#endif
-}
-
 static void __init bootmem_init_node(int node, struct meminfo *mi,
 	unsigned long start_pfn, unsigned long end_pfn)
 {
-	unsigned long boot_pfn;
 	unsigned int boot_pages;
+	phys_addr_t bitmap;
 	pg_data_t *pgdat;
 	int i;
 
 	/*
-	 * Map the memory banks for this node.
-	 */
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-
-		if (!bank->highmem)
-			map_memory_bank(bank);
-	}
-
-	/*
-	 * Allocate the bootmem bitmap page.
+	 * Allocate the bootmem bitmap page.  This must be in a region
+	 * of memory which has already been mapped.
 	 */
 	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
-	boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
+	bitmap = lmb_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES,
+				__pfn_to_phys(end_pfn));
 
 	/*
 	 * Initialise the bootmem allocator for this node, handing the
@@ -270,7 +172,7 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
 	 */
 	node_set_online(node);
 	pgdat = NODE_DATA(node);
-	init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+	init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
 
 	for_each_nodebank(i, mi, node) {
 		struct membank *bank = &mi->bank[i];
@@ -279,31 +181,16 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
 	}
 
 	/*
-	 * Reserve the bootmem bitmap for this node.
+	 * Reserve the LMB reserved regions in bootmem for this node.
 	 */
-	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
-			     boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
-}
-
-static void __init bootmem_reserve_initrd(int node)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	pg_data_t *pgdat = NODE_DATA(node);
-	int res;
-
-	res = reserve_bootmem_node(pgdat, phys_initrd_start,
-			     phys_initrd_size, BOOTMEM_EXCLUSIVE);
-
-	if (res == 0) {
-		initrd_start = __phys_to_virt(phys_initrd_start);
-		initrd_end = initrd_start + phys_initrd_size;
-	} else {
-		printk(KERN_ERR
-			"INITRD: 0x%08lx+0x%08lx overlaps in-use "
-			"memory region - disabling initrd\n",
-			phys_initrd_start, phys_initrd_size);
+	for (i = 0; i < lmb.reserved.cnt; i++) {
+		phys_addr_t start = lmb_start_pfn(&lmb.reserved, i);
+		if (start >= start_pfn &&
+		    lmb_end_pfn(&lmb.reserved, i) <= end_pfn)
+			reserve_bootmem_node(pgdat, __pfn_to_phys(start),
+				lmb_size_bytes(&lmb.reserved, i),
+				BOOTMEM_DEFAULT);
 	}
-#endif
 }
 
 static void __init bootmem_free_node(int node, struct meminfo *mi)
@@ -387,25 +274,23 @@ static void arm_memory_present(struct meminfo *mi, int node)
 }
 #endif
 
-static int __init meminfo_cmp(const void *_a, const void *_b)
+void __init arm_lmb_reserve(void)
 {
-	const struct membank *a = _a, *b = _b;
-	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
-	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+	/* Register the kernel text, kernel data and initrd with lmb. */
+#ifdef CONFIG_XIP_KERNEL
+	lmb_reserve(__pa(_data), _end - _data);
+#else
+	lmb_reserve(__pa(_stext), _end - _stext);
+#endif
+	lmb_reserve(phys_initrd_start, phys_initrd_size);
+	arm_mm_lmb_reserve();
 }
 
 void __init bootmem_init(void)
 {
 	struct meminfo *mi = &meminfo;
 	unsigned long min, max_low, max_high;
-	int node, initrd_node;
-
-	sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
-
-	/*
-	 * Locate which node contains the ramdisk image, if any.
-	 */
-	initrd_node = check_initrd(mi);
+	int node;
 
 	max_low = max_high = 0;
 
@@ -432,18 +317,6 @@ void __init bootmem_init(void)
 		bootmem_init_node(node, mi, min, node_low);
 
 		/*
-		 * Reserve any special node zero regions.
-		 */
-		if (node == 0)
-			reserve_node_zero(NODE_DATA(node));
-
-		/*
-		 * If the initrd is in this node, reserve its memory.
-		 */
-		if (node == initrd_node)
-			bootmem_reserve_initrd(node);
-
-		/*
 		 * Sparsemem tries to allocate bootmem in memory_present(),
 		 * so must be done after the fixed reservations
 		 */
@@ -566,6 +439,13 @@ void __init mem_init(void)
 	unsigned long reserved_pages, free_pages;
 	int i, node;
 
+#ifdef CONFIG_SA1111
+	lmb_free(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+#endif
+
+	lmb_analyze();
+	lmb_dump_all();
+
 #ifndef CONFIG_DISCONTIGMEM
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 #endif
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a888363..966dc45 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -28,10 +28,6 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
 
 #endif
 
-struct map_desc;
-struct meminfo;
-struct pglist_data;
-
-void __init create_mapping(struct map_desc *md);
 void __init bootmem_init(void);
-void reserve_node_zero(struct pglist_data *pgdat);
+void arm_lmb_reserve(void);
+void arm_mm_lmb_reserve(void);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9d4da6a..81eb08a 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -11,9 +11,10 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
+#include <linux/lmb.h>
+#include <linux/sort.h>
 
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
@@ -483,6 +484,13 @@ static void __init build_mem_type_table(void)
 
 #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
 
+static void __init *early_alloc(unsigned long sz)
+{
+	void *ptr = __va(lmb_alloc(sz, sz));
+	memset(ptr, 0, PAGE_SIZE);
+	return ptr;
+}
+
 static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 				  unsigned long end, unsigned long pfn,
 				  const struct mem_type *type)
@@ -490,7 +498,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 	pte_t *pte;
 
 	if (pmd_none(*pmd)) {
-		pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+		pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
 		__pmd_populate(pmd, __pa(pte) | type->prot_l1);
 	}
 
@@ -599,7 +607,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
  * offsets, and we take full advantage of sections and
  * supersections.
  */
-void __init create_mapping(struct map_desc *md)
+static void __init create_mapping(struct map_desc *md)
 {
 	unsigned long phys, addr, length, end;
 	const struct mem_type *type;
@@ -693,6 +701,9 @@ early_param("vmalloc", early_vmalloc);
 
 #define VMALLOC_MIN	(void *)(VMALLOC_END - vmalloc_reserve)
 
+/* FIXME: we need to teach LMB about the highmem boundary */
+phys_addr_t lowmem_end_addr = PHYS_OFFSET + 32*1048576;
+
 static void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
@@ -822,100 +833,23 @@ static inline void prepare_page_table(void)
 }
 
 /*
- * Reserve the various regions of node 0
+ * Reserve the special regions of memory
  */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
 {
-	unsigned long res_size = 0;
-
-	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
 	/*
 	 * Reserve the page tables.  These are already in use,
 	 * and can only be in node 0.
 	 */
-	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
-			     PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT);
-
-	/*
-	 * Hmm... This should go elsewhere, but we really really need to
-	 * stop things allocating the low memory; ideally we need a better
-	 * implementation of GFP_DMA which does not assume that DMA-able
-	 * memory starts at zero.
-	 */
-	if (machine_is_integrator() || machine_is_cintegrator())
-		res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
-
-	/*
-	 * These should likewise go elsewhere.  They pre-reserve the
-	 * screen memory region at the start of main system memory.
-	 */
-	if (machine_is_edb7211())
-		res_size = 0x00020000;
-	if (machine_is_p720t())
-		res_size = 0x00014000;
-
-	/* H1940 and RX3715 need to reserve this for suspend */
-
-	if (machine_is_h1940() || machine_is_rx3715()) {
-		reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
-				BOOTMEM_DEFAULT);
-		reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
-				BOOTMEM_DEFAULT);
-	}
-
-	if (machine_is_palmld() || machine_is_palmtx()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_treo680() || machine_is_centro()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa2000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_palmt5())
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-
-	/*
-	 * U300 - This platform family can share physical memory
-	 * between two ARM cpus, one running Linux and the other
-	 * running another OS.
-	 */
-	if (machine_is_u300()) {
-#ifdef CONFIG_MACH_U300_SINGLE_RAM
-#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) &&	\
-	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
-		res_size = 0x00100000;
-#endif
-#endif
-	}
+	lmb_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
 
 #ifdef CONFIG_SA1111
 	/*
 	 * Because of the SA1111 DMA bug, we want to preserve our
 	 * precious DMA-able memory...
 	 */
-	res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+	lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
 #endif
-	if (res_size)
-		reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size,
-				BOOTMEM_DEFAULT);
 }
 
 /*
@@ -934,7 +868,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 	/*
 	 * Allocate the vector page early.
 	 */
-	vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+	vectors = early_alloc(PAGE_SIZE);
 
 	for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
 		pmd_clear(pmd_off_k(addr));
@@ -1006,13 +940,46 @@ static void __init kmap_init(void)
 {
 #ifdef CONFIG_HIGHMEM
 	pmd_t *pmd = pmd_off_k(PKMAP_BASE);
-	pte_t *pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+	pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
 	BUG_ON(!pmd_none(*pmd) || !pte);
 	__pmd_populate(pmd, __pa(pte) | _PAGE_KERNEL_TABLE);
 	pkmap_page_table = pte + PTRS_PER_PTE;
 #endif
 }
 
+static inline void map_memory_bank(struct membank *bank)
+{
+	struct map_desc map;
+
+	map.pfn = bank_pfn_start(bank);
+	map.virtual = __phys_to_virt(bank_phys_start(bank));
+	map.length = bank_phys_size(bank);
+	map.type = MT_MEMORY;
+
+	create_mapping(&map);
+}
+
+static void __init map_lowmem(void)
+{
+	struct meminfo *mi = &meminfo;
+	int i;
+
+	/* Map all the lowmem memory banks. */
+	for (i = 0; i < mi->nr_banks; i++) {
+		struct membank *bank = &mi->bank[i];
+
+		if (!bank->highmem)
+			map_memory_bank(bank);
+	}
+}
+
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+	const struct membank *a = _a, *b = _b;
+	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
@@ -1021,20 +988,22 @@ void __init paging_init(struct machine_desc *mdesc)
 {
 	void *zero_page;
 
+	sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
 	build_mem_type_table();
 	sanity_check_meminfo();
 	prepare_page_table();
-	bootmem_init();
+	map_lowmem();
 	devicemaps_init(mdesc);
 	kmap_init();
 
 	top_pmd = pmd_off_k(0xffff0000);
 
-	/*
-	 * allocate the zero page.  Note that this always succeeds and
-	 * returns a zeroed result.
-	 */
-	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+	/* allocate the zero page. */
+	zero_page = early_alloc(PAGE_SIZE);
+
+	bootmem_init();
+
 	empty_zero_page = virt_to_page(zero_page);
 	__flush_dcache_page(NULL, empty_zero_page);
 }
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 9bfeb6b..ce00558 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -6,8 +6,8 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/lmb.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
@@ -17,30 +17,14 @@
 
 #include "mm.h"
 
-/*
- * Reserve the various regions of node 0
- */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
 {
 	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
-	/*
 	 * Register the exception vector page.
 	 * some architectures which the DRAM is the exception vector to trap,
 	 * alloc_page breaks with error, although it is not NULL, but "0."
 	 */
-	reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE,
-			BOOTMEM_DEFAULT);
+	lmb_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
 }
 
 /*

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-03-25 23:32 ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-03-25 23:32 UTC (permalink / raw)
  To: linux-arm-kernel

LMB... logical memory blocks.

LM is a different method of managing memory regions during the early
boot period when the usual kernel memory allocators are not up and
running.  LMB has been in the kernel for quite some time, and is
already being used by Microblaze, PPC, SH and Sparc.  Maybe soon x86
as well.

The motivation for this is that there appears to be plans to kill off
the other method - bootmem.  (see discussions on the linux-arch ml.)

Plus points:
1. LMB can be told about all memory areas, and all reserved areas.

2. As a result, we get rid of the "guess where to put the bootmem bitmap"
   code which can sometimes end up overwriting initrds by asking lmb to
   find a suitable place which doesn't conflict with reserved areas.

3. Overall reduction in arch code.

Minus points:
1. breaks OMAP2,3,4 since it fiddles with bootmem in its map_io function
   for framebuffer stuff.  This needs reworking.

2. highmem is probably broken by this.

3. the highmem boundary (as far as lowmem lmb allocations are concerned)
   is set at PHYS_OFFSET + 32MB

4. sparsemem requires bootmem, so we can't get away from bootmem at the
   moment.

The patch below is the combined patch; individual patches can be found
in the arm:lmb patches on the website or the lmb branch of my git tree;
this should be considered unstable.

 arch/arm/Kconfig                         |    1 +
 arch/arm/include/asm/lmb.h               |   13 ++
 arch/arm/include/asm/mach/arch.h         |    1 +
 arch/arm/kernel/setup.c                  |   12 ++
 arch/arm/mach-clps711x/edb7211-arch.c    |    8 ++
 arch/arm/mach-clps711x/mm.c              |    1 -
 arch/arm/mach-integrator/common.h        |    1 +
 arch/arm/mach-integrator/core.c          |   11 ++
 arch/arm/mach-integrator/integrator_ap.c |    1 +
 arch/arm/mach-integrator/integrator_cp.c |    1 +
 arch/arm/mach-ixp4xx/common.c            |    1 -
 arch/arm/mach-omap1/board-htcherald.c    |    1 -
 arch/arm/mach-omap2/omap_hwmod.c         |    1 -
 arch/arm/mach-pxa/palmt5.c               |    7 +
 arch/arm/mach-pxa/palmtreo.c             |    9 ++
 arch/arm/mach-s3c2410/mach-h1940.c       |    9 ++
 arch/arm/mach-s3c2440/mach-rx3715.c      |    9 ++
 arch/arm/mach-u300/u300.c                |   17 +++
 arch/arm/mm/init.c                       |  184 +++++------------------------
 arch/arm/mm/mm.h                         |    8 +-
 arch/arm/mm/mmu.c                        |  153 ++++++++++---------------
 arch/arm/mm/nommu.c                      |   22 +---
 22 files changed, 198 insertions(+), 273 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c5408bf..48254a4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -10,6 +10,7 @@ config ARM
 	default y
 	select HAVE_AOUT
 	select HAVE_IDE
+	select HAVE_LMB
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select GENERIC_ATOMIC64 if (!CPU_32v6K)
diff --git a/arch/arm/include/asm/lmb.h b/arch/arm/include/asm/lmb.h
new file mode 100644
index 0000000..df083f1
--- /dev/null
+++ b/arch/arm/include/asm/lmb.h
@@ -0,0 +1,13 @@
+#ifndef _ASM_ARM_LMB_H
+#define _ASM_ARM_LMB_H
+
+#ifdef CONFIG_MMU
+extern phys_addr_t lowmem_end_addr;
+#define LMB_REAL_LIMIT	lowmem_end_addr
+#else
+#define LMB_REAL_LIMIT	0
+#endif
+
+extern void arm_lmb_reserve(void);
+
+#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index c59842d..f634dbe 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -37,6 +37,7 @@ struct machine_desc {
 	void			(*fixup)(struct machine_desc *,
 					 struct tag *, char **,
 					 struct meminfo *);
+	void			(*reserve)(void);/* reserve lmb blocks	*/
 	void			(*map_io)(void);/* IO mapping function	*/
 	void			(*init_irq)(void);
 	struct sys_timer	*timer;		/* system tick timer	*/
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c91c77b..23633ee 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -25,6 +25,7 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/lmb.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -666,6 +667,7 @@ void __init setup_arch(char **cmdline_p)
 	struct tag *tags = (struct tag *)&init_tags;
 	struct machine_desc *mdesc;
 	char *from = default_command_line;
+	int i;
 
 	unwind_init();
 
@@ -714,6 +716,16 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+	lmb_init();
+	for (i = 0; i < meminfo.nr_banks; i++)
+		lmb_add(meminfo.bank[i].start, meminfo.bank[i].size);
+
+	arm_lmb_reserve();
+
+	/* reserve any lmb areas */
+	if (mdesc->reserve)
+		mdesc->reserve();
+
 	paging_init(mdesc);
 	request_standard_resources(&meminfo, mdesc);
 
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index dc81cc6..aba952c 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/lmb.h>
 #include <linux/types.h>
 #include <linux/string.h>
 
@@ -29,6 +30,12 @@
 
 extern void edb7211_map_io(void);
 
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+	lmb_reserve(PHYS_OFFSET, 0x00020000);
+}
+
 static void __init
 fixup_edb7211(struct machine_desc *desc, struct tag *tags,
 	      char **cmdline, struct meminfo *mi)
@@ -57,6 +64,7 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
 	.boot_params	= 0xc0020100,	/* 0xc0000000 - 0xc001ffff can be video RAM */
 	.fixup		= fixup_edb7211,
 	.map_io		= edb7211_map_io,
+	.reserve	= edb7211_reserve,
 	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
index a7b4591..9865921 100644
--- a/arch/arm/mach-clps711x/mm.c
+++ b/arch/arm/mach-clps711x/mm.c
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index 609c49d..87cfeed 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1,2 +1,3 @@
 extern void integrator_time_init(unsigned long, unsigned int);
 extern unsigned long integrator_gettimeoffset(void);
+void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8b390e3..417c772 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/lmb.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/termios.h>
@@ -334,3 +335,13 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
 	 */
 	setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
 }
+
+/*
+ * We need to stop things allocating the low memory; ideally we need a
+ * better implementation of GFP_DMA which does not assume that DMA-able
+ * memory starts at zero.
+ */
+void __init integrator_reserve(void)
+{
+	lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 8138a7e..9fbde0d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -350,6 +350,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= ap_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= ap_init_irq,
 	.timer		= &ap_timer,
 	.init_machine	= ap_init,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 66ef86d..8de5f35 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -585,6 +585,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= intcp_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= intcp_init_irq,
 	.timer		= &cp_timer,
 	.init_machine	= intcp_init,
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71728d3..0bce097 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -21,7 +21,6 @@
 #include <linux/tty.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
-#include <linux/bootmem.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/time.h>
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index e36639f..8e313b4 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index c664947..aa3e209 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -43,7 +43,6 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/bootmem.h>
 
 #include <plat/common.h>
 #include <plat/cpu.h>
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index d902a81..b33fbe3 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/lmb.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -396,6 +397,11 @@ static void __init palmt5_udc_init(void)
 	}
 }
 
+static void __init palmt5_reserve(void)
+{
+	lmb_reserve(0xa0200000, 0x1000);
+}
+
 static void __init palmt5_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
@@ -421,6 +427,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5")
 	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
 	.boot_params	= 0xa0000100,
 	.map_io		= pxa_map_io,
+	.reserve	= palmt5_reserve,
 	.init_irq	= pxa27x_init_irq,
 	.timer		= &pxa_timer,
 	.init_machine	= palmt5_init
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index d8b4469..e712b86 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/lmb.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -633,6 +634,12 @@ static void __init treo_lcd_power_init(void)
 	treo_lcd_screen.pxafb_lcd_power = treo_lcd_power;
 }
 
+static void __init treo_reserve(void)
+{
+	lmb_reserve(0xa0000000, 0x1000);
+	lmb_reserve(0xa2000000, 0x1000);
+}
+
 static void __init treo_init(void)
 {
 	pxa_set_ffuart_info(NULL);
@@ -668,6 +675,7 @@ MACHINE_START(TREO680, "Palm Treo 680")
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
 	.init_machine   = treo680_init,
@@ -691,6 +699,7 @@ MACHINE_START(CENTRO, "Palm Centro 685")
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
        .init_machine   = centro_init,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index fbedd07..bfbcdd0 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/lmb.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
@@ -301,6 +302,13 @@ static void __init h1940_map_io(void)
 	s3c_pm_init();
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init h1940_reserve(void)
+{
+	lmb_reserve(0x30003000, 0x1000);
+	lmb_reserve(0x30081000, 0x1000);
+}
+
 static void __init h1940_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -342,6 +350,7 @@ MACHINE_START(H1940, "IPAQ-H1940")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= h1940_map_io,
+	.reserve	= h1940_reserve,
 	.init_irq	= h1940_init_irq,
 	.init_machine	= h1940_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 1e836e5..76aa734 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/lmb.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/tty.h>
@@ -191,6 +192,13 @@ static void __init rx3715_map_io(void)
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx3715_reserve(void)
+{
+	lmb_reserve(0x30003000, 0x1000);
+	lmb_reserve(0x30081000, 0x1000);
+}
+
 static void __init rx3715_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -214,6 +222,7 @@ MACHINE_START(RX3715, "IPAQ-RX3715")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= rx3715_map_io,
+	.reserve	= rx3715_reserve,
 	.init_irq	= rx3715_init_irq,
 	.init_machine	= rx3715_init_machine,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index d2a0b88..4fb8660 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/lmb.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <mach/hardware.h>
@@ -22,6 +23,21 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+static void __init u300_reserve(void)
+{
+	/*
+	 * U300 - This platform family can share physical memory
+	 * between two ARM cpus, one running Linux and the other
+	 * running another OS.
+	 */
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+        lmb_reserve(PHYS_OFFSET, 0x00100000);
+#endif
+#endif
+}
+
 static void __init u300_init_machine(void)
 {
 	u300_init_devices();
@@ -49,6 +65,7 @@ MACHINE_START(U300, MACH_U300_STRING)
 	.io_pg_offst	= ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
 	.boot_params	= BOOT_PARAMS_OFFSET,
 	.map_io		= u300_map_io,
+	.reserve	= u300_reserve,
 	.init_irq	= u300_init_irq,
 	.timer		= &u300_timer,
 	.init_machine	= u300_init_machine,
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7829cb5..e714bb2 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,8 +15,8 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
-#include <linux/sort.h>
 #include <linux/highmem.h>
+#include <linux/lmb.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -150,119 +150,21 @@ static void __init find_node_limits(int node, struct meminfo *mi,
 	}
 }
 
-/*
- * FIXME: We really want to avoid allocating the bootmap bitmap
- * over the top of the initrd.  Hopefully, this is located towards
- * the start of a bank, so if we allocate the bootmap bitmap at
- * the end, we won't clash.
- */
-static unsigned int __init
-find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
-{
-	unsigned int start_pfn, i, bootmap_pfn;
-
-	start_pfn   = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT;
-	bootmap_pfn = 0;
-
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-		unsigned int start, end;
-
-		start = bank_pfn_start(bank);
-		end   = bank_pfn_end(bank);
-
-		if (end < start_pfn)
-			continue;
-
-		if (start < start_pfn)
-			start = start_pfn;
-
-		if (end <= start)
-			continue;
-
-		if (end - start >= bootmap_pages) {
-			bootmap_pfn = start;
-			break;
-		}
-	}
-
-	if (bootmap_pfn == 0)
-		BUG();
-
-	return bootmap_pfn;
-}
-
-static int __init check_initrd(struct meminfo *mi)
-{
-	int initrd_node = -2;
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long end = phys_initrd_start + phys_initrd_size;
-
-	/*
-	 * Make sure that the initrd is within a valid area of
-	 * memory.
-	 */
-	if (phys_initrd_size) {
-		unsigned int i;
-
-		initrd_node = -1;
-
-		for (i = 0; i < mi->nr_banks; i++) {
-			struct membank *bank = &mi->bank[i];
-			if (bank_phys_start(bank) <= phys_initrd_start &&
-			    end <= bank_phys_end(bank))
-				initrd_node = bank->node;
-		}
-	}
-
-	if (initrd_node == -1) {
-		printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
-		       "physical memory - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
-		phys_initrd_start = phys_initrd_size = 0;
-	}
-#endif
-
-	return initrd_node;
-}
-
-static inline void map_memory_bank(struct membank *bank)
-{
-#ifdef CONFIG_MMU
-	struct map_desc map;
-
-	map.pfn = bank_pfn_start(bank);
-	map.virtual = __phys_to_virt(bank_phys_start(bank));
-	map.length = bank_phys_size(bank);
-	map.type = MT_MEMORY;
-
-	create_mapping(&map);
-#endif
-}
-
 static void __init bootmem_init_node(int node, struct meminfo *mi,
 	unsigned long start_pfn, unsigned long end_pfn)
 {
-	unsigned long boot_pfn;
 	unsigned int boot_pages;
+	phys_addr_t bitmap;
 	pg_data_t *pgdat;
 	int i;
 
 	/*
-	 * Map the memory banks for this node.
-	 */
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-
-		if (!bank->highmem)
-			map_memory_bank(bank);
-	}
-
-	/*
-	 * Allocate the bootmem bitmap page.
+	 * Allocate the bootmem bitmap page.  This must be in a region
+	 * of memory which has already been mapped.
 	 */
 	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
-	boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
+	bitmap = lmb_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES,
+				__pfn_to_phys(end_pfn));
 
 	/*
 	 * Initialise the bootmem allocator for this node, handing the
@@ -270,7 +172,7 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
 	 */
 	node_set_online(node);
 	pgdat = NODE_DATA(node);
-	init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+	init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
 
 	for_each_nodebank(i, mi, node) {
 		struct membank *bank = &mi->bank[i];
@@ -279,31 +181,16 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
 	}
 
 	/*
-	 * Reserve the bootmem bitmap for this node.
+	 * Reserve the LMB reserved regions in bootmem for this node.
 	 */
-	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
-			     boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
-}
-
-static void __init bootmem_reserve_initrd(int node)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	pg_data_t *pgdat = NODE_DATA(node);
-	int res;
-
-	res = reserve_bootmem_node(pgdat, phys_initrd_start,
-			     phys_initrd_size, BOOTMEM_EXCLUSIVE);
-
-	if (res == 0) {
-		initrd_start = __phys_to_virt(phys_initrd_start);
-		initrd_end = initrd_start + phys_initrd_size;
-	} else {
-		printk(KERN_ERR
-			"INITRD: 0x%08lx+0x%08lx overlaps in-use "
-			"memory region - disabling initrd\n",
-			phys_initrd_start, phys_initrd_size);
+	for (i = 0; i < lmb.reserved.cnt; i++) {
+		phys_addr_t start = lmb_start_pfn(&lmb.reserved, i);
+		if (start >= start_pfn &&
+		    lmb_end_pfn(&lmb.reserved, i) <= end_pfn)
+			reserve_bootmem_node(pgdat, __pfn_to_phys(start),
+				lmb_size_bytes(&lmb.reserved, i),
+				BOOTMEM_DEFAULT);
 	}
-#endif
 }
 
 static void __init bootmem_free_node(int node, struct meminfo *mi)
@@ -387,25 +274,23 @@ static void arm_memory_present(struct meminfo *mi, int node)
 }
 #endif
 
-static int __init meminfo_cmp(const void *_a, const void *_b)
+void __init arm_lmb_reserve(void)
 {
-	const struct membank *a = _a, *b = _b;
-	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
-	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+	/* Register the kernel text, kernel data and initrd with lmb. */
+#ifdef CONFIG_XIP_KERNEL
+	lmb_reserve(__pa(_data), _end - _data);
+#else
+	lmb_reserve(__pa(_stext), _end - _stext);
+#endif
+	lmb_reserve(phys_initrd_start, phys_initrd_size);
+	arm_mm_lmb_reserve();
 }
 
 void __init bootmem_init(void)
 {
 	struct meminfo *mi = &meminfo;
 	unsigned long min, max_low, max_high;
-	int node, initrd_node;
-
-	sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
-
-	/*
-	 * Locate which node contains the ramdisk image, if any.
-	 */
-	initrd_node = check_initrd(mi);
+	int node;
 
 	max_low = max_high = 0;
 
@@ -432,18 +317,6 @@ void __init bootmem_init(void)
 		bootmem_init_node(node, mi, min, node_low);
 
 		/*
-		 * Reserve any special node zero regions.
-		 */
-		if (node == 0)
-			reserve_node_zero(NODE_DATA(node));
-
-		/*
-		 * If the initrd is in this node, reserve its memory.
-		 */
-		if (node == initrd_node)
-			bootmem_reserve_initrd(node);
-
-		/*
 		 * Sparsemem tries to allocate bootmem in memory_present(),
 		 * so must be done after the fixed reservations
 		 */
@@ -566,6 +439,13 @@ void __init mem_init(void)
 	unsigned long reserved_pages, free_pages;
 	int i, node;
 
+#ifdef CONFIG_SA1111
+	lmb_free(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+#endif
+
+	lmb_analyze();
+	lmb_dump_all();
+
 #ifndef CONFIG_DISCONTIGMEM
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 #endif
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a888363..966dc45 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -28,10 +28,6 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
 
 #endif
 
-struct map_desc;
-struct meminfo;
-struct pglist_data;
-
-void __init create_mapping(struct map_desc *md);
 void __init bootmem_init(void);
-void reserve_node_zero(struct pglist_data *pgdat);
+void arm_lmb_reserve(void);
+void arm_mm_lmb_reserve(void);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9d4da6a..81eb08a 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -11,9 +11,10 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
+#include <linux/lmb.h>
+#include <linux/sort.h>
 
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
@@ -483,6 +484,13 @@ static void __init build_mem_type_table(void)
 
 #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
 
+static void __init *early_alloc(unsigned long sz)
+{
+	void *ptr = __va(lmb_alloc(sz, sz));
+	memset(ptr, 0, PAGE_SIZE);
+	return ptr;
+}
+
 static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 				  unsigned long end, unsigned long pfn,
 				  const struct mem_type *type)
@@ -490,7 +498,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 	pte_t *pte;
 
 	if (pmd_none(*pmd)) {
-		pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+		pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
 		__pmd_populate(pmd, __pa(pte) | type->prot_l1);
 	}
 
@@ -599,7 +607,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
  * offsets, and we take full advantage of sections and
  * supersections.
  */
-void __init create_mapping(struct map_desc *md)
+static void __init create_mapping(struct map_desc *md)
 {
 	unsigned long phys, addr, length, end;
 	const struct mem_type *type;
@@ -693,6 +701,9 @@ early_param("vmalloc", early_vmalloc);
 
 #define VMALLOC_MIN	(void *)(VMALLOC_END - vmalloc_reserve)
 
+/* FIXME: we need to teach LMB about the highmem boundary */
+phys_addr_t lowmem_end_addr = PHYS_OFFSET + 32*1048576;
+
 static void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
@@ -822,100 +833,23 @@ static inline void prepare_page_table(void)
 }
 
 /*
- * Reserve the various regions of node 0
+ * Reserve the special regions of memory
  */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
 {
-	unsigned long res_size = 0;
-
-	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
 	/*
 	 * Reserve the page tables.  These are already in use,
 	 * and can only be in node 0.
 	 */
-	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
-			     PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT);
-
-	/*
-	 * Hmm... This should go elsewhere, but we really really need to
-	 * stop things allocating the low memory; ideally we need a better
-	 * implementation of GFP_DMA which does not assume that DMA-able
-	 * memory starts at zero.
-	 */
-	if (machine_is_integrator() || machine_is_cintegrator())
-		res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
-
-	/*
-	 * These should likewise go elsewhere.  They pre-reserve the
-	 * screen memory region at the start of main system memory.
-	 */
-	if (machine_is_edb7211())
-		res_size = 0x00020000;
-	if (machine_is_p720t())
-		res_size = 0x00014000;
-
-	/* H1940 and RX3715 need to reserve this for suspend */
-
-	if (machine_is_h1940() || machine_is_rx3715()) {
-		reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
-				BOOTMEM_DEFAULT);
-		reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
-				BOOTMEM_DEFAULT);
-	}
-
-	if (machine_is_palmld() || machine_is_palmtx()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_treo680() || machine_is_centro()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa2000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_palmt5())
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-
-	/*
-	 * U300 - This platform family can share physical memory
-	 * between two ARM cpus, one running Linux and the other
-	 * running another OS.
-	 */
-	if (machine_is_u300()) {
-#ifdef CONFIG_MACH_U300_SINGLE_RAM
-#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) &&	\
-	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
-		res_size = 0x00100000;
-#endif
-#endif
-	}
+	lmb_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
 
 #ifdef CONFIG_SA1111
 	/*
 	 * Because of the SA1111 DMA bug, we want to preserve our
 	 * precious DMA-able memory...
 	 */
-	res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+	lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
 #endif
-	if (res_size)
-		reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size,
-				BOOTMEM_DEFAULT);
 }
 
 /*
@@ -934,7 +868,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 	/*
 	 * Allocate the vector page early.
 	 */
-	vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+	vectors = early_alloc(PAGE_SIZE);
 
 	for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
 		pmd_clear(pmd_off_k(addr));
@@ -1006,13 +940,46 @@ static void __init kmap_init(void)
 {
 #ifdef CONFIG_HIGHMEM
 	pmd_t *pmd = pmd_off_k(PKMAP_BASE);
-	pte_t *pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+	pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
 	BUG_ON(!pmd_none(*pmd) || !pte);
 	__pmd_populate(pmd, __pa(pte) | _PAGE_KERNEL_TABLE);
 	pkmap_page_table = pte + PTRS_PER_PTE;
 #endif
 }
 
+static inline void map_memory_bank(struct membank *bank)
+{
+	struct map_desc map;
+
+	map.pfn = bank_pfn_start(bank);
+	map.virtual = __phys_to_virt(bank_phys_start(bank));
+	map.length = bank_phys_size(bank);
+	map.type = MT_MEMORY;
+
+	create_mapping(&map);
+}
+
+static void __init map_lowmem(void)
+{
+	struct meminfo *mi = &meminfo;
+	int i;
+
+	/* Map all the lowmem memory banks. */
+	for (i = 0; i < mi->nr_banks; i++) {
+		struct membank *bank = &mi->bank[i];
+
+		if (!bank->highmem)
+			map_memory_bank(bank);
+	}
+}
+
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+	const struct membank *a = _a, *b = _b;
+	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
@@ -1021,20 +988,22 @@ void __init paging_init(struct machine_desc *mdesc)
 {
 	void *zero_page;
 
+	sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
 	build_mem_type_table();
 	sanity_check_meminfo();
 	prepare_page_table();
-	bootmem_init();
+	map_lowmem();
 	devicemaps_init(mdesc);
 	kmap_init();
 
 	top_pmd = pmd_off_k(0xffff0000);
 
-	/*
-	 * allocate the zero page.  Note that this always succeeds and
-	 * returns a zeroed result.
-	 */
-	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+	/* allocate the zero page. */
+	zero_page = early_alloc(PAGE_SIZE);
+
+	bootmem_init();
+
 	empty_zero_page = virt_to_page(zero_page);
 	__flush_dcache_page(NULL, empty_zero_page);
 }
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 9bfeb6b..ce00558 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -6,8 +6,8 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/lmb.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
@@ -17,30 +17,14 @@
 
 #include "mm.h"
 
-/*
- * Reserve the various regions of node 0
- */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
 {
 	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
-	/*
 	 * Register the exception vector page.
 	 * some architectures which the DRAM is the exception vector to trap,
 	 * alloc_page breaks with error, although it is not NULL, but "0."
 	 */
-	reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE,
-			BOOTMEM_DEFAULT);
+	lmb_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
 }
 
 /*

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-03-25 23:32 ` Russell King - ARM Linux
@ 2010-03-31  6:43   ` Jeremy Kerr
  -1 siblings, 0 replies; 80+ messages in thread
From: Jeremy Kerr @ 2010-03-31  6:43 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Russell King - ARM Linux, Tony Lindgren, linux-omap

Hi Russell,

> LMB... logical memory blocks.

Nice, will be good for the DT work too.

> @@ -483,6 +484,13 @@ static void __init build_mem_type_table(void)
> 
>  #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
> 
> +static void __init *early_alloc(unsigned long sz)
> +{
> +      void *ptr = __va(lmb_alloc(sz, sz));
> +      memset(ptr, 0, PAGE_SIZE);

memset(ptr, 0, sz) ?

Cheers,


Jeremy


^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-03-31  6:43   ` Jeremy Kerr
  0 siblings, 0 replies; 80+ messages in thread
From: Jeremy Kerr @ 2010-03-31  6:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

> LMB... logical memory blocks.

Nice, will be good for the DT work too.

> @@ -483,6 +484,13 @@ static void __init build_mem_type_table(void)
> 
>  #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
> 
> +static void __init *early_alloc(unsigned long sz)
> +{
> +      void *ptr = __va(lmb_alloc(sz, sz));
> +      memset(ptr, 0, PAGE_SIZE);

memset(ptr, 0, sz) ?

Cheers,


Jeremy

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-03-31  6:43   ` Jeremy Kerr
@ 2010-04-01  9:47     ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-04-01  9:47 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linux-arm-kernel, Russell King - ARM Linux, linux-omap

* Jeremy Kerr <jeremy.kerr@canonical.com> [100330 23:39]:
> Hi Russell,
> 
> > LMB... logical memory blocks.
> 
> Nice, will be good for the DT work too.

Great, very nice clean up!

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-01  9:47     ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-04-01  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

* Jeremy Kerr <jeremy.kerr@canonical.com> [100330 23:39]:
> Hi Russell,
> 
> > LMB... logical memory blocks.
> 
> Nice, will be good for the DT work too.

Great, very nice clean up!

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-03-25 23:32 ` Russell King - ARM Linux
@ 2010-04-08 15:32   ` Rabin Vincent
  -1 siblings, 0 replies; 80+ messages in thread
From: Rabin Vincent @ 2010-04-08 15:32 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Tony Lindgren, linux-omap, linux-arm-kernel

On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> The patch below is the combined patch; individual patches can be found
> in the arm:lmb patches on the website or the lmb branch of my git tree;
> this should be considered unstable.

Something like the following is needed to make initrds work after this
patch:

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8b2853a..8c12214 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/swap.h>
 #include <linux/init.h>
+#include <linux/initrd.h>
 #include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
@@ -32,9 +33,6 @@
 
 #include "mm.h"
 
-static unsigned long phys_initrd_start __initdata = 0;
-static unsigned long phys_initrd_size __initdata = 0;
-
 static int __init early_initrd(char *p)
 {
 	unsigned long start, size;
@@ -44,8 +42,8 @@ static int __init early_initrd(char *p)
 	if (*endp == ',') {
 		size = memparse(endp + 1, NULL);
 
-		phys_initrd_start = start;
-		phys_initrd_size = size;
+		initrd_start = __phys_to_virt(start);
+		initrd_end = initrd_start + size;
 	}
 	return 0;
 }
@@ -55,8 +53,8 @@ static int __init parse_tag_initrd(const struct tag *tag)
 {
 	printk(KERN_WARNING "ATAG_INITRD is deprecated; "
 		"please update your bootloader.\n");
-	phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
-	phys_initrd_size = tag->u.initrd.size;
+	initrd_start = tag->u.initrd.start;
+	initrd_end = initrd_start + tag->u.initrd.size;
 	return 0;
 }
 
@@ -64,8 +62,8 @@ __tagtable(ATAG_INITRD, parse_tag_initrd);
 
 static int __init parse_tag_initrd2(const struct tag *tag)
 {
-	phys_initrd_start = tag->u.initrd.start;
-	phys_initrd_size = tag->u.initrd.size;
+	initrd_start = __phys_to_virt(tag->u.initrd.start);
+	initrd_end = initrd_start + tag->u.initrd.size;
 	return 0;
 }
 
@@ -284,7 +282,7 @@ void __init arm_lmb_reserve(void)
 #else
 	lmb_reserve(__pa(_stext), _end - _stext);
 #endif
-	lmb_reserve(phys_initrd_start, phys_initrd_size);
+	lmb_reserve(__pa(initrd_start), initrd_end - initrd_start);
 	arm_mm_lmb_reserve();
 }

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-08 15:32   ` Rabin Vincent
  0 siblings, 0 replies; 80+ messages in thread
From: Rabin Vincent @ 2010-04-08 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> The patch below is the combined patch; individual patches can be found
> in the arm:lmb patches on the website or the lmb branch of my git tree;
> this should be considered unstable.

Something like the following is needed to make initrds work after this
patch:

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8b2853a..8c12214 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/swap.h>
 #include <linux/init.h>
+#include <linux/initrd.h>
 #include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
@@ -32,9 +33,6 @@
 
 #include "mm.h"
 
-static unsigned long phys_initrd_start __initdata = 0;
-static unsigned long phys_initrd_size __initdata = 0;
-
 static int __init early_initrd(char *p)
 {
 	unsigned long start, size;
@@ -44,8 +42,8 @@ static int __init early_initrd(char *p)
 	if (*endp == ',') {
 		size = memparse(endp + 1, NULL);
 
-		phys_initrd_start = start;
-		phys_initrd_size = size;
+		initrd_start = __phys_to_virt(start);
+		initrd_end = initrd_start + size;
 	}
 	return 0;
 }
@@ -55,8 +53,8 @@ static int __init parse_tag_initrd(const struct tag *tag)
 {
 	printk(KERN_WARNING "ATAG_INITRD is deprecated; "
 		"please update your bootloader.\n");
-	phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
-	phys_initrd_size = tag->u.initrd.size;
+	initrd_start = tag->u.initrd.start;
+	initrd_end = initrd_start + tag->u.initrd.size;
 	return 0;
 }
 
@@ -64,8 +62,8 @@ __tagtable(ATAG_INITRD, parse_tag_initrd);
 
 static int __init parse_tag_initrd2(const struct tag *tag)
 {
-	phys_initrd_start = tag->u.initrd.start;
-	phys_initrd_size = tag->u.initrd.size;
+	initrd_start = __phys_to_virt(tag->u.initrd.start);
+	initrd_end = initrd_start + tag->u.initrd.size;
 	return 0;
 }
 
@@ -284,7 +282,7 @@ void __init arm_lmb_reserve(void)
 #else
 	lmb_reserve(__pa(_stext), _end - _stext);
 #endif
-	lmb_reserve(phys_initrd_start, phys_initrd_size);
+	lmb_reserve(__pa(initrd_start), initrd_end - initrd_start);
 	arm_mm_lmb_reserve();
 }
 

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-04-08 15:32   ` Rabin Vincent
@ 2010-04-08 18:27     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-04-08 18:27 UTC (permalink / raw)
  To: Rabin Vincent; +Cc: linux-arm-kernel, Tony Lindgren, linux-omap

On Thu, Apr 08, 2010 at 09:02:56PM +0530, Rabin Vincent wrote:
> On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> > The patch below is the combined patch; individual patches can be found
> > in the arm:lmb patches on the website or the lmb branch of my git tree;
> > this should be considered unstable.
> 
> Something like the following is needed to make initrds work after this
> patch:

This to me looks like a very large patch for what is a small problem -
that is the assignment of initrd_start/initrd_size got lost along the
way.

I'd much rather have the smaller patch; keep the initrd parameters in
the physical address space for as long as possible, and only convert
them to the virtual address space once we've finished mm initialisation.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-08 18:27     ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-04-08 18:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 08, 2010 at 09:02:56PM +0530, Rabin Vincent wrote:
> On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> > The patch below is the combined patch; individual patches can be found
> > in the arm:lmb patches on the website or the lmb branch of my git tree;
> > this should be considered unstable.
> 
> Something like the following is needed to make initrds work after this
> patch:

This to me looks like a very large patch for what is a small problem -
that is the assignment of initrd_start/initrd_size got lost along the
way.

I'd much rather have the smaller patch; keep the initrd parameters in
the physical address space for as long as possible, and only convert
them to the virtual address space once we've finished mm initialisation.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-04-08 18:27     ` Russell King - ARM Linux
@ 2010-04-09 11:11       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-04-09 11:11 UTC (permalink / raw)
  To: Rabin Vincent; +Cc: Tony Lindgren, linux-omap, linux-arm-kernel

On Thu, Apr 08, 2010 at 07:27:15PM +0100, Russell King - ARM Linux wrote:
> On Thu, Apr 08, 2010 at 09:02:56PM +0530, Rabin Vincent wrote:
> > On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> > > The patch below is the combined patch; individual patches can be found
> > > in the arm:lmb patches on the website or the lmb branch of my git tree;
> > > this should be considered unstable.
> > 
> > Something like the following is needed to make initrds work after this
> > patch:
> 
> This to me looks like a very large patch for what is a small problem -
> that is the assignment of initrd_start/initrd_size got lost along the
> way.
> 
> I'd much rather have the smaller patch; keep the initrd parameters in
> the physical address space for as long as possible, and only convert
> them to the virtual address space once we've finished mm initialisation.

Here's a revised version which should resolve the initrd problem.

 arch/arm/Kconfig                         |    1 +
 arch/arm/include/asm/lmb.h               |   16 +++
 arch/arm/include/asm/mach/arch.h         |    1 +
 arch/arm/kernel/setup.c                  |    3 +
 arch/arm/mach-clps711x/edb7211-arch.c    |    8 ++
 arch/arm/mach-clps711x/mm.c              |    1 -
 arch/arm/mach-integrator/common.h        |    1 +
 arch/arm/mach-integrator/core.c          |   11 ++
 arch/arm/mach-integrator/integrator_ap.c |    1 +
 arch/arm/mach-integrator/integrator_cp.c |    1 +
 arch/arm/mach-ixp4xx/common.c            |    1 -
 arch/arm/mach-omap1/board-htcherald.c    |    1 -
 arch/arm/mach-omap2/omap_hwmod.c         |    1 -
 arch/arm/mach-pxa/palmt5.c               |    7 +
 arch/arm/mach-pxa/palmtreo.c             |    9 ++
 arch/arm/mach-s3c2410/mach-h1940.c       |    9 ++
 arch/arm/mach-s3c2440/mach-rx3715.c      |    9 ++
 arch/arm/mach-u300/u300.c                |   17 +++
 arch/arm/mm/init.c                       |  202 ++++++++----------------------
 arch/arm/mm/mm.h                         |    8 +-
 arch/arm/mm/mmu.c                        |  153 +++++++++--------------
 arch/arm/mm/nommu.c                      |   22 +---
 22 files changed, 210 insertions(+), 273 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c5408bf..48254a4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -10,6 +10,7 @@ config ARM
 	default y
 	select HAVE_AOUT
 	select HAVE_IDE
+	select HAVE_LMB
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select GENERIC_ATOMIC64 if (!CPU_32v6K)
diff --git a/arch/arm/include/asm/lmb.h b/arch/arm/include/asm/lmb.h
new file mode 100644
index 0000000..1f49657
--- /dev/null
+++ b/arch/arm/include/asm/lmb.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_ARM_LMB_H
+#define _ASM_ARM_LMB_H
+
+#ifdef CONFIG_MMU
+extern phys_addr_t lowmem_end_addr;
+#define LMB_REAL_LIMIT	lowmem_end_addr
+#else
+#define LMB_REAL_LIMIT	0
+#endif
+
+struct meminfo;
+struct machine_desc;
+
+extern void arm_lmb_init(struct meminfo *, struct machine_desc *);
+
+#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index c59842d..f634dbe 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -37,6 +37,7 @@ struct machine_desc {
 	void			(*fixup)(struct machine_desc *,
 					 struct tag *, char **,
 					 struct meminfo *);
+	void			(*reserve)(void);/* reserve lmb blocks	*/
 	void			(*map_io)(void);/* IO mapping function	*/
 	void			(*init_irq)(void);
 	struct sys_timer	*timer;		/* system tick timer	*/
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c91c77b..4f132f7 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -25,6 +25,7 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/lmb.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -714,6 +715,8 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+	arm_lmb_init(&meminfo, mdesc);
+
 	paging_init(mdesc);
 	request_standard_resources(&meminfo, mdesc);
 
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index dc81cc6..aba952c 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/lmb.h>
 #include <linux/types.h>
 #include <linux/string.h>
 
@@ -29,6 +30,12 @@
 
 extern void edb7211_map_io(void);
 
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+	lmb_reserve(PHYS_OFFSET, 0x00020000);
+}
+
 static void __init
 fixup_edb7211(struct machine_desc *desc, struct tag *tags,
 	      char **cmdline, struct meminfo *mi)
@@ -57,6 +64,7 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
 	.boot_params	= 0xc0020100,	/* 0xc0000000 - 0xc001ffff can be video RAM */
 	.fixup		= fixup_edb7211,
 	.map_io		= edb7211_map_io,
+	.reserve	= edb7211_reserve,
 	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
index a7b4591..9865921 100644
--- a/arch/arm/mach-clps711x/mm.c
+++ b/arch/arm/mach-clps711x/mm.c
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index 609c49d..87cfeed 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1,2 +1,3 @@
 extern void integrator_time_init(unsigned long, unsigned int);
 extern unsigned long integrator_gettimeoffset(void);
+void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8b390e3..417c772 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/lmb.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/termios.h>
@@ -334,3 +335,13 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
 	 */
 	setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
 }
+
+/*
+ * We need to stop things allocating the low memory; ideally we need a
+ * better implementation of GFP_DMA which does not assume that DMA-able
+ * memory starts at zero.
+ */
+void __init integrator_reserve(void)
+{
+	lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 8138a7e..9fbde0d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -350,6 +350,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= ap_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= ap_init_irq,
 	.timer		= &ap_timer,
 	.init_machine	= ap_init,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 66ef86d..8de5f35 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -585,6 +585,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= intcp_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= intcp_init_irq,
 	.timer		= &cp_timer,
 	.init_machine	= intcp_init,
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71728d3..0bce097 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -21,7 +21,6 @@
 #include <linux/tty.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
-#include <linux/bootmem.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/time.h>
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index e36639f..8e313b4 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index c664947..aa3e209 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -43,7 +43,6 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/bootmem.h>
 
 #include <plat/common.h>
 #include <plat/cpu.h>
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index d902a81..b33fbe3 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/lmb.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -396,6 +397,11 @@ static void __init palmt5_udc_init(void)
 	}
 }
 
+static void __init palmt5_reserve(void)
+{
+	lmb_reserve(0xa0200000, 0x1000);
+}
+
 static void __init palmt5_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
@@ -421,6 +427,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5")
 	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
 	.boot_params	= 0xa0000100,
 	.map_io		= pxa_map_io,
+	.reserve	= palmt5_reserve,
 	.init_irq	= pxa27x_init_irq,
 	.timer		= &pxa_timer,
 	.init_machine	= palmt5_init
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index d8b4469..e712b86 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/lmb.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -633,6 +634,12 @@ static void __init treo_lcd_power_init(void)
 	treo_lcd_screen.pxafb_lcd_power = treo_lcd_power;
 }
 
+static void __init treo_reserve(void)
+{
+	lmb_reserve(0xa0000000, 0x1000);
+	lmb_reserve(0xa2000000, 0x1000);
+}
+
 static void __init treo_init(void)
 {
 	pxa_set_ffuart_info(NULL);
@@ -668,6 +675,7 @@ MACHINE_START(TREO680, "Palm Treo 680")
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
 	.init_machine   = treo680_init,
@@ -691,6 +699,7 @@ MACHINE_START(CENTRO, "Palm Centro 685")
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
        .init_machine   = centro_init,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index fbedd07..bfbcdd0 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/lmb.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
@@ -301,6 +302,13 @@ static void __init h1940_map_io(void)
 	s3c_pm_init();
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init h1940_reserve(void)
+{
+	lmb_reserve(0x30003000, 0x1000);
+	lmb_reserve(0x30081000, 0x1000);
+}
+
 static void __init h1940_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -342,6 +350,7 @@ MACHINE_START(H1940, "IPAQ-H1940")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= h1940_map_io,
+	.reserve	= h1940_reserve,
 	.init_irq	= h1940_init_irq,
 	.init_machine	= h1940_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 1e836e5..76aa734 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/lmb.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/tty.h>
@@ -191,6 +192,13 @@ static void __init rx3715_map_io(void)
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx3715_reserve(void)
+{
+	lmb_reserve(0x30003000, 0x1000);
+	lmb_reserve(0x30081000, 0x1000);
+}
+
 static void __init rx3715_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -214,6 +222,7 @@ MACHINE_START(RX3715, "IPAQ-RX3715")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= rx3715_map_io,
+	.reserve	= rx3715_reserve,
 	.init_irq	= rx3715_init_irq,
 	.init_machine	= rx3715_init_machine,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index d2a0b88..4fb8660 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/lmb.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <mach/hardware.h>
@@ -22,6 +23,21 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+static void __init u300_reserve(void)
+{
+	/*
+	 * U300 - This platform family can share physical memory
+	 * between two ARM cpus, one running Linux and the other
+	 * running another OS.
+	 */
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+        lmb_reserve(PHYS_OFFSET, 0x00100000);
+#endif
+#endif
+}
+
 static void __init u300_init_machine(void)
 {
 	u300_init_devices();
@@ -49,6 +65,7 @@ MACHINE_START(U300, MACH_U300_STRING)
 	.io_pg_offst	= ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
 	.boot_params	= BOOT_PARAMS_OFFSET,
 	.map_io		= u300_map_io,
+	.reserve	= u300_reserve,
 	.init_irq	= u300_init_irq,
 	.timer		= &u300_timer,
 	.init_machine	= u300_init_machine,
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7829cb5..6eb00f8 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,8 +15,8 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
-#include <linux/sort.h>
 #include <linux/highmem.h>
+#include <linux/lmb.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -150,119 +150,21 @@ static void __init find_node_limits(int node, struct meminfo *mi,
 	}
 }
 
-/*
- * FIXME: We really want to avoid allocating the bootmap bitmap
- * over the top of the initrd.  Hopefully, this is located towards
- * the start of a bank, so if we allocate the bootmap bitmap at
- * the end, we won't clash.
- */
-static unsigned int __init
-find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
-{
-	unsigned int start_pfn, i, bootmap_pfn;
-
-	start_pfn   = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT;
-	bootmap_pfn = 0;
-
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-		unsigned int start, end;
-
-		start = bank_pfn_start(bank);
-		end   = bank_pfn_end(bank);
-
-		if (end < start_pfn)
-			continue;
-
-		if (start < start_pfn)
-			start = start_pfn;
-
-		if (end <= start)
-			continue;
-
-		if (end - start >= bootmap_pages) {
-			bootmap_pfn = start;
-			break;
-		}
-	}
-
-	if (bootmap_pfn == 0)
-		BUG();
-
-	return bootmap_pfn;
-}
-
-static int __init check_initrd(struct meminfo *mi)
-{
-	int initrd_node = -2;
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long end = phys_initrd_start + phys_initrd_size;
-
-	/*
-	 * Make sure that the initrd is within a valid area of
-	 * memory.
-	 */
-	if (phys_initrd_size) {
-		unsigned int i;
-
-		initrd_node = -1;
-
-		for (i = 0; i < mi->nr_banks; i++) {
-			struct membank *bank = &mi->bank[i];
-			if (bank_phys_start(bank) <= phys_initrd_start &&
-			    end <= bank_phys_end(bank))
-				initrd_node = bank->node;
-		}
-	}
-
-	if (initrd_node == -1) {
-		printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
-		       "physical memory - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
-		phys_initrd_start = phys_initrd_size = 0;
-	}
-#endif
-
-	return initrd_node;
-}
-
-static inline void map_memory_bank(struct membank *bank)
-{
-#ifdef CONFIG_MMU
-	struct map_desc map;
-
-	map.pfn = bank_pfn_start(bank);
-	map.virtual = __phys_to_virt(bank_phys_start(bank));
-	map.length = bank_phys_size(bank);
-	map.type = MT_MEMORY;
-
-	create_mapping(&map);
-#endif
-}
-
 static void __init bootmem_init_node(int node, struct meminfo *mi,
 	unsigned long start_pfn, unsigned long end_pfn)
 {
-	unsigned long boot_pfn;
 	unsigned int boot_pages;
+	phys_addr_t bitmap;
 	pg_data_t *pgdat;
 	int i;
 
 	/*
-	 * Map the memory banks for this node.
-	 */
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-
-		if (!bank->highmem)
-			map_memory_bank(bank);
-	}
-
-	/*
-	 * Allocate the bootmem bitmap page.
+	 * Allocate the bootmem bitmap page.  This must be in a region
+	 * of memory which has already been mapped.
 	 */
 	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
-	boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
+	bitmap = lmb_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES,
+				__pfn_to_phys(end_pfn));
 
 	/*
 	 * Initialise the bootmem allocator for this node, handing the
@@ -270,7 +172,7 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
 	 */
 	node_set_online(node);
 	pgdat = NODE_DATA(node);
-	init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+	init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
 
 	for_each_nodebank(i, mi, node) {
 		struct membank *bank = &mi->bank[i];
@@ -279,31 +181,16 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
 	}
 
 	/*
-	 * Reserve the bootmem bitmap for this node.
+	 * Reserve the LMB reserved regions in bootmem for this node.
 	 */
-	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
-			     boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
-}
-
-static void __init bootmem_reserve_initrd(int node)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	pg_data_t *pgdat = NODE_DATA(node);
-	int res;
-
-	res = reserve_bootmem_node(pgdat, phys_initrd_start,
-			     phys_initrd_size, BOOTMEM_EXCLUSIVE);
-
-	if (res == 0) {
-		initrd_start = __phys_to_virt(phys_initrd_start);
-		initrd_end = initrd_start + phys_initrd_size;
-	} else {
-		printk(KERN_ERR
-			"INITRD: 0x%08lx+0x%08lx overlaps in-use "
-			"memory region - disabling initrd\n",
-			phys_initrd_start, phys_initrd_size);
+	for (i = 0; i < lmb.reserved.cnt; i++) {
+		phys_addr_t start = lmb_start_pfn(&lmb.reserved, i);
+		if (start >= start_pfn &&
+		    lmb_end_pfn(&lmb.reserved, i) <= end_pfn)
+			reserve_bootmem_node(pgdat, __pfn_to_phys(start),
+				lmb_size_bytes(&lmb.reserved, i),
+				BOOTMEM_DEFAULT);
 	}
-#endif
 }
 
 static void __init bootmem_free_node(int node, struct meminfo *mi)
@@ -387,25 +274,41 @@ static void arm_memory_present(struct meminfo *mi, int node)
 }
 #endif
 
-static int __init meminfo_cmp(const void *_a, const void *_b)
+void __init arm_lmb_init(struct meminfo *mi, struct machine_desc *mdesc)
 {
-	const struct membank *a = _a, *b = _b;
-	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
-	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+	int i;
+
+	for (i = 0; i < mi->nr_banks; i++)
+		lmb_add(mi->bank[i].start, mi->bank[i].size);
+
+	/* Register the kernel text, kernel data and initrd with lmb. */
+#ifdef CONFIG_XIP_KERNEL
+	lmb_reserve(__pa(_data), _end - _data);
+#else
+	lmb_reserve(__pa(_stext), _end - _stext);
+#endif
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (phys_initrd_size) {
+		lmb_reserve(phys_initrd_start, phys_initrd_size);
+
+		/* Now convert initrd to virtual addresses */
+		initrd_start = __phys_to_virt(phys_initrd_start);
+		initrd_end = initrd_start + phys_initrd_size;
+	}
+#endif
+
+	arm_mm_lmb_reserve();
+
+	/* reserve any lmb areas */
+	if (mdesc->reserve)
+		mdesc->reserve();
 }
 
 void __init bootmem_init(void)
 {
 	struct meminfo *mi = &meminfo;
 	unsigned long min, max_low, max_high;
-	int node, initrd_node;
-
-	sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
-
-	/*
-	 * Locate which node contains the ramdisk image, if any.
-	 */
-	initrd_node = check_initrd(mi);
+	int node;
 
 	max_low = max_high = 0;
 
@@ -432,18 +335,6 @@ void __init bootmem_init(void)
 		bootmem_init_node(node, mi, min, node_low);
 
 		/*
-		 * Reserve any special node zero regions.
-		 */
-		if (node == 0)
-			reserve_node_zero(NODE_DATA(node));
-
-		/*
-		 * If the initrd is in this node, reserve its memory.
-		 */
-		if (node == initrd_node)
-			bootmem_reserve_initrd(node);
-
-		/*
 		 * Sparsemem tries to allocate bootmem in memory_present(),
 		 * so must be done after the fixed reservations
 		 */
@@ -566,6 +457,13 @@ void __init mem_init(void)
 	unsigned long reserved_pages, free_pages;
 	int i, node;
 
+#ifdef CONFIG_SA1111
+	lmb_free(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+#endif
+
+	lmb_analyze();
+	lmb_dump_all();
+
 #ifndef CONFIG_DISCONTIGMEM
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 #endif
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a888363..966dc45 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -28,10 +28,6 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
 
 #endif
 
-struct map_desc;
-struct meminfo;
-struct pglist_data;
-
-void __init create_mapping(struct map_desc *md);
 void __init bootmem_init(void);
-void reserve_node_zero(struct pglist_data *pgdat);
+void arm_lmb_reserve(void);
+void arm_mm_lmb_reserve(void);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9d4da6a..81eb08a 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -11,9 +11,10 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
+#include <linux/lmb.h>
+#include <linux/sort.h>
 
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
@@ -483,6 +484,13 @@ static void __init build_mem_type_table(void)
 
 #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
 
+static void __init *early_alloc(unsigned long sz)
+{
+	void *ptr = __va(lmb_alloc(sz, sz));
+	memset(ptr, 0, PAGE_SIZE);
+	return ptr;
+}
+
 static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 				  unsigned long end, unsigned long pfn,
 				  const struct mem_type *type)
@@ -490,7 +498,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 	pte_t *pte;
 
 	if (pmd_none(*pmd)) {
-		pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+		pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
 		__pmd_populate(pmd, __pa(pte) | type->prot_l1);
 	}
 
@@ -599,7 +607,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
  * offsets, and we take full advantage of sections and
  * supersections.
  */
-void __init create_mapping(struct map_desc *md)
+static void __init create_mapping(struct map_desc *md)
 {
 	unsigned long phys, addr, length, end;
 	const struct mem_type *type;
@@ -693,6 +701,9 @@ early_param("vmalloc", early_vmalloc);
 
 #define VMALLOC_MIN	(void *)(VMALLOC_END - vmalloc_reserve)
 
+/* FIXME: we need to teach LMB about the highmem boundary */
+phys_addr_t lowmem_end_addr = PHYS_OFFSET + 32*1048576;
+
 static void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
@@ -822,100 +833,23 @@ static inline void prepare_page_table(void)
 }
 
 /*
- * Reserve the various regions of node 0
+ * Reserve the special regions of memory
  */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
 {
-	unsigned long res_size = 0;
-
-	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
 	/*
 	 * Reserve the page tables.  These are already in use,
 	 * and can only be in node 0.
 	 */
-	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
-			     PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT);
-
-	/*
-	 * Hmm... This should go elsewhere, but we really really need to
-	 * stop things allocating the low memory; ideally we need a better
-	 * implementation of GFP_DMA which does not assume that DMA-able
-	 * memory starts at zero.
-	 */
-	if (machine_is_integrator() || machine_is_cintegrator())
-		res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
-
-	/*
-	 * These should likewise go elsewhere.  They pre-reserve the
-	 * screen memory region at the start of main system memory.
-	 */
-	if (machine_is_edb7211())
-		res_size = 0x00020000;
-	if (machine_is_p720t())
-		res_size = 0x00014000;
-
-	/* H1940 and RX3715 need to reserve this for suspend */
-
-	if (machine_is_h1940() || machine_is_rx3715()) {
-		reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
-				BOOTMEM_DEFAULT);
-		reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
-				BOOTMEM_DEFAULT);
-	}
-
-	if (machine_is_palmld() || machine_is_palmtx()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_treo680() || machine_is_centro()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa2000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_palmt5())
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-
-	/*
-	 * U300 - This platform family can share physical memory
-	 * between two ARM cpus, one running Linux and the other
-	 * running another OS.
-	 */
-	if (machine_is_u300()) {
-#ifdef CONFIG_MACH_U300_SINGLE_RAM
-#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) &&	\
-	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
-		res_size = 0x00100000;
-#endif
-#endif
-	}
+	lmb_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
 
 #ifdef CONFIG_SA1111
 	/*
 	 * Because of the SA1111 DMA bug, we want to preserve our
 	 * precious DMA-able memory...
 	 */
-	res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+	lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
 #endif
-	if (res_size)
-		reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size,
-				BOOTMEM_DEFAULT);
 }
 
 /*
@@ -934,7 +868,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 	/*
 	 * Allocate the vector page early.
 	 */
-	vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+	vectors = early_alloc(PAGE_SIZE);
 
 	for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
 		pmd_clear(pmd_off_k(addr));
@@ -1006,13 +940,46 @@ static void __init kmap_init(void)
 {
 #ifdef CONFIG_HIGHMEM
 	pmd_t *pmd = pmd_off_k(PKMAP_BASE);
-	pte_t *pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+	pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
 	BUG_ON(!pmd_none(*pmd) || !pte);
 	__pmd_populate(pmd, __pa(pte) | _PAGE_KERNEL_TABLE);
 	pkmap_page_table = pte + PTRS_PER_PTE;
 #endif
 }
 
+static inline void map_memory_bank(struct membank *bank)
+{
+	struct map_desc map;
+
+	map.pfn = bank_pfn_start(bank);
+	map.virtual = __phys_to_virt(bank_phys_start(bank));
+	map.length = bank_phys_size(bank);
+	map.type = MT_MEMORY;
+
+	create_mapping(&map);
+}
+
+static void __init map_lowmem(void)
+{
+	struct meminfo *mi = &meminfo;
+	int i;
+
+	/* Map all the lowmem memory banks. */
+	for (i = 0; i < mi->nr_banks; i++) {
+		struct membank *bank = &mi->bank[i];
+
+		if (!bank->highmem)
+			map_memory_bank(bank);
+	}
+}
+
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+	const struct membank *a = _a, *b = _b;
+	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
@@ -1021,20 +988,22 @@ void __init paging_init(struct machine_desc *mdesc)
 {
 	void *zero_page;
 
+	sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
 	build_mem_type_table();
 	sanity_check_meminfo();
 	prepare_page_table();
-	bootmem_init();
+	map_lowmem();
 	devicemaps_init(mdesc);
 	kmap_init();
 
 	top_pmd = pmd_off_k(0xffff0000);
 
-	/*
-	 * allocate the zero page.  Note that this always succeeds and
-	 * returns a zeroed result.
-	 */
-	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+	/* allocate the zero page. */
+	zero_page = early_alloc(PAGE_SIZE);
+
+	bootmem_init();
+
 	empty_zero_page = virt_to_page(zero_page);
 	__flush_dcache_page(NULL, empty_zero_page);
 }
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 9bfeb6b..ce00558 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -6,8 +6,8 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/lmb.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
@@ -17,30 +17,14 @@
 
 #include "mm.h"
 
-/*
- * Reserve the various regions of node 0
- */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
 {
 	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
-	/*
 	 * Register the exception vector page.
 	 * some architectures which the DRAM is the exception vector to trap,
 	 * alloc_page breaks with error, although it is not NULL, but "0."
 	 */
-	reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE,
-			BOOTMEM_DEFAULT);
+	lmb_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
 }
 
 /*

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-09 11:11       ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-04-09 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 08, 2010 at 07:27:15PM +0100, Russell King - ARM Linux wrote:
> On Thu, Apr 08, 2010 at 09:02:56PM +0530, Rabin Vincent wrote:
> > On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> > > The patch below is the combined patch; individual patches can be found
> > > in the arm:lmb patches on the website or the lmb branch of my git tree;
> > > this should be considered unstable.
> > 
> > Something like the following is needed to make initrds work after this
> > patch:
> 
> This to me looks like a very large patch for what is a small problem -
> that is the assignment of initrd_start/initrd_size got lost along the
> way.
> 
> I'd much rather have the smaller patch; keep the initrd parameters in
> the physical address space for as long as possible, and only convert
> them to the virtual address space once we've finished mm initialisation.

Here's a revised version which should resolve the initrd problem.

 arch/arm/Kconfig                         |    1 +
 arch/arm/include/asm/lmb.h               |   16 +++
 arch/arm/include/asm/mach/arch.h         |    1 +
 arch/arm/kernel/setup.c                  |    3 +
 arch/arm/mach-clps711x/edb7211-arch.c    |    8 ++
 arch/arm/mach-clps711x/mm.c              |    1 -
 arch/arm/mach-integrator/common.h        |    1 +
 arch/arm/mach-integrator/core.c          |   11 ++
 arch/arm/mach-integrator/integrator_ap.c |    1 +
 arch/arm/mach-integrator/integrator_cp.c |    1 +
 arch/arm/mach-ixp4xx/common.c            |    1 -
 arch/arm/mach-omap1/board-htcherald.c    |    1 -
 arch/arm/mach-omap2/omap_hwmod.c         |    1 -
 arch/arm/mach-pxa/palmt5.c               |    7 +
 arch/arm/mach-pxa/palmtreo.c             |    9 ++
 arch/arm/mach-s3c2410/mach-h1940.c       |    9 ++
 arch/arm/mach-s3c2440/mach-rx3715.c      |    9 ++
 arch/arm/mach-u300/u300.c                |   17 +++
 arch/arm/mm/init.c                       |  202 ++++++++----------------------
 arch/arm/mm/mm.h                         |    8 +-
 arch/arm/mm/mmu.c                        |  153 +++++++++--------------
 arch/arm/mm/nommu.c                      |   22 +---
 22 files changed, 210 insertions(+), 273 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c5408bf..48254a4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -10,6 +10,7 @@ config ARM
 	default y
 	select HAVE_AOUT
 	select HAVE_IDE
+	select HAVE_LMB
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select GENERIC_ATOMIC64 if (!CPU_32v6K)
diff --git a/arch/arm/include/asm/lmb.h b/arch/arm/include/asm/lmb.h
new file mode 100644
index 0000000..1f49657
--- /dev/null
+++ b/arch/arm/include/asm/lmb.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_ARM_LMB_H
+#define _ASM_ARM_LMB_H
+
+#ifdef CONFIG_MMU
+extern phys_addr_t lowmem_end_addr;
+#define LMB_REAL_LIMIT	lowmem_end_addr
+#else
+#define LMB_REAL_LIMIT	0
+#endif
+
+struct meminfo;
+struct machine_desc;
+
+extern void arm_lmb_init(struct meminfo *, struct machine_desc *);
+
+#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index c59842d..f634dbe 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -37,6 +37,7 @@ struct machine_desc {
 	void			(*fixup)(struct machine_desc *,
 					 struct tag *, char **,
 					 struct meminfo *);
+	void			(*reserve)(void);/* reserve lmb blocks	*/
 	void			(*map_io)(void);/* IO mapping function	*/
 	void			(*init_irq)(void);
 	struct sys_timer	*timer;		/* system tick timer	*/
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c91c77b..4f132f7 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -25,6 +25,7 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/lmb.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -714,6 +715,8 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+	arm_lmb_init(&meminfo, mdesc);
+
 	paging_init(mdesc);
 	request_standard_resources(&meminfo, mdesc);
 
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index dc81cc6..aba952c 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/lmb.h>
 #include <linux/types.h>
 #include <linux/string.h>
 
@@ -29,6 +30,12 @@
 
 extern void edb7211_map_io(void);
 
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+	lmb_reserve(PHYS_OFFSET, 0x00020000);
+}
+
 static void __init
 fixup_edb7211(struct machine_desc *desc, struct tag *tags,
 	      char **cmdline, struct meminfo *mi)
@@ -57,6 +64,7 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
 	.boot_params	= 0xc0020100,	/* 0xc0000000 - 0xc001ffff can be video RAM */
 	.fixup		= fixup_edb7211,
 	.map_io		= edb7211_map_io,
+	.reserve	= edb7211_reserve,
 	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
index a7b4591..9865921 100644
--- a/arch/arm/mach-clps711x/mm.c
+++ b/arch/arm/mach-clps711x/mm.c
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index 609c49d..87cfeed 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1,2 +1,3 @@
 extern void integrator_time_init(unsigned long, unsigned int);
 extern unsigned long integrator_gettimeoffset(void);
+void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8b390e3..417c772 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/lmb.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/termios.h>
@@ -334,3 +335,13 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
 	 */
 	setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
 }
+
+/*
+ * We need to stop things allocating the low memory; ideally we need a
+ * better implementation of GFP_DMA which does not assume that DMA-able
+ * memory starts at zero.
+ */
+void __init integrator_reserve(void)
+{
+	lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 8138a7e..9fbde0d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -350,6 +350,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= ap_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= ap_init_irq,
 	.timer		= &ap_timer,
 	.init_machine	= ap_init,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 66ef86d..8de5f35 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -585,6 +585,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= intcp_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= intcp_init_irq,
 	.timer		= &cp_timer,
 	.init_machine	= intcp_init,
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71728d3..0bce097 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -21,7 +21,6 @@
 #include <linux/tty.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
-#include <linux/bootmem.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/time.h>
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index e36639f..8e313b4 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index c664947..aa3e209 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -43,7 +43,6 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/bootmem.h>
 
 #include <plat/common.h>
 #include <plat/cpu.h>
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index d902a81..b33fbe3 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/lmb.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -396,6 +397,11 @@ static void __init palmt5_udc_init(void)
 	}
 }
 
+static void __init palmt5_reserve(void)
+{
+	lmb_reserve(0xa0200000, 0x1000);
+}
+
 static void __init palmt5_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
@@ -421,6 +427,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5")
 	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
 	.boot_params	= 0xa0000100,
 	.map_io		= pxa_map_io,
+	.reserve	= palmt5_reserve,
 	.init_irq	= pxa27x_init_irq,
 	.timer		= &pxa_timer,
 	.init_machine	= palmt5_init
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index d8b4469..e712b86 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/lmb.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -633,6 +634,12 @@ static void __init treo_lcd_power_init(void)
 	treo_lcd_screen.pxafb_lcd_power = treo_lcd_power;
 }
 
+static void __init treo_reserve(void)
+{
+	lmb_reserve(0xa0000000, 0x1000);
+	lmb_reserve(0xa2000000, 0x1000);
+}
+
 static void __init treo_init(void)
 {
 	pxa_set_ffuart_info(NULL);
@@ -668,6 +675,7 @@ MACHINE_START(TREO680, "Palm Treo 680")
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
 	.init_machine   = treo680_init,
@@ -691,6 +699,7 @@ MACHINE_START(CENTRO, "Palm Centro 685")
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
        .init_machine   = centro_init,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index fbedd07..bfbcdd0 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/lmb.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
@@ -301,6 +302,13 @@ static void __init h1940_map_io(void)
 	s3c_pm_init();
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init h1940_reserve(void)
+{
+	lmb_reserve(0x30003000, 0x1000);
+	lmb_reserve(0x30081000, 0x1000);
+}
+
 static void __init h1940_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -342,6 +350,7 @@ MACHINE_START(H1940, "IPAQ-H1940")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= h1940_map_io,
+	.reserve	= h1940_reserve,
 	.init_irq	= h1940_init_irq,
 	.init_machine	= h1940_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 1e836e5..76aa734 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/lmb.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/tty.h>
@@ -191,6 +192,13 @@ static void __init rx3715_map_io(void)
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx3715_reserve(void)
+{
+	lmb_reserve(0x30003000, 0x1000);
+	lmb_reserve(0x30081000, 0x1000);
+}
+
 static void __init rx3715_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -214,6 +222,7 @@ MACHINE_START(RX3715, "IPAQ-RX3715")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= rx3715_map_io,
+	.reserve	= rx3715_reserve,
 	.init_irq	= rx3715_init_irq,
 	.init_machine	= rx3715_init_machine,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index d2a0b88..4fb8660 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/lmb.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <mach/hardware.h>
@@ -22,6 +23,21 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+static void __init u300_reserve(void)
+{
+	/*
+	 * U300 - This platform family can share physical memory
+	 * between two ARM cpus, one running Linux and the other
+	 * running another OS.
+	 */
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+        lmb_reserve(PHYS_OFFSET, 0x00100000);
+#endif
+#endif
+}
+
 static void __init u300_init_machine(void)
 {
 	u300_init_devices();
@@ -49,6 +65,7 @@ MACHINE_START(U300, MACH_U300_STRING)
 	.io_pg_offst	= ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
 	.boot_params	= BOOT_PARAMS_OFFSET,
 	.map_io		= u300_map_io,
+	.reserve	= u300_reserve,
 	.init_irq	= u300_init_irq,
 	.timer		= &u300_timer,
 	.init_machine	= u300_init_machine,
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7829cb5..6eb00f8 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,8 +15,8 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
-#include <linux/sort.h>
 #include <linux/highmem.h>
+#include <linux/lmb.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -150,119 +150,21 @@ static void __init find_node_limits(int node, struct meminfo *mi,
 	}
 }
 
-/*
- * FIXME: We really want to avoid allocating the bootmap bitmap
- * over the top of the initrd.  Hopefully, this is located towards
- * the start of a bank, so if we allocate the bootmap bitmap at
- * the end, we won't clash.
- */
-static unsigned int __init
-find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
-{
-	unsigned int start_pfn, i, bootmap_pfn;
-
-	start_pfn   = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT;
-	bootmap_pfn = 0;
-
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-		unsigned int start, end;
-
-		start = bank_pfn_start(bank);
-		end   = bank_pfn_end(bank);
-
-		if (end < start_pfn)
-			continue;
-
-		if (start < start_pfn)
-			start = start_pfn;
-
-		if (end <= start)
-			continue;
-
-		if (end - start >= bootmap_pages) {
-			bootmap_pfn = start;
-			break;
-		}
-	}
-
-	if (bootmap_pfn == 0)
-		BUG();
-
-	return bootmap_pfn;
-}
-
-static int __init check_initrd(struct meminfo *mi)
-{
-	int initrd_node = -2;
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long end = phys_initrd_start + phys_initrd_size;
-
-	/*
-	 * Make sure that the initrd is within a valid area of
-	 * memory.
-	 */
-	if (phys_initrd_size) {
-		unsigned int i;
-
-		initrd_node = -1;
-
-		for (i = 0; i < mi->nr_banks; i++) {
-			struct membank *bank = &mi->bank[i];
-			if (bank_phys_start(bank) <= phys_initrd_start &&
-			    end <= bank_phys_end(bank))
-				initrd_node = bank->node;
-		}
-	}
-
-	if (initrd_node == -1) {
-		printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
-		       "physical memory - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
-		phys_initrd_start = phys_initrd_size = 0;
-	}
-#endif
-
-	return initrd_node;
-}
-
-static inline void map_memory_bank(struct membank *bank)
-{
-#ifdef CONFIG_MMU
-	struct map_desc map;
-
-	map.pfn = bank_pfn_start(bank);
-	map.virtual = __phys_to_virt(bank_phys_start(bank));
-	map.length = bank_phys_size(bank);
-	map.type = MT_MEMORY;
-
-	create_mapping(&map);
-#endif
-}
-
 static void __init bootmem_init_node(int node, struct meminfo *mi,
 	unsigned long start_pfn, unsigned long end_pfn)
 {
-	unsigned long boot_pfn;
 	unsigned int boot_pages;
+	phys_addr_t bitmap;
 	pg_data_t *pgdat;
 	int i;
 
 	/*
-	 * Map the memory banks for this node.
-	 */
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-
-		if (!bank->highmem)
-			map_memory_bank(bank);
-	}
-
-	/*
-	 * Allocate the bootmem bitmap page.
+	 * Allocate the bootmem bitmap page.  This must be in a region
+	 * of memory which has already been mapped.
 	 */
 	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
-	boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
+	bitmap = lmb_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES,
+				__pfn_to_phys(end_pfn));
 
 	/*
 	 * Initialise the bootmem allocator for this node, handing the
@@ -270,7 +172,7 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
 	 */
 	node_set_online(node);
 	pgdat = NODE_DATA(node);
-	init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+	init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
 
 	for_each_nodebank(i, mi, node) {
 		struct membank *bank = &mi->bank[i];
@@ -279,31 +181,16 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
 	}
 
 	/*
-	 * Reserve the bootmem bitmap for this node.
+	 * Reserve the LMB reserved regions in bootmem for this node.
 	 */
-	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
-			     boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
-}
-
-static void __init bootmem_reserve_initrd(int node)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	pg_data_t *pgdat = NODE_DATA(node);
-	int res;
-
-	res = reserve_bootmem_node(pgdat, phys_initrd_start,
-			     phys_initrd_size, BOOTMEM_EXCLUSIVE);
-
-	if (res == 0) {
-		initrd_start = __phys_to_virt(phys_initrd_start);
-		initrd_end = initrd_start + phys_initrd_size;
-	} else {
-		printk(KERN_ERR
-			"INITRD: 0x%08lx+0x%08lx overlaps in-use "
-			"memory region - disabling initrd\n",
-			phys_initrd_start, phys_initrd_size);
+	for (i = 0; i < lmb.reserved.cnt; i++) {
+		phys_addr_t start = lmb_start_pfn(&lmb.reserved, i);
+		if (start >= start_pfn &&
+		    lmb_end_pfn(&lmb.reserved, i) <= end_pfn)
+			reserve_bootmem_node(pgdat, __pfn_to_phys(start),
+				lmb_size_bytes(&lmb.reserved, i),
+				BOOTMEM_DEFAULT);
 	}
-#endif
 }
 
 static void __init bootmem_free_node(int node, struct meminfo *mi)
@@ -387,25 +274,41 @@ static void arm_memory_present(struct meminfo *mi, int node)
 }
 #endif
 
-static int __init meminfo_cmp(const void *_a, const void *_b)
+void __init arm_lmb_init(struct meminfo *mi, struct machine_desc *mdesc)
 {
-	const struct membank *a = _a, *b = _b;
-	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
-	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+	int i;
+
+	for (i = 0; i < mi->nr_banks; i++)
+		lmb_add(mi->bank[i].start, mi->bank[i].size);
+
+	/* Register the kernel text, kernel data and initrd with lmb. */
+#ifdef CONFIG_XIP_KERNEL
+	lmb_reserve(__pa(_data), _end - _data);
+#else
+	lmb_reserve(__pa(_stext), _end - _stext);
+#endif
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (phys_initrd_size) {
+		lmb_reserve(phys_initrd_start, phys_initrd_size);
+
+		/* Now convert initrd to virtual addresses */
+		initrd_start = __phys_to_virt(phys_initrd_start);
+		initrd_end = initrd_start + phys_initrd_size;
+	}
+#endif
+
+	arm_mm_lmb_reserve();
+
+	/* reserve any lmb areas */
+	if (mdesc->reserve)
+		mdesc->reserve();
 }
 
 void __init bootmem_init(void)
 {
 	struct meminfo *mi = &meminfo;
 	unsigned long min, max_low, max_high;
-	int node, initrd_node;
-
-	sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
-
-	/*
-	 * Locate which node contains the ramdisk image, if any.
-	 */
-	initrd_node = check_initrd(mi);
+	int node;
 
 	max_low = max_high = 0;
 
@@ -432,18 +335,6 @@ void __init bootmem_init(void)
 		bootmem_init_node(node, mi, min, node_low);
 
 		/*
-		 * Reserve any special node zero regions.
-		 */
-		if (node == 0)
-			reserve_node_zero(NODE_DATA(node));
-
-		/*
-		 * If the initrd is in this node, reserve its memory.
-		 */
-		if (node == initrd_node)
-			bootmem_reserve_initrd(node);
-
-		/*
 		 * Sparsemem tries to allocate bootmem in memory_present(),
 		 * so must be done after the fixed reservations
 		 */
@@ -566,6 +457,13 @@ void __init mem_init(void)
 	unsigned long reserved_pages, free_pages;
 	int i, node;
 
+#ifdef CONFIG_SA1111
+	lmb_free(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+#endif
+
+	lmb_analyze();
+	lmb_dump_all();
+
 #ifndef CONFIG_DISCONTIGMEM
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 #endif
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a888363..966dc45 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -28,10 +28,6 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
 
 #endif
 
-struct map_desc;
-struct meminfo;
-struct pglist_data;
-
-void __init create_mapping(struct map_desc *md);
 void __init bootmem_init(void);
-void reserve_node_zero(struct pglist_data *pgdat);
+void arm_lmb_reserve(void);
+void arm_mm_lmb_reserve(void);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9d4da6a..81eb08a 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -11,9 +11,10 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
+#include <linux/lmb.h>
+#include <linux/sort.h>
 
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
@@ -483,6 +484,13 @@ static void __init build_mem_type_table(void)
 
 #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
 
+static void __init *early_alloc(unsigned long sz)
+{
+	void *ptr = __va(lmb_alloc(sz, sz));
+	memset(ptr, 0, PAGE_SIZE);
+	return ptr;
+}
+
 static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 				  unsigned long end, unsigned long pfn,
 				  const struct mem_type *type)
@@ -490,7 +498,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 	pte_t *pte;
 
 	if (pmd_none(*pmd)) {
-		pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+		pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
 		__pmd_populate(pmd, __pa(pte) | type->prot_l1);
 	}
 
@@ -599,7 +607,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
  * offsets, and we take full advantage of sections and
  * supersections.
  */
-void __init create_mapping(struct map_desc *md)
+static void __init create_mapping(struct map_desc *md)
 {
 	unsigned long phys, addr, length, end;
 	const struct mem_type *type;
@@ -693,6 +701,9 @@ early_param("vmalloc", early_vmalloc);
 
 #define VMALLOC_MIN	(void *)(VMALLOC_END - vmalloc_reserve)
 
+/* FIXME: we need to teach LMB about the highmem boundary */
+phys_addr_t lowmem_end_addr = PHYS_OFFSET + 32*1048576;
+
 static void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
@@ -822,100 +833,23 @@ static inline void prepare_page_table(void)
 }
 
 /*
- * Reserve the various regions of node 0
+ * Reserve the special regions of memory
  */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
 {
-	unsigned long res_size = 0;
-
-	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
 	/*
 	 * Reserve the page tables.  These are already in use,
 	 * and can only be in node 0.
 	 */
-	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
-			     PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT);
-
-	/*
-	 * Hmm... This should go elsewhere, but we really really need to
-	 * stop things allocating the low memory; ideally we need a better
-	 * implementation of GFP_DMA which does not assume that DMA-able
-	 * memory starts at zero.
-	 */
-	if (machine_is_integrator() || machine_is_cintegrator())
-		res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
-
-	/*
-	 * These should likewise go elsewhere.  They pre-reserve the
-	 * screen memory region at the start of main system memory.
-	 */
-	if (machine_is_edb7211())
-		res_size = 0x00020000;
-	if (machine_is_p720t())
-		res_size = 0x00014000;
-
-	/* H1940 and RX3715 need to reserve this for suspend */
-
-	if (machine_is_h1940() || machine_is_rx3715()) {
-		reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
-				BOOTMEM_DEFAULT);
-		reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
-				BOOTMEM_DEFAULT);
-	}
-
-	if (machine_is_palmld() || machine_is_palmtx()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_treo680() || machine_is_centro()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa2000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_palmt5())
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-
-	/*
-	 * U300 - This platform family can share physical memory
-	 * between two ARM cpus, one running Linux and the other
-	 * running another OS.
-	 */
-	if (machine_is_u300()) {
-#ifdef CONFIG_MACH_U300_SINGLE_RAM
-#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) &&	\
-	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
-		res_size = 0x00100000;
-#endif
-#endif
-	}
+	lmb_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
 
 #ifdef CONFIG_SA1111
 	/*
 	 * Because of the SA1111 DMA bug, we want to preserve our
 	 * precious DMA-able memory...
 	 */
-	res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+	lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
 #endif
-	if (res_size)
-		reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size,
-				BOOTMEM_DEFAULT);
 }
 
 /*
@@ -934,7 +868,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 	/*
 	 * Allocate the vector page early.
 	 */
-	vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+	vectors = early_alloc(PAGE_SIZE);
 
 	for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
 		pmd_clear(pmd_off_k(addr));
@@ -1006,13 +940,46 @@ static void __init kmap_init(void)
 {
 #ifdef CONFIG_HIGHMEM
 	pmd_t *pmd = pmd_off_k(PKMAP_BASE);
-	pte_t *pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+	pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
 	BUG_ON(!pmd_none(*pmd) || !pte);
 	__pmd_populate(pmd, __pa(pte) | _PAGE_KERNEL_TABLE);
 	pkmap_page_table = pte + PTRS_PER_PTE;
 #endif
 }
 
+static inline void map_memory_bank(struct membank *bank)
+{
+	struct map_desc map;
+
+	map.pfn = bank_pfn_start(bank);
+	map.virtual = __phys_to_virt(bank_phys_start(bank));
+	map.length = bank_phys_size(bank);
+	map.type = MT_MEMORY;
+
+	create_mapping(&map);
+}
+
+static void __init map_lowmem(void)
+{
+	struct meminfo *mi = &meminfo;
+	int i;
+
+	/* Map all the lowmem memory banks. */
+	for (i = 0; i < mi->nr_banks; i++) {
+		struct membank *bank = &mi->bank[i];
+
+		if (!bank->highmem)
+			map_memory_bank(bank);
+	}
+}
+
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+	const struct membank *a = _a, *b = _b;
+	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
@@ -1021,20 +988,22 @@ void __init paging_init(struct machine_desc *mdesc)
 {
 	void *zero_page;
 
+	sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
 	build_mem_type_table();
 	sanity_check_meminfo();
 	prepare_page_table();
-	bootmem_init();
+	map_lowmem();
 	devicemaps_init(mdesc);
 	kmap_init();
 
 	top_pmd = pmd_off_k(0xffff0000);
 
-	/*
-	 * allocate the zero page.  Note that this always succeeds and
-	 * returns a zeroed result.
-	 */
-	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+	/* allocate the zero page. */
+	zero_page = early_alloc(PAGE_SIZE);
+
+	bootmem_init();
+
 	empty_zero_page = virt_to_page(zero_page);
 	__flush_dcache_page(NULL, empty_zero_page);
 }
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 9bfeb6b..ce00558 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -6,8 +6,8 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/lmb.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
@@ -17,30 +17,14 @@
 
 #include "mm.h"
 
-/*
- * Reserve the various regions of node 0
- */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
 {
 	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
-	/*
 	 * Register the exception vector page.
 	 * some architectures which the DRAM is the exception vector to trap,
 	 * alloc_page breaks with error, although it is not NULL, but "0."
 	 */
-	reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE,
-			BOOTMEM_DEFAULT);
+	lmb_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
 }
 
 /*

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-03-31  6:43   ` Jeremy Kerr
@ 2010-04-09 11:13     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-04-09 11:13 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linux-arm-kernel, Tony Lindgren, linux-omap

On Wed, Mar 31, 2010 at 02:43:13PM +0800, Jeremy Kerr wrote:
> Hi Russell,
> 
> > LMB... logical memory blocks.
> 
> Nice, will be good for the DT work too.
> 
> > @@ -483,6 +484,13 @@ static void __init build_mem_type_table(void)
> > 
> >  #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
> > 
> > +static void __init *early_alloc(unsigned long sz)
> > +{
> > +      void *ptr = __va(lmb_alloc(sz, sz));
> > +      memset(ptr, 0, PAGE_SIZE);
> 
> memset(ptr, 0, sz) ?

Yes, thanks for catching that.  That's not fixed in the revised version
I just sent, but will be fixed in the final version.  (IOW, I just
committed that correction.)

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-09 11:13     ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-04-09 11:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 31, 2010 at 02:43:13PM +0800, Jeremy Kerr wrote:
> Hi Russell,
> 
> > LMB... logical memory blocks.
> 
> Nice, will be good for the DT work too.
> 
> > @@ -483,6 +484,13 @@ static void __init build_mem_type_table(void)
> > 
> >  #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
> > 
> > +static void __init *early_alloc(unsigned long sz)
> > +{
> > +      void *ptr = __va(lmb_alloc(sz, sz));
> > +      memset(ptr, 0, PAGE_SIZE);
> 
> memset(ptr, 0, sz) ?

Yes, thanks for catching that.  That's not fixed in the revised version
I just sent, but will be fixed in the final version.  (IOW, I just
committed that correction.)

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-04-09 11:11       ` Russell King - ARM Linux
@ 2010-04-10  3:42         ` Rabin Vincent
  -1 siblings, 0 replies; 80+ messages in thread
From: Rabin Vincent @ 2010-04-10  3:42 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Tony Lindgren, linux-omap, linux-arm-kernel

On Fri, Apr 09, 2010 at 12:11:05PM +0100, Russell King - ARM Linux wrote:
> Here's a revised version which should resolve the initrd problem.

It does, after the missing call to lmb_init() is added.

Rabin

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-10  3:42         ` Rabin Vincent
  0 siblings, 0 replies; 80+ messages in thread
From: Rabin Vincent @ 2010-04-10  3:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 09, 2010 at 12:11:05PM +0100, Russell King - ARM Linux wrote:
> Here's a revised version which should resolve the initrd problem.

It does, after the missing call to lmb_init() is added.

Rabin

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-04-10  3:42         ` Rabin Vincent
@ 2010-04-10  7:03           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-04-10  7:03 UTC (permalink / raw)
  To: Rabin Vincent; +Cc: Tony Lindgren, linux-omap, linux-arm-kernel

On Sat, Apr 10, 2010 at 09:12:24AM +0530, Rabin Vincent wrote:
> On Fri, Apr 09, 2010 at 12:11:05PM +0100, Russell King - ARM Linux wrote:
> > Here's a revised version which should resolve the initrd problem.
> 
> It does, after the missing call to lmb_init() is added.

Which missing call?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-10  7:03           ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-04-10  7:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 10, 2010 at 09:12:24AM +0530, Rabin Vincent wrote:
> On Fri, Apr 09, 2010 at 12:11:05PM +0100, Russell King - ARM Linux wrote:
> > Here's a revised version which should resolve the initrd problem.
> 
> It does, after the missing call to lmb_init() is added.

Which missing call?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-04-10  7:03           ` Russell King - ARM Linux
@ 2010-04-10 11:56             ` Rabin Vincent
  -1 siblings, 0 replies; 80+ messages in thread
From: Rabin Vincent @ 2010-04-10 11:56 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Tony Lindgren, linux-omap, linux-arm-kernel

On Sat, Apr 10, 2010 at 08:03:05AM +0100, Russell King - ARM Linux wrote:
> On Sat, Apr 10, 2010 at 09:12:24AM +0530, Rabin Vincent wrote:
> > On Fri, Apr 09, 2010 at 12:11:05PM +0100, Russell King - ARM Linux wrote:
> > > Here's a revised version which should resolve the initrd problem.
> > 
> > It does, after the missing call to lmb_init() is added.
> 
> Which missing call?

This one:

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index bc341c4..f1e0f5d 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -279,6 +279,7 @@ void __init arm_lmb_init(struct meminfo *mi, struct machine_desc *mdesc)
 {
 	int i;
 
+	lmb_init();
 	for (i = 0; i < mi->nr_banks; i++)
 		lmb_add(mi->bank[i].start, mi->bank[i].size);
 

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-10 11:56             ` Rabin Vincent
  0 siblings, 0 replies; 80+ messages in thread
From: Rabin Vincent @ 2010-04-10 11:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 10, 2010 at 08:03:05AM +0100, Russell King - ARM Linux wrote:
> On Sat, Apr 10, 2010 at 09:12:24AM +0530, Rabin Vincent wrote:
> > On Fri, Apr 09, 2010 at 12:11:05PM +0100, Russell King - ARM Linux wrote:
> > > Here's a revised version which should resolve the initrd problem.
> > 
> > It does, after the missing call to lmb_init() is added.
> 
> Which missing call?

This one:

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index bc341c4..f1e0f5d 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -279,6 +279,7 @@ void __init arm_lmb_init(struct meminfo *mi, struct machine_desc *mdesc)
 {
 	int i;
 
+	lmb_init();
 	for (i = 0; i < mi->nr_banks; i++)
 		lmb_add(mi->bank[i].start, mi->bank[i].size);
 

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-04-09 11:11       ` Russell King - ARM Linux
@ 2010-04-14  7:34         ` Benjamin Herrenschmidt
  -1 siblings, 0 replies; 80+ messages in thread
From: Benjamin Herrenschmidt @ 2010-04-14  7:34 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Rabin Vincent, Tony Lindgren, linux-omap, linux-arm-kernel

On Fri, 2010-04-09 at 12:11 +0100, Russell King - ARM Linux wrote:
> On Thu, Apr 08, 2010 at 07:27:15PM +0100, Russell King - ARM Linux wrote:
> > On Thu, Apr 08, 2010 at 09:02:56PM +0530, Rabin Vincent wrote:
> > > On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> > > > The patch below is the combined patch; individual patches can be found
> > > > in the arm:lmb patches on the website or the lmb branch of my git tree;
> > > > this should be considered unstable.
> > > 
> > > Something like the following is needed to make initrds work after this
> > > patch:
> > 
> > This to me looks like a very large patch for what is a small problem -
> > that is the assignment of initrd_start/initrd_size got lost along the
> > way.
> > 
> > I'd much rather have the smaller patch; keep the initrd parameters in
> > the physical address space for as long as possible, and only convert
> > them to the virtual address space once we've finished mm initialisation.
> 
> Here's a revised version which should resolve the initrd problem.

BTW. I'm doing some cleanup of lmb, you can take a peek at my WIP in
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git branch
"lmb".

It shouldn't break your stuff, though you will probably need to add a
call to lmb_set_current_limit() in the right place instead of setting
LMB_REAL_LIMIT to lowmem_end_addr.

Anyway, it's still WIP, but feel free to comment, and if there's
something else you want me to do, cleanup or change in the core LMB, let
me know.

Cheers,
Ben.



^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-04-14  7:34         ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 80+ messages in thread
From: Benjamin Herrenschmidt @ 2010-04-14  7:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2010-04-09 at 12:11 +0100, Russell King - ARM Linux wrote:
> On Thu, Apr 08, 2010 at 07:27:15PM +0100, Russell King - ARM Linux wrote:
> > On Thu, Apr 08, 2010 at 09:02:56PM +0530, Rabin Vincent wrote:
> > > On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> > > > The patch below is the combined patch; individual patches can be found
> > > > in the arm:lmb patches on the website or the lmb branch of my git tree;
> > > > this should be considered unstable.
> > > 
> > > Something like the following is needed to make initrds work after this
> > > patch:
> > 
> > This to me looks like a very large patch for what is a small problem -
> > that is the assignment of initrd_start/initrd_size got lost along the
> > way.
> > 
> > I'd much rather have the smaller patch; keep the initrd parameters in
> > the physical address space for as long as possible, and only convert
> > them to the virtual address space once we've finished mm initialisation.
> 
> Here's a revised version which should resolve the initrd problem.

BTW. I'm doing some cleanup of lmb, you can take a peek at my WIP in
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git branch
"lmb".

It shouldn't break your stuff, though you will probably need to add a
call to lmb_set_current_limit() in the right place instead of setting
LMB_REAL_LIMIT to lowmem_end_addr.

Anyway, it's still WIP, but feel free to comment, and if there's
something else you want me to do, cleanup or change in the core LMB, let
me know.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-03-25 23:32 ` Russell King - ARM Linux
@ 2010-05-05 15:02   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-05 15:02 UTC (permalink / raw)
  To: linux-arm-kernel, Tony Lindgren; +Cc: linux-omap

On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> LMB... logical memory blocks.
> 
> LM is a different method of managing memory regions during the early
> boot period when the usual kernel memory allocators are not up and
> running.  LMB has been in the kernel for quite some time, and is
> already being used by Microblaze, PPC, SH and Sparc.  Maybe soon x86
> as well.
> 
> The motivation for this is that there appears to be plans to kill off
> the other method - bootmem.  (see discussions on the linux-arch ml.)

I've now queued the first three patches in this series for the next
merge window, which is basically the preparation for moving to LMB.
Essentially, that's:

- removing useless includes of linux/bootmem.h
- sorting the meminfo array prior to sanity_check_meminfo()
- moving the mapping of lowmem into mmu.c and making create_mapping()
  static

None of these changes should affect any currently merged platforms, and
wouldn't be affected by Ben's LMB updates either.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-05 15:02   ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-05 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 25, 2010 at 11:32:48PM +0000, Russell King - ARM Linux wrote:
> LMB... logical memory blocks.
> 
> LM is a different method of managing memory regions during the early
> boot period when the usual kernel memory allocators are not up and
> running.  LMB has been in the kernel for quite some time, and is
> already being used by Microblaze, PPC, SH and Sparc.  Maybe soon x86
> as well.
> 
> The motivation for this is that there appears to be plans to kill off
> the other method - bootmem.  (see discussions on the linux-arch ml.)

I've now queued the first three patches in this series for the next
merge window, which is basically the preparation for moving to LMB.
Essentially, that's:

- removing useless includes of linux/bootmem.h
- sorting the meminfo array prior to sanity_check_meminfo()
- moving the mapping of lowmem into mmu.c and making create_mapping()
  static

None of these changes should affect any currently merged platforms, and
wouldn't be affected by Ben's LMB updates either.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-05 15:02   ` Russell King - ARM Linux
@ 2010-05-13 17:40     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-13 17:40 UTC (permalink / raw)
  To: linux-arm-kernel, Tony Lindgren; +Cc: linux-omap

And here's a patch which converts the OMAP FB code to use lmb_reserve
instead of poking about with bootmem stuff.  Untested, so I'd like to
hear back whether it works.

diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 7fc11c3..87b94a8 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -285,6 +285,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= ams_delta_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= ams_delta_init_irq,
 	.init_machine	= ams_delta_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 096f2ed..d7ea74a 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -378,6 +378,7 @@ MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_fsample_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_fsample_init_irq,
 	.init_machine	= omap_fsample_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index e1195a3..12e2f23 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -98,6 +98,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_generic_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_generic_init_irq,
 	.init_machine	= omap_generic_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index d1100e4..616ffa8 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -467,6 +467,7 @@ MACHINE_START(OMAP_H2, "TI-H2")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= h2_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= h2_init_irq,
 	.init_machine	= h2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index a53ab82..bd3d037 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -437,6 +437,7 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= h3_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= h3_init_irq,
 	.init_machine	= h3_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 8e313b4..8e67a10 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -304,6 +304,7 @@ MACHINE_START(HERALD, "HTC Herald")
 	.io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params    = 0x10000100,
 	.map_io         = htcherald_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq       = htcherald_init_irq,
 	.init_machine   = htcherald_init,
 	.timer          = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 5d12fd3..39bd476 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -463,6 +463,7 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= innovator_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= innovator_init_irq,
 	.init_machine	= innovator_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 71e1a3f..615670a 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -400,6 +400,7 @@ MACHINE_START(NOKIA770, "Nokia 770")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_nokia770_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_nokia770_init_irq,
 	.init_machine	= omap_nokia770_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 80d8620..bd94eb2 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -584,6 +584,7 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= osk_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= osk_init_irq,
 	.init_machine	= osk_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 569b4c9..151719f 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -373,6 +373,7 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_palmte_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_palmte_init_irq,
 	.init_machine	= omap_palmte_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 6ad49a2..5034a28 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -321,6 +321,7 @@ MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_palmtt_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_palmtt_init_irq,
 	.init_machine	= omap_palmtt_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 6641de9..ea1b033 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -338,10 +338,12 @@ omap_palmz71_map_io(void)
 }
 
 MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
-	.phys_io = 0xfff00000,
-	.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
-	.boot_params = 0x10000100,.map_io = omap_palmz71_map_io,
-	.init_irq = omap_palmz71_init_irq,
-	.init_machine = omap_palmz71_init,
-	.timer = &omap_timer,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_palmz71_map_io,
+	.reserve	= omap1_reserve,
+	.init_irq	= omap_palmz71_init_irq,
+	.init_machine	= omap_palmz71_init,
+	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index e854d57..1a0ac1c 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -339,6 +339,7 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_perseus2_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_perseus2_init_irq,
 	.init_machine	= omap_perseus2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 2fb1e5f..2a833a1 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -423,7 +423,8 @@ MACHINE_START(SX1, "OMAP310 based Siemens SX1")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_sx1_map_io,
-	.init_irq		= omap_sx1_init_irq,
+	.reserve	= omap1_reserve,
+	.init_irq	= omap_sx1_init_irq,
 	.init_machine	= omap_sx1_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 87b9436..fd47c5f 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -287,6 +287,7 @@ MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= voiceblue_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= voiceblue_init_irq,
 	.init_machine	= voiceblue_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index d9b8d82..f872406 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/omapfb.h>
 
 #include <asm/tlb.h>
 #include <asm/mach/map.h>
@@ -22,7 +23,6 @@
 
 extern void omap_check_revision(void);
 extern void omap_sram_init(void);
-extern void omapfb_reserve_sdram(void);
 
 /*
  * The machine specific code may provide the extra mapping besides the
@@ -122,7 +122,6 @@ void __init omap1_map_common_io(void)
 #endif
 
 	omap_sram_init();
-	omapfb_reserve_sdram();
 }
 
 /*
@@ -144,3 +143,7 @@ void __init omap1_init_common_hw(void)
 	omap1_mux_init();
 }
 
+void __init omap1_reserve(void)
+{
+	omapfb_reserve_sdram_lmb();
+}
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 01d113f..e7a4802 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -229,7 +229,9 @@ MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_2430sdp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_2430sdp_init_irq,
 	.init_machine	= omap_2430sdp_init,
 	.timer		= &omap_timer,
 MACHINE_END
+
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 5822bcf..cec2948 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -816,6 +816,7 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_3430sdp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_3430sdp_init_irq,
 	.init_machine	= omap_3430sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index a0a2a11..4fb164c 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -107,6 +107,7 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_sdp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_sdp_init_irq,
 	.init_machine	= omap_sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index b88f28c..a8bb755 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -134,6 +134,7 @@ MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_4430sdp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_4430sdp_init_irq,
 	.init_machine	= omap_4430sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 6ae8805..39c5c8a 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -326,6 +326,7 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= am3517_evm_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= am3517_evm_init_irq,
 	.init_machine	= am3517_evm_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index aa69fb9..dc2d735 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -346,6 +346,7 @@ MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_apollon_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_apollon_init_irq,
 	.init_machine	= omap_apollon_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 2de4f79..166bd03 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -836,6 +836,7 @@ MACHINE_START(CM_T35, "Compulab CM-T35")
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= cm_t35_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= cm_t35_init_irq,
 	.init_machine	= cm_t35_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 5bfc13b..9f41c49 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -691,6 +691,7 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= devkit8000_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= devkit8000_init_irq,
 	.init_machine	= devkit8000_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 16cc068..227e80b 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -59,6 +59,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_generic_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_generic_init_irq,
 	.init_machine	= omap_generic_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 0665f2c..5743a51 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -378,6 +378,7 @@ MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_h4_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_h4_init_irq,
 	.init_machine	= omap_h4_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 3c7789d..8242921 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -543,6 +543,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= igep2_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= igep2_init_irq,
 	.init_machine	= igep2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 5fcb52e..80d10cd 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -418,6 +418,7 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_ldp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_ldp_init_irq,
 	.init_machine	= omap_ldp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index da9bcb8..a426063 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -687,6 +687,7 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= n8x0_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= n8x0_init_irq,
 	.init_machine	= n8x0_init_machine,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 962d377..5df89f6 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -470,6 +470,7 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_beagle_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap3_beagle_init_irq,
 	.init_machine	= omap3_beagle_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 017bb2f..49aa19c 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -726,6 +726,7 @@ MACHINE_START(OMAP3EVM, "OMAP3 EVM")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_evm_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap3_evm_init_irq,
 	.init_machine	= omap3_evm_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 395d049..ca289ed 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -601,6 +601,7 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3pandora_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap3pandora_init_irq,
 	.init_machine	= omap3pandora_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 2504d41..c59050d 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -572,6 +572,7 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_touchbook_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap3_touchbook_init_irq,
 	.init_machine	= omap3_touchbook_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 8848c7c..af67079 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -483,6 +483,7 @@ MACHINE_START(OVERO, "Gumstix Overo")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= overo_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= overo_init_irq,
 	.init_machine	= overo_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index b155c36..390a0bc 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -152,6 +152,7 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= rx51_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= rx51_init_irq,
 	.init_machine	= rx51_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 9a26f84..377c9ba 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -95,6 +95,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_zoom2_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_zoom2_init_irq,
 	.init_machine	= omap_zoom2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index cd3e40c..d33cf07 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -77,6 +77,7 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_zoom_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_zoom_init_irq,
 	.init_machine	= omap_zoom_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 87f676a..b761904 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -232,7 +232,6 @@ static void __init _omap2_map_common_io(void)
 
 	omap2_check_revision();
 	omap_sram_init();
-	omapfb_reserve_sdram();
 	omap_vram_reserve_sdram();
 }
 
@@ -340,3 +339,9 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
 	}
 	gpmc_init();
 }
+
+void __init omap2_reserve(void)
+{
+	omapfb_reserve_sdram_lmb();
+}
+
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index d3eea4f..8d9afff 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -26,7 +26,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/bootmem.h>
+#include <linux/lmb.h>
 #include <linux/io.h>
 #include <linux/omapfb.h>
 
@@ -171,49 +171,54 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
 	return 0;
 }
 
-/*
- * 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)
+void __init omapfb_reserve_sdram_lmb(void)
 {
-	struct bootmem_data	*bdata;
-	unsigned long		sdram_start, sdram_size;
-	unsigned long		reserved;
-	int			i;
-
-	if (config_invalid)
-		return;
+	unsigned long reserved = 0;
+	int i;
 
-	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;
+		struct lmb_property res;
 
 		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 != 0 && 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) {
+
+		/* Does it fall within SDRAM ? */
+		res.base = rg.paddr;
+		res.size = rg.size;
+		if (lmb_find(&res) || res.base != rg.paddr || res.size != rg.size)
+			continue;
+
+		rg.type = OMAPFB_MEMTYPE_SDRAM;
+
+		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 (lmb_is_region_reserved(rg.paddr, rg.size)) {
+				pr_err("Trying to use reserved memory for FB region %d\n", i);
+				config_invalid = 1;
+				return;
+			}
+
+			lmb_reserve(rg.paddr, rg.size);
 			reserved += rg.size;
 		}
+
+		BUG_ON(omapfb_config.mem_desc.region[i].size);
 		omapfb_config.mem_desc.region[i] = rg;
 		configured_regions++;
 	}
@@ -359,7 +364,10 @@ static inline int omap_init_fb(void)
 
 arch_initcall(omap_init_fb);
 
-void omapfb_reserve_sdram(void) {}
+void omapfb_reserve_sdram_lmb(void)
+{
+}
+
 unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
 				  unsigned long sram_vstart,
 				  unsigned long sram_size,
@@ -375,7 +383,10 @@ void omapfb_set_platform_data(struct omapfb_platform_data *data)
 {
 }
 
-void omapfb_reserve_sdram(void) {}
+void omapfb_reserve_sdram_lmb(void)
+{
+}
+
 unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
 				  unsigned long sram_vstart,
 				  unsigned long sram_size,
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 7556e27..49d662c 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -37,6 +37,9 @@ extern void __iomem *gic_cpu_base_addr;
 extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
 
+extern void omap1_reserve(void);
+extern void omap2_reserve(void);
+
 /*
  * IO bases for various OMAP processors
  * Except the tap base, rest all the io bases
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index 9bdd914..45707be 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -253,7 +253,7 @@ struct omapfb_platform_data {
 /* in arch/arm/plat-omap/fb.c */
 extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
 extern void omapfb_set_ctrl_platform_data(void *pdata);
-extern void omapfb_reserve_sdram(void);
+extern void omapfb_reserve_sdram_lmb(void);
 
 #endif
 

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-13 17:40     ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-13 17:40 UTC (permalink / raw)
  To: linux-arm-kernel

And here's a patch which converts the OMAP FB code to use lmb_reserve
instead of poking about with bootmem stuff.  Untested, so I'd like to
hear back whether it works.

diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 7fc11c3..87b94a8 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -285,6 +285,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= ams_delta_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= ams_delta_init_irq,
 	.init_machine	= ams_delta_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 096f2ed..d7ea74a 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -378,6 +378,7 @@ MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_fsample_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_fsample_init_irq,
 	.init_machine	= omap_fsample_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index e1195a3..12e2f23 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -98,6 +98,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_generic_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_generic_init_irq,
 	.init_machine	= omap_generic_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index d1100e4..616ffa8 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -467,6 +467,7 @@ MACHINE_START(OMAP_H2, "TI-H2")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= h2_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= h2_init_irq,
 	.init_machine	= h2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index a53ab82..bd3d037 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -437,6 +437,7 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= h3_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= h3_init_irq,
 	.init_machine	= h3_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 8e313b4..8e67a10 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -304,6 +304,7 @@ MACHINE_START(HERALD, "HTC Herald")
 	.io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params    = 0x10000100,
 	.map_io         = htcherald_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq       = htcherald_init_irq,
 	.init_machine   = htcherald_init,
 	.timer          = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 5d12fd3..39bd476 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -463,6 +463,7 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= innovator_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= innovator_init_irq,
 	.init_machine	= innovator_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 71e1a3f..615670a 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -400,6 +400,7 @@ MACHINE_START(NOKIA770, "Nokia 770")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_nokia770_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_nokia770_init_irq,
 	.init_machine	= omap_nokia770_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 80d8620..bd94eb2 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -584,6 +584,7 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= osk_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= osk_init_irq,
 	.init_machine	= osk_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 569b4c9..151719f 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -373,6 +373,7 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_palmte_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_palmte_init_irq,
 	.init_machine	= omap_palmte_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 6ad49a2..5034a28 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -321,6 +321,7 @@ MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_palmtt_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_palmtt_init_irq,
 	.init_machine	= omap_palmtt_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 6641de9..ea1b033 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -338,10 +338,12 @@ omap_palmz71_map_io(void)
 }
 
 MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
-	.phys_io = 0xfff00000,
-	.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
-	.boot_params = 0x10000100,.map_io = omap_palmz71_map_io,
-	.init_irq = omap_palmz71_init_irq,
-	.init_machine = omap_palmz71_init,
-	.timer = &omap_timer,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_palmz71_map_io,
+	.reserve	= omap1_reserve,
+	.init_irq	= omap_palmz71_init_irq,
+	.init_machine	= omap_palmz71_init,
+	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index e854d57..1a0ac1c 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -339,6 +339,7 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_perseus2_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= omap_perseus2_init_irq,
 	.init_machine	= omap_perseus2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 2fb1e5f..2a833a1 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -423,7 +423,8 @@ MACHINE_START(SX1, "OMAP310 based Siemens SX1")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_sx1_map_io,
-	.init_irq		= omap_sx1_init_irq,
+	.reserve	= omap1_reserve,
+	.init_irq	= omap_sx1_init_irq,
 	.init_machine	= omap_sx1_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 87b9436..fd47c5f 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -287,6 +287,7 @@ MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= voiceblue_map_io,
+	.reserve	= omap1_reserve,
 	.init_irq	= voiceblue_init_irq,
 	.init_machine	= voiceblue_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index d9b8d82..f872406 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/omapfb.h>
 
 #include <asm/tlb.h>
 #include <asm/mach/map.h>
@@ -22,7 +23,6 @@
 
 extern void omap_check_revision(void);
 extern void omap_sram_init(void);
-extern void omapfb_reserve_sdram(void);
 
 /*
  * The machine specific code may provide the extra mapping besides the
@@ -122,7 +122,6 @@ void __init omap1_map_common_io(void)
 #endif
 
 	omap_sram_init();
-	omapfb_reserve_sdram();
 }
 
 /*
@@ -144,3 +143,7 @@ void __init omap1_init_common_hw(void)
 	omap1_mux_init();
 }
 
+void __init omap1_reserve(void)
+{
+	omapfb_reserve_sdram_lmb();
+}
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 01d113f..e7a4802 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -229,7 +229,9 @@ MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_2430sdp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_2430sdp_init_irq,
 	.init_machine	= omap_2430sdp_init,
 	.timer		= &omap_timer,
 MACHINE_END
+
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 5822bcf..cec2948 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -816,6 +816,7 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_3430sdp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_3430sdp_init_irq,
 	.init_machine	= omap_3430sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index a0a2a11..4fb164c 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -107,6 +107,7 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_sdp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_sdp_init_irq,
 	.init_machine	= omap_sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index b88f28c..a8bb755 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -134,6 +134,7 @@ MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_4430sdp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_4430sdp_init_irq,
 	.init_machine	= omap_4430sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 6ae8805..39c5c8a 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -326,6 +326,7 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= am3517_evm_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= am3517_evm_init_irq,
 	.init_machine	= am3517_evm_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index aa69fb9..dc2d735 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -346,6 +346,7 @@ MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_apollon_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_apollon_init_irq,
 	.init_machine	= omap_apollon_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 2de4f79..166bd03 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -836,6 +836,7 @@ MACHINE_START(CM_T35, "Compulab CM-T35")
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= cm_t35_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= cm_t35_init_irq,
 	.init_machine	= cm_t35_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 5bfc13b..9f41c49 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -691,6 +691,7 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= devkit8000_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= devkit8000_init_irq,
 	.init_machine	= devkit8000_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 16cc068..227e80b 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -59,6 +59,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_generic_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_generic_init_irq,
 	.init_machine	= omap_generic_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 0665f2c..5743a51 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -378,6 +378,7 @@ MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_h4_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_h4_init_irq,
 	.init_machine	= omap_h4_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 3c7789d..8242921 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -543,6 +543,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= igep2_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= igep2_init_irq,
 	.init_machine	= igep2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 5fcb52e..80d10cd 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -418,6 +418,7 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_ldp_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_ldp_init_irq,
 	.init_machine	= omap_ldp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index da9bcb8..a426063 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -687,6 +687,7 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= n8x0_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= n8x0_init_irq,
 	.init_machine	= n8x0_init_machine,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 962d377..5df89f6 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -470,6 +470,7 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_beagle_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap3_beagle_init_irq,
 	.init_machine	= omap3_beagle_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 017bb2f..49aa19c 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -726,6 +726,7 @@ MACHINE_START(OMAP3EVM, "OMAP3 EVM")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_evm_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap3_evm_init_irq,
 	.init_machine	= omap3_evm_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 395d049..ca289ed 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -601,6 +601,7 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3pandora_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap3pandora_init_irq,
 	.init_machine	= omap3pandora_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 2504d41..c59050d 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -572,6 +572,7 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_touchbook_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap3_touchbook_init_irq,
 	.init_machine	= omap3_touchbook_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 8848c7c..af67079 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -483,6 +483,7 @@ MACHINE_START(OVERO, "Gumstix Overo")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= overo_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= overo_init_irq,
 	.init_machine	= overo_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index b155c36..390a0bc 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -152,6 +152,7 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= rx51_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= rx51_init_irq,
 	.init_machine	= rx51_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 9a26f84..377c9ba 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -95,6 +95,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_zoom2_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_zoom2_init_irq,
 	.init_machine	= omap_zoom2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index cd3e40c..d33cf07 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -77,6 +77,7 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_zoom_map_io,
+	.reserve	= omap2_reserve,
 	.init_irq	= omap_zoom_init_irq,
 	.init_machine	= omap_zoom_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 87f676a..b761904 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -232,7 +232,6 @@ static void __init _omap2_map_common_io(void)
 
 	omap2_check_revision();
 	omap_sram_init();
-	omapfb_reserve_sdram();
 	omap_vram_reserve_sdram();
 }
 
@@ -340,3 +339,9 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
 	}
 	gpmc_init();
 }
+
+void __init omap2_reserve(void)
+{
+	omapfb_reserve_sdram_lmb();
+}
+
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index d3eea4f..8d9afff 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -26,7 +26,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/bootmem.h>
+#include <linux/lmb.h>
 #include <linux/io.h>
 #include <linux/omapfb.h>
 
@@ -171,49 +171,54 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
 	return 0;
 }
 
-/*
- * 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)
+void __init omapfb_reserve_sdram_lmb(void)
 {
-	struct bootmem_data	*bdata;
-	unsigned long		sdram_start, sdram_size;
-	unsigned long		reserved;
-	int			i;
-
-	if (config_invalid)
-		return;
+	unsigned long reserved = 0;
+	int i;
 
-	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;
+		struct lmb_property res;
 
 		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 != 0 && 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) {
+
+		/* Does it fall within SDRAM ? */
+		res.base = rg.paddr;
+		res.size = rg.size;
+		if (lmb_find(&res) || res.base != rg.paddr || res.size != rg.size)
+			continue;
+
+		rg.type = OMAPFB_MEMTYPE_SDRAM;
+
+		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 (lmb_is_region_reserved(rg.paddr, rg.size)) {
+				pr_err("Trying to use reserved memory for FB region %d\n", i);
+				config_invalid = 1;
+				return;
+			}
+
+			lmb_reserve(rg.paddr, rg.size);
 			reserved += rg.size;
 		}
+
+		BUG_ON(omapfb_config.mem_desc.region[i].size);
 		omapfb_config.mem_desc.region[i] = rg;
 		configured_regions++;
 	}
@@ -359,7 +364,10 @@ static inline int omap_init_fb(void)
 
 arch_initcall(omap_init_fb);
 
-void omapfb_reserve_sdram(void) {}
+void omapfb_reserve_sdram_lmb(void)
+{
+}
+
 unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
 				  unsigned long sram_vstart,
 				  unsigned long sram_size,
@@ -375,7 +383,10 @@ void omapfb_set_platform_data(struct omapfb_platform_data *data)
 {
 }
 
-void omapfb_reserve_sdram(void) {}
+void omapfb_reserve_sdram_lmb(void)
+{
+}
+
 unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
 				  unsigned long sram_vstart,
 				  unsigned long sram_size,
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 7556e27..49d662c 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -37,6 +37,9 @@ extern void __iomem *gic_cpu_base_addr;
 extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
 
+extern void omap1_reserve(void);
+extern void omap2_reserve(void);
+
 /*
  * IO bases for various OMAP processors
  * Except the tap base, rest all the io bases
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index 9bdd914..45707be 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -253,7 +253,7 @@ struct omapfb_platform_data {
 /* in arch/arm/plat-omap/fb.c */
 extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
 extern void omapfb_set_ctrl_platform_data(void *pdata);
-extern void omapfb_reserve_sdram(void);
+extern void omapfb_reserve_sdram_lmb(void);
 
 #endif
 

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-13 17:40     ` Russell King - ARM Linux
@ 2010-05-13 21:19       ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-13 21:19 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> And here's a patch which converts the OMAP FB code to use lmb_reserve
> instead of poking about with bootmem stuff.  Untested, so I'd like to
> hear back whether it works.

Did a quick test with the following patches picked from your lmb
branch on top of omap for-next branch:

ARM: Remove useless linux/bootmem.h includes
ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
ARM: initial LMB trial
ARM: Move platform LMB memory reservations out of generic code

and then this patch.

It does not boot.. It seems to be related to the patch
"ARM: initial LMB trial". If I only apply the first two patches
above the system boots.

Otherwise it only boots to:

Linux version 2.6.34-rc7-08102-ga1a6e35 ...
CPU: ARMv7 Processor [411fc083] revision 3 (ARMv7), cr=10c53c7f  
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
Machine: Nokia RX-51 board                                       
Ignoring unrecognised tag 0x414f4d50                             
bootconsole [earlycon0] enabled                                  
Memory policy: ECC disabled, Data cache writeback

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-13 21:19       ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-13 21:19 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> And here's a patch which converts the OMAP FB code to use lmb_reserve
> instead of poking about with bootmem stuff.  Untested, so I'd like to
> hear back whether it works.

Did a quick test with the following patches picked from your lmb
branch on top of omap for-next branch:

ARM: Remove useless linux/bootmem.h includes
ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
ARM: initial LMB trial
ARM: Move platform LMB memory reservations out of generic code

and then this patch.

It does not boot.. It seems to be related to the patch
"ARM: initial LMB trial". If I only apply the first two patches
above the system boots.

Otherwise it only boots to:

Linux version 2.6.34-rc7-08102-ga1a6e35 ...
CPU: ARMv7 Processor [411fc083] revision 3 (ARMv7), cr=10c53c7f  
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
Machine: Nokia RX-51 board                                       
Ignoring unrecognised tag 0x414f4d50                             
bootconsole [earlycon0] enabled                                  
Memory policy: ECC disabled, Data cache writeback

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-13 21:19       ` Tony Lindgren
@ 2010-05-13 21:58         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-13 21:58 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > hear back whether it works.
> 
> Did a quick test with the following patches picked from your lmb
> branch on top of omap for-next branch:
> 
> ARM: Remove useless linux/bootmem.h includes
> ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> ARM: initial LMB trial
> ARM: Move platform LMB memory reservations out of generic code
> 
> and then this patch.
> 
> It does not boot.. It seems to be related to the patch
> "ARM: initial LMB trial". If I only apply the first two patches
> above the system boots.

Hmm, I'm sure it worked for me when I tested it out.  Could you try
booting with lmb=debug please?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-13 21:58         ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-13 21:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > hear back whether it works.
> 
> Did a quick test with the following patches picked from your lmb
> branch on top of omap for-next branch:
> 
> ARM: Remove useless linux/bootmem.h includes
> ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> ARM: initial LMB trial
> ARM: Move platform LMB memory reservations out of generic code
> 
> and then this patch.
> 
> It does not boot.. It seems to be related to the patch
> "ARM: initial LMB trial". If I only apply the first two patches
> above the system boots.

Hmm, I'm sure it worked for me when I tested it out.  Could you try
booting with lmb=debug please?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-13 21:58         ` Russell King - ARM Linux
@ 2010-05-13 22:01           ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-13 22:01 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Tomi Valkeinen, linux-omap, linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > hear back whether it works.
> > 
> > Did a quick test with the following patches picked from your lmb
> > branch on top of omap for-next branch:
> > 
> > ARM: Remove useless linux/bootmem.h includes
> > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > ARM: initial LMB trial
> > ARM: Move platform LMB memory reservations out of generic code
> > 
> > and then this patch.
> > 
> > It does not boot.. It seems to be related to the patch
> > "ARM: initial LMB trial". If I only apply the first two patches
> > above the system boots.
> 
> Hmm, I'm sure it worked for me when I tested it out.  Could you try
> booting with lmb=debug please?

No other output with that it seems.

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-13 22:01           ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-13 22:01 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > hear back whether it works.
> > 
> > Did a quick test with the following patches picked from your lmb
> > branch on top of omap for-next branch:
> > 
> > ARM: Remove useless linux/bootmem.h includes
> > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > ARM: initial LMB trial
> > ARM: Move platform LMB memory reservations out of generic code
> > 
> > and then this patch.
> > 
> > It does not boot.. It seems to be related to the patch
> > "ARM: initial LMB trial". If I only apply the first two patches
> > above the system boots.
> 
> Hmm, I'm sure it worked for me when I tested it out.  Could you try
> booting with lmb=debug please?

No other output with that it seems.

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-13 22:01           ` Tony Lindgren
@ 2010-05-13 22:12             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-13 22:12 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > > hear back whether it works.
> > > 
> > > Did a quick test with the following patches picked from your lmb
> > > branch on top of omap for-next branch:
> > > 
> > > ARM: Remove useless linux/bootmem.h includes
> > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > > ARM: initial LMB trial
> > > ARM: Move platform LMB memory reservations out of generic code
> > > 
> > > and then this patch.
> > > 
> > > It does not boot.. It seems to be related to the patch
> > > "ARM: initial LMB trial". If I only apply the first two patches
> > > above the system boots.
> > 
> > Hmm, I'm sure it worked for me when I tested it out.  Could you try
> > booting with lmb=debug please?
> 
> No other output with that it seems.

Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-13 22:12             ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-13 22:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > > hear back whether it works.
> > > 
> > > Did a quick test with the following patches picked from your lmb
> > > branch on top of omap for-next branch:
> > > 
> > > ARM: Remove useless linux/bootmem.h includes
> > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > > ARM: initial LMB trial
> > > ARM: Move platform LMB memory reservations out of generic code
> > > 
> > > and then this patch.
> > > 
> > > It does not boot.. It seems to be related to the patch
> > > "ARM: initial LMB trial". If I only apply the first two patches
> > > above the system boots.
> > 
> > Hmm, I'm sure it worked for me when I tested it out.  Could you try
> > booting with lmb=debug please?
> 
> No other output with that it seems.

Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* RE: [RFC] Initial attempt to make ARM use LMB
  2010-05-13 22:12             ` Russell King - ARM Linux
@ 2010-05-14  7:24               ` Shilimkar, Santosh
  -1 siblings, 0 replies; 80+ messages in thread
From: Shilimkar, Santosh @ 2010-05-14  7:24 UTC (permalink / raw)
  To: Russell King - ARM Linux, Tony Lindgren
  Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Russell
> King - ARM Linux
> Sent: Friday, May 14, 2010 3:42 AM
> To: Tony Lindgren
> Cc: linux-arm-kernel@lists.infradead.org; linux-omap@vger.kernel.org; Tomi Valkeinen
> Subject: Re: [RFC] Initial attempt to make ARM use LMB
> 
> On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> > > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > > > hear back whether it works.
> > > >
> > > > Did a quick test with the following patches picked from your lmb
> > > > branch on top of omap for-next branch:
> > > >
> > > > ARM: Remove useless linux/bootmem.h includes
> > > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > > > ARM: initial LMB trial
> > > > ARM: Move platform LMB memory reservations out of generic code
> > > >
> > > > and then this patch.
> > > >
> > > > It does not boot.. It seems to be related to the patch
> > > > "ARM: initial LMB trial". If I only apply the first two patches
> > > > above the system boots.
> > >
> > > Hmm, I'm sure it worked for me when I tested it out.  Could you try
> > > booting with lmb=debug please?
> >
> > No other output with that it seems.
> 
> Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?

I just gave a try on OMAP3430 and it does boot for me. But fb doesn't
seems to be working. I have tried this on Tony's "omap-testing" 
branch where the LMB support is pulled in

*********************************************************
omapfb omapfb: failed to allocate framebuffer
omapfb omapfb: failed to allocate fbmem
omapfb omapfb: failed to setup omapfb
omapfb: probe of omapfb failed with error -12
twl_rtc twl_rtc: setting system clock to 2000-01-01 00:00:
***********************************************************
Regards,
Santosh


^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-14  7:24               ` Shilimkar, Santosh
  0 siblings, 0 replies; 80+ messages in thread
From: Shilimkar, Santosh @ 2010-05-14  7:24 UTC (permalink / raw)
  To: linux-arm-kernel

> -----Original Message-----
> From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-owner at vger.kernel.org] On Behalf Of Russell
> King - ARM Linux
> Sent: Friday, May 14, 2010 3:42 AM
> To: Tony Lindgren
> Cc: linux-arm-kernel at lists.infradead.org; linux-omap at vger.kernel.org; Tomi Valkeinen
> Subject: Re: [RFC] Initial attempt to make ARM use LMB
> 
> On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> > > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > > > hear back whether it works.
> > > >
> > > > Did a quick test with the following patches picked from your lmb
> > > > branch on top of omap for-next branch:
> > > >
> > > > ARM: Remove useless linux/bootmem.h includes
> > > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > > > ARM: initial LMB trial
> > > > ARM: Move platform LMB memory reservations out of generic code
> > > >
> > > > and then this patch.
> > > >
> > > > It does not boot.. It seems to be related to the patch
> > > > "ARM: initial LMB trial". If I only apply the first two patches
> > > > above the system boots.
> > >
> > > Hmm, I'm sure it worked for me when I tested it out.  Could you try
> > > booting with lmb=debug please?
> >
> > No other output with that it seems.
> 
> Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?

I just gave a try on OMAP3430 and it does boot for me. But fb doesn't
seems to be working. I have tried this on Tony's "omap-testing" 
branch where the LMB support is pulled in

*********************************************************
omapfb omapfb: failed to allocate framebuffer
omapfb omapfb: failed to allocate fbmem
omapfb omapfb: failed to setup omapfb
omapfb: probe of omapfb failed with error -12
twl_rtc twl_rtc: setting system clock to 2000-01-01 00:00:
***********************************************************
Regards,
Santosh

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-14  7:24               ` Shilimkar, Santosh
@ 2010-05-14 10:11                 ` Grazvydas Ignotas
  -1 siblings, 0 replies; 80+ messages in thread
From: Grazvydas Ignotas @ 2010-05-14 10:11 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: Russell King - ARM Linux, Tony Lindgren, linux-arm-kernel,
	linux-omap, Tomi Valkeinen

On Fri, May 14, 2010 at 10:24 AM, Shilimkar, Santosh
<santosh.shilimkar@ti.com> wrote:
>> On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
>> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
>> > > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
>> > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
>> > > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
>> > > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
>> > > > > hear back whether it works.
>> > > >
>> > > > Did a quick test with the following patches picked from your lmb
>> > > > branch on top of omap for-next branch:
>> > > >
>> > > > ARM: Remove useless linux/bootmem.h includes
>> > > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
>> > > > ARM: initial LMB trial
>> > > > ARM: Move platform LMB memory reservations out of generic code
>> > > >
>> > > > and then this patch.
>> > > >
>> > > > It does not boot.. It seems to be related to the patch
>> > > > "ARM: initial LMB trial". If I only apply the first two patches
>> > > > above the system boots.
>> > >
>> > > Hmm, I'm sure it worked for me when I tested it out.  Could you try
>> > > booting with lmb=debug please?
>> >
>> > No other output with that it seems.
>>
>> Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?
>
> I just gave a try on OMAP3430 and it does boot for me. But fb doesn't
> seems to be working. I have tried this on Tony's "omap-testing"
> branch where the LMB support is pulled in
>
> *********************************************************
> omapfb omapfb: failed to allocate framebuffer
> omapfb omapfb: failed to allocate fbmem
> omapfb omapfb: failed to setup omapfb
> omapfb: probe of omapfb failed with error -12
> twl_rtc twl_rtc: setting system clock to 2000-01-01 00:00:
> ***********************************************************

It seems you are using DSS2/CONFIG_FB_OMAP2, looks like this patch is
for DSS1/CONFIG_FB_OMAP.

DSS2 does have a problem on linux-next after 'ARM: Prohibit ioremap()
on kernel managed RAM' because it also uses reserve_bootmem() in
drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
be used to fix that too?
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-14 10:11                 ` Grazvydas Ignotas
  0 siblings, 0 replies; 80+ messages in thread
From: Grazvydas Ignotas @ 2010-05-14 10:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 14, 2010 at 10:24 AM, Shilimkar, Santosh
<santosh.shilimkar@ti.com> wrote:
>> On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
>> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
>> > > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
>> > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
>> > > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
>> > > > > instead of poking about with bootmem stuff. ?Untested, so I'd like to
>> > > > > hear back whether it works.
>> > > >
>> > > > Did a quick test with the following patches picked from your lmb
>> > > > branch on top of omap for-next branch:
>> > > >
>> > > > ARM: Remove useless linux/bootmem.h includes
>> > > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
>> > > > ARM: initial LMB trial
>> > > > ARM: Move platform LMB memory reservations out of generic code
>> > > >
>> > > > and then this patch.
>> > > >
>> > > > It does not boot.. It seems to be related to the patch
>> > > > "ARM: initial LMB trial". If I only apply the first two patches
>> > > > above the system boots.
>> > >
>> > > Hmm, I'm sure it worked for me when I tested it out. ?Could you try
>> > > booting with lmb=debug please?
>> >
>> > No other output with that it seems.
>>
>> Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?
>
> I just gave a try on OMAP3430 and it does boot for me. But fb doesn't
> seems to be working. I have tried this on Tony's "omap-testing"
> branch where the LMB support is pulled in
>
> *********************************************************
> omapfb omapfb: failed to allocate framebuffer
> omapfb omapfb: failed to allocate fbmem
> omapfb omapfb: failed to setup omapfb
> omapfb: probe of omapfb failed with error -12
> twl_rtc twl_rtc: setting system clock to 2000-01-01 00:00:
> ***********************************************************

It seems you are using DSS2/CONFIG_FB_OMAP2, looks like this patch is
for DSS1/CONFIG_FB_OMAP.

DSS2 does have a problem on linux-next after 'ARM: Prohibit ioremap()
on kernel managed RAM' because it also uses reserve_bootmem() in
drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
be used to fix that too?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-14 10:11                 ` Grazvydas Ignotas
@ 2010-05-14 10:16                   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-14 10:16 UTC (permalink / raw)
  To: Grazvydas Ignotas
  Cc: Shilimkar, Santosh, Tony Lindgren, linux-arm-kernel, linux-omap,
	Tomi Valkeinen

On Fri, May 14, 2010 at 01:11:43PM +0300, Grazvydas Ignotas wrote:
> It seems you are using DSS2/CONFIG_FB_OMAP2, looks like this patch is
> for DSS1/CONFIG_FB_OMAP.
> 
> DSS2 does have a problem on linux-next after 'ARM: Prohibit ioremap()
> on kernel managed RAM'

I'm going to drop that patch out - but that's not to say it won't return
(it will.)

> because it also uses reserve_bootmem() in
> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
> be used to fix that too?

WTF is reserve_bootmem doing in a driver?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-14 10:16                   ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-14 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 14, 2010 at 01:11:43PM +0300, Grazvydas Ignotas wrote:
> It seems you are using DSS2/CONFIG_FB_OMAP2, looks like this patch is
> for DSS1/CONFIG_FB_OMAP.
> 
> DSS2 does have a problem on linux-next after 'ARM: Prohibit ioremap()
> on kernel managed RAM'

I'm going to drop that patch out - but that's not to say it won't return
(it will.)

> because it also uses reserve_bootmem() in
> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
> be used to fix that too?

WTF is reserve_bootmem doing in a driver?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-13 22:12             ` Russell King - ARM Linux
@ 2010-05-14 15:22               ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-14 15:22 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 15:07]:
> On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> > > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > > > hear back whether it works.
> > > > 
> > > > Did a quick test with the following patches picked from your lmb
> > > > branch on top of omap for-next branch:
> > > > 
> > > > ARM: Remove useless linux/bootmem.h includes
> > > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > > > ARM: initial LMB trial
> > > > ARM: Move platform LMB memory reservations out of generic code
> > > > 
> > > > and then this patch.
> > > > 
> > > > It does not boot.. It seems to be related to the patch
> > > > "ARM: initial LMB trial". If I only apply the first two patches
> > > > above the system boots.
> > > 
> > > Hmm, I'm sure it worked for me when I tested it out.  Could you try
> > > booting with lmb=debug please?
> > 
> > No other output with that it seems.
> 
> Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?

Hmm, looks like I did not send a reply yesterday.. Here's a
second attempt.

Yeah, that missing patch was it. Compiles and boots now:

Tested-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-14 15:22               ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-14 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 15:07]:
> On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> > > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > > > hear back whether it works.
> > > > 
> > > > Did a quick test with the following patches picked from your lmb
> > > > branch on top of omap for-next branch:
> > > > 
> > > > ARM: Remove useless linux/bootmem.h includes
> > > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > > > ARM: initial LMB trial
> > > > ARM: Move platform LMB memory reservations out of generic code
> > > > 
> > > > and then this patch.
> > > > 
> > > > It does not boot.. It seems to be related to the patch
> > > > "ARM: initial LMB trial". If I only apply the first two patches
> > > > above the system boots.
> > > 
> > > Hmm, I'm sure it worked for me when I tested it out.  Could you try
> > > booting with lmb=debug please?
> > 
> > No other output with that it seems.
> 
> Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?

Hmm, looks like I did not send a reply yesterday.. Here's a
second attempt.

Yeah, that missing patch was it. Compiles and boots now:

Tested-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* RE: [RFC] Initial attempt to make ARM use LMB
  2010-05-14 15:22               ` Tony Lindgren
@ 2010-05-14 15:32                 ` Shilimkar, Santosh
  -1 siblings, 0 replies; 80+ messages in thread
From: Shilimkar, Santosh @ 2010-05-14 15:32 UTC (permalink / raw)
  To: Tony Lindgren, Russell King - ARM Linux
  Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

Tony,
> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Tony
> Lindgren
> Sent: Friday, May 14, 2010 8:52 PM
> To: Russell King - ARM Linux
> Cc: linux-arm-kernel@lists.infradead.org; linux-omap@vger.kernel.org; Tomi Valkeinen
> Subject: Re: [RFC] Initial attempt to make ARM use LMB
> 
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 15:07]:
> > On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
> > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> > > > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > > > > hear back whether it works.
> > > > >
> > > > > Did a quick test with the following patches picked from your lmb
> > > > > branch on top of omap for-next branch:
> > > > >
> > > > > ARM: Remove useless linux/bootmem.h includes
> > > > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > > > > ARM: initial LMB trial
> > > > > ARM: Move platform LMB memory reservations out of generic code
> > > > >
> > > > > and then this patch.
> > > > >
> > > > > It does not boot.. It seems to be related to the patch
> > > > > "ARM: initial LMB trial". If I only apply the first two patches
> > > > > above the system boots.
> > > >
> > > > Hmm, I'm sure it worked for me when I tested it out.  Could you try
> > > > booting with lmb=debug please?
> > >
> > > No other output with that it seems.
> >
> > Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?
> 
> Hmm, looks like I did not send a reply yesterday.. Here's a
> second attempt.
> 
> Yeah, that missing patch was it. Compiles and boots now:
> 
> Tested-by: Tony Lindgren <tony@atomide.com>

Did you get the frame buffer with lmb ??


^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-14 15:32                 ` Shilimkar, Santosh
  0 siblings, 0 replies; 80+ messages in thread
From: Shilimkar, Santosh @ 2010-05-14 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

Tony,
> -----Original Message-----
> From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-owner at vger.kernel.org] On Behalf Of Tony
> Lindgren
> Sent: Friday, May 14, 2010 8:52 PM
> To: Russell King - ARM Linux
> Cc: linux-arm-kernel at lists.infradead.org; linux-omap at vger.kernel.org; Tomi Valkeinen
> Subject: Re: [RFC] Initial attempt to make ARM use LMB
> 
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 15:07]:
> > On Thu, May 13, 2010 at 03:01:39PM -0700, Tony Lindgren wrote:
> > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 14:53]:
> > > > On Thu, May 13, 2010 at 02:19:51PM -0700, Tony Lindgren wrote:
> > > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100513 10:35]:
> > > > > > And here's a patch which converts the OMAP FB code to use lmb_reserve
> > > > > > instead of poking about with bootmem stuff.  Untested, so I'd like to
> > > > > > hear back whether it works.
> > > > >
> > > > > Did a quick test with the following patches picked from your lmb
> > > > > branch on top of omap for-next branch:
> > > > >
> > > > > ARM: Remove useless linux/bootmem.h includes
> > > > > ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
> > > > > ARM: initial LMB trial
> > > > > ARM: Move platform LMB memory reservations out of generic code
> > > > >
> > > > > and then this patch.
> > > > >
> > > > > It does not boot.. It seems to be related to the patch
> > > > > "ARM: initial LMB trial". If I only apply the first two patches
> > > > > above the system boots.
> > > >
> > > > Hmm, I'm sure it worked for me when I tested it out.  Could you try
> > > > booting with lmb=debug please?
> > >
> > > No other output with that it seems.
> >
> > Hang on, you didn't pick up ARM: Move memory mapping into mmu.c ?
> 
> Hmm, looks like I did not send a reply yesterday.. Here's a
> second attempt.
> 
> Yeah, that missing patch was it. Compiles and boots now:
> 
> Tested-by: Tony Lindgren <tony@atomide.com>

Did you get the frame buffer with lmb ??

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-14 15:32                 ` Shilimkar, Santosh
@ 2010-05-14 15:43                   ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-14 15:43 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: Russell King - ARM Linux, linux-arm-kernel, linux-omap, Tomi Valkeinen

* Shilimkar, Santosh <santosh.shilimkar@ti.com> [100514 08:28]:
> > 
> > Yeah, that missing patch was it. Compiles and boots now:
> > 
> > Tested-by: Tony Lindgren <tony@atomide.com>
> 
> Did you get the frame buffer with lmb ??

I've never gotten a DSS2 frame buffer yet with the code that's
in omap for-next, but I believe Tomi has the missing pieces queued up.

My tested-by was for the patch not breaking the current behaviour,
basically to make sure things boot. So since it's really half
tested, maybe acked-by would be more suitable.

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-14 15:43                   ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-14 15:43 UTC (permalink / raw)
  To: linux-arm-kernel

* Shilimkar, Santosh <santosh.shilimkar@ti.com> [100514 08:28]:
> > 
> > Yeah, that missing patch was it. Compiles and boots now:
> > 
> > Tested-by: Tony Lindgren <tony@atomide.com>
> 
> Did you get the frame buffer with lmb ??

I've never gotten a DSS2 frame buffer yet with the code that's
in omap for-next, but I believe Tomi has the missing pieces queued up.

My tested-by was for the patch not breaking the current behaviour,
basically to make sure things boot. So since it's really half
tested, maybe acked-by would be more suitable.

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-14 10:16                   ` Russell King - ARM Linux
@ 2010-05-17  9:38                     ` Grazvydas Ignotas
  -1 siblings, 0 replies; 80+ messages in thread
From: Grazvydas Ignotas @ 2010-05-17  9:38 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Shilimkar, Santosh, Tony Lindgren, linux-arm-kernel, linux-omap,
	Tomi Valkeinen

On Fri, May 14, 2010 at 1:16 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
>> because it also uses reserve_bootmem() in
>> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
>> be used to fix that too?
>
> WTF is reserve_bootmem doing in a driver?

IIRC Tony refused any new fb related code in arch/arm/*omap* so it
ended up there (or maybe because of something else, not that I had
anything to do with this).

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-17  9:38                     ` Grazvydas Ignotas
  0 siblings, 0 replies; 80+ messages in thread
From: Grazvydas Ignotas @ 2010-05-17  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 14, 2010 at 1:16 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
>> because it also uses reserve_bootmem() in
>> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
>> be used to fix that too?
>
> WTF is reserve_bootmem doing in a driver?

IIRC Tony refused any new fb related code in arch/arm/*omap* so it
ended up there (or maybe because of something else, not that I had
anything to do with this).

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-17  9:38                     ` Grazvydas Ignotas
@ 2010-05-17  9:44                       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-17  9:44 UTC (permalink / raw)
  To: Grazvydas Ignotas
  Cc: Shilimkar, Santosh, Tony Lindgren, linux-arm-kernel, linux-omap,
	Tomi Valkeinen

On Mon, May 17, 2010 at 12:38:55PM +0300, Grazvydas Ignotas wrote:
> On Fri, May 14, 2010 at 1:16 PM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> >> because it also uses reserve_bootmem() in
> >> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
> >> be used to fix that too?
> >
> > WTF is reserve_bootmem doing in a driver?
> 
> IIRC Tony refused any new fb related code in arch/arm/*omap* so it
> ended up there (or maybe because of something else, not that I had
> anything to do with this).

Can someone please answer these questions:

1. why does the framebuffer need to _reserve_ a set of specific sections
   of SDRAM rather than _allocate_ a set of sections?
2. what range of sizes of SDRAM does the framebuffer driver need?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-17  9:44                       ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-17  9:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 17, 2010 at 12:38:55PM +0300, Grazvydas Ignotas wrote:
> On Fri, May 14, 2010 at 1:16 PM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> >> because it also uses reserve_bootmem() in
> >> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
> >> be used to fix that too?
> >
> > WTF is reserve_bootmem doing in a driver?
> 
> IIRC Tony refused any new fb related code in arch/arm/*omap* so it
> ended up there (or maybe because of something else, not that I had
> anything to do with this).

Can someone please answer these questions:

1. why does the framebuffer need to _reserve_ a set of specific sections
   of SDRAM rather than _allocate_ a set of sections?
2. what range of sizes of SDRAM does the framebuffer driver need?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-17  9:44                       ` Russell King - ARM Linux
@ 2010-05-17 10:26                         ` Tomi Valkeinen
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-17 10:26 UTC (permalink / raw)
  To: ext Russell King - ARM Linux
  Cc: Grazvydas Ignotas, Shilimkar, Santosh, Tony Lindgren,
	linux-arm-kernel, linux-omap

Hi,

On Mon, 2010-05-17 at 11:44 +0200, ext Russell King - ARM Linux wrote:
> On Mon, May 17, 2010 at 12:38:55PM +0300, Grazvydas Ignotas wrote:
> > On Fri, May 14, 2010 at 1:16 PM, Russell King - ARM Linux
> > <linux@arm.linux.org.uk> wrote:
> > >> because it also uses reserve_bootmem() in
> > >> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
> > >> be used to fix that too?
> > >
> > > WTF is reserve_bootmem doing in a driver?
> > 
> > IIRC Tony refused any new fb related code in arch/arm/*omap* so it
> > ended up there (or maybe because of something else, not that I had
> > anything to do with this).
> 
> Can someone please answer these questions:
> 
> 1. why does the framebuffer need to _reserve_ a set of specific sections
>    of SDRAM rather than _allocate_ a set of sections?
> 2. what range of sizes of SDRAM does the framebuffer driver need?

Yep, vram.c was first located in arch/arm/plat-omap/ but was moved under
drivers/video/omap2 by request from Tony. vram.c is not really a driver,
so in that sense I think it'd fit better into arch/arm/plat-omap/.

To question 1:

- The bootloader may use a certain area of memory to display to boot
image, and the kernel needs to use this same memory area for the
framebuffer, so that we don't get any glitches on the display during
boot. If this is not required, then the memory areas can be allocated.

- OMAP display hardware requires a continuous memory area for the
framebuffer. Allocating such a large continuous memory area later seemed
to be next to impossible, probably because of memory fragmentation.

- Originally I used dma_alloc_*, but that doesn't support the
bootloader-init case, and I also wanted to support having the
framebuffer in OMAP's SRAM. Also, if I recall right, dma_alloc_* didn't
support the huge allocations that are needed for the framebuffer.

To 2:
It varies a lot on the use case. One can configure the reserved VRAM
area, and I would imagine that the smallest would be something like
~150kB (320x240x2) and the largest in extreme case ~40MB (1600x1200*4,
x2 for double buffering and x3 for each overlay).

 Tomi



^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-17 10:26                         ` Tomi Valkeinen
  0 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-17 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, 2010-05-17 at 11:44 +0200, ext Russell King - ARM Linux wrote:
> On Mon, May 17, 2010 at 12:38:55PM +0300, Grazvydas Ignotas wrote:
> > On Fri, May 14, 2010 at 1:16 PM, Russell King - ARM Linux
> > <linux@arm.linux.org.uk> wrote:
> > >> because it also uses reserve_bootmem() in
> > >> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
> > >> be used to fix that too?
> > >
> > > WTF is reserve_bootmem doing in a driver?
> > 
> > IIRC Tony refused any new fb related code in arch/arm/*omap* so it
> > ended up there (or maybe because of something else, not that I had
> > anything to do with this).
> 
> Can someone please answer these questions:
> 
> 1. why does the framebuffer need to _reserve_ a set of specific sections
>    of SDRAM rather than _allocate_ a set of sections?
> 2. what range of sizes of SDRAM does the framebuffer driver need?

Yep, vram.c was first located in arch/arm/plat-omap/ but was moved under
drivers/video/omap2 by request from Tony. vram.c is not really a driver,
so in that sense I think it'd fit better into arch/arm/plat-omap/.

To question 1:

- The bootloader may use a certain area of memory to display to boot
image, and the kernel needs to use this same memory area for the
framebuffer, so that we don't get any glitches on the display during
boot. If this is not required, then the memory areas can be allocated.

- OMAP display hardware requires a continuous memory area for the
framebuffer. Allocating such a large continuous memory area later seemed
to be next to impossible, probably because of memory fragmentation.

- Originally I used dma_alloc_*, but that doesn't support the
bootloader-init case, and I also wanted to support having the
framebuffer in OMAP's SRAM. Also, if I recall right, dma_alloc_* didn't
support the huge allocations that are needed for the framebuffer.

To 2:
It varies a lot on the use case. One can configure the reserved VRAM
area, and I would imagine that the smallest would be something like
~150kB (320x240x2) and the largest in extreme case ~40MB (1600x1200*4,
x2 for double buffering and x3 for each overlay).

 Tomi

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-17 10:26                         ` Tomi Valkeinen
@ 2010-05-17 17:37                           ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-17 17:37 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: ext Russell King - ARM Linux, Grazvydas Ignotas, Shilimkar,
	Santosh, linux-arm-kernel, linux-omap

* Tomi Valkeinen <tomi.valkeinen@nokia.com> [100517 03:21]:
> Hi,
> 
> On Mon, 2010-05-17 at 11:44 +0200, ext Russell King - ARM Linux wrote:
> > On Mon, May 17, 2010 at 12:38:55PM +0300, Grazvydas Ignotas wrote:
> > > On Fri, May 14, 2010 at 1:16 PM, Russell King - ARM Linux
> > > <linux@arm.linux.org.uk> wrote:
> > > >> because it also uses reserve_bootmem() in
> > > >> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
> > > >> be used to fix that too?
> > > >
> > > > WTF is reserve_bootmem doing in a driver?
> > > 
> > > IIRC Tony refused any new fb related code in arch/arm/*omap* so it
> > > ended up there (or maybe because of something else, not that I had
> > > anything to do with this).
> > 
> > Can someone please answer these questions:
> > 
> > 1. why does the framebuffer need to _reserve_ a set of specific sections
> >    of SDRAM rather than _allocate_ a set of sections?
> > 2. what range of sizes of SDRAM does the framebuffer driver need?
> 
> Yep, vram.c was first located in arch/arm/plat-omap/ but was moved under
> drivers/video/omap2 by request from Tony. vram.c is not really a driver,
> so in that sense I think it'd fit better into arch/arm/plat-omap/.
> 
> To question 1:
> 
> - The bootloader may use a certain area of memory to display to boot
> image, and the kernel needs to use this same memory area for the
> framebuffer, so that we don't get any glitches on the display during
> boot. If this is not required, then the memory areas can be allocated.
> 
> - OMAP display hardware requires a continuous memory area for the
> framebuffer. Allocating such a large continuous memory area later seemed
> to be next to impossible, probably because of memory fragmentation.
> 
> - Originally I used dma_alloc_*, but that doesn't support the
> bootloader-init case, and I also wanted to support having the
> framebuffer in OMAP's SRAM. Also, if I recall right, dma_alloc_* didn't
> support the huge allocations that are needed for the framebuffer.
> 
> To 2:
> It varies a lot on the use case. One can configure the reserved VRAM
> area, and I would imagine that the smallest would be something like
> ~150kB (320x240x2) and the largest in extreme case ~40MB (1600x1200*4,
> x2 for double buffering and x3 for each overlay).

Sorry if I've been confused about what vram.c is doing.

How about change vram.c to use dma_alloc_coherent for now? That would
break the non-standard behaviour to preserve the log set by the
bootloader, but that should be OK until we know how to deal with that
properly.

After that you could just optionally reserve the bootloader memory
area using LMB based on some flags in the platform init data.

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-17 17:37                           ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-17 17:37 UTC (permalink / raw)
  To: linux-arm-kernel

* Tomi Valkeinen <tomi.valkeinen@nokia.com> [100517 03:21]:
> Hi,
> 
> On Mon, 2010-05-17 at 11:44 +0200, ext Russell King - ARM Linux wrote:
> > On Mon, May 17, 2010 at 12:38:55PM +0300, Grazvydas Ignotas wrote:
> > > On Fri, May 14, 2010 at 1:16 PM, Russell King - ARM Linux
> > > <linux@arm.linux.org.uk> wrote:
> > > >> because it also uses reserve_bootmem() in
> > > >> drivers/video/omap2/vram.c and later ioremap on RAM. Perhaps LMB can
> > > >> be used to fix that too?
> > > >
> > > > WTF is reserve_bootmem doing in a driver?
> > > 
> > > IIRC Tony refused any new fb related code in arch/arm/*omap* so it
> > > ended up there (or maybe because of something else, not that I had
> > > anything to do with this).
> > 
> > Can someone please answer these questions:
> > 
> > 1. why does the framebuffer need to _reserve_ a set of specific sections
> >    of SDRAM rather than _allocate_ a set of sections?
> > 2. what range of sizes of SDRAM does the framebuffer driver need?
> 
> Yep, vram.c was first located in arch/arm/plat-omap/ but was moved under
> drivers/video/omap2 by request from Tony. vram.c is not really a driver,
> so in that sense I think it'd fit better into arch/arm/plat-omap/.
> 
> To question 1:
> 
> - The bootloader may use a certain area of memory to display to boot
> image, and the kernel needs to use this same memory area for the
> framebuffer, so that we don't get any glitches on the display during
> boot. If this is not required, then the memory areas can be allocated.
> 
> - OMAP display hardware requires a continuous memory area for the
> framebuffer. Allocating such a large continuous memory area later seemed
> to be next to impossible, probably because of memory fragmentation.
> 
> - Originally I used dma_alloc_*, but that doesn't support the
> bootloader-init case, and I also wanted to support having the
> framebuffer in OMAP's SRAM. Also, if I recall right, dma_alloc_* didn't
> support the huge allocations that are needed for the framebuffer.
> 
> To 2:
> It varies a lot on the use case. One can configure the reserved VRAM
> area, and I would imagine that the smallest would be something like
> ~150kB (320x240x2) and the largest in extreme case ~40MB (1600x1200*4,
> x2 for double buffering and x3 for each overlay).

Sorry if I've been confused about what vram.c is doing.

How about change vram.c to use dma_alloc_coherent for now? That would
break the non-standard behaviour to preserve the log set by the
bootloader, but that should be OK until we know how to deal with that
properly.

After that you could just optionally reserve the bootloader memory
area using LMB based on some flags in the platform init data.

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-17 17:37                           ` Tony Lindgren
@ 2010-05-18  7:47                             ` Tomi Valkeinen
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-18  7:47 UTC (permalink / raw)
  To: ext Tony Lindgren
  Cc: ext Russell King - ARM Linux, Grazvydas Ignotas, Shilimkar,
	Santosh, linux-arm-kernel, linux-omap

On Mon, 2010-05-17 at 19:37 +0200, ext Tony Lindgren wrote:

> Sorry if I've been confused about what vram.c is doing.
> 
> How about change vram.c to use dma_alloc_coherent for now? That would
> break the non-standard behaviour to preserve the log set by the
> bootloader, but that should be OK until we know how to deal with that
> properly.
> 
> After that you could just optionally reserve the bootloader memory
> area using LMB based on some flags in the platform init data.

>From vram.c's commit log about features vram.c supports but dma_alloc_*
doesn't:

    - Support for OMAP2's SRAM
    - Allocate without ioremapping
    - Allocate at defined physical addresses
    - Allows larger VRAM area and larger allocations

I haven't heard anybody using OMAP2's SRAM for framebuffer, so that's
probably not an issue.

Reserving the memory at defined physical address is needed for the
bootloader-framebuffer, but I think it's only used on N900's product
kernel with some additional hacks. So that's probably not an issue
either.

Allocating without ioremapping... dma_alloc_* always ioremaps the
allocated area, even though it's never used (in some cases). I think
this is the case when using OMAP's VRFB rotation HW. This may or may not
be an issue, depending on the amount of memory allocated and the
available virtual mem area.

And the last point, I think there was a limit of about 8MB when
allocating with dma_alloc_* (I may remember wrong). This could be a
problem for some use cases.

So, I guess it's possible to use dma_alloc_*, but there may be some
complications.

I still haven't found time to look at the LMB stuff, but I hope I'll
manage to do that this week.

 Tomi



^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-18  7:47                             ` Tomi Valkeinen
  0 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-18  7:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2010-05-17 at 19:37 +0200, ext Tony Lindgren wrote:

> Sorry if I've been confused about what vram.c is doing.
> 
> How about change vram.c to use dma_alloc_coherent for now? That would
> break the non-standard behaviour to preserve the log set by the
> bootloader, but that should be OK until we know how to deal with that
> properly.
> 
> After that you could just optionally reserve the bootloader memory
> area using LMB based on some flags in the platform init data.

>From vram.c's commit log about features vram.c supports but dma_alloc_*
doesn't:

    - Support for OMAP2's SRAM
    - Allocate without ioremapping
    - Allocate at defined physical addresses
    - Allows larger VRAM area and larger allocations

I haven't heard anybody using OMAP2's SRAM for framebuffer, so that's
probably not an issue.

Reserving the memory at defined physical address is needed for the
bootloader-framebuffer, but I think it's only used on N900's product
kernel with some additional hacks. So that's probably not an issue
either.

Allocating without ioremapping... dma_alloc_* always ioremaps the
allocated area, even though it's never used (in some cases). I think
this is the case when using OMAP's VRFB rotation HW. This may or may not
be an issue, depending on the amount of memory allocated and the
available virtual mem area.

And the last point, I think there was a limit of about 8MB when
allocating with dma_alloc_* (I may remember wrong). This could be a
problem for some use cases.

So, I guess it's possible to use dma_alloc_*, but there may be some
complications.

I still haven't found time to look at the LMB stuff, but I hope I'll
manage to do that this week.

 Tomi

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-18  7:47                             ` Tomi Valkeinen
@ 2010-05-18  8:40                               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-18  8:40 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: ext Tony Lindgren, Grazvydas Ignotas, Shilimkar, Santosh,
	linux-arm-kernel, linux-omap

On Tue, May 18, 2010 at 10:47:57AM +0300, Tomi Valkeinen wrote:
> Allocating without ioremapping... dma_alloc_* always ioremaps the
> allocated area, even though it's never used (in some cases).

What do you mean by that?  Are you suggesting that something does
phys_to_virt() on the returned DMA pointer?

Why is it that OMAP seems to do all these _wrong_ things?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-18  8:40                               ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-18  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 18, 2010 at 10:47:57AM +0300, Tomi Valkeinen wrote:
> Allocating without ioremapping... dma_alloc_* always ioremaps the
> allocated area, even though it's never used (in some cases).

What do you mean by that?  Are you suggesting that something does
phys_to_virt() on the returned DMA pointer?

Why is it that OMAP seems to do all these _wrong_ things?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-18  8:40                               ` Russell King - ARM Linux
@ 2010-05-18  8:58                                 ` Tomi Valkeinen
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-18  8:58 UTC (permalink / raw)
  To: ext Russell King - ARM Linux
  Cc: ext Tony Lindgren, Grazvydas Ignotas, Shilimkar, Santosh,
	linux-arm-kernel, linux-omap

On Tue, 2010-05-18 at 10:40 +0200, ext Russell King - ARM Linux wrote:
> On Tue, May 18, 2010 at 10:47:57AM +0300, Tomi Valkeinen wrote:
> > Allocating without ioremapping... dma_alloc_* always ioremaps the
> > allocated area, even though it's never used (in some cases).
> 
> What do you mean by that?  Are you suggesting that something does
> phys_to_virt() on the returned DMA pointer?

No.

VRFB rotation HW uses the real memory as a backend storage, and exposes
0/90/180/270 degree views of that memory area via its own memory areas.
So we need to reserve the real memory, program it to VRFB HW, and then
map VRFB's memory areas, which are used as framebuffers. The real memory
is never used directly in this case.

And even when not using VRFB, I think it's not really required to map
the framebuffer into kernel virtual memory. The kernel doesn't
read/write from/to the framebuffer (except when using FB console), it's
the user space, SGX or DSP that does the writing, and DSS which does the
reading. However, currently the framebuffer is always mapped.

 Tomi



^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-18  8:58                                 ` Tomi Valkeinen
  0 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-18  8:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2010-05-18 at 10:40 +0200, ext Russell King - ARM Linux wrote:
> On Tue, May 18, 2010 at 10:47:57AM +0300, Tomi Valkeinen wrote:
> > Allocating without ioremapping... dma_alloc_* always ioremaps the
> > allocated area, even though it's never used (in some cases).
> 
> What do you mean by that?  Are you suggesting that something does
> phys_to_virt() on the returned DMA pointer?

No.

VRFB rotation HW uses the real memory as a backend storage, and exposes
0/90/180/270 degree views of that memory area via its own memory areas.
So we need to reserve the real memory, program it to VRFB HW, and then
map VRFB's memory areas, which are used as framebuffers. The real memory
is never used directly in this case.

And even when not using VRFB, I think it's not really required to map
the framebuffer into kernel virtual memory. The kernel doesn't
read/write from/to the framebuffer (except when using FB console), it's
the user space, SGX or DSP that does the writing, and DSS which does the
reading. However, currently the framebuffer is always mapped.

 Tomi

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-03-25 23:32 ` Russell King - ARM Linux
@ 2010-05-22 21:58   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-22 21:58 UTC (permalink / raw)
  To: linux-arm-kernel, Tony Lindgren; +Cc: linux-omap

I'm going to take a slightly different approach to LMB given the
(unique) problems that OMAP has with converting over to LMB.  I've
been re-ordering my patchset so that we do as many changes as
possible to sanitize the code before introducing LMB.

So, below is a patch to sanitize the code in arch/arm/plat-omap/fb.c.
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.  I suggest this should be validated
well before the next merge window.

I'm sure with the SDRAM code simplified like this, the SRAM code can be
cleaned up and some of the complex helper functions killed off.

diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index d3eea4f..97db493 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++;
 	}

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-22 21:58   ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-22 21:58 UTC (permalink / raw)
  To: linux-arm-kernel

I'm going to take a slightly different approach to LMB given the
(unique) problems that OMAP has with converting over to LMB.  I've
been re-ordering my patchset so that we do as many changes as
possible to sanitize the code before introducing LMB.

So, below is a patch to sanitize the code in arch/arm/plat-omap/fb.c.
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 -@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.  I suggest this should be validated
well before the next merge window.

I'm sure with the SDRAM code simplified like this, the SRAM code can be
cleaned up and some of the complex helper functions killed off.

diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index d3eea4f..97db493 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++;
 	}

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-22 21:58   ` Russell King - ARM Linux
@ 2010-05-26  0:44     ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-26  0:44 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100522 14:53]:
> I'm going to take a slightly different approach to LMB given the
> (unique) problems that OMAP has with converting over to LMB.  I've
> been re-ordering my patchset so that we do as many changes as
> possible to sanitize the code before introducing LMB.

OK, looks like you have some interesting new patches in your
lmb branch :)
 
> So, below is a patch to sanitize the code in arch/arm/plat-omap/fb.c.
> The logic in this file is rather convoluted, but essentially:

I've tried the patch below with the patches from your lmb branch
up to this one and I can see tux on my osk5912 and n900:

Acked-by: Tony Lindgren <tony@atomide.com>

After applying the next patch in your lmb branch "ARM: OMAP: Convert
to use ->reserve method to reserve boot time memory" tux still works
on 5912osk, but not on n900. The difference is that osk5912 uses
the old omapfb code.

Then, looks like reordering of the patches now causes patch
"ARM: initial LMB trial" to fail with:

arch/arm/mm/init.c:301: error: conflicting types for 'bootmem_init'
arch/arm/mm/mm.h:32: error: previous declaration of 'bootmem_init' was here
arch/arm/mm/init.c: In function 'bootmem_init':
arch/arm/mm/init.c:312: error: 'mdesc' undeclared (first use in this function)
arch/arm/mm/init.c:312: error: (Each undeclared identifier is reported only once
arch/arm/mm/init.c:312: error: for each function it appears in.)
make[1]: *** [arch/arm/mm/init.o] Error 1

Also, the last patch in lmb branch "ARM: use LMB to allocate system
memory MMIO resource structures" causes both osk5912 and n900
to hang very early. Maybe I'm missing some patch again..

Anyways, I've picked the patches from lmb branch up to the one below
into omap-testing. Will add more of them once we get them working.

Would be nice to get acks from Tomi too, and especially the remaining
patches are interesting from Tomi's point of view.

BTW, after today I'll only have remote access to my most of my
boards, so I maybe not be able to test the changes properly from
seeing tux point of view.

Regards,

Tony
 
> 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.  I suggest this should be validated
> well before the next merge window.
> 
> I'm sure with the SDRAM code simplified like this, the SRAM code can be
> cleaned up and some of the complex helper functions killed off.
> 
> diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
> index d3eea4f..97db493 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++;
>  	}

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-26  0:44     ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-26  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100522 14:53]:
> I'm going to take a slightly different approach to LMB given the
> (unique) problems that OMAP has with converting over to LMB.  I've
> been re-ordering my patchset so that we do as many changes as
> possible to sanitize the code before introducing LMB.

OK, looks like you have some interesting new patches in your
lmb branch :)
 
> So, below is a patch to sanitize the code in arch/arm/plat-omap/fb.c.
> The logic in this file is rather convoluted, but essentially:

I've tried the patch below with the patches from your lmb branch
up to this one and I can see tux on my osk5912 and n900:

Acked-by: Tony Lindgren <tony@atomide.com>

After applying the next patch in your lmb branch "ARM: OMAP: Convert
to use ->reserve method to reserve boot time memory" tux still works
on 5912osk, but not on n900. The difference is that osk5912 uses
the old omapfb code.

Then, looks like reordering of the patches now causes patch
"ARM: initial LMB trial" to fail with:

arch/arm/mm/init.c:301: error: conflicting types for 'bootmem_init'
arch/arm/mm/mm.h:32: error: previous declaration of 'bootmem_init' was here
arch/arm/mm/init.c: In function 'bootmem_init':
arch/arm/mm/init.c:312: error: 'mdesc' undeclared (first use in this function)
arch/arm/mm/init.c:312: error: (Each undeclared identifier is reported only once
arch/arm/mm/init.c:312: error: for each function it appears in.)
make[1]: *** [arch/arm/mm/init.o] Error 1

Also, the last patch in lmb branch "ARM: use LMB to allocate system
memory MMIO resource structures" causes both osk5912 and n900
to hang very early. Maybe I'm missing some patch again..

Anyways, I've picked the patches from lmb branch up to the one below
into omap-testing. Will add more of them once we get them working.

Would be nice to get acks from Tomi too, and especially the remaining
patches are interesting from Tomi's point of view.

BTW, after today I'll only have remote access to my most of my
boards, so I maybe not be able to test the changes properly from
seeing tux point of view.

Regards,

Tony
 
> 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.  I suggest this should be validated
> well before the next merge window.
> 
> I'm sure with the SDRAM code simplified like this, the SRAM code can be
> cleaned up and some of the complex helper functions killed off.
> 
> diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
> index d3eea4f..97db493 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++;
>  	}

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-26  0:44     ` Tony Lindgren
@ 2010-05-26  7:50       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-26  7:50 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> > So, below is a patch to sanitize the code in arch/arm/plat-omap/fb.c.
> > The logic in this file is rather convoluted, but essentially:
> 
> I've tried the patch below with the patches from your lmb branch
> up to this one and I can see tux on my osk5912 and n900:
> 
> Acked-by: Tony Lindgren <tony@atomide.com>

Interesting patch name!

> After applying the next patch in your lmb branch "ARM: OMAP: Convert
> to use ->reserve method to reserve boot time memory" tux still works
> on 5912osk, but not on n900. The difference is that osk5912 uses
> the old omapfb code.

I guess this is because I don't have board-n900.c in my tree.  All OMAP
boards need a ".reserve = omap_reserve," line added in their machine
descriptor.

I just noticed that board-n8x0.c contains more than one machine descriptor,
which I've now fixed up.

> Then, looks like reordering of the patches now causes patch
> "ARM: initial LMB trial" to fail with:
> 
> arch/arm/mm/init.c:301: error: conflicting types for 'bootmem_init'
> arch/arm/mm/mm.h:32: error: previous declaration of 'bootmem_init' was here
> arch/arm/mm/init.c: In function 'bootmem_init':
> arch/arm/mm/init.c:312: error: 'mdesc' undeclared (first use in this function)
> arch/arm/mm/init.c:312: error: (Each undeclared identifier is reported only once
> arch/arm/mm/init.c:312: error: for each function it appears in.)
> make[1]: *** [arch/arm/mm/init.o] Error 1

Now fixed, thanks.

> Also, the last patch in lmb branch "ARM: use LMB to allocate system
> memory MMIO resource structures" causes both osk5912 and n900
> to hang very early. Maybe I'm missing some patch again..

Hmm, I'll take a look later today.

> Anyways, I've picked the patches from lmb branch up to the one below
> into omap-testing. Will add more of them once we get them working.

You should now be able to pick all but the last patch.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-26  7:50       ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-26  7:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> > So, below is a patch to sanitize the code in arch/arm/plat-omap/fb.c.
> > The logic in this file is rather convoluted, but essentially:
> 
> I've tried the patch below with the patches from your lmb branch
> up to this one and I can see tux on my osk5912 and n900:
> 
> Acked-by: Tony Lindgren <tony@atomide.com>

Interesting patch name!

> After applying the next patch in your lmb branch "ARM: OMAP: Convert
> to use ->reserve method to reserve boot time memory" tux still works
> on 5912osk, but not on n900. The difference is that osk5912 uses
> the old omapfb code.

I guess this is because I don't have board-n900.c in my tree.  All OMAP
boards need a ".reserve = omap_reserve," line added in their machine
descriptor.

I just noticed that board-n8x0.c contains more than one machine descriptor,
which I've now fixed up.

> Then, looks like reordering of the patches now causes patch
> "ARM: initial LMB trial" to fail with:
> 
> arch/arm/mm/init.c:301: error: conflicting types for 'bootmem_init'
> arch/arm/mm/mm.h:32: error: previous declaration of 'bootmem_init' was here
> arch/arm/mm/init.c: In function 'bootmem_init':
> arch/arm/mm/init.c:312: error: 'mdesc' undeclared (first use in this function)
> arch/arm/mm/init.c:312: error: (Each undeclared identifier is reported only once
> arch/arm/mm/init.c:312: error: for each function it appears in.)
> make[1]: *** [arch/arm/mm/init.o] Error 1

Now fixed, thanks.

> Also, the last patch in lmb branch "ARM: use LMB to allocate system
> memory MMIO resource structures" causes both osk5912 and n900
> to hang very early. Maybe I'm missing some patch again..

Hmm, I'll take a look later today.

> Anyways, I've picked the patches from lmb branch up to the one below
> into omap-testing. Will add more of them once we get them working.

You should now be able to pick all but the last patch.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-26  7:50       ` Russell King - ARM Linux
@ 2010-05-26 13:51         ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-26 13:51 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100526 00:45]:
> On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> 
> > After applying the next patch in your lmb branch "ARM: OMAP: Convert
> > to use ->reserve method to reserve boot time memory" tux still works
> > on 5912osk, but not on n900. The difference is that osk5912 uses
> > the old omapfb code.
> 
> I guess this is because I don't have board-n900.c in my tree.  All OMAP
> boards need a ".reserve = omap_reserve," line added in their machine
> descriptor.

It's there but well hidden, board-rx51.c is the one for n900.
 
> I just noticed that board-n8x0.c contains more than one machine descriptor,
> which I've now fixed up.

OK good catch.

> > Anyways, I've picked the patches from lmb branch up to the one below
> > into omap-testing. Will add more of them once we get them working.
> 
> You should now be able to pick all but the last patch.

Yeah I'll do that once the dss2 code has been verified to work.

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-26 13:51         ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-26 13:51 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100526 00:45]:
> On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> 
> > After applying the next patch in your lmb branch "ARM: OMAP: Convert
> > to use ->reserve method to reserve boot time memory" tux still works
> > on 5912osk, but not on n900. The difference is that osk5912 uses
> > the old omapfb code.
> 
> I guess this is because I don't have board-n900.c in my tree.  All OMAP
> boards need a ".reserve = omap_reserve," line added in their machine
> descriptor.

It's there but well hidden, board-rx51.c is the one for n900.
 
> I just noticed that board-n8x0.c contains more than one machine descriptor,
> which I've now fixed up.

OK good catch.

> > Anyways, I've picked the patches from lmb branch up to the one below
> > into omap-testing. Will add more of them once we get them working.
> 
> You should now be able to pick all but the last patch.

Yeah I'll do that once the dss2 code has been verified to work.

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-26 13:51         ` Tony Lindgren
@ 2010-05-26 21:40           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-26 21:40 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

On Wed, May 26, 2010 at 06:51:29AM -0700, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100526 00:45]:
> > On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> > 
> > > After applying the next patch in your lmb branch "ARM: OMAP: Convert
> > > to use ->reserve method to reserve boot time memory" tux still works
> > > on 5912osk, but not on n900. The difference is that osk5912 uses
> > > the old omapfb code.
> > 
> > I guess this is because I don't have board-n900.c in my tree.  All OMAP
> > boards need a ".reserve = omap_reserve," line added in their machine
> > descriptor.
> 
> It's there but well hidden, board-rx51.c is the one for n900.
>  
> > I just noticed that board-n8x0.c contains more than one machine descriptor,
> > which I've now fixed up.
> 
> OK good catch.
> 
> > > Anyways, I've picked the patches from lmb branch up to the one below
> > > into omap-testing. Will add more of them once we get them working.
> > 
> > You should now be able to pick all but the last patch.
> 
> Yeah I'll do that once the dss2 code has been verified to work.

It'd help with this patch - it seems rx51 needs some additional stuff.
Any other OMAP platforms with this kind of thing?

diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 3bd956f..e3a42d1 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -144,17 +144,22 @@ static void __init rx51_init(void)
 static void __init rx51_map_io(void)
 {
 	omap2_set_globals_343x();
-	rx51_video_mem_init();
 	omap34xx_map_common_io();
 }
 
+static void __init rx51_reserve(void)
+{
+	rx51_video_mem_init();
+	omap_reserve();
+}
+
 MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
 	/* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
 	.phys_io	= 0x48000000,
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= rx51_map_io,
-	.reserve	= omap_reserve,
+	.reserve	= rx51_reserve,
 	.init_irq	= rx51_init_irq,
 	.init_machine	= rx51_init,
 	.timer		= &omap_timer,


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-26 21:40           ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-26 21:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 26, 2010 at 06:51:29AM -0700, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100526 00:45]:
> > On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> > 
> > > After applying the next patch in your lmb branch "ARM: OMAP: Convert
> > > to use ->reserve method to reserve boot time memory" tux still works
> > > on 5912osk, but not on n900. The difference is that osk5912 uses
> > > the old omapfb code.
> > 
> > I guess this is because I don't have board-n900.c in my tree.  All OMAP
> > boards need a ".reserve = omap_reserve," line added in their machine
> > descriptor.
> 
> It's there but well hidden, board-rx51.c is the one for n900.
>  
> > I just noticed that board-n8x0.c contains more than one machine descriptor,
> > which I've now fixed up.
> 
> OK good catch.
> 
> > > Anyways, I've picked the patches from lmb branch up to the one below
> > > into omap-testing. Will add more of them once we get them working.
> > 
> > You should now be able to pick all but the last patch.
> 
> Yeah I'll do that once the dss2 code has been verified to work.

It'd help with this patch - it seems rx51 needs some additional stuff.
Any other OMAP platforms with this kind of thing?

diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 3bd956f..e3a42d1 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -144,17 +144,22 @@ static void __init rx51_init(void)
 static void __init rx51_map_io(void)
 {
 	omap2_set_globals_343x();
-	rx51_video_mem_init();
 	omap34xx_map_common_io();
 }
 
+static void __init rx51_reserve(void)
+{
+	rx51_video_mem_init();
+	omap_reserve();
+}
+
 MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
 	/* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
 	.phys_io	= 0x48000000,
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= rx51_map_io,
-	.reserve	= omap_reserve,
+	.reserve	= rx51_reserve,
 	.init_irq	= rx51_init_irq,
 	.init_machine	= rx51_init,
 	.timer		= &omap_timer,

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-26 21:40           ` Russell King - ARM Linux
@ 2010-05-27  8:52             ` Tomi Valkeinen
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-27  8:52 UTC (permalink / raw)
  To: ext Russell King - ARM Linux; +Cc: Tony Lindgren, linux-arm-kernel, linux-omap

On Wed, 2010-05-26 at 23:40 +0200, ext Russell King - ARM Linux wrote:
> On Wed, May 26, 2010 at 06:51:29AM -0700, Tony Lindgren wrote:

> > Yeah I'll do that once the dss2 code has been verified to work.
> 
> It'd help with this patch - it seems rx51 needs some additional stuff.
> Any other OMAP platforms with this kind of thing?

I think rx51 is currently the only board that configures the VRAM size
dynamically at boot time.

I tested your lmb branch on OMAP 3430SDP board, and after removing the
topmost patch (ARM: use LMB to allocate system memory MMIO resource
structures) everything related to DSS2 (drivers/video/omap2/) seemed to
work ok.

I tested the DSS2 both as built-in and as modules, and I also tested
VRFB rotation. All seemed to be fine.

 Tomi



^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-27  8:52             ` Tomi Valkeinen
  0 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-27  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2010-05-26 at 23:40 +0200, ext Russell King - ARM Linux wrote:
> On Wed, May 26, 2010 at 06:51:29AM -0700, Tony Lindgren wrote:

> > Yeah I'll do that once the dss2 code has been verified to work.
> 
> It'd help with this patch - it seems rx51 needs some additional stuff.
> Any other OMAP platforms with this kind of thing?

I think rx51 is currently the only board that configures the VRAM size
dynamically at boot time.

I tested your lmb branch on OMAP 3430SDP board, and after removing the
topmost patch (ARM: use LMB to allocate system memory MMIO resource
structures) everything related to DSS2 (drivers/video/omap2/) seemed to
work ok.

I tested the DSS2 both as built-in and as modules, and I also tested
VRFB rotation. All seemed to be fine.

 Tomi

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-27  8:52             ` Tomi Valkeinen
@ 2010-05-27  9:25               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-27  9:25 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Tony Lindgren, linux-arm-kernel, linux-omap

On Thu, May 27, 2010 at 11:52:18AM +0300, Tomi Valkeinen wrote:
> On Wed, 2010-05-26 at 23:40 +0200, ext Russell King - ARM Linux wrote:
> > On Wed, May 26, 2010 at 06:51:29AM -0700, Tony Lindgren wrote:
> 
> > > Yeah I'll do that once the dss2 code has been verified to work.
> > 
> > It'd help with this patch - it seems rx51 needs some additional stuff.
> > Any other OMAP platforms with this kind of thing?
> 
> I think rx51 is currently the only board that configures the VRAM size
> dynamically at boot time.
> 
> I tested your lmb branch on OMAP 3430SDP board, and after removing the
> topmost patch (ARM: use LMB to allocate system memory MMIO resource
> structures) everything related to DSS2 (drivers/video/omap2/) seemed to
> work ok.

Great, can I add your tested-by for the OMAP and LMB stuff up to but not
including the last commit?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-27  9:25               ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-27  9:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 27, 2010 at 11:52:18AM +0300, Tomi Valkeinen wrote:
> On Wed, 2010-05-26 at 23:40 +0200, ext Russell King - ARM Linux wrote:
> > On Wed, May 26, 2010 at 06:51:29AM -0700, Tony Lindgren wrote:
> 
> > > Yeah I'll do that once the dss2 code has been verified to work.
> > 
> > It'd help with this patch - it seems rx51 needs some additional stuff.
> > Any other OMAP platforms with this kind of thing?
> 
> I think rx51 is currently the only board that configures the VRAM size
> dynamically at boot time.
> 
> I tested your lmb branch on OMAP 3430SDP board, and after removing the
> topmost patch (ARM: use LMB to allocate system memory MMIO resource
> structures) everything related to DSS2 (drivers/video/omap2/) seemed to
> work ok.

Great, can I add your tested-by for the OMAP and LMB stuff up to but not
including the last commit?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-27  9:25               ` Russell King - ARM Linux
@ 2010-05-27  9:47                 ` Tomi Valkeinen
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-27  9:47 UTC (permalink / raw)
  To: ext Russell King - ARM Linux; +Cc: Tony Lindgren, linux-arm-kernel, linux-omap

On Thu, 2010-05-27 at 11:25 +0200, ext Russell King - ARM Linux wrote:
> On Thu, May 27, 2010 at 11:52:18AM +0300, Tomi Valkeinen wrote:

> > I tested your lmb branch on OMAP 3430SDP board, and after removing the
> > topmost patch (ARM: use LMB to allocate system memory MMIO resource
> > structures) everything related to DSS2 (drivers/video/omap2/) seemed to
> > work ok.
> 
> Great, can I add your tested-by for the OMAP and LMB stuff up to but not
> including the last commit?

Sure.

I'll also try to find time to review the DSS side changes properly.

 Tomi



^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-27  9:47                 ` Tomi Valkeinen
  0 siblings, 0 replies; 80+ messages in thread
From: Tomi Valkeinen @ 2010-05-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2010-05-27 at 11:25 +0200, ext Russell King - ARM Linux wrote:
> On Thu, May 27, 2010 at 11:52:18AM +0300, Tomi Valkeinen wrote:

> > I tested your lmb branch on OMAP 3430SDP board, and after removing the
> > topmost patch (ARM: use LMB to allocate system memory MMIO resource
> > structures) everything related to DSS2 (drivers/video/omap2/) seemed to
> > work ok.
> 
> Great, can I add your tested-by for the OMAP and LMB stuff up to but not
> including the last commit?

Sure.

I'll also try to find time to review the DSS side changes properly.

 Tomi

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-26  0:44     ` Tony Lindgren
@ 2010-05-28 14:32       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-28 14:32 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> Also, the last patch in lmb branch "ARM: use LMB to allocate system
> memory MMIO resource structures" causes both osk5912 and n900
> to hang very early. Maybe I'm missing some patch again..

I'll drop this patch for the time being - we don't have stuff in the
right order yet for lmb_alloc() to work immediately after arm_lmb_init()
with highmem present - lmb_alloc tries to allocate from unmapped or high
memory, which we then use __va() on and referencing the resulting pointer
causes an abort.

However, using lmb_alloc() for the OMAP framebuffers shouldn't be an
issue because the problem only happens if you want to immediately
dereference the memory.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-28 14:32       ` Russell King - ARM Linux
  0 siblings, 0 replies; 80+ messages in thread
From: Russell King - ARM Linux @ 2010-05-28 14:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> Also, the last patch in lmb branch "ARM: use LMB to allocate system
> memory MMIO resource structures" causes both osk5912 and n900
> to hang very early. Maybe I'm missing some patch again..

I'll drop this patch for the time being - we don't have stuff in the
right order yet for lmb_alloc() to work immediately after arm_lmb_init()
with highmem present - lmb_alloc tries to allocate from unmapped or high
memory, which we then use __va() on and referencing the resulting pointer
causes an abort.

However, using lmb_alloc() for the OMAP framebuffers shouldn't be an
issue because the problem only happens if you want to immediately
dereference the memory.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [RFC] Initial attempt to make ARM use LMB
  2010-05-28 14:32       ` Russell King - ARM Linux
@ 2010-05-31  8:04         ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-31  8:04 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap, Tomi Valkeinen

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100528 17:26]:
> On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> > Also, the last patch in lmb branch "ARM: use LMB to allocate system
> > memory MMIO resource structures" causes both osk5912 and n900
> > to hang very early. Maybe I'm missing some patch again..
> 
> I'll drop this patch for the time being - we don't have stuff in the
> right order yet for lmb_alloc() to work immediately after arm_lmb_init()
> with highmem present - lmb_alloc tries to allocate from unmapped or high
> memory, which we then use __va() on and referencing the resulting pointer
> causes an abort.
> 
> However, using lmb_alloc() for the OMAP framebuffers shouldn't be an
> issue because the problem only happens if you want to immediately
> dereference the memory.

OK. Looks like your lmb branch still has it and is from the 23rd,
maybe you forgot to push out the update lmb branch?

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [RFC] Initial attempt to make ARM use LMB
@ 2010-05-31  8:04         ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2010-05-31  8:04 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100528 17:26]:
> On Tue, May 25, 2010 at 05:44:18PM -0700, Tony Lindgren wrote:
> > Also, the last patch in lmb branch "ARM: use LMB to allocate system
> > memory MMIO resource structures" causes both osk5912 and n900
> > to hang very early. Maybe I'm missing some patch again..
> 
> I'll drop this patch for the time being - we don't have stuff in the
> right order yet for lmb_alloc() to work immediately after arm_lmb_init()
> with highmem present - lmb_alloc tries to allocate from unmapped or high
> memory, which we then use __va() on and referencing the resulting pointer
> causes an abort.
> 
> However, using lmb_alloc() for the OMAP framebuffers shouldn't be an
> issue because the problem only happens if you want to immediately
> dereference the memory.

OK. Looks like your lmb branch still has it and is from the 23rd,
maybe you forgot to push out the update lmb branch?

Regards,

Tony

^ permalink raw reply	[flat|nested] 80+ messages in thread

end of thread, other threads:[~2010-05-31  8:04 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-25 23:32 [RFC] Initial attempt to make ARM use LMB Russell King - ARM Linux
2010-03-25 23:32 ` Russell King - ARM Linux
2010-03-31  6:43 ` Jeremy Kerr
2010-03-31  6:43   ` Jeremy Kerr
2010-04-01  9:47   ` Tony Lindgren
2010-04-01  9:47     ` Tony Lindgren
2010-04-09 11:13   ` Russell King - ARM Linux
2010-04-09 11:13     ` Russell King - ARM Linux
2010-04-08 15:32 ` Rabin Vincent
2010-04-08 15:32   ` Rabin Vincent
2010-04-08 18:27   ` Russell King - ARM Linux
2010-04-08 18:27     ` Russell King - ARM Linux
2010-04-09 11:11     ` Russell King - ARM Linux
2010-04-09 11:11       ` Russell King - ARM Linux
2010-04-10  3:42       ` Rabin Vincent
2010-04-10  3:42         ` Rabin Vincent
2010-04-10  7:03         ` Russell King - ARM Linux
2010-04-10  7:03           ` Russell King - ARM Linux
2010-04-10 11:56           ` Rabin Vincent
2010-04-10 11:56             ` Rabin Vincent
2010-04-14  7:34       ` Benjamin Herrenschmidt
2010-04-14  7:34         ` Benjamin Herrenschmidt
2010-05-05 15:02 ` Russell King - ARM Linux
2010-05-05 15:02   ` Russell King - ARM Linux
2010-05-13 17:40   ` Russell King - ARM Linux
2010-05-13 17:40     ` Russell King - ARM Linux
2010-05-13 21:19     ` Tony Lindgren
2010-05-13 21:19       ` Tony Lindgren
2010-05-13 21:58       ` Russell King - ARM Linux
2010-05-13 21:58         ` Russell King - ARM Linux
2010-05-13 22:01         ` Tony Lindgren
2010-05-13 22:01           ` Tony Lindgren
2010-05-13 22:12           ` Russell King - ARM Linux
2010-05-13 22:12             ` Russell King - ARM Linux
2010-05-14  7:24             ` Shilimkar, Santosh
2010-05-14  7:24               ` Shilimkar, Santosh
2010-05-14 10:11               ` Grazvydas Ignotas
2010-05-14 10:11                 ` Grazvydas Ignotas
2010-05-14 10:16                 ` Russell King - ARM Linux
2010-05-14 10:16                   ` Russell King - ARM Linux
2010-05-17  9:38                   ` Grazvydas Ignotas
2010-05-17  9:38                     ` Grazvydas Ignotas
2010-05-17  9:44                     ` Russell King - ARM Linux
2010-05-17  9:44                       ` Russell King - ARM Linux
2010-05-17 10:26                       ` Tomi Valkeinen
2010-05-17 10:26                         ` Tomi Valkeinen
2010-05-17 17:37                         ` Tony Lindgren
2010-05-17 17:37                           ` Tony Lindgren
2010-05-18  7:47                           ` Tomi Valkeinen
2010-05-18  7:47                             ` Tomi Valkeinen
2010-05-18  8:40                             ` Russell King - ARM Linux
2010-05-18  8:40                               ` Russell King - ARM Linux
2010-05-18  8:58                               ` Tomi Valkeinen
2010-05-18  8:58                                 ` Tomi Valkeinen
2010-05-14 15:22             ` Tony Lindgren
2010-05-14 15:22               ` Tony Lindgren
2010-05-14 15:32               ` Shilimkar, Santosh
2010-05-14 15:32                 ` Shilimkar, Santosh
2010-05-14 15:43                 ` Tony Lindgren
2010-05-14 15:43                   ` Tony Lindgren
2010-05-22 21:58 ` Russell King - ARM Linux
2010-05-22 21:58   ` Russell King - ARM Linux
2010-05-26  0:44   ` Tony Lindgren
2010-05-26  0:44     ` Tony Lindgren
2010-05-26  7:50     ` Russell King - ARM Linux
2010-05-26  7:50       ` Russell King - ARM Linux
2010-05-26 13:51       ` Tony Lindgren
2010-05-26 13:51         ` Tony Lindgren
2010-05-26 21:40         ` Russell King - ARM Linux
2010-05-26 21:40           ` Russell King - ARM Linux
2010-05-27  8:52           ` Tomi Valkeinen
2010-05-27  8:52             ` Tomi Valkeinen
2010-05-27  9:25             ` Russell King - ARM Linux
2010-05-27  9:25               ` Russell King - ARM Linux
2010-05-27  9:47               ` Tomi Valkeinen
2010-05-27  9:47                 ` Tomi Valkeinen
2010-05-28 14:32     ` Russell King - ARM Linux
2010-05-28 14:32       ` Russell King - ARM Linux
2010-05-31  8:04       ` Tony Lindgren
2010-05-31  8:04         ` Tony Lindgren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.