diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/power/main.c | 11 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 1 | ||||
-rw-r--r-- | drivers/base/power/wakeup.c | 54 | ||||
-rw-r--r-- | drivers/bus/omap_l3_noc.c | 4 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 2 | ||||
-rw-r--r-- | drivers/leds/led-class.c | 7 |
6 files changed, 67 insertions, 12 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 3d874ec..5528e59 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -920,9 +920,7 @@ static void device_complete(struct device *dev, pm_message_t state) if (callback) { pm_dev_dbg(dev, state, info); - trace_device_pm_callback_start(dev, info, state.event); callback(dev); - trace_device_pm_callback_end(dev, 0); } device_unlock(dev); @@ -954,7 +952,9 @@ void dpm_complete(pm_message_t state) list_move(&dev->power.entry, &list); mutex_unlock(&dpm_list_mtx); + trace_device_pm_callback_start(dev, "", state.event); device_complete(dev, state); + trace_device_pm_callback_end(dev, 0); mutex_lock(&dpm_list_mtx); put_device(dev); @@ -1585,11 +1585,8 @@ static int device_prepare(struct device *dev, pm_message_t state) callback = dev->driver->pm->prepare; } - if (callback) { - trace_device_pm_callback_start(dev, info, state.event); + if (callback) ret = callback(dev); - trace_device_pm_callback_end(dev, ret); - } device_unlock(dev); @@ -1631,7 +1628,9 @@ int dpm_prepare(pm_message_t state) get_device(dev); mutex_unlock(&dpm_list_mtx); + trace_device_pm_callback_start(dev, "", state.event); error = device_prepare(dev, state); + trace_device_pm_callback_end(dev, error); mutex_lock(&dpm_list_mtx); if (error) { diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 5070c4f..4ffe4a2 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -741,6 +741,7 @@ static int rpm_resume(struct device *dev, int rpmflags) } else { no_callback: __update_runtime_status(dev, RPM_ACTIVE); + pm_runtime_mark_last_busy(dev); if (parent) atomic_inc(&parent->power.child_count); } diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 7726200..87c2603 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -56,6 +56,11 @@ static LIST_HEAD(wakeup_sources); static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue); +static struct wakeup_source deleted_ws = { + .name = "deleted", + .lock = __SPIN_LOCK_UNLOCKED(deleted_ws.lock), +}; + /** * wakeup_source_prepare - Prepare a new wakeup source for initialization. * @ws: Wakeup source to prepare. @@ -107,6 +112,34 @@ void wakeup_source_drop(struct wakeup_source *ws) } EXPORT_SYMBOL_GPL(wakeup_source_drop); +/* + * Record wakeup_source statistics being deleted into a dummy wakeup_source. + */ +static void wakeup_source_record(struct wakeup_source *ws) +{ + unsigned long flags; + + spin_lock_irqsave(&deleted_ws.lock, flags); + + if (ws->event_count) { + deleted_ws.total_time = + ktime_add(deleted_ws.total_time, ws->total_time); + deleted_ws.prevent_sleep_time = + ktime_add(deleted_ws.prevent_sleep_time, + ws->prevent_sleep_time); + deleted_ws.max_time = + ktime_compare(deleted_ws.max_time, ws->max_time) > 0 ? + deleted_ws.max_time : ws->max_time; + deleted_ws.event_count += ws->event_count; + deleted_ws.active_count += ws->active_count; + deleted_ws.relax_count += ws->relax_count; + deleted_ws.expire_count += ws->expire_count; + deleted_ws.wakeup_count += ws->wakeup_count; + } + + spin_unlock_irqrestore(&deleted_ws.lock, flags); +} + /** * wakeup_source_destroy - Destroy a struct wakeup_source object. * @ws: Wakeup source to destroy. @@ -119,6 +152,7 @@ void wakeup_source_destroy(struct wakeup_source *ws) return; wakeup_source_drop(ws); + wakeup_source_record(ws); kfree(ws->name); kfree(ws); } @@ -351,6 +385,20 @@ int device_set_wakeup_enable(struct device *dev, bool enable) } EXPORT_SYMBOL_GPL(device_set_wakeup_enable); +/** + * wakeup_source_not_registered - validate the given wakeup source. + * @ws: Wakeup source to be validated. + */ +static bool wakeup_source_not_registered(struct wakeup_source *ws) +{ + /* + * Use timer struct to check if the given source is initialized + * by wakeup_source_add. + */ + return ws->timer.function != pm_wakeup_timer_fn || + ws->timer.data != (unsigned long)ws; +} + /* * The functions below use the observation that each wakeup event starts a * period in which the system should not be suspended. The moment this period @@ -391,6 +439,10 @@ static void wakeup_source_activate(struct wakeup_source *ws) { unsigned int cec; + if (WARN_ONCE(wakeup_source_not_registered(ws), + "unregistered wakeup source\n")) + return; + /* * active wakeup source should bring the system * out of PM_SUSPEND_FREEZE state @@ -894,6 +946,8 @@ static int wakeup_sources_stats_show(struct seq_file *m, void *unused) print_wakeup_source_stats(m, ws); rcu_read_unlock(); + print_wakeup_source_stats(m, &deleted_ws); + return 0; } diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c index ebee57d..5012e3a 100644 --- a/drivers/bus/omap_l3_noc.c +++ b/drivers/bus/omap_l3_noc.c @@ -301,7 +301,7 @@ static int omap_l3_probe(struct platform_device *pdev) return ret; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP /** * l3_resume_noirq() - resume function for l3_noc @@ -347,7 +347,7 @@ static int l3_resume_noirq(struct device *dev) } static const struct dev_pm_ops l3_dev_pm_ops = { - .resume_noirq = l3_resume_noirq, + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, l3_resume_noirq) }; #define L3_DEV_PM_OPS (&l3_dev_pm_ops) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 7f1b8f5..e8e2775 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -97,6 +97,7 @@ static int find_deepest_state(struct cpuidle_driver *drv, return ret; } +#ifdef CONFIG_SUSPEND /** * cpuidle_find_deepest_state - Find the deepest available idle state. * @drv: cpuidle driver for the given CPU. @@ -150,6 +151,7 @@ int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev) return index; } +#endif /* CONFIG_SUSPEND */ /** * cpuidle_enter_state - enter the state and update stats diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 728681d..7fb2a19 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -187,6 +187,7 @@ void led_classdev_resume(struct led_classdev *led_cdev) } EXPORT_SYMBOL_GPL(led_classdev_resume); +#ifdef CONFIG_PM_SLEEP static int led_suspend(struct device *dev) { struct led_classdev *led_cdev = dev_get_drvdata(dev); @@ -206,11 +207,9 @@ static int led_resume(struct device *dev) return 0; } +#endif -static const struct dev_pm_ops leds_class_dev_pm_ops = { - .suspend = led_suspend, - .resume = led_resume, -}; +static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume); static int match_name(struct device *dev, const void *data) { |