diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2018-01-17 20:55:09 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2018-01-17 20:55:09 -0500 |
commit | 4b67157f04b584379dd0e7426bf3485a85c9bb77 (patch) | |
tree | e2a7a619f2062aa2ae9fd4e69c4125ea470fc18f | |
parent | f9b736f64aae9252a1f71fcf64c7aeee4f5d0e29 (diff) | |
parent | 1131b0a4af911de50b22239cabdf6dcd3f15df15 (diff) |
Merge branch 'pm-core'
* pm-core: (29 commits)
dmaengine: rcar-dmac: Make DMAC reinit during system resume explicit
PM / runtime: Allow no callbacks in pm_runtime_force_suspend|resume()
PM / runtime: Check ignore_children in pm_runtime_need_not_resume()
PM / runtime: Rework pm_runtime_force_suspend/resume()
PM / wakeup: Print warn if device gets enabled as wakeup source during sleep
PM / core: Propagate wakeup_path status flag in __device_suspend_late()
PM / core: Re-structure code for clearing the direct_complete flag
PM: i2c-designware-platdrv: Optimize power management
PM: i2c-designware-platdrv: Use DPM_FLAG_SMART_PREPARE
PM / mfd: intel-lpss: Use DPM_FLAG_SMART_SUSPEND
PCI / PM: Use SMART_SUSPEND and LEAVE_SUSPENDED flags for PCIe ports
PM / wakeup: Add device_set_wakeup_path() helper to control wakeup path
PM / core: Assign the wakeup_path status flag in __device_prepare()
PM / wakeup: Do not fail dev_pm_attach_wake_irq() unnecessarily
PM / core: Direct DPM_FLAG_LEAVE_SUSPENDED handling
PM / core: Direct DPM_FLAG_SMART_SUSPEND optimization
PM / core: Add helpers for subsystem callback selection
PM / wakeup: Drop redundant check from device_init_wakeup()
PM / wakeup: Drop redundant check from device_set_wakeup_enable()
PM / wakeup: only recommend "call"ing device_init_wakeup() once
...
-rw-r--r-- | Documentation/driver-api/pm/devices.rst | 54 | ||||
-rw-r--r-- | Documentation/power/pci.txt | 11 | ||||
-rw-r--r-- | drivers/acpi/device_pm.c | 27 | ||||
-rw-r--r-- | drivers/base/power/main.c | 415 | ||||
-rw-r--r-- | drivers/base/power/power.h | 11 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 84 | ||||
-rw-r--r-- | drivers/base/power/sysfs.c | 182 | ||||
-rw-r--r-- | drivers/base/power/wakeirq.c | 8 | ||||
-rw-r--r-- | drivers/base/power/wakeup.c | 26 | ||||
-rw-r--r-- | drivers/dma/sh/rcar-dmac.c | 24 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.h | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 39 | ||||
-rw-r--r-- | drivers/mfd/intel-lpss.c | 6 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 19 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 3 | ||||
-rw-r--r-- | include/linux/pm.h | 16 | ||||
-rw-r--r-- | include/linux/pm_wakeup.h | 7 |
17 files changed, 614 insertions, 320 deletions
diff --git a/Documentation/driver-api/pm/devices.rst b/Documentation/driver-api/pm/devices.rst index 53c1b0b06da5..1128705a5731 100644 --- a/Documentation/driver-api/pm/devices.rst +++ b/Documentation/driver-api/pm/devices.rst | |||
@@ -777,17 +777,51 @@ The driver can indicate that by setting ``DPM_FLAG_SMART_SUSPEND`` in | |||
777 | runtime suspend at the beginning of the ``suspend_late`` phase of system-wide | 777 | runtime suspend at the beginning of the ``suspend_late`` phase of system-wide |
778 | suspend (or in the ``poweroff_late`` phase of hibernation), when runtime PM | 778 | suspend (or in the ``poweroff_late`` phase of hibernation), when runtime PM |
779 | has been disabled for it, under the assumption that its state should not change | 779 | has been disabled for it, under the assumption that its state should not change |
780 | after that point until the system-wide transition is over. If that happens, the | 780 | after that point until the system-wide transition is over (the PM core itself |
781 | driver's system-wide resume callbacks, if present, may still be invoked during | 781 | does that for devices whose "noirq", "late" and "early" system-wide PM callbacks |
782 | the subsequent system-wide resume transition and the device's runtime power | 782 | are executed directly by it). If that happens, the driver's system-wide resume |
783 | management status may be set to "active" before enabling runtime PM for it, | 783 | callbacks, if present, may still be invoked during the subsequent system-wide |
784 | so the driver must be prepared to cope with the invocation of its system-wide | 784 | resume transition and the device's runtime power management status may be set |
785 | resume callbacks back-to-back with its ``->runtime_suspend`` one (without the | 785 | to "active" before enabling runtime PM for it, so the driver must be prepared to |
786 | intervening ``->runtime_resume`` and so on) and the final state of the device | 786 | cope with the invocation of its system-wide resume callbacks back-to-back with |
787 | must reflect the "active" status for runtime PM in that case. | 787 | its ``->runtime_suspend`` one (without the intervening ``->runtime_resume`` and |
788 | so on) and the final state of the device must reflect the "active" runtime PM | ||
789 | status in that case. | ||
788 | 790 | ||
789 | During system-wide resume from a sleep state it's easiest to put devices into | 791 | During system-wide resume from a sleep state it's easiest to put devices into |
790 | the full-power state, as explained in :file:`Documentation/power/runtime_pm.txt`. | 792 | the full-power state, as explained in :file:`Documentation/power/runtime_pm.txt`. |
791 | Refer to that document for more information regarding this particular issue as | 793 | [Refer to that document for more information regarding this particular issue as |
792 | well as for information on the device runtime power management framework in | 794 | well as for information on the device runtime power management framework in |
793 | general. | 795 | general.] |
796 | |||
797 | However, it often is desirable to leave devices in suspend after system | ||
798 | transitions to the working state, especially if those devices had been in | ||
799 | runtime suspend before the preceding system-wide suspend (or analogous) | ||
800 | transition. Device drivers can use the ``DPM_FLAG_LEAVE_SUSPENDED`` flag to | ||
801 | indicate to the PM core (and middle-layer code) that they prefer the specific | ||
802 | devices handled by them to be left suspended and they have no problems with | ||
803 | skipping their system-wide resume callbacks for this reason. Whether or not the | ||
804 | devices will actually be left in suspend may depend on their state before the | ||
805 | given system suspend-resume cycle and on the type of the system transition under | ||
806 | way. In particular, devices are not left suspended if that transition is a | ||
807 | restore from hibernation, as device states are not guaranteed to be reflected | ||
808 | by the information stored in the hibernation image in that case. | ||
809 | |||
810 | The middle-layer code involved in the handling of the device is expected to | ||
811 | indicate to the PM core if the device may be left in suspend by setting its | ||
812 | :c:member:`power.may_skip_resume` status bit which is checked by the PM core | ||
813 | during the "noirq" phase of the preceding system-wide suspend (or analogous) | ||
814 | transition. The middle layer is then responsible for handling the device as | ||
815 | appropriate in its "noirq" resume callback, which is executed regardless of | ||
816 | whether or not the device is left suspended, but the other resume callbacks | ||
817 | (except for ``->complete``) will be skipped automatically by the PM core if the | ||
818 | device really can be left in suspend. | ||
819 | |||
820 | For devices whose "noirq", "late" and "early" driver callbacks are invoked | ||
821 | directly by the PM core, all of the system-wide resume callbacks are skipped if | ||
822 | ``DPM_FLAG_LEAVE_SUSPENDED`` is set and the device is in runtime suspend during | ||
823 | the ``suspend_noirq`` (or analogous) phase or the transition under way is a | ||
824 | proper system suspend (rather than anything related to hibernation) and the | ||
825 | device's wakeup settings are suitable for runtime PM (that is, it cannot | ||
826 | generate wakeup signals at all or it is allowed to wake up the system from | ||
827 | sleep). | ||
diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt index 704cd36079b8..8eaf9ee24d43 100644 --- a/Documentation/power/pci.txt +++ b/Documentation/power/pci.txt | |||
@@ -994,6 +994,17 @@ into D0 going forward), but if it is in runtime suspend in pci_pm_thaw_noirq(), | |||
994 | the function will set the power.direct_complete flag for it (to make the PM core | 994 | the function will set the power.direct_complete flag for it (to make the PM core |
995 | skip the subsequent "thaw" callbacks for it) and return. | 995 | skip the subsequent "thaw" callbacks for it) and return. |
996 | 996 | ||
997 | Setting the DPM_FLAG_LEAVE_SUSPENDED flag means that the driver prefers the | ||
998 | device to be left in suspend after system-wide transitions to the working state. | ||
999 | This flag is checked by the PM core, but the PCI bus type informs the PM core | ||
1000 | which devices may be left in suspend from its perspective (that happens during | ||
1001 | the "noirq" phase of system-wide suspend and analogous transitions) and next it | ||
1002 | uses the dev_pm_may_skip_resume() helper to decide whether or not to return from | ||
1003 | pci_pm_resume_noirq() early, as the PM core will skip the remaining resume | ||
1004 | callbacks for the device during the transition under way and will set its | ||
1005 | runtime PM status to "suspended" if dev_pm_may_skip_resume() returns "true" for | ||
1006 | it. | ||
1007 | |||
997 | 3.2. Device Runtime Power Management | 1008 | 3.2. Device Runtime Power Management |
998 | ------------------------------------ | 1009 | ------------------------------------ |
999 | In addition to providing device power management callbacks PCI device drivers | 1010 | In addition to providing device power management callbacks PCI device drivers |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index a4c8ad98560d..c4d0a1c912f0 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -990,7 +990,7 @@ void acpi_subsys_complete(struct device *dev) | |||
990 | * the sleep state it is going out of and it has never been resumed till | 990 | * the sleep state it is going out of and it has never been resumed till |
991 | * now, resume it in case the firmware powered it up. | 991 | * now, resume it in case the firmware powered it up. |
992 | */ | 992 | */ |
993 | if (dev->power.direct_complete && pm_resume_via_firmware()) | 993 | if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) |
994 | pm_request_resume(dev); | 994 | pm_request_resume(dev); |
995 | } | 995 | } |
996 | EXPORT_SYMBOL_GPL(acpi_subsys_complete); | 996 | EXPORT_SYMBOL_GPL(acpi_subsys_complete); |
@@ -1039,10 +1039,28 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late); | |||
1039 | */ | 1039 | */ |
1040 | int acpi_subsys_suspend_noirq(struct device *dev) | 1040 | int acpi_subsys_suspend_noirq(struct device *dev) |
1041 | { | 1041 | { |
1042 | if (dev_pm_smart_suspend_and_suspended(dev)) | 1042 | int ret; |
1043 | |||
1044 | if (dev_pm_smart_suspend_and_suspended(dev)) { | ||
1045 | dev->power.may_skip_resume = true; | ||
1043 | return 0; | 1046 | return 0; |
1047 | } | ||
1048 | |||
1049 | ret = pm_generic_suspend_noirq(dev); | ||
1050 | if (ret) | ||
1051 | return ret; | ||
1052 | |||
1053 | /* | ||
1054 | * If the target system sleep state is suspend-to-idle, it is sufficient | ||
1055 | * to check whether or not the device's wakeup settings are good for | ||
1056 | * runtime PM. Otherwise, the pm_resume_via_firmware() check will cause | ||
1057 | * acpi_subsys_complete() to take care of fixing up the device's state | ||
1058 | * anyway, if need be. | ||
1059 | */ | ||
1060 | dev->power.may_skip_resume = device_may_wakeup(dev) || | ||
1061 | !device_can_wakeup(dev); | ||
1044 | 1062 | ||
1045 | return pm_generic_suspend_noirq(dev); | 1063 | return 0; |
1046 | } | 1064 | } |
1047 | EXPORT_SYMBOL_GPL(acpi_subsys_suspend_noirq); | 1065 | EXPORT_SYMBOL_GPL(acpi_subsys_suspend_noirq); |
1048 | 1066 | ||
@@ -1052,6 +1070,9 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_noirq); | |||
1052 | */ | 1070 | */ |
1053 | int acpi_subsys_resume_noirq(struct device *dev) | 1071 | int acpi_subsys_resume_noirq(struct device *dev) |
1054 | { | 1072 | { |
1073 | if (dev_pm_may_skip_resume(dev)) | ||
1074 | return 0; | ||
1075 | |||
1055 | /* | 1076 | /* |
1056 | * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend | 1077 | * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend |
1057 | * during system suspend, so update their runtime PM status to "active" | 1078 | * during system suspend, so update their runtime PM status to "active" |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 08744b572af6..02a497e7c785 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -18,7 +18,6 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/kallsyms.h> | ||
22 | #include <linux/export.h> | 21 | #include <linux/export.h> |
23 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
24 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
@@ -541,6 +540,73 @@ void dev_pm_skip_next_resume_phases(struct device *dev) | |||
541 | } | 540 | } |
542 | 541 | ||
543 | /** | 542 | /** |
543 | * suspend_event - Return a "suspend" message for given "resume" one. | ||
544 | * @resume_msg: PM message representing a system-wide resume transition. | ||
545 | */ | ||
546 | static pm_message_t suspend_event(pm_message_t resume_msg) | ||
547 | { | ||
548 | switch (resume_msg.event) { | ||
549 | case PM_EVENT_RESUME: | ||
550 | return PMSG_SUSPEND; | ||
551 | case PM_EVENT_THAW: | ||
552 | case PM_EVENT_RESTORE: | ||
553 | return PMSG_FREEZE; | ||
554 | case PM_EVENT_RECOVER: | ||
555 | return PMSG_HIBERNATE; | ||
556 | } | ||
557 | return PMSG_ON; | ||
558 | } | ||
559 | |||
560 | /** | ||
561 | * dev_pm_may_skip_resume - System-wide device resume optimization check. | ||
562 | * @dev: Target device. | ||
563 | * | ||
564 | * Checks whether or not the device may be left in suspend after a system-wide | ||
565 | * transition to the working state. | ||
566 | */ | ||
567 | bool dev_pm_may_skip_resume(struct device *dev) | ||
568 | { | ||
569 | return !dev->power.must_resume && pm_transition.event != PM_EVENT_RESTORE; | ||
570 | } | ||
571 | |||
572 | static pm_callback_t dpm_subsys_resume_noirq_cb(struct device *dev, | ||
573 | pm_message_t state, | ||
574 | const char **info_p) | ||
575 | { | ||
576 | pm_callback_t callback; | ||
577 | const char *info; | ||
578 | |||
579 | if (dev->pm_domain) { | ||
580 | info = "noirq power domain "; | ||
581 | callback = pm_noirq_op(&dev->pm_domain->ops, state); | ||
582 | } else if (dev->type && dev->type->pm) { | ||
583 | info = "noirq type "; | ||
584 | callback = pm_noirq_op(dev->type->pm, state); | ||
585 | } else if (dev->class && dev->class->pm) { | ||
586 | info = "noirq class "; | ||
587 | callback = pm_noirq_op(dev->class->pm, state); | ||
588 | } else if (dev->bus && dev->bus->pm) { | ||
589 | info = "noirq bus "; | ||
590 | callback = pm_noirq_op(dev->bus->pm, state); | ||
591 | } else { | ||
592 | return NULL; | ||
593 | } | ||
594 | |||
595 | if (info_p) | ||
596 | *info_p = info; | ||
597 | |||
598 | return callback; | ||
599 | } | ||
600 | |||
601 | static pm_callback_t dpm_subsys_suspend_noirq_cb(struct device *dev, | ||
602 | pm_message_t state, | ||
603 | const char **info_p); | ||
604 | |||
605 | static pm_callback_t dpm_subsys_suspend_late_cb(struct device *dev, | ||
606 | pm_message_t state, | ||
607 | const char **info_p); | ||
608 | |||
609 | /** | ||
544 | * device_resume_noirq - Execute a "noirq resume" callback for given device. | 610 | * device_resume_noirq - Execute a "noirq resume" callback for given device. |
545 | * @dev: Device to handle. | 611 | * @dev: Device to handle. |
546 | * @state: PM transition of the system being carried out. | 612 | * @state: PM transition of the system being carried out. |
@@ -551,8 +617,9 @@ void dev_pm_skip_next_resume_phases(struct device *dev) | |||
551 | */ | 617 | */ |
552 | static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) | 618 | static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) |
553 | { | 619 | { |
554 | pm_callback_t callback = NULL; | 620 | pm_callback_t callback; |
555 | const char *info = NULL; | 621 | const char *info; |
622 | bool skip_resume; | ||
556 | int error = 0; | 623 | int error = 0; |
557 | 624 | ||
558 | TRACE_DEVICE(dev); | 625 | TRACE_DEVICE(dev); |
@@ -566,29 +633,61 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn | |||
566 | 633 | ||
567 | dpm_wait_for_superior(dev, async); | 634 | dpm_wait_for_superior(dev, async); |
568 | 635 | ||
569 | if (dev->pm_domain) { | 636 | skip_resume = dev_pm_may_skip_resume(dev); |
570 | info = "noirq power domain "; | 637 | |
571 | callback = pm_noirq_op(&dev->pm_domain->ops, state); | 638 | callback = dpm_subsys_resume_noirq_cb(dev, state, &info); |
572 | } else if (dev->type && dev->type->pm) { | 639 | if (callback) |
573 | info = "noirq type "; | 640 | goto Run; |
574 | callback = pm_noirq_op(dev->type->pm, state); | 641 | |
575 | } else if (dev->class && dev->class->pm) { | 642 | if (skip_resume) |
576 | info = "noirq class "; | 643 | goto Skip; |
577 | callback = pm_noirq_op(dev->class->pm, state); | 644 | |
578 | } else if (dev->bus && dev->bus->pm) { | 645 | if (dev_pm_smart_suspend_and_suspended(dev)) { |
579 | info = "noirq bus "; | 646 | pm_message_t suspend_msg = suspend_event(state); |
580 | callback = pm_noirq_op(dev->bus->pm, state); | 647 | |
648 | /* | ||
649 | * If "freeze" callbacks have been skipped during a transition | ||
650 | * related to hibernation, the subsequent "thaw" callbacks must | ||
651 | * be skipped too or bad things may happen. Otherwise, resume | ||
652 | * callbacks are going to be run for the device, so its runtime | ||
653 | * PM status must be changed to reflect the new state after the | ||
654 | * transition under way. | ||
655 | */ | ||
656 | if (!dpm_subsys_suspend_late_cb(dev, suspend_msg, NULL) && | ||
657 | !dpm_subsys_suspend_noirq_cb(dev, suspend_msg, NULL)) { | ||
658 | if (state.event == PM_EVENT_THAW) { | ||
659 | skip_resume = true; | ||
660 | goto Skip; | ||
661 | } else { | ||
662 | pm_runtime_set_active(dev); | ||
663 | } | ||
664 | } | ||
581 | } | 665 | } |
582 | 666 | ||
583 | if (!callback && dev->driver && dev->driver->pm) { | 667 | if (dev->driver && dev->driver->pm) { |
584 | info = "noirq driver "; | 668 | info = "noirq driver "; |
585 | callback = pm_noirq_op(dev->driver->pm, state); | 669 | callback = pm_noirq_op(dev->driver->pm, state); |
586 | } | 670 | } |
587 | 671 | ||
672 | Run: | ||
588 | error = dpm_run_callback(callback, dev, state, info); | 673 | error = dpm_run_callback(callback, dev, state, info); |
674 | |||
675 | Skip: | ||
589 | dev->power.is_noirq_suspended = false; | 676 | dev->power.is_noirq_suspended = false; |
590 | 677 | ||
591 | Out: | 678 | if (skip_resume) { |
679 | /* | ||
680 | * The device is going to be left in suspend, but it might not | ||
681 | * have been in runtime suspend before the system suspended, so | ||
682 | * its runtime PM status needs to be updated to avoid confusing | ||
683 | * the runtime PM framework when runtime PM is enabled for the | ||
684 | * device again. | ||
685 | */ | ||
686 | pm_runtime_set_suspended(dev); | ||
687 | dev_pm_skip_next_resume_phases(dev); | ||
688 | } | ||
689 | |||
690 | Out: | ||
592 | complete_all(&dev->power.completion); | 691 | complete_all(&dev->power.completion); |
593 | TRACE_RESUME(error); | 692 | TRACE_RESUME(error); |
594 | return error; | 693 | return error; |
@@ -681,6 +780,35 @@ void dpm_resume_noirq(pm_message_t state) | |||
681 | dpm_noirq_end(); | 780 | dpm_noirq_end(); |
682 | } | 781 | } |
683 | 782 | ||
783 | static pm_callback_t dpm_subsys_resume_early_cb(struct device *dev, | ||
784 | pm_message_t state, | ||
785 | const char **info_p) | ||
786 | { | ||
787 | pm_callback_t callback; | ||
788 | const char *info; | ||
789 | |||
790 | if (dev->pm_domain) { | ||
791 | info = "early power domain "; | ||
792 | callback = pm_late_early_op(&dev->pm_domain->ops, state); | ||
793 | } else if (dev->type && dev->type->pm) { | ||
794 | info = "early type "; | ||
795 | callback = pm_late_early_op(dev->type->pm, state); | ||
796 | } else if (dev->class && dev->class->pm) { | ||
797 | info = "early class "; | ||
798 | callback = pm_late_early_op(dev->class->pm, state); | ||
799 | } else if (dev->bus && dev->bus->pm) { | ||
800 | info = "early bus "; | ||
801 | callback = pm_late_early_op(dev->bus->pm, state); | ||
802 | } else { | ||
803 | return NULL; | ||
804 | } | ||
805 | |||
806 | if (info_p) | ||
807 | *info_p = info; | ||
808 | |||
809 | return callback; | ||
810 | } | ||
811 | |||
684 | /** | 812 | /** |
685 | * device_resume_early - Execute an "early resume" callback for given device. | 813 | * device_resume_early - Execute an "early resume" callback for given device. |
686 | * @dev: Device to handle. | 814 | * @dev: Device to handle. |
@@ -691,8 +819,8 @@ void dpm_resume_noirq(pm_message_t state) | |||
691 | */ | 819 | */ |
692 | static int device_resume_early(struct device *dev, pm_message_t state, bool async) | 820 | static int device_resume_early(struct device *dev, pm_message_t state, bool async) |
693 | { | 821 | { |
694 | pm_callback_t callback = NULL; | 822 | pm_callback_t callback; |
695 | const char *info = NULL; | 823 | const char *info; |
696 | int error = 0; | 824 | int error = 0; |
697 | 825 | ||
698 | TRACE_DEVICE(dev); | 826 | TRACE_DEVICE(dev); |
@@ -706,19 +834,7 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn | |||
706 | 834 | ||
707 | dpm_wait_for_superior(dev, async); | 835 | dpm_wait_for_superior(dev, async); |
708 | 836 | ||
709 | if (dev->pm_domain) { | 837 | callback = dpm_subsys_resume_early_cb(dev, state, &info); |
710 | info = "early power domain "; | ||
711 | callback = pm_late_early_op(&dev->pm_domain->ops, state); | ||
712 | } else if (dev->type && dev->type->pm) { | ||
713 | info = "early type "; | ||
714 | callback = pm_late_early_op(dev->type->pm, state); | ||
715 | } else if (dev->class && dev->class->pm) { | ||
716 | info = "early class "; | ||
717 | callback = pm_late_early_op(dev->class->pm, state); | ||
718 | } else if (dev->bus && dev->bus->pm) { | ||
719 | info = "early bus "; | ||
720 | callback = pm_late_early_op(dev->bus->pm, state); | ||
721 | } | ||
722 | 838 | ||
723 | if (!callback && dev->driver && dev->driver->pm) { | 839 | if (!callback && dev->driver && dev->driver->pm) { |
724 | info = "early driver "; | 840 | info = "early driver "; |
@@ -1089,6 +1205,77 @@ static pm_message_t resume_event(pm_message_t sleep_state) | |||
1089 | return PMSG_ON; | 1205 | return PMSG_ON; |
1090 | } | 1206 | } |
1091 | 1207 | ||
1208 | static void dpm_superior_set_must_resume(struct device *dev) | ||
1209 | { | ||
1210 | struct device_link *link; | ||
1211 | int idx; | ||
1212 | |||
1213 | if (dev->parent) | ||
1214 | dev->parent->power.must_resume = true; | ||
1215 | |||
1216 | idx = device_links_read_lock(); | ||
1217 | |||
1218 | list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) | ||
1219 | link->supplier->power.must_resume = true; | ||
1220 | |||
1221 | device_links_read_unlock(idx); | ||
1222 | } | ||
1223 | |||
1224 | static pm_callback_t dpm_subsys_suspend_noirq_cb(struct device *dev, | ||
1225 | pm_message_t state, | ||
1226 | const char **info_p) | ||
1227 | { | ||
1228 | pm_callback_t callback; | ||
1229 | const char *info; | ||
1230 | |||
1231 | if (dev->pm_domain) { | ||
1232 | info = "noirq power domain "; | ||
1233 | callback = pm_noirq_op(&dev->pm_domain->ops, state); | ||
1234 | } else if (dev->type && dev->type->pm) { | ||
1235 | info = "noirq type "; | ||
1236 | callback = pm_noirq_op(dev->type->pm, state); | ||
1237 | } else if (dev->class && dev->class->pm) { | ||
1238 | info = "noirq class "; | ||
1239 | callback = pm_noirq_op(dev->class->pm, state); | ||
1240 | } else if (dev->bus && dev->bus->pm) { | ||
1241 | info = "noirq bus "; | ||
1242 | callback = pm_noirq_op(dev->bus->pm, state); | ||
1243 | } else { | ||
1244 | return NULL; | ||
1245 | } | ||
1246 | |||
1247 | if (info_p) | ||
1248 | *info_p = info; | ||
1249 | |||
1250 | return callback; | ||
1251 | } | ||
1252 | |||
1253 | static bool device_must_resume(struct device *dev, pm_message_t state, | ||
1254 | bool no_subsys_suspend_noirq) | ||
1255 | { | ||
1256 | pm_message_t resume_msg = resume_event(state); | ||
1257 | |||
1258 | /* | ||
1259 | * If all of the device driver's "noirq", "late" and "early" callbacks | ||
1260 | * are invoked directly by the core, the decision to allow the device to | ||
1261 | * stay in suspend can be based on its current runtime PM status and its | ||
1262 | * wakeup settings. | ||
1263 | */ | ||
1264 | if (no_subsys_suspend_noirq && | ||
1265 | !dpm_subsys_suspend_late_cb(dev, state, NULL) && | ||
1266 | !dpm_subsys_resume_early_cb(dev, resume_msg, NULL) && | ||
1267 | !dpm_subsys_resume_noirq_cb(dev, resume_msg, NULL)) | ||
1268 | return !pm_runtime_status_suspended(dev) && | ||
1269 | (resume_msg.event != PM_EVENT_RESUME || | ||
1270 | (device_can_wakeup(dev) && !device_may_wakeup(dev))); | ||
1271 | |||
1272 | /* | ||
1273 | * The only safe strategy here is to require that if the device may not | ||
1274 | * be left in suspend, resume callbacks must be invoked for it. | ||
1275 | */ | ||
1276 | return !dev->power.may_skip_resume; | ||
1277 | } | ||
1278 | |||
1092 | /** | 1279 | /** |
1093 | * __device_suspend_noirq - Execute a "noirq suspend" callback for given device. | 1280 | * __device_suspend_noirq - Execute a "noirq suspend" callback for given device. |
1094 | * @dev: Device to handle. | 1281 | * @dev: Device to handle. |
@@ -1100,8 +1287,9 @@ static pm_message_t resume_event(pm_message_t sleep_state) | |||
1100 | */ | 1287 | */ |
1101 | static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async) | 1288 | static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async) |
1102 | { | 1289 | { |
1103 | pm_callback_t callback = NULL; | 1290 | pm_callback_t callback; |
1104 | const char *info = NULL; | 1291 | const char *info; |
1292 | bool no_subsys_cb = false; | ||
1105 | int error = 0; | 1293 | int error = 0; |
1106 | 1294 | ||
1107 | TRACE_DEVICE(dev); | 1295 | TRACE_DEVICE(dev); |
@@ -1120,30 +1308,40 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a | |||
1120 | if (dev->power.syscore || dev->power.direct_complete) | 1308 | if (dev->power.syscore || dev->power.direct_complete) |
1121 | goto Complete; | 1309 | goto Complete; |
1122 | 1310 | ||
1123 | if (dev->pm_domain) { | 1311 | callback = dpm_subsys_suspend_noirq_cb(dev, state, &info); |
1124 | info = "noirq power domain "; | 1312 | if (callback) |
1125 | callback = pm_noirq_op(&dev->pm_domain->ops, state); | 1313 | goto Run; |
1126 | } else if (dev->type && dev->type->pm) { | ||
1127 | info = "noirq type "; | ||
1128 | callback = pm_noirq_op(dev->type->pm, state); | ||
1129 | } else if (dev->class && dev->class->pm) { | ||
1130 | info = "noirq class "; | ||
1131 | callback = pm_noirq_op(dev->class->pm, state); | ||
1132 | } else if (dev->bus && dev->bus->pm) { | ||
1133 | info = "noirq bus "; | ||
1134 | callback = pm_noirq_op(dev->bus->pm, state); | ||
1135 | } | ||
1136 | 1314 | ||
1137 | if (!callback && dev->driver && dev->driver->pm) { | 1315 | no_subsys_cb = !dpm_subsys_suspend_late_cb(dev, state, NULL); |
1316 | |||
1317 | if (dev_pm_smart_suspend_and_suspended(dev) && no_subsys_cb) | ||
1318 | goto Skip; | ||
1319 | |||
1320 | if (dev->driver && dev->driver->pm) { | ||
1138 | info = "noirq driver "; | 1321 | info = "noirq driver "; |
1139 | callback = pm_noirq_op(dev->driver->pm, state); | 1322 | callback = pm_noirq_op(dev->driver->pm, state); |
1140 | } | 1323 | } |
1141 | 1324 | ||
1325 | Run: | ||
1142 | error = dpm_run_callback(callback, dev, state, info); | 1326 | error = dpm_run_callback(callback, dev, state, info); |
1143 | if (!error) | 1327 | if (error) { |
1144 | dev->power.is_noirq_suspended = true; | ||
1145 | else | ||
1146 | async_error = error; | 1328 | async_error = error; |
1329 | goto Complete; | ||
1330 | } | ||
1331 | |||
1332 | Skip: | ||
1333 | dev->power.is_noirq_suspended = true; | ||
1334 | |||
1335 | if (dev_pm_test_driver_flags(dev, DPM_FLAG_LEAVE_SUSPENDED)) { | ||
1336 | dev->power.must_resume = dev->power.must_resume || | ||
1337 | atomic_read(&dev->power.usage_count) > 1 || | ||
1338 | device_must_resume(dev, state, no_subsys_cb); | ||
1339 | } else { | ||
1340 | dev->power.must_resume = true; | ||
1341 | } | ||
1342 | |||
1343 | if (dev->power.must_resume) | ||
1344 | dpm_superior_set_must_resume(dev); | ||
1147 | 1345 | ||
1148 | Complete: | 1346 | Complete: |
1149 | complete_all(&dev->power.completion); | 1347 | complete_all(&dev->power.completion); |
@@ -1249,6 +1447,50 @@ int dpm_suspend_noirq(pm_message_t state) | |||
1249 | return ret; | 1447 | return ret; |
1250 | } | 1448 | } |
1251 | 1449 | ||
1450 | static void dpm_propagate_wakeup_to_parent(struct device *dev) | ||
1451 | { | ||
1452 | struct device *parent = dev->parent; | ||
1453 | |||
1454 | if (!parent) | ||
1455 | return; | ||
1456 | |||
1457 | spin_lock_irq(&parent->power.lock); | ||
1458 | |||
1459 | if (dev->power.wakeup_path && !parent->power.ignore_children) | ||
1460 | parent->power.wakeup_path = true; | ||
1461 | |||
1462 | spin_unlock_irq(&parent->power.lock); | ||
1463 | } | ||
1464 | |||
1465 | static pm_callback_t dpm_subsys_suspend_late_cb(struct device *dev, | ||
1466 | pm_message_t state, | ||
1467 | const char **info_p) | ||
1468 | { | ||
1469 | pm_callback_t callback; | ||
1470 | const char *info; | ||
1471 | |||
1472 | if (dev->pm_domain) { | ||
1473 | info = "late power domain "; | ||
1474 | callback = pm_late_early_op(&dev->pm_domain->ops, state); | ||
1475 | } else if (dev->type && dev->type->pm) { | ||
1476 | info = "late type "; | ||
1477 | callback = pm_late_early_op(dev->type->pm, state); | ||
1478 | } else if (dev->class && dev->class->pm) { | ||
1479 | info = "late class "; | ||
1480 | callback = pm_late_early_op(dev->class->pm, state); | ||
1481 | } else if (dev->bus && dev->bus->pm) { | ||
1482 | info = "late bus "; | ||
1483 | callback = pm_late_early_op(dev->bus->pm, state); | ||
1484 | } else { | ||
1485 | return NULL; | ||
1486 | } | ||
1487 | |||
1488 | if (info_p) | ||
1489 | *info_p = info; | ||
1490 | |||
1491 | return callback; | ||
1492 | } | ||
1493 | |||
1252 | /** | 1494 | /** |
1253 | * __device_suspend_late - Execute a "late suspend" callback for given device. | 1495 | * __device_suspend_late - Execute a "late suspend" callback for given device. |
1254 | * @dev: Device to handle. | 1496 | * @dev: Device to handle. |
@@ -1259,8 +1501,8 @@ int dpm_suspend_noirq(pm_message_t state) | |||
1259 | */ | 1501 | */ |
1260 | static int __device_suspend_late(struct device *dev, pm_message_t state, bool async) | 1502 | static int __device_suspend_late(struct device *dev, pm_message_t state, bool async) |
1261 | { | 1503 | { |
1262 | pm_callback_t callback = NULL; | 1504 | pm_callback_t callback; |
1263 | const char *info = NULL; | 1505 | const char *info; |
1264 | int error = 0; | 1506 | int error = 0; |
1265 | 1507 | ||
1266 | TRACE_DEVICE(dev); | 1508 | TRACE_DEVICE(dev); |
@@ -1281,30 +1523,29 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as | |||
1281 | if (dev->power.syscore || dev->power.direct_complete) | 1523 | if (dev->power.syscore || dev->power.direct_complete) |
1282 | goto Complete; | 1524 | goto Complete; |
1283 | 1525 | ||
1284 | if (dev->pm_domain) { | 1526 | callback = dpm_subsys_suspend_late_cb(dev, state, &info); |
1285 | info = "late power domain "; | 1527 | if (callback) |
1286 | callback = pm_late_early_op(&dev->pm_domain->ops, state); | 1528 | goto Run; |
1287 | } else if (dev->type && dev->type->pm) { | ||
1288 | info = "late type "; | ||
1289 | callback = pm_late_early_op(dev->type->pm, state); | ||
1290 | } else if (dev->class && dev->class->pm) { | ||
1291 | info = "late class "; | ||
1292 | callback = pm_late_early_op(dev->class->pm, state); | ||
1293 | } else if (dev->bus && dev->bus->pm) { | ||
1294 | info = "late bus "; | ||
1295 | callback = pm_late_early_op(dev->bus->pm, state); | ||
1296 | } | ||
1297 | 1529 | ||
1298 | if (!callback && dev->driver && dev->driver->pm) { | 1530 | if (dev_pm_smart_suspend_and_suspended(dev) && |
1531 | !dpm_subsys_suspend_noirq_cb(dev, state, NULL)) | ||
1532 | goto Skip; | ||
1533 | |||
1534 | if (dev->driver && dev->driver->pm) { | ||
1299 | info = "late driver "; | 1535 | info = "late driver "; |
1300 | callback = pm_late_early_op(dev->driver->pm, state); | 1536 | callback = pm_late_early_op(dev->driver->pm, state); |
1301 | } | 1537 | } |
1302 | 1538 | ||
1539 | Run: | ||
1303 | error = dpm_run_callback(callback, dev, state, info); | 1540 | error = dpm_run_callback(callback, dev, state, info); |
1304 | if (!error) | 1541 | if (error) { |
1305 | dev->power.is_late_suspended = true; | ||
1306 | else | ||
1307 | async_error = error; | 1542 | async_error = error; |
1543 | goto Complete; | ||
1544 | } | ||
1545 | dpm_propagate_wakeup_to_parent(dev); | ||
1546 | |||
1547 | Skip: | ||
1548 | dev->power.is_late_suspended = true; | ||
1308 | 1549 | ||
1309 | Complete: | 1550 | Complete: |
1310 | TRACE_SUSPEND(error); | 1551 | TRACE_SUSPEND(error); |
@@ -1435,11 +1676,17 @@ static int legacy_suspend(struct device *dev, pm_message_t state, | |||
1435 | return error; | 1676 | return error; |
1436 | } | 1677 | } |
1437 | 1678 | ||
1438 | static void dpm_clear_suppliers_direct_complete(struct device *dev) | 1679 | static void dpm_clear_superiors_direct_complete(struct device *dev) |
1439 | { | 1680 | { |
1440 | struct device_link *link; | 1681 | struct device_link *link; |
1441 | int idx; | 1682 | int idx; |
1442 | 1683 | ||
1684 | if (dev->parent) { | ||
1685 | spin_lock_irq(&dev->parent->power.lock); | ||
1686 | dev->parent->power.direct_complete = false; | ||
1687 | spin_unlock_irq(&dev->parent->power.lock); | ||
1688 | } | ||
1689 | |||
1443 | idx = device_links_read_lock(); | 1690 | idx = device_links_read_lock(); |
1444 | 1691 | ||
1445 | list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) { | 1692 | list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) { |
@@ -1500,6 +1747,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
1500 | dev->power.direct_complete = false; | 1747 | dev->power.direct_complete = false; |
1501 | } | 1748 | } |
1502 | 1749 | ||
1750 | dev->power.may_skip_resume = false; | ||
1751 | dev->power.must_resume = false; | ||
1752 | |||
1503 | dpm_watchdog_set(&wd, dev); | 1753 | dpm_watchdog_set(&wd, dev); |
1504 | device_lock(dev); | 1754 | device_lock(dev); |
1505 | 1755 | ||
@@ -1543,20 +1793,12 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
1543 | 1793 | ||
1544 | End: | 1794 | End: |
1545 | if (!error) { | 1795 | if (!error) { |
1546 | struct device *parent = dev->parent; | ||
1547 | |||
1548 | dev->power.is_suspended = true; | 1796 | dev->power.is_suspended = true; |
1549 | if (parent) { | 1797 | if (device_may_wakeup(dev)) |
1550 | spin_lock_irq(&parent->power.lock); | 1798 | dev->power.wakeup_path = true; |
1551 | |||
1552 | dev->parent->power.direct_complete = false; | ||
1553 | if (dev->power.wakeup_path | ||
1554 | && !dev->parent->power.ignore_children) | ||
1555 | dev->parent->power.wakeup_path = true; | ||
1556 | 1799 | ||
1557 | spin_unlock_irq(&parent->power.lock); | 1800 | dpm_propagate_wakeup_to_parent(dev); |
1558 | } | 1801 | dpm_clear_superiors_direct_complete(dev); |
1559 | dpm_clear_suppliers_direct_complete(dev); | ||
1560 | } | 1802 | } |
1561 | 1803 | ||
1562 | device_unlock(dev); | 1804 | device_unlock(dev); |
@@ -1665,8 +1907,9 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
1665 | if (dev->power.syscore) | 1907 | if (dev->power.syscore) |
1666 | return 0; | 1908 | return 0; |
1667 | 1909 | ||
1668 | WARN_ON(dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) && | 1910 | WARN_ON(!pm_runtime_enabled(dev) && |
1669 | !pm_runtime_enabled(dev)); | 1911 | dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND | |
1912 | DPM_FLAG_LEAVE_SUSPENDED)); | ||
1670 | 1913 | ||
1671 | /* | 1914 | /* |
1672 | * If a device's parent goes into runtime suspend at the wrong time, | 1915 | * If a device's parent goes into runtime suspend at the wrong time, |
@@ -1678,7 +1921,7 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
1678 | 1921 | ||
1679 | device_lock(dev); | 1922 | device_lock(dev); |
1680 | 1923 | ||
1681 | dev->power.wakeup_path = device_may_wakeup(dev); | 1924 | dev->power.wakeup_path = false; |
1682 | 1925 | ||
1683 | if (dev->power.no_pm_callbacks) { | 1926 | if (dev->power.no_pm_callbacks) { |
1684 | ret = 1; /* Let device go direct_complete */ | 1927 | ret = 1; /* Let device go direct_complete */ |
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 7beee75399d4..21244c53e377 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -41,20 +41,15 @@ extern void dev_pm_disable_wake_irq_check(struct device *dev); | |||
41 | 41 | ||
42 | #ifdef CONFIG_PM_SLEEP | 42 | #ifdef CONFIG_PM_SLEEP |
43 | 43 | ||
44 | extern int device_wakeup_attach_irq(struct device *dev, | 44 | extern void device_wakeup_attach_irq(struct device *dev, struct wake_irq *wakeirq); |
45 | struct wake_irq *wakeirq); | ||
46 | extern void device_wakeup_detach_irq(struct device *dev); | 45 | extern void device_wakeup_detach_irq(struct device *dev); |
47 | extern void device_wakeup_arm_wake_irqs(void); | 46 | extern void device_wakeup_arm_wake_irqs(void); |
48 | extern void device_wakeup_disarm_wake_irqs(void); | 47 | extern void device_wakeup_disarm_wake_irqs(void); |
49 | 48 | ||
50 | #else | 49 | #else |
51 | 50 | ||
52 | static inline int | 51 | static inline void device_wakeup_attach_irq(struct device *dev, |
53 | device_wakeup_attach_irq(struct device *dev, | 52 | struct wake_irq *wakeirq) {} |
54 | struct wake_irq *wakeirq) | ||
55 | { | ||
56 | return 0; | ||
57 | } | ||
58 | 53 | ||
59 | static inline void device_wakeup_detach_irq(struct device *dev) | 54 | static inline void device_wakeup_detach_irq(struct device *dev) |
60 | { | 55 | { |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 6e89b51ea3d9..8bef3cb2424d 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -1613,22 +1613,34 @@ void pm_runtime_drop_link(struct device *dev) | |||
1613 | spin_unlock_irq(&dev->power.lock); | 1613 | spin_unlock_irq(&dev->power.lock); |
1614 | } | 1614 | } |
1615 | 1615 | ||
1616 | static bool pm_runtime_need_not_resume(struct device *dev) | ||
1617 | { | ||
1618 | return atomic_read(&dev->power.usage_count) <= 1 && | ||
1619 | (atomic_read(&dev->power.child_count) == 0 || | ||
1620 | dev->power.ignore_children); | ||
1621 | } | ||
1622 | |||
1616 | /** | 1623 | /** |
1617 | * pm_runtime_force_suspend - Force a device into suspend state if needed. | 1624 | * pm_runtime_force_suspend - Force a device into suspend state if needed. |
1618 | * @dev: Device to suspend. | 1625 | * @dev: Device to suspend. |
1619 | * | 1626 | * |
1620 | * Disable runtime PM so we safely can check the device's runtime PM status and | 1627 | * Disable runtime PM so we safely can check the device's runtime PM status and |
1621 | * if it is active, invoke it's .runtime_suspend callback to bring it into | 1628 | * if it is active, invoke its ->runtime_suspend callback to suspend it and |
1622 | * suspend state. Keep runtime PM disabled to preserve the state unless we | 1629 | * change its runtime PM status field to RPM_SUSPENDED. Also, if the device's |
1623 | * encounter errors. | 1630 | * usage and children counters don't indicate that the device was in use before |
1631 | * the system-wide transition under way, decrement its parent's children counter | ||
1632 | * (if there is a parent). Keep runtime PM disabled to preserve the state | ||
1633 | * unless we encounter errors. | ||
1624 | * | 1634 | * |
1625 | * Typically this function may be invoked from a system suspend callback to make | 1635 | * Typically this function may be invoked from a system suspend callback to make |
1626 | * sure the device is put into low power state. | 1636 | * sure the device is put into low power state and it should only be used during |
1637 | * system-wide PM transitions to sleep states. It assumes that the analogous | ||
1638 | * pm_runtime_force_resume() will be used to resume the device. | ||
1627 | */ | 1639 | */ |
1628 | int pm_runtime_force_suspend(struct device *dev) | 1640 | int pm_runtime_force_suspend(struct device *dev) |
1629 | { | 1641 | { |
1630 | int (*callback)(struct device *); | 1642 | int (*callback)(struct device *); |
1631 | int ret = 0; | 1643 | int ret; |
1632 | 1644 | ||
1633 | pm_runtime_disable(dev); | 1645 | pm_runtime_disable(dev); |
1634 | if (pm_runtime_status_suspended(dev)) | 1646 | if (pm_runtime_status_suspended(dev)) |
@@ -1636,27 +1648,23 @@ int pm_runtime_force_suspend(struct device *dev) | |||
1636 | 1648 | ||
1637 | callback = RPM_GET_CALLBACK(dev, runtime_suspend); | 1649 | callback = RPM_GET_CALLBACK(dev, runtime_suspend); |
1638 | 1650 | ||
1639 | if (!callback) { | 1651 | ret = callback ? callback(dev) : 0; |
1640 | ret = -ENOSYS; | ||
1641 | goto err; | ||
1642 | } | ||
1643 | |||
1644 | ret = callback(dev); | ||
1645 | if (ret) | 1652 | if (ret) |
1646 | goto err; | 1653 | goto err; |
1647 | 1654 | ||
1648 | /* | 1655 | /* |
1649 | * Increase the runtime PM usage count for the device's parent, in case | 1656 | * If the device can stay in suspend after the system-wide transition |
1650 | * when we find the device being used when system suspend was invoked. | 1657 | * to the working state that will follow, drop the children counter of |
1651 | * This informs pm_runtime_force_resume() to resume the parent | 1658 | * its parent, but set its status to RPM_SUSPENDED anyway in case this |
1652 | * immediately, which is needed to be able to resume its children, | 1659 | * function will be called again for it in the meantime. |
1653 | * when not deferring the resume to be managed via runtime PM. | ||
1654 | */ | 1660 | */ |
1655 | if (dev->parent && atomic_read(&dev->power.usage_count) > 1) | 1661 | if (pm_runtime_need_not_resume(dev)) |
1656 | pm_runtime_get_noresume(dev->parent); | 1662 | pm_runtime_set_suspended(dev); |
1663 | else | ||
1664 | __update_runtime_status(dev, RPM_SUSPENDED); | ||
1657 | 1665 | ||
1658 | pm_runtime_set_suspended(dev); | ||
1659 | return 0; | 1666 | return 0; |
1667 | |||
1660 | err: | 1668 | err: |
1661 | pm_runtime_enable(dev); | 1669 | pm_runtime_enable(dev); |
1662 | return ret; | 1670 | return ret; |
@@ -1669,13 +1677,9 @@ EXPORT_SYMBOL_GPL(pm_runtime_force_suspend); | |||
1669 | * | 1677 | * |
1670 | * Prior invoking this function we expect the user to have brought the device | 1678 | * Prior invoking this function we expect the user to have brought the device |
1671 | * into low power state by a call to pm_runtime_force_suspend(). Here we reverse | 1679 | * into low power state by a call to pm_runtime_force_suspend(). Here we reverse |
1672 | * those actions and brings the device into full power, if it is expected to be | 1680 | * those actions and bring the device into full power, if it is expected to be |
1673 | * used on system resume. To distinguish that, we check whether the runtime PM | 1681 | * used on system resume. In the other case, we defer the resume to be managed |
1674 | * usage count is greater than 1 (the PM core increases the usage count in the | 1682 | * via runtime PM. |
1675 | * system PM prepare phase), as that indicates a real user (such as a subsystem, | ||
1676 | * driver, userspace, etc.) is using it. If that is the case, the device is | ||
1677 | * expected to be used on system resume as well, so then we resume it. In the | ||
1678 | * other case, we defer the resume to be managed via runtime PM. | ||
1679 | * | 1683 | * |
1680 | * Typically this function may be invoked from a system resume callback. | 1684 | * Typically this function may be invoked from a system resume callback. |
1681 | */ | 1685 | */ |
@@ -1684,32 +1688,18 @@ int pm_runtime_force_resume(struct device *dev) | |||
1684 | int (*callback)(struct device *); | 1688 | int (*callback)(struct device *); |
1685 | int ret = 0; | 1689 | int ret = 0; |
1686 | 1690 | ||
1687 | callback = RPM_GET_CALLBACK(dev, runtime_resume); | 1691 | if (!pm_runtime_status_suspended(dev) || pm_runtime_need_not_resume(dev)) |
1688 | |||
1689 | if (!callback) { | ||
1690 | ret = -ENOSYS; | ||
1691 | goto out; | ||
1692 | } | ||
1693 | |||
1694 | if (!pm_runtime_status_suspended(dev)) | ||
1695 | goto out; | 1692 | goto out; |
1696 | 1693 | ||
1697 | /* | 1694 | /* |
1698 | * Decrease the parent's runtime PM usage count, if we increased it | 1695 | * The value of the parent's children counter is correct already, so |
1699 | * during system suspend in pm_runtime_force_suspend(). | 1696 | * just update the status of the device. |
1700 | */ | 1697 | */ |
1701 | if (atomic_read(&dev->power.usage_count) > 1) { | 1698 | __update_runtime_status(dev, RPM_ACTIVE); |
1702 | if (dev->parent) | ||
1703 | pm_runtime_put_noidle(dev->parent); | ||
1704 | } else { | ||
1705 | goto out; | ||
1706 | } | ||
1707 | 1699 | ||
1708 | ret = pm_runtime_set_active(dev); | 1700 | callback = RPM_GET_CALLBACK(dev, runtime_resume); |
1709 | if (ret) | ||
1710 | goto out; | ||
1711 | 1701 | ||
1712 | ret = callback(dev); | 1702 | ret = callback ? callback(dev) : 0; |
1713 | if (ret) { | 1703 | if (ret) { |
1714 | pm_runtime_set_suspended(dev); | 1704 | pm_runtime_set_suspended(dev); |
1715 | goto out; | 1705 | goto out; |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index e153e28b1857..0f651efc58a1 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
@@ -108,16 +108,10 @@ static ssize_t control_show(struct device *dev, struct device_attribute *attr, | |||
108 | static ssize_t control_store(struct device * dev, struct device_attribute *attr, | 108 | static ssize_t control_store(struct device * dev, struct device_attribute *attr, |
109 | const char * buf, size_t n) | 109 | const char * buf, size_t n) |
110 | { | 110 | { |
111 | char *cp; | ||
112 | int len = n; | ||
113 | |||
114 | cp = memchr(buf, '\n', n); | ||
115 | if (cp) | ||
116 | len = cp - buf; | ||
117 | device_lock(dev); | 111 | device_lock(dev); |
118 | if (len == sizeof ctrl_auto - 1 && strncmp(buf, ctrl_auto, len) == 0) | 112 | if (sysfs_streq(buf, ctrl_auto)) |
119 | pm_runtime_allow(dev); | 113 | pm_runtime_allow(dev); |
120 | else if (len == sizeof ctrl_on - 1 && strncmp(buf, ctrl_on, len) == 0) | 114 | else if (sysfs_streq(buf, ctrl_on)) |
121 | pm_runtime_forbid(dev); | 115 | pm_runtime_forbid(dev); |
122 | else | 116 | else |
123 | n = -EINVAL; | 117 | n = -EINVAL; |
@@ -125,9 +119,9 @@ static ssize_t control_store(struct device * dev, struct device_attribute *attr, | |||
125 | return n; | 119 | return n; |
126 | } | 120 | } |
127 | 121 | ||
128 | static DEVICE_ATTR(control, 0644, control_show, control_store); | 122 | static DEVICE_ATTR_RW(control); |
129 | 123 | ||
130 | static ssize_t rtpm_active_time_show(struct device *dev, | 124 | static ssize_t runtime_active_time_show(struct device *dev, |
131 | struct device_attribute *attr, char *buf) | 125 | struct device_attribute *attr, char *buf) |
132 | { | 126 | { |
133 | int ret; | 127 | int ret; |
@@ -138,9 +132,9 @@ static ssize_t rtpm_active_time_show(struct device *dev, | |||
138 | return ret; | 132 | return ret; |
139 | } | 133 | } |
140 | 134 | ||
141 | static DEVICE_ATTR(runtime_active_time, 0444, rtpm_active_time_show, NULL); | 135 | static DEVICE_ATTR_RO(runtime_active_time); |
142 | 136 | ||
143 | static ssize_t rtpm_suspended_time_show(struct device *dev, | 137 | static ssize_t runtime_suspended_time_show(struct device *dev, |
144 | struct device_attribute *attr, char *buf) | 138 | struct device_attribute *attr, char *buf) |
145 | { | 139 | { |
146 | int ret; | 140 | int ret; |
@@ -152,9 +146,9 @@ static ssize_t rtpm_suspended_time_show(struct device *dev, | |||
152 | return ret; | 146 | return ret; |
153 | } | 147 | } |
154 | 148 | ||
155 | static DEVICE_ATTR(runtime_suspended_time, 0444, rtpm_suspended_time_show, NULL); | 149 | static DEVICE_ATTR_RO(runtime_suspended_time); |
156 | 150 | ||
157 | static ssize_t rtpm_status_show(struct device *dev, | 151 | static ssize_t runtime_status_show(struct device *dev, |
158 | struct device_attribute *attr, char *buf) | 152 | struct device_attribute *attr, char *buf) |
159 | { | 153 | { |
160 | const char *p; | 154 | const char *p; |
@@ -184,7 +178,7 @@ static ssize_t rtpm_status_show(struct device *dev, | |||
184 | return sprintf(buf, p); | 178 | return sprintf(buf, p); |
185 | } | 179 | } |
186 | 180 | ||
187 | static DEVICE_ATTR(runtime_status, 0444, rtpm_status_show, NULL); | 181 | static DEVICE_ATTR_RO(runtime_status); |
188 | 182 | ||
189 | static ssize_t autosuspend_delay_ms_show(struct device *dev, | 183 | static ssize_t autosuspend_delay_ms_show(struct device *dev, |
190 | struct device_attribute *attr, char *buf) | 184 | struct device_attribute *attr, char *buf) |
@@ -211,26 +205,25 @@ static ssize_t autosuspend_delay_ms_store(struct device *dev, | |||
211 | return n; | 205 | return n; |
212 | } | 206 | } |
213 | 207 | ||
214 | static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show, | 208 | static DEVICE_ATTR_RW(autosuspend_delay_ms); |
215 | autosuspend_delay_ms_store); | ||
216 | 209 | ||
217 | static ssize_t pm_qos_resume_latency_show(struct device *dev, | 210 | static ssize_t pm_qos_resume_latency_us_show(struct device *dev, |
218 | struct device_attribute *attr, | 211 | struct device_attribute *attr, |
219 | char *buf) | 212 | char *buf) |
220 | { | 213 | { |
221 | s32 value = dev_pm_qos_requested_resume_latency(dev); | 214 | s32 value = dev_pm_qos_requested_resume_latency(dev); |
222 | 215 | ||
223 | if (value == 0) | 216 | if (value == 0) |
224 | return sprintf(buf, "n/a\n"); | 217 | return sprintf(buf, "n/a\n"); |
225 | else if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) | 218 | if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) |
226 | value = 0; | 219 | value = 0; |
227 | 220 | ||
228 | return sprintf(buf, "%d\n", value); | 221 | return sprintf(buf, "%d\n", value); |
229 | } | 222 | } |
230 | 223 | ||
231 | static ssize_t pm_qos_resume_latency_store(struct device *dev, | 224 | static ssize_t pm_qos_resume_latency_us_store(struct device *dev, |
232 | struct device_attribute *attr, | 225 | struct device_attribute *attr, |
233 | const char *buf, size_t n) | 226 | const char *buf, size_t n) |
234 | { | 227 | { |
235 | s32 value; | 228 | s32 value; |
236 | int ret; | 229 | int ret; |
@@ -245,7 +238,7 @@ static ssize_t pm_qos_resume_latency_store(struct device *dev, | |||
245 | 238 | ||
246 | if (value == 0) | 239 | if (value == 0) |
247 | value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; | 240 | value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; |
248 | } else if (!strcmp(buf, "n/a") || !strcmp(buf, "n/a\n")) { | 241 | } else if (sysfs_streq(buf, "n/a")) { |
249 | value = 0; | 242 | value = 0; |
250 | } else { | 243 | } else { |
251 | return -EINVAL; | 244 | return -EINVAL; |
@@ -256,26 +249,25 @@ static ssize_t pm_qos_resume_latency_store(struct device *dev, | |||
256 | return ret < 0 ? ret : n; | 249 | return ret < 0 ? ret : n; |
257 | } | 250 | } |
258 | 251 | ||
259 | static DEVICE_ATTR(pm_qos_resume_latency_us, 0644, | 252 | static DEVICE_ATTR_RW(pm_qos_resume_latency_us); |
260 | pm_qos_resume_latency_show, pm_qos_resume_latency_store); | ||
261 | 253 | ||
262 | static ssize_t pm_qos_latency_tolerance_show(struct device *dev, | 254 | static ssize_t pm_qos_latency_tolerance_us_show(struct device *dev, |
263 | struct device_attribute *attr, | 255 | struct device_attribute *attr, |
264 | char *buf) | 256 | char *buf) |
265 | { | 257 | { |
266 | s32 value = dev_pm_qos_get_user_latency_tolerance(dev); | 258 | s32 value = dev_pm_qos_get_user_latency_tolerance(dev); |
267 | 259 | ||
268 | if (value < 0) | 260 | if (value < 0) |
269 | return sprintf(buf, "auto\n"); | 261 | return sprintf(buf, "auto\n"); |
270 | else if (value == PM_QOS_LATENCY_ANY) | 262 | if (value == PM_QOS_LATENCY_ANY) |
271 | return sprintf(buf, "any\n"); | 263 | return sprintf(buf, "any\n"); |
272 | 264 | ||
273 | return sprintf(buf, "%d\n", value); | 265 | return sprintf(buf, "%d\n", value); |
274 | } | 266 | } |
275 | 267 | ||
276 | static ssize_t pm_qos_latency_tolerance_store(struct device *dev, | 268 | static ssize_t pm_qos_latency_tolerance_us_store(struct device *dev, |
277 | struct device_attribute *attr, | 269 | struct device_attribute *attr, |
278 | const char *buf, size_t n) | 270 | const char *buf, size_t n) |
279 | { | 271 | { |
280 | s32 value; | 272 | s32 value; |
281 | int ret; | 273 | int ret; |
@@ -285,9 +277,9 @@ static ssize_t pm_qos_latency_tolerance_store(struct device *dev, | |||
285 | if (value < 0) | 277 | if (value < 0) |
286 | return -EINVAL; | 278 | return -EINVAL; |
287 | } else { | 279 | } else { |
288 | if (!strcmp(buf, "auto") || !strcmp(buf, "auto\n")) | 280 | if (sysfs_streq(buf, "auto")) |
289 | value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; | 281 | value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; |
290 | else if (!strcmp(buf, "any") || !strcmp(buf, "any\n")) | 282 | else if (sysfs_streq(buf, "any")) |
291 | value = PM_QOS_LATENCY_ANY; | 283 | value = PM_QOS_LATENCY_ANY; |
292 | else | 284 | else |
293 | return -EINVAL; | 285 | return -EINVAL; |
@@ -296,8 +288,7 @@ static ssize_t pm_qos_latency_tolerance_store(struct device *dev, | |||
296 | return ret < 0 ? ret : n; | 288 | return ret < 0 ? ret : n; |
297 | } | 289 | } |
298 | 290 | ||
299 | static DEVICE_ATTR(pm_qos_latency_tolerance_us, 0644, | 291 | static DEVICE_ATTR_RW(pm_qos_latency_tolerance_us); |
300 | pm_qos_latency_tolerance_show, pm_qos_latency_tolerance_store); | ||
301 | 292 | ||
302 | static ssize_t pm_qos_no_power_off_show(struct device *dev, | 293 | static ssize_t pm_qos_no_power_off_show(struct device *dev, |
303 | struct device_attribute *attr, | 294 | struct device_attribute *attr, |
@@ -323,49 +314,39 @@ static ssize_t pm_qos_no_power_off_store(struct device *dev, | |||
323 | return ret < 0 ? ret : n; | 314 | return ret < 0 ? ret : n; |
324 | } | 315 | } |
325 | 316 | ||
326 | static DEVICE_ATTR(pm_qos_no_power_off, 0644, | 317 | static DEVICE_ATTR_RW(pm_qos_no_power_off); |
327 | pm_qos_no_power_off_show, pm_qos_no_power_off_store); | ||
328 | 318 | ||
329 | #ifdef CONFIG_PM_SLEEP | 319 | #ifdef CONFIG_PM_SLEEP |
330 | static const char _enabled[] = "enabled"; | 320 | static const char _enabled[] = "enabled"; |
331 | static const char _disabled[] = "disabled"; | 321 | static const char _disabled[] = "disabled"; |
332 | 322 | ||
333 | static ssize_t | 323 | static ssize_t wakeup_show(struct device *dev, struct device_attribute *attr, |
334 | wake_show(struct device * dev, struct device_attribute *attr, char * buf) | 324 | char *buf) |
335 | { | 325 | { |
336 | return sprintf(buf, "%s\n", device_can_wakeup(dev) | 326 | return sprintf(buf, "%s\n", device_can_wakeup(dev) |
337 | ? (device_may_wakeup(dev) ? _enabled : _disabled) | 327 | ? (device_may_wakeup(dev) ? _enabled : _disabled) |
338 | : ""); | 328 | : ""); |
339 | } | 329 | } |
340 | 330 | ||
341 | static ssize_t | 331 | static ssize_t wakeup_store(struct device *dev, struct device_attribute *attr, |
342 | wake_store(struct device * dev, struct device_attribute *attr, | 332 | const char *buf, size_t n) |
343 | const char * buf, size_t n) | ||
344 | { | 333 | { |
345 | char *cp; | ||
346 | int len = n; | ||
347 | |||
348 | if (!device_can_wakeup(dev)) | 334 | if (!device_can_wakeup(dev)) |
349 | return -EINVAL; | 335 | return -EINVAL; |
350 | 336 | ||
351 | cp = memchr(buf, '\n', n); | 337 | if (sysfs_streq(buf, _enabled)) |
352 | if (cp) | ||
353 | len = cp - buf; | ||
354 | if (len == sizeof _enabled - 1 | ||
355 | && strncmp(buf, _enabled, sizeof _enabled - 1) == 0) | ||
356 | device_set_wakeup_enable(dev, 1); | 338 | device_set_wakeup_enable(dev, 1); |
357 | else if (len == sizeof _disabled - 1 | 339 | else if (sysfs_streq(buf, _disabled)) |
358 | && strncmp(buf, _disabled, sizeof _disabled - 1) == 0) | ||
359 | device_set_wakeup_enable(dev, 0); | 340 | device_set_wakeup_enable(dev, 0); |
360 | else | 341 | else |
361 | return -EINVAL; | 342 | return -EINVAL; |
362 | return n; | 343 | return n; |
363 | } | 344 | } |
364 | 345 | ||
365 | static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store); | 346 | static DEVICE_ATTR_RW(wakeup); |
366 | 347 | ||
367 | static ssize_t wakeup_count_show(struct device *dev, | 348 | static ssize_t wakeup_count_show(struct device *dev, |
368 | struct device_attribute *attr, char *buf) | 349 | struct device_attribute *attr, char *buf) |
369 | { | 350 | { |
370 | unsigned long count = 0; | 351 | unsigned long count = 0; |
371 | bool enabled = false; | 352 | bool enabled = false; |
@@ -379,10 +360,11 @@ static ssize_t wakeup_count_show(struct device *dev, | |||
379 | return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); | 360 | return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); |
380 | } | 361 | } |
381 | 362 | ||
382 | static DEVICE_ATTR(wakeup_count, 0444, wakeup_count_show, NULL); | 363 | static DEVICE_ATTR_RO(wakeup_count); |
383 | 364 | ||
384 | static ssize_t wakeup_active_count_show(struct device *dev, | 365 | static ssize_t wakeup_active_count_show(struct device *dev, |
385 | struct device_attribute *attr, char *buf) | 366 | struct device_attribute *attr, |
367 | char *buf) | ||
386 | { | 368 | { |
387 | unsigned long count = 0; | 369 | unsigned long count = 0; |
388 | bool enabled = false; | 370 | bool enabled = false; |
@@ -396,11 +378,11 @@ static ssize_t wakeup_active_count_show(struct device *dev, | |||
396 | return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); | 378 | return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); |
397 | } | 379 | } |
398 | 380 | ||
399 | static DEVICE_ATTR(wakeup_active_count, 0444, wakeup_active_count_show, NULL); | 381 | static DEVICE_ATTR_RO(wakeup_active_count); |
400 | 382 | ||
401 | static ssize_t wakeup_abort_count_show(struct device *dev, | 383 | static ssize_t wakeup_abort_count_show(struct device *dev, |
402 | struct device_attribute *attr, | 384 | struct device_attribute *attr, |
403 | char *buf) | 385 | char *buf) |
404 | { | 386 | { |
405 | unsigned long count = 0; | 387 | unsigned long count = 0; |
406 | bool enabled = false; | 388 | bool enabled = false; |
@@ -414,7 +396,7 @@ static ssize_t wakeup_abort_count_show(struct device *dev, | |||
414 | return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); | 396 | return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); |
415 | } | 397 | } |
416 | 398 | ||
417 | static DEVICE_ATTR(wakeup_abort_count, 0444, wakeup_abort_count_show, NULL); | 399 | static DEVICE_ATTR_RO(wakeup_abort_count); |
418 | 400 | ||
419 | static ssize_t wakeup_expire_count_show(struct device *dev, | 401 | static ssize_t wakeup_expire_count_show(struct device *dev, |
420 | struct device_attribute *attr, | 402 | struct device_attribute *attr, |
@@ -432,10 +414,10 @@ static ssize_t wakeup_expire_count_show(struct device *dev, | |||
432 | return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); | 414 | return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); |
433 | } | 415 | } |
434 | 416 | ||
435 | static DEVICE_ATTR(wakeup_expire_count, 0444, wakeup_expire_count_show, NULL); | 417 | static DEVICE_ATTR_RO(wakeup_expire_count); |
436 | 418 | ||
437 | static ssize_t wakeup_active_show(struct device *dev, | 419 | static ssize_t wakeup_active_show(struct device *dev, |
438 | struct device_attribute *attr, char *buf) | 420 | struct device_attribute *attr, char *buf) |
439 | { | 421 | { |
440 | unsigned int active = 0; | 422 | unsigned int active = 0; |
441 | bool enabled = false; | 423 | bool enabled = false; |
@@ -449,10 +431,11 @@ static ssize_t wakeup_active_show(struct device *dev, | |||
449 | return enabled ? sprintf(buf, "%u\n", active) : sprintf(buf, "\n"); | 431 | return enabled ? sprintf(buf, "%u\n", active) : sprintf(buf, "\n"); |
450 | } | 432 | } |
451 | 433 | ||
452 | static DEVICE_ATTR(wakeup_active, 0444, wakeup_active_show, NULL); | 434 | static DEVICE_ATTR_RO(wakeup_active); |
453 | 435 | ||
454 | static ssize_t wakeup_total_time_show(struct device *dev, | 436 | static ssize_t wakeup_total_time_ms_show(struct device *dev, |
455 | struct device_attribute *attr, char *buf) | 437 | struct device_attribute *attr, |
438 | char *buf) | ||
456 | { | 439 | { |
457 | s64 msec = 0; | 440 | s64 msec = 0; |
458 | bool enabled = false; | 441 | bool enabled = false; |
@@ -466,10 +449,10 @@ static ssize_t wakeup_total_time_show(struct device *dev, | |||
466 | return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); | 449 | return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); |
467 | } | 450 | } |
468 | 451 | ||
469 | static DEVICE_ATTR(wakeup_total_time_ms, 0444, wakeup_total_time_show, NULL); | 452 | static DEVICE_ATTR_RO(wakeup_total_time_ms); |
470 | 453 | ||
471 | static ssize_t wakeup_max_time_show(struct device *dev, | 454 | static ssize_t wakeup_max_time_ms_show(struct device *dev, |
472 | struct device_attribute *attr, char *buf) | 455 | struct device_attribute *attr, char *buf) |
473 | { | 456 | { |
474 | s64 msec = 0; | 457 | s64 msec = 0; |
475 | bool enabled = false; | 458 | bool enabled = false; |
@@ -483,10 +466,11 @@ static ssize_t wakeup_max_time_show(struct device *dev, | |||
483 | return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); | 466 | return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); |
484 | } | 467 | } |
485 | 468 | ||
486 | static DEVICE_ATTR(wakeup_max_time_ms, 0444, wakeup_max_time_show, NULL); | 469 | static DEVICE_ATTR_RO(wakeup_max_time_ms); |
487 | 470 | ||
488 | static ssize_t wakeup_last_time_show(struct device *dev, | 471 | static ssize_t wakeup_last_time_ms_show(struct device *dev, |
489 | struct device_attribute *attr, char *buf) | 472 | struct device_attribute *attr, |
473 | char *buf) | ||
490 | { | 474 | { |
491 | s64 msec = 0; | 475 | s64 msec = 0; |
492 | bool enabled = false; | 476 | bool enabled = false; |
@@ -500,12 +484,12 @@ static ssize_t wakeup_last_time_show(struct device *dev, | |||
500 | return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); | 484 | return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); |
501 | } | 485 | } |
502 | 486 | ||
503 | static DEVICE_ATTR(wakeup_last_time_ms, 0444, wakeup_last_time_show, NULL); | 487 | static DEVICE_ATTR_RO(wakeup_last_time_ms); |
504 | 488 | ||
505 | #ifdef CONFIG_PM_AUTOSLEEP | 489 | #ifdef CONFIG_PM_AUTOSLEEP |
506 | static ssize_t wakeup_prevent_sleep_time_show(struct device *dev, | 490 | static ssize_t wakeup_prevent_sleep_time_ms_show(struct device *dev, |
507 | struct device_attribute *attr, | 491 | struct device_attribute *attr, |
508 | char *buf) | 492 | char *buf) |
509 | { | 493 | { |
510 | s64 msec = 0; | 494 | s64 msec = 0; |
511 | bool enabled = false; | 495 | bool enabled = false; |
@@ -519,40 +503,39 @@ static ssize_t wakeup_prevent_sleep_time_show(struct device *dev, | |||
519 | return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); | 503 | return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); |
520 | } | 504 | } |
521 | 505 | ||
522 | static DEVICE_ATTR(wakeup_prevent_sleep_time_ms, 0444, | 506 | static DEVICE_ATTR_RO(wakeup_prevent_sleep_time_ms); |
523 | wakeup_prevent_sleep_time_show, NULL); | ||
524 | #endif /* CONFIG_PM_AUTOSLEEP */ | 507 | #endif /* CONFIG_PM_AUTOSLEEP */ |
525 | #endif /* CONFIG_PM_SLEEP */ | 508 | #endif /* CONFIG_PM_SLEEP */ |
526 | 509 | ||
527 | #ifdef CONFIG_PM_ADVANCED_DEBUG | 510 | #ifdef CONFIG_PM_ADVANCED_DEBUG |
528 | static ssize_t rtpm_usagecount_show(struct device *dev, | 511 | static ssize_t runtime_usage_show(struct device *dev, |
529 | struct device_attribute *attr, char *buf) | 512 | struct device_attribute *attr, char *buf) |
530 | { | 513 | { |
531 | return sprintf(buf, "%d\n", atomic_read(&dev->power.usage_count)); | 514 | return sprintf(buf, "%d\n", atomic_read(&dev->power.usage_count)); |
532 | } | 515 | } |
516 | static DEVICE_ATTR_RO(runtime_usage); | ||
533 | 517 | ||
534 | static ssize_t rtpm_children_show(struct device *dev, | 518 | static ssize_t runtime_active_kids_show(struct device *dev, |
535 | struct device_attribute *attr, char *buf) | 519 | struct device_attribute *attr, |
520 | char *buf) | ||
536 | { | 521 | { |
537 | return sprintf(buf, "%d\n", dev->power.ignore_children ? | 522 | return sprintf(buf, "%d\n", dev->power.ignore_children ? |
538 | 0 : atomic_read(&dev->power.child_count)); | 523 | 0 : atomic_read(&dev->power.child_count)); |
539 | } | 524 | } |
525 | static DEVICE_ATTR_RO(runtime_active_kids); | ||
540 | 526 | ||
541 | static ssize_t rtpm_enabled_show(struct device *dev, | 527 | static ssize_t runtime_enabled_show(struct device *dev, |
542 | struct device_attribute *attr, char *buf) | 528 | struct device_attribute *attr, char *buf) |
543 | { | 529 | { |
544 | if ((dev->power.disable_depth) && (dev->power.runtime_auto == false)) | 530 | if (dev->power.disable_depth && (dev->power.runtime_auto == false)) |
545 | return sprintf(buf, "disabled & forbidden\n"); | 531 | return sprintf(buf, "disabled & forbidden\n"); |
546 | else if (dev->power.disable_depth) | 532 | if (dev->power.disable_depth) |
547 | return sprintf(buf, "disabled\n"); | 533 | return sprintf(buf, "disabled\n"); |
548 | else if (dev->power.runtime_auto == false) | 534 | if (dev->power.runtime_auto == false) |
549 | return sprintf(buf, "forbidden\n"); | 535 | return sprintf(buf, "forbidden\n"); |
550 | return sprintf(buf, "enabled\n"); | 536 | return sprintf(buf, "enabled\n"); |
551 | } | 537 | } |
552 | 538 | static DEVICE_ATTR_RO(runtime_enabled); | |
553 | static DEVICE_ATTR(runtime_usage, 0444, rtpm_usagecount_show, NULL); | ||
554 | static DEVICE_ATTR(runtime_active_kids, 0444, rtpm_children_show, NULL); | ||
555 | static DEVICE_ATTR(runtime_enabled, 0444, rtpm_enabled_show, NULL); | ||
556 | 539 | ||
557 | #ifdef CONFIG_PM_SLEEP | 540 | #ifdef CONFIG_PM_SLEEP |
558 | static ssize_t async_show(struct device *dev, struct device_attribute *attr, | 541 | static ssize_t async_show(struct device *dev, struct device_attribute *attr, |
@@ -566,23 +549,16 @@ static ssize_t async_show(struct device *dev, struct device_attribute *attr, | |||
566 | static ssize_t async_store(struct device *dev, struct device_attribute *attr, | 549 | static ssize_t async_store(struct device *dev, struct device_attribute *attr, |
567 | const char *buf, size_t n) | 550 | const char *buf, size_t n) |
568 | { | 551 | { |
569 | char *cp; | 552 | if (sysfs_streq(buf, _enabled)) |
570 | int len = n; | ||
571 | |||
572 | cp = memchr(buf, '\n', n); | ||
573 | if (cp) | ||
574 | len = cp - buf; | ||
575 | if (len == sizeof _enabled - 1 && strncmp(buf, _enabled, len) == 0) | ||
576 | device_enable_async_suspend(dev); | 553 | device_enable_async_suspend(dev); |
577 | else if (len == sizeof _disabled - 1 && | 554 | else if (sysfs_streq(buf, _disabled)) |
578 | strncmp(buf, _disabled, len) == 0) | ||
579 | device_disable_async_suspend(dev); | 555 | device_disable_async_suspend(dev); |
580 | else | 556 | else |
581 | return -EINVAL; | 557 | return -EINVAL; |
582 | return n; | 558 | return n; |
583 | } | 559 | } |
584 | 560 | ||
585 | static DEVICE_ATTR(async, 0644, async_show, async_store); | 561 | static DEVICE_ATTR_RW(async); |
586 | 562 | ||
587 | #endif /* CONFIG_PM_SLEEP */ | 563 | #endif /* CONFIG_PM_SLEEP */ |
588 | #endif /* CONFIG_PM_ADVANCED_DEBUG */ | 564 | #endif /* CONFIG_PM_ADVANCED_DEBUG */ |
diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c index ae0429827f31..a8ac86e4d79e 100644 --- a/drivers/base/power/wakeirq.c +++ b/drivers/base/power/wakeirq.c | |||
@@ -33,7 +33,6 @@ static int dev_pm_attach_wake_irq(struct device *dev, int irq, | |||
33 | struct wake_irq *wirq) | 33 | struct wake_irq *wirq) |
34 | { | 34 | { |
35 | unsigned long flags; | 35 | unsigned long flags; |
36 | int err; | ||
37 | 36 | ||
38 | if (!dev || !wirq) | 37 | if (!dev || !wirq) |
39 | return -EINVAL; | 38 | return -EINVAL; |
@@ -45,12 +44,11 @@ static int dev_pm_attach_wake_irq(struct device *dev, int irq, | |||
45 | return -EEXIST; | 44 | return -EEXIST; |
46 | } | 45 | } |
47 | 46 | ||
48 | err = device_wakeup_attach_irq(dev, wirq); | 47 | dev->power.wakeirq = wirq; |
49 | if (!err) | 48 | device_wakeup_attach_irq(dev, wirq); |
50 | dev->power.wakeirq = wirq; | ||
51 | 49 | ||
52 | spin_unlock_irqrestore(&dev->power.lock, flags); | 50 | spin_unlock_irqrestore(&dev->power.lock, flags); |
53 | return err; | 51 | return 0; |
54 | } | 52 | } |
55 | 53 | ||
56 | /** | 54 | /** |
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 38559f04db2c..ea01621ed769 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -19,6 +19,11 @@ | |||
19 | 19 | ||
20 | #include "power.h" | 20 | #include "power.h" |
21 | 21 | ||
22 | #ifndef CONFIG_SUSPEND | ||
23 | suspend_state_t pm_suspend_target_state; | ||
24 | #define pm_suspend_target_state (PM_SUSPEND_ON) | ||
25 | #endif | ||
26 | |||
22 | /* | 27 | /* |
23 | * If set, the suspend/hibernate code will abort transitions to a sleep state | 28 | * If set, the suspend/hibernate code will abort transitions to a sleep state |
24 | * if wakeup events are registered during or immediately before the transition. | 29 | * if wakeup events are registered during or immediately before the transition. |
@@ -268,6 +273,9 @@ int device_wakeup_enable(struct device *dev) | |||
268 | if (!dev || !dev->power.can_wakeup) | 273 | if (!dev || !dev->power.can_wakeup) |
269 | return -EINVAL; | 274 | return -EINVAL; |
270 | 275 | ||
276 | if (pm_suspend_target_state != PM_SUSPEND_ON) | ||
277 | dev_dbg(dev, "Suspicious %s() during system transition!\n", __func__); | ||
278 | |||
271 | ws = wakeup_source_register(dev_name(dev)); | 279 | ws = wakeup_source_register(dev_name(dev)); |
272 | if (!ws) | 280 | if (!ws) |
273 | return -ENOMEM; | 281 | return -ENOMEM; |
@@ -291,22 +299,19 @@ EXPORT_SYMBOL_GPL(device_wakeup_enable); | |||
291 | * | 299 | * |
292 | * Call under the device's power.lock lock. | 300 | * Call under the device's power.lock lock. |
293 | */ | 301 | */ |
294 | int device_wakeup_attach_irq(struct device *dev, | 302 | void device_wakeup_attach_irq(struct device *dev, |
295 | struct wake_irq *wakeirq) | 303 | struct wake_irq *wakeirq) |
296 | { | 304 | { |
297 | struct wakeup_source *ws; | 305 | struct wakeup_source *ws; |
298 | 306 | ||
299 | ws = dev->power.wakeup; | 307 | ws = dev->power.wakeup; |
300 | if (!ws) { | 308 | if (!ws) |
301 | dev_err(dev, "forgot to call call device_init_wakeup?\n"); | 309 | return; |
302 | return -EINVAL; | ||
303 | } | ||
304 | 310 | ||
305 | if (ws->wakeirq) | 311 | if (ws->wakeirq) |
306 | return -EEXIST; | 312 | dev_err(dev, "Leftover wakeup IRQ found, overriding\n"); |
307 | 313 | ||
308 | ws->wakeirq = wakeirq; | 314 | ws->wakeirq = wakeirq; |
309 | return 0; | ||
310 | } | 315 | } |
311 | 316 | ||
312 | /** | 317 | /** |
@@ -448,9 +453,7 @@ int device_init_wakeup(struct device *dev, bool enable) | |||
448 | device_set_wakeup_capable(dev, true); | 453 | device_set_wakeup_capable(dev, true); |
449 | ret = device_wakeup_enable(dev); | 454 | ret = device_wakeup_enable(dev); |
450 | } else { | 455 | } else { |
451 | if (dev->power.can_wakeup) | 456 | device_wakeup_disable(dev); |
452 | device_wakeup_disable(dev); | ||
453 | |||
454 | device_set_wakeup_capable(dev, false); | 457 | device_set_wakeup_capable(dev, false); |
455 | } | 458 | } |
456 | 459 | ||
@@ -464,9 +467,6 @@ EXPORT_SYMBOL_GPL(device_init_wakeup); | |||
464 | */ | 467 | */ |
465 | int device_set_wakeup_enable(struct device *dev, bool enable) | 468 | int device_set_wakeup_enable(struct device *dev, bool enable) |
466 | { | 469 | { |
467 | if (!dev || !dev->power.can_wakeup) | ||
468 | return -EINVAL; | ||
469 | |||
470 | return enable ? device_wakeup_enable(dev) : device_wakeup_disable(dev); | 470 | return enable ? device_wakeup_enable(dev) : device_wakeup_disable(dev); |
471 | } | 471 | } |
472 | EXPORT_SYMBOL_GPL(device_set_wakeup_enable); | 472 | EXPORT_SYMBOL_GPL(device_set_wakeup_enable); |
diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 2b2c7db3e480..35c3936edc45 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c | |||
@@ -1615,22 +1615,6 @@ static struct dma_chan *rcar_dmac_of_xlate(struct of_phandle_args *dma_spec, | |||
1615 | * Power management | 1615 | * Power management |
1616 | */ | 1616 | */ |
1617 | 1617 | ||
1618 | #ifdef CONFIG_PM_SLEEP | ||
1619 | static int rcar_dmac_sleep_suspend(struct device *dev) | ||
1620 | { | ||
1621 | /* | ||
1622 | * TODO: Wait for the current transfer to complete and stop the device. | ||
1623 | */ | ||
1624 | return 0; | ||
1625 | } | ||
1626 | |||
1627 | static int rcar_dmac_sleep_resume(struct device *dev) | ||
1628 | { | ||
1629 | /* TODO: Resume transfers, if any. */ | ||
1630 | return 0; | ||
1631 | } | ||
1632 | #endif | ||
1633 | |||
1634 | #ifdef CONFIG_PM | 1618 | #ifdef CONFIG_PM |
1635 | static int rcar_dmac_runtime_suspend(struct device *dev) | 1619 | static int rcar_dmac_runtime_suspend(struct device *dev) |
1636 | { | 1620 | { |
@@ -1646,7 +1630,13 @@ static int rcar_dmac_runtime_resume(struct device *dev) | |||
1646 | #endif | 1630 | #endif |
1647 | 1631 | ||
1648 | static const struct dev_pm_ops rcar_dmac_pm = { | 1632 | static const struct dev_pm_ops rcar_dmac_pm = { |
1649 | SET_SYSTEM_SLEEP_PM_OPS(rcar_dmac_sleep_suspend, rcar_dmac_sleep_resume) | 1633 | /* |
1634 | * TODO for system sleep/resume: | ||
1635 | * - Wait for the current transfer to complete and stop the device, | ||
1636 | * - Resume transfers, if any. | ||
1637 | */ | ||
1638 | SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | ||
1639 | pm_runtime_force_resume) | ||
1650 | SET_RUNTIME_PM_OPS(rcar_dmac_runtime_suspend, rcar_dmac_runtime_resume, | 1640 | SET_RUNTIME_PM_OPS(rcar_dmac_runtime_suspend, rcar_dmac_runtime_resume, |
1651 | NULL) | 1641 | NULL) |
1652 | }; | 1642 | }; |
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 21bf619a86c5..9fee4c054d3d 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h | |||
@@ -280,8 +280,6 @@ struct dw_i2c_dev { | |||
280 | int (*acquire_lock)(struct dw_i2c_dev *dev); | 280 | int (*acquire_lock)(struct dw_i2c_dev *dev); |
281 | void (*release_lock)(struct dw_i2c_dev *dev); | 281 | void (*release_lock)(struct dw_i2c_dev *dev); |
282 | bool pm_disabled; | 282 | bool pm_disabled; |
283 | bool suspended; | ||
284 | bool skip_resume; | ||
285 | void (*disable)(struct dw_i2c_dev *dev); | 283 | void (*disable)(struct dw_i2c_dev *dev); |
286 | void (*disable_int)(struct dw_i2c_dev *dev); | 284 | void (*disable_int)(struct dw_i2c_dev *dev); |
287 | int (*init)(struct dw_i2c_dev *dev); | 285 | int (*init)(struct dw_i2c_dev *dev); |
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 58add69a441c..153b947702c5 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/reset.h> | 42 | #include <linux/reset.h> |
43 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/suspend.h> | ||
45 | 46 | ||
46 | #include "i2c-designware-core.h" | 47 | #include "i2c-designware-core.h" |
47 | 48 | ||
@@ -372,6 +373,11 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) | |||
372 | ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); | 373 | ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); |
373 | adap->dev.of_node = pdev->dev.of_node; | 374 | adap->dev.of_node = pdev->dev.of_node; |
374 | 375 | ||
376 | dev_pm_set_driver_flags(&pdev->dev, | ||
377 | DPM_FLAG_SMART_PREPARE | | ||
378 | DPM_FLAG_SMART_SUSPEND | | ||
379 | DPM_FLAG_LEAVE_SUSPENDED); | ||
380 | |||
375 | /* The code below assumes runtime PM to be disabled. */ | 381 | /* The code below assumes runtime PM to be disabled. */ |
376 | WARN_ON(pm_runtime_enabled(&pdev->dev)); | 382 | WARN_ON(pm_runtime_enabled(&pdev->dev)); |
377 | 383 | ||
@@ -435,12 +441,24 @@ MODULE_DEVICE_TABLE(of, dw_i2c_of_match); | |||
435 | #ifdef CONFIG_PM_SLEEP | 441 | #ifdef CONFIG_PM_SLEEP |
436 | static int dw_i2c_plat_prepare(struct device *dev) | 442 | static int dw_i2c_plat_prepare(struct device *dev) |
437 | { | 443 | { |
438 | return pm_runtime_suspended(dev); | 444 | /* |
445 | * If the ACPI companion device object is present for this device, it | ||
446 | * may be accessed during suspend and resume of other devices via I2C | ||
447 | * operation regions, so tell the PM core and middle layers to avoid | ||
448 | * skipping system suspend/resume callbacks for it in that case. | ||
449 | */ | ||
450 | return !has_acpi_companion(dev); | ||
439 | } | 451 | } |
440 | 452 | ||
441 | static void dw_i2c_plat_complete(struct device *dev) | 453 | static void dw_i2c_plat_complete(struct device *dev) |
442 | { | 454 | { |
443 | if (dev->power.direct_complete) | 455 | /* |
456 | * The device can only be in runtime suspend at this point if it has not | ||
457 | * been resumed throughout the ending system suspend/resume cycle, so if | ||
458 | * the platform firmware might mess up with it, request the runtime PM | ||
459 | * framework to resume it. | ||
460 | */ | ||
461 | if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) | ||
444 | pm_request_resume(dev); | 462 | pm_request_resume(dev); |
445 | } | 463 | } |
446 | #else | 464 | #else |
@@ -453,16 +471,9 @@ static int dw_i2c_plat_suspend(struct device *dev) | |||
453 | { | 471 | { |
454 | struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); | 472 | struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); |
455 | 473 | ||
456 | if (i_dev->suspended) { | ||
457 | i_dev->skip_resume = true; | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | i_dev->disable(i_dev); | 474 | i_dev->disable(i_dev); |
462 | i2c_dw_plat_prepare_clk(i_dev, false); | 475 | i2c_dw_plat_prepare_clk(i_dev, false); |
463 | 476 | ||
464 | i_dev->suspended = true; | ||
465 | |||
466 | return 0; | 477 | return 0; |
467 | } | 478 | } |
468 | 479 | ||
@@ -470,19 +481,9 @@ static int dw_i2c_plat_resume(struct device *dev) | |||
470 | { | 481 | { |
471 | struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); | 482 | struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); |
472 | 483 | ||
473 | if (!i_dev->suspended) | ||
474 | return 0; | ||
475 | |||
476 | if (i_dev->skip_resume) { | ||
477 | i_dev->skip_resume = false; | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | i2c_dw_plat_prepare_clk(i_dev, true); | 484 | i2c_dw_plat_prepare_clk(i_dev, true); |
482 | i_dev->init(i_dev); | 485 | i_dev->init(i_dev); |
483 | 486 | ||
484 | i_dev->suspended = false; | ||
485 | |||
486 | return 0; | 487 | return 0; |
487 | } | 488 | } |
488 | 489 | ||
diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c index 0e0ab9bb1530..9e545eb6e8b4 100644 --- a/drivers/mfd/intel-lpss.c +++ b/drivers/mfd/intel-lpss.c | |||
@@ -450,6 +450,8 @@ int intel_lpss_probe(struct device *dev, | |||
450 | if (ret) | 450 | if (ret) |
451 | goto err_remove_ltr; | 451 | goto err_remove_ltr; |
452 | 452 | ||
453 | dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND); | ||
454 | |||
453 | return 0; | 455 | return 0; |
454 | 456 | ||
455 | err_remove_ltr: | 457 | err_remove_ltr: |
@@ -478,7 +480,9 @@ EXPORT_SYMBOL_GPL(intel_lpss_remove); | |||
478 | 480 | ||
479 | static int resume_lpss_device(struct device *dev, void *data) | 481 | static int resume_lpss_device(struct device *dev, void *data) |
480 | { | 482 | { |
481 | pm_runtime_resume(dev); | 483 | if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) |
484 | pm_runtime_resume(dev); | ||
485 | |||
482 | return 0; | 486 | return 0; |
483 | } | 487 | } |
484 | 488 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 765890e77cd5..5958c8dda4e3 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -699,7 +699,7 @@ static void pci_pm_complete(struct device *dev) | |||
699 | pm_generic_complete(dev); | 699 | pm_generic_complete(dev); |
700 | 700 | ||
701 | /* Resume device if platform firmware has put it in reset-power-on */ | 701 | /* Resume device if platform firmware has put it in reset-power-on */ |
702 | if (dev->power.direct_complete && pm_resume_via_firmware()) { | 702 | if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) { |
703 | pci_power_t pre_sleep_state = pci_dev->current_state; | 703 | pci_power_t pre_sleep_state = pci_dev->current_state; |
704 | 704 | ||
705 | pci_update_current_state(pci_dev, pci_dev->current_state); | 705 | pci_update_current_state(pci_dev, pci_dev->current_state); |
@@ -783,8 +783,10 @@ static int pci_pm_suspend_noirq(struct device *dev) | |||
783 | struct pci_dev *pci_dev = to_pci_dev(dev); | 783 | struct pci_dev *pci_dev = to_pci_dev(dev); |
784 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 784 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
785 | 785 | ||
786 | if (dev_pm_smart_suspend_and_suspended(dev)) | 786 | if (dev_pm_smart_suspend_and_suspended(dev)) { |
787 | dev->power.may_skip_resume = true; | ||
787 | return 0; | 788 | return 0; |
789 | } | ||
788 | 790 | ||
789 | if (pci_has_legacy_pm_support(pci_dev)) | 791 | if (pci_has_legacy_pm_support(pci_dev)) |
790 | return pci_legacy_suspend_late(dev, PMSG_SUSPEND); | 792 | return pci_legacy_suspend_late(dev, PMSG_SUSPEND); |
@@ -838,6 +840,16 @@ static int pci_pm_suspend_noirq(struct device *dev) | |||
838 | Fixup: | 840 | Fixup: |
839 | pci_fixup_device(pci_fixup_suspend_late, pci_dev); | 841 | pci_fixup_device(pci_fixup_suspend_late, pci_dev); |
840 | 842 | ||
843 | /* | ||
844 | * If the target system sleep state is suspend-to-idle, it is sufficient | ||
845 | * to check whether or not the device's wakeup settings are good for | ||
846 | * runtime PM. Otherwise, the pm_resume_via_firmware() check will cause | ||
847 | * pci_pm_complete() to take care of fixing up the device's state | ||
848 | * anyway, if need be. | ||
849 | */ | ||
850 | dev->power.may_skip_resume = device_may_wakeup(dev) || | ||
851 | !device_can_wakeup(dev); | ||
852 | |||
841 | return 0; | 853 | return 0; |
842 | } | 854 | } |
843 | 855 | ||
@@ -847,6 +859,9 @@ static int pci_pm_resume_noirq(struct device *dev) | |||
847 | struct device_driver *drv = dev->driver; | 859 | struct device_driver *drv = dev->driver; |
848 | int error = 0; | 860 | int error = 0; |
849 | 861 | ||
862 | if (dev_pm_may_skip_resume(dev)) | ||
863 | return 0; | ||
864 | |||
850 | /* | 865 | /* |
851 | * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend | 866 | * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend |
852 | * during system suspend, so update their runtime PM status to "active" | 867 | * during system suspend, so update their runtime PM status to "active" |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index ffbf4e723527..fb1c1bb87316 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -150,6 +150,9 @@ static int pcie_portdrv_probe(struct pci_dev *dev, | |||
150 | 150 | ||
151 | pci_save_state(dev); | 151 | pci_save_state(dev); |
152 | 152 | ||
153 | dev_pm_set_driver_flags(&dev->dev, DPM_FLAG_SMART_SUSPEND | | ||
154 | DPM_FLAG_LEAVE_SUSPENDED); | ||
155 | |||
153 | if (pci_bridge_d3_possible(dev)) { | 156 | if (pci_bridge_d3_possible(dev)) { |
154 | /* | 157 | /* |
155 | * Keep the port resumed 100ms to make sure things like | 158 | * Keep the port resumed 100ms to make sure things like |
diff --git a/include/linux/pm.h b/include/linux/pm.h index 492ed473ba7e..e723b78d8357 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -556,9 +556,10 @@ struct pm_subsys_data { | |||
556 | * These flags can be set by device drivers at the probe time. They need not be | 556 | * These flags can be set by device drivers at the probe time. They need not be |
557 | * cleared by the drivers as the driver core will take care of that. | 557 | * cleared by the drivers as the driver core will take care of that. |
558 | * | 558 | * |
559 | * NEVER_SKIP: Do not skip system suspend/resume callbacks for the device. | 559 | * NEVER_SKIP: Do not skip all system suspend/resume callbacks for the device. |
560 | * SMART_PREPARE: Check the return value of the driver's ->prepare callback. | 560 | * SMART_PREPARE: Check the return value of the driver's ->prepare callback. |
561 | * SMART_SUSPEND: No need to resume the device from runtime suspend. | 561 | * SMART_SUSPEND: No need to resume the device from runtime suspend. |
562 | * LEAVE_SUSPENDED: Avoid resuming the device during system resume if possible. | ||
562 | * | 563 | * |
563 | * Setting SMART_PREPARE instructs bus types and PM domains which may want | 564 | * Setting SMART_PREPARE instructs bus types and PM domains which may want |
564 | * system suspend/resume callbacks to be skipped for the device to return 0 from | 565 | * system suspend/resume callbacks to be skipped for the device to return 0 from |
@@ -572,10 +573,14 @@ struct pm_subsys_data { | |||
572 | * necessary from the driver's perspective. It also may cause them to skip | 573 | * necessary from the driver's perspective. It also may cause them to skip |
573 | * invocations of the ->suspend_late and ->suspend_noirq callbacks provided by | 574 | * invocations of the ->suspend_late and ->suspend_noirq callbacks provided by |
574 | * the driver if they decide to leave the device in runtime suspend. | 575 | * the driver if they decide to leave the device in runtime suspend. |
576 | * | ||
577 | * Setting LEAVE_SUSPENDED informs the PM core and middle-layer code that the | ||
578 | * driver prefers the device to be left in suspend after system resume. | ||
575 | */ | 579 | */ |
576 | #define DPM_FLAG_NEVER_SKIP BIT(0) | 580 | #define DPM_FLAG_NEVER_SKIP BIT(0) |
577 | #define DPM_FLAG_SMART_PREPARE BIT(1) | 581 | #define DPM_FLAG_SMART_PREPARE BIT(1) |
578 | #define DPM_FLAG_SMART_SUSPEND BIT(2) | 582 | #define DPM_FLAG_SMART_SUSPEND BIT(2) |
583 | #define DPM_FLAG_LEAVE_SUSPENDED BIT(3) | ||
579 | 584 | ||
580 | struct dev_pm_info { | 585 | struct dev_pm_info { |
581 | pm_message_t power_state; | 586 | pm_message_t power_state; |
@@ -597,6 +602,8 @@ struct dev_pm_info { | |||
597 | bool wakeup_path:1; | 602 | bool wakeup_path:1; |
598 | bool syscore:1; | 603 | bool syscore:1; |
599 | bool no_pm_callbacks:1; /* Owned by the PM core */ | 604 | bool no_pm_callbacks:1; /* Owned by the PM core */ |
605 | unsigned int must_resume:1; /* Owned by the PM core */ | ||
606 | unsigned int may_skip_resume:1; /* Set by subsystems */ | ||
600 | #else | 607 | #else |
601 | unsigned int should_wakeup:1; | 608 | unsigned int should_wakeup:1; |
602 | #endif | 609 | #endif |
@@ -766,6 +773,7 @@ extern int pm_generic_poweroff(struct device *dev); | |||
766 | extern void pm_generic_complete(struct device *dev); | 773 | extern void pm_generic_complete(struct device *dev); |
767 | 774 | ||
768 | extern void dev_pm_skip_next_resume_phases(struct device *dev); | 775 | extern void dev_pm_skip_next_resume_phases(struct device *dev); |
776 | extern bool dev_pm_may_skip_resume(struct device *dev); | ||
769 | extern bool dev_pm_smart_suspend_and_suspended(struct device *dev); | 777 | extern bool dev_pm_smart_suspend_and_suspended(struct device *dev); |
770 | 778 | ||
771 | #else /* !CONFIG_PM_SLEEP */ | 779 | #else /* !CONFIG_PM_SLEEP */ |
diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 4c2cba7ec1d4..4238dde0aaf0 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h | |||
@@ -88,6 +88,11 @@ static inline bool device_may_wakeup(struct device *dev) | |||
88 | return dev->power.can_wakeup && !!dev->power.wakeup; | 88 | return dev->power.can_wakeup && !!dev->power.wakeup; |
89 | } | 89 | } |
90 | 90 | ||
91 | static inline void device_set_wakeup_path(struct device *dev) | ||
92 | { | ||
93 | dev->power.wakeup_path = true; | ||
94 | } | ||
95 | |||
91 | /* drivers/base/power/wakeup.c */ | 96 | /* drivers/base/power/wakeup.c */ |
92 | extern void wakeup_source_prepare(struct wakeup_source *ws, const char *name); | 97 | extern void wakeup_source_prepare(struct wakeup_source *ws, const char *name); |
93 | extern struct wakeup_source *wakeup_source_create(const char *name); | 98 | extern struct wakeup_source *wakeup_source_create(const char *name); |
@@ -174,6 +179,8 @@ static inline bool device_may_wakeup(struct device *dev) | |||
174 | return dev->power.can_wakeup && dev->power.should_wakeup; | 179 | return dev->power.can_wakeup && dev->power.should_wakeup; |
175 | } | 180 | } |
176 | 181 | ||
182 | static inline void device_set_wakeup_path(struct device *dev) {} | ||
183 | |||
177 | static inline void __pm_stay_awake(struct wakeup_source *ws) {} | 184 | static inline void __pm_stay_awake(struct wakeup_source *ws) {} |
178 | 185 | ||
179 | static inline void pm_stay_awake(struct device *dev) {} | 186 | static inline void pm_stay_awake(struct device *dev) {} |