Commit d4450261 authored by Russell King's avatar Russell King

ARM: CPU hotplug: fix reporting of spurious wakeups

The original scheme for reporting spurious wakeups was broken - it
tried to use printk() from a context which wasn't coherent with the
other CPUs, which risks corrupting the printk() data.

Fix this by noting the number spurious wakeups, and only report them
when we are properly woken - when we will be coherent with the rest
of the system.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 58613cd1
...@@ -53,7 +53,7 @@ static inline void cpu_leave_lowpower(void) ...@@ -53,7 +53,7 @@ static inline void cpu_leave_lowpower(void)
: "cc"); : "cc");
} }
static inline void platform_do_lowpower(unsigned int cpu) static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{ {
/* /*
* there is no power-control hardware on this platform, so all * there is no power-control hardware on this platform, so all
...@@ -77,16 +77,13 @@ static inline void platform_do_lowpower(unsigned int cpu) ...@@ -77,16 +77,13 @@ static inline void platform_do_lowpower(unsigned int cpu)
} }
/* /*
* getting here, means that we have come out of WFI without * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen * having been woken up - this shouldn't happen
* *
* The trouble is, letting people know about this is not really * Just note it happening - when we're woken, we can report
* possible, since we are currently running incoherently, and * its occurrence.
* therefore cannot safely call printk() or anything else
*/ */
#ifdef DEBUG (*spurious)++;
printk("CPU%u: spurious wakeup call\n", cpu);
#endif
} }
} }
...@@ -102,17 +99,22 @@ int platform_cpu_kill(unsigned int cpu) ...@@ -102,17 +99,22 @@ int platform_cpu_kill(unsigned int cpu)
*/ */
void platform_cpu_die(unsigned int cpu) void platform_cpu_die(unsigned int cpu)
{ {
int spurious = 0;
/* /*
* we're ready for shutdown now, so do it * we're ready for shutdown now, so do it
*/ */
cpu_enter_lowpower(); cpu_enter_lowpower();
platform_do_lowpower(cpu); platform_do_lowpower(cpu, &spurious);
/* /*
* bring this CPU back into the world of cache * bring this CPU back into the world of cache
* coherency, and then restore interrupts * coherency, and then restore interrupts
*/ */
cpu_leave_lowpower(); cpu_leave_lowpower();
if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
} }
int platform_cpu_disable(unsigned int cpu) int platform_cpu_disable(unsigned int cpu)
......
...@@ -56,7 +56,7 @@ static inline void cpu_leave_lowpower(void) ...@@ -56,7 +56,7 @@ static inline void cpu_leave_lowpower(void)
: "cc"); : "cc");
} }
static inline void platform_do_lowpower(unsigned int cpu) static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{ {
/* /*
* there is no power-control hardware on this platform, so all * there is no power-control hardware on this platform, so all
...@@ -80,16 +80,13 @@ static inline void platform_do_lowpower(unsigned int cpu) ...@@ -80,16 +80,13 @@ static inline void platform_do_lowpower(unsigned int cpu)
} }
/* /*
* getting here, means that we have come out of WFI without * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen * having been woken up - this shouldn't happen
* *
* The trouble is, letting people know about this is not really * Just note it happening - when we're woken, we can report
* possible, since we are currently running incoherently, and * its occurrence.
* therefore cannot safely call printk() or anything else
*/ */
#ifdef DEBUG (*spurious)++;
printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
#endif
} }
} }
...@@ -105,17 +102,22 @@ int platform_cpu_kill(unsigned int cpu) ...@@ -105,17 +102,22 @@ int platform_cpu_kill(unsigned int cpu)
*/ */
void platform_cpu_die(unsigned int cpu) void platform_cpu_die(unsigned int cpu)
{ {
int spurious = 0;
/* /*
* we're ready for shutdown now, so do it * we're ready for shutdown now, so do it
*/ */
cpu_enter_lowpower(); cpu_enter_lowpower();
platform_do_lowpower(cpu); platform_do_lowpower(cpu, &spurious);
/* /*
* bring this CPU back into the world of cache * bring this CPU back into the world of cache
* coherency, and then restore interrupts * coherency, and then restore interrupts
*/ */
cpu_leave_lowpower(); cpu_leave_lowpower();
if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
} }
int platform_cpu_disable(unsigned int cpu) int platform_cpu_disable(unsigned int cpu)
......
...@@ -52,7 +52,7 @@ static inline void cpu_leave_lowpower(void) ...@@ -52,7 +52,7 @@ static inline void cpu_leave_lowpower(void)
: "cc"); : "cc");
} }
static inline void platform_do_lowpower(unsigned int cpu) static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{ {
/* /*
* there is no power-control hardware on this platform, so all * there is no power-control hardware on this platform, so all
...@@ -76,16 +76,13 @@ static inline void platform_do_lowpower(unsigned int cpu) ...@@ -76,16 +76,13 @@ static inline void platform_do_lowpower(unsigned int cpu)
/*}*/ /*}*/
/* /*
* getting here, means that we have come out of WFI without * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen * having been woken up - this shouldn't happen
* *
* The trouble is, letting people know about this is not really * Just note it happening - when we're woken, we can report
* possible, since we are currently running incoherently, and * its occurrence.
* therefore cannot safely call printk() or anything else
*/ */
#ifdef DEBUG (*spurious)++;
printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
#endif
} }
} }
...@@ -101,17 +98,22 @@ int platform_cpu_kill(unsigned int cpu) ...@@ -101,17 +98,22 @@ int platform_cpu_kill(unsigned int cpu)
*/ */
void platform_cpu_die(unsigned int cpu) void platform_cpu_die(unsigned int cpu)
{ {
int spurious = 0;
/* /*
* we're ready for shutdown now, so do it * we're ready for shutdown now, so do it
*/ */
cpu_enter_lowpower(); cpu_enter_lowpower();
platform_do_lowpower(cpu); platform_do_lowpower(cpu, &spurious);
/* /*
* bring this CPU back into the world of cache * bring this CPU back into the world of cache
* coherency, and then restore interrupts * coherency, and then restore interrupts
*/ */
cpu_leave_lowpower(); cpu_leave_lowpower();
if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
} }
int platform_cpu_disable(unsigned int cpu) int platform_cpu_disable(unsigned int cpu)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment