diff options
Diffstat (limited to 'arch/mips/loongson64/smp.c')
-rw-r--r-- | arch/mips/loongson64/smp.c | 217 |
1 files changed, 103 insertions, 114 deletions
diff --git a/arch/mips/loongson64/smp.c b/arch/mips/loongson64/smp.c index 660e1de4412a..5a990cdef91a 100644 --- a/arch/mips/loongson64/smp.c +++ b/arch/mips/loongson64/smp.c @@ -14,6 +14,7 @@ #include <linux/cpufreq.h> #include <linux/kexec.h> #include <asm/processor.h> +#include <asm/smp.h> #include <asm/time.h> #include <asm/tlbflush.h> #include <asm/cacheflush.h> @@ -27,30 +28,13 @@ DEFINE_PER_CPU(int, cpu_state); #define LS_IPI_IRQ (MIPS_CPU_IRQ_BASE + 6) -static void *ipi_set0_regs[16]; -static void *ipi_clear0_regs[16]; -static void *ipi_status0_regs[16]; -static void *ipi_en0_regs[16]; -static void *ipi_mailbox_buf[16]; +static void __iomem *ipi_set0_regs[16]; +static void __iomem *ipi_clear0_regs[16]; +static void __iomem *ipi_status0_regs[16]; +static void __iomem *ipi_en0_regs[16]; +static void __iomem *ipi_mailbox_buf[16]; static uint32_t core0_c0count[NR_CPUS]; -/* read a 32bit value from ipi register */ -#define loongson3_ipi_read32(addr) readl(addr) -/* read a 64bit value from ipi register */ -#define loongson3_ipi_read64(addr) readq(addr) -/* write a 32bit value to ipi register */ -#define loongson3_ipi_write32(action, addr) \ - do { \ - writel(action, addr); \ - __wbflush(); \ - } while (0) -/* write a 64bit value to ipi register */ -#define loongson3_ipi_write64(action, addr) \ - do { \ - writeq(action, addr); \ - __wbflush(); \ - } while (0) - static u32 (*ipi_read_clear)(int cpu); static void (*ipi_write_action)(int cpu, u32 action); static void (*ipi_write_enable)(int cpu); @@ -136,26 +120,28 @@ static u32 legacy_ipi_read_clear(int cpu) u32 action; /* Load the ipi register to figure out what we're supposed to do */ - action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]); + action = readl_relaxed(ipi_status0_regs[cpu_logical_map(cpu)]); /* Clear the ipi register to clear the interrupt */ - loongson3_ipi_write32(action, ipi_clear0_regs[cpu_logical_map(cpu)]); + writel_relaxed(action, ipi_clear0_regs[cpu_logical_map(cpu)]); + nudge_writes(); return action; } static void legacy_ipi_write_action(int cpu, u32 action) { - loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu]); + writel_relaxed((u32)action, ipi_set0_regs[cpu]); + nudge_writes(); } static void legacy_ipi_write_enable(int cpu) { - loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(cpu)]); + writel_relaxed(0xffffffff, ipi_en0_regs[cpu_logical_map(cpu)]); } static void legacy_ipi_clear_buf(int cpu) { - loongson3_ipi_write64(0, ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0); + writeq_relaxed(0, ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0); } static void legacy_ipi_write_buf(int cpu, struct task_struct *idle) @@ -171,14 +157,15 @@ static void legacy_ipi_write_buf(int cpu, struct task_struct *idle) pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n", cpu, startargs[0], startargs[1], startargs[2]); - loongson3_ipi_write64(startargs[3], + writeq_relaxed(startargs[3], ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x18); - loongson3_ipi_write64(startargs[2], + writeq_relaxed(startargs[2], ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x10); - loongson3_ipi_write64(startargs[1], + writeq_relaxed(startargs[1], ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x8); - loongson3_ipi_write64(startargs[0], + writeq_relaxed(startargs[0], ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0); + nudge_writes(); } static void csr_ipi_probe(void) @@ -200,181 +187,181 @@ static void csr_ipi_probe(void) static void ipi_set0_regs_init(void) { - ipi_set0_regs[0] = (void *) + ipi_set0_regs[0] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[1] = (void *) + ipi_set0_regs[1] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[2] = (void *) + ipi_set0_regs[2] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[3] = (void *) + ipi_set0_regs[3] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[4] = (void *) + ipi_set0_regs[4] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[5] = (void *) + ipi_set0_regs[5] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[6] = (void *) + ipi_set0_regs[6] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[7] = (void *) + ipi_set0_regs[7] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[8] = (void *) + ipi_set0_regs[8] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[9] = (void *) + ipi_set0_regs[9] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[10] = (void *) + ipi_set0_regs[10] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[11] = (void *) + ipi_set0_regs[11] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[12] = (void *) + ipi_set0_regs[12] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[13] = (void *) + ipi_set0_regs[13] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[14] = (void *) + ipi_set0_regs[14] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[15] = (void *) + ipi_set0_regs[15] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0); } static void ipi_clear0_regs_init(void) { - ipi_clear0_regs[0] = (void *) + ipi_clear0_regs[0] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[1] = (void *) + ipi_clear0_regs[1] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[2] = (void *) + ipi_clear0_regs[2] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[3] = (void *) + ipi_clear0_regs[3] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[4] = (void *) + ipi_clear0_regs[4] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[5] = (void *) + ipi_clear0_regs[5] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[6] = (void *) + ipi_clear0_regs[6] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[7] = (void *) + ipi_clear0_regs[7] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[8] = (void *) + ipi_clear0_regs[8] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[9] = (void *) + ipi_clear0_regs[9] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[10] = (void *) + ipi_clear0_regs[10] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[11] = (void *) + ipi_clear0_regs[11] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[12] = (void *) + ipi_clear0_regs[12] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[13] = (void *) + ipi_clear0_regs[13] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[14] = (void *) + ipi_clear0_regs[14] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[15] = (void *) + ipi_clear0_regs[15] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0); } static void ipi_status0_regs_init(void) { - ipi_status0_regs[0] = (void *) + ipi_status0_regs[0] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[1] = (void *) + ipi_status0_regs[1] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[2] = (void *) + ipi_status0_regs[2] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[3] = (void *) + ipi_status0_regs[3] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[4] = (void *) + ipi_status0_regs[4] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[5] = (void *) + ipi_status0_regs[5] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[6] = (void *) + ipi_status0_regs[6] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[7] = (void *) + ipi_status0_regs[7] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[8] = (void *) + ipi_status0_regs[8] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[9] = (void *) + ipi_status0_regs[9] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[10] = (void *) + ipi_status0_regs[10] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[11] = (void *) + ipi_status0_regs[11] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[12] = (void *) + ipi_status0_regs[12] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[13] = (void *) + ipi_status0_regs[13] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[14] = (void *) + ipi_status0_regs[14] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[15] = (void *) + ipi_status0_regs[15] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0); } static void ipi_en0_regs_init(void) { - ipi_en0_regs[0] = (void *) + ipi_en0_regs[0] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[1] = (void *) + ipi_en0_regs[1] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[2] = (void *) + ipi_en0_regs[2] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[3] = (void *) + ipi_en0_regs[3] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[4] = (void *) + ipi_en0_regs[4] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[5] = (void *) + ipi_en0_regs[5] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[6] = (void *) + ipi_en0_regs[6] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[7] = (void *) + ipi_en0_regs[7] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[8] = (void *) + ipi_en0_regs[8] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[9] = (void *) + ipi_en0_regs[9] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[10] = (void *) + ipi_en0_regs[10] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[11] = (void *) + ipi_en0_regs[11] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[12] = (void *) + ipi_en0_regs[12] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[13] = (void *) + ipi_en0_regs[13] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[14] = (void *) + ipi_en0_regs[14] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[15] = (void *) + ipi_en0_regs[15] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0); } static void ipi_mailbox_buf_init(void) { - ipi_mailbox_buf[0] = (void *) + ipi_mailbox_buf[0] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[1] = (void *) + ipi_mailbox_buf[1] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[2] = (void *) + ipi_mailbox_buf[2] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[3] = (void *) + ipi_mailbox_buf[3] = (void __iomem *) (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[4] = (void *) + ipi_mailbox_buf[4] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[5] = (void *) + ipi_mailbox_buf[5] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[6] = (void *) + ipi_mailbox_buf[6] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[7] = (void *) + ipi_mailbox_buf[7] = (void __iomem *) (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[8] = (void *) + ipi_mailbox_buf[8] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[9] = (void *) + ipi_mailbox_buf[9] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[10] = (void *) + ipi_mailbox_buf[10] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[11] = (void *) + ipi_mailbox_buf[11] = (void __iomem *) (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[12] = (void *) + ipi_mailbox_buf[12] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[13] = (void *) + ipi_mailbox_buf[13] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[14] = (void *) + ipi_mailbox_buf[14] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[15] = (void *) + ipi_mailbox_buf[15] = (void __iomem *) (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF); } @@ -418,7 +405,7 @@ static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id) c0count = c0count ? c0count : 1; for (i = 1; i < nr_cpu_ids; i++) core0_c0count[i] = c0count; - __wbflush(); /* Let others see the result ASAP */ + nudge_writes(); /* Let others see the result ASAP */ } return IRQ_HANDLED; @@ -529,7 +516,7 @@ static void __init loongson3_prepare_cpus(unsigned int max_cpus) } /* - * Setup the PC, SP, and GP of a secondary processor and start it runing! + * Setup the PC, SP, and GP of a secondary processor and start it running! */ static int loongson3_boot_secondary(int cpu, struct task_struct *idle) { @@ -788,6 +775,7 @@ void play_dead(void) void (*play_dead_at_ckseg1)(int *); idle_task_exit(); + cpuhp_ap_report_dead(); prid_imp = read_c0_prid() & PRID_IMP_MASK; prid_rev = read_c0_prid() & PRID_REV_MASK; @@ -822,6 +810,7 @@ out: state_addr = &per_cpu(cpu_state, cpu); mb(); play_dead_at_ckseg1(state_addr); + BUG(); } static int loongson3_disable_clock(unsigned int cpu) @@ -875,7 +864,7 @@ const struct plat_smp_ops loongson3_smp_ops = { .cpu_disable = loongson3_cpu_disable, .cpu_die = loongson3_cpu_die, #endif -#ifdef CONFIG_KEXEC +#ifdef CONFIG_KEXEC_CORE .kexec_nonboot_cpu = kexec_nonboot_cpu_jump, #endif }; |