aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/power/main.c17
-rw-r--r--drivers/usb/core/driver.c7
-rw-r--r--include/linux/device.h4
-rw-r--r--include/linux/pm.h43
4 files changed, 12 insertions, 59 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index bb5c8cb64174..a90480baa850 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -63,7 +63,7 @@ static int async_error;
63 */ 63 */
64void device_pm_init(struct device *dev) 64void device_pm_init(struct device *dev)
65{ 65{
66 dev->power.status = DPM_ON; 66 dev->power.in_suspend = false;
67 init_completion(&dev->power.completion); 67 init_completion(&dev->power.completion);
68 complete_all(&dev->power.completion); 68 complete_all(&dev->power.completion);
69 dev->power.wakeup = NULL; 69 dev->power.wakeup = NULL;
@@ -98,7 +98,7 @@ void device_pm_add(struct device *dev)
98 kobject_name(&dev->kobj)); 98 kobject_name(&dev->kobj));
99 mutex_lock(&dpm_list_mtx); 99 mutex_lock(&dpm_list_mtx);
100 if (dev->parent) { 100 if (dev->parent) {
101 if (dev->parent->power.status >= DPM_SUSPENDING) 101 if (dev->parent->power.in_suspend)
102 dev_warn(dev, "parent %s should not be sleeping\n", 102 dev_warn(dev, "parent %s should not be sleeping\n",
103 dev_name(dev->parent)); 103 dev_name(dev->parent));
104 } else if (transition_started) { 104 } else if (transition_started) {
@@ -488,7 +488,6 @@ void dpm_resume_noirq(pm_message_t state)
488 int error; 488 int error;
489 489
490 get_device(dev); 490 get_device(dev);
491 dev->power.status = DPM_OFF;
492 list_move_tail(&dev->power.entry, &dpm_suspended_list); 491 list_move_tail(&dev->power.entry, &dpm_suspended_list);
493 mutex_unlock(&dpm_list_mtx); 492 mutex_unlock(&dpm_list_mtx);
494 493
@@ -541,7 +540,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
541 dpm_wait(dev->parent, async); 540 dpm_wait(dev->parent, async);
542 device_lock(dev); 541 device_lock(dev);
543 542
544 dev->power.status = DPM_RESUMING; 543 dev->power.in_suspend = false;
545 544
546 if (dev->bus) { 545 if (dev->bus) {
547 if (dev->bus->pm) { 546 if (dev->bus->pm) {
@@ -690,7 +689,7 @@ static void dpm_complete(pm_message_t state)
690 struct device *dev = to_device(dpm_prepared_list.prev); 689 struct device *dev = to_device(dpm_prepared_list.prev);
691 690
692 get_device(dev); 691 get_device(dev);
693 dev->power.status = DPM_ON; 692 dev->power.in_suspend = false;
694 list_move(&dev->power.entry, &list); 693 list_move(&dev->power.entry, &list);
695 mutex_unlock(&dpm_list_mtx); 694 mutex_unlock(&dpm_list_mtx);
696 695
@@ -806,7 +805,6 @@ int dpm_suspend_noirq(pm_message_t state)
806 put_device(dev); 805 put_device(dev);
807 break; 806 break;
808 } 807 }
809 dev->power.status = DPM_OFF_IRQ;
810 if (!list_empty(&dev->power.entry)) 808 if (!list_empty(&dev->power.entry))
811 list_move(&dev->power.entry, &dpm_noirq_list); 809 list_move(&dev->power.entry, &dpm_noirq_list);
812 put_device(dev); 810 put_device(dev);
@@ -894,9 +892,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
894 } 892 }
895 } 893 }
896 894
897 if (!error)
898 dev->power.status = DPM_OFF;
899
900 End: 895 End:
901 device_unlock(dev); 896 device_unlock(dev);
902 complete_all(&dev->power.completion); 897 complete_all(&dev->power.completion);
@@ -1030,7 +1025,6 @@ static int dpm_prepare(pm_message_t state)
1030 struct device *dev = to_device(dpm_list.next); 1025 struct device *dev = to_device(dpm_list.next);
1031 1026
1032 get_device(dev); 1027 get_device(dev);
1033 dev->power.status = DPM_PREPARING;
1034 mutex_unlock(&dpm_list_mtx); 1028 mutex_unlock(&dpm_list_mtx);
1035 1029
1036 pm_runtime_get_noresume(dev); 1030 pm_runtime_get_noresume(dev);
@@ -1046,7 +1040,6 @@ static int dpm_prepare(pm_message_t state)
1046 1040
1047 mutex_lock(&dpm_list_mtx); 1041 mutex_lock(&dpm_list_mtx);
1048 if (error) { 1042 if (error) {
1049 dev->power.status = DPM_ON;
1050 if (error == -EAGAIN) { 1043 if (error == -EAGAIN) {
1051 put_device(dev); 1044 put_device(dev);
1052 error = 0; 1045 error = 0;
@@ -1058,7 +1051,7 @@ static int dpm_prepare(pm_message_t state)
1058 put_device(dev); 1051 put_device(dev);
1059 break; 1052 break;
1060 } 1053 }
1061 dev->power.status = DPM_SUSPENDING; 1054 dev->power.in_suspend = true;
1062 if (!list_empty(&dev->power.entry)) 1055 if (!list_empty(&dev->power.entry))
1063 list_move_tail(&dev->power.entry, &dpm_prepared_list); 1056 list_move_tail(&dev->power.entry, &dpm_prepared_list);
1064 put_device(dev); 1057 put_device(dev);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index c0e60fbcb048..4ec50224ee86 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -376,7 +376,7 @@ static int usb_unbind_interface(struct device *dev)
376 * Just re-enable it without affecting the endpoint toggles. 376 * Just re-enable it without affecting the endpoint toggles.
377 */ 377 */
378 usb_enable_interface(udev, intf, false); 378 usb_enable_interface(udev, intf, false);
379 } else if (!error && intf->dev.power.status == DPM_ON) { 379 } else if (!error && !intf->dev.power.in_suspend) {
380 r = usb_set_interface(udev, intf->altsetting[0]. 380 r = usb_set_interface(udev, intf->altsetting[0].
381 desc.bInterfaceNumber, 0); 381 desc.bInterfaceNumber, 0);
382 if (r < 0) 382 if (r < 0)
@@ -961,7 +961,7 @@ void usb_rebind_intf(struct usb_interface *intf)
961 } 961 }
962 962
963 /* Try to rebind the interface */ 963 /* Try to rebind the interface */
964 if (intf->dev.power.status == DPM_ON) { 964 if (!intf->dev.power.in_suspend) {
965 intf->needs_binding = 0; 965 intf->needs_binding = 0;
966 rc = device_attach(&intf->dev); 966 rc = device_attach(&intf->dev);
967 if (rc < 0) 967 if (rc < 0)
@@ -1108,8 +1108,7 @@ static int usb_resume_interface(struct usb_device *udev,
1108 if (intf->condition == USB_INTERFACE_UNBOUND) { 1108 if (intf->condition == USB_INTERFACE_UNBOUND) {
1109 1109
1110 /* Carry out a deferred switch to altsetting 0 */ 1110 /* Carry out a deferred switch to altsetting 0 */
1111 if (intf->needs_altsetting0 && 1111 if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) {
1112 intf->dev.power.status == DPM_ON) {
1113 usb_set_interface(udev, intf->altsetting[0]. 1112 usb_set_interface(udev, intf->altsetting[0].
1114 desc.bInterfaceNumber, 0); 1113 desc.bInterfaceNumber, 0);
1115 intf->needs_altsetting0 = 0; 1114 intf->needs_altsetting0 = 0;
diff --git a/include/linux/device.h b/include/linux/device.h
index dd4895313468..45bc8c1669d2 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -508,13 +508,13 @@ static inline int device_is_registered(struct device *dev)
508 508
509static inline void device_enable_async_suspend(struct device *dev) 509static inline void device_enable_async_suspend(struct device *dev)
510{ 510{
511 if (dev->power.status == DPM_ON) 511 if (!dev->power.in_suspend)
512 dev->power.async_suspend = true; 512 dev->power.async_suspend = true;
513} 513}
514 514
515static inline void device_disable_async_suspend(struct device *dev) 515static inline void device_disable_async_suspend(struct device *dev)
516{ 516{
517 if (dev->power.status == DPM_ON) 517 if (!dev->power.in_suspend)
518 dev->power.async_suspend = false; 518 dev->power.async_suspend = false;
519} 519}
520 520
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 61f2066e6852..c1756dfeb8c5 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -367,45 +367,6 @@ extern struct dev_pm_ops generic_subsys_pm_ops;
367 { .event = PM_EVENT_AUTO_RESUME, }) 367 { .event = PM_EVENT_AUTO_RESUME, })
368 368
369/** 369/**
370 * Device power management states
371 *
372 * These state labels are used internally by the PM core to indicate the current
373 * status of a device with respect to the PM core operations.
374 *
375 * DPM_ON Device is regarded as operational. Set this way
376 * initially and when ->complete() is about to be called.
377 * Also set when ->prepare() fails.
378 *
379 * DPM_PREPARING Device is going to be prepared for a PM transition. Set
380 * when ->prepare() is about to be called.
381 *
382 * DPM_RESUMING Device is going to be resumed. Set when ->resume(),
383 * ->thaw(), or ->restore() is about to be called.
384 *
385 * DPM_SUSPENDING Device has been prepared for a power transition. Set
386 * when ->prepare() has just succeeded.
387 *
388 * DPM_OFF Device is regarded as inactive. Set immediately after
389 * ->suspend(), ->freeze(), or ->poweroff() has succeeded.
390 * Also set when ->resume()_noirq, ->thaw_noirq(), or
391 * ->restore_noirq() is about to be called.
392 *
393 * DPM_OFF_IRQ Device is in a "deep sleep". Set immediately after
394 * ->suspend_noirq(), ->freeze_noirq(), or
395 * ->poweroff_noirq() has just succeeded.
396 */
397
398enum dpm_state {
399 DPM_INVALID,
400 DPM_ON,
401 DPM_PREPARING,
402 DPM_RESUMING,
403 DPM_SUSPENDING,
404 DPM_OFF,
405 DPM_OFF_IRQ,
406};
407
408/**
409 * Device run-time power management status. 370 * Device run-time power management status.
410 * 371 *
411 * These status labels are used internally by the PM core to indicate the 372 * These status labels are used internally by the PM core to indicate the
@@ -463,8 +424,8 @@ struct wakeup_source;
463struct dev_pm_info { 424struct dev_pm_info {
464 pm_message_t power_state; 425 pm_message_t power_state;
465 unsigned int can_wakeup:1; 426 unsigned int can_wakeup:1;
466 unsigned async_suspend:1; 427 unsigned int async_suspend:1;
467 enum dpm_state status; /* Owned by the PM core */ 428 unsigned int in_suspend:1; /* Owned by the PM core */
468 spinlock_t lock; 429 spinlock_t lock;
469#ifdef CONFIG_PM_SLEEP 430#ifdef CONFIG_PM_SLEEP
470 struct list_head entry; 431 struct list_head entry;