]>
Commit | Line | Data |
---|---|---|
59ac59f6 RK |
1 | /* |
2 | * linux/arch/arm/mach-vexpress/platsmp.c | |
3 | * | |
4 | * Copyright (C) 2002 ARM Ltd. | |
5 | * All Rights Reserved | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | */ | |
11 | #include <linux/init.h> | |
12 | #include <linux/errno.h> | |
59ac59f6 RK |
13 | #include <linux/smp.h> |
14 | #include <linux/io.h> | |
d2606f81 | 15 | #include <linux/of_address.h> |
38669e04 | 16 | #include <linux/vexpress.h> |
95d59741 | 17 | |
033a899c | 18 | #include <asm/mcpm.h> |
95d59741 | 19 | #include <asm/smp_scu.h> |
95d59741 | 20 | #include <asm/mach/map.h> |
59ac59f6 | 21 | |
3695adc2 | 22 | #include <plat/platsmp.h> |
59ac59f6 | 23 | |
3695adc2 | 24 | #include "core.h" |
3705ff6d | 25 | |
033a899c JM |
26 | bool __init vexpress_smp_init_ops(void) |
27 | { | |
28 | #ifdef CONFIG_MCPM | |
29 | /* | |
30 | * The best way to detect a multi-cluster configuration at the moment | |
31 | * is to look for the presence of a CCI in the system. | |
32 | * Override the default vexpress_smp_ops if so. | |
33 | */ | |
34 | struct device_node *node; | |
35 | node = of_find_compatible_node(NULL, NULL, "arm,cci-400"); | |
36 | if (node && of_device_is_available(node)) { | |
37 | mcpm_smp_set_ops(); | |
38 | return true; | |
39 | } | |
40 | #endif | |
41 | return false; | |
42 | } | |
d2606f81 | 43 | |
d2606f81 PM |
44 | static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = { |
45 | { .compatible = "arm,cortex-a5-scu", }, | |
46 | { .compatible = "arm,cortex-a9-scu", }, | |
47 | {} | |
48 | }; | |
49 | ||
50 | static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus) | |
51 | { | |
52 | struct device_node *scu = of_find_matching_node(NULL, | |
53 | vexpress_smp_dt_scu_match); | |
54 | ||
55 | if (scu) | |
56 | scu_enable(of_iomap(scu, 0)); | |
57 | ||
58 | /* | |
59 | * Write the address of secondary startup into the | |
60 | * system-wide flags register. The boot monitor waits | |
61 | * until it receives a soft interrupt, and then the | |
62 | * secondary CPU branches to this address. | |
63 | */ | |
64 | vexpress_flags_set(virt_to_phys(versatile_secondary_startup)); | |
65 | } | |
66 | ||
75305275 | 67 | const struct smp_operations vexpress_smp_dt_ops __initconst = { |
d2606f81 PM |
68 | .smp_prepare_cpus = vexpress_smp_dt_prepare_cpus, |
69 | .smp_secondary_init = versatile_secondary_init, | |
70 | .smp_boot_secondary = versatile_boot_secondary, | |
71 | #ifdef CONFIG_HOTPLUG_CPU | |
72 | .cpu_die = vexpress_cpu_die, | |
73 | #endif | |
74 | }; |