From 0371d3f7e8f1cddaee1f215e42c09a40e235d810 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 5 Jul 2011 19:58:29 +0100 Subject: ARM: move memory layout sanity checking before meminfo initialization Ensure that the meminfo array is sanity checked before we pass the memory to memblock. This helps to ensure that memblock and meminfo agree on the dimensions of memory, especially when more memory is passed than the kernel can deal with. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 5 +++-- arch/arm/mm/nommu.c | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9d9e736..594d677 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -759,7 +759,7 @@ early_param("vmalloc", early_vmalloc); static phys_addr_t lowmem_limit __initdata = 0; -static void __init sanity_check_meminfo(void) +void __init sanity_check_meminfo(void) { int i, j, highmem = 0; @@ -1032,8 +1032,9 @@ void __init paging_init(struct machine_desc *mdesc) { void *zero_page; + memblock_set_current_limit(lowmem_limit); + build_mem_type_table(); - sanity_check_meminfo(); prepare_page_table(); map_lowmem(); devicemaps_init(mdesc); diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 687d023..941a98c 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -27,6 +27,10 @@ void __init arm_mm_memblock_reserve(void) memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); } +void __init sanity_check_meminfo(void) +{ +} + /* * paging_init() sets up the page tables, initialises the zone memory * maps, and sets up the zero page, bad page and bad page tables. -- cgit v1.1 From 38a8914f9ac2379293944f613e6ca24b61373de8 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 1 Jul 2011 14:36:19 +0100 Subject: ARM: 6987/1: l2x0: fix disabling function to avoid deadlock The l2x0_disable function attempts to writel with the l2x0_lock held. This results in deadlock when the writel contains an outer_sync call for the platform since the l2x0_lock is already held by the disable function. A further problem is that disabling the L2 without flushing it first can lead to the spin_lock operation becoming visible after the spin_unlock, causing any subsequent L2 maintenance to deadlock. This patch replaces the writel with a call to writel_relaxed in the disabling code and adds a flush before disabling in the control register, preventing livelock from occurring. Acked-by: Catalin Marinas Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mm/cache-l2x0.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index ef59099..44c0867 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -120,17 +120,22 @@ static void l2x0_cache_sync(void) spin_unlock_irqrestore(&l2x0_lock, flags); } -static void l2x0_flush_all(void) +static void __l2x0_flush_all(void) { - unsigned long flags; - - /* clean all ways */ - spin_lock_irqsave(&l2x0_lock, flags); debug_writel(0x03); writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); cache_sync(); debug_writel(0x00); +} + +static void l2x0_flush_all(void) +{ + unsigned long flags; + + /* clean all ways */ + spin_lock_irqsave(&l2x0_lock, flags); + __l2x0_flush_all(); spin_unlock_irqrestore(&l2x0_lock, flags); } @@ -266,7 +271,9 @@ static void l2x0_disable(void) unsigned long flags; spin_lock_irqsave(&l2x0_lock, flags); - writel(0, l2x0_base + L2X0_CTRL); + __l2x0_flush_all(); + writel_relaxed(0, l2x0_base + L2X0_CTRL); + dsb(); spin_unlock_irqrestore(&l2x0_lock, flags); } -- cgit v1.1