summaryrefslogtreecommitdiffstats
path: root/arch/riscv/kernel/clint.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv/kernel/clint.c')
-rw-r--r--arch/riscv/kernel/clint.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/arch/riscv/kernel/clint.c b/arch/riscv/kernel/clint.c
index 3647980d14c3..a9845ee023e2 100644
--- a/arch/riscv/kernel/clint.c
+++ b/arch/riscv/kernel/clint.c
@@ -5,11 +5,11 @@
#include <linux/io.h>
#include <linux/of_address.h>
+#include <linux/smp.h>
#include <linux/types.h>
#include <asm/clint.h>
#include <asm/csr.h>
#include <asm/timex.h>
-#include <asm/smp.h>
/*
* This is the layout used by the SiFive clint, which is also shared by the qemu
@@ -21,6 +21,24 @@
u32 __iomem *clint_ipi_base;
+static void clint_send_ipi(const struct cpumask *target)
+{
+ unsigned int cpu;
+
+ for_each_cpu(cpu, target)
+ writel(1, clint_ipi_base + cpuid_to_hartid_map(cpu));
+}
+
+static void clint_clear_ipi(void)
+{
+ writel(0, clint_ipi_base + cpuid_to_hartid_map(smp_processor_id()));
+}
+
+static struct riscv_ipi_ops clint_ipi_ops = {
+ .ipi_inject = clint_send_ipi,
+ .ipi_clear = clint_clear_ipi,
+};
+
void clint_init_boot_cpu(void)
{
struct device_node *np;
@@ -40,5 +58,6 @@ void clint_init_boot_cpu(void)
riscv_time_cmp = base + CLINT_TIME_CMP_OFF;
riscv_time_val = base + CLINT_TIME_VAL_OFF;
- clint_clear_ipi(boot_cpu_hartid);
+ clint_clear_ipi();
+ riscv_set_ipi_ops(&clint_ipi_ops);
}