diff options
author | Yunhong Jiang <yunhong.jiang@intel.com> | 2015-08-04 12:17:53 -0700 |
---|---|---|
committer | Yunhong Jiang <yunhong.jiang@intel.com> | 2015-08-04 15:44:42 -0700 |
commit | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (patch) | |
tree | 1c9cafbcd35f783a87880a10f85d1a060db1a563 /kernel/arch/arm/mach-shmobile/platsmp-scu.c | |
parent | 98260f3884f4a202f9ca5eabed40b1354c489b29 (diff) |
Add the rt linux 4.1.3-rt3 as base
Import the rt linux 4.1.3-rt3 as OPNFV kvm base.
It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and
the base is:
commit 0917f823c59692d751951bf5ea699a2d1e2f26a2
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Sat Jul 25 12:13:34 2015 +0200
Prepare v4.1.3-rt3
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
We lose all the git history this way and it's not good. We
should apply another opnfv project repo in future.
Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Diffstat (limited to 'kernel/arch/arm/mach-shmobile/platsmp-scu.c')
-rw-r--r-- | kernel/arch/arm/mach-shmobile/platsmp-scu.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/kernel/arch/arm/mach-shmobile/platsmp-scu.c b/kernel/arch/arm/mach-shmobile/platsmp-scu.c new file mode 100644 index 000000000..64663110a --- /dev/null +++ b/kernel/arch/arm/mach-shmobile/platsmp-scu.c @@ -0,0 +1,97 @@ +/* + * SMP support for SoCs with SCU covered by mach-shmobile + * + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/cpu.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/smp.h> +#include <asm/cacheflush.h> +#include <asm/smp_plat.h> +#include <asm/smp_scu.h> +#include "common.h" + +static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action) { + case CPU_UP_PREPARE: + /* For this particular CPU register SCU SMP boot vector */ + shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), + (unsigned long)shmobile_scu_base); + break; + }; + + return NOTIFY_OK; +} + +static struct notifier_block shmobile_smp_scu_notifier = { + .notifier_call = shmobile_smp_scu_notifier_call, +}; + +void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) +{ + /* install boot code shared by all CPUs */ + shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); + shmobile_boot_arg = MPIDR_HWID_BITMASK; + + /* enable SCU and cache coherency on booting CPU */ + scu_enable(shmobile_scu_base); + scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); + + /* Use CPU notifier for reset vector control */ + register_cpu_notifier(&shmobile_smp_scu_notifier); +} + +#ifdef CONFIG_HOTPLUG_CPU +void shmobile_smp_scu_cpu_die(unsigned int cpu) +{ + /* For this particular CPU deregister boot vector */ + shmobile_smp_hook(cpu, 0, 0); + + dsb(); + flush_cache_all(); + + /* disable cache coherency */ + scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF); + + /* jump to shared mach-shmobile sleep / reset code */ + shmobile_smp_sleep(); +} + +static int shmobile_smp_scu_psr_core_disabled(int cpu) +{ + unsigned long mask = SCU_PM_POWEROFF << (cpu * 8); + + if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask) + return 1; + + return 0; +} + +int shmobile_smp_scu_cpu_kill(unsigned int cpu) +{ + int k; + + /* this function is running on another CPU than the offline target, + * here we need wait for shutdown code in platform_cpu_die() to + * finish before asking SoC-specific code to power off the CPU core. + */ + for (k = 0; k < 1000; k++) { + if (shmobile_smp_scu_psr_core_disabled(cpu)) + return 1; + + mdelay(1); + } + + return 0; +} +#endif |