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

Commit 25468fe8 authored by Olof Johansson's avatar Olof Johansson
Browse files

Merge branch 'multiplatform/smp_ops' into next/multiplatform



* 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: default avatarOlof Johansson <olof@lixom.net>
parents a283580c 28e8e29c
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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	*/
@@ -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	*/
+34 −14
Original line number Diff line number Diff line
@@ -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.
@@ -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 */
+3 −1
Original line number Diff line number Diff line
@@ -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();

+69 −3
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#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>
@@ -27,6 +26,7 @@
#include <linux/completion.h>

#include <linux/atomic.h>
#include <asm/smp.h>
#include <asm/cacheflush.h>
#include <asm/cpu.h>
#include <asm/cputype.h>
@@ -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
@@ -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,
@@ -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;
@@ -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;
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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 */
Loading