mirror of https://gitee.com/openkylin/linux.git
Merge back PM core material for v4.18.
This commit is contained in:
commit
21c73367fc
|
@ -161,3 +161,6 @@ extern void device_links_driver_cleanup(struct device *dev);
|
|||
extern void device_links_no_driver(struct device *dev);
|
||||
extern bool device_links_busy(struct device *dev);
|
||||
extern void device_links_unbind_consumers(struct device *dev);
|
||||
|
||||
/* device pm support */
|
||||
void device_pm_move_to_tail(struct device *dev);
|
||||
|
|
|
@ -144,6 +144,26 @@ static int device_reorder_to_tail(struct device *dev, void *not_used)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* device_pm_move_to_tail - Move set of devices to the end of device lists
|
||||
* @dev: Device to move
|
||||
*
|
||||
* This is a device_reorder_to_tail() wrapper taking the requisite locks.
|
||||
*
|
||||
* It moves the @dev along with all of its children and all of its consumers
|
||||
* to the ends of the device_kset and dpm_list, recursively.
|
||||
*/
|
||||
void device_pm_move_to_tail(struct device *dev)
|
||||
{
|
||||
int idx;
|
||||
|
||||
idx = device_links_read_lock();
|
||||
device_pm_lock();
|
||||
device_reorder_to_tail(dev, NULL);
|
||||
device_pm_unlock();
|
||||
device_links_read_unlock(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* device_link_add - Create a link between two devices.
|
||||
* @consumer: Consumer end of the link.
|
||||
|
|
|
@ -122,9 +122,7 @@ static void deferred_probe_work_func(struct work_struct *work)
|
|||
* the list is a good order for suspend but deferred
|
||||
* probe makes that very unsafe.
|
||||
*/
|
||||
device_pm_lock();
|
||||
device_pm_move_last(dev);
|
||||
device_pm_unlock();
|
||||
device_pm_move_to_tail(dev);
|
||||
|
||||
dev_dbg(dev, "Retrying from deferred list\n");
|
||||
if (initcall_debug && !initcalls_done)
|
||||
|
|
|
@ -192,34 +192,31 @@ void device_pm_move_last(struct device *dev)
|
|||
list_move_tail(&dev->power.entry, &dpm_list);
|
||||
}
|
||||
|
||||
static ktime_t initcall_debug_start(struct device *dev)
|
||||
static ktime_t initcall_debug_start(struct device *dev, void *cb)
|
||||
{
|
||||
ktime_t calltime = 0;
|
||||
if (!pm_print_times_enabled)
|
||||
return 0;
|
||||
|
||||
if (pm_print_times_enabled) {
|
||||
pr_info("calling %s+ @ %i, parent: %s\n",
|
||||
dev_name(dev), task_pid_nr(current),
|
||||
dev->parent ? dev_name(dev->parent) : "none");
|
||||
calltime = ktime_get();
|
||||
}
|
||||
|
||||
return calltime;
|
||||
dev_info(dev, "calling %pF @ %i, parent: %s\n", cb,
|
||||
task_pid_nr(current),
|
||||
dev->parent ? dev_name(dev->parent) : "none");
|
||||
return ktime_get();
|
||||
}
|
||||
|
||||
static void initcall_debug_report(struct device *dev, ktime_t calltime,
|
||||
int error, pm_message_t state,
|
||||
const char *info)
|
||||
void *cb, int error)
|
||||
{
|
||||
ktime_t rettime;
|
||||
s64 nsecs;
|
||||
|
||||
if (!pm_print_times_enabled)
|
||||
return;
|
||||
|
||||
rettime = ktime_get();
|
||||
nsecs = (s64) ktime_to_ns(ktime_sub(rettime, calltime));
|
||||
|
||||
if (pm_print_times_enabled) {
|
||||
pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
|
||||
error, (unsigned long long)nsecs >> 10);
|
||||
}
|
||||
dev_info(dev, "%pF returned %d after %Ld usecs\n", cb, error,
|
||||
(unsigned long long)nsecs >> 10);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -446,7 +443,7 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev,
|
|||
if (!cb)
|
||||
return 0;
|
||||
|
||||
calltime = initcall_debug_start(dev);
|
||||
calltime = initcall_debug_start(dev, cb);
|
||||
|
||||
pm_dev_dbg(dev, state, info);
|
||||
trace_device_pm_callback_start(dev, info, state.event);
|
||||
|
@ -454,7 +451,7 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev,
|
|||
trace_device_pm_callback_end(dev, error);
|
||||
suspend_report_result(cb, error);
|
||||
|
||||
initcall_debug_report(dev, calltime, error, state, info);
|
||||
initcall_debug_report(dev, calltime, cb, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -1664,14 +1661,14 @@ static int legacy_suspend(struct device *dev, pm_message_t state,
|
|||
int error;
|
||||
ktime_t calltime;
|
||||
|
||||
calltime = initcall_debug_start(dev);
|
||||
calltime = initcall_debug_start(dev, cb);
|
||||
|
||||
trace_device_pm_callback_start(dev, info, state.event);
|
||||
error = cb(dev, state);
|
||||
trace_device_pm_callback_end(dev, error);
|
||||
suspend_report_result(cb, error);
|
||||
|
||||
initcall_debug_report(dev, calltime, error, state, info);
|
||||
initcall_debug_report(dev, calltime, cb, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -56,14 +56,6 @@ static inline void device_wakeup_detach_irq(struct device *dev)
|
|||
{
|
||||
}
|
||||
|
||||
static inline void device_wakeup_arm_wake_irqs(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void device_wakeup_disarm_wake_irqs(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
/*
|
||||
|
@ -95,28 +87,6 @@ static inline void pm_runtime_remove(struct device *dev) {}
|
|||
|
||||
static inline int dpm_sysfs_add(struct device *dev) { return 0; }
|
||||
static inline void dpm_sysfs_remove(struct device *dev) {}
|
||||
static inline void rpm_sysfs_remove(struct device *dev) {}
|
||||
static inline int wakeup_sysfs_add(struct device *dev) { return 0; }
|
||||
static inline void wakeup_sysfs_remove(struct device *dev) {}
|
||||
static inline int pm_qos_sysfs_add(struct device *dev) { return 0; }
|
||||
static inline void pm_qos_sysfs_remove(struct device *dev) {}
|
||||
|
||||
static inline void dev_pm_arm_wake_irq(struct wake_irq *wirq)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void dev_pm_enable_wake_irq_check(struct device *dev,
|
||||
bool can_change_status)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void dev_pm_disable_wake_irq_check(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -183,7 +183,6 @@ void wakeup_source_add(struct wakeup_source *ws)
|
|||
spin_lock_init(&ws->lock);
|
||||
timer_setup(&ws->timer, pm_wakeup_timer_fn, 0);
|
||||
ws->active = false;
|
||||
ws->last_time = ktime_get();
|
||||
|
||||
spin_lock_irqsave(&events_lock, flags);
|
||||
list_add_rcu(&ws->entry, &wakeup_sources);
|
||||
|
@ -854,7 +853,7 @@ bool pm_wakeup_pending(void)
|
|||
spin_unlock_irqrestore(&events_lock, flags);
|
||||
|
||||
if (ret) {
|
||||
pr_info("PM: Wakeup pending, aborting suspend\n");
|
||||
pr_debug("PM: Wakeup pending, aborting suspend\n");
|
||||
pm_print_active_wakeup_sources();
|
||||
}
|
||||
|
||||
|
@ -1029,32 +1028,75 @@ static int print_wakeup_source_stats(struct seq_file *m,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* wakeup_sources_stats_show - Print wakeup sources statistics information.
|
||||
* @m: seq_file to print the statistics into.
|
||||
*/
|
||||
static int wakeup_sources_stats_show(struct seq_file *m, void *unused)
|
||||
static void *wakeup_sources_stats_seq_start(struct seq_file *m,
|
||||
loff_t *pos)
|
||||
{
|
||||
struct wakeup_source *ws;
|
||||
int srcuidx;
|
||||
loff_t n = *pos;
|
||||
int *srcuidx = m->private;
|
||||
|
||||
seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
|
||||
"expire_count\tactive_since\ttotal_time\tmax_time\t"
|
||||
"last_change\tprevent_suspend_time\n");
|
||||
if (n == 0) {
|
||||
seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
|
||||
"expire_count\tactive_since\ttotal_time\tmax_time\t"
|
||||
"last_change\tprevent_suspend_time\n");
|
||||
}
|
||||
|
||||
srcuidx = srcu_read_lock(&wakeup_srcu);
|
||||
list_for_each_entry_rcu(ws, &wakeup_sources, entry)
|
||||
print_wakeup_source_stats(m, ws);
|
||||
srcu_read_unlock(&wakeup_srcu, srcuidx);
|
||||
*srcuidx = srcu_read_lock(&wakeup_srcu);
|
||||
list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
|
||||
if (n-- <= 0)
|
||||
return ws;
|
||||
}
|
||||
|
||||
print_wakeup_source_stats(m, &deleted_ws);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *wakeup_sources_stats_seq_next(struct seq_file *m,
|
||||
void *v, loff_t *pos)
|
||||
{
|
||||
struct wakeup_source *ws = v;
|
||||
struct wakeup_source *next_ws = NULL;
|
||||
|
||||
++(*pos);
|
||||
|
||||
list_for_each_entry_continue_rcu(ws, &wakeup_sources, entry) {
|
||||
next_ws = ws;
|
||||
break;
|
||||
}
|
||||
|
||||
return next_ws;
|
||||
}
|
||||
|
||||
static void wakeup_sources_stats_seq_stop(struct seq_file *m, void *v)
|
||||
{
|
||||
int *srcuidx = m->private;
|
||||
|
||||
srcu_read_unlock(&wakeup_srcu, *srcuidx);
|
||||
}
|
||||
|
||||
/**
|
||||
* wakeup_sources_stats_seq_show - Print wakeup sources statistics information.
|
||||
* @m: seq_file to print the statistics into.
|
||||
* @v: wakeup_source of each iteration
|
||||
*/
|
||||
static int wakeup_sources_stats_seq_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct wakeup_source *ws = v;
|
||||
|
||||
print_wakeup_source_stats(m, ws);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations wakeup_sources_stats_seq_ops = {
|
||||
.start = wakeup_sources_stats_seq_start,
|
||||
.next = wakeup_sources_stats_seq_next,
|
||||
.stop = wakeup_sources_stats_seq_stop,
|
||||
.show = wakeup_sources_stats_seq_show,
|
||||
};
|
||||
|
||||
static int wakeup_sources_stats_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wakeup_sources_stats_show, NULL);
|
||||
return seq_open_private(file, &wakeup_sources_stats_seq_ops, sizeof(int));
|
||||
}
|
||||
|
||||
static const struct file_operations wakeup_sources_stats_fops = {
|
||||
|
@ -1062,7 +1104,7 @@ static const struct file_operations wakeup_sources_stats_fops = {
|
|||
.open = wakeup_sources_stats_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.release = seq_release_private,
|
||||
};
|
||||
|
||||
static int __init wakeup_sources_debugfs_init(void)
|
||||
|
|
|
@ -188,6 +188,7 @@ static struct wakelock *wakelock_lookup_add(const char *name, size_t len,
|
|||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
wl->ws.name = wl->name;
|
||||
wl->ws.last_time = ktime_get();
|
||||
wakeup_source_add(&wl->ws);
|
||||
rb_link_node(&wl->node, parent, node);
|
||||
rb_insert_color(&wl->node, &wakelocks_tree);
|
||||
|
|
Loading…
Reference in New Issue