blob: 8671e1079ab54c7764adfe729294e793e9504d17 [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>
Tony Lindgren670c1042006-04-02 17:46:25 +010033
Russell Kinga09e64f2008-08-05 16:14:15 +010034#include <mach/irqs.h>
35#include <mach/clock.h>
36#include <mach/sram.h>
37#include <mach/pm.h>
Tony Lindgren670c1042006-04-02 17:46:25 +010038
39static struct clk *vclk;
40static void (*omap2_sram_idle)(void);
41static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
42static void (*saved_idle)(void);
43
Tony Lindgren22a16f32006-06-26 16:16:18 -070044extern void __init pmdomain_init(void);
45extern void pmdomain_set_autoidle(void);
46
47static unsigned int omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_SIZE];
48
Tony Lindgren670c1042006-04-02 17:46:25 +010049void omap2_pm_idle(void)
50{
51 local_irq_disable();
52 local_fiq_disable();
53 if (need_resched()) {
54 local_fiq_enable();
55 local_irq_enable();
56 return;
57 }
58
Tony Lindgren670c1042006-04-02 17:46:25 +010059 omap2_sram_idle();
60 local_fiq_enable();
61 local_irq_enable();
62}
63
Rafael J. Wysockie6c5eb92007-10-18 03:04:41 -070064static int omap2_pm_prepare(void)
Tony Lindgren670c1042006-04-02 17:46:25 +010065{
Tony Lindgren670c1042006-04-02 17:46:25 +010066 /* We cannot sleep in idle until we have resumed */
67 saved_idle = pm_idle;
68 pm_idle = NULL;
Rafael J. Wysockie6c5eb92007-10-18 03:04:41 -070069 return 0;
Tony Lindgren670c1042006-04-02 17:46:25 +010070}
71
Tony Lindgren22a16f32006-06-26 16:16:18 -070072static int omap2_pm_suspend(void)
73{
Tony Lindgren22a16f32006-06-26 16:16:18 -070074 return 0;
75}
76
Tony Lindgren670c1042006-04-02 17:46:25 +010077static int omap2_pm_enter(suspend_state_t state)
78{
Tony Lindgren22a16f32006-06-26 16:16:18 -070079 int ret = 0;
80
Tony Lindgren670c1042006-04-02 17:46:25 +010081 switch (state)
82 {
83 case PM_SUSPEND_STANDBY:
84 case PM_SUSPEND_MEM:
Tony Lindgren22a16f32006-06-26 16:16:18 -070085 ret = omap2_pm_suspend();
Tony Lindgren670c1042006-04-02 17:46:25 +010086 break;
Tony Lindgren670c1042006-04-02 17:46:25 +010087 default:
Tony Lindgren22a16f32006-06-26 16:16:18 -070088 ret = -EINVAL;
Tony Lindgren670c1042006-04-02 17:46:25 +010089 }
90
Tony Lindgren22a16f32006-06-26 16:16:18 -070091 return ret;
Tony Lindgren670c1042006-04-02 17:46:25 +010092}
93
Rafael J. Wysockie6c5eb92007-10-18 03:04:41 -070094static void omap2_pm_finish(void)
Tony Lindgren670c1042006-04-02 17:46:25 +010095{
96 pm_idle = saved_idle;
Tony Lindgren670c1042006-04-02 17:46:25 +010097}
98
Rafael J. Wysocki26398a72007-10-18 03:04:40 -070099static struct platform_suspend_ops omap_pm_ops = {
Tony Lindgren670c1042006-04-02 17:46:25 +0100100 .prepare = omap2_pm_prepare,
101 .enter = omap2_pm_enter,
102 .finish = omap2_pm_finish,
Rafael J. Wysocki26398a72007-10-18 03:04:40 -0700103 .valid = suspend_valid_only_mem,
Tony Lindgren670c1042006-04-02 17:46:25 +0100104};
105
106int __init omap2_pm_init(void)
107{
Tony Lindgren670c1042006-04-02 17:46:25 +0100108 return 0;
109}
110
111__initcall(omap2_pm_init);