diff options
Diffstat (limited to 'arch/mips/pmc-sierra')
-rw-r--r-- | arch/mips/pmc-sierra/yosemite/prom.c | 5 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/yosemite/smp.c | 149 |
2 files changed, 89 insertions, 65 deletions
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c index 96d3ff051d3d..35dc435846a6 100644 --- a/arch/mips/pmc-sierra/yosemite/prom.c +++ b/arch/mips/pmc-sierra/yosemite/prom.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/pgtable.h> | 19 | #include <asm/pgtable.h> |
20 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
21 | #include <asm/reboot.h> | 21 | #include <asm/reboot.h> |
22 | #include <asm/smp-ops.h> | ||
22 | #include <asm/system.h> | 23 | #include <asm/system.h> |
23 | #include <asm/bootinfo.h> | 24 | #include <asm/bootinfo.h> |
24 | #include <asm/pmon.h> | 25 | #include <asm/pmon.h> |
@@ -78,6 +79,8 @@ static void prom_halt(void) | |||
78 | __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); | 79 | __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); |
79 | } | 80 | } |
80 | 81 | ||
82 | extern struct plat_smp_ops yos_smp_ops; | ||
83 | |||
81 | /* | 84 | /* |
82 | * Init routine which accepts the variables from PMON | 85 | * Init routine which accepts the variables from PMON |
83 | */ | 86 | */ |
@@ -127,6 +130,8 @@ void __init prom_init(void) | |||
127 | } | 130 | } |
128 | 131 | ||
129 | prom_grab_secondary(); | 132 | prom_grab_secondary(); |
133 | |||
134 | register_smp_ops(&yos_smp_ops); | ||
130 | } | 135 | } |
131 | 136 | ||
132 | void __init prom_free_prom_memory(void) | 137 | void __init prom_free_prom_memory(void) |
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index b0f12cd2968a..653f3ec61cab 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c | |||
@@ -42,70 +42,6 @@ void __init prom_grab_secondary(void) | |||
42 | launchstack + LAUNCHSTACK_SIZE, 0); | 42 | launchstack + LAUNCHSTACK_SIZE, 0); |
43 | } | 43 | } |
44 | 44 | ||
45 | /* | ||
46 | * Detect available CPUs, populate phys_cpu_present_map before smp_init | ||
47 | * | ||
48 | * We don't want to start the secondary CPU yet nor do we have a nice probing | ||
49 | * feature in PMON so we just assume presence of the secondary core. | ||
50 | */ | ||
51 | void __init plat_smp_setup(void) | ||
52 | { | ||
53 | int i; | ||
54 | |||
55 | cpus_clear(phys_cpu_present_map); | ||
56 | |||
57 | for (i = 0; i < 2; i++) { | ||
58 | cpu_set(i, phys_cpu_present_map); | ||
59 | __cpu_number_map[i] = i; | ||
60 | __cpu_logical_map[i] = i; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | void __init plat_prepare_cpus(unsigned int max_cpus) | ||
65 | { | ||
66 | /* | ||
67 | * Be paranoid. Enable the IPI only if we're really about to go SMP. | ||
68 | */ | ||
69 | if (cpus_weight(cpu_possible_map)) | ||
70 | set_c0_status(STATUSF_IP5); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Firmware CPU startup hook | ||
75 | * Complicated by PMON's weird interface which tries to minimic the UNIX fork. | ||
76 | * It launches the next * available CPU and copies some information on the | ||
77 | * stack so the first thing we do is throw away that stuff and load useful | ||
78 | * values into the registers ... | ||
79 | */ | ||
80 | void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) | ||
81 | { | ||
82 | unsigned long gp = (unsigned long) task_thread_info(idle); | ||
83 | unsigned long sp = __KSTK_TOS(idle); | ||
84 | |||
85 | secondary_sp = sp; | ||
86 | secondary_gp = gp; | ||
87 | |||
88 | spin_unlock(&launch_lock); | ||
89 | } | ||
90 | |||
91 | /* Hook for after all CPUs are online */ | ||
92 | void prom_cpus_done(void) | ||
93 | { | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * After we've done initial boot, this function is called to allow the | ||
98 | * board code to clean up state, if needed | ||
99 | */ | ||
100 | void __cpuinit prom_init_secondary(void) | ||
101 | { | ||
102 | set_c0_status(ST0_CO | ST0_IE | ST0_IM); | ||
103 | } | ||
104 | |||
105 | void __cpuinit prom_smp_finish(void) | ||
106 | { | ||
107 | } | ||
108 | |||
109 | void titan_mailbox_irq(void) | 45 | void titan_mailbox_irq(void) |
110 | { | 46 | { |
111 | int cpu = smp_processor_id(); | 47 | int cpu = smp_processor_id(); |
@@ -133,7 +69,7 @@ void titan_mailbox_irq(void) | |||
133 | /* | 69 | /* |
134 | * Send inter-processor interrupt | 70 | * Send inter-processor interrupt |
135 | */ | 71 | */ |
136 | void core_send_ipi(int cpu, unsigned int action) | 72 | static void yos_send_ipi_single(int cpu, unsigned int action) |
137 | { | 73 | { |
138 | /* | 74 | /* |
139 | * Generate an INTMSG so that it can be sent over to the | 75 | * Generate an INTMSG so that it can be sent over to the |
@@ -159,3 +95,86 @@ void core_send_ipi(int cpu, unsigned int action) | |||
159 | break; | 95 | break; |
160 | } | 96 | } |
161 | } | 97 | } |
98 | |||
99 | static void yos_send_ipi_mask(cpumask_t mask, unsigned int action) | ||
100 | { | ||
101 | unsigned int i; | ||
102 | |||
103 | for_each_cpu_mask(i, mask) | ||
104 | yos_send_ipi_single(i, action); | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * After we've done initial boot, this function is called to allow the | ||
109 | * board code to clean up state, if needed | ||
110 | */ | ||
111 | static void __cpuinit yos_init_secondary(void) | ||
112 | { | ||
113 | set_c0_status(ST0_CO | ST0_IE | ST0_IM); | ||
114 | } | ||
115 | |||
116 | static void __cpuinit yos_smp_finish(void) | ||
117 | { | ||
118 | } | ||
119 | |||
120 | /* Hook for after all CPUs are online */ | ||
121 | static void yos_cpus_done(void) | ||
122 | { | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Firmware CPU startup hook | ||
127 | * Complicated by PMON's weird interface which tries to minimic the UNIX fork. | ||
128 | * It launches the next * available CPU and copies some information on the | ||
129 | * stack so the first thing we do is throw away that stuff and load useful | ||
130 | * values into the registers ... | ||
131 | */ | ||
132 | static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle) | ||
133 | { | ||
134 | unsigned long gp = (unsigned long) task_thread_info(idle); | ||
135 | unsigned long sp = __KSTK_TOS(idle); | ||
136 | |||
137 | secondary_sp = sp; | ||
138 | secondary_gp = gp; | ||
139 | |||
140 | spin_unlock(&launch_lock); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Detect available CPUs, populate phys_cpu_present_map before smp_init | ||
145 | * | ||
146 | * We don't want to start the secondary CPU yet nor do we have a nice probing | ||
147 | * feature in PMON so we just assume presence of the secondary core. | ||
148 | */ | ||
149 | static void __init yos_smp_setup(void) | ||
150 | { | ||
151 | int i; | ||
152 | |||
153 | cpus_clear(phys_cpu_present_map); | ||
154 | |||
155 | for (i = 0; i < 2; i++) { | ||
156 | cpu_set(i, phys_cpu_present_map); | ||
157 | __cpu_number_map[i] = i; | ||
158 | __cpu_logical_map[i] = i; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static void __init yos_prepare_cpus(unsigned int max_cpus) | ||
163 | { | ||
164 | /* | ||
165 | * Be paranoid. Enable the IPI only if we're really about to go SMP. | ||
166 | */ | ||
167 | if (cpus_weight(cpu_possible_map)) | ||
168 | set_c0_status(STATUSF_IP5); | ||
169 | } | ||
170 | |||
171 | struct plat_smp_ops yos_smp_ops = { | ||
172 | .send_ipi_single = yos_send_ipi_single, | ||
173 | .send_ipi_mask = yos_send_ipi_mask, | ||
174 | .init_secondary = yos_init_secondary, | ||
175 | .smp_finish = yos_smp_finish, | ||
176 | .cpus_done = yos_cpus_done, | ||
177 | .boot_secondary = yos_boot_secondary, | ||
178 | .smp_setup = yos_smp_setup, | ||
179 | .prepare_cpus = yos_prepare_cpus, | ||
180 | }; | ||