If you don't know what to do here, say Y.
 
-config THEAD_C900_ACLINT_SSWI
-       bool "THEAD C9XX ACLINT S-mode IPI Interrupt Controller"
+config ACLINT_SSWI
+       bool "RISC-V ACLINT S-mode IPI Interrupt Controller"
        depends on RISCV
        depends on SMP
        select IRQ_DOMAIN_HIERARCHY
        select GENERIC_IRQ_IPI_MUX
        help
-         This enables support for T-HEAD specific ACLINT SSWI device
-         support.
+         This enables support for variants of the RISC-V ACLINT-SSWI device.
+         Supported variants are:
+         - T-HEAD, with compatible "thead,c900-aclint-sswi"
+         - MIPS P8700, with compatible "mips,p8700-aclint-sswi"
 
          If you don't know what to do here, say Y.
 
+# Backwards compatibility so oldconfig does not drop it.
+config THEAD_C900_ACLINT_SSWI
+       bool
+       select ACLINT_SSWI
+
 config EXYNOS_IRQ_COMBINER
        bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
        depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
 
  * Copyright (C) 2024 Inochi Amaoto <inochiama@gmail.com>
  */
 
-#define pr_fmt(fmt) "thead-c900-aclint-sswi: " fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <asm/sbi.h>
 #include <asm/vendorid_list.h>
 
-#define THEAD_ACLINT_xSWI_REGISTER_SIZE                4
-
-#define THEAD_C9XX_CSR_SXSTATUS                        0x5c0
-#define THEAD_C9XX_SXSTATUS_CLINTEE            BIT(17)
-
 static int sswi_ipi_virq __ro_after_init;
 static DEFINE_PER_CPU(void __iomem *, sswi_cpu_regs);
 
-static void thead_aclint_sswi_ipi_send(unsigned int cpu)
+static void aclint_sswi_ipi_send(unsigned int cpu)
 {
        writel(0x1, per_cpu(sswi_cpu_regs, cpu));
 }
 
-static void thead_aclint_sswi_ipi_clear(void)
+static void aclint_sswi_ipi_clear(void)
 {
        writel_relaxed(0x0, this_cpu_read(sswi_cpu_regs));
 }
 
-static void thead_aclint_sswi_ipi_handle(struct irq_desc *desc)
+static void aclint_sswi_ipi_handle(struct irq_desc *desc)
 {
        struct irq_chip *chip = irq_desc_get_chip(desc);
 
        chained_irq_enter(chip, desc);
 
        csr_clear(CSR_IP, IE_SIE);
-       thead_aclint_sswi_ipi_clear();
+       aclint_sswi_ipi_clear();
 
        ipi_mux_process();
 
        chained_irq_exit(chip, desc);
 }
 
-static int thead_aclint_sswi_starting_cpu(unsigned int cpu)
+static int aclint_sswi_starting_cpu(unsigned int cpu)
 {
        enable_percpu_irq(sswi_ipi_virq, irq_get_trigger_type(sswi_ipi_virq));
 
        return 0;
 }
 
-static int thead_aclint_sswi_dying_cpu(unsigned int cpu)
+static int aclint_sswi_dying_cpu(unsigned int cpu)
 {
-       thead_aclint_sswi_ipi_clear();
+       aclint_sswi_ipi_clear();
 
        disable_percpu_irq(sswi_ipi_virq);
 
        return 0;
 }
 
-static int __init thead_aclint_sswi_parse_irq(struct fwnode_handle *fwnode,
-                                             void __iomem *reg)
+static int __init aclint_sswi_parse_irq(struct fwnode_handle *fwnode, void __iomem *reg)
 {
        struct of_phandle_args parent;
        unsigned long hartid;
 
                cpu = riscv_hartid_to_cpuid(hartid);
 
-               per_cpu(sswi_cpu_regs, cpu) = reg + i * THEAD_ACLINT_xSWI_REGISTER_SIZE;
+               per_cpu(sswi_cpu_regs, cpu) = reg + hart_index * 4;
        }
 
        pr_info("%pfwP: register %u CPU%s\n", fwnode, contexts, str_plural(contexts));
        return 0;
 }
 
