aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-12-15 18:51:21 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2010-12-24 09:02:44 -0500
commitb8c76f6aed0ab7df73a6410f3f82de2c831bb144 (patch)
tree1194ded4c23f62ab253a2e0712cfdd436aa2365b
parent5b219a51fdceaf76e0e18da57c7efb9e5586e567 (diff)
PM: Replace the device power.status field with a bit field
The device power.status field is too complicated for its purpose (storing the information about whether or not the device is in the "active" state from the PM core's point of view), so replace it with a bit field and modify all of its users accordingly. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-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;