Skip to content

Commit

Permalink
Merge branch 'multiplatform/smp_ops' into next/multiplatform
Browse files Browse the repository at this point in the history
* multiplatform/smp_ops:
  ARM: consolidate pen_release instead of having per platform definitions
  ARM: smp: Make SMP operations mandatory
  ARM: SoC: convert spear13xx to SMP operations
  ARM: SoC: convert imx6q to SMP operations
  ARM: SoC: convert highbank to SMP operations
  ARM: SoC: convert shmobile SMP to SMP operations
  ARM: SoC: convert ux500 to SMP operations
  ARM: SoC: convert MSM to SMP operations
  ARM: SoC: convert Exynos4 to SMP operations
  ARM: SoC: convert Tegra to SMP operations
  ARM: SoC: convert OMAP4 to SMP operations
  ARM: SoC: convert VExpress/RealView to SMP operations
  ARM: SoC: add per-platform SMP operations

Conflicts due to file moves or removals in:
	arch/arm/mach-msm/board-msm8960.c
	arch/arm/mach-msm/board-msm8x60.c
	arch/arm/mach-tegra/board-harmony.c
	arch/arm/mach-tegra/board-trimslice.c

Conflicts due to board file cleanup:
	arch/arm/mach-tegra/board-paz00.c

Conflicts due to cpu hotplug addition:
	arch/arm/mach-tegra/hotplug.c

Signed-off-by: Olof Johansson <olof@lixom.net>
  • Loading branch information
Olof Johansson committed Sep 22, 2012
2 parents a283580 + 28e8e29 commit 25468fe
Show file tree
Hide file tree
Showing 74 changed files with 535 additions and 401 deletions.
7 changes: 7 additions & 0 deletions arch/arm/include/asm/mach/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ struct tag;
struct meminfo;
struct sys_timer;
struct pt_regs;
struct smp_operations;
#ifdef CONFIG_SMP
#define smp_ops(ops) (&(ops))
#else
#define smp_ops(ops) (struct smp_operations *)NULL
#endif

