Skip to content

Commit df0f030

Browse files
vlkondratievKAGA-KOKO
authored andcommitted
irqchip/thead-c900-aclint-sswi: Generalize aclint-sswi driver and add MIPS P800 support
Refactor the Thead specific implementation of the ACLINT-SSWI irqchip: - Rename the source file and related details to reflect the generic nature of the driver - Factor out the generic code that serves both Thead and MIPS variants. This generic part is compliant with the RISC-V draft spec [1] - Provide generic and Thead specific initialization functions Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/all/20250612143911.3224046-5-vladimir.kondratiev@mobileye.com Link: https://github.com/riscvarchive/riscv-aclint [1]
1 parent ed65197 commit df0f030

4 files changed

Lines changed: 74 additions & 35 deletions

File tree

drivers/irqchip/Kconfig

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -634,18 +634,25 @@ config STARFIVE_JH8100_INTC
634634

635635
If you don't know what to do here, say Y.
636636

637-
config THEAD_C900_ACLINT_SSWI
638-
bool "THEAD C9XX ACLINT S-mode IPI Interrupt Controller"
637+
config ACLINT_SSWI
638+
bool "RISC-V ACLINT S-mode IPI Interrupt Controller"
639639
depends on RISCV
640640
depends on SMP
641641
select IRQ_DOMAIN_HIERARCHY
642642
select GENERIC_IRQ_IPI_MUX
643643
help
644-
This enables support for T-HEAD specific ACLINT SSWI device
645-
support.
644+
This enables support for variants of the RISC-V ACLINT-SSWI device.
645+
Supported variants are:
646+
- T-HEAD, with compatible "thead,c900-aclint-sswi"
647+
- MIPS P8700, with compatible "mips,p8700-aclint-sswi"
646648

647649
If you don't know what to do here, say Y.
648650

651+
# Backwards compatibility so oldconfig does not drop it.
652+
config THEAD_C900_ACLINT_SSWI
653+
bool
654+
select ACLINT_SSWI
655+
649656
config EXYNOS_IRQ_COMBINER
650657
bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
651658
depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST

drivers/irqchip/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ obj-$(CONFIG_RISCV_APLIC_MSI) += irq-riscv-aplic-msi.o
105105
obj-$(CONFIG_RISCV_IMSIC) += irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
106106
obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
107107
obj-$(CONFIG_STARFIVE_JH8100_INTC) += irq-starfive-jh8100-intc.o
108-
obj-$(CONFIG_THEAD_C900_ACLINT_SSWI) += irq-thead-c900-aclint-sswi.o
108+
obj-$(CONFIG_ACLINT_SSWI) += irq-aclint-sswi.o
109109
obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
110110
obj-$(CONFIG_IMX_INTMUX) += irq-imx-intmux.o
111111
obj-$(CONFIG_IMX_MU_MSI) += irq-imx-mu-msi.o

drivers/irqchip/irq-thead-c900-aclint-sswi.c renamed to drivers/irqchip/irq-aclint-sswi.c

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* Copyright (C) 2024 Inochi Amaoto <inochiama@gmail.com>
44
*/
55

6-
#define pr_fmt(fmt) "thead-c900-aclint-sswi: " fmt
6+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7+
78
#include <linux/cpu.h>
89
#include <linux/interrupt.h>
910
#include <linux/io.h>
@@ -21,56 +22,50 @@
2122
#include <asm/sbi.h>
2223
#include <asm/vendorid_list.h>
2324

24-
#define THEAD_ACLINT_xSWI_REGISTER_SIZE 4
25-
26-
#define THEAD_C9XX_CSR_SXSTATUS 0x5c0
27-
#define THEAD_C9XX_SXSTATUS_CLINTEE BIT(17)
28-
2925
static int sswi_ipi_virq __ro_after_init;
3026
static DEFINE_PER_CPU(void __iomem *, sswi_cpu_regs);
3127

