Skip to content

Commit 3f614ab

Browse files
committed
Merge tag 'irq-core-2023-04-24' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull interrupt updates from Thomas Gleixner: "Core: - Add tracepoints for tasklet callbacks which makes it possible to analyze individual tasklet functions instead of guess working from the overall duration of tasklet processing - Ensure that secondary interrupt threads have their affinity adjusted correctly Drivers: - A large rework of the RISC-V IPI management to prepare for a new RISC-V interrupt architecture - Small fixes and enhancements all over the place - Removal of support for various obsolete hardware platforms and the related code" * tag 'irq-core-2023-04-24' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits) irqchip/st: Remove stih415/stih416 and stid127 platforms support irqchip/gic-v3: Add Rockchip 3588001 erratum workaround genirq: Update affinity of secondary threads softirq: Add trace points for tasklet entry/exit irqchip/loongson-pch-pic: Fix pch_pic_acpi_init calling irqchip/loongson-pch-pic: Fix registration of syscore_ops irqchip/loongson-eiointc: Fix registration of syscore_ops irqchip/loongson-eiointc: Fix incorrect use of acpi_get_vec_parent irqchip/loongson-eiointc: Fix returned value on parsing MADT 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 irqchip/irq-sifive-plic: Add syscore callbacks for hibernation irqchip: Use of_property_read_bool() for boolean properties irqchip/bcm-6345-l1: Request memory region irqchip/gicv3: Workaround for NVIDIA erratum T241-FABRIC-4 ...
2 parents 15bbeec + f37202a commit 3f614ab

35 files changed

+819
-380
lines changed

Documentation/arm64/silicon-errata.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ stable kernels.
172172
+----------------+-----------------+-----------------+-----------------------------+
173173
| NVIDIA | Carmel Core | N/A | NVIDIA_CARMEL_CNP_ERRATUM |
174174
+----------------+-----------------+-----------------+-----------------------------+
175+
| NVIDIA | T241 GICv3/4.x | T241-FABRIC-4 | N/A |
176+
+----------------+-----------------+-----------------+-----------------------------+
175177
+----------------+-----------------+-----------------+-----------------------------+
176178
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
177179
+----------------+-----------------+-----------------+-----------------------------+
@@ -205,6 +207,9 @@ stable kernels.
205207
+----------------+-----------------+-----------------+-----------------------------+
206208
| Qualcomm Tech. | Kryo4xx Gold | N/A | ARM64_ERRATUM_1286807 |
207209
+----------------+-----------------+-----------------+-----------------------------+
210+
+----------------+-----------------+-----------------+-----------------------------+
211+
| Rockchip | RK3588 | #3588001 | ROCKCHIP_ERRATUM_3588001 |
212+
+----------------+-----------------+-----------------+-----------------------------+
208213

209214
+----------------+-----------------+-----------------+-----------------------------+
210215
| Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 |

arch/arm64/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,16 @@ config NVIDIA_CARMEL_CNP_ERRATUM
11501150

11511151
If unsure, say Y.
11521152

1153+
config ROCKCHIP_ERRATUM_3588001
1154+
bool "Rockchip 3588001: GIC600 can not support shareability attributes"
1155+
default y
1156+
help
1157+
The Rockchip RK3588 GIC600 SoC integration does not support ACE/ACE-lite.
1158+
This means, that its sharability feature may not be used, even though it
1159+
is supported by the IP itself.
1160+
1161+
If unsure, say Y.
1162+
11531163
config SOCIONEXT_SYNQUACER_PREITS
11541164
bool "Socionext Synquacer: Workaround for GICv3 pre-ITS"
11551165
default y

arch/riscv/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ config RISCV
6363
select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO
6464
select GENERIC_IDLE_POLL_SETUP
6565
select GENERIC_IOREMAP if MMU
66+
select GENERIC_IRQ_IPI if SMP
67+
select GENERIC_IRQ_IPI_MUX if SMP
6668
select GENERIC_IRQ_MULTI_HANDLER
6769
select GENERIC_IRQ_SHOW
6870
select GENERIC_IRQ_SHOW_LEVEL

arch/riscv/include/asm/irq.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212

1313
#include <asm-generic/irq.h>
1414

15+
void riscv_set_intc_hwnode_fn(struct fwnode_handle *(*fn)(void));
16+
17+
struct fwnode_handle *riscv_get_intc_hwnode(void);
18+
1519
extern void __init init_IRQ(void);
1620

1721
#endif /* _ASM_RISCV_IRQ_H */

