Merge branches 'misc' and 'sa1111-base' into for-linus
[cascardo/linux.git] / arch / arm / kernel / setup.c
index 85a0bcb..34e3f3c 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/screen_info.h>
-#include <linux/of_iommu.h>
 #include <linux/of_platform.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
@@ -115,19 +114,19 @@ EXPORT_SYMBOL(elf_hwcap2);
 
 
 #ifdef MULTI_CPU
-struct processor processor __read_mostly;
+struct processor processor __ro_after_init;
 #endif
 #ifdef MULTI_TLB
-struct cpu_tlb_fns cpu_tlb __read_mostly;
+struct cpu_tlb_fns cpu_tlb __ro_after_init;
 #endif
 #ifdef MULTI_USER
-struct cpu_user_fns cpu_user __read_mostly;
+struct cpu_user_fns cpu_user __ro_after_init;
 #endif
 #ifdef MULTI_CACHE
-struct cpu_cache_fns cpu_cache __read_mostly;
+struct cpu_cache_fns cpu_cache __ro_after_init;
 #endif
 #ifdef CONFIG_OUTER_CACHE
-struct outer_cache_fns outer_cache __read_mostly;
+struct outer_cache_fns outer_cache __ro_after_init;
 EXPORT_SYMBOL(outer_cache);
 #endif
 
@@ -291,12 +290,9 @@ static int cpu_has_aliasing_icache(unsigned int arch)
        /* arch specifies the register format */
        switch (arch) {
        case CPU_ARCH_ARMv7:
-               asm("mcr        p15, 2, %0, c0, c0, 0 @ set CSSELR"
-                   : /* No output operands */
-                   : "r" (1));
+               set_csselr(CSSELR_ICACHE | CSSELR_L1);
                isb();
-               asm("mrc        p15, 1, %0, c0, c0, 0 @ read CCSIDR"
-                   : "=r" (id_reg));
+               id_reg = read_ccsidr();
                line_size = 4 << ((id_reg & 0x7) + 2);
                num_sets = ((id_reg >> 13) & 0x7fff) + 1;
                aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
@@ -316,11 +312,12 @@ static void __init cacheid_init(void)
 {
        unsigned int arch = cpu_architecture();
 
-       if (arch == CPU_ARCH_ARMv7M) {
-               cacheid = 0;
-       } else if (arch >= CPU_ARCH_ARMv6) {
+       if (arch >= CPU_ARCH_ARMv6) {
                unsigned int cachetype = read_cpuid_cachetype();
-               if ((cachetype & (7 << 29)) == 4 << 29) {
+
+               if ((arch == CPU_ARCH_ARMv7M) && !cachetype) {
+                       cacheid = 0;
+               } else if ((cachetype & (7 << 29)) == 4 << 29) {
                        /* ARMv7 register format */
                        arch = CPU_ARCH_ARMv7;
                        cacheid = CACHEID_VIPT_NONALIASING;
@@ -849,10 +846,29 @@ static void __init request_standard_resources(const struct machine_desc *mdesc)
        kernel_data.end     = virt_to_phys(_end - 1);
 
        for_each_memblock(memory, region) {
+               phys_addr_t start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
+               phys_addr_t end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
+               unsigned long boot_alias_start;
+
+               /*
+                * Some systems have a special memory alias which is only
+                * used for booting.  We need to advertise this region to
+                * kexec-tools so they know where bootable RAM is located.
+                */
+               boot_alias_start = phys_to_idmap(start);
+               if (arm_has_idmap_alias() && boot_alias_start != IDMAP_INVALID_ADDR) {
+                       res = memblock_virt_alloc(sizeof(*res), 0);
+                       res->name = "System RAM (boot alias)";
+                       res->start = boot_alias_start;
+                       res->end = phys_to_idmap(end);
+                       res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+                       request_resource(&iomem_resource, res);
+               }
+
                res = memblock_virt_alloc(sizeof(*res), 0);
                res->name  = "System RAM";
-               res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
-               res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
+               res->start = start;
+               res->end = end;
                res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
 
                request_resource(&iomem_resource, res);
@@ -903,14 +919,9 @@ static int __init customize_machine(void)
         * machine from the device tree, if no callback is provided,
         * otherwise we would always need an init_machine callback.
         */
-       of_iommu_init();
        if (machine_desc->init_machine)
                machine_desc->init_machine();
-#ifdef CONFIG_OF
-       else
-               of_platform_populate(NULL, of_default_bus_match_table,
-                                       NULL, NULL);
-#endif
+
        return 0;
 }
 arch_initcall(customize_machine);
@@ -1006,9 +1017,25 @@ static void __init reserve_crashkernel(void)
                (unsigned long)(crash_base >> 20),
                (unsigned long)(total_mem >> 20));
 
+       /* The crashk resource must always be located in normal mem */
        crashk_res.start = crash_base;
        crashk_res.end = crash_base + crash_size - 1;
        insert_resource(&iomem_resource, &crashk_res);
+
+       if (arm_has_idmap_alias()) {
+               /*
+                * If we have a special RAM alias for use at boot, we
+                * need to advertise to kexec tools where the alias is.
+                */
+               static struct resource crashk_boot_res = {
+                       .name = "Crash kernel (boot alias)",
+                       .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+               };
+
+               crashk_boot_res.start = phys_to_idmap(crash_base);
+               crashk_boot_res.end = crashk_boot_res.start + crash_size - 1;
+               insert_resource(&iomem_resource, &crashk_boot_res);
+       }
 }
 #else
 static inline void reserve_crashkernel(void) {}