struct machine_desc {
unsigned int nr; /* architecture number */
Expand All @@ -35,6 +41,7 @@ struct machine_desc {
unsigned char reserve_lp1 :1; /* never has lp1 */
unsigned char reserve_lp2 :1; /* never has lp2 */
char restart_mode; /* default restart mode */
struct smp_operations *smp; /* SMP operations */
void (*fixup)(struct tag *, char **,
struct meminfo *);
void (*reserve)(void);/* reserve mem blocks */
Expand Down
48 changes: 34 additions & 14 deletions arch/arm/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,6 @@ extern int boot_secondary(unsigned int cpu, struct task_struct *);
*/
asmlinkage void secondary_start_kernel(void);

/*
* Perform platform specific initialisation of the specified CPU.
*/
extern void platform_secondary_init(unsigned int cpu);

/*
* Initialize cpu_possible map, and enable coherency
*/
extern void platform_smp_prepare_cpus(unsigned int);

/*
* Initial data for bringing up a secondary CPU.
Expand All @@ -79,18 +70,47 @@ struct secondary_data {
void *stack;
};
extern struct secondary_data secondary_data;
extern volatile int pen_release;

extern int __cpu_disable(void);
extern int platform_cpu_disable(unsigned int cpu);

extern void __cpu_die(unsigned int cpu);
extern void cpu_die(void);

extern void platform_cpu_die(unsigned int cpu);
extern int platform_cpu_kill(unsigned int cpu);
extern void platform_cpu_enable(unsigned int cpu);

extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);

struct smp_operations {
#ifdef CONFIG_SMP
/*
* Setup the set of possible CPUs (via set_cpu_possible)
*/
void (*smp_init_cpus)(void);
/*
* Initialize cpu_possible map, and enable coherency
*/
void (*smp_prepare_cpus)(unsigned int max_cpus);

/*
* Perform platform specific initialisation of the specified CPU.
*/
void (*smp_secondary_init)(unsigned int cpu);
/*
* Boot a secondary CPU, and assign it the specified idle task.
* This also gives us the initial stack to use for this CPU.
*/
int (*smp_boot_secondary)(unsigned int cpu, struct task_struct *idle);
#ifdef CONFIG_HOTPLUG_CPU
int (*cpu_kill)(unsigned int cpu);
void (*cpu_die)(unsigned int cpu);
int (*cpu_disable)(unsigned int cpu);
#endif
#endif
};

/*
* set platform specific SMP operations
*/
extern void smp_set_ops(struct smp_operations *);

#endif /* ifndef __ASM_ARM_SMP_H */
4 changes: 3 additions & 1 deletion arch/arm/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,8 +977,10 @@ void __init setup_arch(char **cmdline_p)
unflatten_device_tree();

#ifdef CONFIG_SMP
if (is_smp())
if (is_smp()) {
smp_set_ops(mdesc->smp);
smp_init_cpus();
}
#endif
reserve_crashkernel();

Expand Down
72 changes: 69 additions & 3 deletions arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/seq_file.h>
#include <linux/irq.h>
#include <linux/percpu.h>
#include <linux/clockchips.h>
#include <linux/completion.h>

#include <linux/atomic.h>
#include <asm/smp.h>
#include <asm/cacheflush.h>
#include <asm/cpu.h>
#include <asm/cputype.h>
Expand All @@ -42,6 +42,7 @@
#include <asm/ptrace.h>
#include <asm/localtimer.h>
#include <asm/smp_plat.h>
#include <asm/mach/arch.h>

/*
* as from 2.5, kernels no longer have an init_tasks structure
Expand All @@ -50,6 +51,12 @@
*/
struct secondary_data secondary_data;

/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile int __cpuinitdata pen_release = -1;

enum ipi_msg_type {
IPI_TIMER = 2,
IPI_RESCHEDULE,
Expand All @@ -60,6 +67,14 @@ enum ipi_msg_type {

static DECLARE_COMPLETION(cpu_running);

static struct smp_operations smp_ops;

void __init smp_set_ops(struct smp_operations *ops)
{
if (ops)
smp_ops = *ops;
};

int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
{
int ret;
Expand Down Expand Up @@ -100,13 +115,64 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
return ret;
}

/* platform specific SMP operations */
void __init smp_init_cpus(void)
{
if (smp_ops.smp_init_cpus)
smp_ops.smp_init_cpus();
}

static void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
if (smp_ops.smp_prepare_cpus)
smp_ops.smp_prepare_cpus(max_cpus);
}

static void __cpuinit platform_secondary_init(unsigned int cpu)
{
if (smp_ops.smp_secondary_init)
smp_ops.smp_secondary_init(cpu);
}

int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
if (smp_ops.smp_boot_secondary)
return smp_ops.smp_boot_secondary(cpu, idle);
return -ENOSYS;
}

#ifdef CONFIG_HOTPLUG_CPU
static void percpu_timer_stop(void);

static int platform_cpu_kill(unsigned int cpu)
{
if (smp_ops.cpu_kill)
return smp_ops.cpu_kill(cpu);
return 1;
}

static void platform_cpu_die(unsigned int cpu)
{
if (smp_ops.cpu_die)
smp_ops.cpu_die(cpu);
}

static int platform_cpu_disable(unsigned int cpu)
{
if (smp_ops.cpu_disable)
return smp_ops.cpu_disable(cpu);

/*
* By default, allow disabling all CPUs except the first one,
* since this is special on a lot of platforms, e.g. because
* of clock tick interrupts.
*/
return cpu == 0 ? -EPERM : 0;
}
/*
* __cpu_disable runs on the processor to be shutdown.
*/
int __cpu_disable(void)
int __cpuinit __cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
int ret;
Expand Down Expand Up @@ -149,7 +215,7 @@ static DECLARE_COMPLETION(cpu_died);
* called on the thread which is asking for a CPU to be shutdown -
* waits until shutdown has completed, or it is timed out.
*/
void __cpu_die(unsigned int cpu)
void __cpuinit __cpu_die(unsigned int cpu)
{
if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
pr_err("CPU%u: cpu didn't die\n", cpu);
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/mach-exynos/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

extern struct sys_timer exynos4_timer;

struct map_desc;
void exynos_init_io(struct map_desc *mach_desc, int size);
void exynos4_init_irq(void);
void exynos5_init_irq(void);
Expand Down Expand Up @@ -59,4 +60,8 @@ void exynos4212_register_clocks(void);
#define exynos4212_register_clocks()
#endif

extern struct smp_operations exynos_smp_ops;

extern void exynos_cpu_die(unsigned int cpu);

#endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
18 changes: 2 additions & 16 deletions arch/arm/mach-exynos/hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

#include <mach/regs-pmu.h>

extern volatile int pen_release;
#include "common.h"

static inline void cpu_enter_lowpower(void)
{
Expand Down Expand Up @@ -95,17 +95,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
}
}

int platform_cpu_kill(unsigned int cpu)
{
return 1;
}

/*
* platform-specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
void platform_cpu_die(unsigned int cpu)
void __ref exynos_cpu_die(unsigned int cpu)
{
int spurious = 0;

Expand All @@ -124,12 +119,3 @@ void platform_cpu_die(unsigned int cpu)
if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
}

int platform_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
* e.g. clock tick interrupts)
*/
return cpu == 0 ? -EPERM : 0;
}
1 change: 1 addition & 0 deletions arch/arm/mach-exynos/mach-armlex4210.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ static void __init armlex4210_machine_init(void)
MACHINE_START(ARMLEX4210, "ARMLEX4210")
/* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
.atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq,
.map_io = armlex4210_map_io,
.handle_irq = gic_handle_irq,
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-exynos/mach-exynos5-dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ static char const *exynos5250_dt_compat[] __initdata = {
DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.init_irq = exynos5_init_irq,
.smp = smp_ops(exynos_smp_ops),
.map_io = exynos5250_dt_map_io,
.handle_irq = gic_handle_irq,
.init_machine = exynos5250_dt_machine_init,
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-exynos/mach-nuri.c
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,7 @@ static void __init nuri_machine_init(void)
MACHINE_START(NURI, "NURI")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
.atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq,
.map_io = nuri_map_io,
.handle_irq = gic_handle_irq,
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-exynos/mach-origen.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,7 @@ static void __init origen_machine_init(void)
MACHINE_START(ORIGEN, "ORIGEN")
/* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
.atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq,
.map_io = origen_map_io,
.handle_irq = gic_handle_irq,
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mach-exynos/mach-smdk4x12.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ static void __init smdk4x12_machine_init(void)
MACHINE_START(SMDK4212, "SMDK4212")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq,
.map_io = smdk4x12_map_io,
.handle_irq = gic_handle_irq,
Expand All @@ -383,6 +384,7 @@ MACHINE_START(SMDK4412, "SMDK4412")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
.atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq,
.map_io = smdk4x12_map_io,
.handle_irq = gic_handle_irq,
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mach-exynos/mach-smdkv310.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ MACHINE_START(SMDKV310, "SMDKV310")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
.atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq,
.map_io = smdkv310_map_io,
.handle_irq = gic_handle_irq,
Expand All @@ -429,6 +430,7 @@ MACHINE_END
MACHINE_START(SMDKC210, "SMDKC210")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq,
.map_io = smdkv310_map_io,
.handle_irq = gic_handle_irq,
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-exynos/mach-universal_c210.c
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,7 @@ static void __init universal_machine_init(void)
MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
.atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq,
.map_io = universal_map_io,
.handle_irq = gic_handle_irq,
Expand Down
Loading

0 comments on commit 25468fe

Please sign in to comment.