Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * linux/arch/arm/mach-vexpress/mcpm_platsmp.c
  3 *
  4 * Created by:  Nicolas Pitre, November 2012
  5 * Copyright:   (C) 2012-2013  Linaro Limited
  6 *
  7 * This program is free software; you can redistribute it and/or modify
  8 * it under the terms of the GNU General Public License version 2 as
  9 * published by the Free Software Foundation.
 10 *
 11 * Code to handle secondary CPU bringup and hotplug for the cluster power API.
 12 */
 13
 14#include <linux/init.h>
 15#include <linux/smp.h>
 16#include <linux/spinlock.h>
 17
 18#include <asm/mcpm.h>
 19#include <asm/smp.h>
 20#include <asm/smp_plat.h>
 21
 22static void cpu_to_pcpu(unsigned int cpu,
 23			unsigned int *pcpu, unsigned int *pcluster)
 24{
 25	unsigned int mpidr;
 26
 27	mpidr = cpu_logical_map(cpu);
 28	*pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
 29	*pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
 30}
 31
 32static int mcpm_boot_secondary(unsigned int cpu, struct task_struct *idle)
 33{
 34	unsigned int pcpu, pcluster, ret;
 35	extern void secondary_startup(void);
 36
 37	cpu_to_pcpu(cpu, &pcpu, &pcluster);
 38
 39	pr_debug("%s: logical CPU %d is physical CPU %d cluster %d\n",
 40		 __func__, cpu, pcpu, pcluster);
 41
 42	mcpm_set_entry_vector(pcpu, pcluster, NULL);
 43	ret = mcpm_cpu_power_up(pcpu, pcluster);
 44	if (ret)
 45		return ret;
 46	mcpm_set_entry_vector(pcpu, pcluster, secondary_startup);
 47	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
 48	dsb_sev();
 49	return 0;
 50}
 51
 52static void mcpm_secondary_init(unsigned int cpu)
 53{
 54	mcpm_cpu_powered_up();
 55}
 56
 57#ifdef CONFIG_HOTPLUG_CPU
 58
 59static int mcpm_cpu_kill(unsigned int cpu)
 60{
 61	unsigned int pcpu, pcluster;
 62
 63	cpu_to_pcpu(cpu, &pcpu, &pcluster);
 64
 65	return !mcpm_cpu_power_down_finish(pcpu, pcluster);
 66}
 67
 68static int mcpm_cpu_disable(unsigned int cpu)
 69{
 70	/*
 71	 * We assume all CPUs may be shut down.
 72	 * This would be the hook to use for eventual Secure
 73	 * OS migration requests as described in the PSCI spec.
 74	 */
 75	return 0;
 76}
 77
 78static void mcpm_cpu_die(unsigned int cpu)
 79{
 80	unsigned int mpidr, pcpu, pcluster;
 81	mpidr = read_cpuid_mpidr();
 82	pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
 83	pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
 84	mcpm_set_entry_vector(pcpu, pcluster, NULL);
 85	mcpm_cpu_power_down();
 86}
 87
 88#endif
 89
 90static struct smp_operations __initdata mcpm_smp_ops = {
 91	.smp_boot_secondary	= mcpm_boot_secondary,
 92	.smp_secondary_init	= mcpm_secondary_init,
 93#ifdef CONFIG_HOTPLUG_CPU
 94	.cpu_kill		= mcpm_cpu_kill,
 95	.cpu_disable		= mcpm_cpu_disable,
 96	.cpu_die		= mcpm_cpu_die,
 97#endif
 98};
 99
100void __init mcpm_smp_set_ops(void)
101{
102	smp_set_ops(&mcpm_smp_ops);
103}