aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/smp_scu.h6
-rw-r--r--arch/arm/kernel/smp_scu.c18
2 files changed, 23 insertions, 1 deletions
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
index 4c47bdfd4f61..1529d1ae2f8d 100644
--- a/arch/arm/include/asm/smp_scu.h
+++ b/arch/arm/include/asm/smp_scu.h
@@ -28,6 +28,7 @@ static inline unsigned long scu_a9_get_base(void)
28unsigned int scu_get_core_count(void __iomem *); 28unsigned int scu_get_core_count(void __iomem *);
29int scu_power_mode(void __iomem *, unsigned int); 29int scu_power_mode(void __iomem *, unsigned int);
30int scu_cpu_power_enable(void __iomem *, unsigned int); 30int scu_cpu_power_enable(void __iomem *, unsigned int);
31int scu_get_cpu_power_mode(void __iomem *scu_base, unsigned int logical_cpu);
31#else 32#else
32static inline unsigned int scu_get_core_count(void __iomem *scu_base) 33static inline unsigned int scu_get_core_count(void __iomem *scu_base)
33{ 34{
@@ -42,6 +43,11 @@ static inline int scu_cpu_power_enable(void __iomem *scu_base,
42{ 43{
43 return -EINVAL; 44 return -EINVAL;
44} 45}
46static inline int scu_get_cpu_power_mode(void __iomem *scu_base,
47 unsigned int logical_cpu)
48{
49 return -EINVAL;
50}
45#endif 51#endif
46 52
47#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU) 53#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 1d549c16b5fc..c6b33074c393 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -21,6 +21,7 @@
21#define SCU_STANDBY_ENABLE (1 << 5) 21#define SCU_STANDBY_ENABLE (1 << 5)
22#define SCU_CONFIG 0x04 22#define SCU_CONFIG 0x04
23#define SCU_CPU_STATUS 0x08 23#define SCU_CPU_STATUS 0x08
24#define SCU_CPU_STATUS_MASK GENMASK(1, 0)
24#define SCU_INVALIDATE 0x0c 25#define SCU_INVALIDATE 0x0c
25#define SCU_FPGA_REVISION 0x10 26#define SCU_FPGA_REVISION 0x10
26 27
@@ -82,7 +83,8 @@ static int scu_set_power_mode_internal(void __iomem *scu_base,
82 if (mode > 3 || mode == 1 || cpu > 3) 83 if (mode > 3 || mode == 1 || cpu > 3)
83 return -EINVAL; 84 return -EINVAL;
84 85
85 val = readb_relaxed(scu_base + SCU_CPU_STATUS + cpu) & ~0x03; 86 val = readb_relaxed(scu_base + SCU_CPU_STATUS + cpu);
87 val &= ~SCU_CPU_STATUS_MASK;
86 val |= mode; 88 val |= mode;
87 writeb_relaxed(val, scu_base + SCU_CPU_STATUS + cpu); 89 writeb_relaxed(val, scu_base + SCU_CPU_STATUS + cpu);
88 90
@@ -109,3 +111,17 @@ int scu_cpu_power_enable(void __iomem *scu_base, unsigned int cpu)
109{ 111{
110 return scu_set_power_mode_internal(scu_base, cpu, SCU_PM_NORMAL); 112 return scu_set_power_mode_internal(scu_base, cpu, SCU_PM_NORMAL);
111} 113}
114
115int scu_get_cpu_power_mode(void __iomem *scu_base, unsigned int logical_cpu)
116{
117 unsigned int val;
118 int cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(logical_cpu), 0);
119
120 if (cpu > 3)
121 return -EINVAL;
122
123 val = readb_relaxed(scu_base + SCU_CPU_STATUS + cpu);
124 val &= SCU_CPU_STATUS_MASK;
125
126 return val;
127}