This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / arm / mach-omap / pm.c
1 /*
2  * linux/arch/arm/mach-omap/pm.c
3  *
4  * OMAP Power Management Routines
5  *
6  * Original code for the SA11x0:
7  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
8  *
9  * Modified for the PXA250 by Nicolas Pitre:
10  * Copyright (c) 2002 Monta Vista Software, Inc.
11  *
12  * Modified for the OMAP1510 by David Singleton:
13  * Copyright (c) 2002 Monta Vista Software, Inc.
14  *
15  * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
16  *
17  * This program is free software; you can redistribute it and/or modify it
18  * under the terms of the GNU General Public License as published by the
19  * Free Software Foundation; either version 2 of the License, or (at your
20  * option) any later version.
21  *
22  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * You should have received a copy of the GNU General Public License along
34  * with this program; if not, write to the Free Software Foundation, Inc.,
35  * 675 Mass Ave, Cambridge, MA 02139, USA.
36  */
37
38 #include <linux/pm.h>
39 #include <linux/sched.h>
40 #include <linux/proc_fs.h>
41 #include <linux/pm.h>
42
43 #include <asm/io.h>
44 #include <asm/mach-types.h>
45 #include <asm/arch/omap16xx.h>
46 #include <asm/arch/pm.h>
47 #include <asm/arch/mux.h>
48 #include <asm/arch/tps65010.h>
49
50 #include "clock.h"
51
52 static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
53 static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
54 static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
55 static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
56
57 /*
58  * Let's power down on idle, but only if we are really
59  * idle, because once we start down the path of
60  * going idle we continue to do idle even if we get
61  * a clock tick interrupt . .
62  */
63 void omap_pm_idle(void)
64 {
65         int (*func_ptr)(void) = 0;
66         unsigned int mask32 = 0;
67
68         /*
69          * If the DSP is being used let's just idle the CPU, the overhead
70          * to wake up from Big Sleep is big, milliseconds versus micro
71          * seconds for wait for interrupt.
72          */
73
74         local_irq_disable();
75         local_fiq_disable();
76         if (need_resched()) {
77                 local_fiq_enable();
78                 local_irq_enable();
79                 return;
80         }
81         mask32 = omap_readl(ARM_SYSST);
82         local_fiq_enable();
83         local_irq_enable();
84         if ((mask32 & DSP_IDLE) == 0) {
85                 __asm__ volatile ("mcr  p15, 0, r0, c7, c0, 4");
86         } else {
87
88                 if (cpu_is_omap1510()) {
89                         func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND);
90                 } else if (cpu_is_omap1610() || cpu_is_omap1710()) {
91                         func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND);
92                 } else if (cpu_is_omap5912()) {
93                         func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND);
94                 }
95
96                 func_ptr();
97         }
98 }
99
100 /*
101  * Configuration of the wakeup event is board specific. For the
102  * moment we put it into this helper function. Later it may move
103  * to board specific files.
104  */
105 static void omap_pm_wakeup_setup(void)
106 {
107         /*
108          * Enable ARM XOR clock and release peripheral from reset by
109          * writing 1 to PER_EN bit in ARM_RSTCT2, this is required
110          * for UART configuration to use UART2 to wake up.
111          */
112
113         omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2);
114         omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2);
115         omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL);
116
117         /*
118          * Turn off all interrupts except L1-2nd level cascade,
119          * and the L2 wakeup interrupts: keypad and UART2.
120          */
121
122         omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR);
123
124         if (cpu_is_omap1510()) {
125                 omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD),  OMAP_IH2_MIR);
126         }
127
128         if (cpu_is_omap16xx()) {
129                 omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR);
130
131                 omap_writel(~0x0, OMAP_IH2_1_MIR);
132                 omap_writel(~0x0, OMAP_IH2_2_MIR);
133                 omap_writel(~0x0, OMAP_IH2_3_MIR);
134         }
135
136         /*  New IRQ agreement */
137         omap_writel(1, OMAP_IH1_CONTROL);
138
139         /* external PULL to down, bit 22 = 0 */
140         omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2);
141 }
142
143 void omap_pm_suspend(void)
144 {
145         unsigned int mask32 = 0;
146         unsigned long arg0 = 0, arg1 = 0;
147         int (*func_ptr)(unsigned short, unsigned short) = 0;
148         unsigned short save_dsp_idlect2;
149
150         printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev);
151
152         if (machine_is_omap_osk()) {
153                 /* Stop LED1 (D9) blink */
154                 tps65010_set_led(LED1, OFF);
155         }
156
157         /*
158          * Step 1: turn off interrupts
159          */
160
161         local_irq_disable();
162         local_fiq_disable();
163
164         /*
165          * Step 2: save registers
166          *
167          * The omap is a strange/beautiful device. The caches, memory
168          * and register state are preserved across power saves.
169          * We have to save and restore very little register state to
170          * idle the omap.
171          *
172          * Save interrupt, MPUI, ARM and UPLD control registers.
173          */
174
175         if (cpu_is_omap1510()) {
176                 MPUI1510_SAVE(OMAP_IH1_MIR);
177                 MPUI1510_SAVE(OMAP_IH2_MIR);
178                 MPUI1510_SAVE(MPUI_CTRL);
179                 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
180                 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
181                 MPUI1510_SAVE(EMIFS_CONFIG);
182                 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
183         } else if (cpu_is_omap16xx()) {
184                 MPUI1610_SAVE(OMAP_IH1_MIR);
185                 MPUI1610_SAVE(OMAP_IH2_0_MIR);
186                 MPUI1610_SAVE(OMAP_IH2_1_MIR);
187                 MPUI1610_SAVE(OMAP_IH2_2_MIR);
188                 MPUI1610_SAVE(OMAP_IH2_3_MIR);
189                 MPUI1610_SAVE(MPUI_CTRL);
190                 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
191                 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
192                 MPUI1610_SAVE(EMIFS_CONFIG);
193                 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
194         }
195
196         ARM_SAVE(ARM_CKCTL);
197         ARM_SAVE(ARM_IDLECT1);
198         ARM_SAVE(ARM_IDLECT2);
199         ARM_SAVE(ARM_EWUPCT);
200         ARM_SAVE(ARM_RSTCT1);
201         ARM_SAVE(ARM_RSTCT2);
202         ARM_SAVE(ARM_SYSST);
203         ULPD_SAVE(ULPD_CLOCK_CTRL);
204         ULPD_SAVE(ULPD_STATUS_REQ);
205
206         /*
207          * Step 3: LOW_PWR signal enabling
208          *
209          * Allow the LOW_PWR signal to be visible on MPUIO5 ball.
210          */
211         if (cpu_is_omap1510()) {
212                 /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
213                 omap_writew(omap_readw(ULPD_POWER_CTRL) |
214                             OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
215         } else if (cpu_is_omap16xx()) {
216                 /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
217                 omap_writew(omap_readw(ULPD_POWER_CTRL) |
218                             OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
219         }
220
221         /* configure LOW_PWR pin */
222         omap_cfg_reg(T20_1610_LOW_PWR);
223
224         /*
225          * Step 4: OMAP DSP Shutdown
226          */
227
228         /* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */
229         omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE,
230                     ARM_RSTCT1);
231
232         /* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */
233         omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG);
234
235         /* Set EN_DSPCK = 0, stop DSP block clock */
236         omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL);
237
238         /* Stop any DSP domain clocks */
239         omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
240         save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
241         __raw_writew(0, DSP_IDLECT2);
242
243         /*
244          * Step 5: Wakeup Event Setup
245          */
246
247         omap_pm_wakeup_setup();
248
249         /*
250          * Step 6a: ARM and Traffic controller shutdown
251          *
252          * Step 6 starts here with clock and watchdog disable
253          */
254
255         /* stop clocks */
256         mask32 = omap_readl(ARM_IDLECT2);
257         mask32 &= ~(1<<EN_WDTCK);  /* bit 0 -> 0 (WDT clock) */
258         mask32 |=  (1<<EN_XORPCK); /* bit 1 -> 1 (XORPCK clock) */
259         mask32 &= ~(1<<EN_PERCK);  /* bit 2 -> 0 (MPUPER_CK clock) */
260         mask32 &= ~(1<<EN_LCDCK);  /* bit 3 -> 0 (LCDC clock) */
261         mask32 &= ~(1<<EN_LBCK);   /* bit 4 -> 0 (local bus clock) */
262         mask32 |=  (1<<EN_APICK);  /* bit 6 -> 1 (MPUI clock) */
263         mask32 &= ~(1<<EN_TIMCK);  /* bit 7 -> 0 (MPU timer clock) */
264         mask32 &= ~(1<<DMACK_REQ); /* bit 8 -> 0 (DMAC clock) */
265         mask32 &= ~(1<<EN_GPIOCK); /* bit 9 -> 0 (GPIO clock) */
266         omap_writel(mask32, ARM_IDLECT2);
267
268         /* disable ARM watchdog */
269         omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
270         omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
271
272         /*
273          * Step 6b: ARM and Traffic controller shutdown
274          *
275          * Step 6 continues here. Prepare jump to power management
276          * assembly code in internal SRAM.
277          *
278          * Since the omap_cpu_suspend routine has been copied to
279          * SRAM, we'll do an indirect procedure call to it and pass the
280          * contents of arm_idlect1 and arm_idlect2 so it can restore
281          * them when it wakes up and it will return.
282          */
283
284         arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
285         arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
286
287         if (cpu_is_omap1510()) {
288                 func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND);
289         } else if (cpu_is_omap1610() || cpu_is_omap1710()) {
290                 func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND);
291         } else if (cpu_is_omap5912()) {
292                 func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND);
293         }
294
295         /*
296          * Step 6c: ARM and Traffic controller shutdown
297          *
298          * Jump to assembly code. The processor will stay there
299          * until wake up.
300          */
301
302         func_ptr(arg0, arg1);
303
304         /*
305          * If we are here, processor is woken up!
306          */
307
308         if (cpu_is_omap1510()) {
309                 /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
310                 omap_writew(omap_readw(ULPD_POWER_CTRL) &
311                             ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
312         } else if (cpu_is_omap16xx()) {
313                 /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
314                 omap_writew(omap_readw(ULPD_POWER_CTRL) &
315                             ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
316         }
317
318
319         /* Restore DSP clocks */
320         omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
321         __raw_writew(save_dsp_idlect2, DSP_IDLECT2);
322         ARM_RESTORE(ARM_IDLECT2);
323
324         /*
325          * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
326          */
327
328         ARM_RESTORE(ARM_CKCTL);
329         ARM_RESTORE(ARM_EWUPCT);
330         ARM_RESTORE(ARM_RSTCT1);
331         ARM_RESTORE(ARM_RSTCT2);
332         ARM_RESTORE(ARM_SYSST);
333         ULPD_RESTORE(ULPD_CLOCK_CTRL);
334         ULPD_RESTORE(ULPD_STATUS_REQ);
335
336         if (cpu_is_omap1510()) {
337                 MPUI1510_RESTORE(MPUI_CTRL);
338                 MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
339                 MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
340                 MPUI1510_RESTORE(EMIFS_CONFIG);
341                 MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
342                 MPUI1510_RESTORE(OMAP_IH1_MIR);
343                 MPUI1510_RESTORE(OMAP_IH2_MIR);
344         } else if (cpu_is_omap16xx()) {
345                 MPUI1610_RESTORE(MPUI_CTRL);
346                 MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
347                 MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
348                 MPUI1610_RESTORE(EMIFS_CONFIG);
349                 MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
350
351                 MPUI1610_RESTORE(OMAP_IH1_MIR);
352                 MPUI1610_RESTORE(OMAP_IH2_0_MIR);
353                 MPUI1610_RESTORE(OMAP_IH2_1_MIR);
354                 MPUI1610_RESTORE(OMAP_IH2_2_MIR);
355                 MPUI1610_RESTORE(OMAP_IH2_3_MIR);
356         }
357
358         /*
359          * Reenable interrupts
360          */
361
362         local_irq_enable();
363         local_fiq_enable();
364
365         printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
366
367         if (machine_is_omap_osk()) {
368                 /* Let LED1 (D9) blink again */
369                 tps65010_set_led(LED1, BLINK);
370         }
371 }
372
373 #if defined(DEBUG) && defined(CONFIG_PROC_FS)
374 static int g_read_completed;
375
376 /*
377  * Read system PM registers for debugging
378  */
379 static int omap_pm_read_proc(
380         char *page_buffer,
381         char **my_first_byte,
382         off_t virtual_start,
383         int length,
384         int *eof,
385         void *data)
386 {
387         int my_buffer_offset = 0;
388         char * const my_base = page_buffer;
389
390         ARM_SAVE(ARM_CKCTL);
391         ARM_SAVE(ARM_IDLECT1);
392         ARM_SAVE(ARM_IDLECT2);
393         ARM_SAVE(ARM_EWUPCT);
394         ARM_SAVE(ARM_RSTCT1);
395         ARM_SAVE(ARM_RSTCT2);
396         ARM_SAVE(ARM_SYSST);
397
398         ULPD_SAVE(ULPD_IT_STATUS);
399         ULPD_SAVE(ULPD_CLOCK_CTRL);
400         ULPD_SAVE(ULPD_SOFT_REQ);
401         ULPD_SAVE(ULPD_STATUS_REQ);
402         ULPD_SAVE(ULPD_DPLL_CTRL);
403         ULPD_SAVE(ULPD_POWER_CTRL);
404
405         if (cpu_is_omap1510()) {
406                 MPUI1510_SAVE(MPUI_CTRL);
407                 MPUI1510_SAVE(MPUI_DSP_STATUS);
408                 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
409                 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
410                 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
411                 MPUI1510_SAVE(EMIFS_CONFIG);
412         } else if (cpu_is_omap16xx()) {
413                 MPUI1610_SAVE(MPUI_CTRL);
414                 MPUI1610_SAVE(MPUI_DSP_STATUS);
415                 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
416                 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
417                 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
418                 MPUI1610_SAVE(EMIFS_CONFIG);
419         }
420
421         if (virtual_start == 0) {
422                 g_read_completed = 0;
423
424                 my_buffer_offset += sprintf(my_base + my_buffer_offset,
425                    "ARM_CKCTL_REG:            0x%-8x     \n"
426                    "ARM_IDLECT1_REG:          0x%-8x     \n"
427                    "ARM_IDLECT2_REG:          0x%-8x     \n"
428                    "ARM_EWUPCT_REG:           0x%-8x     \n"
429                    "ARM_RSTCT1_REG:           0x%-8x     \n"
430                    "ARM_RSTCT2_REG:           0x%-8x     \n"
431                    "ARM_SYSST_REG:            0x%-8x     \n"
432                    "ULPD_IT_STATUS_REG:       0x%-4x     \n"
433                    "ULPD_CLOCK_CTRL_REG:      0x%-4x     \n"
434                    "ULPD_SOFT_REQ_REG:        0x%-4x     \n"
435                    "ULPD_DPLL_CTRL_REG:       0x%-4x     \n"
436                    "ULPD_STATUS_REQ_REG:      0x%-4x     \n"
437                    "ULPD_POWER_CTRL_REG:      0x%-4x     \n",
438                    ARM_SHOW(ARM_CKCTL),
439                    ARM_SHOW(ARM_IDLECT1),
440                    ARM_SHOW(ARM_IDLECT2),
441                    ARM_SHOW(ARM_EWUPCT),
442                    ARM_SHOW(ARM_RSTCT1),
443                    ARM_SHOW(ARM_RSTCT2),
444                    ARM_SHOW(ARM_SYSST),
445                    ULPD_SHOW(ULPD_IT_STATUS),
446                    ULPD_SHOW(ULPD_CLOCK_CTRL),
447                    ULPD_SHOW(ULPD_SOFT_REQ),
448                    ULPD_SHOW(ULPD_DPLL_CTRL),
449                    ULPD_SHOW(ULPD_STATUS_REQ),
450                    ULPD_SHOW(ULPD_POWER_CTRL));
451
452                 if (cpu_is_omap1510()) {
453                         my_buffer_offset += sprintf(my_base + my_buffer_offset,
454                            "MPUI1510_CTRL_REG             0x%-8x \n"
455                            "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
456                            "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
457                            "MPUI1510_DSP_API_CONFIG_REG:  0x%-8x \n"
458                            "MPUI1510_SDRAM_CONFIG_REG:    0x%-8x \n"
459                            "MPUI1510_EMIFS_CONFIG_REG:    0x%-8x \n",
460                            MPUI1510_SHOW(MPUI_CTRL),
461                            MPUI1510_SHOW(MPUI_DSP_STATUS),
462                            MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
463                            MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
464                            MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
465                            MPUI1510_SHOW(EMIFS_CONFIG));
466                 } else if (cpu_is_omap16xx()) {
467                         my_buffer_offset += sprintf(my_base + my_buffer_offset,
468                            "MPUI1610_CTRL_REG             0x%-8x \n"
469                            "MPUI1610_DSP_STATUS_REG:      0x%-8x \n"
470                            "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
471                            "MPUI1610_DSP_API_CONFIG_REG:  0x%-8x \n"
472                            "MPUI1610_SDRAM_CONFIG_REG:    0x%-8x \n"
473                            "MPUI1610_EMIFS_CONFIG_REG:    0x%-8x \n",
474                            MPUI1610_SHOW(MPUI_CTRL),
475                            MPUI1610_SHOW(MPUI_DSP_STATUS),
476                            MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
477                            MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
478                            MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
479                            MPUI1610_SHOW(EMIFS_CONFIG));
480                 }
481
482                 g_read_completed++;
483         } else if (g_read_completed >= 1) {
484                  *eof = 1;
485                  return 0;
486         }
487         g_read_completed++;
488
489         *my_first_byte = page_buffer;
490         return  my_buffer_offset;
491 }
492
493 static void omap_pm_init_proc(void)
494 {
495         struct proc_dir_entry *entry;
496
497         entry = create_proc_read_entry("driver/omap_pm",
498                                        S_IWUSR | S_IRUGO, NULL,
499                                        omap_pm_read_proc, 0);
500 }
501
502 #endif /* DEBUG && CONFIG_PROC_FS */
503
504 /*
505  *      omap_pm_prepare - Do preliminary suspend work.
506  *      @state:         suspend state we're entering.
507  *
508  */
509 //#include <asm/arch/hardware.h>
510
511 static int omap_pm_prepare(u32 state)
512 {
513         int error = 0;
514
515         switch (state)
516         {
517         case PM_SUSPEND_STANDBY:
518         case PM_SUSPEND_MEM:
519                 break;
520
521         case PM_SUSPEND_DISK:
522                 return -ENOTSUPP;
523
524         default:
525                 return -EINVAL;
526         }
527
528         return error;
529 }
530
531
532 /*
533  *      omap_pm_enter - Actually enter a sleep state.
534  *      @state:         State we're entering.
535  *
536  */
537
538 static int omap_pm_enter(u32 state)
539 {
540         switch (state)
541         {
542         case PM_SUSPEND_STANDBY:
543         case PM_SUSPEND_MEM:
544                 omap_pm_suspend();
545                 break;
546
547         case PM_SUSPEND_DISK:
548                 return -ENOTSUPP;
549
550         default:
551                 return -EINVAL;
552         }
553
554         return 0;
555 }
556
557
558 /**
559  *      omap_pm_finish - Finish up suspend sequence.
560  *      @state:         State we're coming out of.
561  *
562  *      This is called after we wake back up (or if entering the sleep state
563  *      failed).
564  */
565
566 static int omap_pm_finish(u32 state)
567 {
568         return 0;
569 }
570
571
572 struct pm_ops omap_pm_ops ={
573         .pm_disk_mode = 0,
574         .prepare        = omap_pm_prepare,
575         .enter          = omap_pm_enter,
576         .finish         = omap_pm_finish,
577 };
578
579 static int __init omap_pm_init(void)
580 {
581         printk("Power Management for TI OMAP.\n");
582         pm_idle = omap_pm_idle;
583         /*
584          * We copy the assembler sleep/wakeup routines to SRAM.
585          * These routines need to be in SRAM as that's the only
586          * memory the MPU can see when it wakes up.
587          */
588
589 #ifdef  CONFIG_ARCH_OMAP1510
590         if (cpu_is_omap1510()) {
591                 memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND,
592                        omap1510_idle_loop_suspend,
593                        omap1510_idle_loop_suspend_sz);
594                 memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend,
595                        omap1510_cpu_suspend_sz);
596         } else
597 #endif
598         if (cpu_is_omap1610() || cpu_is_omap1710()) {
599                 memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND,
600                        omap1610_idle_loop_suspend,
601                        omap1610_idle_loop_suspend_sz);
602                 memcpy((void *)OMAP1610_SRAM_API_SUSPEND, omap1610_cpu_suspend,
603                        omap1610_cpu_suspend_sz);
604         } else if (cpu_is_omap5912()) {
605                 memcpy((void *)OMAP5912_SRAM_IDLE_SUSPEND,
606                        omap1610_idle_loop_suspend,
607                        omap1610_idle_loop_suspend_sz);
608                 memcpy((void *)OMAP5912_SRAM_API_SUSPEND, omap1610_cpu_suspend,
609                        omap1610_cpu_suspend_sz);
610         }
611
612         pm_set_ops(&omap_pm_ops);
613
614 #if defined(DEBUG) && defined(CONFIG_PROC_FS)
615         omap_pm_init_proc();
616 #endif
617
618         return 0;
619 }
620 __initcall(omap_pm_init);
621