summaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/cache-feroceon-l2.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 14:03:14 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 14:03:14 -0700
commit0fe41b8982001cd14ee2c77cd776735a5024e98b (patch)
tree83e65d595c413d55259ea14fb97748ce5efe5707 /arch/arm/mm/cache-feroceon-l2.c
parenteedf2c5296a8dfaaf9aec1a938c1d3bd73159a30 (diff)
parent9759d22c8348343b0da4e25d6150c41712686c14 (diff)
downloadblackbird-op-linux-0fe41b8982001cd14ee2c77cd776735a5024e98b.tar.gz
blackbird-op-linux-0fe41b8982001cd14ee2c77cd776735a5024e98b.zip
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (422 commits) [ARM] 5435/1: fix compile warning in sanity_check_meminfo() [ARM] 5434/1: ARM: OMAP: Fix mailbox compile for 24xx [ARM] pxa: fix the bad assumption that PCMCIA sockets always start with 0 [ARM] pxa: fix Colibri PXA300 and PXA320 LCD backlight pins imxfb: Fix TFT mode i.MX21/27: remove ifdef CONFIG_FB_IMX imxfb: add clock support mxc: add arch_reset() function clkdev: add possibility to get a clock based on the device name i.MX1: remove fb support from mach-imx [ARM] pxa: build arch/arm/plat-pxa/mfp.c only when PXA3xx or ARCH_MMP defined Gemini: Add support for Teltonika RUT100 Gemini: gpiolib based GPIO support v2 MAINTAINERS: add myself as Gemini architecture maintainer ARM: Add Gemini architecture v3 [ARM] OMAP: Fix compile for omap2_init_common_hw() MAINTAINERS: Add myself as Faraday ARM core variant maintainer ARM: Add support for FA526 v2 [ARM] acorn,ebsa110,footbridge,integrator,sa1100: Convert asm/io.h to linux/io.h [ARM] collie: fix two minor formatting nits ...
Diffstat (limited to 'arch/arm/mm/cache-feroceon-l2.c')
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c54
1 files changed, 37 insertions, 17 deletions
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 80cd207cbaea..d6dd83826f8a 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -14,8 +14,12 @@
#include <linux/init.h>
#include <asm/cacheflush.h>
+#include <asm/kmap_types.h>
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
#include <plat/cache-feroceon-l2.h>
-
+#include "mm.h"
/*
* Low-level cache maintenance operations.
@@ -34,14 +38,36 @@
* The range operations require two successive cp15 writes, in
* between which we don't want to be preempted.
*/
+
+static inline unsigned long l2_start_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.
+ */
+ 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);
+#else
+ return __phys_to_virt(paddr);
+#endif
+}
+
static inline void l2_clean_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
}
-static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
+static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
{
- unsigned long flags;
+ unsigned long va_start, va_end, flags;
/*
* Make sure 'start' and 'end' reference the same page, as
@@ -51,17 +77,14 @@ static inline void l2_clean_mva_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_end = va_start + (end - start);
__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
"mcr p15, 1, %1, c15, c9, 5"
- : : "r" (start), "r" (end));
+ : : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
}
-static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
-{
- l2_clean_mva_range(__phys_to_virt(start), __phys_to_virt(end));
-}
-
static inline void l2_clean_inv_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c15, c10, 3" : : "r" (addr));
@@ -72,9 +95,9 @@ static inline void l2_inv_pa(unsigned long addr)
__asm__("mcr p15, 1, %0, c15, c11, 3" : : "r" (addr));
}
-static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
+static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
{
- unsigned long flags;
+ unsigned long va_start, va_end, flags;
/*
* Make sure 'start' and 'end' reference the same page, as
@@ -84,17 +107,14 @@ static inline void l2_inv_mva_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_end = va_start + (end - start);
__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
"mcr p15, 1, %1, c15, c11, 5"
- : : "r" (start), "r" (end));
+ : : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
}
-static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
-{
- l2_inv_mva_range(__phys_to_virt(start), __phys_to_virt(end));
-}
-
/*
* Linux primitives.
OpenPOWER on IntegriCloud