arch/riscv/include/asm/sbi.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,7 @@ long sbi_get_marchid(void);
271271
long sbi_get_mimpid(void);
272272
void sbi_set_timer(uint64_t stime_value);
273273
void sbi_shutdown(void);
274-
void sbi_clear_ipi(void);
275-
int sbi_send_ipi(const struct cpumask *cpu_mask);
274+
void sbi_send_ipi(unsigned int cpu);
276275
int sbi_remote_fence_i(const struct cpumask *cpu_mask);
277276
int sbi_remote_sfence_vma(const struct cpumask *cpu_mask,
278277
unsigned long start,
@@ -335,4 +334,10 @@ unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
335334
unsigned long riscv_cached_marchid(unsigned int cpu_id);
336335
unsigned long riscv_cached_mimpid(unsigned int cpu_id);
337336

337+
#if IS_ENABLED(CONFIG_SMP) && IS_ENABLED(CONFIG_RISCV_SBI)
338+
void sbi_ipi_init(void);
339+
#else
340+
static inline void sbi_ipi_init(void) { }
341+
#endif
342+
338343
#endif /* _ASM_RISCV_SBI_H */

arch/riscv/include/asm/smp.h

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@
1515
struct seq_file;
1616
extern unsigned long boot_cpu_hartid;
1717

18-
struct riscv_ipi_ops {
19-
void (*ipi_inject)(const struct cpumask *target);
20-
void (*ipi_clear)(void);
21-
};
22-
2318
#ifdef CONFIG_SMP
19+
20+
#include <linux/jump_label.h>
21+
2422
/*
2523
* Mapping between linux logical cpu index and hartid.
2624
*/
@@ -33,9 +31,6 @@ void show_ipi_stats(struct seq_file *p, int prec);
3331
/* SMP initialization hook for setup_arch */
3432
void __init setup_smp(void);
3533

36-
/* Called from C code, this handles an IPI. */
37-
void handle_IPI(struct pt_regs *regs);
38-
3934
/* Hook for the generic smp_call_function_many() routine. */
4035
void arch_send_call_function_ipi_mask(struct cpumask *mask);
4136

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

4540
int riscv_hartid_to_cpuid(unsigned long hartid);
4641

47-
/* Set custom IPI operations */
48-
void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops);
42+
/* Enable IPI for CPU hotplug */
43+
void riscv_ipi_enable(void);
44+
45+
/* Disable IPI for CPU hotplug */
46+
void riscv_ipi_disable(void);
4947

50-
/* Clear IPI for current CPU */
51-
void riscv_clear_ipi(void);
48+
/* Check if IPI interrupt numbers are available */
49+
bool riscv_ipi_have_virq_range(void);
50+
51+
/* Set the IPI interrupt numbers for arch (called by irqchip drivers) */
52+
void riscv_ipi_set_virq_range(int virq, int nr, bool use_for_rfence);
53+
54+
/* Check if we can use IPIs for remote FENCEs */
55+
DECLARE_STATIC_KEY_FALSE(riscv_ipi_for_rfence);
56+
#define riscv_use_ipi_for_rfence() \
57+
static_branch_unlikely(&riscv_ipi_for_rfence)
5258

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

88-
static inline void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops)
94+
static inline void riscv_ipi_enable(void)
95+
{
96+
}
97+
98+
static inline void riscv_ipi_disable(void)
8999
{
90100
}
91101

92-
static inline void riscv_clear_ipi(void)
102+
static inline bool riscv_ipi_have_virq_range(void)
103+
{
104+
return false;
105+
}
106+
107+
static inline void riscv_ipi_set_virq_range(int virq, int nr,
108+
bool use_for_rfence)
93109
{
94110
}
95111

112+
static inline bool riscv_use_ipi_for_rfence(void)
113+
{
114+
return false;
115+
}
116+
96117
#endif /* CONFIG_SMP */
97118

98119
#if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP)

arch/riscv/kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
7474
obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o
7575
obj-$(CONFIG_RISCV_SBI) += sbi.o
7676
ifeq ($(CONFIG_RISCV_SBI), y)
77+
obj-$(CONFIG_SMP) += sbi-ipi.o
7778
obj-$(CONFIG_SMP) += cpu_ops_sbi.o
7879
endif
7980
obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o

arch/riscv/kernel/cpu-hotplug.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include <asm/irq.h>
1414
#include <asm/cpu_ops.h>
1515
#include <asm/numa.h>
16-
#include <asm/sbi.h>
16+
#include <asm/smp.h>
1717