-static int __init thead_aclint_sswi_probe(struct fwnode_handle *fwnode)
+static int __init aclint_sswi_probe(struct fwnode_handle *fwnode)
 {
        struct irq_domain *domain;
        void __iomem *reg;
        int virq, rc;
 
-       /* If it is T-HEAD CPU, check whether SSWI is enabled */
-       if (riscv_cached_mvendorid(0) == THEAD_VENDOR_ID &&
-           !(csr_read(THEAD_C9XX_CSR_SXSTATUS) & THEAD_C9XX_SXSTATUS_CLINTEE))
-               return -ENOTSUPP;
-
        if (!is_of_node(fwnode))
                return -EINVAL;
 
                return -ENOMEM;
 
        /* Parse SSWI setting */
-       rc = thead_aclint_sswi_parse_irq(fwnode, reg);
+       rc = aclint_sswi_parse_irq(fwnode, reg);
        if (rc < 0)
                return rc;
 
        }
 
        /* Register SSWI irq and handler */
-       virq = ipi_mux_create(BITS_PER_BYTE, thead_aclint_sswi_ipi_send);
+       virq = ipi_mux_create(BITS_PER_BYTE, aclint_sswi_ipi_send);
        if (virq <= 0) {
                pr_err("unable to create muxed IPIs\n");
                irq_dispose_mapping(sswi_ipi_virq);
                return virq < 0 ? virq : -ENOMEM;
        }
 
-       irq_set_chained_handler(sswi_ipi_virq, thead_aclint_sswi_ipi_handle);
+       irq_set_chained_handler(sswi_ipi_virq, aclint_sswi_ipi_handle);
 
-       cpuhp_setup_state(CPUHP_AP_IRQ_THEAD_ACLINT_SSWI_STARTING,
-                         "irqchip/thead-aclint-sswi:starting",
-                         thead_aclint_sswi_starting_cpu,
-                         thead_aclint_sswi_dying_cpu);
+       cpuhp_setup_state(CPUHP_AP_IRQ_ACLINT_SSWI_STARTING,
+                         "irqchip/aclint-sswi:starting",
+                         aclint_sswi_starting_cpu,
+                         aclint_sswi_dying_cpu);
 
        riscv_ipi_set_virq_range(virq, BITS_PER_BYTE);
 
+       return 0;
+}
+
+/* generic/MIPS variant */
+static int __init generic_aclint_sswi_probe(struct fwnode_handle *fwnode)
+{
+       int rc;
+
+       rc = aclint_sswi_probe(fwnode);
+       if (rc)
+               return rc;
+
+       /* Announce that SSWI is providing IPIs */
+       pr_info("providing IPIs using ACLINT SSWI\n");
+
+       return 0;
+}
+
+static int __init generic_aclint_sswi_early_probe(struct device_node *node,
+                                                 struct device_node *parent)
+{
+       return generic_aclint_sswi_probe(&node->fwnode);
+}
+IRQCHIP_DECLARE(generic_aclint_sswi, "mips,p8700-aclint-sswi", generic_aclint_sswi_early_probe);
+
+/* THEAD variant */
+#define THEAD_C9XX_CSR_SXSTATUS                        0x5c0
+#define THEAD_C9XX_SXSTATUS_CLINTEE            BIT(17)
+
+static int __init thead_aclint_sswi_probe(struct fwnode_handle *fwnode)
+{
+       int rc;
+
+       /* If it is T-HEAD CPU, check whether SSWI is enabled */
+       if (riscv_cached_mvendorid(0) == THEAD_VENDOR_ID &&
+           !(csr_read(THEAD_C9XX_CSR_SXSTATUS) & THEAD_C9XX_SXSTATUS_CLINTEE))
+               return -ENOTSUPP;
+
+       rc = aclint_sswi_probe(fwnode);
+       if (rc)
+               return rc;
+
        /* Announce that SSWI is providing IPIs */
        pr_info("providing IPIs using THEAD ACLINT SSWI\n");