]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/arm/kernel/setup.c
Merge branches 'amba', 'devel-stable', 'kexec-for-next' and 'misc' into for-linus
[karo-tx-linux.git] / arch / arm / kernel / setup.c
index 139791ed473d5264682c004ea2ea7af8ddd28f5d..9cd27dff5d10ae22f862faa23e87aa6ea8b131bf 100644 (file)
@@ -430,11 +430,13 @@ static void __init patch_aeabi_idiv(void)
        pr_info("CPU: div instructions available: patching division code\n");
 
        fn_addr = ((uintptr_t)&__aeabi_uidiv) & ~1;
+       asm ("" : "+g" (fn_addr));
        ((u32 *)fn_addr)[0] = udiv_instruction();
        ((u32 *)fn_addr)[1] = bx_lr_instruction();
        flush_icache_range(fn_addr, fn_addr + 8);
 
        fn_addr = ((uintptr_t)&__aeabi_idiv) & ~1;
+       asm ("" : "+g" (fn_addr));
        ((u32 *)fn_addr)[0] = sdiv_instruction();
        ((u32 *)fn_addr)[1] = bx_lr_instruction();
        flush_icache_range(fn_addr, fn_addr + 8);
@@ -938,6 +940,12 @@ static int __init init_machine_late(void)
 late_initcall(init_machine_late);
 
 #ifdef CONFIG_KEXEC
+/*
+ * The crash region must be aligned to 128MB to avoid
+ * zImage relocating below the reserved region.
+ */
+#define CRASH_ALIGN    (128 << 20)
+
 static inline unsigned long long get_total_mem(void)
 {
        unsigned long total;
@@ -965,6 +973,26 @@ static void __init reserve_crashkernel(void)
        if (ret)
                return;
 
+       if (crash_base <= 0) {
+               unsigned long long crash_max = idmap_to_phys((u32)~0);
+               crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
+                                                   crash_size, CRASH_ALIGN);
+               if (!crash_base) {
+                       pr_err("crashkernel reservation failed - No suitable area found.\n");
+                       return;
+               }
+       } else {
+               unsigned long long start;
+
+               start = memblock_find_in_range(crash_base,
+                                              crash_base + crash_size,
+                                              crash_size, SECTION_SIZE);
+               if (start != crash_base) {
+                       pr_err("crashkernel reservation failed - memory is in use.\n");
+                       return;
+               }
+       }
+
        ret = memblock_reserve(crash_base, crash_size);
        if (ret < 0) {
                pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",