1818
bool cpu_has_hotplug(unsigned int cpu)
1919
{
@@ -43,6 +43,7 @@ int __cpu_disable(void)
4343
remove_cpu_topology(cpu);
4444
numa_remove_cpu(cpu);
4545
set_cpu_online(cpu, false);
46+
riscv_ipi_disable();
4647
irq_migrate_all_off_this_cpu();
4748

4849
return ret;

arch/riscv/kernel/irq.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,26 @@
77

88
#include <linux/interrupt.h>
99
#include <linux/irqchip.h>
10+
#include <linux/irqdomain.h>
11+
#include <linux/module.h>
1012
#include <linux/seq_file.h>
11-
#include <asm/smp.h>
13+
#include <asm/sbi.h>
14+
15+
static struct fwnode_handle *(*__get_intc_node)(void);
16+
17+
void riscv_set_intc_hwnode_fn(struct fwnode_handle *(*fn)(void))
18+
{
19+
__get_intc_node = fn;
20+
}
21+
22+
struct fwnode_handle *riscv_get_intc_hwnode(void)
23+
{
24+
if (__get_intc_node)
25+
return __get_intc_node();
26+
27+
return NULL;
28+
}
29+
EXPORT_SYMBOL_GPL(riscv_get_intc_hwnode);
1230

1331
int arch_show_interrupts(struct seq_file *p, int prec)
1432
{
@@ -21,4 +39,5 @@ void __init init_IRQ(void)
2139
irqchip_init();
2240
if (!handle_arch_irq)
2341
panic("No interrupt controller found.");
42+
sbi_ipi_init();
2443
}

arch/riscv/kernel/sbi-ipi.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Multiplex several IPIs over a single HW IPI.
4+
*
5+
* Copyright (c) 2022 Ventana Micro Systems Inc.
6+
*/
7+
8+
#define pr_fmt(fmt) "riscv: " fmt
9+
#include <linux/cpu.h>
10+
#include <linux/init.h>
11+
#include <linux/irq.h>
12+
#include <linux/irqchip/chained_irq.h>
13+
#include <linux/irqdomain.h>
14+
#include <asm/sbi.h>
15+
16+
static int sbi_ipi_virq;
17+
18+
static void sbi_ipi_handle(struct irq_desc *desc)
19+
{
20+
struct irq_chip *chip = irq_desc_get_chip(desc);
21+
22+
chained_irq_enter(chip, desc);
23+
24+
csr_clear(CSR_IP, IE_SIE);
25+
ipi_mux_process();
26+
27+
chained_irq_exit(chip, desc);
28+
}
29+
30+
static int sbi_ipi_starting_cpu(unsigned int cpu)
31+
{
32+
enable_percpu_irq(sbi_ipi_virq, irq_get_trigger_type(sbi_ipi_virq));
33+
return 0;
34+
}
35+
36+
void __init sbi_ipi_init(void)
37+
{
38+
int virq;
39+
struct irq_domain *domain;
40+
41+
if (riscv_ipi_have_virq_range())
42+
return;
43+
44+
domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
45+
DOMAIN_BUS_ANY);
46+
if (!domain) {
47+
pr_err("unable to find INTC IRQ domain\n");
48+
return;
49+
}
50+
51+
sbi_ipi_virq = irq_create_mapping(domain, RV_IRQ_SOFT);
52+
if (!sbi_ipi_virq) {
53+
pr_err("unable to create INTC IRQ mapping\n");
54+
return;
55+
}
56+
57+
virq = ipi_mux_create(BITS_PER_BYTE, sbi_send_ipi);
58+
if (virq <= 0) {
59+
pr_err("unable to create muxed IPIs\n");
60+
irq_dispose_mapping(sbi_ipi_virq);
61+
return;
62+
}
63+
64+
irq_set_chained_handler(sbi_ipi_virq, sbi_ipi_handle);
65+
66+
/*
67+
* Don't disable IPI when CPU goes offline because
68+
* the masking/unmasking of virtual IPIs is done
69+
* via generic IPI-Mux
70+
*/
71+
cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
72+
"irqchip/sbi-ipi:starting",
73+
sbi_ipi_starting_cpu, NULL);
74+
75+
riscv_ipi_set_virq_range(virq, BITS_PER_BYTE, false);
76+
pr_info("providing IPIs using SBI IPI extension\n");
77+
}

0 commit comments

Comments
 (0)