Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 46bcfad7 authored by Deepthi Dharwar's avatar Deepthi Dharwar Committed by Len Brown
Browse files

cpuidle: Single/Global registration of idle states

This patch makes the cpuidle_states structure global (single copy)
instead of per-cpu. The statistics needed on per-cpu basis
by the governor are kept per-cpu. This simplifies the cpuidle
subsystem as state registration is done by single cpu only.
Having single copy of cpuidle_states saves memory. Rare case
of asymmetric C-states can be handled within the cpuidle driver
and architectures such as POWER do not have asymmetric C-states.

Having single/global registration of all the idle states,
dynamic C-state transitions on x86 are handled by
the boot cpu. Here, the boot cpu  would disable all the devices,
re-populate the states and later enable all the devices,
irrespective of the cpu that would receive the notification first.

Reference:
https://lkml.org/lkml/2011/4/25/83



Signed-off-by: default avatarDeepthi Dharwar <deepthi@linux.vnet.ibm.com>
Signed-off-by: default avatarTrinabh Gupta <g.trinabh@gmail.com>
Tested-by: default avatarJean Pihet <j-pihet@ti.com>
Reviewed-by: default avatarKevin Hilman <khilman@ti.com>
Acked-by: default avatarArjan van de Ven <arjan@linux.intel.com>
Acked-by: default avatarKevin Hilman <khilman@ti.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 4202735e
Loading
Loading
Loading
Loading
+17 −14
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {


/* Actual code that puts the SoC in different idle states */
/* Actual code that puts the SoC in different idle states */
static int at91_enter_idle(struct cpuidle_device *dev,
static int at91_enter_idle(struct cpuidle_device *dev,
			struct cpuidle_driver *drv,
			       int index)
			       int index)
{
{
	struct timeval before, after;
	struct timeval before, after;
@@ -64,27 +65,29 @@ static int at91_enter_idle(struct cpuidle_device *dev,
static int at91_init_cpuidle(void)
static int at91_init_cpuidle(void)
{
{
	struct cpuidle_device *device;
	struct cpuidle_device *device;

	struct cpuidle_driver *driver = &at91_idle_driver;
	cpuidle_register_driver(&at91_idle_driver);


	device = &per_cpu(at91_cpuidle_device, smp_processor_id());
	device = &per_cpu(at91_cpuidle_device, smp_processor_id());
	device->state_count = AT91_MAX_STATES;
	device->state_count = AT91_MAX_STATES;
	driver->state_count = AT91_MAX_STATES;


	/* Wait for interrupt state */
	/* Wait for interrupt state */
	device->states[0].enter = at91_enter_idle;
	driver->states[0].enter = at91_enter_idle;
	device->states[0].exit_latency = 1;
	driver->states[0].exit_latency = 1;
	device->states[0].target_residency = 10000;
	driver->states[0].target_residency = 10000;
	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[0].name, "WFI");
	strcpy(driver->states[0].name, "WFI");
	strcpy(device->states[0].desc, "Wait for interrupt");
	strcpy(driver->states[0].desc, "Wait for interrupt");


	/* Wait for interrupt and RAM self refresh state */
	/* Wait for interrupt and RAM self refresh state */
	device->states[1].enter = at91_enter_idle;
	driver->states[1].enter = at91_enter_idle;
	device->states[1].exit_latency = 10;
	driver->states[1].exit_latency = 10;
	device->states[1].target_residency = 10000;
	driver->states[1].target_residency = 10000;
	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[1].name, "RAM_SR");
	strcpy(driver->states[1].name, "RAM_SR");
	strcpy(device->states[1].desc, "WFI and RAM Self Refresh");
	strcpy(driver->states[1].desc, "WFI and RAM Self Refresh");

	cpuidle_register_driver(&at91_idle_driver);


	if (cpuidle_register_device(device)) {
	if (cpuidle_register_device(device)) {
		printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
		printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
+21 −18
Original line number Original line Diff line number Diff line
@@ -78,6 +78,7 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {


/* Actual code that puts the SoC in different idle states */
/* Actual code that puts the SoC in different idle states */
static int davinci_enter_idle(struct cpuidle_device *dev,
static int davinci_enter_idle(struct cpuidle_device *dev,
				struct cpuidle_driver *drv,
						int index)
						int index)
{
{
	struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
	struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
@@ -109,6 +110,7 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
{
{
	int ret;
	int ret;
	struct cpuidle_device *device;
	struct cpuidle_device *device;
	struct cpuidle_driver *driver = &davinci_idle_driver;
	struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
	struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;


	device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
	device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
@@ -120,32 +122,33 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)


	ddr2_reg_base = pdata->ddr2_ctlr_base;
	ddr2_reg_base = pdata->ddr2_ctlr_base;


	ret = cpuidle_register_driver(&davinci_idle_driver);
	if (ret) {
		dev_err(&pdev->dev, "failed to register driver\n");
		return ret;
	}

	/* Wait for interrupt state */
	/* Wait for interrupt state */
	device->states[0].enter = davinci_enter_idle;
	driver->states[0].enter = davinci_enter_idle;
	device->states[0].exit_latency = 1;
	driver->states[0].exit_latency = 1;
	device->states[0].target_residency = 10000;
	driver->states[0].target_residency = 10000;
	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[0].name, "WFI");
	strcpy(driver->states[0].name, "WFI");
	strcpy(device->states[0].desc, "Wait for interrupt");
	strcpy(driver->states[0].desc, "Wait for interrupt");


	/* Wait for interrupt and DDR self refresh state */
	/* Wait for interrupt and DDR self refresh state */
	device->states[1].enter = davinci_enter_idle;
	driver->states[1].enter = davinci_enter_idle;
	device->states[1].exit_latency = 10;
	driver->states[1].exit_latency = 10;
	device->states[1].target_residency = 10000;
	driver->states[1].target_residency = 10000;
	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[1].name, "DDR SR");
	strcpy(driver->states[1].name, "DDR SR");
	strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
	strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
	if (pdata->ddr2_pdown)
	if (pdata->ddr2_pdown)
		davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
		davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
	cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]);
	cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]);


	device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
	device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
	driver->state_count = DAVINCI_CPUIDLE_MAX_STATES;

	ret = cpuidle_register_driver(&davinci_idle_driver);
	if (ret) {
		dev_err(&pdev->dev, "failed to register driver\n");
		return ret;
	}


	ret = cpuidle_register_device(device);
	ret = cpuidle_register_device(device);
	if (ret) {
	if (ret) {
+13 −10
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@
#include <asm/proc-fns.h>
#include <asm/proc-fns.h>


static int exynos4_enter_idle(struct cpuidle_device *dev,
static int exynos4_enter_idle(struct cpuidle_device *dev,
			struct cpuidle_driver *drv,
			      int index);
			      int index);


static struct cpuidle_state exynos4_cpuidle_set[] = {
static struct cpuidle_state exynos4_cpuidle_set[] = {
@@ -37,6 +38,7 @@ static struct cpuidle_driver exynos4_idle_driver = {
};
};


static int exynos4_enter_idle(struct cpuidle_device *dev,
static int exynos4_enter_idle(struct cpuidle_device *dev,
				struct cpuidle_driver *drv,
			      int index)
			      int index)
{
{
	struct timeval before, after;
	struct timeval before, after;
@@ -60,22 +62,23 @@ static int __init exynos4_init_cpuidle(void)
{
{
	int i, max_cpuidle_state, cpu_id;
	int i, max_cpuidle_state, cpu_id;
	struct cpuidle_device *device;
	struct cpuidle_device *device;
	struct cpuidle_driver *drv = &exynos4_idle_driver;


	/* Setup cpuidle driver */
	drv->state_count = (sizeof(exynos4_cpuidle_set) /
				       sizeof(struct cpuidle_state));
	max_cpuidle_state = drv->state_count;
	for (i = 0; i < max_cpuidle_state; i++) {
		memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
				sizeof(struct cpuidle_state));
	}
	cpuidle_register_driver(&exynos4_idle_driver);
	cpuidle_register_driver(&exynos4_idle_driver);


	for_each_cpu(cpu_id, cpu_online_mask) {
	for_each_cpu(cpu_id, cpu_online_mask) {
		device = &per_cpu(exynos4_cpuidle_device, cpu_id);
		device = &per_cpu(exynos4_cpuidle_device, cpu_id);
		device->cpu = cpu_id;
		device->cpu = cpu_id;


		device->state_count = (sizeof(exynos4_cpuidle_set) /
		device->state_count = drv->state_count;
					       sizeof(struct cpuidle_state));

		max_cpuidle_state = device->state_count;

		for (i = 0; i < max_cpuidle_state; i++) {
			memcpy(&device->states[i], &exynos4_cpuidle_set[i],
					sizeof(struct cpuidle_state));
		}


		if (cpuidle_register_device(device)) {
		if (cpuidle_register_device(device)) {
			printk(KERN_ERR "CPUidle register device failed\n,");
			printk(KERN_ERR "CPUidle register device failed\n,");
+16 −14
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@ static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);


/* Actual code that puts the SoC in different idle states */
/* Actual code that puts the SoC in different idle states */
static int kirkwood_enter_idle(struct cpuidle_device *dev,
static int kirkwood_enter_idle(struct cpuidle_device *dev,
				struct cpuidle_driver *drv,
			       int index)
			       int index)
{
{
	struct timeval before, after;
	struct timeval before, after;
@@ -68,28 +69,29 @@ static int kirkwood_enter_idle(struct cpuidle_device *dev,
static int kirkwood_init_cpuidle(void)
static int kirkwood_init_cpuidle(void)
{
{
	struct cpuidle_device *device;
	struct cpuidle_device *device;

	struct cpuidle_driver *driver = &kirkwood_idle_driver;
	cpuidle_register_driver(&kirkwood_idle_driver);


	device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
	device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
	device->state_count = KIRKWOOD_MAX_STATES;
	device->state_count = KIRKWOOD_MAX_STATES;
	driver->state_count = KIRKWOOD_MAX_STATES;


	/* Wait for interrupt state */
	/* Wait for interrupt state */
	device->states[0].enter = kirkwood_enter_idle;
	driver->states[0].enter = kirkwood_enter_idle;
	device->states[0].exit_latency = 1;
	driver->states[0].exit_latency = 1;
	device->states[0].target_residency = 10000;
	driver->states[0].target_residency = 10000;
	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[0].name, "WFI");
	strcpy(driver->states[0].name, "WFI");
	strcpy(device->states[0].desc, "Wait for interrupt");
	strcpy(driver->states[0].desc, "Wait for interrupt");


	/* Wait for interrupt and DDR self refresh state */
	/* Wait for interrupt and DDR self refresh state */
	device->states[1].enter = kirkwood_enter_idle;
	driver->states[1].enter = kirkwood_enter_idle;
	device->states[1].exit_latency = 10;
	driver->states[1].exit_latency = 10;
	device->states[1].target_residency = 10000;
	driver->states[1].target_residency = 10000;
	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[1].name, "DDR SR");
	strcpy(driver->states[1].name, "DDR SR");
	strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
	strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");


	cpuidle_register_driver(&kirkwood_idle_driver);
	if (cpuidle_register_device(device)) {
	if (cpuidle_register_device(device)) {
		printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n");
		printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n");
		return -EIO;
		return -EIO;
+49 −24
Original line number Original line Diff line number Diff line
@@ -88,12 +88,14 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
/**
/**
 * omap3_enter_idle - Programs OMAP3 to enter the specified state
 * omap3_enter_idle - Programs OMAP3 to enter the specified state
 * @dev: cpuidle device
 * @dev: cpuidle device
 * @drv: cpuidle driver
 * @index: the index of state to be entered
 * @index: the index of state to be entered
 *
 *
 * Called from the CPUidle framework to program the device to the
 * Called from the CPUidle framework to program the device to the
 * specified target state selected by the governor.
 * specified target state selected by the governor.
 */
 */
static int omap3_enter_idle(struct cpuidle_device *dev,
static int omap3_enter_idle(struct cpuidle_device *dev,
				struct cpuidle_driver *drv,
				int index)
				int index)
{
{
	struct omap3_idle_statedata *cx =
	struct omap3_idle_statedata *cx =
@@ -148,6 +150,7 @@ return_sleep_time:
/**
/**
 * next_valid_state - Find next valid C-state
 * next_valid_state - Find next valid C-state
 * @dev: cpuidle device
 * @dev: cpuidle device
 * @drv: cpuidle driver
 * @index: Index of currently selected c-state
 * @index: Index of currently selected c-state
 *
 *
 * If the state corresponding to index is valid, index is returned back
 * If the state corresponding to index is valid, index is returned back
@@ -158,10 +161,11 @@ return_sleep_time:
 * if it satisfies the enable_off_mode condition.
 * if it satisfies the enable_off_mode condition.
 */
 */
static int next_valid_state(struct cpuidle_device *dev,
static int next_valid_state(struct cpuidle_device *dev,
			struct cpuidle_driver *drv,
				int index)
				int index)
{
{
	struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
	struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
	struct cpuidle_state *curr = &dev->states[index];
	struct cpuidle_state *curr = &drv->states[index];
	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
	u32 mpu_deepest_state = PWRDM_POWER_RET;
	u32 mpu_deepest_state = PWRDM_POWER_RET;
	u32 core_deepest_state = PWRDM_POWER_RET;
	u32 core_deepest_state = PWRDM_POWER_RET;
@@ -188,7 +192,7 @@ static int next_valid_state(struct cpuidle_device *dev,


		/* Reach the current state starting at highest C-state */
		/* Reach the current state starting at highest C-state */
		for (; idx >= 0; idx--) {
		for (; idx >= 0; idx--) {
			if (&dev->states[idx] == curr) {
			if (&drv->states[idx] == curr) {
				next_index = idx;
				next_index = idx;
				break;
				break;
			}
			}
@@ -224,12 +228,14 @@ static int next_valid_state(struct cpuidle_device *dev,
/**
/**
 * omap3_enter_idle_bm - Checks for any bus activity
 * omap3_enter_idle_bm - Checks for any bus activity
 * @dev: cpuidle device
 * @dev: cpuidle device
 * @drv: cpuidle driver
 * @index: array index of target state to be programmed
 * @index: array index of target state to be programmed
 *
 *
 * This function checks for any pending activity and then programs
 * This function checks for any pending activity and then programs
 * the device to the specified or a safer state.
 * the device to the specified or a safer state.
 */
 */
static int omap3_enter_idle_bm(struct cpuidle_device *dev,
static int omap3_enter_idle_bm(struct cpuidle_device *dev,
				struct cpuidle_driver *drv,
			       int index)
			       int index)
{
{
	int new_state_idx;
	int new_state_idx;
@@ -238,7 +244,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
	int ret;
	int ret;


	if (!omap3_can_sleep()) {
	if (!omap3_can_sleep()) {
		new_state_idx = dev->safe_state_index;
		new_state_idx = drv->safe_state_index;
		goto select_state;
		goto select_state;
	}
	}


@@ -248,7 +254,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
	 */
	 */
	cam_state = pwrdm_read_pwrst(cam_pd);
	cam_state = pwrdm_read_pwrst(cam_pd);
	if (cam_state == PWRDM_POWER_ON) {
	if (cam_state == PWRDM_POWER_ON) {
		new_state_idx = dev->safe_state_index;
		new_state_idx = drv->safe_state_index;
		goto select_state;
		goto select_state;
	}
	}


@@ -275,10 +281,10 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
	if (per_next_state != per_saved_state)
	if (per_next_state != per_saved_state)
		pwrdm_set_next_pwrst(per_pd, per_next_state);
		pwrdm_set_next_pwrst(per_pd, per_next_state);


	new_state_idx = next_valid_state(dev, index);
	new_state_idx = next_valid_state(dev, drv, index);


select_state:
select_state:
	ret = omap3_enter_idle(dev, new_state_idx);
	ret = omap3_enter_idle(dev, drv, new_state_idx);


	/* Restore original PER state if it was modified */
	/* Restore original PER state if it was modified */
	if (per_next_state != per_saved_state)
	if (per_next_state != per_saved_state)
@@ -311,22 +317,30 @@ struct cpuidle_driver omap3_idle_driver = {
	.owner = 	THIS_MODULE,
	.owner = 	THIS_MODULE,
};
};


/* Helper to fill the C-state common data and register the driver_data */
/* Helper to fill the C-state common data*/
static inline struct omap3_idle_statedata *_fill_cstate(
static inline void _fill_cstate(struct cpuidle_driver *drv,
					struct cpuidle_device *dev,
					int idx, const char *descr)
					int idx, const char *descr)
{
{
	struct omap3_idle_statedata *cx = &omap3_idle_data[idx];
	struct cpuidle_state *state = &drv->states[idx];
	struct cpuidle_state *state = &dev->states[idx];
	struct cpuidle_state_usage *state_usage = &dev->states_usage[idx];


	state->exit_latency	= cpuidle_params_table[idx].exit_latency;
	state->exit_latency	= cpuidle_params_table[idx].exit_latency;
	state->target_residency	= cpuidle_params_table[idx].target_residency;
	state->target_residency	= cpuidle_params_table[idx].target_residency;
	state->flags		= CPUIDLE_FLAG_TIME_VALID;
	state->flags		= CPUIDLE_FLAG_TIME_VALID;
	state->enter		= omap3_enter_idle_bm;
	state->enter		= omap3_enter_idle_bm;
	cx->valid		= cpuidle_params_table[idx].valid;
	sprintf(state->name, "C%d", idx + 1);
	sprintf(state->name, "C%d", idx + 1);
	strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
	strncpy(state->desc, descr, CPUIDLE_DESC_LEN);

}

/* Helper to register the driver_data */
static inline struct omap3_idle_statedata *_fill_cstate_usage(
					struct cpuidle_device *dev,
					int idx)
{
	struct omap3_idle_statedata *cx = &omap3_idle_data[idx];
	struct cpuidle_state_usage *state_usage = &dev->states_usage[idx];

	cx->valid		= cpuidle_params_table[idx].valid;
	cpuidle_set_statedata(state_usage, cx);
	cpuidle_set_statedata(state_usage, cx);


	return cx;
	return cx;
@@ -341,6 +355,7 @@ static inline struct omap3_idle_statedata *_fill_cstate(
int __init omap3_idle_init(void)
int __init omap3_idle_init(void)
{
{
	struct cpuidle_device *dev;
	struct cpuidle_device *dev;
	struct cpuidle_driver *drv = &omap3_idle_driver;
	struct omap3_idle_statedata *cx;
	struct omap3_idle_statedata *cx;


	mpu_pd = pwrdm_lookup("mpu_pwrdm");
	mpu_pd = pwrdm_lookup("mpu_pwrdm");
@@ -348,45 +363,52 @@ int __init omap3_idle_init(void)
	per_pd = pwrdm_lookup("per_pwrdm");
	per_pd = pwrdm_lookup("per_pwrdm");
	cam_pd = pwrdm_lookup("cam_pwrdm");
	cam_pd = pwrdm_lookup("cam_pwrdm");


	cpuidle_register_driver(&omap3_idle_driver);

	drv->safe_state_index = -1;
	dev = &per_cpu(omap3_idle_dev, smp_processor_id());
	dev = &per_cpu(omap3_idle_dev, smp_processor_id());
	dev->safe_state_index = -1;


	/* C1 . MPU WFI + Core active */
	/* C1 . MPU WFI + Core active */
	cx = _fill_cstate(dev, 0, "MPU ON + CORE ON");
	_fill_cstate(drv, 0, "MPU ON + CORE ON");
	(&dev->states[0])->enter = omap3_enter_idle;
	(&drv->states[0])->enter = omap3_enter_idle;
	dev->safe_state_index = 0;
	drv->safe_state_index = 0;
	cx = _fill_cstate_usage(dev, 0);
	cx->valid = 1;	/* C1 is always valid */
	cx->valid = 1;	/* C1 is always valid */
	cx->mpu_state = PWRDM_POWER_ON;
	cx->mpu_state = PWRDM_POWER_ON;
	cx->core_state = PWRDM_POWER_ON;
	cx->core_state = PWRDM_POWER_ON;


	/* C2 . MPU WFI + Core inactive */
	/* C2 . MPU WFI + Core inactive */
	cx = _fill_cstate(dev, 1, "MPU ON + CORE ON");
	_fill_cstate(drv, 1, "MPU ON + CORE ON");
	cx = _fill_cstate_usage(dev, 1);
	cx->mpu_state = PWRDM_POWER_ON;
	cx->mpu_state = PWRDM_POWER_ON;
	cx->core_state = PWRDM_POWER_ON;
	cx->core_state = PWRDM_POWER_ON;


	/* C3 . MPU CSWR + Core inactive */
	/* C3 . MPU CSWR + Core inactive */
	cx = _fill_cstate(dev, 2, "MPU RET + CORE ON");
	_fill_cstate(drv, 2, "MPU RET + CORE ON");
	cx = _fill_cstate_usage(dev, 2);
	cx->mpu_state = PWRDM_POWER_RET;
	cx->mpu_state = PWRDM_POWER_RET;
	cx->core_state = PWRDM_POWER_ON;
	cx->core_state = PWRDM_POWER_ON;


	/* C4 . MPU OFF + Core inactive */
	/* C4 . MPU OFF + Core inactive */
	cx = _fill_cstate(dev, 3, "MPU OFF + CORE ON");
	_fill_cstate(drv, 3, "MPU OFF + CORE ON");
	cx = _fill_cstate_usage(dev, 3);
	cx->mpu_state = PWRDM_POWER_OFF;
	cx->mpu_state = PWRDM_POWER_OFF;
	cx->core_state = PWRDM_POWER_ON;
	cx->core_state = PWRDM_POWER_ON;


	/* C5 . MPU RET + Core RET */
	/* C5 . MPU RET + Core RET */
	cx = _fill_cstate(dev, 4, "MPU RET + CORE RET");
	_fill_cstate(drv, 4, "MPU RET + CORE RET");
	cx = _fill_cstate_usage(dev, 4);
	cx->mpu_state = PWRDM_POWER_RET;
	cx->mpu_state = PWRDM_POWER_RET;
	cx->core_state = PWRDM_POWER_RET;
	cx->core_state = PWRDM_POWER_RET;


	/* C6 . MPU OFF + Core RET */
	/* C6 . MPU OFF + Core RET */
	cx = _fill_cstate(dev, 5, "MPU OFF + CORE RET");
	_fill_cstate(drv, 5, "MPU OFF + CORE RET");
	cx = _fill_cstate_usage(dev, 5);
	cx->mpu_state = PWRDM_POWER_OFF;
	cx->mpu_state = PWRDM_POWER_OFF;
	cx->core_state = PWRDM_POWER_RET;
	cx->core_state = PWRDM_POWER_RET;


	/* C7 . MPU OFF + Core OFF */
	/* C7 . MPU OFF + Core OFF */
	cx = _fill_cstate(dev, 6, "MPU OFF + CORE OFF");
	_fill_cstate(drv, 6, "MPU OFF + CORE OFF");
	cx = _fill_cstate_usage(dev, 6);
	/*
	/*
	 * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
	 * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
	 * enable OFF mode in a stable form for previous revisions.
	 * enable OFF mode in a stable form for previous revisions.
@@ -400,6 +422,9 @@ int __init omap3_idle_init(void)
	cx->mpu_state = PWRDM_POWER_OFF;
	cx->mpu_state = PWRDM_POWER_OFF;
	cx->core_state = PWRDM_POWER_OFF;
	cx->core_state = PWRDM_POWER_OFF;


	drv->state_count = OMAP3_NUM_STATES;
	cpuidle_register_driver(&omap3_idle_driver);

	dev->state_count = OMAP3_NUM_STATES;
	dev->state_count = OMAP3_NUM_STATES;
	if (cpuidle_register_device(dev)) {
	if (cpuidle_register_device(dev)) {
		printk(KERN_ERR "%s: CPUidle register device failed\n",
		printk(KERN_ERR "%s: CPUidle register device failed\n",
Loading