Merge branch 'devel-stable' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git...
[pandora-kernel.git] / arch / arm / kernel / setup.c
index 6136144..bda0a21 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/memblock.h>
+#include <linux/bug.h>
+#include <linux/compiler.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -42,6 +44,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
 #include <asm/tlbflush.h>
+#include <asm/system.h>
 
 #include <asm/prom.h>
 #include <asm/mach/arch.h>
@@ -115,6 +118,13 @@ struct outer_cache_fns outer_cache __read_mostly;
 EXPORT_SYMBOL(outer_cache);
 #endif
 
+/*
+ * Cached cpu_architecture() result for use by assembler code.
+ * C code should use the cpu_architecture() function instead of accessing this
+ * variable directly.
+ */
+int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
+
 struct stack {
        u32 irq[3];
        u32 abt[3];
@@ -210,7 +220,7 @@ static const char *proc_arch[] = {
        "?(17)",
 };
 
-int cpu_architecture(void)
+static int __get_cpu_architecture(void)
 {
        int cpu_arch;
 
@@ -243,11 +253,22 @@ int cpu_architecture(void)
        return cpu_arch;
 }
 
+int __pure cpu_architecture(void)
+{
+       BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);
+
+       return __cpu_architecture;
+}
+
 static int cpu_has_aliasing_icache(unsigned int arch)
 {
        int aliasing_icache;
        unsigned int id_reg, num_sets, line_size;
 
+       /* PIPT caches never alias. */
+       if (icache_is_pipt())
+               return 0;
+
        /* arch specifies the register format */
        switch (arch) {
        case CPU_ARCH_ARMv7:
@@ -282,8 +303,14 @@ static void __init cacheid_init(void)
                        /* ARMv7 register format */
                        arch = CPU_ARCH_ARMv7;
                        cacheid = CACHEID_VIPT_NONALIASING;
-                       if ((cachetype & (3 << 14)) == 1 << 14)
+                       switch (cachetype & (3 << 14)) {
+                       case (1 << 14):
                                cacheid |= CACHEID_ASID_TAGGED;
+                               break;
+                       case (3 << 14):
+                               cacheid |= CACHEID_PIPT;
+                               break;
+                       }
                } else {
                        arch = CPU_ARCH_ARMv6;
                        if (cachetype & (1 << 23))
@@ -300,10 +327,11 @@ static void __init cacheid_init(void)
        printk("CPU: %s data cache, %s instruction cache\n",
                cache_is_vivt() ? "VIVT" :
                cache_is_vipt_aliasing() ? "VIPT aliasing" :
-               cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
+               cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown",
                cache_is_vivt() ? "VIVT" :
                icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
                icache_is_vipt_aliasing() ? "VIPT aliasing" :
+               icache_is_pipt() ? "PIPT" :
                cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
 }
 
@@ -414,6 +442,7 @@ static void __init setup_processor(void)
        }
 
        cpu_name = list->cpu_name;
+       __cpu_architecture = __get_cpu_architecture();
 
 #ifdef MULTI_CPU
        processor = *list->proc;
@@ -844,7 +873,7 @@ static struct machine_desc * __init setup_machine_tags(unsigned int nr)
        }
 
        if (mdesc->fixup)
-               mdesc->fixup(mdesc, tags, &from, &meminfo);
+               mdesc->fixup(tags, &from, &meminfo);
 
        if (tags->hdr.tag == ATAG_CORE) {
                if (meminfo.nr_banks != 0)