2012-04-19 22:23:13 +05:30
/*
* linux / arch / arm / mach - spear13xx / hotplug . c
*
* Copyright ( C ) 2012 ST Microelectronics Ltd .
* Deepak Sikri < deepak . sikri @ st . com >
*
* based upon linux / arch / arm / mach - realview / hotplug . c
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/smp.h>
# include <asm/cp15.h>
# include <asm/smp_plat.h>
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
# include "generic.h"
2012-04-19 22:23:13 +05:30
static inline void cpu_enter_lowpower ( void )
{
unsigned int v ;
asm volatile (
" mcr p15, 0, %1, c7, c5, 0 \n "
" dsb \n "
/*
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1 \n "
" bic %0, %0, #0x20 \n "
" mcr p15, 0, %0, c1, c0, 1 \n "
" mrc p15, 0, %0, c1, c0, 0 \n "
" bic %0, %0, %2 \n "
" mcr p15, 0, %0, c1, c0, 0 \n "
: " =&r " ( v )
: " r " ( 0 ) , " Ir " ( CR_C )
: " cc " , " memory " ) ;
}
static inline void cpu_leave_lowpower ( void )
{
unsigned int v ;
asm volatile ( " mrc p15, 0, %0, c1, c0, 0 \n "
" orr %0, %0, %1 \n "
" mcr p15, 0, %0, c1, c0, 0 \n "
" mrc p15, 0, %0, c1, c0, 1 \n "
" orr %0, %0, #0x20 \n "
" mcr p15, 0, %0, c1, c0, 1 \n "
: " =&r " ( v )
: " Ir " ( CR_C )
: " cc " ) ;
}
2011-09-08 13:15:22 +01:00
static inline void spear13xx_do_lowpower ( unsigned int cpu , int * spurious )
2012-04-19 22:23:13 +05:30
{
for ( ; ; ) {
wfi ( ) ;
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
if ( spear_pen_release = = cpu ) {
2012-04-19 22:23:13 +05:30
/*
* OK , proper wakeup , we ' re done
*/
break ;
}
/*
* Getting here , means that we have come out of WFI without
* having been woken up - this shouldn ' t happen
*
* Just note it happening - when we ' re woken , we can report
* its occurrence .
*/
( * spurious ) + + ;
}
}
/*
* platform - specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
2015-10-19 13:05:33 -07:00
void spear13xx_cpu_die ( unsigned int cpu )
2012-04-19 22:23:13 +05:30
{
int spurious = 0 ;
/*
* we ' re ready for shutdown now , so do it
*/
cpu_enter_lowpower ( ) ;
2011-09-08 13:15:22 +01:00
spear13xx_do_lowpower ( cpu , & spurious ) ;
2012-04-19 22:23:13 +05:30
/*
* bring this CPU back into the world of cache
* coherency , and then restore interrupts
*/
cpu_leave_lowpower ( ) ;
if ( spurious )
pr_warn ( " CPU%u: %u spurious wakeup calls \n " , cpu , spurious ) ;
}