-From: "Rajendra Nayak" <rnayak@ti.com>\r
-To: <linux-omap@vger.kernel.org>\r
-Subject: [PATCH 01/02] OMAP3 CPUidle driver\r
-Date: Tue, 10 Jun 2008 12:39:00 +0530\r
-\r
-This patch adds the OMAP3 cpuidle driver. Irq enable/disable is done in the core cpuidle driver\r
-before it queries the governor for the next state.\r
-\r
-Signed-off-by: Rajendra Nayak <rnayak@ti.com> \r
-\r
----\r
- arch/arm/mach-omap2/Makefile | 2 \r
- arch/arm/mach-omap2/cpuidle34xx.c | 293 ++++++++++++++++++++++++++++++++++++++\r
- arch/arm/mach-omap2/cpuidle34xx.h | 51 ++++++\r
- arch/arm/mach-omap2/pm34xx.c | 5 \r
- drivers/cpuidle/cpuidle.c | 10 +\r
- 5 files changed, 359 insertions(+), 2 deletions(-)\r
-\r
-Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile\r
-===================================================================\r
---- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:33.855303920 +0530\r
-+++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:39.569121361 +0530\r
-@@ -20,7 +20,7 @@ obj-y += pm.o\r
- obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o\r
- obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o\r
- obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o\r
--obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o\r
-+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o\r
- obj-$(CONFIG_PM_DEBUG) += pm-debug.o\r
- endif\r
- \r
-Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c\r
-===================================================================\r
---- /dev/null 1970-01-01 00:00:00.000000000 +0000\r
-+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-06-10 11:41:27.644820323 +0530\r
-@@ -0,0 +1,293 @@\r
-+/*\r
-+ * linux/arch/arm/mach-omap2/cpuidle34xx.c\r
-+ *\r
-+ * OMAP3 CPU IDLE Routines\r
-+ *\r
-+ * Copyright (C) 2007-2008 Texas Instruments, Inc.\r
-+ * Rajendra Nayak <rnayak@ti.com>\r
-+ *\r
-+ * Copyright (C) 2007 Texas Instruments, Inc.\r
-+ * Karthik Dasu <karthik-dp@ti.com>\r
-+ *\r
-+ * Copyright (C) 2006 Nokia Corporation\r
-+ * Tony Lindgren <tony@atomide.com>\r
-+ *\r
-+ * Copyright (C) 2005 Texas Instruments, Inc.\r
-+ * Richard Woodruff <r-woodruff2@ti.com>\r
-+ *\r
-+ * This program is free software; you can redistribute it and/or modify\r
-+ * it under the terms of the GNU General Public License version 2 as\r
-+ * published by the Free Software Foundation.\r
-+ */\r
-+\r
-+#include <linux/cpuidle.h>\r
-+#include <asm/arch/pm.h>\r
-+#include <asm/arch/prcm.h>\r
-+#include <asm/arch/powerdomain.h>\r
-+#include <asm/arch/clockdomain.h>\r
-+#include <asm/arch/irqs.h>\r
-+#include "cpuidle34xx.h"\r
-+\r
-+#ifdef CONFIG_CPU_IDLE\r
-+\r
-+struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];\r
-+struct omap3_processor_cx current_cx_state;\r
-+\r
-+static int omap3_idle_bm_check(void)\r
-+{\r
-+ /* Check for omap3_fclks_active() here once available */\r
-+ return 0;\r
-+}\r
-+\r
-+/* omap3_enter_idle - Programs OMAP3 to enter the specified state.\r
-+ * returns the total time during which the system was idle.\r
-+ */\r
-+static int omap3_enter_idle(struct cpuidle_device *dev,\r
-+ struct cpuidle_state *state)\r
-+{\r
-+ struct omap3_processor_cx *cx = cpuidle_get_statedata(state);\r
-+ struct timespec ts_preidle, ts_postidle, ts_idle;\r
-+ struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd;\r
-+ int neon_pwrst;\r
-+\r
-+ current_cx_state = *cx;\r
-+\r
-+ if (cx->type == OMAP3_STATE_C0) {\r
-+ /* Do nothing for C0, not even a wfi */\r
-+ return 0;\r
-+ }\r
-+\r
-+ /* Used to keep track of the total time in idle */\r
-+ getnstimeofday(&ts_preidle);\r
-+\r
-+ mpu_pd = pwrdm_lookup("mpu_pwrdm");\r
-+ core_pd = pwrdm_lookup("core_pwrdm");\r
-+ per_pd = pwrdm_lookup("per_pwrdm");\r
-+ neon_pd = pwrdm_lookup("neon_pwrdm");\r
-+\r
-+ /* Reset previous power state registers */\r
-+ pwrdm_clear_all_prev_pwrst(mpu_pd);\r
-+ pwrdm_clear_all_prev_pwrst(neon_pd);\r
-+ pwrdm_clear_all_prev_pwrst(core_pd);\r
-+ pwrdm_clear_all_prev_pwrst(per_pd);\r
-+\r
-+ if (omap_irq_pending())\r
-+ return 0;\r
-+\r
-+ neon_pwrst = pwrdm_read_pwrst(neon_pd);\r
-+\r
-+ /* Program MPU/NEON to target state */\r
-+ if (cx->mpu_state < PWRDM_POWER_ON) {\r
-+ if (neon_pwrst == PWRDM_POWER_ON) {\r
-+ if (cx->mpu_state == PWRDM_POWER_RET)\r
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET);\r
-+ else if (cx->mpu_state == PWRDM_POWER_OFF)\r
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF);\r
-+ }\r
-+ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);\r
-+ }\r
-+\r
-+ /* Program CORE to target state */\r
-+ if (cx->core_state < PWRDM_POWER_ON)\r
-+ pwrdm_set_next_pwrst(core_pd, cx->core_state);\r
-+\r
-+ /* Execute ARM wfi */\r
-+ omap_sram_idle();\r
-+\r
-+ /* Program MPU/NEON to ON */\r
-+ if (cx->mpu_state < PWRDM_POWER_ON) {\r
-+ if (neon_pwrst == PWRDM_POWER_ON)\r
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON);\r
-+ pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);\r
-+ }\r
-+\r
-+ if (cx->core_state < PWRDM_POWER_ON)\r
-+ pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);\r
-+\r
-+ getnstimeofday(&ts_postidle);\r
-+ ts_idle = timespec_sub(ts_postidle, ts_preidle);\r
-+ return timespec_to_ns(&ts_idle);\r
-+}\r
-+\r
-+/*\r
-+ * omap3_enter_idle_bm - enter function for states with CPUIDLE_FLAG_CHECK_BM\r
-+ *\r
-+ * This function checks for all the pre-requisites needed for OMAP3 to enter\r
-+ * CORE RET/OFF state. It then calls omap3_enter_idle to program the desired\r
-+ * C state.\r
-+ */\r
-+static int omap3_enter_idle_bm(struct cpuidle_device *dev,\r
-+ struct cpuidle_state *state)\r
-+{\r
-+ struct cpuidle_state *new_state = NULL;\r
-+ int i, j;\r
-+\r
-+ if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {\r
-+\r
-+ /* Find current state in list */\r
-+ for (i = 0; i < OMAP3_MAX_STATES; i++)\r
-+ if (state == &dev->states[i])\r
-+ break;\r
-+ BUG_ON(i == OMAP3_MAX_STATES);\r
-+\r
-+ /* Back up to non 'CHECK_BM' state */\r
-+ for (j = i - 1; j > 0; j--) {\r
-+ struct cpuidle_state *s = &dev->states[j];\r
-+\r
-+ if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) {\r
-+ new_state = s;\r
-+ break;\r
-+ }\r
-+ }\r
-+\r
-+ pr_debug("%s: Bus activity: Entering %s (instead of %s)\n",\r
-+ __FUNCTION__, new_state->name, state->name);\r
-+ }\r
-+\r
-+ return omap3_enter_idle(dev, new_state ? : state);\r
-+}\r
-+\r
-+DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);\r
-+\r
-+/* omap3_init_power_states - Initialises the OMAP3 specific C states.\r
-+ * Below is the desciption of each C state.\r
-+ *\r
-+ C0 . System executing code\r
-+ C1 . MPU WFI + Core active\r
-+ C2 . MPU CSWR + Core active\r
-+ C3 . MPU OFF + Core active\r
-+ C4 . MPU CSWR + Core CSWR\r
-+ C5 . MPU OFF + Core CSWR\r
-+ C6 . MPU OFF + Core OFF\r
-+ */\r
-+void omap_init_power_states(void)\r
-+{\r
-+ /* C0 . System executing code */\r
-+ omap3_power_states[0].valid = 1;\r
-+ omap3_power_states[0].type = OMAP3_STATE_C0;\r
-+ omap3_power_states[0].sleep_latency = 0;\r
-+ omap3_power_states[0].wakeup_latency = 0;\r
-+ omap3_power_states[0].threshold = 0;\r
-+ omap3_power_states[0].mpu_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[0].core_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_SHALLOW;\r
-+\r
-+ /* C1 . MPU WFI + Core active */\r
-+ omap3_power_states[1].valid = 1;\r
-+ omap3_power_states[1].type = OMAP3_STATE_C1;\r
-+ omap3_power_states[1].sleep_latency = 10;\r
-+ omap3_power_states[1].wakeup_latency = 10;\r
-+ omap3_power_states[1].threshold = 30;\r
-+ omap3_power_states[1].mpu_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[1].core_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_SHALLOW;\r
-+\r
-+ /* C2 . MPU CSWR + Core active */\r
-+ omap3_power_states[2].valid = 1;\r
-+ omap3_power_states[2].type = OMAP3_STATE_C2;\r
-+ omap3_power_states[2].sleep_latency = 50;\r
-+ omap3_power_states[2].wakeup_latency = 50;\r
-+ omap3_power_states[2].threshold = 300;\r
-+ omap3_power_states[2].mpu_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[2].core_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_BALANCED;\r
-+\r
-+ /* C3 . MPU OFF + Core active */\r
-+ omap3_power_states[3].valid = 0;\r
-+ omap3_power_states[3].type = OMAP3_STATE_C3;\r
-+ omap3_power_states[3].sleep_latency = 1500;\r
-+ omap3_power_states[3].wakeup_latency = 1800;\r
-+ omap3_power_states[3].threshold = 4000;\r
-+ omap3_power_states[3].mpu_state = PWRDM_POWER_OFF;\r
-+ omap3_power_states[3].core_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_BALANCED;\r
-+\r
-+ /* C4 . MPU CSWR + Core CSWR*/\r
-+ omap3_power_states[4].valid = 1;\r
-+ omap3_power_states[4].type = OMAP3_STATE_C4;\r
-+ omap3_power_states[4].sleep_latency = 2500;\r
-+ omap3_power_states[4].wakeup_latency = 7500;\r
-+ omap3_power_states[4].threshold = 12000;\r
-+ omap3_power_states[4].mpu_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[4].core_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;\r
-+\r
-+ /* C5 . MPU OFF + Core CSWR */\r
-+ omap3_power_states[5].valid = 0;\r
-+ omap3_power_states[5].type = OMAP3_STATE_C5;\r
-+ omap3_power_states[5].sleep_latency = 3000;\r
-+ omap3_power_states[5].wakeup_latency = 8500;\r
-+ omap3_power_states[5].threshold = 15000;\r
-+ omap3_power_states[5].mpu_state = PWRDM_POWER_OFF;\r
-+ omap3_power_states[5].core_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;\r
-+\r
-+ /* C6 . MPU OFF + Core OFF */\r
-+ omap3_power_states[6].valid = 0;\r
-+ omap3_power_states[6].type = OMAP3_STATE_C6;\r
-+ omap3_power_states[6].sleep_latency = 10000;\r
-+ omap3_power_states[6].wakeup_latency = 30000;\r
-+ omap3_power_states[6].threshold = 300000;\r
-+ omap3_power_states[6].mpu_state = PWRDM_POWER_OFF;\r
-+ omap3_power_states[6].core_state = PWRDM_POWER_OFF;\r
-+ omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM;\r
-+}\r
-+\r
-+struct cpuidle_driver omap3_idle_driver = {\r
-+ .name = "omap3_idle",\r
-+ .owner = THIS_MODULE,\r
-+};\r
-+/*\r
-+ * omap3_idle_init - Init routine for OMAP3 idle.\r
-+ * Registers the OMAP3 specific cpuidle driver with the cpuidle f/w\r
-+ * with the valid set of states.\r
-+ */\r
-+int omap3_idle_init(void)\r
-+{\r
-+ int i, count = 0;\r
-+ struct omap3_processor_cx *cx;\r
-+ struct cpuidle_state *state;\r
-+ struct cpuidle_device *dev;\r
-+\r
-+ omap_init_power_states();\r
-+ cpuidle_register_driver(&omap3_idle_driver);\r
-+\r
-+ dev = &per_cpu(omap3_idle_dev, smp_processor_id());\r
-+\r
-+ for (i = 0; i < OMAP3_MAX_STATES; i++) {\r
-+ cx = &omap3_power_states[i];\r
-+ state = &dev->states[count];\r
-+\r
-+ if (!cx->valid)\r
-+ continue;\r
-+ cpuidle_set_statedata(state, cx);\r
-+ state->exit_latency = cx->sleep_latency + cx->wakeup_latency;\r
-+ state->target_residency = cx->threshold;\r
-+ state->flags = cx->flags;\r
-+ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?\r
-+ omap3_enter_idle_bm : omap3_enter_idle;\r
-+ sprintf(state->name, "C%d", count+1);\r
-+ count++;\r
-+ }\r
-+\r
-+ if (!count)\r
-+ return -EINVAL;\r
-+ dev->state_count = count;\r
-+\r
-+ if (cpuidle_register_device(dev)) {\r
-+ printk(KERN_ERR "%s: CPUidle register device failed\n",\r
-+ __FUNCTION__);\r
-+ return -EIO;\r
-+ }\r
-+\r
-+ return 0;\r
-+}\r
-+__initcall(omap3_idle_init);\r
-+#endif /* CONFIG_CPU_IDLE */\r
-Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h\r
-===================================================================\r
---- /dev/null 1970-01-01 00:00:00.000000000 +0000\r
-+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h 2008-06-09 20:15:39.569121361 +0530\r
-@@ -0,0 +1,51 @@\r
-+/*\r
-+ * linux/arch/arm/mach-omap2/cpuidle34xx.h\r
-+ *\r
-+ * OMAP3 cpuidle structure definitions\r
-+ *\r
-+ * Copyright (C) 2007-2008 Texas Instruments, Inc.\r
-+ * Written by Rajendra Nayak <rnayak@ti.com>\r
-+ *\r
-+ * This program is free software; you can redistribute it and/or modify\r
-+ * it under the terms of the GNU General Public License version 2 as\r
-+ * published by the Free Software Foundation.\r
-+ *\r
-+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
-+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
-+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
-+ *\r
-+ * History:\r
-+ *\r
-+ */\r
-+\r
-+#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX\r
-+#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX\r
-+\r
-+#define OMAP3_MAX_STATES 7\r
-+#define OMAP3_STATE_C0 0 /* C0 - System executing code */\r
-+#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */\r
-+#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */\r
-+#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */\r
-+#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */\r
-+#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */\r
-+#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */\r
-+\r
-+extern void omap_sram_idle(void);\r
-+extern int omap3_irq_pending(void);\r
-+\r
-+struct omap3_processor_cx {\r
-+ u8 valid;\r
-+ u8 type;\r
-+ u32 sleep_latency;\r
-+ u32 wakeup_latency;\r
-+ u32 mpu_state;\r
-+ u32 core_state;\r
-+ u32 threshold;\r
-+ u32 flags;\r
-+};\r
-+\r
-+void omap_init_power_states(void);\r
-+int omap3_idle_init(void);\r
-+\r
-+#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */\r
-+\r
-Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c\r
-===================================================================\r
---- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:15:33.855303920 +0530\r
-+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:16:20.976798343 +0530\r
-@@ -141,7 +141,7 @@ static irqreturn_t prcm_interrupt_handle\r
- return IRQ_HANDLED;\r
- }\r
- \r
--static void omap_sram_idle(void)\r
-+void omap_sram_idle(void)\r
- {\r
- /* Variable to tell what needs to be saved and restored\r
- * in omap_sram_idle*/\r
-@@ -156,6 +156,7 @@ static void omap_sram_idle(void)\r
- \r
- mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);\r
- switch (mpu_next_state) {\r
-+ case PWRDM_POWER_ON:\r
- case PWRDM_POWER_RET:\r
- /* No need to save context */\r
- save_state = 0;\r
-@@ -386,7 +387,9 @@ int __init omap3_pm_init(void)\r
- \r
- prcm_setup_regs();\r
- \r
-+#ifndef CONFIG_CPU_IDLE\r
- pm_idle = omap3_pm_idle;\r
-+#endif\r
- \r
- err1:\r
- return ret;\r
-Index: linux-omap-2.6/drivers/cpuidle/cpuidle.c\r
-===================================================================\r
---- linux-omap-2.6.orig/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:33.856303888 +0530\r
-+++ linux-omap-2.6/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:39.570121329 +0530\r
-@@ -58,6 +58,11 @@ static void cpuidle_idle_call(void)\r
- return;\r
- }\r
- \r
-+#ifdef CONFIG_ARCH_OMAP3\r
-+ local_irq_disable();\r
-+ local_fiq_disable();\r
-+#endif\r
-+\r
- /* ask the governor for the next state */\r
- next_state = cpuidle_curr_governor->select(dev);\r
- if (need_resched())\r
-@@ -70,6 +75,11 @@ static void cpuidle_idle_call(void)\r
- target_state->time += (unsigned long long)dev->last_residency;\r
- target_state->usage++;\r
- \r
-+#ifdef CONFIG_ARCH_OMAP3\r
-+ local_irq_enable();\r
-+ local_fiq_enable();\r
-+#endif\r
-+\r
- /* give the governor an opportunity to reflect on the outcome */\r
- if (cpuidle_curr_governor->reflect)\r
- cpuidle_curr_governor->reflect(dev);\r
-\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at http://vger.kernel.org/majordomo-info.html\r
-\r
+From: "Rajendra Nayak" <rnayak@ti.com>
+To: <linux-omap@vger.kernel.org>
+Subject: [PATCH 01/02] OMAP3 CPUidle driver
+Date: Tue, 10 Jun 2008 12:39:00 +0530
+
+This patch adds the OMAP3 cpuidle driver. Irq enable/disable is done in the core cpuidle driver
+before it queries the governor for the next state.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+
+---
+ arch/arm/mach-omap2/Makefile | 2
+ arch/arm/mach-omap2/cpuidle34xx.c | 293 ++++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-omap2/cpuidle34xx.h | 51 ++++++
+ arch/arm/mach-omap2/pm34xx.c | 5
+ drivers/cpuidle/cpuidle.c | 10 +
+ 5 files changed, 359 insertions(+), 2 deletions(-)
+
+Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:33.855303920 +0530
++++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:39.569121361 +0530
+@@ -20,7 +20,7 @@ obj-y += pm.o
+ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
+ obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o
+ obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o
+-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
++obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
+ obj-$(CONFIG_PM_DEBUG) += pm-debug.o
+ endif
+
+Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-06-10 11:41:27.644820323 +0530
+@@ -0,0 +1,293 @@
++/*
++ * linux/arch/arm/mach-omap2/cpuidle34xx.c
++ *
++ * OMAP3 CPU IDLE Routines
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Rajendra Nayak <rnayak@ti.com>
++ *
++ * Copyright (C) 2007 Texas Instruments, Inc.
++ * Karthik Dasu <karthik-dp@ti.com>
++ *
++ * Copyright (C) 2006 Nokia Corporation
++ * Tony Lindgren <tony@atomide.com>
++ *
++ * Copyright (C) 2005 Texas Instruments, Inc.
++ * Richard Woodruff <r-woodruff2@ti.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 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/cpuidle.h>
++#include <asm/arch/pm.h>
++#include <asm/arch/prcm.h>
++#include <asm/arch/powerdomain.h>
++#include <asm/arch/clockdomain.h>
++#include <asm/arch/irqs.h>
++#include "cpuidle34xx.h"
++
++#ifdef CONFIG_CPU_IDLE
++
++struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
++struct omap3_processor_cx current_cx_state;
++
++static int omap3_idle_bm_check(void)
++{
++ /* Check for omap3_fclks_active() here once available */
++ return 0;
++}
++
++/* omap3_enter_idle - Programs OMAP3 to enter the specified state.
++ * returns the total time during which the system was idle.
++ */
++static int omap3_enter_idle(struct cpuidle_device *dev,
++ struct cpuidle_state *state)
++{
++ struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
++ struct timespec ts_preidle, ts_postidle, ts_idle;
++ struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd;
++ int neon_pwrst;
++
++ current_cx_state = *cx;
++
++ if (cx->type == OMAP3_STATE_C0) {
++ /* Do nothing for C0, not even a wfi */
++ return 0;
++ }
++
++ /* Used to keep track of the total time in idle */
++ getnstimeofday(&ts_preidle);
++
++ mpu_pd = pwrdm_lookup("mpu_pwrdm");
++ core_pd = pwrdm_lookup("core_pwrdm");
++ per_pd = pwrdm_lookup("per_pwrdm");
++ neon_pd = pwrdm_lookup("neon_pwrdm");
++
++ /* Reset previous power state registers */
++ pwrdm_clear_all_prev_pwrst(mpu_pd);
++ pwrdm_clear_all_prev_pwrst(neon_pd);
++ pwrdm_clear_all_prev_pwrst(core_pd);
++ pwrdm_clear_all_prev_pwrst(per_pd);
++
++ if (omap_irq_pending())
++ return 0;
++
++ neon_pwrst = pwrdm_read_pwrst(neon_pd);
++
++ /* Program MPU/NEON to target state */
++ if (cx->mpu_state < PWRDM_POWER_ON) {
++ if (neon_pwrst == PWRDM_POWER_ON) {
++ if (cx->mpu_state == PWRDM_POWER_RET)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET);
++ else if (cx->mpu_state == PWRDM_POWER_OFF)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF);
++ }
++ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
++ }
++
++ /* Program CORE to target state */
++ if (cx->core_state < PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(core_pd, cx->core_state);
++
++ /* Execute ARM wfi */
++ omap_sram_idle();
++
++ /* Program MPU/NEON to ON */
++ if (cx->mpu_state < PWRDM_POWER_ON) {
++ if (neon_pwrst == PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON);
++ pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
++ }
++
++ if (cx->core_state < PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);
++
++ getnstimeofday(&ts_postidle);
++ ts_idle = timespec_sub(ts_postidle, ts_preidle);
++ return timespec_to_ns(&ts_idle);
++}
++
++/*
++ * omap3_enter_idle_bm - enter function for states with CPUIDLE_FLAG_CHECK_BM
++ *
++ * This function checks for all the pre-requisites needed for OMAP3 to enter
++ * CORE RET/OFF state. It then calls omap3_enter_idle to program the desired
++ * C state.
++ */
++static int omap3_enter_idle_bm(struct cpuidle_device *dev,
++ struct cpuidle_state *state)
++{
++ struct cpuidle_state *new_state = NULL;
++ int i, j;
++
++ if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
++
++ /* Find current state in list */
++ for (i = 0; i < OMAP3_MAX_STATES; i++)
++ if (state == &dev->states[i])
++ break;
++ BUG_ON(i == OMAP3_MAX_STATES);
++
++ /* Back up to non 'CHECK_BM' state */
++ for (j = i - 1; j > 0; j--) {
++ struct cpuidle_state *s = &dev->states[j];
++
++ if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) {
++ new_state = s;
++ break;
++ }
++ }
++
++ pr_debug("%s: Bus activity: Entering %s (instead of %s)\n",
++ __FUNCTION__, new_state->name, state->name);
++ }
++
++ return omap3_enter_idle(dev, new_state ? : state);
++}
++
++DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
++
++/* omap3_init_power_states - Initialises the OMAP3 specific C states.
++ * Below is the desciption of each C state.
++ *
++ C0 . System executing code
++ C1 . MPU WFI + Core active
++ C2 . MPU CSWR + Core active
++ C3 . MPU OFF + Core active
++ C4 . MPU CSWR + Core CSWR
++ C5 . MPU OFF + Core CSWR
++ C6 . MPU OFF + Core OFF
++ */
++void omap_init_power_states(void)
++{
++ /* C0 . System executing code */
++ omap3_power_states[0].valid = 1;
++ omap3_power_states[0].type = OMAP3_STATE_C0;
++ omap3_power_states[0].sleep_latency = 0;
++ omap3_power_states[0].wakeup_latency = 0;
++ omap3_power_states[0].threshold = 0;
++ omap3_power_states[0].mpu_state = PWRDM_POWER_ON;
++ omap3_power_states[0].core_state = PWRDM_POWER_ON;
++ omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_SHALLOW;
++
++ /* C1 . MPU WFI + Core active */
++ omap3_power_states[1].valid = 1;
++ omap3_power_states[1].type = OMAP3_STATE_C1;
++ omap3_power_states[1].sleep_latency = 10;
++ omap3_power_states[1].wakeup_latency = 10;
++ omap3_power_states[1].threshold = 30;
++ omap3_power_states[1].mpu_state = PWRDM_POWER_ON;
++ omap3_power_states[1].core_state = PWRDM_POWER_ON;
++ omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_SHALLOW;
++
++ /* C2 . MPU CSWR + Core active */
++ omap3_power_states[2].valid = 1;
++ omap3_power_states[2].type = OMAP3_STATE_C2;
++ omap3_power_states[2].sleep_latency = 50;
++ omap3_power_states[2].wakeup_latency = 50;
++ omap3_power_states[2].threshold = 300;
++ omap3_power_states[2].mpu_state = PWRDM_POWER_RET;
++ omap3_power_states[2].core_state = PWRDM_POWER_ON;
++ omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED;
++
++ /* C3 . MPU OFF + Core active */
++ omap3_power_states[3].valid = 0;
++ omap3_power_states[3].type = OMAP3_STATE_C3;
++ omap3_power_states[3].sleep_latency = 1500;
++ omap3_power_states[3].wakeup_latency = 1800;
++ omap3_power_states[3].threshold = 4000;
++ omap3_power_states[3].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[3].core_state = PWRDM_POWER_RET;
++ omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED;
++
++ /* C4 . MPU CSWR + Core CSWR*/
++ omap3_power_states[4].valid = 1;
++ omap3_power_states[4].type = OMAP3_STATE_C4;
++ omap3_power_states[4].sleep_latency = 2500;
++ omap3_power_states[4].wakeup_latency = 7500;
++ omap3_power_states[4].threshold = 12000;
++ omap3_power_states[4].mpu_state = PWRDM_POWER_RET;
++ omap3_power_states[4].core_state = PWRDM_POWER_RET;
++ omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
++
++ /* C5 . MPU OFF + Core CSWR */
++ omap3_power_states[5].valid = 0;
++ omap3_power_states[5].type = OMAP3_STATE_C5;
++ omap3_power_states[5].sleep_latency = 3000;
++ omap3_power_states[5].wakeup_latency = 8500;
++ omap3_power_states[5].threshold = 15000;
++ omap3_power_states[5].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[5].core_state = PWRDM_POWER_RET;
++ omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
++
++ /* C6 . MPU OFF + Core OFF */
++ omap3_power_states[6].valid = 0;
++ omap3_power_states[6].type = OMAP3_STATE_C6;
++ omap3_power_states[6].sleep_latency = 10000;
++ omap3_power_states[6].wakeup_latency = 30000;
++ omap3_power_states[6].threshold = 300000;
++ omap3_power_states[6].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[6].core_state = PWRDM_POWER_OFF;
++ omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM;
++}
++
++struct cpuidle_driver omap3_idle_driver = {
++ .name = "omap3_idle",
++ .owner = THIS_MODULE,
++};
++/*
++ * omap3_idle_init - Init routine for OMAP3 idle.
++ * Registers the OMAP3 specific cpuidle driver with the cpuidle f/w
++ * with the valid set of states.
++ */
++int omap3_idle_init(void)
++{
++ int i, count = 0;
++ struct omap3_processor_cx *cx;
++ struct cpuidle_state *state;
++ struct cpuidle_device *dev;
++
++ omap_init_power_states();
++ cpuidle_register_driver(&omap3_idle_driver);
++
++ dev = &per_cpu(omap3_idle_dev, smp_processor_id());
++
++ for (i = 0; i < OMAP3_MAX_STATES; i++) {
++ cx = &omap3_power_states[i];
++ state = &dev->states[count];
++
++ if (!cx->valid)
++ continue;
++ cpuidle_set_statedata(state, cx);
++ state->exit_latency = cx->sleep_latency + cx->wakeup_latency;
++ state->target_residency = cx->threshold;
++ state->flags = cx->flags;
++ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
++ omap3_enter_idle_bm : omap3_enter_idle;
++ sprintf(state->name, "C%d", count+1);
++ count++;
++ }
++
++ if (!count)
++ return -EINVAL;
++ dev->state_count = count;
++
++ if (cpuidle_register_device(dev)) {
++ printk(KERN_ERR "%s: CPUidle register device failed\n",
++ __FUNCTION__);
++ return -EIO;
++ }
++
++ return 0;
++}
++__initcall(omap3_idle_init);
++#endif /* CONFIG_CPU_IDLE */
+Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h 2008-06-09 20:15:39.569121361 +0530
+@@ -0,0 +1,51 @@
++/*
++ * linux/arch/arm/mach-omap2/cpuidle34xx.h
++ *
++ * OMAP3 cpuidle structure definitions
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Written by Rajendra Nayak <rnayak@ti.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 as
++ * published by the Free Software Foundation.
++ *
++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * History:
++ *
++ */
++
++#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
++#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
++
++#define OMAP3_MAX_STATES 7
++#define OMAP3_STATE_C0 0 /* C0 - System executing code */
++#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */
++#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */
++#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */
++#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */
++#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */
++#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */
++
++extern void omap_sram_idle(void);
++extern int omap3_irq_pending(void);
++
++struct omap3_processor_cx {
++ u8 valid;
++ u8 type;
++ u32 sleep_latency;
++ u32 wakeup_latency;
++ u32 mpu_state;
++ u32 core_state;
++ u32 threshold;
++ u32 flags;
++};
++
++void omap_init_power_states(void);
++int omap3_idle_init(void);
++
++#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */
++
+Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:15:33.855303920 +0530
++++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:16:20.976798343 +0530
+@@ -141,7 +141,7 @@ static irqreturn_t prcm_interrupt_handle
+ return IRQ_HANDLED;
+ }
+
+-static void omap_sram_idle(void)
++void omap_sram_idle(void)
+ {
+ /* Variable to tell what needs to be saved and restored
+ * in omap_sram_idle*/
+@@ -156,6 +156,7 @@ static void omap_sram_idle(void)
+
+ mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+ switch (mpu_next_state) {
++ case PWRDM_POWER_ON:
+ case PWRDM_POWER_RET:
+ /* No need to save context */
+ save_state = 0;
+@@ -386,7 +387,9 @@ int __init omap3_pm_init(void)
+
+ prcm_setup_regs();
+
++#ifndef CONFIG_CPU_IDLE
+ pm_idle = omap3_pm_idle;
++#endif
+
+ err1:
+ return ret;
+Index: linux-omap-2.6/drivers/cpuidle/cpuidle.c
+===================================================================
+--- linux-omap-2.6.orig/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:33.856303888 +0530
++++ linux-omap-2.6/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:39.570121329 +0530
+@@ -58,6 +58,11 @@ static void cpuidle_idle_call(void)
+ return;
+ }
+
++#ifdef CONFIG_ARCH_OMAP3
++ local_irq_disable();
++ local_fiq_disable();
++#endif
++
+ /* ask the governor for the next state */
+ next_state = cpuidle_curr_governor->select(dev);
+ if (need_resched())
+@@ -70,6 +75,11 @@ static void cpuidle_idle_call(void)
+ target_state->time += (unsigned long long)dev->last_residency;
+ target_state->usage++;
+
++#ifdef CONFIG_ARCH_OMAP3
++ local_irq_enable();
++ local_fiq_enable();
++#endif
++
+ /* give the governor an opportunity to reflect on the outcome */
+ if (cpuidle_curr_governor->reflect)
+ cpuidle_curr_governor->reflect(dev);
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
-From: "Rajendra Nayak" <rnayak@ti.com>\r
-To: <linux-omap@vger.kernel.org>\r
-Subject: [PATCH 02/02] Kconfig changes\r
-Date: Tue, 10 Jun 2008 12:39:02 +0530\r
-\r
-Updates the CPUidle Kconfig\r
-\r
-Signed-off-by: Rajendra Nayak <rnayak@ti.com> \r
-\r
----\r
- arch/arm/Kconfig | 10 ++++++++++\r
- drivers/cpuidle/Kconfig | 28 ++++++++++++++++++++++------\r
- 2 files changed, 32 insertions(+), 6 deletions(-)\r
-\r
-Index: linux-omap-2.6/arch/arm/Kconfig\r
-===================================================================\r
---- linux-omap-2.6.orig/arch/arm/Kconfig 2008-06-10 11:43:10.790502713 +0530\r
-+++ linux-omap-2.6/arch/arm/Kconfig 2008-06-10 11:43:38.701604549 +0530\r
-@@ -954,6 +954,16 @@ config ATAGS_PROC\r
- \r
- endmenu\r
- \r
-+if (ARCH_OMAP)\r
-+\r
-+menu "CPUIdle"\r
-+\r
-+source "drivers/cpuidle/Kconfig"\r
-+\r
-+endmenu\r
-+\r
-+endif\r
-+\r
- if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)\r
- \r
- menu "CPU Frequency scaling"\r
-Index: linux-omap-2.6/drivers/cpuidle/Kconfig\r
-===================================================================\r
---- linux-omap-2.6.orig/drivers/cpuidle/Kconfig 2008-06-10 11:43:10.790502713 +0530\r
-+++ linux-omap-2.6/drivers/cpuidle/Kconfig 2008-06-10 12:06:36.139332151 +0530\r
-@@ -1,20 +1,36 @@\r
-+menu "CPU idle PM support"\r
- \r
- config CPU_IDLE\r
- bool "CPU idle PM support"\r
-- default ACPI\r
-+ default n\r
- help\r
- CPU idle is a generic framework for supporting software-controlled\r
- idle processor power management. It includes modular cross-platform\r
- governors that can be swapped during runtime.\r
- \r
-- If you're using an ACPI-enabled platform, you should say Y here.\r
-+ If you're using a mobile platform that supports CPU idle PM (e.g.\r
-+ an ACPI-capable notebook), you should say Y here.\r
-+\r
-+if CPU_IDLE\r
-+\r
-+comment "Governors"\r
- \r
- config CPU_IDLE_GOV_LADDER\r
-- bool\r
-+ bool "ladder"\r
- depends on CPU_IDLE\r
-- default y\r
-+ default n\r
- \r
- config CPU_IDLE_GOV_MENU\r
-- bool\r
-+ bool "menu"\r
- depends on CPU_IDLE && NO_HZ\r
-- default y\r
-+ default n\r
-+ help\r
-+ This cpuidle governor evaluates all available states and chooses the\r
-+ deepest state that meets all of the following constraints: BM activity,\r
-+ expected time until next timer interrupt, and last break event time\r
-+ delta. It is designed to minimize power consumption. Currently\r
-+ dynticks is required.\r
-+\r
-+endif # CPU_IDLE\r
-+\r
-+endmenu\r
-\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at http://vger.kernel.org/majordomo-info.html\r
-\r
+From: "Rajendra Nayak" <rnayak@ti.com>
+To: <linux-omap@vger.kernel.org>
+Subject: [PATCH 02/02] Kconfig changes
+Date: Tue, 10 Jun 2008 12:39:02 +0530
+
+Updates the CPUidle Kconfig
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+
+---
+ arch/arm/Kconfig | 10 ++++++++++
+ drivers/cpuidle/Kconfig | 28 ++++++++++++++++++++++------
+ 2 files changed, 32 insertions(+), 6 deletions(-)
+
+Index: linux-omap-2.6/arch/arm/Kconfig
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/Kconfig 2008-06-10 11:43:10.790502713 +0530
++++ linux-omap-2.6/arch/arm/Kconfig 2008-06-10 11:43:38.701604549 +0530
+@@ -954,6 +954,16 @@ config ATAGS_PROC
+
+ endmenu
+
++if (ARCH_OMAP)
++
++menu "CPUIdle"
++
++source "drivers/cpuidle/Kconfig"
++
++endmenu
++
++endif
++
+ if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
+
+ menu "CPU Frequency scaling"
+Index: linux-omap-2.6/drivers/cpuidle/Kconfig
+===================================================================
+--- linux-omap-2.6.orig/drivers/cpuidle/Kconfig 2008-06-10 11:43:10.790502713 +0530
++++ linux-omap-2.6/drivers/cpuidle/Kconfig 2008-06-10 12:06:36.139332151 +0530
+@@ -1,20 +1,36 @@
++menu "CPU idle PM support"
+
+ config CPU_IDLE
+ bool "CPU idle PM support"
+- default ACPI
++ default n
+ help
+ CPU idle is a generic framework for supporting software-controlled
+ idle processor power management. It includes modular cross-platform
+ governors that can be swapped during runtime.
+
+- If you're using an ACPI-enabled platform, you should say Y here.
++ If you're using a mobile platform that supports CPU idle PM (e.g.
++ an ACPI-capable notebook), you should say Y here.
++
++if CPU_IDLE
++
++comment "Governors"
+
+ config CPU_IDLE_GOV_LADDER
+- bool
++ bool "ladder"
+ depends on CPU_IDLE
+- default y
++ default n
+
+ config CPU_IDLE_GOV_MENU
+- bool
++ bool "menu"
+ depends on CPU_IDLE && NO_HZ
+- default y
++ default n
++ help
++ This cpuidle governor evaluates all available states and chooses the
++ deepest state that meets all of the following constraints: BM activity,
++ expected time until next timer interrupt, and last break event time
++ delta. It is designed to minimize power consumption. Currently
++ dynticks is required.
++
++endif # CPU_IDLE
++
++endmenu
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
-From linux-omap-owner@vger.kernel.org Sun Jun 22 10:11:39 2008\r
-Received: from localhost\r
- ([127.0.0.1] helo=dominion ident=koen)\r
- by dominion.dominion.void with esmtp (Exim 4.63)\r
- (envelope-from <linux-omap-owner@vger.kernel.org>)\r
- id 1KAKfj-0008Qc-FC\r
- for koen@localhost; Sun, 22 Jun 2008 10:11:39 +0200\r
-Received: from xs.service.utwente.nl [130.89.5.250]\r
- by dominion with POP3 (fetchmail-6.3.6)\r
- for <koen@localhost> (single-drop); Sun, 22 Jun 2008 10:11:39 +0200 (CEST)\r
-Received: from mail.service.utwente.nl ([130.89.5.253]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);\r
- Sat, 21 Jun 2008 19:06:02 +0200\r
-Received: from smtp.utwente.nl ([130.89.2.9]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);\r
- Sat, 21 Jun 2008 19:06:01 +0200\r
-Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])\r
- by smtp.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id m5LH5TSm026212\r
- for <k.kooi@student.utwente.nl>; Sat, 21 Jun 2008 19:05:30 +0200\r
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand\r
- id S1753396AbYFURFN (ORCPT <rfc822;k.kooi@student.utwente.nl>);\r
- Sat, 21 Jun 2008 13:05:13 -0400\r
-Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753305AbYFURFN\r
- (ORCPT <rfc822;linux-omap-outgoing>);\r
- Sat, 21 Jun 2008 13:05:13 -0400\r
-Received: from utopia.booyaka.com ([72.9.107.138]:41675 "EHLO\r
- utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\r
- with ESMTP id S1753145AbYFURFL (ORCPT\r
- <rfc822;linux-omap@vger.kernel.org>); Sat, 21 Jun 2008 13:05:11 -0400\r
-Received: (qmail 20532 invoked by uid 526); 21 Jun 2008 17:05:10 -0000\r
-Date: Sat, 21 Jun 2008 11:05:10 -0600 (MDT)\r
-From: Paul Walmsley <paul@pwsan.com>\r
-To: "Gadiyar, Anand" <gadiyar@ti.com>,\r
- "linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>\r
-cc: Dirk Behme <dirk.behme@googlemail.com>,\r
- "jouni.hogander@nokia.com" <jouni.hogander@nokia.com>\r
-Subject: [PATCH] OMAP3 clock: fix omap2_clk_wait_ready for OMAP3430ES2 DSS\r
-In-Reply-To: <5A47E75E594F054BAF48C5E4FC4B92AB022BB66209@dbde02.ent.ti.com>\r
-Message-ID: <alpine.DEB.1.00.0806211054100.19765@utopia.booyaka.com>\r
-References: <5A47E75E594F054BAF48C5E4FC4B92AB022BE46296@dbde02.ent.ti.com>,<485CA347.909@googlemail.com> <5A47E75E594F054BAF48C5E4FC4B92AB022BB66209@dbde02.ent.ti.com>\r
-User-Agent: Alpine 1.00 (DEB 882 2007-12-20)\r
-MIME-Version: 1.0\r
-Content-Type: TEXT/PLAIN; charset=US-ASCII\r
-Sender: linux-omap-owner@vger.kernel.org\r
-Precedence: bulk\r
-List-ID: <linux-omap.vger.kernel.org>\r
-X-Mailing-List: linux-omap@vger.kernel.org\r
-X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.\r
-X-UTwente-MailScanner: Found to be clean\r
-X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org\r
-X-Spam-Status: No\r
-X-OriginalArrivalTime: 21 Jun 2008 17:06:02.0187 (UTC) FILETIME=[157001B0:01C8D3C1]\r
-\r
-\r
-On OMAP3430ES2, DSS has both an initiator standby CM_IDLEST bit, and a\r
-target idle CM_IDLEST bit. This is a departure from previous silicon,\r
-which only had an initiator standby bit.\r
-\r
-This means we need to test the target idle bit after enabling\r
-dss1_alwon_fclk. Previous clock code has done the wrong thing since ES2\r
-came out: it's either tested the wrong bit, causing intermittent\r
-\r
- Clock dss1_alwon_fck didn't enable in 100000 tries\r
-\r
-messages; or not tested anything at all, causing intermittent crashes \r
-during DISPC initialization with:\r
-\r
- Unhandled fault: external abort on non-linefetch (0x1028)\r
-\r
-This patch modifies omap2_clk_wait_ready() to wait for the DSS to become\r
-accessible after dss1_alwon_fclk is enabled.\r
-\r
-Thanks to Anand Gadiyar <gadiyar@ti.com> for identifying one of the\r
-problem patches.\r
-\r
-Signed-off-by: Paul Walmsley <paul@pwsan.com>\r
----\r
-\r
- arch/arm/mach-omap2/clock.c | 30 ++++++++++++++++++++++++------\r
- arch/arm/mach-omap2/cm-regbits-34xx.h | 4 +++-\r
- 2 files changed, 27 insertions(+), 7 deletions(-)\r
-\r
-diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c\r
-index ed15868..1820f75 100644\r
---- a/arch/arm/mach-omap2/clock.c\r
-+++ b/arch/arm/mach-omap2/clock.c\r
-@@ -244,18 +244,36 @@ static void omap2_clk_wait_ready(struct clk *clk)\r
- }\r
- \r
- /* REVISIT: What are the appropriate exclusions for 34XX? */\r
-- /* OMAP3: ignore DSS-mod clocks */\r
-- if (cpu_is_omap34xx() &&\r
-- ((reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||\r
-- (((reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(CORE_MOD, 0)) &&\r
-- clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))\r
-- return;\r
-+ if (cpu_is_omap34xx()) {\r
-+\r
-+ /* 3430ES1 DSS and SSI have no target idlest bits */\r
-+ if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0) &&\r
-+ ((reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||\r
-+ ((reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(CORE_MOD, 0) &&\r
-+ clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))\r
-+ return;\r
-+\r
-+ /* Even for 3430ES2 DSS, only wait for dss1_alwon_fclk */\r
-+ if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0) &&\r
-+ (reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) &&\r
-+ clk->enable_bit != OMAP3430_EN_DSS1_SHIFT)\r
-+ return;\r
-+\r
-+ }\r
- \r
- /* Check if both functional and interface clocks\r
- * are running. */\r
- bit = 1 << clk->enable_bit;\r
- if (!(__raw_readl((__force void __iomem *)other_reg) & bit))\r
- return;\r
-+\r
-+ /* OMAP3430ES2 DSS is an unusual case */\r
-+ if (cpu_is_omap34xx() &&\r
-+ (reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) &&\r
-+ clk->enable_bit == OMAP3430_EN_DSS1_SHIFT) {\r
-+ bit = OMAP3430ES2_ST_DSS_IDLE;\r
-+ }\r
-+\r
- st_reg = ((other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */\r
- \r
- omap2_wait_clock_ready((__force void __iomem *)st_reg, bit, clk->name);\r
-diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h\r
-index 6ec66f4..946c552 100644\r
---- a/arch/arm/mach-omap2/cm-regbits-34xx.h\r
-+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h\r
-@@ -500,7 +500,9 @@\r
- #define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT 0\r
- \r
- /* CM_IDLEST_DSS */\r
--#define OMAP3430_ST_DSS (1 << 0)\r
-+#define OMAP3430ES2_ST_DSS_IDLE (1 << 1)\r
-+#define OMAP3430ES2_ST_DSS_STDBY (1 << 0)\r
-+#define OMAP3430ES1_ST_DSS (1 << 0)\r
- \r
- /* CM_AUTOIDLE_DSS */\r
- #define OMAP3430_AUTO_DSS (1 << 0)\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at http://vger.kernel.org/majordomo-info.html\r
-\r
+From linux-omap-owner@vger.kernel.org Sun Jun 22 10:11:39 2008
+Received: from localhost
+ ([127.0.0.1] helo=dominion ident=koen)
+ by dominion.dominion.void with esmtp (Exim 4.63)
+ (envelope-from <linux-omap-owner@vger.kernel.org>)
+ id 1KAKfj-0008Qc-FC
+ for koen@localhost; Sun, 22 Jun 2008 10:11:39 +0200
+Received: from xs.service.utwente.nl [130.89.5.250]
+ by dominion with POP3 (fetchmail-6.3.6)
+ for <koen@localhost> (single-drop); Sun, 22 Jun 2008 10:11:39 +0200 (CEST)
+Received: from mail.service.utwente.nl ([130.89.5.253]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
+ Sat, 21 Jun 2008 19:06:02 +0200
+Received: from smtp.utwente.nl ([130.89.2.9]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
+ Sat, 21 Jun 2008 19:06:01 +0200
+Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
+ by smtp.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id m5LH5TSm026212
+ for <k.kooi@student.utwente.nl>; Sat, 21 Jun 2008 19:05:30 +0200
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+ id S1753396AbYFURFN (ORCPT <rfc822;k.kooi@student.utwente.nl>);
+ Sat, 21 Jun 2008 13:05:13 -0400
+Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753305AbYFURFN
+ (ORCPT <rfc822;linux-omap-outgoing>);
+ Sat, 21 Jun 2008 13:05:13 -0400
+Received: from utopia.booyaka.com ([72.9.107.138]:41675 "EHLO
+ utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
+ with ESMTP id S1753145AbYFURFL (ORCPT
+ <rfc822;linux-omap@vger.kernel.org>); Sat, 21 Jun 2008 13:05:11 -0400
+Received: (qmail 20532 invoked by uid 526); 21 Jun 2008 17:05:10 -0000
+Date: Sat, 21 Jun 2008 11:05:10 -0600 (MDT)
+From: Paul Walmsley <paul@pwsan.com>
+To: "Gadiyar, Anand" <gadiyar@ti.com>,
+ "linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>
+cc: Dirk Behme <dirk.behme@googlemail.com>,
+ "jouni.hogander@nokia.com" <jouni.hogander@nokia.com>
+Subject: [PATCH] OMAP3 clock: fix omap2_clk_wait_ready for OMAP3430ES2 DSS
+In-Reply-To: <5A47E75E594F054BAF48C5E4FC4B92AB022BB66209@dbde02.ent.ti.com>
+Message-ID: <alpine.DEB.1.00.0806211054100.19765@utopia.booyaka.com>
+References: <5A47E75E594F054BAF48C5E4FC4B92AB022BE46296@dbde02.ent.ti.com>,<485CA347.909@googlemail.com> <5A47E75E594F054BAF48C5E4FC4B92AB022BB66209@dbde02.ent.ti.com>
+User-Agent: Alpine 1.00 (DEB 882 2007-12-20)
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Sender: linux-omap-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <linux-omap.vger.kernel.org>
+X-Mailing-List: linux-omap@vger.kernel.org
+X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.
+X-UTwente-MailScanner: Found to be clean
+X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org
+X-Spam-Status: No
+X-OriginalArrivalTime: 21 Jun 2008 17:06:02.0187 (UTC) FILETIME=[157001B0:01C8D3C1]
+
+
+On OMAP3430ES2, DSS has both an initiator standby CM_IDLEST bit, and a
+target idle CM_IDLEST bit. This is a departure from previous silicon,
+which only had an initiator standby bit.
+
+This means we need to test the target idle bit after enabling
+dss1_alwon_fclk. Previous clock code has done the wrong thing since ES2
+came out: it's either tested the wrong bit, causing intermittent
+
+ Clock dss1_alwon_fck didn't enable in 100000 tries
+
+messages; or not tested anything at all, causing intermittent crashes
+during DISPC initialization with:
+
+ Unhandled fault: external abort on non-linefetch (0x1028)
+
+This patch modifies omap2_clk_wait_ready() to wait for the DSS to become
+accessible after dss1_alwon_fclk is enabled.
+
+Thanks to Anand Gadiyar <gadiyar@ti.com> for identifying one of the
+problem patches.
+
+Signed-off-by: Paul Walmsley <paul@pwsan.com>
+---
+
+ arch/arm/mach-omap2/clock.c | 30 ++++++++++++++++++++++++------
+ arch/arm/mach-omap2/cm-regbits-34xx.h | 4 +++-
+ 2 files changed, 27 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
+index ed15868..1820f75 100644
+--- a/arch/arm/mach-omap2/clock.c
++++ b/arch/arm/mach-omap2/clock.c
+@@ -244,18 +244,36 @@ static void omap2_clk_wait_ready(struct clk *clk)
+ }
+
+ /* REVISIT: What are the appropriate exclusions for 34XX? */
+- /* OMAP3: ignore DSS-mod clocks */
+- if (cpu_is_omap34xx() &&
+- ((reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||
+- (((reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(CORE_MOD, 0)) &&
+- clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))
+- return;
++ if (cpu_is_omap34xx()) {
++
++ /* 3430ES1 DSS and SSI have no target idlest bits */
++ if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0) &&
++ ((reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||
++ ((reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(CORE_MOD, 0) &&
++ clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))
++ return;
++
++ /* Even for 3430ES2 DSS, only wait for dss1_alwon_fclk */
++ if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0) &&
++ (reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) &&
++ clk->enable_bit != OMAP3430_EN_DSS1_SHIFT)
++ return;
++
++ }
+
+ /* Check if both functional and interface clocks
+ * are running. */
+ bit = 1 << clk->enable_bit;
+ if (!(__raw_readl((__force void __iomem *)other_reg) & bit))
+ return;
++
++ /* OMAP3430ES2 DSS is an unusual case */
++ if (cpu_is_omap34xx() &&
++ (reg & ~0xff) == (__force u32)OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) &&
++ clk->enable_bit == OMAP3430_EN_DSS1_SHIFT) {
++ bit = OMAP3430ES2_ST_DSS_IDLE;
++ }
++
+ st_reg = ((other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */
+
+ omap2_wait_clock_ready((__force void __iomem *)st_reg, bit, clk->name);
+diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
+index 6ec66f4..946c552 100644
+--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
++++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
+@@ -500,7 +500,9 @@
+ #define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT 0
+
+ /* CM_IDLEST_DSS */
+-#define OMAP3430_ST_DSS (1 << 0)
++#define OMAP3430ES2_ST_DSS_IDLE (1 << 1)
++#define OMAP3430ES2_ST_DSS_STDBY (1 << 0)
++#define OMAP3430ES1_ST_DSS (1 << 0)
+
+ /* CM_AUTOIDLE_DSS */
+ #define OMAP3430_AUTO_DSS (1 << 0)
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
-From: "Rajendra Nayak" <rnayak@ti.com>\r
-To: <linux-omap@vger.kernel.org>\r
-Subject: [PATCH 01/02] OMAP3 CPUidle driver\r
-Date: Tue, 10 Jun 2008 12:39:00 +0530\r
-\r
-This patch adds the OMAP3 cpuidle driver. Irq enable/disable is done in the core cpuidle driver\r
-before it queries the governor for the next state.\r
-\r
-Signed-off-by: Rajendra Nayak <rnayak@ti.com> \r
-\r
----\r
- arch/arm/mach-omap2/Makefile | 2 \r
- arch/arm/mach-omap2/cpuidle34xx.c | 293 ++++++++++++++++++++++++++++++++++++++\r
- arch/arm/mach-omap2/cpuidle34xx.h | 51 ++++++\r
- arch/arm/mach-omap2/pm34xx.c | 5 \r
- drivers/cpuidle/cpuidle.c | 10 +\r
- 5 files changed, 359 insertions(+), 2 deletions(-)\r
-\r
-Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile\r
-===================================================================\r
---- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:33.855303920 +0530\r
-+++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:39.569121361 +0530\r
-@@ -20,7 +20,7 @@ obj-y += pm.o\r
- obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o\r
- obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o\r
- obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o\r
--obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o\r
-+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o\r
- obj-$(CONFIG_PM_DEBUG) += pm-debug.o\r
- endif\r
- \r
-Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c\r
-===================================================================\r
---- /dev/null 1970-01-01 00:00:00.000000000 +0000\r
-+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-06-10 11:41:27.644820323 +0530\r
-@@ -0,0 +1,293 @@\r
-+/*\r
-+ * linux/arch/arm/mach-omap2/cpuidle34xx.c\r
-+ *\r
-+ * OMAP3 CPU IDLE Routines\r
-+ *\r
-+ * Copyright (C) 2007-2008 Texas Instruments, Inc.\r
-+ * Rajendra Nayak <rnayak@ti.com>\r
-+ *\r
-+ * Copyright (C) 2007 Texas Instruments, Inc.\r
-+ * Karthik Dasu <karthik-dp@ti.com>\r
-+ *\r
-+ * Copyright (C) 2006 Nokia Corporation\r
-+ * Tony Lindgren <tony@atomide.com>\r
-+ *\r
-+ * Copyright (C) 2005 Texas Instruments, Inc.\r
-+ * Richard Woodruff <r-woodruff2@ti.com>\r
-+ *\r
-+ * This program is free software; you can redistribute it and/or modify\r
-+ * it under the terms of the GNU General Public License version 2 as\r
-+ * published by the Free Software Foundation.\r
-+ */\r
-+\r
-+#include <linux/cpuidle.h>\r
-+#include <asm/arch/pm.h>\r
-+#include <asm/arch/prcm.h>\r
-+#include <asm/arch/powerdomain.h>\r
-+#include <asm/arch/clockdomain.h>\r
-+#include <asm/arch/irqs.h>\r
-+#include "cpuidle34xx.h"\r
-+\r
-+#ifdef CONFIG_CPU_IDLE\r
-+\r
-+struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];\r
-+struct omap3_processor_cx current_cx_state;\r
-+\r
-+static int omap3_idle_bm_check(void)\r
-+{\r
-+ /* Check for omap3_fclks_active() here once available */\r
-+ return 0;\r
-+}\r
-+\r
-+/* omap3_enter_idle - Programs OMAP3 to enter the specified state.\r
-+ * returns the total time during which the system was idle.\r
-+ */\r
-+static int omap3_enter_idle(struct cpuidle_device *dev,\r
-+ struct cpuidle_state *state)\r
-+{\r
-+ struct omap3_processor_cx *cx = cpuidle_get_statedata(state);\r
-+ struct timespec ts_preidle, ts_postidle, ts_idle;\r
-+ struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd;\r
-+ int neon_pwrst;\r
-+\r
-+ current_cx_state = *cx;\r
-+\r
-+ if (cx->type == OMAP3_STATE_C0) {\r
-+ /* Do nothing for C0, not even a wfi */\r
-+ return 0;\r
-+ }\r
-+\r
-+ /* Used to keep track of the total time in idle */\r
-+ getnstimeofday(&ts_preidle);\r
-+\r
-+ mpu_pd = pwrdm_lookup("mpu_pwrdm");\r
-+ core_pd = pwrdm_lookup("core_pwrdm");\r
-+ per_pd = pwrdm_lookup("per_pwrdm");\r
-+ neon_pd = pwrdm_lookup("neon_pwrdm");\r
-+\r
-+ /* Reset previous power state registers */\r
-+ pwrdm_clear_all_prev_pwrst(mpu_pd);\r
-+ pwrdm_clear_all_prev_pwrst(neon_pd);\r
-+ pwrdm_clear_all_prev_pwrst(core_pd);\r
-+ pwrdm_clear_all_prev_pwrst(per_pd);\r
-+\r
-+ if (omap_irq_pending())\r
-+ return 0;\r
-+\r
-+ neon_pwrst = pwrdm_read_pwrst(neon_pd);\r
-+\r
-+ /* Program MPU/NEON to target state */\r
-+ if (cx->mpu_state < PWRDM_POWER_ON) {\r
-+ if (neon_pwrst == PWRDM_POWER_ON) {\r
-+ if (cx->mpu_state == PWRDM_POWER_RET)\r
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET);\r
-+ else if (cx->mpu_state == PWRDM_POWER_OFF)\r
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF);\r
-+ }\r
-+ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);\r
-+ }\r
-+\r
-+ /* Program CORE to target state */\r
-+ if (cx->core_state < PWRDM_POWER_ON)\r
-+ pwrdm_set_next_pwrst(core_pd, cx->core_state);\r
-+\r
-+ /* Execute ARM wfi */\r
-+ omap_sram_idle();\r
-+\r
-+ /* Program MPU/NEON to ON */\r
-+ if (cx->mpu_state < PWRDM_POWER_ON) {\r
-+ if (neon_pwrst == PWRDM_POWER_ON)\r
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON);\r
-+ pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);\r
-+ }\r
-+\r
-+ if (cx->core_state < PWRDM_POWER_ON)\r
-+ pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);\r
-+\r
-+ getnstimeofday(&ts_postidle);\r
-+ ts_idle = timespec_sub(ts_postidle, ts_preidle);\r
-+ return timespec_to_ns(&ts_idle);\r
-+}\r
-+\r
-+/*\r
-+ * omap3_enter_idle_bm - enter function for states with CPUIDLE_FLAG_CHECK_BM\r
-+ *\r
-+ * This function checks for all the pre-requisites needed for OMAP3 to enter\r
-+ * CORE RET/OFF state. It then calls omap3_enter_idle to program the desired\r
-+ * C state.\r
-+ */\r
-+static int omap3_enter_idle_bm(struct cpuidle_device *dev,\r
-+ struct cpuidle_state *state)\r
-+{\r
-+ struct cpuidle_state *new_state = NULL;\r
-+ int i, j;\r
-+\r
-+ if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {\r
-+\r
-+ /* Find current state in list */\r
-+ for (i = 0; i < OMAP3_MAX_STATES; i++)\r
-+ if (state == &dev->states[i])\r
-+ break;\r
-+ BUG_ON(i == OMAP3_MAX_STATES);\r
-+\r
-+ /* Back up to non 'CHECK_BM' state */\r
-+ for (j = i - 1; j > 0; j--) {\r
-+ struct cpuidle_state *s = &dev->states[j];\r
-+\r
-+ if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) {\r
-+ new_state = s;\r
-+ break;\r
-+ }\r
-+ }\r
-+\r
-+ pr_debug("%s: Bus activity: Entering %s (instead of %s)\n",\r
-+ __FUNCTION__, new_state->name, state->name);\r
-+ }\r
-+\r
-+ return omap3_enter_idle(dev, new_state ? : state);\r
-+}\r
-+\r
-+DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);\r
-+\r
-+/* omap3_init_power_states - Initialises the OMAP3 specific C states.\r
-+ * Below is the desciption of each C state.\r
-+ *\r
-+ C0 . System executing code\r
-+ C1 . MPU WFI + Core active\r
-+ C2 . MPU CSWR + Core active\r
-+ C3 . MPU OFF + Core active\r
-+ C4 . MPU CSWR + Core CSWR\r
-+ C5 . MPU OFF + Core CSWR\r
-+ C6 . MPU OFF + Core OFF\r
-+ */\r
-+void omap_init_power_states(void)\r
-+{\r
-+ /* C0 . System executing code */\r
-+ omap3_power_states[0].valid = 1;\r
-+ omap3_power_states[0].type = OMAP3_STATE_C0;\r
-+ omap3_power_states[0].sleep_latency = 0;\r
-+ omap3_power_states[0].wakeup_latency = 0;\r
-+ omap3_power_states[0].threshold = 0;\r
-+ omap3_power_states[0].mpu_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[0].core_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_SHALLOW;\r
-+\r
-+ /* C1 . MPU WFI + Core active */\r
-+ omap3_power_states[1].valid = 1;\r
-+ omap3_power_states[1].type = OMAP3_STATE_C1;\r
-+ omap3_power_states[1].sleep_latency = 10;\r
-+ omap3_power_states[1].wakeup_latency = 10;\r
-+ omap3_power_states[1].threshold = 30;\r
-+ omap3_power_states[1].mpu_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[1].core_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_SHALLOW;\r
-+\r
-+ /* C2 . MPU CSWR + Core active */\r
-+ omap3_power_states[2].valid = 1;\r
-+ omap3_power_states[2].type = OMAP3_STATE_C2;\r
-+ omap3_power_states[2].sleep_latency = 50;\r
-+ omap3_power_states[2].wakeup_latency = 50;\r
-+ omap3_power_states[2].threshold = 300;\r
-+ omap3_power_states[2].mpu_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[2].core_state = PWRDM_POWER_ON;\r
-+ omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_BALANCED;\r
-+\r
-+ /* C3 . MPU OFF + Core active */\r
-+ omap3_power_states[3].valid = 0;\r
-+ omap3_power_states[3].type = OMAP3_STATE_C3;\r
-+ omap3_power_states[3].sleep_latency = 1500;\r
-+ omap3_power_states[3].wakeup_latency = 1800;\r
-+ omap3_power_states[3].threshold = 4000;\r
-+ omap3_power_states[3].mpu_state = PWRDM_POWER_OFF;\r
-+ omap3_power_states[3].core_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_BALANCED;\r
-+\r
-+ /* C4 . MPU CSWR + Core CSWR*/\r
-+ omap3_power_states[4].valid = 1;\r
-+ omap3_power_states[4].type = OMAP3_STATE_C4;\r
-+ omap3_power_states[4].sleep_latency = 2500;\r
-+ omap3_power_states[4].wakeup_latency = 7500;\r
-+ omap3_power_states[4].threshold = 12000;\r
-+ omap3_power_states[4].mpu_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[4].core_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;\r
-+\r
-+ /* C5 . MPU OFF + Core CSWR */\r
-+ omap3_power_states[5].valid = 0;\r
-+ omap3_power_states[5].type = OMAP3_STATE_C5;\r
-+ omap3_power_states[5].sleep_latency = 3000;\r
-+ omap3_power_states[5].wakeup_latency = 8500;\r
-+ omap3_power_states[5].threshold = 15000;\r
-+ omap3_power_states[5].mpu_state = PWRDM_POWER_OFF;\r
-+ omap3_power_states[5].core_state = PWRDM_POWER_RET;\r
-+ omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;\r
-+\r
-+ /* C6 . MPU OFF + Core OFF */\r
-+ omap3_power_states[6].valid = 0;\r
-+ omap3_power_states[6].type = OMAP3_STATE_C6;\r
-+ omap3_power_states[6].sleep_latency = 10000;\r
-+ omap3_power_states[6].wakeup_latency = 30000;\r
-+ omap3_power_states[6].threshold = 300000;\r
-+ omap3_power_states[6].mpu_state = PWRDM_POWER_OFF;\r
-+ omap3_power_states[6].core_state = PWRDM_POWER_OFF;\r
-+ omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID |\r
-+ CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM;\r
-+}\r
-+\r
-+struct cpuidle_driver omap3_idle_driver = {\r
-+ .name = "omap3_idle",\r
-+ .owner = THIS_MODULE,\r
-+};\r
-+/*\r
-+ * omap3_idle_init - Init routine for OMAP3 idle.\r
-+ * Registers the OMAP3 specific cpuidle driver with the cpuidle f/w\r
-+ * with the valid set of states.\r
-+ */\r
-+int omap3_idle_init(void)\r
-+{\r
-+ int i, count = 0;\r
-+ struct omap3_processor_cx *cx;\r
-+ struct cpuidle_state *state;\r
-+ struct cpuidle_device *dev;\r
-+\r
-+ omap_init_power_states();\r
-+ cpuidle_register_driver(&omap3_idle_driver);\r
-+\r
-+ dev = &per_cpu(omap3_idle_dev, smp_processor_id());\r
-+\r
-+ for (i = 0; i < OMAP3_MAX_STATES; i++) {\r
-+ cx = &omap3_power_states[i];\r
-+ state = &dev->states[count];\r
-+\r
-+ if (!cx->valid)\r
-+ continue;\r
-+ cpuidle_set_statedata(state, cx);\r
-+ state->exit_latency = cx->sleep_latency + cx->wakeup_latency;\r
-+ state->target_residency = cx->threshold;\r
-+ state->flags = cx->flags;\r
-+ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?\r
-+ omap3_enter_idle_bm : omap3_enter_idle;\r
-+ sprintf(state->name, "C%d", count+1);\r
-+ count++;\r
-+ }\r
-+\r
-+ if (!count)\r
-+ return -EINVAL;\r
-+ dev->state_count = count;\r
-+\r
-+ if (cpuidle_register_device(dev)) {\r
-+ printk(KERN_ERR "%s: CPUidle register device failed\n",\r
-+ __FUNCTION__);\r
-+ return -EIO;\r
-+ }\r
-+\r
-+ return 0;\r
-+}\r
-+__initcall(omap3_idle_init);\r
-+#endif /* CONFIG_CPU_IDLE */\r
-Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h\r
-===================================================================\r
---- /dev/null 1970-01-01 00:00:00.000000000 +0000\r
-+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h 2008-06-09 20:15:39.569121361 +0530\r
-@@ -0,0 +1,51 @@\r
-+/*\r
-+ * linux/arch/arm/mach-omap2/cpuidle34xx.h\r
-+ *\r
-+ * OMAP3 cpuidle structure definitions\r
-+ *\r
-+ * Copyright (C) 2007-2008 Texas Instruments, Inc.\r
-+ * Written by Rajendra Nayak <rnayak@ti.com>\r
-+ *\r
-+ * This program is free software; you can redistribute it and/or modify\r
-+ * it under the terms of the GNU General Public License version 2 as\r
-+ * published by the Free Software Foundation.\r
-+ *\r
-+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r
-+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r
-+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r
-+ *\r
-+ * History:\r
-+ *\r
-+ */\r
-+\r
-+#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX\r
-+#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX\r
-+\r
-+#define OMAP3_MAX_STATES 7\r
-+#define OMAP3_STATE_C0 0 /* C0 - System executing code */\r
-+#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */\r
-+#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */\r
-+#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */\r
-+#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */\r
-+#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */\r
-+#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */\r
-+\r
-+extern void omap_sram_idle(void);\r
-+extern int omap3_irq_pending(void);\r
-+\r
-+struct omap3_processor_cx {\r
-+ u8 valid;\r
-+ u8 type;\r
-+ u32 sleep_latency;\r
-+ u32 wakeup_latency;\r
-+ u32 mpu_state;\r
-+ u32 core_state;\r
-+ u32 threshold;\r
-+ u32 flags;\r
-+};\r
-+\r
-+void omap_init_power_states(void);\r
-+int omap3_idle_init(void);\r
-+\r
-+#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */\r
-+\r
-Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c\r
-===================================================================\r
---- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:15:33.855303920 +0530\r
-+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:16:20.976798343 +0530\r
-@@ -141,7 +141,7 @@ static irqreturn_t prcm_interrupt_handle\r
- return IRQ_HANDLED;\r
- }\r
- \r
--static void omap_sram_idle(void)\r
-+void omap_sram_idle(void)\r
- {\r
- /* Variable to tell what needs to be saved and restored\r
- * in omap_sram_idle*/\r
-@@ -156,6 +156,7 @@ static void omap_sram_idle(void)\r
- \r
- mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);\r
- switch (mpu_next_state) {\r
-+ case PWRDM_POWER_ON:\r
- case PWRDM_POWER_RET:\r
- /* No need to save context */\r
- save_state = 0;\r
-@@ -386,7 +387,9 @@ int __init omap3_pm_init(void)\r
- \r
- prcm_setup_regs();\r
- \r
-+#ifndef CONFIG_CPU_IDLE\r
- pm_idle = omap3_pm_idle;\r
-+#endif\r
- \r
- err1:\r
- return ret;\r
-Index: linux-omap-2.6/drivers/cpuidle/cpuidle.c\r
-===================================================================\r
---- linux-omap-2.6.orig/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:33.856303888 +0530\r
-+++ linux-omap-2.6/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:39.570121329 +0530\r
-@@ -58,6 +58,11 @@ static void cpuidle_idle_call(void)\r
- return;\r
- }\r
- \r
-+#ifdef CONFIG_ARCH_OMAP3\r
-+ local_irq_disable();\r
-+ local_fiq_disable();\r
-+#endif\r
-+\r
- /* ask the governor for the next state */\r
- next_state = cpuidle_curr_governor->select(dev);\r
- if (need_resched())\r
-@@ -70,6 +75,11 @@ static void cpuidle_idle_call(void)\r
- target_state->time += (unsigned long long)dev->last_residency;\r
- target_state->usage++;\r
- \r
-+#ifdef CONFIG_ARCH_OMAP3\r
-+ local_irq_enable();\r
-+ local_fiq_enable();\r
-+#endif\r
-+\r
- /* give the governor an opportunity to reflect on the outcome */\r
- if (cpuidle_curr_governor->reflect)\r
- cpuidle_curr_governor->reflect(dev);\r
-\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at http://vger.kernel.org/majordomo-info.html\r
-\r
+From: "Rajendra Nayak" <rnayak@ti.com>
+To: <linux-omap@vger.kernel.org>
+Subject: [PATCH 01/02] OMAP3 CPUidle driver
+Date: Tue, 10 Jun 2008 12:39:00 +0530
+
+This patch adds the OMAP3 cpuidle driver. Irq enable/disable is done in the core cpuidle driver
+before it queries the governor for the next state.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+
+---
+ arch/arm/mach-omap2/Makefile | 2
+ arch/arm/mach-omap2/cpuidle34xx.c | 293 ++++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-omap2/cpuidle34xx.h | 51 ++++++
+ arch/arm/mach-omap2/pm34xx.c | 5
+ drivers/cpuidle/cpuidle.c | 10 +
+ 5 files changed, 359 insertions(+), 2 deletions(-)
+
+Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:33.855303920 +0530
++++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:39.569121361 +0530
+@@ -20,7 +20,7 @@ obj-y += pm.o
+ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
+ obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o
+ obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o
+-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
++obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
+ obj-$(CONFIG_PM_DEBUG) += pm-debug.o
+ endif
+
+Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-06-10 11:41:27.644820323 +0530
+@@ -0,0 +1,293 @@
++/*
++ * linux/arch/arm/mach-omap2/cpuidle34xx.c
++ *
++ * OMAP3 CPU IDLE Routines
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Rajendra Nayak <rnayak@ti.com>
++ *
++ * Copyright (C) 2007 Texas Instruments, Inc.
++ * Karthik Dasu <karthik-dp@ti.com>
++ *
++ * Copyright (C) 2006 Nokia Corporation
++ * Tony Lindgren <tony@atomide.com>
++ *
++ * Copyright (C) 2005 Texas Instruments, Inc.
++ * Richard Woodruff <r-woodruff2@ti.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 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/cpuidle.h>
++#include <asm/arch/pm.h>
++#include <asm/arch/prcm.h>
++#include <asm/arch/powerdomain.h>
++#include <asm/arch/clockdomain.h>
++#include <asm/arch/irqs.h>
++#include "cpuidle34xx.h"
++
++#ifdef CONFIG_CPU_IDLE
++
++struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
++struct omap3_processor_cx current_cx_state;
++
++static int omap3_idle_bm_check(void)
++{
++ /* Check for omap3_fclks_active() here once available */
++ return 0;
++}
++
++/* omap3_enter_idle - Programs OMAP3 to enter the specified state.
++ * returns the total time during which the system was idle.
++ */
++static int omap3_enter_idle(struct cpuidle_device *dev,
++ struct cpuidle_state *state)
++{
++ struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
++ struct timespec ts_preidle, ts_postidle, ts_idle;
++ struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd;
++ int neon_pwrst;
++
++ current_cx_state = *cx;
++
++ if (cx->type == OMAP3_STATE_C0) {
++ /* Do nothing for C0, not even a wfi */
++ return 0;
++ }
++
++ /* Used to keep track of the total time in idle */
++ getnstimeofday(&ts_preidle);
++
++ mpu_pd = pwrdm_lookup("mpu_pwrdm");
++ core_pd = pwrdm_lookup("core_pwrdm");
++ per_pd = pwrdm_lookup("per_pwrdm");
++ neon_pd = pwrdm_lookup("neon_pwrdm");
++
++ /* Reset previous power state registers */
++ pwrdm_clear_all_prev_pwrst(mpu_pd);
++ pwrdm_clear_all_prev_pwrst(neon_pd);
++ pwrdm_clear_all_prev_pwrst(core_pd);
++ pwrdm_clear_all_prev_pwrst(per_pd);
++
++ if (omap_irq_pending())
++ return 0;
++
++ neon_pwrst = pwrdm_read_pwrst(neon_pd);
++
++ /* Program MPU/NEON to target state */
++ if (cx->mpu_state < PWRDM_POWER_ON) {
++ if (neon_pwrst == PWRDM_POWER_ON) {
++ if (cx->mpu_state == PWRDM_POWER_RET)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET);
++ else if (cx->mpu_state == PWRDM_POWER_OFF)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF);
++ }
++ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
++ }
++
++ /* Program CORE to target state */
++ if (cx->core_state < PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(core_pd, cx->core_state);
++
++ /* Execute ARM wfi */
++ omap_sram_idle();
++
++ /* Program MPU/NEON to ON */
++ if (cx->mpu_state < PWRDM_POWER_ON) {
++ if (neon_pwrst == PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON);
++ pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
++ }
++
++ if (cx->core_state < PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);
++
++ getnstimeofday(&ts_postidle);
++ ts_idle = timespec_sub(ts_postidle, ts_preidle);
++ return timespec_to_ns(&ts_idle);
++}
++
++/*
++ * omap3_enter_idle_bm - enter function for states with CPUIDLE_FLAG_CHECK_BM
++ *
++ * This function checks for all the pre-requisites needed for OMAP3 to enter
++ * CORE RET/OFF state. It then calls omap3_enter_idle to program the desired
++ * C state.
++ */
++static int omap3_enter_idle_bm(struct cpuidle_device *dev,
++ struct cpuidle_state *state)
++{
++ struct cpuidle_state *new_state = NULL;
++ int i, j;
++
++ if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
++
++ /* Find current state in list */
++ for (i = 0; i < OMAP3_MAX_STATES; i++)
++ if (state == &dev->states[i])
++ break;
++ BUG_ON(i == OMAP3_MAX_STATES);
++
++ /* Back up to non 'CHECK_BM' state */
++ for (j = i - 1; j > 0; j--) {
++ struct cpuidle_state *s = &dev->states[j];
++
++ if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) {
++ new_state = s;
++ break;
++ }
++ }
++
++ pr_debug("%s: Bus activity: Entering %s (instead of %s)\n",
++ __FUNCTION__, new_state->name, state->name);
++ }
++
++ return omap3_enter_idle(dev, new_state ? : state);
++}
++
++DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
++
++/* omap3_init_power_states - Initialises the OMAP3 specific C states.
++ * Below is the desciption of each C state.
++ *
++ C0 . System executing code
++ C1 . MPU WFI + Core active
++ C2 . MPU CSWR + Core active
++ C3 . MPU OFF + Core active
++ C4 . MPU CSWR + Core CSWR
++ C5 . MPU OFF + Core CSWR
++ C6 . MPU OFF + Core OFF
++ */
++void omap_init_power_states(void)
++{
++ /* C0 . System executing code */
++ omap3_power_states[0].valid = 1;
++ omap3_power_states[0].type = OMAP3_STATE_C0;
++ omap3_power_states[0].sleep_latency = 0;
++ omap3_power_states[0].wakeup_latency = 0;
++ omap3_power_states[0].threshold = 0;
++ omap3_power_states[0].mpu_state = PWRDM_POWER_ON;
++ omap3_power_states[0].core_state = PWRDM_POWER_ON;
++ omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_SHALLOW;
++
++ /* C1 . MPU WFI + Core active */
++ omap3_power_states[1].valid = 1;
++ omap3_power_states[1].type = OMAP3_STATE_C1;
++ omap3_power_states[1].sleep_latency = 10;
++ omap3_power_states[1].wakeup_latency = 10;
++ omap3_power_states[1].threshold = 30;
++ omap3_power_states[1].mpu_state = PWRDM_POWER_ON;
++ omap3_power_states[1].core_state = PWRDM_POWER_ON;
++ omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_SHALLOW;
++
++ /* C2 . MPU CSWR + Core active */
++ omap3_power_states[2].valid = 1;
++ omap3_power_states[2].type = OMAP3_STATE_C2;
++ omap3_power_states[2].sleep_latency = 50;
++ omap3_power_states[2].wakeup_latency = 50;
++ omap3_power_states[2].threshold = 300;
++ omap3_power_states[2].mpu_state = PWRDM_POWER_RET;
++ omap3_power_states[2].core_state = PWRDM_POWER_ON;
++ omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED;
++
++ /* C3 . MPU OFF + Core active */
++ omap3_power_states[3].valid = 0;
++ omap3_power_states[3].type = OMAP3_STATE_C3;
++ omap3_power_states[3].sleep_latency = 1500;
++ omap3_power_states[3].wakeup_latency = 1800;
++ omap3_power_states[3].threshold = 4000;
++ omap3_power_states[3].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[3].core_state = PWRDM_POWER_RET;
++ omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED;
++
++ /* C4 . MPU CSWR + Core CSWR*/
++ omap3_power_states[4].valid = 1;
++ omap3_power_states[4].type = OMAP3_STATE_C4;
++ omap3_power_states[4].sleep_latency = 2500;
++ omap3_power_states[4].wakeup_latency = 7500;
++ omap3_power_states[4].threshold = 12000;
++ omap3_power_states[4].mpu_state = PWRDM_POWER_RET;
++ omap3_power_states[4].core_state = PWRDM_POWER_RET;
++ omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
++
++ /* C5 . MPU OFF + Core CSWR */
++ omap3_power_states[5].valid = 0;
++ omap3_power_states[5].type = OMAP3_STATE_C5;
++ omap3_power_states[5].sleep_latency = 3000;
++ omap3_power_states[5].wakeup_latency = 8500;
++ omap3_power_states[5].threshold = 15000;
++ omap3_power_states[5].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[5].core_state = PWRDM_POWER_RET;
++ omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
++
++ /* C6 . MPU OFF + Core OFF */
++ omap3_power_states[6].valid = 0;
++ omap3_power_states[6].type = OMAP3_STATE_C6;
++ omap3_power_states[6].sleep_latency = 10000;
++ omap3_power_states[6].wakeup_latency = 30000;
++ omap3_power_states[6].threshold = 300000;
++ omap3_power_states[6].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[6].core_state = PWRDM_POWER_OFF;
++ omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM;
++}
++
++struct cpuidle_driver omap3_idle_driver = {
++ .name = "omap3_idle",
++ .owner = THIS_MODULE,
++};
++/*
++ * omap3_idle_init - Init routine for OMAP3 idle.
++ * Registers the OMAP3 specific cpuidle driver with the cpuidle f/w
++ * with the valid set of states.
++ */
++int omap3_idle_init(void)
++{
++ int i, count = 0;
++ struct omap3_processor_cx *cx;
++ struct cpuidle_state *state;
++ struct cpuidle_device *dev;
++
++ omap_init_power_states();
++ cpuidle_register_driver(&omap3_idle_driver);
++
++ dev = &per_cpu(omap3_idle_dev, smp_processor_id());
++
++ for (i = 0; i < OMAP3_MAX_STATES; i++) {
++ cx = &omap3_power_states[i];
++ state = &dev->states[count];
++
++ if (!cx->valid)
++ continue;
++ cpuidle_set_statedata(state, cx);
++ state->exit_latency = cx->sleep_latency + cx->wakeup_latency;
++ state->target_residency = cx->threshold;
++ state->flags = cx->flags;
++ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
++ omap3_enter_idle_bm : omap3_enter_idle;
++ sprintf(state->name, "C%d", count+1);
++ count++;
++ }
++
++ if (!count)
++ return -EINVAL;
++ dev->state_count = count;
++
++ if (cpuidle_register_device(dev)) {
++ printk(KERN_ERR "%s: CPUidle register device failed\n",
++ __FUNCTION__);
++ return -EIO;
++ }
++
++ return 0;
++}
++__initcall(omap3_idle_init);
++#endif /* CONFIG_CPU_IDLE */
+Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h 2008-06-09 20:15:39.569121361 +0530
+@@ -0,0 +1,51 @@
++/*
++ * linux/arch/arm/mach-omap2/cpuidle34xx.h
++ *
++ * OMAP3 cpuidle structure definitions
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Written by Rajendra Nayak <rnayak@ti.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 as
++ * published by the Free Software Foundation.
++ *
++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * History:
++ *
++ */
++
++#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
++#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
++
++#define OMAP3_MAX_STATES 7
++#define OMAP3_STATE_C0 0 /* C0 - System executing code */
++#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */
++#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */
++#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */
++#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */
++#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */
++#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */
++
++extern void omap_sram_idle(void);
++extern int omap3_irq_pending(void);
++
++struct omap3_processor_cx {
++ u8 valid;
++ u8 type;
++ u32 sleep_latency;
++ u32 wakeup_latency;
++ u32 mpu_state;
++ u32 core_state;
++ u32 threshold;
++ u32 flags;
++};
++
++void omap_init_power_states(void);
++int omap3_idle_init(void);
++
++#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */
++
+Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:15:33.855303920 +0530
++++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:16:20.976798343 +0530
+@@ -141,7 +141,7 @@ static irqreturn_t prcm_interrupt_handle
+ return IRQ_HANDLED;
+ }
+
+-static void omap_sram_idle(void)
++void omap_sram_idle(void)
+ {
+ /* Variable to tell what needs to be saved and restored
+ * in omap_sram_idle*/
+@@ -156,6 +156,7 @@ static void omap_sram_idle(void)
+
+ mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+ switch (mpu_next_state) {
++ case PWRDM_POWER_ON:
+ case PWRDM_POWER_RET:
+ /* No need to save context */
+ save_state = 0;
+@@ -386,7 +387,9 @@ int __init omap3_pm_init(void)
+
+ prcm_setup_regs();
+
++#ifndef CONFIG_CPU_IDLE
+ pm_idle = omap3_pm_idle;
++#endif
+
+ err1:
+ return ret;
+Index: linux-omap-2.6/drivers/cpuidle/cpuidle.c
+===================================================================
+--- linux-omap-2.6.orig/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:33.856303888 +0530
++++ linux-omap-2.6/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:39.570121329 +0530
+@@ -58,6 +58,11 @@ static void cpuidle_idle_call(void)
+ return;
+ }
+
++#ifdef CONFIG_ARCH_OMAP3
++ local_irq_disable();
++ local_fiq_disable();
++#endif
++
+ /* ask the governor for the next state */
+ next_state = cpuidle_curr_governor->select(dev);
+ if (need_resched())
+@@ -70,6 +75,11 @@ static void cpuidle_idle_call(void)
+ target_state->time += (unsigned long long)dev->last_residency;
+ target_state->usage++;
+
++#ifdef CONFIG_ARCH_OMAP3
++ local_irq_enable();
++ local_fiq_enable();
++#endif
++
+ /* give the governor an opportunity to reflect on the outcome */
+ if (cpuidle_curr_governor->reflect)
+ cpuidle_curr_governor->reflect(dev);
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
-From: "Rajendra Nayak" <rnayak@ti.com>\r
-To: <linux-omap@vger.kernel.org>\r
-Subject: [PATCH 02/02] Kconfig changes\r
-Date: Tue, 10 Jun 2008 12:39:02 +0530\r
-\r
-Updates the CPUidle Kconfig\r
-\r
-Signed-off-by: Rajendra Nayak <rnayak@ti.com> \r
-\r
----\r
- arch/arm/Kconfig | 10 ++++++++++\r
- drivers/cpuidle/Kconfig | 28 ++++++++++++++++++++++------\r
- 2 files changed, 32 insertions(+), 6 deletions(-)\r
-\r
-Index: linux-omap-2.6/arch/arm/Kconfig\r
-===================================================================\r
---- linux-omap-2.6.orig/arch/arm/Kconfig 2008-06-10 11:43:10.790502713 +0530\r
-+++ linux-omap-2.6/arch/arm/Kconfig 2008-06-10 11:43:38.701604549 +0530\r
-@@ -954,6 +954,16 @@ config ATAGS_PROC\r
- \r
- endmenu\r
- \r
-+if (ARCH_OMAP)\r
-+\r
-+menu "CPUIdle"\r
-+\r
-+source "drivers/cpuidle/Kconfig"\r
-+\r
-+endmenu\r
-+\r
-+endif\r
-+\r
- if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)\r
- \r
- menu "CPU Frequency scaling"\r
-Index: linux-omap-2.6/drivers/cpuidle/Kconfig\r
-===================================================================\r
---- linux-omap-2.6.orig/drivers/cpuidle/Kconfig 2008-06-10 11:43:10.790502713 +0530\r
-+++ linux-omap-2.6/drivers/cpuidle/Kconfig 2008-06-10 12:06:36.139332151 +0530\r
-@@ -1,20 +1,36 @@\r
-+menu "CPU idle PM support"\r
- \r
- config CPU_IDLE\r
- bool "CPU idle PM support"\r
-- default ACPI\r
-+ default n\r
- help\r
- CPU idle is a generic framework for supporting software-controlled\r
- idle processor power management. It includes modular cross-platform\r
- governors that can be swapped during runtime.\r
- \r
-- If you're using an ACPI-enabled platform, you should say Y here.\r
-+ If you're using a mobile platform that supports CPU idle PM (e.g.\r
-+ an ACPI-capable notebook), you should say Y here.\r
-+\r
-+if CPU_IDLE\r
-+\r
-+comment "Governors"\r
- \r
- config CPU_IDLE_GOV_LADDER\r
-- bool\r
-+ bool "ladder"\r
- depends on CPU_IDLE\r
-- default y\r
-+ default n\r
- \r
- config CPU_IDLE_GOV_MENU\r
-- bool\r
-+ bool "menu"\r
- depends on CPU_IDLE && NO_HZ\r
-- default y\r
-+ default n\r
-+ help\r
-+ This cpuidle governor evaluates all available states and chooses the\r
-+ deepest state that meets all of the following constraints: BM activity,\r
-+ expected time until next timer interrupt, and last break event time\r
-+ delta. It is designed to minimize power consumption. Currently\r
-+ dynticks is required.\r
-+\r
-+endif # CPU_IDLE\r
-+\r
-+endmenu\r
-\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at http://vger.kernel.org/majordomo-info.html\r
-\r
+From: "Rajendra Nayak" <rnayak@ti.com>
+To: <linux-omap@vger.kernel.org>
+Subject: [PATCH 02/02] Kconfig changes
+Date: Tue, 10 Jun 2008 12:39:02 +0530
+
+Updates the CPUidle Kconfig
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+
+---
+ arch/arm/Kconfig | 10 ++++++++++
+ drivers/cpuidle/Kconfig | 28 ++++++++++++++++++++++------
+ 2 files changed, 32 insertions(+), 6 deletions(-)
+
+Index: linux-omap-2.6/arch/arm/Kconfig
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/Kconfig 2008-06-10 11:43:10.790502713 +0530
++++ linux-omap-2.6/arch/arm/Kconfig 2008-06-10 11:43:38.701604549 +0530
+@@ -954,6 +954,16 @@ config ATAGS_PROC
+
+ endmenu
+
++if (ARCH_OMAP)
++
++menu "CPUIdle"
++
++source "drivers/cpuidle/Kconfig"
++
++endmenu
++
++endif
++
+ if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
+
+ menu "CPU Frequency scaling"
+Index: linux-omap-2.6/drivers/cpuidle/Kconfig
+===================================================================
+--- linux-omap-2.6.orig/drivers/cpuidle/Kconfig 2008-06-10 11:43:10.790502713 +0530
++++ linux-omap-2.6/drivers/cpuidle/Kconfig 2008-06-10 12:06:36.139332151 +0530
+@@ -1,20 +1,36 @@
++menu "CPU idle PM support"
+
+ config CPU_IDLE
+ bool "CPU idle PM support"
+- default ACPI
++ default n
+ help
+ CPU idle is a generic framework for supporting software-controlled
+ idle processor power management. It includes modular cross-platform
+ governors that can be swapped during runtime.
+
+- If you're using an ACPI-enabled platform, you should say Y here.
++ If you're using a mobile platform that supports CPU idle PM (e.g.
++ an ACPI-capable notebook), you should say Y here.
++
++if CPU_IDLE
++
++comment "Governors"
+
+ config CPU_IDLE_GOV_LADDER
+- bool
++ bool "ladder"
+ depends on CPU_IDLE
+- default y
++ default n
+
+ config CPU_IDLE_GOV_MENU
+- bool
++ bool "menu"
+ depends on CPU_IDLE && NO_HZ
+- default y
++ default n
++ help
++ This cpuidle governor evaluates all available states and chooses the
++ deepest state that meets all of the following constraints: BM activity,
++ expected time until next timer interrupt, and last break event time
++ delta. It is designed to minimize power consumption. Currently
++ dynticks is required.
++
++endif # CPU_IDLE
++
++endmenu
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+