diff options
Diffstat (limited to 'arch/arm/kernel/devtree.c')
-rw-r--r-- | arch/arm/kernel/devtree.c | 67 |
1 files changed, 37 insertions, 30 deletions
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index f751714d52c..e94a157ddff 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -18,6 +18,7 @@ #include <linux/of_fdt.h> #include <linux/of_irq.h> #include <linux/of_platform.h> +#include <linux/smp.h> #include <asm/cputype.h> #include <asm/setup.h> @@ -26,42 +27,37 @@ #include <asm/mach/arch.h> #include <asm/mach-types.h> -void __init early_init_dt_add_memory_arch(u64 base, u64 size) -{ - arm_add_memory(base, size); -} -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return memblock_virt_alloc(size, align); -} +#ifdef CONFIG_SMP +extern struct of_cpu_method __cpu_method_of_table[]; + +static const struct of_cpu_method __cpu_method_of_table_sentinel + __used __section(__cpu_method_of_table_end); -void __init arm_dt_memblock_reserve(void) + +static int __init set_smp_ops_by_method(struct device_node *node) { - u64 *reserve_map, base, size; + const char *method; + struct of_cpu_method *m = __cpu_method_of_table; - if (!initial_boot_params) - return; + if (of_property_read_string(node, "enable-method", &method)) + return 0; - /* Reserve the dtb region */ - memblock_reserve(virt_to_phys(initial_boot_params), - be32_to_cpu(initial_boot_params->totalsize)); + for (; m->method; m++) + if (!strcmp(m->method, method)) { + smp_set_ops(m->ops); + return 1; + } - /* - * Process the reserve map. This will probably overlap the initrd - * and dtb locations which are already reserved, but overlaping - * doesn't hurt anything - */ - reserve_map = ((void*)initial_boot_params) + - be32_to_cpu(initial_boot_params->off_mem_rsvmap); - while (1) { - base = be64_to_cpup(reserve_map++); - size = be64_to_cpup(reserve_map++); - if (!size) - break; - memblock_reserve(base, size); - } + return 0; } +#else +static inline int set_smp_ops_by_method(struct device_node *node) +{ + return 1; +} +#endif + /* * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree @@ -79,6 +75,7 @@ void __init arm_dt_init_cpu_maps(void) * read as 0. */ struct device_node *cpu, *cpus; + int found_method = 0; u32 i, j, cpuidx = 1; u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; @@ -150,8 +147,18 @@ void __init arm_dt_init_cpu_maps(void) } tmp_map[i] = hwid; + + if (!found_method) + found_method = set_smp_ops_by_method(cpu); } + /* + * Fallback to an enable-method in the cpus node if nothing found in + * a cpu node. + */ + if (!found_method) + set_smp_ops_by_method(cpus); + if (!bootcpu_valid) { pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n"); return; @@ -212,7 +219,7 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) if (!mdesc) { const char *prop; - long size; + int size; unsigned long dt_root; early_print("\nError: unrecognized/unsupported " |