cpuidle-kirkwood.c revision 30dc72c6fa91c640e98ce5ef5ec33fb2beb41ad2
1e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury/* 2e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * arch/arm/mach-kirkwood/cpuidle.c 3e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * 4e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * CPU idle Marvell Kirkwood SoCs 5e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * 6e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * This file is licensed under the terms of the GNU General Public 7e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * License version 2. This program is licensed "as is" without any 8e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * warranty of any kind, whether express or implied. 9e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * 10e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * The cpu idle uses wait-for-interrupt and DDR self refresh in order 11e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * to implement two idle states - 12e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * #1 wait-for-interrupt 13e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury * #2 wait-for-interrupt and DDR self refresh 14e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury */ 15e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury 16e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury#include <linux/kernel.h> 179cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn#include <linux/module.h> 18e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury#include <linux/init.h> 19e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury#include <linux/platform_device.h> 20e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury#include <linux/cpuidle.h> 21e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury#include <linux/io.h> 22dc28094b905a872f8884f1f1c48ca86b3b78583aPaul Gortmaker#include <linux/export.h> 23e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury#include <asm/proc-fns.h> 24b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee#include <asm/cpuidle.h> 25e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury 26e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury#define KIRKWOOD_MAX_STATES 2 27e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury 289cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunnstatic void __iomem *ddr_operation_base; 299cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn 30e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury/* Actual code that puts the SoC in different idle states */ 31e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khourystatic int kirkwood_enter_idle(struct cpuidle_device *dev, 329cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn struct cpuidle_driver *drv, 33e978aa7d7d57d04eb5f88a7507c4fb98577def77Deepthi Dharwar int index) 34e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury{ 359cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn writel(0x7, ddr_operation_base); 36b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee cpu_do_idle(); 37e978aa7d7d57d04eb5f88a7507c4fb98577def77Deepthi Dharwar 38e978aa7d7d57d04eb5f88a7507c4fb98577def77Deepthi Dharwar return index; 39e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury} 40e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury 41b334648db0ff2d07b00d81cf033c6eddff277680Robert Leestatic struct cpuidle_driver kirkwood_idle_driver = { 42b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .name = "kirkwood_idle", 43b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .owner = THIS_MODULE, 44b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .states[0] = ARM_CPUIDLE_WFI_STATE, 45b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .states[1] = { 46b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .enter = kirkwood_enter_idle, 47b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .exit_latency = 10, 48b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .target_residency = 100000, 49b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .flags = CPUIDLE_FLAG_TIME_VALID, 50b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .name = "DDR SR", 51b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .desc = "WFI and DDR Self Refresh", 52b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee }, 53b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee .state_count = KIRKWOOD_MAX_STATES, 54b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee}; 55b334648db0ff2d07b00d81cf033c6eddff277680Robert Lee 56e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury/* Initialize CPU idle by registering the idle states */ 579cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunnstatic int kirkwood_cpuidle_probe(struct platform_device *pdev) 58e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury{ 599cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn struct resource *res; 609cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn 619cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 629cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn if (res == NULL) 639cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn return -EINVAL; 649cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn 65488540bf41ce8ccfe8b54c646c3ea67a7196edcdSilviu-Mihai Popescu ddr_operation_base = devm_ioremap_resource(&pdev->dev, res); 66488540bf41ce8ccfe8b54c646c3ea67a7196edcdSilviu-Mihai Popescu if (IS_ERR(ddr_operation_base)) 67488540bf41ce8ccfe8b54c646c3ea67a7196edcdSilviu-Mihai Popescu return PTR_ERR(ddr_operation_base); 68e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury 6930dc72c6fa91c640e98ce5ef5ec33fb2beb41ad2Daniel Lezcano return cpuidle_register(&kirkwood_idle_driver, NULL); 70e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury} 71e50b6befae9ea91c2d190fb78ff1e06a0b950addRabeeh Khoury 729cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunnint kirkwood_cpuidle_remove(struct platform_device *pdev) 739cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn{ 7430dc72c6fa91c640e98ce5ef5ec33fb2beb41ad2Daniel Lezcano cpuidle_unregister(&kirkwood_idle_driver); 759cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn return 0; 769cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn} 779cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn 789cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunnstatic struct platform_driver kirkwood_cpuidle_driver = { 799cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn .probe = kirkwood_cpuidle_probe, 809cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn .remove = kirkwood_cpuidle_remove, 819cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn .driver = { 829cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn .name = "kirkwood_cpuidle", 839cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn .owner = THIS_MODULE, 849cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn }, 859cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn}; 869cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn 879cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunnmodule_platform_driver(kirkwood_cpuidle_driver); 889cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew Lunn 899cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew LunnMODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>"); 909cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew LunnMODULE_DESCRIPTION("Kirkwood cpu idle driver"); 919cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew LunnMODULE_LICENSE("GPL v2"); 929cfc94eb0f4843af5d1141a37d7b7ca5d3b27220Andrew LunnMODULE_ALIAS("platform:kirkwood-cpuidle"); 93