Commit e7b5771a authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch irq/riscv-ipi into irq/irqchip-next



* irq/riscv-ipi:
  : .
  : RISC-V IPI rework from Anup Patel:
  :
  : "This series aims to improve IPI support in Linux RISC-V in following ways:
  :  1) Treat IPIs as normal per-CPU interrupts instead of having custom RISC-V
  :     specific hooks. This also makes Linux RISC-V IPI support aligned with
  :     other architectures.
  :  2) Remote TLB flushes and icache flushes should prefer local IPIs instead
  :     of SBI calls whenever we have specialized hardware (such as RISC-V AIA
  :     IMSIC and RISC-V SWI) which allows S-mode software to directly inject
  :     IPIs without any assistance from M-mode runtime firmware."
  : .
  irqchip/riscv-intc: Add empty irq_eoi() for chained irq handlers
  RISC-V: Use IPIs for remote icache flush when possible
  RISC-V: Use IPIs for remote TLB flush when possible
  RISC-V: Allow marking IPIs as suitable for remote FENCEs
  RISC-V: Treat IPIs as normal Linux IRQs
  irqchip/riscv-intc: Allow drivers to directly discover INTC hwnode
  RISC-V: Clear SIP bit only when using SBI IPI operations

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents f39157b3 f8415f2d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ config RISCV
	select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO
	select GENERIC_IDLE_POLL_SETUP
	select GENERIC_IOREMAP if MMU
	select GENERIC_IRQ_IPI if SMP
	select GENERIC_IRQ_IPI_MUX if SMP
	select GENERIC_IRQ_MULTI_HANDLER
	select GENERIC_IRQ_SHOW
	select GENERIC_IRQ_SHOW_LEVEL
+4 −0
Original line number Diff line number Diff line
@@ -12,6 +12,10 @@

#include <asm-generic/irq.h>

void riscv_set_intc_hwnode_fn(struct fwnode_handle *(*fn)(void));

struct fwnode_handle *riscv_get_intc_hwnode(void);

extern void __init init_IRQ(void);

#endif /* _ASM_RISCV_IRQ_H */
+7 −2
Original line number Diff line number Diff line
@@ -271,8 +271,7 @@ long sbi_get_marchid(void);
long sbi_get_mimpid(void);
void sbi_set_timer(uint64_t stime_value);
void sbi_shutdown(void);
void sbi_clear_ipi(void);
int sbi_send_ipi(const struct cpumask *cpu_mask);
void sbi_send_ipi(unsigned int cpu);
int sbi_remote_fence_i(const struct cpumask *cpu_mask);
int sbi_remote_sfence_vma(const struct cpumask *cpu_mask,
			   unsigned long start,
@@ -335,4 +334,10 @@ unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
unsigned long riscv_cached_marchid(unsigned int cpu_id);
unsigned long riscv_cached_mimpid(unsigned int cpu_id);

#if IS_ENABLED(CONFIG_SMP) && IS_ENABLED(CONFIG_RISCV_SBI)
void sbi_ipi_init(void);
#else
static inline void sbi_ipi_init(void) { }
#endif

#endif /* _ASM_RISCV_SBI_H */
+35 −14
Original line number Diff line number Diff line
@@ -15,12 +15,10 @@
struct seq_file;
extern unsigned long boot_cpu_hartid;

struct riscv_ipi_ops {
	void (*ipi_inject)(const struct cpumask *target);
	void (*ipi_clear)(void);
};

#ifdef CONFIG_SMP

#include <linux/jump_label.h>

/*
 * Mapping between linux logical cpu index and hartid.
 */
@@ -33,9 +31,6 @@ void show_ipi_stats(struct seq_file *p, int prec);
/* SMP initialization hook for setup_arch */
void __init setup_smp(void);

/* Called from C code, this handles an IPI. */
void handle_IPI(struct pt_regs *regs);

/* Hook for the generic smp_call_function_many() routine. */
void arch_send_call_function_ipi_mask(struct cpumask *mask);

@@ -44,11 +39,22 @@ void arch_send_call_function_single_ipi(int cpu);

int riscv_hartid_to_cpuid(unsigned long hartid);

/* Set custom IPI operations */
void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops);
/* Enable IPI for CPU hotplug */
void riscv_ipi_enable(void);

/* Disable IPI for CPU hotplug */
void riscv_ipi_disable(void);

/* Clear IPI for current CPU */
void riscv_clear_ipi(void);
/* Check if IPI interrupt numbers are available */
bool riscv_ipi_have_virq_range(void);

/* Set the IPI interrupt numbers for arch (called by irqchip drivers) */
void riscv_ipi_set_virq_range(int virq, int nr, bool use_for_rfence);

/* Check if we can use IPIs for remote FENCEs */
DECLARE_STATIC_KEY_FALSE(riscv_ipi_for_rfence);
#define riscv_use_ipi_for_rfence() \
	static_branch_unlikely(&riscv_ipi_for_rfence)

/* Check other CPUs stop or not */
bool smp_crash_stop_failed(void);
@@ -85,14 +91,29 @@ static inline unsigned long cpuid_to_hartid_map(int cpu)
	return boot_cpu_hartid;
}

static inline void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops)
static inline void riscv_ipi_enable(void)
{
}

static inline void riscv_ipi_disable(void)
{
}

static inline void riscv_clear_ipi(void)
static inline bool riscv_ipi_have_virq_range(void)
{
	return false;
}

static inline void riscv_ipi_set_virq_range(int virq, int nr,
					    bool use_for_rfence)
{
}

static inline bool riscv_use_ipi_for_rfence(void)
{
	return false;
}

#endif /* CONFIG_SMP */

#if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP)
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
obj-$(CONFIG_HAVE_PERF_REGS)	+= perf_regs.o
obj-$(CONFIG_RISCV_SBI)		+= sbi.o
ifeq ($(CONFIG_RISCV_SBI), y)
obj-$(CONFIG_SMP)		+= sbi-ipi.o
obj-$(CONFIG_SMP) += cpu_ops_sbi.o
endif
obj-$(CONFIG_HOTPLUG_CPU)	+= cpu-hotplug.o
Loading