2009-11-01 17:40:50 +00:00
|
|
|
/*
|
|
|
|
* based on arch/arm/mach-kirkwood/cpuidle.c
|
|
|
|
*
|
|
|
|
* CPU idle support for AT91 SoC
|
|
|
|
*
|
|
|
|
* 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 RAM self refresh in order
|
|
|
|
* to implement two idle states -
|
|
|
|
* #1 wait-for-interrupt
|
|
|
|
* #2 wait-for-interrupt and RAM self refresh
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/cpuidle.h>
|
|
|
|
#include <linux/io.h>
|
2011-07-31 20:17:29 +00:00
|
|
|
#include <linux/export.h>
|
2012-03-20 20:22:43 +00:00
|
|
|
#include <asm/proc-fns.h>
|
|
|
|
#include <asm/cpuidle.h>
|
2009-11-01 17:40:50 +00:00
|
|
|
|
|
|
|
#include "pm.h"
|
|
|
|
|
|
|
|
#define AT91_MAX_STATES 2
|
|
|
|
|
|
|
|
static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device);
|
|
|
|
|
|
|
|
/* Actual code that puts the SoC in different idle states */
|
|
|
|
static int at91_enter_idle(struct cpuidle_device *dev,
|
2011-10-28 10:50:42 +00:00
|
|
|
struct cpuidle_driver *drv,
|
2011-10-28 10:50:09 +00:00
|
|
|
int index)
|
2009-11-01 17:40:50 +00:00
|
|
|
{
|
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
Pull ACPI & Power Management changes from Len Brown:
- ACPI 5.0 after-ripples, ACPICA/Linux divergence cleanup
- cpuidle evolving, more ARM use
- thermal sub-system evolving, ditto
- assorted other PM bits
Fix up conflicts in various cpuidle implementations due to ARM cpuidle
cleanups (ARM at91 self-refresh and cpu idle code rewritten into
"standby" in asm conflicting with the consolidation of cpuidle time
keeping), trivial SH include file context conflict and RCU tracing fixes
in generic code.
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: (77 commits)
ACPI throttling: fix endian bug in acpi_read_throttling_status()
Disable MCP limit exceeded messages from Intel IPS driver
ACPI video: Don't start video device until its associated input device has been allocated
ACPI video: Harden video bus adding.
ACPI: Add support for exposing BGRT data
ACPI: export acpi_kobj
ACPI: Fix logic for removing mappings in 'acpi_unmap'
CPER failed to handle generic error records with multiple sections
ACPI: Clean redundant codes in scan.c
ACPI: Fix unprotected smp_processor_id() in acpi_processor_cst_has_changed()
ACPI: consistently use should_use_kmap()
PNPACPI: Fix device ref leaking in acpi_pnp_match
ACPI: Fix use-after-free in acpi_map_lsapic
ACPI: processor_driver: add missing kfree
ACPI, APEI: Fix incorrect APEI register bit width check and usage
Update documentation for parameter *notrigger* in einj.txt
ACPI, APEI, EINJ, new parameter to control trigger action
ACPI, APEI, EINJ, limit the range of einj_param
ACPI, APEI, Fix ERST header length check
cpuidle: power_usage should be declared signed integer
...
2012-03-30 23:45:38 +00:00
|
|
|
at91_standby();
|
2012-01-24 23:56:08 +00:00
|
|
|
|
2011-10-28 10:50:09 +00:00
|
|
|
return index;
|
2009-11-01 17:40:50 +00:00
|
|
|
}
|
|
|
|
|
2012-03-20 20:22:43 +00:00
|
|
|
static struct cpuidle_driver at91_idle_driver = {
|
|
|
|
.name = "at91_idle",
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.en_core_tk_irqen = 1,
|
|
|
|
.states[0] = ARM_CPUIDLE_WFI_STATE,
|
|
|
|
.states[1] = {
|
|
|
|
.enter = at91_enter_idle,
|
|
|
|
.exit_latency = 10,
|
|
|
|
.target_residency = 100000,
|
|
|
|
.flags = CPUIDLE_FLAG_TIME_VALID,
|
|
|
|
.name = "RAM_SR",
|
|
|
|
.desc = "WFI and DDR Self Refresh",
|
|
|
|
},
|
|
|
|
.state_count = AT91_MAX_STATES,
|
|
|
|
};
|
|
|
|
|
2009-11-01 17:40:50 +00:00
|
|
|
/* Initialize CPU idle by registering the idle states */
|
|
|
|
static int at91_init_cpuidle(void)
|
|
|
|
{
|
|
|
|
struct cpuidle_device *device;
|
|
|
|
|
|
|
|
device = &per_cpu(at91_cpuidle_device, smp_processor_id());
|
|
|
|
device->state_count = AT91_MAX_STATES;
|
2011-10-28 10:50:42 +00:00
|
|
|
|
|
|
|
cpuidle_register_driver(&at91_idle_driver);
|
2009-11-01 17:40:50 +00:00
|
|
|
|
|
|
|
if (cpuidle_register_device(device)) {
|
|
|
|
printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
device_initcall(at91_init_cpuidle);
|