Path: blob/master/arch/arm/mach-realview/hotplug.c
10817 views
/*1* linux/arch/arm/mach-realview/hotplug.c2*3* Copyright (C) 2002 ARM Ltd.4* All Rights Reserved5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License version 2 as8* published by the Free Software Foundation.9*/10#include <linux/kernel.h>11#include <linux/errno.h>12#include <linux/smp.h>1314#include <asm/cacheflush.h>1516extern volatile int pen_release;1718static inline void cpu_enter_lowpower(void)19{20unsigned int v;2122flush_cache_all();23asm volatile(24" mcr p15, 0, %1, c7, c5, 0\n"25" mcr p15, 0, %1, c7, c10, 4\n"26/*27* Turn off coherency28*/29" mrc p15, 0, %0, c1, c0, 1\n"30" bic %0, %0, #0x20\n"31" mcr p15, 0, %0, c1, c0, 1\n"32" mrc p15, 0, %0, c1, c0, 0\n"33" bic %0, %0, %2\n"34" mcr p15, 0, %0, c1, c0, 0\n"35: "=&r" (v)36: "r" (0), "Ir" (CR_C)37: "cc");38}3940static inline void cpu_leave_lowpower(void)41{42unsigned int v;4344asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"45" orr %0, %0, %1\n"46" mcr p15, 0, %0, c1, c0, 0\n"47" mrc p15, 0, %0, c1, c0, 1\n"48" orr %0, %0, #0x20\n"49" mcr p15, 0, %0, c1, c0, 1\n"50: "=&r" (v)51: "Ir" (CR_C)52: "cc");53}5455static inline void platform_do_lowpower(unsigned int cpu, int *spurious)56{57/*58* there is no power-control hardware on this platform, so all59* we can do is put the core into WFI; this is safe as the calling60* code will have already disabled interrupts61*/62for (;;) {63/*64* here's the WFI65*/66asm(".word 0xe320f003\n"67:68:69: "memory", "cc");7071if (pen_release == cpu) {72/*73* OK, proper wakeup, we're done74*/75break;76}7778/*79* Getting here, means that we have come out of WFI without80* having been woken up - this shouldn't happen81*82* Just note it happening - when we're woken, we can report83* its occurrence.84*/85(*spurious)++;86}87}8889int platform_cpu_kill(unsigned int cpu)90{91return 1;92}9394/*95* platform-specific code to shutdown a CPU96*97* Called with IRQs disabled98*/99void platform_cpu_die(unsigned int cpu)100{101int spurious = 0;102103/*104* we're ready for shutdown now, so do it105*/106cpu_enter_lowpower();107platform_do_lowpower(cpu, &spurious);108109/*110* bring this CPU back into the world of cache111* coherency, and then restore interrupts112*/113cpu_leave_lowpower();114115if (spurious)116pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);117}118119int platform_cpu_disable(unsigned int cpu)120{121/*122* we don't allow CPU 0 to be shutdown (it is still too special123* e.g. clock tick interrupts)124*/125return cpu == 0 ? -EPERM : 0;126}127128129