From 8be062892365b09f41d64cda7fa63d306e95e0c9 Mon Sep 17 00:00:00 2001 From: Akira Takeuchi Date: Wed, 27 Oct 2010 17:28:47 +0100 Subject: MN10300: Cache: Implement SMP global cache flushing Implement SMP global cache flushing for MN10300. This will be used by the AM34 which is SMP capable. Signed-off-by: Akira Takeuchi Signed-off-by: Kiyoshi Owada Signed-off-by: David Howells --- arch/mn10300/mm/cache-inv-icache.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'arch/mn10300/mm/cache-inv-icache.c') diff --git a/arch/mn10300/mm/cache-inv-icache.c b/arch/mn10300/mm/cache-inv-icache.c index 4a3f7afcfe53..a8933a60b2d4 100644 --- a/arch/mn10300/mm/cache-inv-icache.c +++ b/arch/mn10300/mm/cache-inv-icache.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include "cache-smp.h" /** * flush_icache_page_range - Flush dcache and invalidate icache for part of a @@ -66,7 +68,8 @@ static void flush_icache_page_range(unsigned long start, unsigned long end) addr = page_to_phys(page); /* invalidate the icache coverage on that region */ - mn10300_icache_inv_range2(addr + off, size); + mn10300_local_icache_inv_range2(addr + off, size); + smp_cache_call(SMP_ICACHE_INV_FLUSH_RANGE, start, end); } /** @@ -81,28 +84,31 @@ static void flush_icache_page_range(unsigned long start, unsigned long end) void flush_icache_range(unsigned long start, unsigned long end) { unsigned long start_page, end_page; + unsigned long flags; + + flags = smp_lock_cache(); if (end > 0x80000000UL) { /* addresses above 0xa0000000 do not go through the cache */ if (end > 0xa0000000UL) { end = 0xa0000000UL; if (start >= end) - return; + goto done; } /* kernel addresses between 0x80000000 and 0x9fffffff do not * require page tables, so we just map such addresses * directly */ start_page = (start >= 0x80000000UL) ? start : 0x80000000UL; - mn10300_dcache_flush_range(start_page, end); mn10300_icache_inv_range(start_page, end); + smp_cache_call(SMP_ICACHE_INV_FLUSH_RANGE, start, end); if (start_page == start) - return; + goto done; end = start_page; } start_page = start & PAGE_MASK; - end_page = end & PAGE_MASK; + end_page = (end - 1) & PAGE_MASK; if (start_page == end_page) { /* the first and last bytes are on the same page */ @@ -113,7 +119,11 @@ void flush_icache_range(unsigned long start, unsigned long end) flush_icache_page_range(end_page, end); } else { /* more than 2 pages; just flush the entire cache */ - mn10300_icache_inv(); + mn10300_local_icache_inv(); + smp_cache_call(SMP_ICACHE_INV, 0, 0); } + +done: + smp_unlock_cache(flags); } EXPORT_SYMBOL(flush_icache_range); -- cgit