summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/binfmt_elfo32.c20
-rw-r--r--arch/mips/kernel/cevt-bcm1480.c1
-rw-r--r--arch/mips/kernel/cevt-ds1287.c2
-rw-r--r--arch/mips/kernel/cevt-gt641xx.c2
-rw-r--r--arch/mips/kernel/cevt-r4k.c1
-rw-r--r--arch/mips/kernel/cevt-sb1250.c1
-rw-r--r--arch/mips/kernel/cevt-smtc.c1
-rw-r--r--arch/mips/kernel/cpu-probe.c1
-rw-r--r--arch/mips/kernel/csrc-ioasic.c2
-rw-r--r--arch/mips/kernel/i8253.c1
-rw-r--r--arch/mips/kernel/irq-gic.c20
-rw-r--r--arch/mips/kernel/irq-gt641xx.c2
-rw-r--r--arch/mips/kernel/kgdb.c1
-rw-r--r--arch/mips/kernel/process.c13
-rw-r--r--arch/mips/kernel/ptrace32.c1
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/smp-cmp.c67
-rw-r--r--arch/mips/kernel/smp-up.c16
-rw-r--r--arch/mips/kernel/smp.c18
-rw-r--r--arch/mips/kernel/smtc.c1
-rw-r--r--arch/mips/kernel/sync-r4k.c31
-rw-r--r--arch/mips/kernel/topology.c5
-rw-r--r--arch/mips/kernel/vpe.c2
26 files changed, 115 insertions, 102 deletions
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
index e1333d7319e2..ff448233dab5 100644
--- a/arch/mips/kernel/binfmt_elfo32.c
+++ b/arch/mips/kernel/binfmt_elfo32.c
@@ -53,6 +53,23 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
#include <asm/processor.h>
+
+/*
+ * When this file is selected, we are definitely running a 64bit kernel.
+ * So using the right regs define in asm/reg.h
+ */
+#define WANT_COMPAT_REG_H
+
+/* These MUST be defined before elf.h gets included */
+extern void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs);
+#define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs);
+#define ELF_CORE_COPY_TASK_REGS(_tsk, _dest) \
+({ \
+ int __res = 1; \
+ elf32_core_copy_regs(*(_dest), task_pt_regs(_tsk)); \
+ __res; \
+})
+
#include <linux/module.h>
#include <linux/elfcore.h>
#include <linux/compat.h>
@@ -110,9 +127,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
value->tv_usec = rem / NSEC_PER_USEC;
}
-#undef ELF_CORE_COPY_REGS
-#define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs);
-
void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs)
{
int i;
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c
index a5182a207696..e02f79b1eb51 100644
--- a/arch/mips/kernel/cevt-bcm1480.c
+++ b/arch/mips/kernel/cevt-bcm1480.c
@@ -18,6 +18,7 @@
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/percpu.h>
+#include <linux/smp.h>
#include <asm/addrspace.h>
#include <asm/io.h>
diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c
index 1ada45ea0700..6996da4d74a2 100644
--- a/arch/mips/kernel/cevt-ds1287.c
+++ b/arch/mips/kernel/cevt-ds1287.c
@@ -1,7 +1,7 @@
/*
* DS1287 clockevent driver
*
- * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
index e9b787feedcb..92351e00ae0e 100644
--- a/arch/mips/kernel/cevt-gt641xx.c
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -1,7 +1,7 @@
/*
* GT641xx clockevent routines.
*
- * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 0015e442572b..2652362ce047 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -9,6 +9,7 @@
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/percpu.h>
+#include <linux/smp.h>
#include <asm/smtc_ipi.h>
#include <asm/time.h>
diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c
index 340f53e5c6b1..ac5903d1b20e 100644
--- a/arch/mips/kernel/cevt-sb1250.c
+++ b/arch/mips/kernel/cevt-sb1250.c
@@ -18,6 +18,7 @@
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/percpu.h>
+#include <linux/smp.h>
#include <asm/addrspace.h>
#include <asm/io.h>
diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c
index df6f5bc60572..98bd7de75778 100644
--- a/arch/mips/kernel/cevt-smtc.c
+++ b/arch/mips/kernel/cevt-smtc.c
@@ -10,6 +10,7 @@
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/percpu.h>
+#include <linux/smp.h>
#include <asm/smtc_ipi.h>
#include <asm/time.h>
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index b13b8eb30596..1abe9905c9c1 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <linux/smp.h>
#include <linux/stddef.h>
#include <asm/bugs.h>
diff --git a/arch/mips/kernel/csrc-ioasic.c b/arch/mips/kernel/csrc-ioasic.c
index b551f48d3a07..23da108506b0 100644
--- a/arch/mips/kernel/csrc-ioasic.c
+++ b/arch/mips/kernel/csrc-ioasic.c
@@ -1,7 +1,7 @@
/*
* DEC I/O ASIC's counter clocksource
*
- * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
index ed20e7fe65e3..f7d8d5d0ddbf 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/i8253.c
@@ -7,6 +7,7 @@
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
+#include <linux/smp.h>
#include <linux/spinlock.h>
#include <asm/delay.h>
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index 3f43c2e3aa5a..d2072cd38592 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -2,6 +2,7 @@
#include <linux/bitmap.h>
#include <linux/init.h>
+#include <linux/smp.h>
#include <asm/io.h>
#include <asm/gic.h>
@@ -106,9 +107,7 @@ static unsigned int gic_irq_startup(unsigned int irq)
{
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
- /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
- GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))),
- 1 << (irq % 32));
+ GIC_SET_INTR_MASK(irq, 1);
return 0;
}
@@ -119,8 +118,7 @@ static void gic_irq_ack(unsigned int irq)
#endif
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
- GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))),
- 1 << (irq % 32));
+ GIC_CLR_INTR_MASK(irq, 1);
if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) {
if (!gic_wedgeb2bok)
@@ -137,18 +135,14 @@ static void gic_mask_irq(unsigned int irq)
{
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
- /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
- GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))),
- 1 << (irq % 32));
+ GIC_CLR_INTR_MASK(irq, 1);
}
static void gic_unmask_irq(unsigned int irq)
{
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
- /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
- GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))),
- 1 << (irq % 32));
+ GIC_SET_INTR_MASK(irq, 1);
}
#ifdef CONFIG_SMP
@@ -253,6 +247,10 @@ static void __init gic_basic_init(void)
if (cpu == X)
continue;
+ if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 &&
+ _intrmap[i].ipiflag == 0)
+ continue;
+
setup_intr(_intrmap[i].intrnum,
_intrmap[i].cpunum,
_intrmap[i].pin,
diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c
index 1b81b131f43c..ebcc5f7ad9c2 100644
--- a/arch/mips/kernel/irq-gt641xx.c
+++ b/arch/mips/kernel/irq-gt641xx.c
@@ -1,7 +1,7 @@
/*
* GT641xx IRQ routines.
*
- * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c
index 6e152c80cd4a..50c9bb880667 100644
--- a/arch/mips/kernel/kgdb.c
+++ b/arch/mips/kernel/kgdb.c
@@ -26,6 +26,7 @@
#include <linux/kgdb.h>
#include <linux/kdebug.h>
#include <linux/sched.h>
+#include <linux/smp.h>
#include <asm/inst.h>
#include <asm/fpu.h>
#include <asm/cacheflush.h>
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 1eaaa450e20c..c09d681b7181 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -50,10 +50,15 @@
*/
void __noreturn cpu_idle(void)
{
+ int cpu;
+
+ /* CPU is going idle. */
+ cpu = smp_processor_id();
+
/* endless idle loop with no priority at all */
while (1) {
tick_nohz_stop_sched_tick(1);
- while (!need_resched()) {
+ while (!need_resched() && cpu_online(cpu)) {
#ifdef CONFIG_MIPS_MT_SMTC
extern void smtc_idle_loop_hook(void);
@@ -62,6 +67,12 @@ void __noreturn cpu_idle(void)
if (cpu_wait)
(*cpu_wait)();
}
+#ifdef CONFIG_HOTPLUG_CPU
+ if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
+ (system_state == SYSTEM_RUNNING ||
+ system_state == SYSTEM_BOOTING))
+ play_dead();
+#endif
tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
schedule();
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index c4f9ac17474a..32644b4a0714 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -22,7 +22,6 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/user.h>
#include <linux/security.h>
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 0b31b9bda048..20a86e08fd58 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -652,6 +652,8 @@ einval: li v0, -ENOSYS
sys sys_inotify_init1 1
sys sys_preadv 6 /* 4330 */
sys sys_pwritev 6
+ sys sys_rt_tgsigqueueinfo 4
+ sys sys_perf_counter_open 5
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index c647fd6e722f..b046130d4c5d 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -489,4 +489,6 @@ sys_call_table:
PTR sys_inotify_init1
PTR sys_preadv
PTR sys_pwritev /* 5390 */
+ PTR sys_rt_tgsigqueueinfo
+ PTR sys_perf_counter_open
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 93cc672f4522..15874f9812cc 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -415,4 +415,6 @@ EXPORT(sysn32_call_table)
PTR sys_inotify_init1
PTR sys_preadv
PTR sys_pwritev
+ PTR compat_sys_rt_tgsigqueueinfo /* 5295 */
+ PTR sys_perf_counter_open
.size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index a5598b2339dd..781e0f1e9533 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -535,4 +535,6 @@ sys_call_table:
PTR sys_inotify_init1
PTR compat_sys_preadv /* 4330 */
PTR compat_sys_pwritev
+ PTR compat_sys_rt_tgsigqueueinfo
+ PTR sys_perf_counter_open
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index f27beca4b26d..ad0ff5dc4d59 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/compiler.h>
@@ -36,80 +37,24 @@
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/mips_mt.h>
-
-/*
- * Crude manipulation of the CPU masks to control which
- * which CPU's are brought online during initialisation
- *
- * Beware... this needs to be called after CPU discovery
- * but before CPU bringup
- */
-static int __init allowcpus(char *str)
-{
- cpumask_t cpu_allow_map;
- char buf[256];
- int len;
-
- cpus_clear(cpu_allow_map);
- if (cpulist_parse(str, &cpu_allow_map) == 0) {
- cpu_set(0, cpu_allow_map);
- cpus_and(cpu_possible_map, cpu_possible_map, cpu_allow_map);
- len = cpulist_scnprintf(buf, sizeof(buf)-1, &cpu_possible_map);
- buf[len] = '\0';
- pr_debug("Allowable CPUs: %s\n", buf);
- return 1;
- } else
- return 0;
-}
-__setup("allowcpus=", allowcpus);
+#include <asm/amon.h>
+#include <asm/gic.h>
static void ipi_call_function(unsigned int cpu)
{
- unsigned int action = 0;
-
pr_debug("CPU%d: %s cpu %d status %08x\n",
smp_processor_id(), __func__, cpu, read_c0_status());
- switch (cpu) {
- case 0:
- action = GIC_IPI_EXT_INTR_CALLFNC_VPE0;
- break;
- case 1:
- action = GIC_IPI_EXT_INTR_CALLFNC_VPE1;
- break;
- case 2:
- action = GIC_IPI_EXT_INTR_CALLFNC_VPE2;
- break;
- case 3:
- action = GIC_IPI_EXT_INTR_CALLFNC_VPE3;
- break;
- }
- gic_send_ipi(action);
+ gic_send_ipi(plat_ipi_call_int_xlate(cpu));
}
static void ipi_resched(unsigned int cpu)
{
- unsigned int action = 0;
-
pr_debug("CPU%d: %s cpu %d status %08x\n",
smp_processor_id(), __func__, cpu, read_c0_status());
- switch (cpu) {
- case 0:
- action = GIC_IPI_EXT_INTR_RESCHED_VPE0;
- break;
- case 1:
- action = GIC_IPI_EXT_INTR_RESCHED_VPE1;
- break;
- case 2:
- action = GIC_IPI_EXT_INTR_RESCHED_VPE2;
- break;
- case 3:
- action = GIC_IPI_EXT_INTR_RESCHED_VPE3;
- break;
- }
- gic_send_ipi(action);
+ gic_send_ipi(plat_ipi_resched_int_xlate(cpu));
}
/*
@@ -205,7 +150,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle)
(unsigned long)(gp + sizeof(struct thread_info)));
#endif
- amon_cpu_start(cpu, pc, sp, gp, a0);
+ amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0);
}
/*
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c
index 878e3733bbb2..2508d55d68fd 100644
--- a/arch/mips/kernel/smp-up.c
+++ b/arch/mips/kernel/smp-up.c
@@ -55,6 +55,18 @@ static void __init up_prepare_cpus(unsigned int max_cpus)
{
}
+#ifdef CONFIG_HOTPLUG_CPU
+static int up_cpu_disable(void)
+{
+ return -ENOSYS;
+}
+
+static void up_cpu_die(unsigned int cpu)
+{
+ BUG();
+}
+#endif
+
struct plat_smp_ops up_smp_ops = {
.send_ipi_single = up_send_ipi_single,
.send_ipi_mask = up_send_ipi_mask,
@@ -64,4 +76,8 @@ struct plat_smp_ops up_smp_ops = {
.boot_secondary = up_boot_secondary,
.smp_setup = up_smp_setup,
.prepare_cpus = up_prepare_cpus,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = up_cpu_disable,
+ .cpu_die = up_cpu_die,
+#endif
};
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index c937506a03aa..bc7d9b05e2f4 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/smp.h>
#include <linux/spinlock.h>
#include <linux/threads.h>
#include <linux/module.h>
@@ -44,7 +45,7 @@
#include <asm/mipsmtregs.h>
#endif /* CONFIG_MIPS_MT_SMTC */
-static volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */
+volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */
int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
@@ -200,6 +201,8 @@ void __devinit smp_prepare_boot_cpu(void)
* and keep control until "cpu_online(cpu)" is set. Note: cpu is
* physical, not logical.
*/
+static struct task_struct *cpu_idle_thread[NR_CPUS];
+
int __cpuinit __cpu_up(unsigned int cpu)
{
struct task_struct *idle;
@@ -209,9 +212,16 @@ int __cpuinit __cpu_up(unsigned int cpu)
* The following code is purely to make sure
* Linux can schedule processes on this slave.
*/
- idle = fork_idle(cpu);
- if (IS_ERR(idle))
- panic(KERN_ERR "Fork failed for CPU %d", cpu);
+ if (!cpu_idle_thread[cpu]) {
+ idle = fork_idle(cpu);
+ cpu_idle_thread[cpu] = idle;
+
+ if (IS_ERR(idle))
+ panic(KERN_ERR "Fork failed for CPU %d", cpu);
+ } else {
+ idle = cpu_idle_thread[cpu];
+ init_idle(idle, cpu);
+ }
mp_ops->boot_secondary(cpu, idle);
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 37d51cd124e9..8a0626cbb108 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -20,6 +20,7 @@
#include <linux/clockchips.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c
index 9021108eb9c1..05dd170a83f7 100644
--- a/arch/mips/kernel/sync-r4k.c
+++ b/arch/mips/kernel/sync-r4k.c
@@ -1,7 +1,7 @@
/*
* Count register synchronisation.
*
- * All CPUs will have their count registers synchronised to the CPU0 expirelo
+ * All CPUs will have their count registers synchronised to the CPU0 next time
* value. This can cause a small timewarp for CPU0. All other CPU's should
* not have done anything significant (but they may have had interrupts
* enabled briefly - prom_smp_finish() should not be responsible for enabling
@@ -13,21 +13,22 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irqflags.h>
-#include <linux/r4k-timer.h>
+#include <linux/cpumask.h>
+#include <asm/r4k-timer.h>
#include <asm/atomic.h>
#include <asm/barrier.h>
-#include <asm/cpumask.h>
#include <asm/mipsregs.h>
-static atomic_t __initdata count_start_flag = ATOMIC_INIT(0);
-static atomic_t __initdata count_count_start = ATOMIC_INIT(0);
-static atomic_t __initdata count_count_stop = ATOMIC_INIT(0);
+static atomic_t __cpuinitdata count_start_flag = ATOMIC_INIT(0);
+static atomic_t __cpuinitdata count_count_start = ATOMIC_INIT(0);
+static atomic_t __cpuinitdata count_count_stop = ATOMIC_INIT(0);
+static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0);
#define COUNTON 100
#define NR_LOOPS 5
-void __init synchronise_count_master(void)
+void __cpuinit synchronise_count_master(void)
{
int i;
unsigned long flags;
@@ -42,19 +43,20 @@ void __init synchronise_count_master(void)
return;
#endif
- pr_info("Checking COUNT synchronization across %u CPUs: ",
- num_online_cpus());
+ printk(KERN_INFO "Synchronize counters across %u CPUs: ",
+ num_online_cpus());
local_irq_save(flags);
/*
* Notify the slaves that it's time to start
*/
+ atomic_set(&count_reference, read_c0_count());
atomic_set(&count_start_flag, 1);
smp_wmb();
- /* Count will be initialised to expirelo for all CPU's */
- initcount = expirelo;
+ /* Count will be initialised to current timer for all CPU's */
+ initcount = read_c0_count();
/*
* We loop a few times to get a primed instruction cache,
@@ -106,7 +108,7 @@ void __init synchronise_count_master(void)
printk("done.\n");
}
-void __init synchronise_count_slave(void)
+void __cpuinit synchronise_count_slave(void)
{
int i;
unsigned long flags;
@@ -131,8 +133,8 @@ void __init synchronise_count_slave(void)
while (!atomic_read(&count_start_flag))
mb();
- /* Count will be initialised to expirelo for all CPU's */
- initcount = expirelo;
+ /* Count will be initialised to next expire for all CPU's */
+ initcount = atomic_read(&count_reference);
ncpus = num_online_cpus();
for (i = 0; i < NR_LOOPS; i++) {
@@ -156,4 +158,3 @@ void __init synchronise_count_slave(void)
local_irq_restore(flags);
}
#undef NR_LOOPS
-#endif
diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c
index 660e44ed44d7..cf3eb61fad12 100644
--- a/arch/mips/kernel/topology.c
+++ b/arch/mips/kernel/topology.c
@@ -17,7 +17,10 @@ static int __init topology_init(void)
#endif /* CONFIG_NUMA */
for_each_present_cpu(i) {
- ret = register_cpu(&per_cpu(cpu_devices, i), i);
+ struct cpu *c = &per_cpu(cpu_devices, i);
+
+ c->hotpluggable = 1;
+ ret = register_cpu(c, i);
if (ret)
printk(KERN_WARNING "topology_init: register_cpu %d "
"failed (%d)\n", i, ret);
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 3ca5f42e819d..07b9ec2c6e3d 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1387,7 +1387,7 @@ static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr,
return len;
out_einval:
- return -EINVAL;;
+ return -EINVAL;
}
static struct device_attribute vpe_class_attributes[] = {