diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2010-12-15 18:51:21 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2010-12-24 09:02:44 -0500 |
commit | b8c76f6aed0ab7df73a6410f3f82de2c831bb144 (patch) | |
tree | 1194ded4c23f62ab253a2e0712cfdd436aa2365b | |
parent | 5b219a51fdceaf76e0e18da57c7efb9e5586e567 (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.c | 17 | ||||
-rw-r--r-- | drivers/usb/core/driver.c | 7 | ||||
-rw-r--r-- | include/linux/device.h | 4 | ||||
-rw-r--r-- | include/linux/pm.h | 43 |
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 | */ |
64 | void device_pm_init(struct device *dev) | 64 | void 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 | ||
509 | static inline void device_enable_async_suspend(struct device *dev) | 509 | static 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 | ||
515 | static inline void device_disable_async_suspend(struct device *dev) | 515 | static 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 | |||
398 | enum 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; | |||
463 | struct dev_pm_info { | 424 | struct 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; |