32-
static void thead_aclint_sswi_ipi_send(unsigned int cpu)
28+
static void aclint_sswi_ipi_send(unsigned int cpu)
3329
{
3430
writel(0x1, per_cpu(sswi_cpu_regs, cpu));
3531
}
3632

37-
static void thead_aclint_sswi_ipi_clear(void)
33+
static void aclint_sswi_ipi_clear(void)
3834
{
3935
writel_relaxed(0x0, this_cpu_read(sswi_cpu_regs));
4036
}
4137

42-
static void thead_aclint_sswi_ipi_handle(struct irq_desc *desc)
38+
static void aclint_sswi_ipi_handle(struct irq_desc *desc)
4339
{
4440
struct irq_chip *chip = irq_desc_get_chip(desc);
4541

4642
chained_irq_enter(chip, desc);
4743

4844
csr_clear(CSR_IP, IE_SIE);
49-
thead_aclint_sswi_ipi_clear();
45+
aclint_sswi_ipi_clear();
5046

5147
ipi_mux_process();
5248

5349
chained_irq_exit(chip, desc);
5450
}
5551

56-
static int thead_aclint_sswi_starting_cpu(unsigned int cpu)
52+
static int aclint_sswi_starting_cpu(unsigned int cpu)
5753
{
5854
enable_percpu_irq(sswi_ipi_virq, irq_get_trigger_type(sswi_ipi_virq));
5955

6056
return 0;
6157
}
6258

63-
static int thead_aclint_sswi_dying_cpu(unsigned int cpu)
59+
static int aclint_sswi_dying_cpu(unsigned int cpu)
6460
{
65-
thead_aclint_sswi_ipi_clear();
61+
aclint_sswi_ipi_clear();
6662

6763
disable_percpu_irq(sswi_ipi_virq);
6864

6965
return 0;
7066
}
7167

72-
static int __init thead_aclint_sswi_parse_irq(struct fwnode_handle *fwnode,
73-
void __iomem *reg)
68+
static int __init aclint_sswi_parse_irq(struct fwnode_handle *fwnode, void __iomem *reg)
7469
{
7570
struct of_phandle_args parent;
7671
unsigned long hartid;
@@ -97,25 +92,20 @@ static int __init thead_aclint_sswi_parse_irq(struct fwnode_handle *fwnode,
9792

9893
cpu = riscv_hartid_to_cpuid(hartid);
9994

100-
per_cpu(sswi_cpu_regs, cpu) = reg + i * THEAD_ACLINT_xSWI_REGISTER_SIZE;
95+
per_cpu(sswi_cpu_regs, cpu) = reg + hart_index * 4;
10196
}
10297

10398
pr_info("%pfwP: register %u CPU%s\n", fwnode, contexts, str_plural(contexts));
10499

105100
return 0;
106101
}
107102

108-
static int __init thead_aclint_sswi_probe(struct fwnode_handle *fwnode)
103+
static int __init aclint_sswi_probe(struct fwnode_handle *fwnode)
109104
{
110105
struct irq_domain *domain;
111106
void __iomem *reg;
112107
int virq, rc;
113108

114-
/* If it is T-HEAD CPU, check whether SSWI is enabled */
115-
if (riscv_cached_mvendorid(0) == THEAD_VENDOR_ID &&
116-
!(csr_read(THEAD_C9XX_CSR_SXSTATUS) & THEAD_C9XX_SXSTATUS_CLINTEE))
117-
return -ENOTSUPP;
118-
119109
if (!is_of_node(fwnode))
120110
return -EINVAL;
121111

@@ -124,7 +114,7 @@ static int __init thead_aclint_sswi_probe(struct fwnode_handle *fwnode)
124114
return -ENOMEM;
125115

126116
/* Parse SSWI setting */
127-
rc = thead_aclint_sswi_parse_irq(fwnode, reg);
117+
rc = aclint_sswi_parse_irq(fwnode, reg);
128118
if (rc < 0)
129119
return rc;
130120

@@ -146,22 +136,64 @@ static int __init thead_aclint_sswi_probe(struct fwnode_handle *fwnode)
146136
}
147137

