2 * Copyright (C) 2012-2014 ROCKCHIP, Inc.
3 * Copyright (C) 2002 ARM Ltd.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/smp.h>
14 #include <linux/delay.h>
15 #include <linux/rockchip/common.h>
16 #include <linux/rockchip/pmu.h>
18 #include <asm/cacheflush.h>
20 #include <asm/smp_plat.h>
21 #include <asm/system.h>
24 static cpumask_t dead_cpus;
26 int rockchip_cpu_kill(unsigned int cpu)
30 /* this function is running on another CPU than the offline target,
31 * here we need wait for shutdown code in platform_cpu_die() to
32 * finish before asking SoC-specific code to power off the CPU core.
34 for (k = 0; k < 1000; k++) {
35 if (cpumask_test_cpu(cpu, &dead_cpus)) {
37 rockchip_pmu_ops.set_power_domain(PD_CPU_0 + cpu, false);
48 * platform-specific code to shutdown a CPU
50 * Called with IRQs disabled
52 void rockchip_cpu_die_a9(unsigned int cpu)
56 /* hardware shutdown code running on the CPU that is being offlined */
60 /* notify platform_cpu_kill() that hardware shutdown is finished */
61 cpumask_set_cpu(cpu, &dead_cpus);
65 " mcr p15, 0, %1, c7, c5, 0\n"
66 " mcr p15, 0, %1, c7, c10, 4\n"
70 " mrc p15, 0, %0, c1, c0, 1\n"
71 " bic %0, %0, %3\n" // clear ACTLR.SMP | ACTLR.FW
72 " mcr p15, 0, %0, c1, c0, 1\n"
73 " mrc p15, 0, %0, c1, c0, 0\n"
75 " mcr p15, 0, %0, c1, c0, 0\n"
77 : "r" (0), "Ir" (CR_C), "Ir" ((1 << 6) | (1 << 0))
80 /* wait for SoC code in platform_cpu_kill() to shut off CPU core
81 * power. CPU bring up starts from the reset vector.
89 void rockchip_cpu_die(unsigned int cpu)
91 /* notify platform_cpu_kill() that hardware shutdown is finished */
92 cpumask_set_cpu(cpu, &dead_cpus);
95 v7_exit_coherency_flush(louis);
103 int rockchip_cpu_disable(unsigned int cpu)
105 cpumask_clear_cpu(cpu, &dead_cpus);
107 * we don't allow CPU 0 to be shutdown (it is still too special
108 * e.g. clock tick interrupts)
110 return cpu == 0 ? -EPERM : 0;