2014-02-22 20:14:57 +01:00
/*
* Power Management driver for Marvell Kirkwood SoCs
*
* Copyright ( C ) 2013 Ezequiel Garcia < ezequiel @ free - electrons . com >
* Copyright ( C ) 2010 Simon Guinot < sguinot @ lacie . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License ,
* version 2 of the License .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*/
# include <linux/kernel.h>
# include <linux/suspend.h>
# include <linux/io.h>
2014-02-22 20:15:03 +01:00
# include "kirkwood.h"
2014-02-22 20:14:57 +01:00
static void __iomem * ddr_operation_base ;
static void __iomem * memory_pm_ctrl ;
static void kirkwood_low_power ( void )
{
u32 mem_pm_ctrl ;
mem_pm_ctrl = readl ( memory_pm_ctrl ) ;
/* Set peripherals to low-power mode */
writel_relaxed ( ~ 0 , memory_pm_ctrl ) ;
/* Set DDR in self-refresh */
writel_relaxed ( 0x7 , ddr_operation_base ) ;
/*
* Set CPU in wait - for - interrupt state .
* This disables the CPU core clocks ,
* the array clocks , and also the L2 controller .
*/
cpu_do_idle ( ) ;
writel_relaxed ( mem_pm_ctrl , memory_pm_ctrl ) ;
}
static int kirkwood_suspend_enter ( suspend_state_t state )
{
switch ( state ) {
case PM_SUSPEND_STANDBY :
kirkwood_low_power ( ) ;
break ;
default :
return - EINVAL ;
}
return 0 ;
}
static int kirkwood_pm_valid_standby ( suspend_state_t state )
{
return state = = PM_SUSPEND_STANDBY ;
}
static const struct platform_suspend_ops kirkwood_suspend_ops = {
. enter = kirkwood_suspend_enter ,
. valid = kirkwood_pm_valid_standby ,
} ;
int __init kirkwood_pm_init ( void )
{
ddr_operation_base = ioremap ( DDR_OPERATION_BASE , 4 ) ;
memory_pm_ctrl = ioremap ( MEMORY_PM_CTRL_PHYS , 4 ) ;
suspend_set_ops ( & kirkwood_suspend_ops ) ;
return 0 ;
}