X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=arch%2Fmips%2Fmm%2Fc-sb1.c;h=d0ddb4a768a50e6d13e30fea902f1b0d36358040;hb=ddc081a19585c8ba5aad437779950c2ef215360a;hp=5537558f19f795d467e327a5225e662ff03dd7b6;hpb=c59a0f15be6e586aa0fe1fb5c7f740005c36ec56;p=pandora-kernel.git diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 5537558f19f7..85ce2842d0da 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include @@ -49,6 +50,15 @@ static unsigned short dcache_sets; static unsigned int icache_range_cutoff; static unsigned int dcache_range_cutoff; +static inline void sb1_on_each_cpu(void (*func) (void *info), void *info, + int retry, int wait) +{ + preempt_disable(); + smp_call_function(func, info, retry, wait); + func(info); + preempt_enable(); +} + /* * The dcache is fully coherent to the system, with one * big caveat: the instruction stream. In other words, @@ -226,18 +236,43 @@ static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, args.vma = vma; args.addr = addr; args.pfn = pfn; - on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); + sb1_on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); } #else void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) __attribute__((alias("local_sb1_flush_cache_page"))); #endif +#ifdef CONFIG_SMP +static void sb1_flush_cache_data_page_ipi(void *info) +{ + unsigned long start = (unsigned long)info; + + __sb1_writeback_inv_dcache_range(start, start + PAGE_SIZE); +} + +static void sb1_flush_cache_data_page(unsigned long addr) +{ + if (in_atomic()) + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); + else + on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1); +} +#else + +static void local_sb1_flush_cache_data_page(unsigned long addr) +{ + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); +} + +void sb1_flush_cache_data_page(unsigned long) + __attribute__((alias("local_sb1_flush_cache_data_page"))); +#endif /* * Invalidate all caches on this CPU */ -static void __attribute_used__ local_sb1___flush_cache_all(void) +static void __used local_sb1___flush_cache_all(void) { __sb1_writeback_inv_dcache_all(); __sb1_flush_icache_all(); @@ -249,7 +284,7 @@ void sb1___flush_cache_all_ipi(void *ignored) static void sb1___flush_cache_all(void) { - on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); + sb1_on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); } #else void sb1___flush_cache_all(void) @@ -299,7 +334,7 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end) args.start = start; args.end = end; - on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); + sb1_on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); } #else void sb1_flush_icache_range(unsigned long start, unsigned long end) @@ -326,7 +361,7 @@ static void sb1_flush_cache_sigtramp_ipi(void *info) static void sb1_flush_cache_sigtramp(unsigned long addr) { - on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); + sb1_on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); } #else void sb1_flush_cache_sigtramp(unsigned long addr) @@ -441,10 +476,9 @@ static __init void probe_cache_sizes(void) * memory management function pointers, as well as initialize * the caches and tlbs */ -void sb1_cache_init(void) +void __init sb1_cache_init(void) { extern char except_vec2_sb1; - extern char handle_vec2_sb1; /* Special cache error handler for SB1 */ set_uncached_handler (0x100, &except_vec2_sb1, 0x80); @@ -473,7 +507,7 @@ void sb1_cache_init(void) flush_cache_sigtramp = sb1_flush_cache_sigtramp; local_flush_data_cache_page = (void *) sb1_nop; - flush_data_cache_page = (void *) sb1_nop; + flush_data_cache_page = sb1_flush_cache_data_page; /* Full flush */ __flush_cache_all = sb1___flush_cache_all; @@ -497,5 +531,5 @@ void sb1_cache_init(void) : : "memory"); - flush_cache_all(); + local_sb1___flush_cache_all(); }