aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2007-07-25 01:36:31 -0400
committerLen Brown <len.brown@intel.com>2007-07-25 01:36:31 -0400
commitcb3e0c107bebc6cf3e7158f7aa54c32017c7d4c4 (patch)
tree2c52ac06cce163bf467d259119b824eed96f2eca /drivers/acpi
parent1e1f3f24cdbc53e67acd7b2e37e6cf0cb11bd13c (diff)
parent50ad147aa09c829cd452fae6ca99396c0b5b0695 (diff)
Pull d-states into release branch
Conflicts: drivers/acpi/sleep/main.c Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/sleep/main.c160
1 files changed, 127 insertions, 33 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 54c2dfcf8651..ab21357c5c7b 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -34,35 +34,55 @@ static u32 acpi_suspend_states[] = {
34 34
35static int init_8259A_after_S1; 35static int init_8259A_after_S1;
36 36
37extern int acpi_sleep_prepare(u32 acpi_state);
38extern void acpi_power_off(void);
39
40static u32 acpi_target_sleep_state = ACPI_STATE_S0;
41
42/**
43 * acpi_pm_set_target - Set the target system sleep state to the state
44 * associated with given @pm_state, if supported.
45 */
46
47static int acpi_pm_set_target(suspend_state_t pm_state)
48{
49 u32 acpi_state = acpi_suspend_states[pm_state];
50 int error = 0;
51
52 if (sleep_states[acpi_state]) {
53 acpi_target_sleep_state = acpi_state;
54 } else {
55 printk(KERN_ERR "ACPI does not support this state: %d\n",
56 pm_state);
57 error = -ENOSYS;
58 }
59 return error;
60}
61
37/** 62/**
38 * acpi_pm_prepare - Do preliminary suspend work. 63 * acpi_pm_prepare - Do preliminary suspend work.
39 * @pm_state: suspend state we're entering. 64 * @pm_state: ignored
40 * 65 *
41 * Make sure we support the state. If we do, and we need it, set the 66 * If necessary, set the firmware waking vector and do arch-specific
42 * firmware waking vector and do arch-specific nastiness to get the 67 * nastiness to get the wakeup code to the waking vector.
43 * wakeup code to the waking vector.
44 */ 68 */
45 69
46extern int acpi_sleep_prepare(u32 acpi_state);
47extern void acpi_power_off(void);
48
49static int acpi_pm_prepare(suspend_state_t pm_state) 70static int acpi_pm_prepare(suspend_state_t pm_state)
50{ 71{
51 u32 acpi_state = acpi_suspend_states[pm_state]; 72 int error = acpi_sleep_prepare(acpi_target_sleep_state);
52 73
53 if (!sleep_states[acpi_state]) { 74 if (error)
54 printk("acpi_pm_prepare does not support %d \n", pm_state); 75 acpi_target_sleep_state = ACPI_STATE_S0;
55 return -EPERM; 76
56 } 77 return error;
57 return acpi_sleep_prepare(acpi_state);
58} 78}
59 79
60/** 80/**
61 * acpi_pm_enter - Actually enter a sleep state. 81 * acpi_pm_enter - Actually enter a sleep state.
62 * @pm_state: State we're entering. 82 * @pm_state: ignored
63 * 83 *
64 * Flush caches and go to sleep. For STR or STD, we have to call 84 * Flush caches and go to sleep. For STR we have to call arch-specific
65 * arch-specific assembly, which in turn call acpi_enter_sleep_state(). 85 * assembly, which in turn call acpi_enter_sleep_state().
66 * It's unfortunate, but it works. Please fix if you're feeling frisky. 86 * It's unfortunate, but it works. Please fix if you're feeling frisky.
67 */ 87 */
68 88
@@ -70,31 +90,31 @@ static int acpi_pm_enter(suspend_state_t pm_state)
70{ 90{
71 acpi_status status = AE_OK; 91 acpi_status status = AE_OK;
72 unsigned long flags = 0; 92 unsigned long flags = 0;
73 u32 acpi_state = acpi_suspend_states[pm_state]; 93 u32 acpi_state = acpi_target_sleep_state;
74 94
75 ACPI_FLUSH_CPU_CACHE(); 95 ACPI_FLUSH_CPU_CACHE();
76 96
77 /* Do arch specific saving of state. */ 97 /* Do arch specific saving of state. */
78 if (pm_state > PM_SUSPEND_STANDBY) { 98 if (acpi_state == ACPI_STATE_S3) {
79 int error = acpi_save_state_mem(); 99 int error = acpi_save_state_mem();
80 if (error) 100
101 if (error) {
102 acpi_target_sleep_state = ACPI_STATE_S0;
81 return error; 103 return error;
104 }
82 } 105 }
83 106
84 local_irq_save(flags); 107 local_irq_save(flags);
85 acpi_enable_wakeup_device(acpi_state); 108 acpi_enable_wakeup_device(acpi_state);
86 switch (pm_state) { 109 switch (acpi_state) {
87 case PM_SUSPEND_STANDBY: 110 case ACPI_STATE_S1:
88 barrier(); 111 barrier();
89 status = acpi_enter_sleep_state(acpi_state); 112 status = acpi_enter_sleep_state(acpi_state);
90 break; 113 break;
91 114
92 case PM_SUSPEND_MEM: 115 case ACPI_STATE_S3:
93 do_suspend_lowlevel(); 116 do_suspend_lowlevel();
94 break; 117 break;
95
96 default:
97 return -EINVAL;
98 } 118 }
99 119
100 /* ACPI 3.0 specs (P62) says that it's the responsabilty 120 /* ACPI 3.0 specs (P62) says that it's the responsabilty
@@ -107,12 +127,8 @@ static int acpi_pm_enter(suspend_state_t pm_state)
107 local_irq_restore(flags); 127 local_irq_restore(flags);
108 printk(KERN_DEBUG "Back to C!\n"); 128 printk(KERN_DEBUG "Back to C!\n");
109 129
110 /* restore processor state 130 /* restore processor state */
111 * We should only be here if we're coming back from STR or STD. 131 if (acpi_state == ACPI_STATE_S3)
112 * And, in the case of the latter, the memory image should have already
113 * been loaded from disk.
114 */
115 if (pm_state > PM_SUSPEND_STANDBY)
116 acpi_restore_state_mem(); 132 acpi_restore_state_mem();
117 133
118 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 134 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
@@ -120,7 +136,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
120 136
121/** 137/**
122 * acpi_pm_finish - Finish up suspend sequence. 138 * acpi_pm_finish - Finish up suspend sequence.
123 * @pm_state: State we're coming out of. 139 * @pm_state: ignored
124 * 140 *
125 * This is called after we wake back up (or if entering the sleep state 141 * This is called after we wake back up (or if entering the sleep state
126 * failed). 142 * failed).
@@ -128,7 +144,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
128 144
129static int acpi_pm_finish(suspend_state_t pm_state) 145static int acpi_pm_finish(suspend_state_t pm_state)
130{ 146{
131 u32 acpi_state = acpi_suspend_states[pm_state]; 147 u32 acpi_state = acpi_target_sleep_state;
132 148
133 acpi_leave_sleep_state(acpi_state); 149 acpi_leave_sleep_state(acpi_state);
134 acpi_disable_wakeup_device(acpi_state); 150 acpi_disable_wakeup_device(acpi_state);
@@ -136,6 +152,8 @@ static int acpi_pm_finish(suspend_state_t pm_state)
136 /* reset firmware waking vector */ 152 /* reset firmware waking vector */
137 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 153 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
138 154
155 acpi_target_sleep_state = ACPI_STATE_S0;
156
139#ifdef CONFIG_X86 157#ifdef CONFIG_X86
140 if (init_8259A_after_S1) { 158 if (init_8259A_after_S1) {
141 printk("Broken toshiba laptop -> kicking interrupts\n"); 159 printk("Broken toshiba laptop -> kicking interrupts\n");
@@ -178,6 +196,7 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
178 196
179static struct pm_ops acpi_pm_ops = { 197static struct pm_ops acpi_pm_ops = {
180 .valid = acpi_pm_state_valid, 198 .valid = acpi_pm_state_valid,
199 .set_target = acpi_pm_set_target,
181 .prepare = acpi_pm_prepare, 200 .prepare = acpi_pm_prepare,
182 .enter = acpi_pm_enter, 201 .enter = acpi_pm_enter,
183 .finish = acpi_pm_finish, 202 .finish = acpi_pm_finish,
@@ -237,6 +256,81 @@ static struct hibernation_ops acpi_hibernation_ops = {
237}; 256};
238#endif /* CONFIG_SOFTWARE_SUSPEND */ 257#endif /* CONFIG_SOFTWARE_SUSPEND */
239 258
259/**
260 * acpi_pm_device_sleep_state - return preferred power state of ACPI device
261 * in the system sleep state given by %acpi_target_sleep_state
262 * @dev: device to examine
263 * @wake: if set, the device should be able to wake up the system
264 * @d_min_p: used to store the upper limit of allowed states range
265 * Return value: preferred power state of the device on success, -ENODEV on
266 * failure (ie. if there's no 'struct acpi_device' for @dev)
267 *
268 * Find the lowest power (highest number) ACPI device power state that
269 * device @dev can be in while the system is in the sleep state represented
270 * by %acpi_target_sleep_state. If @wake is nonzero, the device should be
271 * able to wake up the system from this sleep state. If @d_min_p is set,
272 * the highest power (lowest number) device power state of @dev allowed
273 * in this system sleep state is stored at the location pointed to by it.
274 *
275 * The caller must ensure that @dev is valid before using this function.
276 * The caller is also responsible for figuring out if the device is
277 * supposed to be able to wake up the system and passing this information
278 * via @wake.
279 */
280
281int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
282{
283 acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
284 struct acpi_device *adev;
285 char acpi_method[] = "_SxD";
286 unsigned long d_min, d_max;
287
288 if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
289 printk(KERN_ERR "ACPI handle has no context!\n");
290 return -ENODEV;
291 }
292
293 acpi_method[2] = '0' + acpi_target_sleep_state;
294 /*
295 * If the sleep state is S0, we will return D3, but if the device has
296 * _S0W, we will use the value from _S0W
297 */
298 d_min = ACPI_STATE_D0;
299 d_max = ACPI_STATE_D3;
300
301 /*
302 * If present, _SxD methods return the minimum D-state (highest power
303 * state) we can use for the corresponding S-states. Otherwise, the
304 * minimum D-state is D0 (ACPI 3.x).
305 *
306 * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer
307 * provided -- that's our fault recovery, we ignore retval.
308 */
309 if (acpi_target_sleep_state > ACPI_STATE_S0)
310 acpi_evaluate_integer(handle, acpi_method, NULL, &d_min);
311
312 /*
313 * If _PRW says we can wake up the system from the target sleep state,
314 * the D-state returned by _SxD is sufficient for that (we assume a
315 * wakeup-aware driver if wake is set). Still, if _SxW exists
316 * (ACPI 3.x), it should return the maximum (lowest power) D-state that
317 * can wake the system. _S0W may be valid, too.
318 */
319 if (acpi_target_sleep_state == ACPI_STATE_S0 ||
320 (wake && adev->wakeup.state.enabled &&
321 adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
322 acpi_method[3] = 'W';
323 acpi_evaluate_integer(handle, acpi_method, NULL, &d_max);
324 /* Sanity check */
325 if (d_max < d_min)
326 d_min = d_max;
327 }
328
329 if (d_min_p)
330 *d_min_p = d_min;
331 return d_max;
332}
333
240/* 334/*
241 * Toshiba fails to preserve interrupts over S1, reinitialization 335 * Toshiba fails to preserve interrupts over S1, reinitialization
242 * of 8259 is needed after S1 resume. 336 * of 8259 is needed after S1 resume.