* [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs
@ 2026-11-10 4:31 Florian Fainelli
2026-11-10 4:31 ` [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically Florian Fainelli
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: Florian Fainelli @ 2026-11-10 4:31 UTC (permalink / raw)
To: linux-mips
Cc: Florian Fainelli, Thomas Bogendoerfer, Paul Burton, Paul Cercueil,
Stephen Boyd, Brian Masney, Jerome Brunet,
周琰杰 (Zhou Yanjie), Jiaxun Yang, open list,
open list:COMMON CLK FRAMEWORK, hns, paul
This patch series resurrects SMP support for the CI20 board. This was
submitted back in 2020 by Zhou Yanjie.
Changes in v2:
• Moved SMP sources to arch/mips/ingenic/ and the header to arch/mips/include/asm/
• Removed CONFIG_MIPS_INGENIC_SMP, using CONFIG_MACH_JZ4780 and CONFIG_SMP directly
• Renamed JZ4780-specific SMP symbols to XBurst names
• Changed CPU enumeration to assign consecutive logical IDs and removed the explicit two-core limit
• Changed mailbox IRQ allocation failure from panic to logging and returning
• Shortened commit descriptions, removed Codex attribution, and adjusted source credits and sign-offs
• Kept the clock polling patch and CI20 defconfig changes unchanged,
added Paul's R-b for patch #1
• Updated the kernel baseline to include additional upstream fixes
Florian Fainelli (1):
clk: ingenic: Poll JZ4780 CPU1 power status atomically
周琰杰 (Zhou Yanjie) (2):
MIPS: Ingenic: Add XBurst SMP support
MIPS: CI20: Enable SMP with two CPUs
MAINTAINERS | 3 +-
arch/mips/Kbuild | 1 +
arch/mips/configs/ci20_defconfig | 2 +
arch/mips/generic/init.c | 3 +
arch/mips/include/asm/ingenic-smp.h | 20 +++
arch/mips/ingenic/Kconfig | 2 +
arch/mips/ingenic/Makefile | 5 +
arch/mips/ingenic/ingenic-smp-entry.S | 54 ++++++
arch/mips/ingenic/ingenic-smp.c | 247 ++++++++++++++++++++++++++
arch/mips/kernel/idle.c | 26 ++-
drivers/clk/ingenic/jz4780-cgu.c | 2 +-
11 files changed, 362 insertions(+), 3 deletions(-)
create mode 100644 arch/mips/include/asm/ingenic-smp.h
create mode 100644 arch/mips/ingenic/Makefile
create mode 100644 arch/mips/ingenic/ingenic-smp-entry.S
create mode 100644 arch/mips/ingenic/ingenic-smp.c
--
2.53.0
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically 2026-11-10 4:31 [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli @ 2026-11-10 4:31 ` Florian Fainelli 2026-11-11 18:41 ` Brian Masney 2026-11-10 4:31 ` [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support Florian Fainelli ` (2 subsequent siblings) 3 siblings, 1 reply; 13+ messages in thread From: Florian Fainelli @ 2026-11-10 4:31 UTC (permalink / raw) To: linux-mips Cc: Florian Fainelli, Paul Cercueil, Thomas Bogendoerfer, Paul Burton, Stephen Boyd, Brian Masney, Jerome Brunet, 周琰杰 (Zhou Yanjie), Jiaxun Yang, open list, open list:COMMON CLK FRAMEWORK, hns, paul The CPU1 clock enable callback runs under the clock framework's spinlock with interrupts disabled. Its readl_poll_timeout() can sleep between reads, which is invalid in this context when SMP powers up CPU1. Use readl_poll_timeout_atomic() with the existing interval and timeout. This is a prerequisite for the JZ4780 SMP bring-up path. The original CPU1 clock implementation by Zhou Yanjie is already upstream. Cross-built for CI20; the subsequent SMP-enabled image brought up both CPU cores. Development and validation used Codex assistance. Fixes: 6673db4f3f26 ("clk: JZ4780: Add function for enable the second core.") Link: https://lkml.kernel.org/r/1582215889-113034-3-git-send-email-zhouyanjie@wanyeetech.com Reviewed-by: Paul Cercueil <paul@crapouillou.net> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> --- drivers/clk/ingenic/jz4780-cgu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index 1e88aef7ac0f..f5983033583a 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c @@ -242,7 +242,7 @@ static int jz4780_core1_enable(struct clk_hw *hw) spin_unlock_irqrestore(&cgu->lock, flags); /* wait for the CPU to be powered up */ - retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr, + retval = readl_poll_timeout_atomic(cgu->base + CGU_REG_LCR, lcr, !(lcr & LCR_SCPUS), 10, timeout); if (retval == -ETIMEDOUT) { pr_err("%s: Wait for power up core1 timeout\n", __func__); -- 2.53.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically 2026-11-10 4:31 ` [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically Florian Fainelli @ 2026-11-11 18:41 ` Brian Masney 2026-11-11 19:21 ` Florian Fainelli 0 siblings, 1 reply; 13+ messages in thread From: Brian Masney @ 2026-11-11 18:41 UTC (permalink / raw) To: Florian Fainelli Cc: linux-mips, Paul Cercueil, Thomas Bogendoerfer, Paul Burton, Stephen Boyd, Brian Masney, Jerome Brunet, 周琰杰 (Zhou Yanjie), Jiaxun Yang, linux-kernel, linux-clk, hns, paul, Brian Masney Hi Florian, > The CPU1 clock enable callback runs under the clock framework's spinlock > with interrupts disabled. Its readl_poll_timeout() can sleep between > reads, which is invalid in this context when SMP powers up CPU1. > > Use readl_poll_timeout_atomic() with the existing interval and timeout. > This is a prerequisite for the JZ4780 SMP bring-up path. The original > CPU1 clock implementation by Zhou Yanjie is already upstream. > > Cross-built for CI20; the subsequent SMP-enabled image brought up both > CPU cores. Development and validation used Codex assistance. > > Fixes: 6673db4f3f26 ("clk: JZ4780: Add function for enable the second core.") > Link: https://lkml.kernel.org/r/1582215889-113034-3-git-send-email-zhouyanjie@wanyeetech.com Cc: stable > Reviewed-by: Paul Cercueil <paul@crapouillou.net> > Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> > --- > drivers/clk/ingenic/jz4780-cgu.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c > index 1e88aef7ac0f..f5983033583a 100644 > --- a/drivers/clk/ingenic/jz4780-cgu.c > +++ b/drivers/clk/ingenic/jz4780-cgu.c > @@ -242,7 +242,7 @@ static int jz4780_core1_enable(struct clk_hw *hw) > spin_unlock_irqrestore(&cgu->lock, flags); > > /* wait for the CPU to be powered up */ > - retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr, > + retval = readl_poll_timeout_atomic(cgu->base + CGU_REG_LCR, lcr, > !(lcr & LCR_SCPUS), 10, timeout); Since you are making changes here, please fix the alignment of the next line with (. Brian -- Brian Masney <masneyb@kernel.org> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically 2026-11-11 18:41 ` Brian Masney @ 2026-11-11 19:21 ` Florian Fainelli 0 siblings, 0 replies; 13+ messages in thread From: Florian Fainelli @ 2026-11-11 19:21 UTC (permalink / raw) To: Brian Masney Cc: linux-mips, Paul Cercueil, Thomas Bogendoerfer, Paul Burton, Stephen Boyd, Brian Masney, Jerome Brunet, 周琰杰 (Zhou Yanjie), Jiaxun Yang, linux-kernel, linux-clk, hns, paul On 11/11/26 10:41, Brian Masney wrote: > Hi Florian, > >> The CPU1 clock enable callback runs under the clock framework's spinlock >> with interrupts disabled. Its readl_poll_timeout() can sleep between >> reads, which is invalid in this context when SMP powers up CPU1. >> >> Use readl_poll_timeout_atomic() with the existing interval and timeout. >> This is a prerequisite for the JZ4780 SMP bring-up path. The original >> CPU1 clock implementation by Zhou Yanjie is already upstream. >> >> Cross-built for CI20; the subsequent SMP-enabled image brought up both >> CPU cores. Development and validation used Codex assistance. >> >> Fixes: 6673db4f3f26 ("clk: JZ4780: Add function for enable the second core.") >> Link: https://lkml.kernel.org/r/1582215889-113034-3-git-send-email-zhouyanjie@wanyeetech.com > > Cc: stable OK, I will add that, thanks! > >> Reviewed-by: Paul Cercueil <paul@crapouillou.net> >> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> >> --- >> drivers/clk/ingenic/jz4780-cgu.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c >> index 1e88aef7ac0f..f5983033583a 100644 >> --- a/drivers/clk/ingenic/jz4780-cgu.c >> +++ b/drivers/clk/ingenic/jz4780-cgu.c >> @@ -242,7 +242,7 @@ static int jz4780_core1_enable(struct clk_hw *hw) >> spin_unlock_irqrestore(&cgu->lock, flags); >> >> /* wait for the CPU to be powered up */ >> - retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr, >> + retval = readl_poll_timeout_atomic(cgu->base + CGU_REG_LCR, lcr, >> !(lcr & LCR_SCPUS), 10, timeout); > > Since you are making changes here, please fix the alignment of the > next line with (. Certainly, will submit a newer version shortly. -- Florian ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support 2026-11-10 4:31 [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli 2026-11-10 4:31 ` [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically Florian Fainelli @ 2026-11-10 4:31 ` Florian Fainelli 2026-11-10 5:10 ` sashiko-bot 2026-11-10 15:30 ` Paul Cercueil 2026-11-10 4:31 ` [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli 2026-11-10 15:44 ` [PATCH v2 0/3] " Paul Cercueil 3 siblings, 2 replies; 13+ messages in thread From: Florian Fainelli @ 2026-11-10 4:31 UTC (permalink / raw) To: linux-mips Cc: 周琰杰 (Zhou Yanjie), Florian Fainelli, Thomas Bogendoerfer, Paul Burton, Paul Cercueil, Stephen Boyd, Brian Masney, Jerome Brunet, Jiaxun Yang, open list, open list:COMMON CLK FRAMEWORK, hns, paul From: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> Add support for the second XBurst core on the JZ4780, based on Zhou Yanjie's 2020 series and Paul Burton's original CI20 SMP implementation. Use the CP0 mailboxes for inter-processor interrupts. XBurst stops its private cache clock when executing WAIT. Write back the data cache before entering idle so that the other core can access data belonging to the sleeping core. Link: https://lkml.iu.edu/hypermail/linux/kernel/2005.2/03488.html Link: https://lists.openwall.net/linux-kernel/2020/05/13/1482 Link: https://lists.openwall.net/linux-kernel/2020/05/19/1099 Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> [florian: forward ported to latest version] Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> --- MAINTAINERS | 3 +- arch/mips/Kbuild | 1 + arch/mips/generic/init.c | 3 + arch/mips/include/asm/ingenic-smp.h | 20 +++ arch/mips/ingenic/Kconfig | 2 + arch/mips/ingenic/Makefile | 5 + arch/mips/ingenic/ingenic-smp-entry.S | 54 ++++++ arch/mips/ingenic/ingenic-smp.c | 247 ++++++++++++++++++++++++++ arch/mips/kernel/idle.c | 26 ++- 9 files changed, 359 insertions(+), 2 deletions(-) create mode 100644 arch/mips/include/asm/ingenic-smp.h create mode 100644 arch/mips/ingenic/Makefile create mode 100644 arch/mips/ingenic/ingenic-smp-entry.S create mode 100644 arch/mips/ingenic/ingenic-smp.c diff --git a/MAINTAINERS b/MAINTAINERS index 222b7fc2c3aa..7128df320bab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13150,8 +13150,9 @@ L: linux-mips@vger.kernel.org S: Maintained F: arch/mips/boot/dts/ingenic/ F: arch/mips/generic/board-ingenic.c +F: arch/mips/include/asm/ingenic-smp.h F: arch/mips/include/asm/mach-ingenic/ -F: arch/mips/ingenic/Kconfig +F: arch/mips/ingenic/ F: drivers/clk/ingenic/ F: drivers/dma/dma-jz4780.c F: drivers/gpu/drm/ingenic/ diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild index e901bf554483..4912ab80d143 100644 --- a/arch/mips/Kbuild +++ b/arch/mips/Kbuild @@ -12,6 +12,7 @@ obj- := $(platform-y) # The object files are linked as core-y files would be linked obj-y += generic/ +obj-$(CONFIG_MACH_INGENIC) += ingenic/ obj-y += kernel/ obj-y += mm/ obj-y += net/ diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c index 1d712eac1617..38f294887c17 100644 --- a/arch/mips/generic/init.c +++ b/arch/mips/generic/init.c @@ -13,6 +13,7 @@ #include <asm/bootinfo.h> #include <asm/fw/fw.h> +#include <asm/ingenic-smp.h> #include <asm/irq_cpu.h> #include <asm/machine.h> #include <asm/mips-cps.h> @@ -113,6 +114,8 @@ void __init device_tree_init(void) unflatten_and_copy_device_tree(); mips_cpc_probe(); + if (!register_ingenic_smp_ops()) + return; if (!register_cps_smp_ops()) return; if (!register_vsmp_smp_ops()) diff --git a/arch/mips/include/asm/ingenic-smp.h b/arch/mips/include/asm/ingenic-smp.h new file mode 100644 index 000000000000..ea81c333820d --- /dev/null +++ b/arch/mips/include/asm/ingenic-smp.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2013 Paul Burton <paulburton@kernel.org> */ +#ifndef __ASM_INGENIC_SMP_H__ +#define __ASM_INGENIC_SMP_H__ + +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/kconfig.h> + +#if defined(CONFIG_MACH_JZ4780) && defined(CONFIG_SMP) +int __init register_ingenic_smp_ops(void); +void xburst_secondary_cpu_entry(void); +#else +static inline int register_ingenic_smp_ops(void) +{ + return -ENODEV; +} +#endif + +#endif /* __ASM_INGENIC_SMP_H__ */ diff --git a/arch/mips/ingenic/Kconfig b/arch/mips/ingenic/Kconfig index f595b339a4b8..583f8d3651df 100644 --- a/arch/mips/ingenic/Kconfig +++ b/arch/mips/ingenic/Kconfig @@ -64,6 +64,8 @@ config MACH_JZ4780 select MIPS_CPU_SCACHE select SYS_HAS_CPU_MIPS32_R2 select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_SMP + select SMP_UP if SMP config MACH_X1000 bool diff --git a/arch/mips/ingenic/Makefile b/arch/mips/ingenic/Makefile new file mode 100644 index 000000000000..fc3b1bf1f25a --- /dev/null +++ b/arch/mips/ingenic/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +ifdef CONFIG_SMP +obj-$(CONFIG_MACH_JZ4780) += ingenic-smp.o ingenic-smp-entry.o +endif diff --git a/arch/mips/ingenic/ingenic-smp-entry.S b/arch/mips/ingenic/ingenic-smp-entry.S new file mode 100644 index 000000000000..250a0c89c955 --- /dev/null +++ b/arch/mips/ingenic/ingenic-smp-entry.S @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2013 Paul Burton <paulburton@kernel.org> + * XBurst secondary CPU reset entry + */ + +#include <asm/addrspace.h> +#include <asm/asm.h> +#include <asm/asmmacro.h> +#include <asm/cacheops.h> +#include <asm/mipsregs.h> + +#define CACHE_SIZE (32 * 1024) +#define CACHE_LINESIZE 32 + + /* The CP0 REIM register only stores the upper 16 address bits. */ + .section .text.smp-entry, "ax" + .balign 0x10000 + .set noreorder +LEAF(xburst_secondary_cpu_entry) + mtc0 zero, CP0_CAUSE + li t0, ST0_CU0 + mtc0 t0, CP0_STATUS + ehb + + /* Invalidate both private caches before entering cached code. */ + li t0, KSEG0 + ori t1, t0, CACHE_SIZE + mtc0 zero, CP0_TAGLO + ehb +1: cache Index_Store_Tag_I, 0(t0) + cache Index_Store_Tag_D, 0(t0) + addiu t0, t0, CACHE_LINESIZE + bne t0, t1, 1b + nop + + mfc0 t0, CP0_CONFIG + li t1, ~CONF_CM_CMASK + and t0, t0, t1 + ori t0, t0, CONF_CM_CACHABLE_NONCOHERENT + mtc0 t0, CP0_CONFIG + mtc0 zero, CP0_PAGEMASK + ehb + + /* CPU0 publishes these in RAM before releasing CPU1 from reset. */ + la t0, xburst_cpu_entry_sp + lw sp, 0(t0) + la t0, xburst_cpu_entry_gp + lw gp, 0(t0) + + la t0, smp_bootstrap + jr t0 + nop +END(xburst_secondary_cpu_entry) diff --git a/arch/mips/ingenic/ingenic-smp.c b/arch/mips/ingenic/ingenic-smp.c new file mode 100644 index 000000000000..3cdb953c7a87 --- /dev/null +++ b/arch/mips/ingenic/ingenic-smp.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * XBurst SMP support, based on Paul Burton's CI20 implementation and + * Zhou Yanjie's 2020 JZ4780 SMP series. + * Copyright (C) 2013 Paul Burton <paulburton@kernel.org> + */ + +#include <linux/clk.h> +#include <linux/cpu.h> +#include <linux/interrupt.h> +#include <linux/of.h> +#include <linux/of_clk.h> +#include <linux/sched/task_stack.h> +#include <linux/smp.h> + +#include <asm/addrspace.h> +#include <asm/irq_cpu.h> +#include <asm/mipsregs.h> +#include <asm/r4kcache.h> +#include <asm/smp-ops.h> + +#include <asm/ingenic-smp.h> + +#define read_c0_corectrl() __read_32bit_c0_register($12, 2) +#define write_c0_corectrl(val) __write_32bit_c0_register($12, 2, val) +#define read_c0_corestatus() __read_32bit_c0_register($12, 3) +#define write_c0_corestatus(val) __write_32bit_c0_register($12, 3, val) +#define read_c0_reim() __read_32bit_c0_register($12, 4) +#define write_c0_reim(val) __write_32bit_c0_register($12, 4, val) +#define read_c0_mailbox0() __read_32bit_c0_register($20, 0) +#define write_c0_mailbox0(val) __write_32bit_c0_register($20, 0, val) +#define read_c0_mailbox1() __read_32bit_c0_register($20, 1) +#define write_c0_mailbox1(val) __write_32bit_c0_register($20, 1, val) + +#define XBURST_MBOX_IRQ (MIPS_CPU_IRQ_BASE + 3) +#define CORECTRL_SWRST(cpu) BIT(cpu) +#define CORECTRL_RPC(cpu) BIT(8 + (cpu)) +#define CORESTATUS_MIRQ(cpu) BIT(cpu) +#define REIM_ENTRY GENMASK(31, 16) +#define REIM_MBOXIRQ(cpu) BIT(cpu) + +static struct clk *cpu1_clock; +static DEFINE_RAW_SPINLOCK(smp_lock); + +/* Referenced by the uncached secondary CPU reset entry. */ +unsigned long xburst_cpu_entry_sp; +unsigned long xburst_cpu_entry_gp; + +static irqreturn_t xburst_mbox_interrupt(int irq, void *dev_id) +{ + unsigned int cpu = cpu_logical_map(smp_processor_id()); + u32 action, status; + + raw_spin_lock(&smp_lock); + if (cpu == 0) { + action = read_c0_mailbox0(); + write_c0_mailbox0(0); + } else { + action = read_c0_mailbox1(); + write_c0_mailbox1(0); + } + + status = read_c0_corestatus(); + write_c0_corestatus(status & ~CORESTATUS_MIRQ(cpu)); + irq_disable_hazard(); + raw_spin_unlock(&smp_lock); + + if (action & SMP_RESCHEDULE_YOURSELF) + scheduler_ipi(); + if (action & SMP_CALL_FUNCTION) + generic_smp_call_function_interrupt(); + + return IRQ_HANDLED; +} + +static void __init xburst_smp_setup(void) +{ + struct device_node *np; + u32 entry, reim; + unsigned int cpu = 0; + u64 hwid; + + for_each_of_cpu_node(np) { + hwid = of_get_cpu_hwid(np, 0); + if (!of_device_is_available(np) || + hwid >= ARRAY_SIZE(__cpu_number_map)) + continue; + if (cpu >= nr_cpu_ids) { + of_node_put(np); + break; + } + __cpu_number_map[hwid] = cpu; + __cpu_logical_map[cpu] = hwid; + set_cpu_possible(cpu, true); + cpu++; + } + + /* Program the shared reset vector with mailbox delivery masked. */ + reim = read_c0_reim(); + reim &= ~(REIM_MBOXIRQ(0) | REIM_MBOXIRQ(1)); + write_c0_reim(reim); + write_c0_mailbox0(0); + write_c0_mailbox1(0); + write_c0_corestatus(0); + + entry = KSEG1ADDR((unsigned long)xburst_secondary_cpu_entry); + write_c0_reim((reim & ~REIM_ENTRY) | (entry & REIM_ENTRY)); +} + +static void __init xburst_prepare_cpus(unsigned int max_cpus) +{ + struct device_node *np; + u32 reim; + int ret; + + ret = request_irq(XBURST_MBOX_IRQ, xburst_mbox_interrupt, + IRQF_PERCPU | IRQF_NO_THREAD, "core mailbox", NULL); + if (ret) { + pr_err("XBurst: cannot request mailbox IRQ: %d\n", ret); + return; + } + + reim = read_c0_reim(); + write_c0_reim(reim | REIM_MBOXIRQ(0)); + set_c0_status(STATUSF_IP3); + irq_enable_hazard(); + + if (!cpu_possible(1)) + return; + + np = of_get_cpu_node(1, NULL); + cpu1_clock = of_clk_get(np, 0); + of_node_put(np); + if (IS_ERR(cpu1_clock)) { + pr_err("XBurst: cannot get CPU1 clock: %ld\n", + PTR_ERR(cpu1_clock)); + return; + } + + ret = clk_prepare(cpu1_clock); + if (ret) { + clk_put(cpu1_clock); + cpu1_clock = ERR_PTR(ret); + pr_err("XBurst: cannot prepare CPU1 clock: %d\n", ret); + } +} + +static int xburst_boot_secondary(int cpu, struct task_struct *idle) +{ + unsigned long flags; + u32 ctrl; + int ret; + + if (cpu_logical_map(cpu) != 1 || IS_ERR_OR_NULL(cpu1_clock)) + return -ENODEV; + + raw_spin_lock_irqsave(&smp_lock, flags); + ctrl = read_c0_corectrl() | CORECTRL_SWRST(1) | CORECTRL_RPC(1); + write_c0_corectrl(ctrl); + back_to_back_c0_hazard(); + + ret = clk_enable(cpu1_clock); + if (ret) + goto unlock; + + xburst_cpu_entry_sp = __KSTK_TOS(idle); + xburst_cpu_entry_gp = (unsigned long)task_thread_info(idle); + /* Publish bootstrap state before CPU1 starts using its private cache. */ + r4k_blast_dcache(); + /* Complete cache writeback before releasing reset. */ + mb(); + write_c0_corectrl(ctrl & ~CORECTRL_SWRST(1)); + back_to_back_c0_hazard(); +unlock: + raw_spin_unlock_irqrestore(&smp_lock, flags); + return ret; +} + +static void xburst_init_secondary(void) +{ + clear_c0_status(ST0_IM); + irq_disable_hazard(); +} + +static void xburst_smp_finish(void) +{ + unsigned int cpu = cpu_logical_map(smp_processor_id()); + u32 reim; + + raw_spin_lock(&smp_lock); + reim = read_c0_reim(); + write_c0_reim(reim | REIM_MBOXIRQ(cpu)); + raw_spin_unlock(&smp_lock); + + change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP2 | + STATUSF_IP1 | STATUSF_IP0); + irq_enable_hazard(); + local_irq_enable(); +} + +static void xburst_send_ipi_locked(int cpu, unsigned int action) +{ + if (cpu_logical_map(cpu) == 0) + write_c0_mailbox0(read_c0_mailbox0() | action); + else + write_c0_mailbox1(read_c0_mailbox1() | action); + back_to_back_c0_hazard(); +} + +static void xburst_send_ipi_single(int cpu, unsigned int action) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&smp_lock, flags); + xburst_send_ipi_locked(cpu, action); + raw_spin_unlock_irqrestore(&smp_lock, flags); +} + +static void xburst_send_ipi_mask(const struct cpumask *mask, unsigned int action) +{ + unsigned long flags; + int cpu; + + raw_spin_lock_irqsave(&smp_lock, flags); + for_each_cpu(cpu, mask) + xburst_send_ipi_locked(cpu, action); + raw_spin_unlock_irqrestore(&smp_lock, flags); +} + +static const struct plat_smp_ops xburst_smp_ops = { + .send_ipi_single = xburst_send_ipi_single, + .send_ipi_mask = xburst_send_ipi_mask, + .init_secondary = xburst_init_secondary, + .smp_finish = xburst_smp_finish, + .boot_secondary = xburst_boot_secondary, + .smp_setup = xburst_smp_setup, + .prepare_cpus = xburst_prepare_cpus, +}; + +int __init register_ingenic_smp_ops(void) +{ + if (!of_machine_is_compatible("ingenic,jz4780")) + return -ENODEV; + + register_smp_ops(&xburst_smp_ops); + return 0; +} diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 80e8a04a642e..46526997a4c6 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -18,6 +18,7 @@ #include <asm/cpu-type.h> #include <asm/idle.h> #include <asm/mipsregs.h> +#include <asm/r4kcache.h> /* * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, @@ -71,6 +72,23 @@ static void __cpuidle rm7k_wait_irqoff(void) " .set pop \n"); } +/* XBurst gates its private cache clock in WAIT; write back dirty data first. */ +static void __cpuidle xburst_wait_irqoff(void) +{ + unsigned long pending = read_c0_cause() & read_c0_status() & CAUSEF_IP; + + if (!need_resched() && !pending) { + r4k_blast_dcache(); + __asm__ __volatile__( + ".set push\n" + ".set mips3\n" + "sync\n" + "wait\n" + ".set pop\n" + : : : "memory"); + } +} + /* * Au1 'wait' is only useful when the 32kHz counter is used as timer, * since coreclock (and the cp0 counter) stops upon executing it. Only an @@ -156,10 +174,16 @@ void __init check_wait(void) case CPU_CAVIUM_OCTEON_PLUS: case CPU_CAVIUM_OCTEON2: case CPU_CAVIUM_OCTEON3: - case CPU_XBURST: case CPU_LOONGSON32: cpu_wait = r4k_wait; break; + case CPU_XBURST: + if (IS_ENABLED(CONFIG_MACH_JZ4780) && + IS_ENABLED(CONFIG_SMP)) + cpu_wait = xburst_wait_irqoff; + else + cpu_wait = r4k_wait; + break; case CPU_LOONGSON64: if ((c->processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) >= (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) || -- 2.53.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support 2026-11-10 4:31 ` [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support Florian Fainelli @ 2026-11-10 5:10 ` sashiko-bot 2026-11-10 15:30 ` Paul Cercueil 1 sibling, 0 replies; 13+ messages in thread From: sashiko-bot @ 2026-11-10 5:10 UTC (permalink / raw) To: Florian Fainelli; +Cc: open list:COMMON CLK FRAMEWORK Thank you for your contribution! Sashiko AI review found 6 potential issues to consider: - [High] MIPS: idle: check_wait() selects xburst_wait_irqoff() on UP XBurst SoCs - [High] MIPS: Ingenic: boot BUG_ON in mips_smp_ipi_allocate() on generic kernel - [High] MIPS: Ingenic: missing set_cpu_present() and hotplug callbacks in xburst_smp_ops - [High] MIPS: Ingenic: missing cpu_set_core() suppresses cache IPIs under MIPS_CPS - [Medium] MIPS: Ingenic: invalid wait context in xburst_boot_secondary() - [Low] MIPS: Ingenic: 64-bit generic kernel build failure in ingenic-smp -- commit 84aca91e29a4f9f60b4d407205a2e5c0ec8d50c1 Author: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> MIPS: Ingenic: Add XBurst SMP support This commit adds SMP support for the second XBurst core on the Ingenic JZ4780 using CP0 mailboxes for inter-processor interrupts, and flushes the private data cache before entering WAIT on SMP builds. Link: https://lkml.iu.edu/hypermail/linux/kernel/2005.2/03488.html Link: https://lists.openwall.net/linux-kernel/2020/05/13/1482 Link: https://lists.openwall.net/linux-kernel/2020/05/19/1099 > diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c > index 1d712eac16171..38f294887c17a 100644 > --- a/arch/mips/generic/init.c > +++ b/arch/mips/generic/init.c > @@ -13,6 +13,7 @@ > > #include <asm/bootinfo.h> > #include <asm/fw/fw.h> > +#include <asm/ingenic-smp.h> > #include <asm/irq_cpu.h> > #include <asm/machine.h> > #include <asm/mips-cps.h> > @@ -113,6 +114,8 @@ void __init device_tree_init(void) > unflatten_and_copy_device_tree(); > mips_cpc_probe(); > > + if (!register_ingenic_smp_ops()) > + return; > if (!register_cps_smp_ops()) > return; > if (!register_vsmp_smp_ops()) [Severity: High] Does registering xburst_smp_ops on a generic MIPS kernel trigger the BUG_ON() in mips_smp_ipi_allocate() during boot on JZ4780? CONFIG_MIPS_GENERIC_KERNEL selects CONFIG_MIPS_GIC and CONFIG_SYS_SUPPORTS_MULTITHREADING, which enable CONFIG_GENERIC_IRQ_IPI when CONFIG_SMP is enabled. During early initcalls, mips_smp_ipi_init() calls mips_smp_ipi_allocate() whenever num_possible_cpus() > 1, but JZ4780 uses CP0 mailbox interrupts instead of registering a DOMAIN_BUS_IPI irq_domain: arch/mips/kernel/smp.c:mips_smp_ipi_allocate() { ... if (!ipidomain) { BUG_ON(num_present_cpus() > 1); return 0; } ... } > diff --git a/arch/mips/ingenic/ingenic-smp-entry.S b/arch/mips/ingenic/ingenic-smp-entry.S > new file mode 100644 > index 0000000000000..250a0c89c9556 > --- /dev/null > +++ b/arch/mips/ingenic/ingenic-smp-entry.S > @@ -0,0 +1,54 @@ [ ... ] > + /* Invalidate both private caches before entering cached code. */ > + li t0, KSEG0 > + ori t1, t0, CACHE_SIZE > + mtc0 zero, CP0_TAGLO > + ehb > +1: cache Index_Store_Tag_I, 0(t0) > + cache Index_Store_Tag_D, 0(t0) > + addiu t0, t0, CACHE_LINESIZE > + bne t0, t1, 1b > + nop > + > + mfc0 t0, CP0_CONFIG > + li t1, ~CONF_CM_CMASK > + and t0, t0, t1 > + ori t0, t0, CONF_CM_CACHABLE_NONCOHERENT > + mtc0 t0, CP0_CONFIG > + mtc0 zero, CP0_PAGEMASK > + ehb > + > + /* CPU0 publishes these in RAM before releasing CPU1 from reset. */ > + la t0, xburst_cpu_entry_sp > + lw sp, 0(t0) > + la t0, xburst_cpu_entry_gp > + lw gp, 0(t0) > + > + la t0, smp_bootstrap > + jr t0 > + nop > +END(xburst_secondary_cpu_entry) [Severity: Low] Does this break 64-bit generic kernel builds when CONFIG_BOARD_INGENIC and CONFIG_SMP are enabled? CONFIG_BOARD_INGENIC has no dependency on CONFIG_32BIT and selects CONFIG_MACH_JZ4780, so a 64-bit CONFIG_MIPS_GENERIC_KERNEL build compiles arch/mips/ingenic/. Under CONFIG_64BIT, KSEG0 (used here) and KSEG1ADDR (used in xburst_smp_setup()) are not defined in <asm/addrspace.h>, and xburst_secondary_cpu_entry uses 32-bit la and lw instructions to load the unsigned long globals xburst_cpu_entry_sp and xburst_cpu_entry_gp. > diff --git a/arch/mips/ingenic/ingenic-smp.c b/arch/mips/ingenic/ingenic-smp.c > new file mode 100644 > index 0000000000000..3cdb953c7a871 > --- /dev/null > +++ b/arch/mips/ingenic/ingenic-smp.c > @@ -0,0 +1,247 @@ [ ... ] > +static void __init xburst_smp_setup(void) > +{ > + struct device_node *np; > + u32 entry, reim; > + unsigned int cpu = 0; > + u64 hwid; > + > + for_each_of_cpu_node(np) { > + hwid = of_get_cpu_hwid(np, 0); > + if (!of_device_is_available(np) || > + hwid >= ARRAY_SIZE(__cpu_number_map)) > + continue; > + if (cpu >= nr_cpu_ids) { > + of_node_put(np); > + break; > + } > + __cpu_number_map[hwid] = cpu; > + __cpu_logical_map[cpu] = hwid; > + set_cpu_possible(cpu, true); > + cpu++; > + } [Severity: High] Does omitting cpu_set_core() leave cpu_foreign_map empty when CONFIG_MIPS_CPS is enabled (such as in generic_defconfig)? decode_configs() only populates the core ID from EBase.CPUNum when CONFIG_MIPS_CPS is disabled: arch/mips/kernel/cpu-probe.c:decode_configs() { ... #ifndef CONFIG_MIPS_CPS if (cpu_has_mips_r2_r6) { unsigned int core; core = get_ebase_cpunum(); if (cpu_has_mipsmt) core >>= fls(core_nvpes()) - 1; cpu_set_core(c, core); } #endif } Because neither xburst_smp_setup() nor xburst_init_secondary() calls cpu_set_core(), both CPUs keep core ID 0 under CONFIG_MIPS_CPS. calculate_cpu_foreign_map() then treats CPU0 and CPU1 as SMT siblings sharing L1 caches and leaves cpu_foreign_map empty, so r4k_op_needs_ipi() returns false and cross-CPU cache flushes never send IPIs to the other core's private L1 caches. [ ... ] > +static int xburst_boot_secondary(int cpu, struct task_struct *idle) > +{ > + unsigned long flags; > + u32 ctrl; > + int ret; > + > + if (cpu_logical_map(cpu) != 1 || IS_ERR_OR_NULL(cpu1_clock)) > + return -ENODEV; > + > + raw_spin_lock_irqsave(&smp_lock, flags); > + ctrl = read_c0_corectrl() | CORECTRL_SWRST(1) | CORECTRL_RPC(1); > + write_c0_corectrl(ctrl); > + back_to_back_c0_hazard(); > + > + ret = clk_enable(cpu1_clock); > + if (ret) > + goto unlock; [Severity: Medium] Does calling clk_enable() while holding the raw spinlock smp_lock trigger an invalid wait context warning under lockdep? clk_enable() acquires the non-raw spinlock_t enable_lock in clk_enable_lock() and cgu->lock in jz4780_core1_enable(), nesting spinlock_t inside raw_spinlock_t and holding smp_lock with interrupts disabled across the register polling loop in jz4780_core1_enable(). [ ... ] > +static const struct plat_smp_ops xburst_smp_ops = { > + .send_ipi_single = xburst_send_ipi_single, > + .send_ipi_mask = xburst_send_ipi_mask, > + .init_secondary = xburst_init_secondary, > + .smp_finish = xburst_smp_finish, > + .boot_secondary = xburst_boot_secondary, > + .smp_setup = xburst_smp_setup, > + .prepare_cpus = xburst_prepare_cpus, > +}; [Severity: High] What happens when CONFIG_HOTPLUG_CPU is enabled (for example in a CONFIG_MIPS_GENERIC_KERNEL build where CONFIG_MIPS_CPS selects CONFIG_SYS_SUPPORTS_HOTPLUG_CPU)? smp_prepare_cpus() only initializes cpu_present_mask from cpu_possible_mask when CONFIG_HOTPLUG_CPU is disabled: arch/mips/kernel/smp.c:smp_prepare_cpus() { ... #ifndef CONFIG_HOTPLUG_CPU init_cpu_present(cpu_possible_mask); #endif } Because neither xburst_smp_setup() nor xburst_prepare_cpus() calls set_cpu_present(cpu, true), CPU1 is never marked present and is never brought online during boot when CONFIG_HOTPLUG_CPU is enabled. In addition, xburst_smp_ops leaves .cpu_disable and .cpu_die NULL, while __cpu_disable() and __cpu_die() in <asm/smp.h> dereference them unconditionally. > diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c > index 80e8a04a642e0..46526997a4c64 100644 > --- a/arch/mips/kernel/idle.c > +++ b/arch/mips/kernel/idle.c [ ... ] > @@ -156,10 +174,16 @@ void __init check_wait(void) > case CPU_CAVIUM_OCTEON_PLUS: > case CPU_CAVIUM_OCTEON2: > case CPU_CAVIUM_OCTEON3: > - case CPU_XBURST: > case CPU_LOONGSON32: > cpu_wait = r4k_wait; > break; > + case CPU_XBURST: > + if (IS_ENABLED(CONFIG_MACH_JZ4780) && > + IS_ENABLED(CONFIG_SMP)) > + cpu_wait = xburst_wait_irqoff; > + else > + cpu_wait = r4k_wait; > + break; [Severity: High] Does this compile-time check cause single-core XBurst SoCs to use xburst_wait_irqoff() when booted with a shared Ingenic kernel? CONFIG_MACH_INGENIC_GENERIC unconditionally selects CONFIG_MACH_JZ4780 alongside single-core XBurst SoCs such as JZ4740, JZ4725B, JZ4770, X1000 and X1830, and all of them report CPU_XBURST. When CONFIG_SMP is enabled in a multi-SoC kernel, booting on any single-core XBurst SoC selects xburst_wait_irqoff() instead of r4k_wait(). That blasts the entire L1 data cache on every idle entry and executes WAIT with local interrupts disabled (CP0_Status.IE == 0) and without the r4k_wait rollback handler, which prevents interrupts from waking MIPS32r1 XBurst cores such as JZ4740 and JZ4725B from idle. Checking num_possible_cpus() > 1 at runtime would restrict xburst_wait_irqoff() to SMP systems. -- Sashiko AI review · https://sashiko.dev/#/patchset/20261110043131.1985993-1-f.fainelli@gmail.com?part=2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support 2026-11-10 4:31 ` [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support Florian Fainelli 2026-11-10 5:10 ` sashiko-bot @ 2026-11-10 15:30 ` Paul Cercueil 1 sibling, 0 replies; 13+ messages in thread From: Paul Cercueil @ 2026-11-10 15:30 UTC (permalink / raw) To: Florian Fainelli, linux-mips Cc: 周琰杰 (Zhou Yanjie), Thomas Bogendoerfer, Paul Burton, Stephen Boyd, Brian Masney, Jerome Brunet, Jiaxun Yang, open list, open list:COMMON CLK FRAMEWORK, hns, paul Hi Florian, Le lundi 09 novembre 2026 à 20:31 -0800, Florian Fainelli a écrit : > From: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> > > Add support for the second XBurst core on the JZ4780, based on Zhou > Yanjie's 2020 series and Paul Burton's original CI20 SMP implementation. > Use the CP0 mailboxes for inter-processor interrupts. > > XBurst stops its private cache clock when executing WAIT. Write back > the data cache before entering idle so that the other core can access > data belonging to the sleeping core. > > Link: https://lkml.iu.edu/hypermail/linux/kernel/2005.2/03488.html > Link: https://lists.openwall.net/linux-kernel/2020/05/13/1482 > Link: https://lists.openwall.net/linux-kernel/2020/05/19/1099 > Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> > [florian: forward ported to latest version] > Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-by: Paul Cercueil <paul@crapouillou.net> Cheers, -Paul > --- > MAINTAINERS | 3 +- > arch/mips/Kbuild | 1 + > arch/mips/generic/init.c | 3 + > arch/mips/include/asm/ingenic-smp.h | 20 +++ > arch/mips/ingenic/Kconfig | 2 + > arch/mips/ingenic/Makefile | 5 + > arch/mips/ingenic/ingenic-smp-entry.S | 54 ++++++ > arch/mips/ingenic/ingenic-smp.c | 247 ++++++++++++++++++++++++++ > arch/mips/kernel/idle.c | 26 ++- > 9 files changed, 359 insertions(+), 2 deletions(-) > create mode 100644 arch/mips/include/asm/ingenic-smp.h > create mode 100644 arch/mips/ingenic/Makefile > create mode 100644 arch/mips/ingenic/ingenic-smp-entry.S > create mode 100644 arch/mips/ingenic/ingenic-smp.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 222b7fc2c3aa..7128df320bab 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -13150,8 +13150,9 @@ L: linux-mips@vger.kernel.org > S: Maintained > F: arch/mips/boot/dts/ingenic/ > F: arch/mips/generic/board-ingenic.c > +F: arch/mips/include/asm/ingenic-smp.h > F: arch/mips/include/asm/mach-ingenic/ > -F: arch/mips/ingenic/Kconfig > +F: arch/mips/ingenic/ > F: drivers/clk/ingenic/ > F: drivers/dma/dma-jz4780.c > F: drivers/gpu/drm/ingenic/ > diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild > index e901bf554483..4912ab80d143 100644 > --- a/arch/mips/Kbuild > +++ b/arch/mips/Kbuild > @@ -12,6 +12,7 @@ obj- := $(platform-y) > # The object files are linked as core-y files would be linked > > obj-y += generic/ > +obj-$(CONFIG_MACH_INGENIC) += ingenic/ > obj-y += kernel/ > obj-y += mm/ > obj-y += net/ > diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c > index 1d712eac1617..38f294887c17 100644 > --- a/arch/mips/generic/init.c > +++ b/arch/mips/generic/init.c > @@ -13,6 +13,7 @@ > > #include <asm/bootinfo.h> > #include <asm/fw/fw.h> > +#include <asm/ingenic-smp.h> > #include <asm/irq_cpu.h> > #include <asm/machine.h> > #include <asm/mips-cps.h> > @@ -113,6 +114,8 @@ void __init device_tree_init(void) > unflatten_and_copy_device_tree(); > mips_cpc_probe(); > > + if (!register_ingenic_smp_ops()) > + return; > if (!register_cps_smp_ops()) > return; > if (!register_vsmp_smp_ops()) > diff --git a/arch/mips/include/asm/ingenic-smp.h > b/arch/mips/include/asm/ingenic-smp.h > new file mode 100644 > index 000000000000..ea81c333820d > --- /dev/null > +++ b/arch/mips/include/asm/ingenic-smp.h > @@ -0,0 +1,20 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* Copyright (C) 2013 Paul Burton <paulburton@kernel.org> */ > +#ifndef __ASM_INGENIC_SMP_H__ > +#define __ASM_INGENIC_SMP_H__ > + > +#include <linux/errno.h> > +#include <linux/init.h> > +#include <linux/kconfig.h> > + > +#if defined(CONFIG_MACH_JZ4780) && defined(CONFIG_SMP) > +int __init register_ingenic_smp_ops(void); > +void xburst_secondary_cpu_entry(void); > +#else > +static inline int register_ingenic_smp_ops(void) > +{ > + return -ENODEV; > +} > +#endif > + > +#endif /* __ASM_INGENIC_SMP_H__ */ > diff --git a/arch/mips/ingenic/Kconfig b/arch/mips/ingenic/Kconfig > index f595b339a4b8..583f8d3651df 100644 > --- a/arch/mips/ingenic/Kconfig > +++ b/arch/mips/ingenic/Kconfig > @@ -64,6 +64,8 @@ config MACH_JZ4780 > select MIPS_CPU_SCACHE > select SYS_HAS_CPU_MIPS32_R2 > select SYS_SUPPORTS_HIGHMEM > + select SYS_SUPPORTS_SMP > + select SMP_UP if SMP > > config MACH_X1000 > bool > diff --git a/arch/mips/ingenic/Makefile b/arch/mips/ingenic/Makefile > new file mode 100644 > index 000000000000..fc3b1bf1f25a > --- /dev/null > +++ b/arch/mips/ingenic/Makefile > @@ -0,0 +1,5 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +ifdef CONFIG_SMP > +obj-$(CONFIG_MACH_JZ4780) += ingenic-smp.o ingenic-smp-entry.o > +endif > diff --git a/arch/mips/ingenic/ingenic-smp-entry.S > b/arch/mips/ingenic/ingenic-smp-entry.S > new file mode 100644 > index 000000000000..250a0c89c955 > --- /dev/null > +++ b/arch/mips/ingenic/ingenic-smp-entry.S > @@ -0,0 +1,54 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * Copyright (C) 2013 Paul Burton <paulburton@kernel.org> > + * XBurst secondary CPU reset entry > + */ > + > +#include <asm/addrspace.h> > +#include <asm/asm.h> > +#include <asm/asmmacro.h> > +#include <asm/cacheops.h> > +#include <asm/mipsregs.h> > + > +#define CACHE_SIZE (32 * 1024) > +#define CACHE_LINESIZE 32 > + > + /* The CP0 REIM register only stores the upper 16 address bits. */ > + .section .text.smp-entry, "ax" > + .balign 0x10000 > + .set noreorder > +LEAF(xburst_secondary_cpu_entry) > + mtc0 zero, CP0_CAUSE > + li t0, ST0_CU0 > + mtc0 t0, CP0_STATUS > + ehb > + > + /* Invalidate both private caches before entering cached code. */ > + li t0, KSEG0 > + ori t1, t0, CACHE_SIZE > + mtc0 zero, CP0_TAGLO > + ehb > +1: cache Index_Store_Tag_I, 0(t0) > + cache Index_Store_Tag_D, 0(t0) > + addiu t0, t0, CACHE_LINESIZE > + bne t0, t1, 1b > + nop > + > + mfc0 t0, CP0_CONFIG > + li t1, ~CONF_CM_CMASK > + and t0, t0, t1 > + ori t0, t0, CONF_CM_CACHABLE_NONCOHERENT > + mtc0 t0, CP0_CONFIG > + mtc0 zero, CP0_PAGEMASK > + ehb > + > + /* CPU0 publishes these in RAM before releasing CPU1 from reset. */ > + la t0, xburst_cpu_entry_sp > + lw sp, 0(t0) > + la t0, xburst_cpu_entry_gp > + lw gp, 0(t0) > + > + la t0, smp_bootstrap > + jr t0 > + nop > +END(xburst_secondary_cpu_entry) > diff --git a/arch/mips/ingenic/ingenic-smp.c b/arch/mips/ingenic/ingenic-smp.c > new file mode 100644 > index 000000000000..3cdb953c7a87 > --- /dev/null > +++ b/arch/mips/ingenic/ingenic-smp.c > @@ -0,0 +1,247 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * XBurst SMP support, based on Paul Burton's CI20 implementation and > + * Zhou Yanjie's 2020 JZ4780 SMP series. > + * Copyright (C) 2013 Paul Burton <paulburton@kernel.org> > + */ > + > +#include <linux/clk.h> > +#include <linux/cpu.h> > +#include <linux/interrupt.h> > +#include <linux/of.h> > +#include <linux/of_clk.h> > +#include <linux/sched/task_stack.h> > +#include <linux/smp.h> > + > +#include <asm/addrspace.h> > +#include <asm/irq_cpu.h> > +#include <asm/mipsregs.h> > +#include <asm/r4kcache.h> > +#include <asm/smp-ops.h> > + > +#include <asm/ingenic-smp.h> > + > +#define read_c0_corectrl() __read_32bit_c0_register($12, 2) > +#define write_c0_corectrl(val) __write_32bit_c0_register($12, 2, val) > +#define read_c0_corestatus() __read_32bit_c0_register($12, 3) > +#define write_c0_corestatus(val) __write_32bit_c0_register($12, 3, > val) > +#define read_c0_reim() __read_32bit_c0_register($12, 4) > +#define write_c0_reim(val) __write_32bit_c0_register($12, 4, val) > +#define read_c0_mailbox0() __read_32bit_c0_register($20, 0) > +#define write_c0_mailbox0(val) __write_32bit_c0_register($20, 0, val) > +#define read_c0_mailbox1() __read_32bit_c0_register($20, 1) > +#define write_c0_mailbox1(val) __write_32bit_c0_register($20, 1, val) > + > +#define XBURST_MBOX_IRQ (MIPS_CPU_IRQ_BASE + 3) > +#define CORECTRL_SWRST(cpu) BIT(cpu) > +#define CORECTRL_RPC(cpu) BIT(8 + (cpu)) > +#define CORESTATUS_MIRQ(cpu) BIT(cpu) > +#define REIM_ENTRY GENMASK(31, 16) > +#define REIM_MBOXIRQ(cpu) BIT(cpu) > + > +static struct clk *cpu1_clock; > +static DEFINE_RAW_SPINLOCK(smp_lock); > + > +/* Referenced by the uncached secondary CPU reset entry. */ > +unsigned long xburst_cpu_entry_sp; > +unsigned long xburst_cpu_entry_gp; > + > +static irqreturn_t xburst_mbox_interrupt(int irq, void *dev_id) > +{ > + unsigned int cpu = cpu_logical_map(smp_processor_id()); > + u32 action, status; > + > + raw_spin_lock(&smp_lock); > + if (cpu == 0) { > + action = read_c0_mailbox0(); > + write_c0_mailbox0(0); > + } else { > + action = read_c0_mailbox1(); > + write_c0_mailbox1(0); > + } > + > + status = read_c0_corestatus(); > + write_c0_corestatus(status & ~CORESTATUS_MIRQ(cpu)); > + irq_disable_hazard(); > + raw_spin_unlock(&smp_lock); > + > + if (action & SMP_RESCHEDULE_YOURSELF) > + scheduler_ipi(); > + if (action & SMP_CALL_FUNCTION) > + generic_smp_call_function_interrupt(); > + > + return IRQ_HANDLED; > +} > + > +static void __init xburst_smp_setup(void) > +{ > + struct device_node *np; > + u32 entry, reim; > + unsigned int cpu = 0; > + u64 hwid; > + > + for_each_of_cpu_node(np) { > + hwid = of_get_cpu_hwid(np, 0); > + if (!of_device_is_available(np) || > + hwid >= ARRAY_SIZE(__cpu_number_map)) > + continue; > + if (cpu >= nr_cpu_ids) { > + of_node_put(np); > + break; > + } > + __cpu_number_map[hwid] = cpu; > + __cpu_logical_map[cpu] = hwid; > + set_cpu_possible(cpu, true); > + cpu++; > + } > + > + /* Program the shared reset vector with mailbox delivery masked. */ > + reim = read_c0_reim(); > + reim &= ~(REIM_MBOXIRQ(0) | REIM_MBOXIRQ(1)); > + write_c0_reim(reim); > + write_c0_mailbox0(0); > + write_c0_mailbox1(0); > + write_c0_corestatus(0); > + > + entry = KSEG1ADDR((unsigned long)xburst_secondary_cpu_entry); > + write_c0_reim((reim & ~REIM_ENTRY) | (entry & REIM_ENTRY)); > +} > + > +static void __init xburst_prepare_cpus(unsigned int max_cpus) > +{ > + struct device_node *np; > + u32 reim; > + int ret; > + > + ret = request_irq(XBURST_MBOX_IRQ, xburst_mbox_interrupt, > + IRQF_PERCPU | IRQF_NO_THREAD, "core mailbox", > NULL); > + if (ret) { > + pr_err("XBurst: cannot request mailbox IRQ: %d\n", ret); > + return; > + } > + > + reim = read_c0_reim(); > + write_c0_reim(reim | REIM_MBOXIRQ(0)); > + set_c0_status(STATUSF_IP3); > + irq_enable_hazard(); > + > + if (!cpu_possible(1)) > + return; > + > + np = of_get_cpu_node(1, NULL); > + cpu1_clock = of_clk_get(np, 0); > + of_node_put(np); > + if (IS_ERR(cpu1_clock)) { > + pr_err("XBurst: cannot get CPU1 clock: %ld\n", > + PTR_ERR(cpu1_clock)); > + return; > + } > + > + ret = clk_prepare(cpu1_clock); > + if (ret) { > + clk_put(cpu1_clock); > + cpu1_clock = ERR_PTR(ret); > + pr_err("XBurst: cannot prepare CPU1 clock: %d\n", ret); > + } > +} > + > +static int xburst_boot_secondary(int cpu, struct task_struct *idle) > +{ > + unsigned long flags; > + u32 ctrl; > + int ret; > + > + if (cpu_logical_map(cpu) != 1 || IS_ERR_OR_NULL(cpu1_clock)) > + return -ENODEV; > + > + raw_spin_lock_irqsave(&smp_lock, flags); > + ctrl = read_c0_corectrl() | CORECTRL_SWRST(1) | CORECTRL_RPC(1); > + write_c0_corectrl(ctrl); > + back_to_back_c0_hazard(); > + > + ret = clk_enable(cpu1_clock); > + if (ret) > + goto unlock; > + > + xburst_cpu_entry_sp = __KSTK_TOS(idle); > + xburst_cpu_entry_gp = (unsigned long)task_thread_info(idle); > + /* Publish bootstrap state before CPU1 starts using its private > cache. */ > + r4k_blast_dcache(); > + /* Complete cache writeback before releasing reset. */ > + mb(); > + write_c0_corectrl(ctrl & ~CORECTRL_SWRST(1)); > + back_to_back_c0_hazard(); > +unlock: > + raw_spin_unlock_irqrestore(&smp_lock, flags); > + return ret; > +} > + > +static void xburst_init_secondary(void) > +{ > + clear_c0_status(ST0_IM); > + irq_disable_hazard(); > +} > + > +static void xburst_smp_finish(void) > +{ > + unsigned int cpu = cpu_logical_map(smp_processor_id()); > + u32 reim; > + > + raw_spin_lock(&smp_lock); > + reim = read_c0_reim(); > + write_c0_reim(reim | REIM_MBOXIRQ(cpu)); > + raw_spin_unlock(&smp_lock); > + > + change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP2 | > + STATUSF_IP1 | STATUSF_IP0); > + irq_enable_hazard(); > + local_irq_enable(); > +} > + > +static void xburst_send_ipi_locked(int cpu, unsigned int action) > +{ > + if (cpu_logical_map(cpu) == 0) > + write_c0_mailbox0(read_c0_mailbox0() | action); > + else > + write_c0_mailbox1(read_c0_mailbox1() | action); > + back_to_back_c0_hazard(); > +} > + > +static void xburst_send_ipi_single(int cpu, unsigned int action) > +{ > + unsigned long flags; > + > + raw_spin_lock_irqsave(&smp_lock, flags); > + xburst_send_ipi_locked(cpu, action); > + raw_spin_unlock_irqrestore(&smp_lock, flags); > +} > + > +static void xburst_send_ipi_mask(const struct cpumask *mask, unsigned int > action) > +{ > + unsigned long flags; > + int cpu; > + > + raw_spin_lock_irqsave(&smp_lock, flags); > + for_each_cpu(cpu, mask) > + xburst_send_ipi_locked(cpu, action); > + raw_spin_unlock_irqrestore(&smp_lock, flags); > +} > + > +static const struct plat_smp_ops xburst_smp_ops = { > + .send_ipi_single = xburst_send_ipi_single, > + .send_ipi_mask = xburst_send_ipi_mask, > + .init_secondary = xburst_init_secondary, > + .smp_finish = xburst_smp_finish, > + .boot_secondary = xburst_boot_secondary, > + .smp_setup = xburst_smp_setup, > + .prepare_cpus = xburst_prepare_cpus, > +}; > + > +int __init register_ingenic_smp_ops(void) > +{ > + if (!of_machine_is_compatible("ingenic,jz4780")) > + return -ENODEV; > + > + register_smp_ops(&xburst_smp_ops); > + return 0; > +} > diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c > index 80e8a04a642e..46526997a4c6 100644 > --- a/arch/mips/kernel/idle.c > +++ b/arch/mips/kernel/idle.c > @@ -18,6 +18,7 @@ > #include <asm/cpu-type.h> > #include <asm/idle.h> > #include <asm/mipsregs.h> > +#include <asm/r4kcache.h> > > /* > * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, > @@ -71,6 +72,23 @@ static void __cpuidle rm7k_wait_irqoff(void) > " .set pop \n"); > } > > +/* XBurst gates its private cache clock in WAIT; write back dirty data first. > */ > +static void __cpuidle xburst_wait_irqoff(void) > +{ > + unsigned long pending = read_c0_cause() & read_c0_status() & > CAUSEF_IP; > + > + if (!need_resched() && !pending) { > + r4k_blast_dcache(); > + __asm__ __volatile__( > + ".set push\n" > + ".set mips3\n" > + "sync\n" > + "wait\n" > + ".set pop\n" > + : : : "memory"); > + } > +} > + > /* > * Au1 'wait' is only useful when the 32kHz counter is used as timer, > * since coreclock (and the cp0 counter) stops upon executing it. Only an > @@ -156,10 +174,16 @@ void __init check_wait(void) > case CPU_CAVIUM_OCTEON_PLUS: > case CPU_CAVIUM_OCTEON2: > case CPU_CAVIUM_OCTEON3: > - case CPU_XBURST: > case CPU_LOONGSON32: > cpu_wait = r4k_wait; > break; > + case CPU_XBURST: > + if (IS_ENABLED(CONFIG_MACH_JZ4780) && > + IS_ENABLED(CONFIG_SMP)) > + cpu_wait = xburst_wait_irqoff; > + else > + cpu_wait = r4k_wait; > + break; > case CPU_LOONGSON64: > if ((c->processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) >= > (PRID_IMP_LOONGSON_64C | > PRID_REV_LOONGSON3A_R2_0) || ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs 2026-11-10 4:31 [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli 2026-11-10 4:31 ` [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically Florian Fainelli 2026-11-10 4:31 ` [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support Florian Fainelli @ 2026-11-10 4:31 ` Florian Fainelli 2026-11-10 5:32 ` sashiko-bot 2026-11-10 15:31 ` Paul Cercueil 2026-11-10 15:44 ` [PATCH v2 0/3] " Paul Cercueil 3 siblings, 2 replies; 13+ messages in thread From: Florian Fainelli @ 2026-11-10 4:31 UTC (permalink / raw) To: linux-mips Cc: 周琰杰 (Zhou Yanjie), Florian Fainelli, Thomas Bogendoerfer, Paul Burton, Paul Cercueil, Stephen Boyd, Brian Masney, Jerome Brunet, Jiaxun Yang, open list, open list:COMMON CLK FRAMEWORK, hns, paul From: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> Enable both JZ4780 cores now that the generic Ingenic platform provides secondary CPU reset and mailbox support. The existing device tree already reserves TCU channels for both per-CPU clock events. Link: https://lists.openwall.net/linux-kernel/2020/05/19/739 Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> --- arch/mips/configs/ci20_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index 90536cab417e..09d65094b1bd 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig @@ -22,6 +22,8 @@ CONFIG_EXPERT=y CONFIG_MACH_INGENIC_SOC=y CONFIG_JZ4780_CI20=y CONFIG_HIGHMEM=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2 CONFIG_HZ_100=y # CONFIG_SUSPEND is not set # CONFIG_SECCOMP is not set -- 2.53.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs 2026-11-10 4:31 ` [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli @ 2026-11-10 5:32 ` sashiko-bot 2026-11-10 15:31 ` Paul Cercueil 1 sibling, 0 replies; 13+ messages in thread From: sashiko-bot @ 2026-11-10 5:32 UTC (permalink / raw) To: Florian Fainelli; +Cc: open list:COMMON CLK FRAMEWORK Thank you for your contribution! Sashiko AI review found 4 potential issues to consider: - [High] mips: ingenic: invalid lock nesting in xburst_boot_secondary() - [High] mips: ingenic: boot BUG_ON in mips_smp_ipi_allocate() and missing present mask - [High] mips: ingenic: missing cpu_set_core() skips cache IPIs under CONFIG_MIPS_CPS - [Low] mips: ingenic: 64-bit build failure in xburst_smp_setup() and entry asm -- commit 80faf5187246f2a8b8c7ef1db1522ec3cdf520d4 Author: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> MIPS: CI20: Enable SMP with two CPUs This commit enables CONFIG_SMP=y and sets CONFIG_NR_CPUS=2 in ci20_defconfig to use both cores of the JZ4780 SoC. Link: https://lists.openwall.net/linux-kernel/2020/05/19/739 > diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig > index 90536cab417ee..09d65094b1bd2 100644 > --- a/arch/mips/configs/ci20_defconfig > +++ b/arch/mips/configs/ci20_defconfig > @@ -22,6 +22,8 @@ CONFIG_EXPERT=y > CONFIG_MACH_INGENIC_SOC=y > CONFIG_JZ4780_CI20=y > CONFIG_HIGHMEM=y > +CONFIG_SMP=y > +CONFIG_NR_CPUS=2 [Severity: High] Does xburst_boot_secondary() acquire non-raw spinlocks while holding the raw_spinlock_t smp_lock? arch/mips/ingenic/ingenic-smp.c:xburst_boot_secondary() { ... raw_spin_lock_irqsave(&smp_lock, flags); ctrl = read_c0_corectrl() | CORECTRL_SWRST(1) | CORECTRL_RPC(1); write_c0_corectrl(ctrl); back_to_back_c0_hazard(); ret = clk_enable(cpu1_clock); ... } When bringing up CPU1 via smp_init() -> cpu_up(1) -> xburst_boot_secondary(), clk_enable() acquires the non-raw spinlock_t enable_lock in clk_enable_lock() and cgu->lock in jz4780_core1_enable() while smp_lock is held. This triggers an invalid wait context lockdep BUG under CONFIG_PROVE_LOCKING, sleeps in atomic context on PREEMPT_RT kernels, and holds smp_lock with interrupts disabled across the 5000 us busy-poll loop in jz4780_core1_enable(). [Severity: High] Does booting a generic MIPS SMP kernel (CONFIG_MIPS_GENERIC_KERNEL=y, CONFIG_BOARD_INGENIC=y, CONFIG_SMP=y) on JZ4780 either leave CPU1 offline or hit BUG_ON(num_present_cpus() > 1) in mips_smp_ipi_allocate()? xburst_smp_setup() only calls set_cpu_possible(cpu, true), and smp_prepare_cpus() only runs init_cpu_present(cpu_possible_mask) when CONFIG_HOTPLUG_CPU is disabled. When CONFIG_HOTPLUG_CPU=y (such as in generic_defconfig), CPU1 is never marked present in cpu_present_mask and is never brought up. Furthermore, CONFIG_MIPS_GENERIC_KERNEL selects CONFIG_MIPS_GIC, which selects CONFIG_GENERIC_IRQ_IPI when CONFIG_SMP=y. During boot, mips_smp_ipi_init() calls mips_smp_ipi_allocate(cpu_possible_mask), where ipidomain is NULL because JZ4780 uses its own mailbox IPI handlers instead of registering a DOMAIN_BUS_IPI irq_domain: arch/mips/kernel/smp.c:mips_smp_ipi_allocate() { ... if (!ipidomain) { BUG_ON(num_present_cpus() > 1); return 0; } ... } Whenever CPU1 is marked present (for example with CONFIG_HOTPLUG_CPU=n), this triggers a kernel panic at boot. [Severity: High] Does xburst_smp_setup() leave both JZ4780 cores with core ID 0 when CONFIG_MIPS_CPS=y, causing r4k_on_each_cpu() to skip cross-CPU cache flush IPIs? decode_configs() in arch/mips/kernel/cpu-probe.c only calls cpu_set_core() when CONFIG_MIPS_CPS is disabled, and neither xburst_smp_setup() nor xburst_init_secondary() calls cpu_set_core(). Under CONFIG_MIPS_CPS=y (such as in generic_defconfig), both CPU0 and CPU1 retain core ID 0, so cpus_are_siblings(0, 1) returns true and calculate_cpu_foreign_map() leaves cpu_foreign_map[0] empty. r4k_op_needs_ipi() then returns false and skips all cross-CPU L1 I-cache and D-cache flush IPIs between Core 0 and Core 1, corrupting memory and instructions across their non-coherent L1 caches. [Severity: Low] Does building a 64-bit generic MIPS SMP kernel (CONFIG_MIPS_GENERIC_KERNEL=y, CONFIG_64BIT=y, CONFIG_BOARD_INGENIC=y, CONFIG_SMP=y) fail in arch/mips/ingenic/ingenic-smp.c and arch/mips/ingenic/ingenic-smp-entry.S? CONFIG_BOARD_INGENIC can be enabled on 64-bit generic kernels and selects CONFIG_MACH_JZ4780 and CONFIG_SYS_SUPPORTS_SMP. When CONFIG_64BIT=y, KSEG1ADDR and KSEG0 are not defined in arch/mips/include/asm/addrspace.h, so xburst_smp_setup() fails to compile at KSEG1ADDR(), and xburst_secondary_cpu_entry fails to assemble on KSEG0 as well as the 32-bit la and lw instructions used on 64-bit pointers and unsigned long symbols. -- Sashiko AI review · https://sashiko.dev/#/patchset/20261110043131.1985993-1-f.fainelli@gmail.com?part=3 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs 2026-11-10 4:31 ` [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli 2026-11-10 5:32 ` sashiko-bot @ 2026-11-10 15:31 ` Paul Cercueil 1 sibling, 0 replies; 13+ messages in thread From: Paul Cercueil @ 2026-11-10 15:31 UTC (permalink / raw) To: Florian Fainelli, linux-mips Cc: 周琰杰 (Zhou Yanjie), Thomas Bogendoerfer, Paul Burton, Stephen Boyd, Brian Masney, Jerome Brunet, Jiaxun Yang, open list, open list:COMMON CLK FRAMEWORK, hns, paul Le lundi 09 novembre 2026 à 20:31 -0800, Florian Fainelli a écrit : > From: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> > > Enable both JZ4780 cores now that the generic Ingenic platform provides > secondary CPU reset and mailbox support. The existing device tree > already reserves TCU channels for both per-CPU clock events. > > Link: https://lists.openwall.net/linux-kernel/2020/05/19/739 > Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> > Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-by: Paul Cercueil <paul@crapouillou.net> Cheers, -Paul > --- > arch/mips/configs/ci20_defconfig | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/arch/mips/configs/ci20_defconfig > b/arch/mips/configs/ci20_defconfig > index 90536cab417e..09d65094b1bd 100644 > --- a/arch/mips/configs/ci20_defconfig > +++ b/arch/mips/configs/ci20_defconfig > @@ -22,6 +22,8 @@ CONFIG_EXPERT=y > CONFIG_MACH_INGENIC_SOC=y > CONFIG_JZ4780_CI20=y > CONFIG_HIGHMEM=y > +CONFIG_SMP=y > +CONFIG_NR_CPUS=2 > CONFIG_HZ_100=y > # CONFIG_SUSPEND is not set > # CONFIG_SECCOMP is not set ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs 2026-11-10 4:31 [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli ` (2 preceding siblings ...) 2026-11-10 4:31 ` [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli @ 2026-11-10 15:44 ` Paul Cercueil 2026-11-10 17:14 ` Florian Fainelli 3 siblings, 1 reply; 13+ messages in thread From: Paul Cercueil @ 2026-11-10 15:44 UTC (permalink / raw) To: Florian Fainelli, linux-mips Cc: Thomas Bogendoerfer, Paul Burton, Stephen Boyd, Brian Masney, Jerome Brunet, 周琰杰 (Zhou Yanjie), Jiaxun Yang, open list, open list:COMMON CLK FRAMEWORK, hns, paul Hi Florian, Le lundi 09 novembre 2026 à 20:31 -0800, Florian Fainelli a écrit : > This patch series resurrects SMP support for the CI20 board. This was > submitted back in 2020 by Zhou Yanjie. > > Changes in v2: > > • Moved SMP sources to arch/mips/ingenic/ and the header to > arch/mips/include/asm/ > • Removed CONFIG_MIPS_INGENIC_SMP, using CONFIG_MACH_JZ4780 and CONFIG_SMP > directly > • Renamed JZ4780-specific SMP symbols to XBurst names > • Changed CPU enumeration to assign consecutive logical IDs and removed the > explicit two-core limit > • Changed mailbox IRQ allocation failure from panic to logging and returning > • Shortened commit descriptions, removed Codex attribution, and adjusted > source credits and sign-offs > • Kept the clock polling patch and CI20 defconfig changes unchanged, > added Paul's R-b for patch #1 > • Updated the kernel baseline to include additional upstream fixes You should also have a changelog per-patch, in each patch's header. Your patch [1/3] has a Fixes: tag but does not Cc stable@vger.kernel.org, so you'll have to send a v3. I reviewed [2/3] and it looks good to me, but I'm a bit concerned about Nikolaus' reported issue. Thomas, if you can wait a few days, I can test it on my CI20 and if it works report back with a Tested-by: tag. Cheers, -Paul > > Florian Fainelli (1): > clk: ingenic: Poll JZ4780 CPU1 power status atomically > > 周琰杰 (Zhou Yanjie) (2): > MIPS: Ingenic: Add XBurst SMP support > MIPS: CI20: Enable SMP with two CPUs > > MAINTAINERS | 3 +- > arch/mips/Kbuild | 1 + > arch/mips/configs/ci20_defconfig | 2 + > arch/mips/generic/init.c | 3 + > arch/mips/include/asm/ingenic-smp.h | 20 +++ > arch/mips/ingenic/Kconfig | 2 + > arch/mips/ingenic/Makefile | 5 + > arch/mips/ingenic/ingenic-smp-entry.S | 54 ++++++ > arch/mips/ingenic/ingenic-smp.c | 247 ++++++++++++++++++++++++++ > arch/mips/kernel/idle.c | 26 ++- > drivers/clk/ingenic/jz4780-cgu.c | 2 +- > 11 files changed, 362 insertions(+), 3 deletions(-) > create mode 100644 arch/mips/include/asm/ingenic-smp.h > create mode 100644 arch/mips/ingenic/Makefile > create mode 100644 arch/mips/ingenic/ingenic-smp-entry.S > create mode 100644 arch/mips/ingenic/ingenic-smp.c ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs 2026-11-10 15:44 ` [PATCH v2 0/3] " Paul Cercueil @ 2026-11-10 17:14 ` Florian Fainelli 2026-11-10 18:11 ` Paul Cercueil 0 siblings, 1 reply; 13+ messages in thread From: Florian Fainelli @ 2026-11-10 17:14 UTC (permalink / raw) To: Paul Cercueil, linux-mips Cc: Thomas Bogendoerfer, Paul Burton, Stephen Boyd, Brian Masney, Jerome Brunet, 周琰杰 (Zhou Yanjie), Jiaxun Yang, open list, open list:COMMON CLK FRAMEWORK, hns, paul On 11/10/26 07:44, Paul Cercueil wrote: > Hi Florian, > > Le lundi 09 novembre 2026 à 20:31 -0800, Florian Fainelli a écrit : >> This patch series resurrects SMP support for the CI20 board. This was >> submitted back in 2020 by Zhou Yanjie. >> >> Changes in v2: >> >> • Moved SMP sources to arch/mips/ingenic/ and the header to >> arch/mips/include/asm/ >> • Removed CONFIG_MIPS_INGENIC_SMP, using CONFIG_MACH_JZ4780 and CONFIG_SMP >> directly >> • Renamed JZ4780-specific SMP symbols to XBurst names >> • Changed CPU enumeration to assign consecutive logical IDs and removed the >> explicit two-core limit >> • Changed mailbox IRQ allocation failure from panic to logging and returning >> • Shortened commit descriptions, removed Codex attribution, and adjusted >> source credits and sign-offs >> • Kept the clock polling patch and CI20 defconfig changes unchanged, >> added Paul's R-b for patch #1 >> • Updated the kernel baseline to include additional upstream fixes > > You should also have a changelog per-patch, in each patch's header. This seems to vary on per-subsystem basis, for netdev where I contribute the vast majority of the time, putting the changelog in the cover letter works, but I will do it on a per-patch basis next time. > > Your patch [1/3] has a Fixes: tag but does not Cc stable@vger.kernel.org, so > you'll have to send a v3. > > I reviewed [2/3] and it looks good to me, but I'm a bit concerned about > Nikolaus' reported issue. > > Thomas, if you can wait a few days, I can test it on my CI20 and if it works > report back with a Tested-by: tag. Thanks Paul, yes please do test it because I could not reproduce what Nikolaus reported, that makes me think there must be additional configuration options and/or patches being carried that could be responsible. -- Florian ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs 2026-11-10 17:14 ` Florian Fainelli @ 2026-11-10 18:11 ` Paul Cercueil 0 siblings, 0 replies; 13+ messages in thread From: Paul Cercueil @ 2026-11-10 18:11 UTC (permalink / raw) To: Florian Fainelli, linux-mips Cc: Thomas Bogendoerfer, Paul Burton, Stephen Boyd, Brian Masney, Jerome Brunet, 周琰杰 (Zhou Yanjie), Jiaxun Yang, open list, open list:COMMON CLK FRAMEWORK, hns, paul Hi, Le mardi 10 novembre 2026 à 09:14 -0800, Florian Fainelli a écrit : > On 11/10/26 07:44, Paul Cercueil wrote: > > Hi Florian, > > > > Le lundi 09 novembre 2026 à 20:31 -0800, Florian Fainelli a écrit : > > > This patch series resurrects SMP support for the CI20 board. This > > > was > > > submitted back in 2020 by Zhou Yanjie. > > > > > > Changes in v2: > > > > > > • Moved SMP sources to arch/mips/ingenic/ and the header to > > > arch/mips/include/asm/ > > > • Removed CONFIG_MIPS_INGENIC_SMP, using CONFIG_MACH_JZ4780 and > > > CONFIG_SMP > > > directly > > > • Renamed JZ4780-specific SMP symbols to XBurst names > > > • Changed CPU enumeration to assign consecutive logical IDs and > > > removed the > > > explicit two-core limit > > > • Changed mailbox IRQ allocation failure from panic to logging > > > and returning > > > • Shortened commit descriptions, removed Codex attribution, and > > > adjusted > > > source credits and sign-offs > > > • Kept the clock polling patch and CI20 defconfig changes > > > unchanged, > > > added Paul's R-b for patch #1 > > > • Updated the kernel baseline to include additional upstream > > > fixes > > > > You should also have a changelog per-patch, in each patch's header. > > This seems to vary on per-subsystem basis, for netdev where I > contribute > the vast majority of the time, putting the changelog in the cover > letter > works, but I will do it on a per-patch basis next time. > > > > > Your patch [1/3] has a Fixes: tag but does not Cc > > stable@vger.kernel.org, so > > you'll have to send a v3. > > > > I reviewed [2/3] and it looks good to me, but I'm a bit concerned > > about > > Nikolaus' reported issue. > > > > Thomas, if you can wait a few days, I can test it on my CI20 and if > > it works > > report back with a Tested-by: tag. > > Thanks Paul, yes please do test it because I could not reproduce what > Nikolaus reported, that makes me think there must be additional > configuration options and/or patches being carried that could be > responsible. Tested right now on my CI20, with just this patchset on top of 7.4-rc2. It works fine. So: Tested-by: Paul Cercueil <paul@crapouillou.net> For the series. Best regards, -Paul ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-11-11 19:21 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-10 4:31 [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli 2026-11-10 4:31 ` [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically Florian Fainelli 2026-11-11 18:41 ` Brian Masney 2026-11-11 19:21 ` Florian Fainelli 2026-11-10 4:31 ` [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support Florian Fainelli 2026-11-10 5:10 ` sashiko-bot 2026-11-10 15:30 ` Paul Cercueil 2026-11-10 4:31 ` [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli 2026-11-10 5:32 ` sashiko-bot 2026-11-10 15:31 ` Paul Cercueil 2026-11-10 15:44 ` [PATCH v2 0/3] " Paul Cercueil 2026-11-10 17:14 ` Florian Fainelli 2026-11-10 18:11 ` Paul Cercueil
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox