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