aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/sleep/main.c160
-rw-r--r--drivers/pci/pci-acpi.c28
-rw-r--r--drivers/pci/pci.c8
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pnp/driver.c5
-rw-r--r--drivers/pnp/pnpacpi/core.c14
-rw-r--r--include/acpi/acpi_bus.h2
-rw-r--r--include/linux/pnp.h4
8 files changed, 181 insertions, 42 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.
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index c8062494009f..67c63d1f1582 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -245,16 +245,33 @@ EXPORT_SYMBOL(pci_osc_control_set);
245 * currently we simply return _SxD, if present. 245 * currently we simply return _SxD, if present.
246 */ 246 */
247 247
248static int acpi_pci_choose_state(struct pci_dev *pdev, pm_message_t state) 248static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev,
249 pm_message_t state)
249{ 250{
250 /* TBD */ 251 int acpi_state;
251 252
252 return -ENODEV; 253 acpi_state = acpi_pm_device_sleep_state(&pdev->dev,
254 device_may_wakeup(&pdev->dev), NULL);
255 if (acpi_state < 0)
256 return PCI_POWER_ERROR;
257
258 switch (acpi_state) {
259 case ACPI_STATE_D0:
260 return PCI_D0;
261 case ACPI_STATE_D1:
262 return PCI_D1;
263 case ACPI_STATE_D2:
264 return PCI_D2;
265 case ACPI_STATE_D3:
266 return PCI_D3hot;
267 }
268 return PCI_POWER_ERROR;
253} 269}
254 270
255static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) 271static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
256{ 272{
257 acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); 273 acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
274 acpi_handle tmp;
258 static int state_conv[] = { 275 static int state_conv[] = {
259 [0] = 0, 276 [0] = 0,
260 [1] = 1, 277 [1] = 1,
@@ -266,6 +283,9 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
266 283
267 if (!handle) 284 if (!handle)
268 return -ENODEV; 285 return -ENODEV;
286 /* If the ACPI device has _EJ0, ignore the device */
287 if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp)))
288 return 0;
269 return acpi_bus_set_power(handle, acpi_state); 289 return acpi_bus_set_power(handle, acpi_state);
270} 290}
271 291
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 03fd59e80fef..1458fd69e670 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -499,7 +499,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
499 return 0; 499 return 0;
500} 500}
501 501
502int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); 502pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
503 503
504/** 504/**
505 * pci_choose_state - Choose the power state of a PCI device 505 * pci_choose_state - Choose the power state of a PCI device
@@ -513,15 +513,15 @@ int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
513 513
514pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) 514pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
515{ 515{
516 int ret; 516 pci_power_t ret;
517 517
518 if (!pci_find_capability(dev, PCI_CAP_ID_PM)) 518 if (!pci_find_capability(dev, PCI_CAP_ID_PM))
519 return PCI_D0; 519 return PCI_D0;
520 520
521 if (platform_pci_choose_state) { 521 if (platform_pci_choose_state) {
522 ret = platform_pci_choose_state(dev, state); 522 ret = platform_pci_choose_state(dev, state);
523 if (ret >= 0) 523 if (ret != PCI_POWER_ERROR)
524 state.event = ret; 524 return ret;
525 } 525 }
526 526
527 switch (state.event) { 527 switch (state.event) {
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3fec13d3add7..c293ba1f274a 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -13,7 +13,7 @@ extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
13 resource_size_t, resource_size_t), 13 resource_size_t, resource_size_t),
14 void *alignf_data); 14 void *alignf_data);
15/* Firmware callbacks */ 15/* Firmware callbacks */
16extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); 16extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
17extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); 17extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
18 18
19extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); 19extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index e161423b4300..1432806451cd 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -167,6 +167,8 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state)
167 return error; 167 return error;
168 } 168 }
169 169
170 if (pnp_dev->protocol && pnp_dev->protocol->suspend)
171 pnp_dev->protocol->suspend(pnp_dev, state);
170 return 0; 172 return 0;
171} 173}
172 174
@@ -179,6 +181,9 @@ static int pnp_bus_resume(struct device *dev)
179 if (!pnp_drv) 181 if (!pnp_drv)
180 return 0; 182 return 0;
181 183
184 if (pnp_dev->protocol && pnp_dev->protocol->resume)
185 pnp_dev->protocol->resume(pnp_dev);
186
182 if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) { 187 if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
183 error = pnp_start_dev(pnp_dev); 188 error = pnp_start_dev(pnp_dev);
184 if (error) 189 if (error)
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index a00548799e98..c37a558ecd96 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -119,11 +119,25 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
119 return ACPI_FAILURE(status) ? -ENODEV : 0; 119 return ACPI_FAILURE(status) ? -ENODEV : 0;
120} 120}
121 121
122static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
123{
124 return acpi_bus_set_power((acpi_handle)dev->data,
125 acpi_pm_device_sleep_state(&dev->dev,
126 device_may_wakeup(&dev->dev), NULL));
127}
128
129static int pnpacpi_resume(struct pnp_dev *dev)
130{
131 return acpi_bus_set_power((acpi_handle)dev->data, ACPI_STATE_D0);
132}
133
122static struct pnp_protocol pnpacpi_protocol = { 134static struct pnp_protocol pnpacpi_protocol = {
123 .name = "Plug and Play ACPI", 135 .name = "Plug and Play ACPI",
124 .get = pnpacpi_get_resources, 136 .get = pnpacpi_get_resources,
125 .set = pnpacpi_set_resources, 137 .set = pnpacpi_set_resources,
126 .disable = pnpacpi_disable_resources, 138 .disable = pnpacpi_disable_resources,
139 .suspend = pnpacpi_suspend,
140 .resume = pnpacpi_resume,
127}; 141};
128 142
129static int __init pnpacpi_add_device(struct acpi_device *device) 143static int __init pnpacpi_add_device(struct acpi_device *device)
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 5e3dcf3299bf..a9f73efa01bc 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -365,6 +365,8 @@ acpi_handle acpi_get_child(acpi_handle, acpi_integer);
365acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); 365acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
366#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) 366#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
367 367
368int acpi_pm_device_sleep_state(struct device *, int, int *);
369
368#endif /* CONFIG_ACPI */ 370#endif /* CONFIG_ACPI */
369 371
370#endif /*__ACPI_BUS_H__*/ 372#endif /*__ACPI_BUS_H__*/
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 2a1897e6f937..66edb2293184 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -335,6 +335,10 @@ struct pnp_protocol {
335 int (*set)(struct pnp_dev *dev, struct pnp_resource_table *res); 335 int (*set)(struct pnp_dev *dev, struct pnp_resource_table *res);
336 int (*disable)(struct pnp_dev *dev); 336 int (*disable)(struct pnp_dev *dev);
337 337
338 /* protocol specific suspend/resume */
339 int (*suspend)(struct pnp_dev *dev, pm_message_t state);
340 int (*resume)(struct pnp_dev *dev);
341
338 /* used by pnp layer only (look but don't touch) */ 342 /* used by pnp layer only (look but don't touch) */
339 unsigned char number; /* protocol number*/ 343 unsigned char number; /* protocol number*/
340 struct device dev; /* link to driver model */ 344 struct device dev; /* link to driver model */