Merge back earlier PM core material for v5.1.
This commit is contained in:
@@ -66,20 +66,30 @@ static int rpm_suspend(struct device *dev, int rpmflags);
|
||||
*/
|
||||
void update_pm_runtime_accounting(struct device *dev)
|
||||
{
|
||||
unsigned long now = jiffies;
|
||||
unsigned long delta;
|
||||
|
||||
delta = now - dev->power.accounting_timestamp;
|
||||
|
||||
dev->power.accounting_timestamp = now;
|
||||
u64 now, last, delta;
|
||||
|
||||
if (dev->power.disable_depth > 0)
|
||||
return;
|
||||
|
||||
last = dev->power.accounting_timestamp;
|
||||
|
||||
now = ktime_get_mono_fast_ns();
|
||||
dev->power.accounting_timestamp = now;
|
||||
|
||||
/*
|
||||
* Because ktime_get_mono_fast_ns() is not monotonic during
|
||||
* timekeeping updates, ensure that 'now' is after the last saved
|
||||
* timesptamp.
|
||||
*/
|
||||
if (now < last)
|
||||
return;
|
||||
|
||||
delta = now - last;
|
||||
|
||||
if (dev->power.runtime_status == RPM_SUSPENDED)
|
||||
dev->power.suspended_jiffies += delta;
|
||||
dev->power.suspended_time += delta;
|
||||
else
|
||||
dev->power.active_jiffies += delta;
|
||||
dev->power.active_time += delta;
|
||||
}
|
||||
|
||||
static void __update_runtime_status(struct device *dev, enum rpm_status status)
|
||||
@@ -88,6 +98,22 @@ static void __update_runtime_status(struct device *dev, enum rpm_status status)
|
||||
dev->power.runtime_status = status;
|
||||
}
|
||||
|
||||
u64 pm_runtime_suspended_time(struct device *dev)
|
||||
{
|
||||
u64 time;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->power.lock, flags);
|
||||
|
||||
update_pm_runtime_accounting(dev);
|
||||
time = dev->power.suspended_time;
|
||||
|
||||
spin_unlock_irqrestore(&dev->power.lock, flags);
|
||||
|
||||
return time;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm_runtime_suspended_time);
|
||||
|
||||
/**
|
||||
* pm_runtime_deactivate_timer - Deactivate given device's suspend timer.
|
||||
* @dev: Device to handle.
|
||||
@@ -129,24 +155,21 @@ static void pm_runtime_cancel_pending(struct device *dev)
|
||||
u64 pm_runtime_autosuspend_expiration(struct device *dev)
|
||||
{
|
||||
int autosuspend_delay;
|
||||
u64 last_busy, expires = 0;
|
||||
u64 now = ktime_get_mono_fast_ns();
|
||||
u64 expires;
|
||||
|
||||
if (!dev->power.use_autosuspend)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
autosuspend_delay = READ_ONCE(dev->power.autosuspend_delay);
|
||||
if (autosuspend_delay < 0)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
last_busy = READ_ONCE(dev->power.last_busy);
|
||||
expires = READ_ONCE(dev->power.last_busy);
|
||||
expires += (u64)autosuspend_delay * NSEC_PER_MSEC;
|
||||
if (expires > ktime_get_mono_fast_ns())
|
||||
return expires; /* Expires in the future */
|
||||
|
||||
expires = last_busy + (u64)autosuspend_delay * NSEC_PER_MSEC;
|
||||
if (expires <= now)
|
||||
expires = 0; /* Already expired. */
|
||||
|
||||
out:
|
||||
return expires;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm_runtime_autosuspend_expiration);
|
||||
|
||||
@@ -1276,6 +1299,9 @@ void __pm_runtime_disable(struct device *dev, bool check_resume)
|
||||
pm_runtime_put_noidle(dev);
|
||||
}
|
||||
|
||||
/* Update time accounting before disabling PM-runtime. */
|
||||
update_pm_runtime_accounting(dev);
|
||||
|
||||
if (!dev->power.disable_depth++)
|
||||
__pm_runtime_barrier(dev);
|
||||
|
||||
@@ -1294,10 +1320,15 @@ void pm_runtime_enable(struct device *dev)
|
||||
|
||||
spin_lock_irqsave(&dev->power.lock, flags);
|
||||
|
||||
if (dev->power.disable_depth > 0)
|
||||
if (dev->power.disable_depth > 0) {
|
||||
dev->power.disable_depth--;
|
||||
else
|
||||
|
||||
/* About to enable runtime pm, set accounting_timestamp to now */
|
||||
if (!dev->power.disable_depth)
|
||||
dev->power.accounting_timestamp = ktime_get_mono_fast_ns();
|
||||
} else {
|
||||
dev_warn(dev, "Unbalanced %s!\n", __func__);
|
||||
}
|
||||
|
||||
WARN(!dev->power.disable_depth &&
|
||||
dev->power.runtime_status == RPM_SUSPENDED &&
|
||||
@@ -1494,7 +1525,6 @@ void pm_runtime_init(struct device *dev)
|
||||
dev->power.request_pending = false;
|
||||
dev->power.request = RPM_REQ_NONE;
|
||||
dev->power.deferred_resume = false;
|
||||
dev->power.accounting_timestamp = jiffies;
|
||||
INIT_WORK(&dev->power.work, pm_runtime_work);
|
||||
|
||||
dev->power.timer_expires = 0;
|
||||
|
Reference in New Issue
Block a user