aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/power/runtime.c')
-rw-r--r--drivers/base/power/runtime.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 70624695b6d5..ccd296dbb95c 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -95,7 +95,7 @@ static void __update_runtime_status(struct device *dev, enum rpm_status status)
95static void pm_runtime_deactivate_timer(struct device *dev) 95static void pm_runtime_deactivate_timer(struct device *dev)
96{ 96{
97 if (dev->power.timer_expires > 0) { 97 if (dev->power.timer_expires > 0) {
98 hrtimer_cancel(&dev->power.suspend_timer); 98 hrtimer_try_to_cancel(&dev->power.suspend_timer);
99 dev->power.timer_expires = 0; 99 dev->power.timer_expires = 0;
100 } 100 }
101} 101}
@@ -121,7 +121,7 @@ static void pm_runtime_cancel_pending(struct device *dev)
121 * Compute the autosuspend-delay expiration time based on the device's 121 * Compute the autosuspend-delay expiration time based on the device's
122 * power.last_busy time. If the delay has already expired or is disabled 122 * power.last_busy time. If the delay has already expired or is disabled
123 * (negative) or the power.use_autosuspend flag isn't set, return 0. 123 * (negative) or the power.use_autosuspend flag isn't set, return 0.
124 * Otherwise return the expiration time in jiffies (adjusted to be nonzero). 124 * Otherwise return the expiration time in nanoseconds (adjusted to be nonzero).
125 * 125 *
126 * This function may be called either with or without dev->power.lock held. 126 * This function may be called either with or without dev->power.lock held.
127 * Either way it can be racy, since power.last_busy may be updated at any time. 127 * Either way it can be racy, since power.last_busy may be updated at any time.
@@ -130,7 +130,7 @@ u64 pm_runtime_autosuspend_expiration(struct device *dev)
130{ 130{
131 int autosuspend_delay; 131 int autosuspend_delay;
132 u64 last_busy, expires = 0; 132 u64 last_busy, expires = 0;
133 u64 now = ktime_to_ns(ktime_get()); 133 u64 now = ktime_get_mono_fast_ns();
134 134
135 if (!dev->power.use_autosuspend) 135 if (!dev->power.use_autosuspend)
136 goto out; 136 goto out;
@@ -141,7 +141,7 @@ u64 pm_runtime_autosuspend_expiration(struct device *dev)
141 141
142 last_busy = READ_ONCE(dev->power.last_busy); 142 last_busy = READ_ONCE(dev->power.last_busy);
143 143
144 expires = last_busy + autosuspend_delay * NSEC_PER_MSEC; 144 expires = last_busy + (u64)autosuspend_delay * NSEC_PER_MSEC;
145 if (expires <= now) 145 if (expires <= now)
146 expires = 0; /* Already expired. */ 146 expires = 0; /* Already expired. */
147 147
@@ -525,7 +525,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
525 * We add a slack of 25% to gather wakeups 525 * We add a slack of 25% to gather wakeups
526 * without sacrificing the granularity. 526 * without sacrificing the granularity.
527 */ 527 */
528 u64 slack = READ_ONCE(dev->power.autosuspend_delay) * 528 u64 slack = (u64)READ_ONCE(dev->power.autosuspend_delay) *
529 (NSEC_PER_MSEC >> 2); 529 (NSEC_PER_MSEC >> 2);
530 530
531 dev->power.timer_expires = expires; 531 dev->power.timer_expires = expires;
@@ -905,8 +905,11 @@ static enum hrtimer_restart pm_suspend_timer_fn(struct hrtimer *timer)
905 spin_lock_irqsave(&dev->power.lock, flags); 905 spin_lock_irqsave(&dev->power.lock, flags);
906 906
907 expires = dev->power.timer_expires; 907 expires = dev->power.timer_expires;
908 /* If 'expire' is after 'jiffies' we've been called too early. */ 908 /*
909 if (expires > 0 && expires < ktime_to_ns(ktime_get())) { 909 * If 'expires' is after the current time, we've been called
910 * too early.
911 */
912 if (expires > 0 && expires < ktime_get_mono_fast_ns()) {
910 dev->power.timer_expires = 0; 913 dev->power.timer_expires = 0;
911 rpm_suspend(dev, dev->power.timer_autosuspends ? 914 rpm_suspend(dev, dev->power.timer_autosuspends ?
912 (RPM_ASYNC | RPM_AUTO) : RPM_ASYNC); 915 (RPM_ASYNC | RPM_AUTO) : RPM_ASYNC);
@@ -925,7 +928,7 @@ static enum hrtimer_restart pm_suspend_timer_fn(struct hrtimer *timer)
925int pm_schedule_suspend(struct device *dev, unsigned int delay) 928int pm_schedule_suspend(struct device *dev, unsigned int delay)
926{ 929{
927 unsigned long flags; 930 unsigned long flags;
928 ktime_t expires; 931 u64 expires;
929 int retval; 932 int retval;
930 933
931 spin_lock_irqsave(&dev->power.lock, flags); 934 spin_lock_irqsave(&dev->power.lock, flags);
@@ -942,8 +945,8 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)
942 /* Other scheduled or pending requests need to be canceled. */ 945 /* Other scheduled or pending requests need to be canceled. */
943 pm_runtime_cancel_pending(dev); 946 pm_runtime_cancel_pending(dev);
944 947
945 expires = ktime_add(ktime_get(), ms_to_ktime(delay)); 948 expires = ktime_get_mono_fast_ns() + (u64)delay * NSEC_PER_MSEC;
946 dev->power.timer_expires = ktime_to_ns(expires); 949 dev->power.timer_expires = expires;
947 dev->power.timer_autosuspends = 0; 950 dev->power.timer_autosuspends = 0;
948 hrtimer_start(&dev->power.suspend_timer, expires, HRTIMER_MODE_ABS); 951 hrtimer_start(&dev->power.suspend_timer, expires, HRTIMER_MODE_ABS);
949 952