diff options
Diffstat (limited to 'arch/mips/kernel/mips-cpc.c')
-rw-r--r-- | arch/mips/kernel/mips-cpc.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index c9dc67402969..ba473608a347 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c | |||
@@ -9,12 +9,18 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/percpu.h> | ||
13 | #include <linux/spinlock.h> | ||
12 | 14 | ||
13 | #include <asm/mips-cm.h> | 15 | #include <asm/mips-cm.h> |
14 | #include <asm/mips-cpc.h> | 16 | #include <asm/mips-cpc.h> |
15 | 17 | ||
16 | void __iomem *mips_cpc_base; | 18 | void __iomem *mips_cpc_base; |
17 | 19 | ||
20 | static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock); | ||
21 | |||
22 | static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); | ||
23 | |||
18 | phys_t __weak mips_cpc_phys_base(void) | 24 | phys_t __weak mips_cpc_phys_base(void) |
19 | { | 25 | { |
20 | u32 cpc_base; | 26 | u32 cpc_base; |
@@ -39,6 +45,10 @@ phys_t __weak mips_cpc_phys_base(void) | |||
39 | int mips_cpc_probe(void) | 45 | int mips_cpc_probe(void) |
40 | { | 46 | { |
41 | phys_t addr; | 47 | phys_t addr; |
48 | unsigned cpu; | ||
49 | |||
50 | for_each_possible_cpu(cpu) | ||
51 | spin_lock_init(&per_cpu(cpc_core_lock, cpu)); | ||
42 | 52 | ||
43 | addr = mips_cpc_phys_base(); | 53 | addr = mips_cpc_phys_base(); |
44 | if (!addr) | 54 | if (!addr) |
@@ -50,3 +60,21 @@ int mips_cpc_probe(void) | |||
50 | 60 | ||
51 | return 0; | 61 | return 0; |
52 | } | 62 | } |
63 | |||
64 | void mips_cpc_lock_other(unsigned int core) | ||
65 | { | ||
66 | unsigned curr_core; | ||
67 | preempt_disable(); | ||
68 | curr_core = current_cpu_data.core; | ||
69 | spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), | ||
70 | per_cpu(cpc_core_lock_flags, curr_core)); | ||
71 | write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF); | ||
72 | } | ||
73 | |||
74 | void mips_cpc_unlock_other(void) | ||
75 | { | ||
76 | unsigned curr_core = current_cpu_data.core; | ||
77 | spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core), | ||
78 | per_cpu(cpc_core_lock_flags, curr_core)); | ||
79 | preempt_enable(); | ||
80 | } | ||