Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1/*
  2 *  linux/arch/arm/mach-realview/hotplug.c
  3 *
  4 *  Copyright (C) 2002 ARM Ltd.
  5 *  All Rights Reserved
  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#include <linux/kernel.h>
 12#include <linux/errno.h>
 13#include <linux/smp.h>
 14
 15#include <asm/cacheflush.h>
 16#include <asm/cp15.h>
 17#include <asm/smp_plat.h>
 18
 19extern volatile int pen_release;
 20
 21static inline void cpu_enter_lowpower(void)
 22{
 23	unsigned int v;
 24
 25	flush_cache_all();
 26	asm volatile(
 27	"	mcr	p15, 0, %1, c7, c5, 0\n"
 28	"	mcr	p15, 0, %1, c7, c10, 4\n"
 29	/*
 30	 * Turn off coherency
 31	 */
 32	"	mrc	p15, 0, %0, c1, c0, 1\n"
 33	"	bic	%0, %0, #0x20\n"
 34	"	mcr	p15, 0, %0, c1, c0, 1\n"
 35	"	mrc	p15, 0, %0, c1, c0, 0\n"
 36	"	bic	%0, %0, %2\n"
 37	"	mcr	p15, 0, %0, c1, c0, 0\n"
 38	  : "=&r" (v)
 39	  : "r" (0), "Ir" (CR_C)
 40	  : "cc");
 41}
 42
 43static inline void cpu_leave_lowpower(void)
 44{
 45	unsigned int v;
 46
 47	asm volatile(	"mrc	p15, 0, %0, c1, c0, 0\n"
 48	"	orr	%0, %0, %1\n"
 49	"	mcr	p15, 0, %0, c1, c0, 0\n"
 50	"	mrc	p15, 0, %0, c1, c0, 1\n"
 51	"	orr	%0, %0, #0x20\n"
 52	"	mcr	p15, 0, %0, c1, c0, 1\n"
 53	  : "=&r" (v)
 54	  : "Ir" (CR_C)
 55	  : "cc");
 56}
 57
 58static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 59{
 60	/*
 61	 * there is no power-control hardware on this platform, so all
 62	 * we can do is put the core into WFI; this is safe as the calling
 63	 * code will have already disabled interrupts
 64	 */
 65	for (;;) {
 66		/*
 67		 * here's the WFI
 68		 */
 69		asm(".word	0xe320f003\n"
 70		    :
 71		    :
 72		    : "memory", "cc");
 73
 74		if (pen_release == cpu_logical_map(cpu)) {
 75			/*
 76			 * OK, proper wakeup, we're done
 77			 */
 78			break;
 79		}
 80
 81		/*
 82		 * Getting here, means that we have come out of WFI without
 83		 * having been woken up - this shouldn't happen
 84		 *
 85		 * Just note it happening - when we're woken, we can report
 86		 * its occurrence.
 87		 */
 88		(*spurious)++;
 89	}
 90}
 91
 92int platform_cpu_kill(unsigned int cpu)
 93{
 94	return 1;
 95}
 96
 97/*
 98 * platform-specific code to shutdown a CPU
 99 *
100 * Called with IRQs disabled
101 */
102void platform_cpu_die(unsigned int cpu)
103{
104	int spurious = 0;
105
106	/*
107	 * we're ready for shutdown now, so do it
108	 */
109	cpu_enter_lowpower();
110	platform_do_lowpower(cpu, &spurious);
111
112	/*
113	 * bring this CPU back into the world of cache
114	 * coherency, and then restore interrupts
115	 */
116	cpu_leave_lowpower();
117
118	if (spurious)
119		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
120}
121
122int platform_cpu_disable(unsigned int cpu)
123{
124	/*
125	 * we don't allow CPU 0 to be shutdown (it is still too special
126	 * e.g. clock tick interrupts)
127	 */
128	return cpu == 0 ? -EPERM : 0;
129}