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