148138
/* Register SSWI irq and handler */
149-
virq = ipi_mux_create(BITS_PER_BYTE, thead_aclint_sswi_ipi_send);
139+
virq = ipi_mux_create(BITS_PER_BYTE, aclint_sswi_ipi_send);
150140
if (virq <= 0) {
151141
pr_err("unable to create muxed IPIs\n");
152142
irq_dispose_mapping(sswi_ipi_virq);
153143
return virq < 0 ? virq : -ENOMEM;
154144
}
155145

156-
irq_set_chained_handler(sswi_ipi_virq, thead_aclint_sswi_ipi_handle);
146+
irq_set_chained_handler(sswi_ipi_virq, aclint_sswi_ipi_handle);
157147

158-
cpuhp_setup_state(CPUHP_AP_IRQ_THEAD_ACLINT_SSWI_STARTING,
159-
"irqchip/thead-aclint-sswi:starting",
160-
thead_aclint_sswi_starting_cpu,
161-
thead_aclint_sswi_dying_cpu);
148+
cpuhp_setup_state(CPUHP_AP_IRQ_ACLINT_SSWI_STARTING,
149+
"irqchip/aclint-sswi:starting",
150+
aclint_sswi_starting_cpu,
151+
aclint_sswi_dying_cpu);
162152

163153
riscv_ipi_set_virq_range(virq, BITS_PER_BYTE);
164154

155+
return 0;
156+
}
157+
158+
/* generic/MIPS variant */
159+
static int __init generic_aclint_sswi_probe(struct fwnode_handle *fwnode)
160+
{
161+
int rc;
162+
163+
rc = aclint_sswi_probe(fwnode);
164+
if (rc)
165+
return rc;
166+
167+
/* Announce that SSWI is providing IPIs */
168+
pr_info("providing IPIs using ACLINT SSWI\n");
169+
170+
return 0;
171+
}
172+
173+
static int __init generic_aclint_sswi_early_probe(struct device_node *node,
174+
struct device_node *parent)
175+
{
176+
return generic_aclint_sswi_probe(&node->fwnode);
177+
}
178+
IRQCHIP_DECLARE(generic_aclint_sswi, "mips,p8700-aclint-sswi", generic_aclint_sswi_early_probe);
179+
180+
/* THEAD variant */
181+
#define THEAD_C9XX_CSR_SXSTATUS 0x5c0
182+
#define THEAD_C9XX_SXSTATUS_CLINTEE BIT(17)
183+
184+
static int __init thead_aclint_sswi_probe(struct fwnode_handle *fwnode)
185+
{
186+
int rc;
187+
188+
/* If it is T-HEAD CPU, check whether SSWI is enabled */
189+
if (riscv_cached_mvendorid(0) == THEAD_VENDOR_ID &&
190+
!(csr_read(THEAD_C9XX_CSR_SXSTATUS) & THEAD_C9XX_SXSTATUS_CLINTEE))
191+
return -ENOTSUPP;
192+
193+
rc = aclint_sswi_probe(fwnode);
194+
if (rc)
195+
return rc;
196+
165197
/* Announce that SSWI is providing IPIs */
166198
pr_info("providing IPIs using THEAD ACLINT SSWI\n");
167199

include/linux/cpuhotplug.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ enum cpuhp_state {
145145
CPUHP_AP_IRQ_EIOINTC_STARTING,
146146
CPUHP_AP_IRQ_AVECINTC_STARTING,
147147
CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
148-
CPUHP_AP_IRQ_THEAD_ACLINT_SSWI_STARTING,
148+
CPUHP_AP_IRQ_ACLINT_SSWI_STARTING,
149149
CPUHP_AP_IRQ_RISCV_IMSIC_STARTING,
150150
CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING,
151151
CPUHP_AP_ARM_MVEBU_COHERENCY,

0 commit comments

Comments
 (0)