From 63afd0d8de012fe33e9b9bfe9a7264d17a5abe23 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 16 Dec 2010 14:56:34 -0500 Subject: [PATCH] --- yaml --- r: 223743 b: refs/heads/master c: 6d3e6d3640052cac958d61c44597cc216f6ee09f h: refs/heads/master i: 223741: 78e79d62afa014268adbb1e4071ad8b9031ef80b 223739: 14d1317dd2e2cf322b449d07a8f41f4e1a212a92 223735: b9d2f648ddcfe9d100eb147726e346d7b7ae3d62 223727: e718fd69e601b381512c23307642b760f9a8ace2 223711: 36f86f2b57a9ada78c90d5bfae81a1b8e71ab37f 223679: 0f2052efeb2d56a46868cfb455a99b0ab6909806 223615: 9ad19a9daaafe95740817284479c083db44f7999 223487: d7ceef3e66ccc06001b99513a98ccaabe21862a0 223231: 3ba73eb2000ab1125a2db6928387f373e6c946b0 v: v3 --- [refs] | 2 +- trunk/arch/arm/mm/cache-feroceon-l2.c | 37 ++++++++++++++------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/[refs] b/[refs] index 9c23bcda0369..a1733aae7c87 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 25cbe45440ea89a3b0f6f7ed326d3d476d53068b +refs/heads/master: 6d3e6d3640052cac958d61c44597cc216f6ee09f diff --git a/trunk/arch/arm/mm/cache-feroceon-l2.c b/trunk/arch/arm/mm/cache-feroceon-l2.c index 6e77c042d8e9..e0b0e7a4ec68 100644 --- a/trunk/arch/arm/mm/cache-feroceon-l2.c +++ b/trunk/arch/arm/mm/cache-feroceon-l2.c @@ -13,13 +13,9 @@ */ #include +#include #include -#include -#include -#include -#include #include -#include "mm.h" /* * Low-level cache maintenance operations. @@ -39,27 +35,30 @@ * between which we don't want to be preempted. */ -static inline unsigned long l2_start_va(unsigned long paddr) +static inline unsigned long l2_get_va(unsigned long paddr) { #ifdef CONFIG_HIGHMEM /* - * Let's do our own fixmap stuff in a minimal way here. * Because range ops can't be done on physical addresses, * we simply install a virtual mapping for it only for the * TLB lookup to occur, hence no need to flush the untouched - * memory mapping. This is protected with the disabling of - * interrupts by the caller. + * memory mapping afterwards (note: a cache flush may happen + * in some circumstances depending on the path taken in kunmap_atomic). */ - unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id(); - unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0); - local_flush_tlb_kernel_page(vaddr); - return vaddr + (paddr & ~PAGE_MASK); + void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT); + return (unsigned long)vaddr + (paddr & ~PAGE_MASK); #else return __phys_to_virt(paddr); #endif } +static inline void l2_put_va(unsigned long vaddr) +{ +#ifdef CONFIG_HIGHMEM + kunmap_atomic((void *)vaddr); +#endif +} + static inline void l2_clean_pa(unsigned long addr) { __asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr)); @@ -76,13 +75,14 @@ static inline void l2_clean_pa_range(unsigned long start, unsigned long end) */ BUG_ON((start ^ end) >> PAGE_SHIFT); - raw_local_irq_save(flags); - va_start = l2_start_va(start); + va_start = l2_get_va(start); va_end = va_start + (end - start); + raw_local_irq_save(flags); __asm__("mcr p15, 1, %0, c15, c9, 4\n\t" "mcr p15, 1, %1, c15, c9, 5" : : "r" (va_start), "r" (va_end)); raw_local_irq_restore(flags); + l2_put_va(va_start); } static inline void l2_clean_inv_pa(unsigned long addr) @@ -106,13 +106,14 @@ static inline void l2_inv_pa_range(unsigned long start, unsigned long end) */ BUG_ON((start ^ end) >> PAGE_SHIFT); - raw_local_irq_save(flags); - va_start = l2_start_va(start); + va_start = l2_get_va(start); va_end = va_start + (end - start); + raw_local_irq_save(flags); __asm__("mcr p15, 1, %0, c15, c11, 4\n\t" "mcr p15, 1, %1, c15, c11, 5" : : "r" (va_start), "r" (va_end)); raw_local_irq_restore(flags); + l2_put_va(va_start); } static inline void l2_inv_all(void)