Commit | Line | Data |
---|---|---|
e616c591 RK |
1 | /* |
2 | * ARM specific SMP header, this contains our implementation | |
3 | * details. | |
4 | */ | |
5 | #ifndef __ASMARM_SMP_PLAT_H | |
6 | #define __ASMARM_SMP_PLAT_H | |
7 | ||
7f124aaf LP |
8 | #include <linux/cpumask.h> |
9 | #include <linux/err.h> | |
10 | ||
eba1c718 | 11 | #include <asm/cpu.h> |
e616c591 RK |
12 | #include <asm/cputype.h> |
13 | ||
f00ec48f RK |
14 | /* |
15 | * Return true if we are running on a SMP platform | |
16 | */ | |
17 | static inline bool is_smp(void) | |
18 | { | |
19 | #ifndef CONFIG_SMP | |
20 | return false; | |
21 | #elif defined(CONFIG_SMP_ON_UP) | |
22 | extern unsigned int smp_on_up; | |
23 | return !!smp_on_up; | |
24 | #else | |
25 | return true; | |
26 | #endif | |
27 | } | |
28 | ||
eba1c718 JL |
29 | /** |
30 | * smp_cpuid_part() - return part id for a given cpu | |
31 | * @cpu: logical cpu id. | |
32 | * | |
33 | * Return: part id of logical cpu passed as argument. | |
34 | */ | |
35 | static inline unsigned int smp_cpuid_part(int cpu) | |
36 | { | |
37 | struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpu); | |
38 | ||
39 | return is_smp() ? cpu_info->cpuid & ARM_CPU_PART_MASK : | |
40 | read_cpuid_part(); | |
41 | } | |
42 | ||
e616c591 | 43 | /* all SMP configurations have the extended CPUID registers */ |
5c709e69 WD |
44 | #ifndef CONFIG_MMU |
45 | #define tlb_ops_need_broadcast() 0 | |
46 | #else | |
e616c591 RK |
47 | static inline int tlb_ops_need_broadcast(void) |
48 | { | |
7511db9d TL |
49 | if (!is_smp()) |
50 | return 0; | |
51 | ||
e616c591 RK |
52 | return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2; |
53 | } | |
5c709e69 | 54 | #endif |
e616c591 | 55 | |
85848dd7 CM |
56 | #if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7 |
57 | #define cache_ops_need_broadcast() 0 | |
58 | #else | |
2ef7f3db RK |
59 | static inline int cache_ops_need_broadcast(void) |
60 | { | |
7511db9d TL |
61 | if (!is_smp()) |
62 | return 0; | |
63 | ||
2ef7f3db RK |
64 | return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1; |
65 | } | |
85848dd7 | 66 | #endif |
2ef7f3db | 67 | |
eb50439b WD |
68 | /* |
69 | * Logical CPU mapping. | |
70 | */ | |
18d7f152 | 71 | extern u32 __cpu_logical_map[]; |
eb50439b | 72 | #define cpu_logical_map(cpu) __cpu_logical_map[cpu] |
7f124aaf LP |
73 | /* |
74 | * Retrieve logical cpu index corresponding to a given MPIDR[23:0] | |
75 | * - mpidr: MPIDR[23:0] to be used for the look-up | |
76 | * | |
77 | * Returns the cpu logical index or -EINVAL on look-up error | |
78 | */ | |
79 | static inline int get_logical_index(u32 mpidr) | |
80 | { | |
81 | int cpu; | |
82 | for (cpu = 0; cpu < nr_cpu_ids; cpu++) | |
83 | if (cpu_logical_map(cpu) == mpidr) | |
84 | return cpu; | |
85 | return -EINVAL; | |
86 | } | |
eb50439b | 87 | |
7604537b LP |
88 | /* |
89 | * NOTE ! Assembly code relies on the following | |
90 | * structure memory layout in order to carry out load | |
91 | * multiple from its base address. For more | |
92 | * information check arch/arm/kernel/sleep.S | |
93 | */ | |
8cf72172 | 94 | struct mpidr_hash { |
7604537b LP |
95 | u32 mask; /* used by sleep.S */ |
96 | u32 shift_aff[3]; /* used by sleep.S */ | |
8cf72172 LP |
97 | u32 bits; |
98 | }; | |
99 | ||
100 | extern struct mpidr_hash mpidr_hash; | |
101 | ||
102 | static inline u32 mpidr_hash_size(void) | |
103 | { | |
104 | return 1 << mpidr_hash.bits; | |
105 | } | |
2103f6cb | 106 | |
fee3fd4f | 107 | extern int platform_can_secondary_boot(void); |
2103f6cb SW |
108 | extern int platform_can_cpu_hotplug(void); |
109 | ||
787047ee SB |
110 | #ifdef CONFIG_HOTPLUG_CPU |
111 | extern int platform_can_hotplug_cpu(unsigned int cpu); | |
112 | #else | |
113 | static inline int platform_can_hotplug_cpu(unsigned int cpu) | |
114 | { | |
115 | return 0; | |
116 | } | |
117 | #endif | |
118 | ||
e616c591 | 119 | #endif |