aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/mips-cpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/mips-cpc.c')
-rw-r--r--arch/mips/kernel/mips-cpc.c28
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
16void __iomem *mips_cpc_base; 18void __iomem *mips_cpc_base;
17 19
20static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock);
21
22static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);
23
18phys_t __weak mips_cpc_phys_base(void) 24phys_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)
39int mips_cpc_probe(void) 45int 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
64void 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
74void 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}