Blame view

arch/arm/mach-sa1100/pm.c 2.61 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * SA1100 Power Management Routines
   *
   * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License.
   *
   * History:
   *
   * 2001-02-06:	Cliff Brake         Initial code
   *
   * 2001-02-25:	Sukjae Cho <sjcho@east.isi.edu> &
   * 		Chester Kuo <chester@linux.org.tw>
   * 			Save more value for the resume function! Support
   * 			Bitsy/Assabet/Freebird board
   *
2f82af08f   Nicolas Pitre   Nicolas Pitre has...
18
   * 2001-08-29:	Nicolas Pitre <nico@fluxnic.net>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
24
25
26
27
28
   * 			Cleaned up, pushed platform dependent stuff
   * 			in the platform specific files.
   *
   * 2002-05-27:	Nicolas Pitre	Killed sleep.h and the kmalloced save array.
   * 				Storage is local on the stack now.
   */
  #include <linux/init.h>
  #include <linux/suspend.h>
  #include <linux/errno.h>
  #include <linux/time.h>
a09e64fbc   Russell King   [ARM] Move includ...
29
  #include <mach/hardware.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  #include <asm/memory.h>
2c74a0cef   Russell King   ARM: pm: hide 1st...
31
  #include <asm/suspend.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
  #include <asm/system.h>
  #include <asm/mach/time.h>
29cb3cd20   Russell King   ARM: pm: allow su...
34
  extern int sa1100_finish_suspend(unsigned long);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
38
39
40
41
42
43
  
  #define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
  #define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
  
  /*
   * List of global SA11x0 peripheral registers to preserve.
   * More ones like CP and general purpose register values are preserved
   * on the stack and then the stack pointer is stored last in sleep.S.
   */
649de51b8   Robert Jarzmik   [ARM] 5027/1: Fix...
44
  enum {	SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
  	SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
  
  	SLEEP_SAVE_Ser1SDCR0,
649de51b8   Robert Jarzmik   [ARM] 5027/1: Fix...
48
  	SLEEP_SAVE_COUNT
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
  };
  
  
  static int sa11x0_pm_enter(suspend_state_t state)
  {
649de51b8   Robert Jarzmik   [ARM] 5027/1: Fix...
54
  	unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  	gpio = GPLR;
  
  	/* save vital registers */
  	SAVE(GPDR);
  	SAVE(GAFR);
  
  	SAVE(PPDR);
  	SAVE(PPSR);
  	SAVE(PPAR);
  	SAVE(PSDR);
  
  	SAVE(Ser1SDCR0);
  
  	/* Clear previous reset status */
  	RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
  
  	/* set resume return address */
96c20015d   Russell King   ARM: pm: convert ...
73
  	PSPR = virt_to_phys(cpu_resume);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
  
  	/* go zzz */
2c74a0cef   Russell King   ARM: pm: hide 1st...
76
  	cpu_suspend(0, sa1100_finish_suspend);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  
  	/*
  	 * Ensure not to come back here if it wasn't intended
  	 */
  	PSPR = 0;
  
  	/*
  	 * Ensure interrupt sources are disabled; we will re-init
  	 * the interrupt subsystem via the device manager.
  	 */
  	ICLR = 0;
  	ICCR = 1;
  	ICMR = 0;
  
  	/* restore registers */
  	RESTORE(GPDR);
  	RESTORE(GAFR);
  
  	RESTORE(PPDR);
  	RESTORE(PPSR);
  	RESTORE(PPAR);
  	RESTORE(PSDR);
  
  	RESTORE(Ser1SDCR0);
  
  	GPSR = gpio;
  	GPCR = ~gpio;
  
  	/*
  	 * Clear the peripheral sleep-hold bit.
  	 */
  	PSSR = PSSR_PH;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
  	return 0;
  }
2f55ac072   Lionel Debroux   suspend: constify...
111
  static const struct platform_suspend_ops sa11x0_pm_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
  	.enter		= sa11x0_pm_enter,
26398a70e   Rafael J. Wysocki   PM: Rename struct...
113
  	.valid		= suspend_valid_only_mem,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
115
116
117
  };
  
  static int __init sa11x0_pm_init(void)
  {
26398a70e   Rafael J. Wysocki   PM: Rename struct...
118
  	suspend_set_ops(&sa11x0_pm_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
  	return 0;
  }
  
  late_initcall(sa11x0_pm_init);