Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4a987db authored by Huacai Chen's avatar Huacai Chen Committed by Ralf Baechle
Browse files

MIPS: Loongson 3: Add CPU hotplug support



Tips of Loongson's CPU hotplug:
1, To fully shutdown a core in Loongson 3, the target core should go to
   CKSEG1 and flush all L1 cache entries at first. Then, another core
   (usually Core 0) can safely disable the clock of the target core. So
   play_dead() call loongson3_play_dead() via CKSEG1 (both uncached and
   unmmaped).
2, The default clocksource of Loongson is MIPS. Since clock source is a
   global device, timekeeping need the CP0' Count registers of each core
   be synchronous. Thus, when a core is up, we use a SMP_ASK_C0COUNT IPI
   to ask Core-0's Count.

Signed-off-by: default avatarHuacai Chen <chenhc@lemote.com>
Signed-off-by: default avatarHongliang Tao <taohl@lemote.com>
Signed-off-by: default avatarHua Yan <yanh@lemote.com>
Tested-by: default avatarAlex Smith <alex.smith@imgtec.com>
Reviewed-by: default avatarAlex Smith <alex.smith@imgtec.com>
Cc: John Crispin <john@phrozen.org>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: linux-mips@linux-mips.org
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/6639


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 300459d5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@

#endif

extern void fixup_irqs(void);
extern void loongson3_ipi_interrupt(struct pt_regs *regs);

#include_next <irq.h>
+3 −3
Original line number Diff line number Diff line
@@ -249,6 +249,9 @@ static inline void do_perfcnt_IRQ(void)
#define LOONGSON_PXARB_CFG		LOONGSON_REG(LOONGSON_REGBASE + 0x68)
#define LOONGSON_PXARB_STATUS		LOONGSON_REG(LOONGSON_REGBASE + 0x6c)

/* Chip Config */
#define LOONGSON_CHIPCFG0		LOONGSON_REG(LOONGSON_REGBASE + 0x80)

/* pcimap */

#define LOONGSON_PCIMAP_PCIMAP_LO0	0x0000003f
@@ -264,9 +267,6 @@ static inline void do_perfcnt_IRQ(void)
#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
#include <linux/cpufreq.h>
extern struct cpufreq_frequency_table loongson2_clockmod_table[];

/* Chip Config */
#define LOONGSON_CHIPCFG0		LOONGSON_REG(LOONGSON_REGBASE + 0x80)
#endif

/*
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ extern int __cpu_logical_map[NR_CPUS];
#define SMP_ICACHE_FLUSH	0x4
/* Used by kexec crashdump to save all cpu's state */
#define SMP_DUMP		0x8
#define SMP_ASK_C0COUNT		0x10

extern volatile cpumask_t cpu_callin_map;

+1 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ config LEMOTE_MACH3A
	select SYS_HAS_CPU_LOONGSON3
	select SYS_HAS_EARLY_PRINTK
	select SYS_SUPPORTS_SMP
	select SYS_SUPPORTS_HOTPLUG_CPU
	select SYS_SUPPORTS_64BIT_KERNEL
	select SYS_SUPPORTS_HIGHMEM
	select SYS_SUPPORTS_LITTLE_ENDIAN
+10 −0
Original line number Diff line number Diff line
@@ -114,3 +114,13 @@ void __init mach_init_irq(void)

	set_c0_status(STATUSF_IP2 | STATUSF_IP6);
}

#ifdef CONFIG_HOTPLUG_CPU

void fixup_irqs(void)
{
	irq_cpu_offline();
	clear_c0_status(ST0_IM);
}

#endif
Loading