Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: pm: add function to set WFI low-power mode for SMP CPUs

Add a function to set the SCU low-power mode for SMP CPUs. This
centralizes this functionality rather than having to expose the
SCU register definitions to each platform.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

+30
+7
arch/arm/include/asm/smp_scu.h
··· 1 1 #ifndef __ASMARM_ARCH_SCU_H 2 2 #define __ASMARM_ARCH_SCU_H 3 3 4 + #define SCU_PM_NORMAL 0 5 + #define SCU_PM_DORMANT 2 6 + #define SCU_PM_POWEROFF 3 7 + 8 + #ifndef __ASSEMBLER__ 4 9 unsigned int scu_get_core_count(void __iomem *); 5 10 void scu_enable(void __iomem *); 11 + int scu_power_mode(void __iomem *, unsigned int); 12 + #endif 6 13 7 14 #endif
+23
arch/arm/kernel/smp_scu.c
··· 50 50 */ 51 51 flush_cache_all(); 52 52 } 53 + 54 + /* 55 + * Set the executing CPUs power mode as defined. This will be in 56 + * preparation for it executing a WFI instruction. 57 + * 58 + * This function must be called with preemption disabled, and as it 59 + * has the side effect of disabling coherency, caches must have been 60 + * flushed. Interrupts must also have been disabled. 61 + */ 62 + int scu_power_mode(void __iomem *scu_base, unsigned int mode) 63 + { 64 + unsigned int val; 65 + int cpu = smp_processor_id(); 66 + 67 + if (mode > 3 || mode == 1 || cpu > 3) 68 + return -EINVAL; 69 + 70 + val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu) & ~0x03; 71 + val |= mode; 72 + __raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu); 73 + 74 + return 0; 75 + }