pm.c revision b81ad56b078a5ee7c0061b117c7287e8987d6692
1/*
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
19#include <linux/suspend.h>
20#include <linux/sched.h>
21#include <linux/proc_fs.h>
22#include <linux/interrupt.h>
23#include <linux/sysfs.h>
24#include <linux/module.h>
25#include <linux/delay.h>
26#include <linux/clk.h>
27
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
45extern void __init pmdomain_init(void);
46extern void pmdomain_set_autoidle(void);
47
48static unsigned int omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_SIZE];
49
50void 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
72static int omap2_pm_prepare(void)
73{
74	/* We cannot sleep in idle until we have resumed */
75	saved_idle = pm_idle;
76	pm_idle = NULL;
77	return 0;
78}
79
80static int omap2_pm_suspend(void)
81{
82	return 0;
83}
84
85static int omap2_pm_enter(suspend_state_t state)
86{
87	int ret = 0;
88
89	switch (state)
90	{
91	case PM_SUSPEND_STANDBY:
92	case PM_SUSPEND_MEM:
93		ret = omap2_pm_suspend();
94		break;
95	default:
96		ret = -EINVAL;
97	}
98
99	return ret;
100}
101
102static void omap2_pm_finish(void)
103{
104	pm_idle = saved_idle;
105}
106
107static struct platform_suspend_ops omap_pm_ops = {
108	.prepare	= omap2_pm_prepare,
109	.enter		= omap2_pm_enter,
110	.finish		= omap2_pm_finish,
111	.valid		= suspend_valid_only_mem,
112};
113
114int __init omap2_pm_init(void)
115{
116	return 0;
117}
118
119__initcall(omap2_pm_init);
120