diff options
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r-- | arch/arm/kernel/setup.c | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 122d999bdc7c..776ea1aa974b 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -19,12 +19,15 @@ | |||
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/screen_info.h> | 20 | #include <linux/screen_info.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/kexec.h> | ||
23 | #include <linux/crash_dump.h> | ||
22 | #include <linux/root_dev.h> | 24 | #include <linux/root_dev.h> |
23 | #include <linux/cpu.h> | 25 | #include <linux/cpu.h> |
24 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
25 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
26 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
27 | #include <linux/proc_fs.h> | 29 | #include <linux/proc_fs.h> |
30 | #include <linux/memblock.h> | ||
28 | 31 | ||
29 | #include <asm/unified.h> | 32 | #include <asm/unified.h> |
30 | #include <asm/cpu.h> | 33 | #include <asm/cpu.h> |
@@ -269,6 +272,21 @@ static void __init cacheid_init(void) | |||
269 | extern struct proc_info_list *lookup_processor_type(unsigned int); | 272 | extern struct proc_info_list *lookup_processor_type(unsigned int); |
270 | extern struct machine_desc *lookup_machine_type(unsigned int); | 273 | extern struct machine_desc *lookup_machine_type(unsigned int); |
271 | 274 | ||
275 | static void __init feat_v6_fixup(void) | ||
276 | { | ||
277 | int id = read_cpuid_id(); | ||
278 | |||
279 | if ((id & 0xff0f0000) != 0x41070000) | ||
280 | return; | ||
281 | |||
282 | /* | ||
283 | * HWCAP_TLS is available only on 1136 r1p0 and later, | ||
284 | * see also kuser_get_tls_init. | ||
285 | */ | ||
286 | if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0)) | ||
287 | elf_hwcap &= ~HWCAP_TLS; | ||
288 | } | ||
289 | |||
272 | static void __init setup_processor(void) | 290 | static void __init setup_processor(void) |
273 | { | 291 | { |
274 | struct proc_info_list *list; | 292 | struct proc_info_list *list; |
@@ -311,6 +329,8 @@ static void __init setup_processor(void) | |||
311 | elf_hwcap &= ~HWCAP_THUMB; | 329 | elf_hwcap &= ~HWCAP_THUMB; |
312 | #endif | 330 | #endif |
313 | 331 | ||
332 | feat_v6_fixup(); | ||
333 | |||
314 | cacheid_init(); | 334 | cacheid_init(); |
315 | cpu_proc_init(); | 335 | cpu_proc_init(); |
316 | } | 336 | } |
@@ -402,13 +422,12 @@ static int __init arm_add_memory(unsigned long start, unsigned long size) | |||
402 | size -= start & ~PAGE_MASK; | 422 | size -= start & ~PAGE_MASK; |
403 | bank->start = PAGE_ALIGN(start); | 423 | bank->start = PAGE_ALIGN(start); |
404 | bank->size = size & PAGE_MASK; | 424 | bank->size = size & PAGE_MASK; |
405 | bank->node = PHYS_TO_NID(start); | ||
406 | 425 | ||
407 | /* | 426 | /* |
408 | * Check whether this memory region has non-zero size or | 427 | * Check whether this memory region has non-zero size or |
409 | * invalid node number. | 428 | * invalid node number. |
410 | */ | 429 | */ |
411 | if (bank->size == 0 || bank->node >= MAX_NUMNODES) | 430 | if (bank->size == 0) |
412 | return -EINVAL; | 431 | return -EINVAL; |
413 | 432 | ||
414 | meminfo.nr_banks++; | 433 | meminfo.nr_banks++; |
@@ -663,6 +682,79 @@ static int __init customize_machine(void) | |||
663 | } | 682 | } |
664 | arch_initcall(customize_machine); | 683 | arch_initcall(customize_machine); |
665 | 684 | ||
685 | #ifdef CONFIG_KEXEC | ||
686 | static inline unsigned long long get_total_mem(void) | ||
687 | { | ||
688 | unsigned long total; | ||
689 | |||
690 | total = max_low_pfn - min_low_pfn; | ||
691 | return total << PAGE_SHIFT; | ||
692 | } | ||
693 | |||
694 | /** | ||
695 | * reserve_crashkernel() - reserves memory are for crash kernel | ||
696 | * | ||
697 | * This function reserves memory area given in "crashkernel=" kernel command | ||
698 | * line parameter. The memory reserved is used by a dump capture kernel when | ||
699 | * primary kernel is crashing. | ||
700 | */ | ||
701 | static void __init reserve_crashkernel(void) | ||
702 | { | ||
703 | unsigned long long crash_size, crash_base; | ||
704 | unsigned long long total_mem; | ||
705 | int ret; | ||
706 | |||
707 | total_mem = get_total_mem(); | ||
708 | ret = parse_crashkernel(boot_command_line, total_mem, | ||
709 | &crash_size, &crash_base); | ||
710 | if (ret) | ||
711 | return; | ||
712 | |||
713 | ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE); | ||
714 | if (ret < 0) { | ||
715 | printk(KERN_WARNING "crashkernel reservation failed - " | ||
716 | "memory is in use (0x%lx)\n", (unsigned long)crash_base); | ||
717 | return; | ||
718 | } | ||
719 | |||
720 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | ||
721 | "for crashkernel (System RAM: %ldMB)\n", | ||
722 | (unsigned long)(crash_size >> 20), | ||
723 | (unsigned long)(crash_base >> 20), | ||
724 | (unsigned long)(total_mem >> 20)); | ||
725 | |||
726 | crashk_res.start = crash_base; | ||
727 | crashk_res.end = crash_base + crash_size - 1; | ||
728 | insert_resource(&iomem_resource, &crashk_res); | ||
729 | } | ||
730 | #else | ||
731 | static inline void reserve_crashkernel(void) {} | ||
732 | #endif /* CONFIG_KEXEC */ | ||
733 | |||
734 | /* | ||
735 | * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by | ||
736 | * is_kdump_kernel() to determine if we are booting after a panic. Hence | ||
737 | * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE. | ||
738 | */ | ||
739 | |||
740 | #ifdef CONFIG_CRASH_DUMP | ||
741 | /* | ||
742 | * elfcorehdr= specifies the location of elf core header stored by the crashed | ||
743 | * kernel. This option will be passed by kexec loader to the capture kernel. | ||
744 | */ | ||
745 | static int __init setup_elfcorehdr(char *arg) | ||
746 | { | ||
747 | char *end; | ||
748 | |||
749 | if (!arg) | ||
750 | return -EINVAL; | ||
751 | |||
752 | elfcorehdr_addr = memparse(arg, &end); | ||
753 | return end > arg ? 0 : -EINVAL; | ||
754 | } | ||
755 | early_param("elfcorehdr", setup_elfcorehdr); | ||
756 | #endif /* CONFIG_CRASH_DUMP */ | ||
757 | |||
666 | void __init setup_arch(char **cmdline_p) | 758 | void __init setup_arch(char **cmdline_p) |
667 | { | 759 | { |
668 | struct tag *tags = (struct tag *)&init_tags; | 760 | struct tag *tags = (struct tag *)&init_tags; |
@@ -716,12 +808,15 @@ void __init setup_arch(char **cmdline_p) | |||
716 | 808 | ||
717 | parse_early_param(); | 809 | parse_early_param(); |
718 | 810 | ||
811 | arm_memblock_init(&meminfo, mdesc); | ||
812 | |||
719 | paging_init(mdesc); | 813 | paging_init(mdesc); |
720 | request_standard_resources(&meminfo, mdesc); | 814 | request_standard_resources(&meminfo, mdesc); |
721 | 815 | ||
722 | #ifdef CONFIG_SMP | 816 | #ifdef CONFIG_SMP |
723 | smp_init_cpus(); | 817 | smp_init_cpus(); |
724 | #endif | 818 | #endif |
819 | reserve_crashkernel(); | ||
725 | 820 | ||
726 | cpu_init(); | 821 | cpu_init(); |
727 | tcm_init(); | 822 | tcm_init(); |
@@ -729,6 +824,7 @@ void __init setup_arch(char **cmdline_p) | |||
729 | /* | 824 | /* |
730 | * Set up various architecture-specific pointers | 825 | * Set up various architecture-specific pointers |
731 | */ | 826 | */ |
827 | arch_nr_irqs = mdesc->nr_irqs; | ||
732 | init_arch_irq = mdesc->init_irq; | 828 | init_arch_irq = mdesc->init_irq; |
733 | system_timer = mdesc->timer; | 829 | system_timer = mdesc->timer; |
734 | init_machine = mdesc->init_machine; | 830 | init_machine = mdesc->init_machine; |