Commit | Line | Data |
---|---|---|
72e20142 PB |
1 | /* |
2 | * Copyright (C) 2013 Imagination Technologies | |
3 | * Author: Paul Burton <paul.burton@imgtec.com> | |
4 | * | |
5 | * Based on smp-cmp.c: | |
6 | * Copyright (C) 2007 MIPS Technologies, Inc. | |
7 | * Author: Chris Dearman (chris@mips.com) | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify it | |
10 | * under the terms of the GNU General Public License as published by the | |
11 | * Free Software Foundation; either version 2 of the License, or (at your | |
12 | * option) any later version. | |
13 | */ | |
14 | ||
4060bbe9 | 15 | #include <linux/irqchip/mips-gic.h> |
72e20142 PB |
16 | #include <linux/printk.h> |
17 | ||
d0508944 | 18 | #include <asm/mips-cpc.h> |
72e20142 PB |
19 | #include <asm/smp-ops.h> |
20 | ||
21 | void gic_send_ipi_single(int cpu, unsigned int action) | |
22 | { | |
23 | unsigned long flags; | |
24 | unsigned int intr; | |
d0508944 | 25 | unsigned int core = cpu_data[cpu].core; |
72e20142 PB |
26 | |
27 | pr_debug("CPU%d: %s cpu %d action %u status %08x\n", | |
28 | smp_processor_id(), __func__, cpu, action, read_c0_status()); | |
29 | ||
30 | local_irq_save(flags); | |
31 | ||
32 | switch (action) { | |
33 | case SMP_CALL_FUNCTION: | |
34 | intr = plat_ipi_call_int_xlate(cpu); | |
35 | break; | |
36 | ||
37 | case SMP_RESCHEDULE_YOURSELF: | |
38 | intr = plat_ipi_resched_int_xlate(cpu); | |
39 | break; | |
40 | ||
41 | default: | |
42 | BUG(); | |
43 | } | |
44 | ||
45 | gic_send_ipi(intr); | |
d0508944 PB |
46 | |
47 | if (mips_cpc_present() && (core != current_cpu_data.core)) { | |
48 | while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { | |
4ede3161 | 49 | mips_cm_lock_other(core, 0); |
d0508944 PB |
50 | mips_cpc_lock_other(core); |
51 | write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); | |
52 | mips_cpc_unlock_other(); | |
4ede3161 | 53 | mips_cm_unlock_other(); |
d0508944 PB |
54 | } |
55 | } | |
56 | ||
72e20142 PB |
57 | local_irq_restore(flags); |
58 | } | |
59 | ||
60 | void gic_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |
61 | { | |
62 | unsigned int i; | |
63 | ||
64 | for_each_cpu(i, mask) | |
65 | gic_send_ipi_single(i, action); | |
66 | } |