2011-09-06 10:59:40 +04:00
/*
* Copyright 2011 Freescale Semiconductor , Inc .
* Copyright 2011 Linaro Ltd .
*
* The code contained herein is licensed under the GNU General Public
* License . You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations :
*
* http : //www.opensource.org/licenses/gpl-license.html
* http : //www.gnu.org/copyleft/gpl.html
*/
# include <linux/errno.h>
# include <asm/cacheflush.h>
2012-05-22 18:13:46 +04:00
# include <asm/cp15.h>
2012-09-13 17:01:00 +04:00
# include "common.h"
2011-09-06 10:59:40 +04:00
2012-05-22 18:13:46 +04:00
static inline void cpu_enter_lowpower ( void )
{
unsigned int v ;
flush_cache_all ( ) ;
asm volatile (
" mcr p15, 0, %1, c7, c5, 0 \n "
" mcr p15, 0, %1, c7, c10, 4 \n "
/*
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1 \n "
" bic %0, %0, %3 \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 ) , " Ir " ( 0x40 )
: " cc " ) ;
}
2011-09-06 10:59:40 +04:00
/*
* platform - specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
2011-09-08 16:15:22 +04:00
void imx_cpu_die ( unsigned int cpu )
2011-09-06 10:59:40 +04:00
{
2012-05-22 18:13:46 +04:00
cpu_enter_lowpower ( ) ;
2013-03-26 12:46:07 +04:00
/*
* We use the cpu jumping argument register to sync with
* imx_cpu_kill ( ) which is running on cpu0 and waiting for
* the register being cleared to kill the cpu .
*/
imx_set_cpu_arg ( cpu , ~ 0 ) ;
2013-01-14 10:08:50 +04:00
cpu_do_idle ( ) ;
}
2011-09-06 10:59:40 +04:00
2013-01-14 10:08:50 +04:00
int imx_cpu_kill ( unsigned int cpu )
{
2013-03-26 12:46:07 +04:00
unsigned long timeout = jiffies + msecs_to_jiffies ( 50 ) ;
while ( imx_get_cpu_arg ( cpu ) = = 0 )
if ( time_after ( jiffies , timeout ) )
return 0 ;
2013-01-14 10:08:50 +04:00
imx_enable_cpu ( cpu , false ) ;
2013-03-26 12:46:07 +04:00
imx_set_cpu_arg ( cpu , 0 ) ;
2013-01-14 10:08:50 +04:00
return 1 ;
2011-09-06 10:59:40 +04:00
}