blob: aad781dcf1b1b4f5cf18e3d0d8c3b034c5394f98 [file] [log] [blame]
Tony Lindgren670c1042006-04-02 17:46:25 +01001/*
2 * linux/arch/arm/mach-omap2/pm.c
3 *
4 * OMAP2 Power Management Routines
5 *
6 * Copyright (C) 2006 Nokia Corporation
7 * Tony Lindgren <tony@atomide.com>
8 *
9 * Copyright (C) 2005 Texas Instruments, Inc.
10 * Richard Woodruff <r-woodruff2@ti.com>
11 *
12 * Based on pm.c for omap1
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
Rafael J. Wysocki95d9ffb2007-10-18 03:04:39 -070019#include <linux/suspend.h>
Tony Lindgren670c1042006-04-02 17:46:25 +010020#include <linux/sched.h>
21#include <linux/proc_fs.h>
Tony Lindgren670c1042006-04-02 17:46:25 +010022#include <linux/interrupt.h>
23#include <linux/sysfs.h>
24#include <linux/module.h>
Tony Lindgren22a16f32006-06-26 16:16:18 -070025#include <linux/delay.h>
Tony Lindgrenb81ad562008-03-18 10:59:00 +020026#include <linux/clk.h>
Tony Lindgren670c1042006-04-02 17:46:25 +010027
28#include <asm/io.h>
29#include <asm/irq.h>
30#include <asm/atomic.h>
31#include <asm/mach/time.h>
32#include <asm/mach/irq.h>
33#include <asm/mach-types.h>
34
35#include <asm/arch/irqs.h>
36#include <asm/arch/clock.h>
37#include <asm/arch/sram.h>
38#include <asm/arch/pm.h>
39
40static struct clk *vclk;
41static void (*omap2_sram_idle)(void);
42static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
43static void (*saved_idle)(void);
44
Tony Lindgren22a16f32006-06-26 16:16:18 -070045extern void __init pmdomain_init(void);
46extern void pmdomain_set_autoidle(void);
47
48static unsigned int omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_SIZE];
49
Tony Lindgren670c1042006-04-02 17:46:25 +010050void omap2_pm_idle(void)
51{
52 local_irq_disable();
53 local_fiq_disable();
54 if (need_resched()) {
55 local_fiq_enable();
56 local_irq_enable();
57 return;
58 }
59
60 /*
61 * Since an interrupt may set up a timer, we don't want to
62 * reprogram the hardware timer with interrupts enabled.
63 * Re-enable interrupts only after returning from idle.
64 */
65 timer_dyn_reprogram();
66
67 omap2_sram_idle();
68 local_fiq_enable();
69 local_irq_enable();
70}
71
Rafael J. Wysockie6c5eb92007-10-18 03:04:41 -070072static int omap2_pm_prepare(void)
Tony Lindgren670c1042006-04-02 17:46:25 +010073{
Tony Lindgren670c1042006-04-02 17:46:25 +010074 /* We cannot sleep in idle until we have resumed */
75 saved_idle = pm_idle;
76 pm_idle = NULL;
Rafael J. Wysockie6c5eb92007-10-18 03:04:41 -070077 return 0;
Tony Lindgren670c1042006-04-02 17:46:25 +010078}
79
Tony Lindgren22a16f32006-06-26 16:16:18 -070080static int omap2_pm_suspend(void)
81{
Tony Lindgren22a16f32006-06-26 16:16:18 -070082 return 0;
83}
84
Tony Lindgren670c1042006-04-02 17:46:25 +010085static int omap2_pm_enter(suspend_state_t state)
86{
Tony Lindgren22a16f32006-06-26 16:16:18 -070087 int ret = 0;
88
Tony Lindgren670c1042006-04-02 17:46:25 +010089 switch (state)
90 {
91 case PM_SUSPEND_STANDBY:
92 case PM_SUSPEND_MEM:
Tony Lindgren22a16f32006-06-26 16:16:18 -070093 ret = omap2_pm_suspend();
Tony Lindgren670c1042006-04-02 17:46:25 +010094 break;
Tony Lindgren670c1042006-04-02 17:46:25 +010095 default:
Tony Lindgren22a16f32006-06-26 16:16:18 -070096 ret = -EINVAL;
Tony Lindgren670c1042006-04-02 17:46:25 +010097 }
98
Tony Lindgren22a16f32006-06-26 16:16:18 -070099 return ret;
Tony Lindgren670c1042006-04-02 17:46:25 +0100100}
101
Rafael J. Wysockie6c5eb92007-10-18 03:04:41 -0700102static void omap2_pm_finish(void)
Tony Lindgren670c1042006-04-02 17:46:25 +0100103{
104 pm_idle = saved_idle;
Tony Lindgren670c1042006-04-02 17:46:25 +0100105}
106
Rafael J. Wysocki26398a72007-10-18 03:04:40 -0700107static struct platform_suspend_ops omap_pm_ops = {
Tony Lindgren670c1042006-04-02 17:46:25 +0100108 .prepare = omap2_pm_prepare,
109 .enter = omap2_pm_enter,
110 .finish = omap2_pm_finish,
Rafael J. Wysocki26398a72007-10-18 03:04:40 -0700111 .valid = suspend_valid_only_mem,
Tony Lindgren670c1042006-04-02 17:46:25 +0100112};
113
114int __init omap2_pm_init(void)
115{
Tony Lindgren670c1042006-04-02 17:46:25 +0100116 return 0;
117}
118
119__initcall(omap2_pm_init);