Commit | Line | Data |
---|---|---|
088f3876 A |
1 | /* |
2 | * MSP71xx Platform-specific hooks for SMP operation | |
3 | */ | |
4 | #include <linux/irq.h> | |
5 | #include <linux/init.h> | |
6 | ||
7 | #include <asm/mipsmtregs.h> | |
8 | #include <asm/mipsregs.h> | |
9 | #include <asm/smtc.h> | |
10 | #include <asm/smtc_ipi.h> | |
11 | ||
12 | /* VPE/SMP Prototype implements platform interfaces directly */ | |
13 | ||
14 | /* | |
15 | * Cause the specified action to be performed on a targeted "CPU" | |
16 | */ | |
17 | ||
18 | static void msp_smtc_send_ipi_single(int cpu, unsigned int action) | |
19 | { | |
20 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | |
21 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | |
22 | } | |
23 | ||
24 | static void msp_smtc_send_ipi_mask(const struct cpumask *mask, | |
25 | unsigned int action) | |
26 | { | |
27 | unsigned int i; | |
28 | ||
29 | for_each_cpu(i, mask) | |
30 | msp_smtc_send_ipi_single(i, action); | |
31 | } | |
32 | ||
33 | /* | |
34 | * Post-config but pre-boot cleanup entry point | |
35 | */ | |
36 | static void __cpuinit msp_smtc_init_secondary(void) | |
37 | { | |
38 | int myvpe; | |
39 | ||
40 | /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ | |
41 | myvpe = read_c0_tcbind() & TCBIND_CURVPE; | |
42 | if (myvpe > 0) | |
43 | change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 | | |
44 | STATUSF_IP6 | STATUSF_IP7); | |
45 | smtc_init_secondary(); | |
46 | } | |
47 | ||
48 | /* | |
49 | * Platform "CPU" startup hook | |
50 | */ | |
51 | static void __cpuinit msp_smtc_boot_secondary(int cpu, | |
52 | struct task_struct *idle) | |
53 | { | |
54 | smtc_boot_secondary(cpu, idle); | |
55 | } | |
56 | ||
57 | /* | |
58 | * SMP initialization finalization entry point | |
59 | */ | |
60 | static void __cpuinit msp_smtc_smp_finish(void) | |
61 | { | |
62 | smtc_smp_finish(); | |
63 | } | |
64 | ||
65 | /* | |
66 | * Hook for after all CPUs are online | |
67 | */ | |
68 | ||
69 | static void msp_smtc_cpus_done(void) | |
70 | { | |
71 | } | |
72 | ||
73 | /* | |
74 | * Platform SMP pre-initialization | |
75 | * | |
76 | * As noted above, we can assume a single CPU for now | |
77 | * but it may be multithreaded. | |
78 | */ | |
79 | ||
80 | static void __init msp_smtc_smp_setup(void) | |
81 | { | |
82 | /* | |
83 | * we won't get the definitive value until | |
84 | * we've run smtc_prepare_cpus later, but | |
85 | */ | |
86 | ||
87 | if (read_c0_config3() & (1 << 2)) | |
88 | smp_num_siblings = smtc_build_cpu_map(0); | |
89 | } | |
90 | ||
91 | static void __init msp_smtc_prepare_cpus(unsigned int max_cpus) | |
92 | { | |
93 | smtc_prepare_cpus(max_cpus); | |
94 | } | |
95 | ||
96 | struct plat_smp_ops msp_smtc_smp_ops = { | |
97 | .send_ipi_single = msp_smtc_send_ipi_single, | |
98 | .send_ipi_mask = msp_smtc_send_ipi_mask, | |
99 | .init_secondary = msp_smtc_init_secondary, | |
100 | .smp_finish = msp_smtc_smp_finish, | |
101 | .cpus_done = msp_smtc_cpus_done, | |
102 | .boot_secondary = msp_smtc_boot_secondary, | |
103 | .smp_setup = msp_smtc_smp_setup, | |
104 | .prepare_cpus = msp_smtc_prepare_cpus, | |
105 | }; |