2009-03-24 17:10:15 +03:00
/*
* CPU idle Marvell Kirkwood SoCs
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed " as is " without any
* warranty of any kind , whether express or implied .
*
* The cpu idle uses wait - for - interrupt and DDR self refresh in order
* to implement two idle states -
* # 1 wait - for - interrupt
* # 2 wait - for - interrupt and DDR self refresh
2013-04-26 15:05:44 +04:00
*
* Maintainer : Jason Cooper < jason @ lakedaemon . net >
* Maintainer : Andrew Lunn < andrew @ lunn . ch >
2009-03-24 17:10:15 +03:00
*/
# include <linux/kernel.h>
2013-01-09 16:22:15 +04:00
# include <linux/module.h>
2009-03-24 17:10:15 +03:00
# include <linux/init.h>
# include <linux/platform_device.h>
# include <linux/cpuidle.h>
# include <linux/io.h>
2011-08-01 00:17:29 +04:00
# include <linux/export.h>
2012-03-21 00:22:44 +04:00
# include <asm/cpuidle.h>
2009-03-24 17:10:15 +03:00
# define KIRKWOOD_MAX_STATES 2
2013-01-09 16:22:15 +04:00
static void __iomem * ddr_operation_base ;
2009-03-24 17:10:15 +03:00
/* Actual code that puts the SoC in different idle states */
static int kirkwood_enter_idle ( struct cpuidle_device * dev ,
2013-01-09 16:22:15 +04:00
struct cpuidle_driver * drv ,
2011-10-28 14:50:09 +04:00
int index )
2009-03-24 17:10:15 +03:00
{
2013-01-09 16:22:15 +04:00
writel ( 0x7 , ddr_operation_base ) ;
2012-03-21 00:22:44 +04:00
cpu_do_idle ( ) ;
2011-10-28 14:50:09 +04:00
return index ;
2009-03-24 17:10:15 +03:00
}
2012-03-21 00:22:44 +04:00
static struct cpuidle_driver kirkwood_idle_driver = {
. name = " kirkwood_idle " ,
. owner = THIS_MODULE ,
. states [ 0 ] = ARM_CPUIDLE_WFI_STATE ,
. states [ 1 ] = {
. enter = kirkwood_enter_idle ,
. exit_latency = 10 ,
. target_residency = 100000 ,
. name = " DDR SR " ,
. desc = " WFI and DDR Self Refresh " ,
} ,
. state_count = KIRKWOOD_MAX_STATES ,
} ;
2009-03-24 17:10:15 +03:00
/* Initialize CPU idle by registering the idle states */
2013-01-09 16:22:15 +04:00
static int kirkwood_cpuidle_probe ( struct platform_device * pdev )
2009-03-24 17:10:15 +03:00
{
2013-01-09 16:22:15 +04:00
struct resource * res ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2013-03-22 17:10:42 +04:00
ddr_operation_base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( ddr_operation_base ) )
return PTR_ERR ( ddr_operation_base ) ;
2009-03-24 17:10:15 +03:00
2013-04-23 12:54:43 +04:00
return cpuidle_register ( & kirkwood_idle_driver , NULL ) ;
2009-03-24 17:10:15 +03:00
}
2013-08-09 11:11:34 +04:00
static int kirkwood_cpuidle_remove ( struct platform_device * pdev )
2013-01-09 16:22:15 +04:00
{
2013-04-23 12:54:43 +04:00
cpuidle_unregister ( & kirkwood_idle_driver ) ;
2013-01-09 16:22:15 +04:00
return 0 ;
}
static struct platform_driver kirkwood_cpuidle_driver = {
. probe = kirkwood_cpuidle_probe ,
. remove = kirkwood_cpuidle_remove ,
. driver = {
. name = " kirkwood_cpuidle " ,
} ,
} ;
module_platform_driver ( kirkwood_cpuidle_driver ) ;
MODULE_AUTHOR ( " Andrew Lunn <andrew@lunn.ch> " ) ;
MODULE_DESCRIPTION ( " Kirkwood cpu idle driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_ALIAS ( " platform:kirkwood-cpuidle " ) ;