aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/setup.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-08-04 07:43:45 -0400
committerTony Lindgren <tony@atomide.com>2010-08-04 07:43:45 -0400
commit7590d1defdc720a97a9e186f45f529c4ae1b40f7 (patch)
treee7ffdc043a2847f410d654d8e99e001f3138937a /arch/arm/kernel/setup.c
parent7e788b4289bb025a96e327c604cb2db92e17108f (diff)
parent869fef41547db95df8523bf67845a21313709428 (diff)
Merge branch 'devel-map-io' into omap-for-linus
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r--arch/arm/kernel/setup.c111
1 files changed, 109 insertions, 2 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 122d999bdc7c..d5231ae7355a 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>
@@ -44,7 +47,9 @@
44#include <asm/traps.h> 47#include <asm/traps.h>
45#include <asm/unwind.h> 48#include <asm/unwind.h>
46 49
50#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
47#include "compat.h" 51#include "compat.h"
52#endif
48#include "atags.h" 53#include "atags.h"
49#include "tcm.h" 54#include "tcm.h"
50 55
@@ -269,6 +274,21 @@ static void __init cacheid_init(void)
269extern struct proc_info_list *lookup_processor_type(unsigned int); 274extern struct proc_info_list *lookup_processor_type(unsigned int);
270extern struct machine_desc *lookup_machine_type(unsigned int); 275extern struct machine_desc *lookup_machine_type(unsigned int);
271 276
277static void __init feat_v6_fixup(void)
278{
279 int id = read_cpuid_id();
280
281 if ((id & 0xff0f0000) != 0x41070000)
282 return;
283
284 /*
285 * HWCAP_TLS is available only on 1136 r1p0 and later,
286 * see also kuser_get_tls_init.
287 */
288 if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0))
289 elf_hwcap &= ~HWCAP_TLS;
290}
291
272static void __init setup_processor(void) 292static void __init setup_processor(void)
273{ 293{
274 struct proc_info_list *list; 294 struct proc_info_list *list;
@@ -311,6 +331,8 @@ static void __init setup_processor(void)
311 elf_hwcap &= ~HWCAP_THUMB; 331 elf_hwcap &= ~HWCAP_THUMB;
312#endif 332#endif
313 333
334 feat_v6_fixup();
335
314 cacheid_init(); 336 cacheid_init();
315 cpu_proc_init(); 337 cpu_proc_init();
316} 338}
@@ -402,13 +424,12 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
402 size -= start & ~PAGE_MASK; 424 size -= start & ~PAGE_MASK;
403 bank->start = PAGE_ALIGN(start); 425 bank->start = PAGE_ALIGN(start);
404 bank->size = size & PAGE_MASK; 426 bank->size = size & PAGE_MASK;
405 bank->node = PHYS_TO_NID(start);
406 427
407 /* 428 /*
408 * Check whether this memory region has non-zero size or 429 * Check whether this memory region has non-zero size or
409 * invalid node number. 430 * invalid node number.
410 */ 431 */
411 if (bank->size == 0 || bank->node >= MAX_NUMNODES) 432 if (bank->size == 0)
412 return -EINVAL; 433 return -EINVAL;
413 434
414 meminfo.nr_banks++; 435 meminfo.nr_banks++;
@@ -663,6 +684,86 @@ static int __init customize_machine(void)
663} 684}
664arch_initcall(customize_machine); 685arch_initcall(customize_machine);
665 686
687#ifdef CONFIG_KEXEC
688static inline unsigned long long get_total_mem(void)
689{
690 unsigned long total;
691
692 total = max_low_pfn - min_low_pfn;
693 return total << PAGE_SHIFT;
694}
695
696/**
697 * reserve_crashkernel() - reserves memory are for crash kernel
698 *
699 * This function reserves memory area given in "crashkernel=" kernel command
700 * line parameter. The memory reserved is used by a dump capture kernel when
701 * primary kernel is crashing.
702 */
703static void __init reserve_crashkernel(void)
704{
705 unsigned long long crash_size, crash_base;
706 unsigned long long total_mem;
707 int ret;
708
709 total_mem = get_total_mem();
710 ret = parse_crashkernel(boot_command_line, total_mem,
711 &crash_size, &crash_base);
712 if (ret)
713 return;
714
715 ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE);
716 if (ret < 0) {
717 printk(KERN_WARNING "crashkernel reservation failed - "
718 "memory is in use (0x%lx)\n", (unsigned long)crash_base);
719 return;
720 }
721
722 printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
723 "for crashkernel (System RAM: %ldMB)\n",
724 (unsigned long)(crash_size >> 20),
725 (unsigned long)(crash_base >> 20),
726 (unsigned long)(total_mem >> 20));
727
728 crashk_res.start = crash_base;
729 crashk_res.end = crash_base + crash_size - 1;
730 insert_resource(&iomem_resource, &crashk_res);
731}
732#else
733static inline void reserve_crashkernel(void) {}
734#endif /* CONFIG_KEXEC */
735
736/*
737 * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
738 * is_kdump_kernel() to determine if we are booting after a panic. Hence
739 * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
740 */
741
742#ifdef CONFIG_CRASH_DUMP
743/*
744 * elfcorehdr= specifies the location of elf core header stored by the crashed
745 * kernel. This option will be passed by kexec loader to the capture kernel.
746 */
747static int __init setup_elfcorehdr(char *arg)
748{
749 char *end;
750
751 if (!arg)
752 return -EINVAL;
753
754 elfcorehdr_addr = memparse(arg, &end);
755 return end > arg ? 0 : -EINVAL;
756}
757early_param("elfcorehdr", setup_elfcorehdr);
758#endif /* CONFIG_CRASH_DUMP */
759
760static void __init squash_mem_tags(struct tag *tag)
761{
762 for (; tag->hdr.size; tag = tag_next(tag))
763 if (tag->hdr.tag == ATAG_MEM)
764 tag->hdr.tag = ATAG_NONE;
765}
766
666void __init setup_arch(char **cmdline_p) 767void __init setup_arch(char **cmdline_p)
667{ 768{
668 struct tag *tags = (struct tag *)&init_tags; 769 struct tag *tags = (struct tag *)&init_tags;
@@ -683,12 +784,14 @@ void __init setup_arch(char **cmdline_p)
683 else if (mdesc->boot_params) 784 else if (mdesc->boot_params)
684 tags = phys_to_virt(mdesc->boot_params); 785 tags = phys_to_virt(mdesc->boot_params);
685 786
787#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
686 /* 788 /*
687 * If we have the old style parameters, convert them to 789 * If we have the old style parameters, convert them to
688 * a tag list. 790 * a tag list.
689 */ 791 */
690 if (tags->hdr.tag != ATAG_CORE) 792 if (tags->hdr.tag != ATAG_CORE)
691 convert_to_tag_list(tags); 793 convert_to_tag_list(tags);
794#endif
692 if (tags->hdr.tag != ATAG_CORE) 795 if (tags->hdr.tag != ATAG_CORE)
693 tags = (struct tag *)&init_tags; 796 tags = (struct tag *)&init_tags;
694 797
@@ -716,12 +819,15 @@ void __init setup_arch(char **cmdline_p)
716 819
717 parse_early_param(); 820 parse_early_param();
718 821
822 arm_memblock_init(&meminfo, mdesc);
823
719 paging_init(mdesc); 824 paging_init(mdesc);
720 request_standard_resources(&meminfo, mdesc); 825 request_standard_resources(&meminfo, mdesc);
721 826
722#ifdef CONFIG_SMP 827#ifdef CONFIG_SMP
723 smp_init_cpus(); 828 smp_init_cpus();
724#endif 829#endif
830 reserve_crashkernel();
725 831
726 cpu_init(); 832 cpu_init();
727 tcm_init(); 833 tcm_init();
@@ -729,6 +835,7 @@ void __init setup_arch(char **cmdline_p)
729 /* 835 /*
730 * Set up various architecture-specific pointers 836 * Set up various architecture-specific pointers
731 */ 837 */
838 arch_nr_irqs = mdesc->nr_irqs;
732 init_arch_irq = mdesc->init_irq; 839 init_arch_irq = mdesc->init_irq;
733 system_timer = mdesc->timer; 840 system_timer = mdesc->timer;
734 init_machine = mdesc->init_machine; 841 init_machine = mdesc->init_machine;