aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm34xx.c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@deeprootsystems.com>2009-02-04 13:51:40 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2009-05-28 13:59:06 -0400
commit4af4016c53f52b26461b8030211f8427a58fa5ed (patch)
tree984ffcb57bcc8158332c10ef799203bd905d7147 /arch/arm/mach-omap2/pm34xx.c
parent5a1a5abdb2e9a301f1ac62feb37228f3f4d3117c (diff)
OMAP3: PM: UART: disable clocks when idle and off-mode support
This patch allows the UART clocks to be disabled when the OMAP UARTs are inactive, thus permitting the chip to hit retention in idle. After the expiration of an activity timer, each UART is allowed to disable its clocks so the system can enter retention. The activity timer is (re)activated on any UART interrupt, UART wake event or any IO pad wakeup. The actual disable of the UART clocks is done in the 'prepare_idle' hook called from the OMAP idle loop. While the activity timer is active, the smart-idle mode of the UART is also disabled. This is due to a "feature" of the UART module that after a UART wakeup, the smart-idle mode may be entered before the UART has communicated the interrupt, or upon TX, an idle mode may be entered before the TX FIFOs are emptied. Upon suspend, the 'prepare_suspend' hook cancels any pending activity timers and allows the clocks to be disabled immediately. In addition, upon disabling clocks the UART state is saved in case of an off-mode transition while clocks are off. Special thanks to Tero Kristo for the initial ideas and first versions of UART idle support, and to Jouni Hogander for extra testing and bugfixes. Tested on OMAP3 (Beagle, RX51, SDP, EVM) and OMAP2 (n810) Cc: Tero Kristo <tero.kristo@nokia.com> Cc: Jouni Hogander <jouni.hogander@nokia.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
-rw-r--r--arch/arm/mach-omap2/pm34xx.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b2a8730771e9..54876aca2d45 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -27,6 +27,7 @@
27#include <mach/clockdomain.h> 27#include <mach/clockdomain.h>
28#include <mach/powerdomain.h> 28#include <mach/powerdomain.h>
29#include <mach/control.h> 29#include <mach/control.h>
30#include <mach/serial.h>
30 31
31#include "cm.h" 32#include "cm.h"
32#include "cm-regbits-34xx.h" 33#include "cm-regbits-34xx.h"
@@ -168,10 +169,16 @@ static void omap_sram_idle(void)
168 return; 169 return;
169 } 170 }
170 omap2_gpio_prepare_for_retention(); 171 omap2_gpio_prepare_for_retention();
172 omap_uart_prepare_idle(0);
173 omap_uart_prepare_idle(1);
174 omap_uart_prepare_idle(2);
171 175
172 _omap_sram_idle(NULL, save_state); 176 _omap_sram_idle(NULL, save_state);
173 cpu_init(); 177 cpu_init();
174 178
179 omap_uart_resume_idle(2);
180 omap_uart_resume_idle(1);
181 omap_uart_resume_idle(0);
175 omap2_gpio_resume_after_retention(); 182 omap2_gpio_resume_after_retention();
176} 183}
177 184
@@ -204,6 +211,11 @@ static int omap3_fclks_active(void)
204 CM_FCLKEN); 211 CM_FCLKEN);
205 fck_per = cm_read_mod_reg(OMAP3430_PER_MOD, 212 fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
206 CM_FCLKEN); 213 CM_FCLKEN);
214
215 /* Ignore UART clocks. These are handled by UART core (serial.c) */
216 fck_core1 &= ~(OMAP3430_EN_UART1 | OMAP3430_EN_UART2);
217 fck_per &= ~OMAP3430_EN_UART3;
218
207 if (fck_core1 | fck_core3 | fck_sgx | fck_dss | 219 if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
208 fck_cam | fck_per | fck_usbhost) 220 fck_cam | fck_per | fck_usbhost)
209 return 1; 221 return 1;
@@ -212,6 +224,8 @@ static int omap3_fclks_active(void)
212 224
213static int omap3_can_sleep(void) 225static int omap3_can_sleep(void)
214{ 226{
227 if (!omap_uart_can_sleep())
228 return 0;
215 if (omap3_fclks_active()) 229 if (omap3_fclks_active())
216 return 0; 230 return 0;
217 return 1; 231 return 1;
@@ -301,6 +315,7 @@ static int omap3_pm_suspend(void)
301 goto restore; 315 goto restore;
302 } 316 }
303 317
318 omap_uart_prepare_suspend();
304 omap_sram_idle(); 319 omap_sram_idle();
305 320
306restore: 321restore: