Skip to content

Commit f1c7d00

Browse files
committed
Merge branches 'pm-qos' and 'pm-core'
* pm-qos: PM / QoS: Drop redundant declaration of pm_qos_get_value() * pm-core: PM / runtime: Drop usage count for suppliers at device link removal PM / runtime: Fixup reference counting of device link suppliers at probe PM: wakeup: Use pr_debug() for the "aborting suspend" message PM / core: Drop unused internal inline functions for sysfs PM / core: Drop unused internal functions for pm_qos sysfs PM / core: Drop unused internal inline functions for wakeirqs PM / core: Drop internal unused inline functions for wakeups PM / wakeup: Only update last time for active wakeup sources PM / wakeup: Use seq_open() to show wakeup stats PM / core: Use dev_printk() and symbols in suspend/resume diagnostics PM / core: Simplify initcall_debug_report() timing PM / core: Remove unused initcall_debug_report() arguments PM / core: fix deferred probe breaking suspend resume order
3 parents 9b34ffa + 74cd817 + a0504ae commit f1c7d00

File tree

10 files changed

+110
-102
lines changed

10 files changed

+110
-102
lines changed

drivers/base/base.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,6 @@ extern void device_links_driver_cleanup(struct device *dev);
161161
extern void device_links_no_driver(struct device *dev);
162162
extern bool device_links_busy(struct device *dev);
163163
extern void device_links_unbind_consumers(struct device *dev);
164+
165+
/* device pm support */
166+
void device_pm_move_to_tail(struct device *dev);

drivers/base/core.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,26 @@ static int device_reorder_to_tail(struct device *dev, void *not_used)
144144
return 0;
145145
}
146146

147+
/**
148+
* device_pm_move_to_tail - Move set of devices to the end of device lists
149+
* @dev: Device to move
150+
*
151+
* This is a device_reorder_to_tail() wrapper taking the requisite locks.
152+
*
153+
* It moves the @dev along with all of its children and all of its consumers
154+
* to the ends of the device_kset and dpm_list, recursively.
155+
*/
156+
void device_pm_move_to_tail(struct device *dev)
157+
{
158+
int idx;
159+
160+
idx = device_links_read_lock();
161+
device_pm_lock();
162+
device_reorder_to_tail(dev, NULL);
163+
device_pm_unlock();
164+
device_links_read_unlock(idx);
165+
}
166+
147167
/**
148168
* device_link_add - Create a link between two devices.
149169
* @consumer: Consumer end of the link.

drivers/base/dd.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,7 @@ static void deferred_probe_work_func(struct work_struct *work)
122122
* the list is a good order for suspend but deferred
123123
* probe makes that very unsafe.
124124
*/
125-
device_pm_lock();
126-
device_pm_move_last(dev);
127-
device_pm_unlock();
125+
device_pm_move_to_tail(dev);
128126

129127
dev_dbg(dev, "Retrying from deferred list\n");
130128
if (initcall_debug && !initcalls_done)
@@ -582,7 +580,7 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
582580
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
583581
drv->bus->name, __func__, dev_name(dev), drv->name);
584582

585-
pm_runtime_get_suppliers(dev);
583+
pm_runtime_resume_suppliers(dev);
586584
if (dev->parent)
587585
pm_runtime_get_sync(dev->parent);
588586

@@ -593,7 +591,6 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
593591
if (dev->parent)
594592
pm_runtime_put(dev->parent);
595593

596-
pm_runtime_put_suppliers(dev);
597594
return ret;
598595
}
599596

drivers/base/power/main.c

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -192,34 +192,31 @@ void device_pm_move_last(struct device *dev)
192192
list_move_tail(&dev->power.entry, &dpm_list);
193193
}
194194

195-
static ktime_t initcall_debug_start(struct device *dev)
195+
static ktime_t initcall_debug_start(struct device *dev, void *cb)
196196
{
197-
ktime_t calltime = 0;
198-
199-
if (pm_print_times_enabled) {
200-
pr_info("calling %s+ @ %i, parent: %s\n",
201-
dev_name(dev), task_pid_nr(current),
202-
dev->parent ? dev_name(dev->parent) : "none");
203-
calltime = ktime_get();
204-
}
197+
if (!pm_print_times_enabled)
198+
return 0;
205199

206-
return calltime;
200+
dev_info(dev, "calling %pF @ %i, parent: %s\n", cb,
201+
task_pid_nr(current),
202+
dev->parent ? dev_name(dev->parent) : "none");
203+
return ktime_get();
207204
}
208205

209206
static void initcall_debug_report(struct device *dev, ktime_t calltime,
210-
int error, pm_message_t state,
211-
const char *info)
207+
void *cb, int error)
212208
{
213209
ktime_t rettime;
214210
s64 nsecs;
215211

212+
if (!pm_print_times_enabled)
213+
return;
214+
216215
rettime = ktime_get();
217216
nsecs = (s64) ktime_to_ns(ktime_sub(rettime, calltime));
218217

219-
if (pm_print_times_enabled) {
220-
pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
221-
error, (unsigned long long)nsecs >> 10);
222-
}
218+
dev_info(dev, "%pF returned %d after %Ld usecs\n", cb, error,
219+
(unsigned long long)nsecs >> 10);
223220
}
224221

225222
/**
@@ -446,15 +443,15 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev,
446443
if (!cb)
447444
return 0;
448445

449-
calltime = initcall_debug_start(dev);
446+
calltime = initcall_debug_start(dev, cb);
450447

451448
pm_dev_dbg(dev, state, info);
452449
trace_device_pm_callback_start(dev, info, state.event);
453450
error = cb(dev);
454451
trace_device_pm_callback_end(dev, error);
455452
suspend_report_result(cb, error);
456453

457-
initcall_debug_report(dev, calltime, error, state, info);
454+
initcall_debug_report(dev, calltime, cb, error);
458455

459456
return error;
460457
}
@@ -1664,14 +1661,14 @@ static int legacy_suspend(struct device *dev, pm_message_t state,
16641661
int error;
16651662
ktime_t calltime;
16661663

1667-
calltime = initcall_debug_start(dev);
1664+
calltime = initcall_debug_start(dev, cb);
16681665

16691666
trace_device_pm_callback_start(dev, info, state.event);
16701667
error = cb(dev, state);
16711668
trace_device_pm_callback_end(dev, error);
16721669
suspend_report_result(cb, error);
16731670

1674-
initcall_debug_report(dev, calltime, error, state, info);
1671+
initcall_debug_report(dev, calltime, cb, error);
16751672

16761673
return error;
16771674
}

drivers/base/power/power.h

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,6 @@ static inline void device_wakeup_detach_irq(struct device *dev)
5656
{
5757
}
5858

59-
static inline void device_wakeup_arm_wake_irqs(void)
60-
{
61-
}
62-
63-
static inline void device_wakeup_disarm_wake_irqs(void)
64-
{
65-
}
66-
6759
#endif /* CONFIG_PM_SLEEP */
6860

6961
/*
@@ -95,28 +87,6 @@ static inline void pm_runtime_remove(struct device *dev) {}
9587

9688
static inline int dpm_sysfs_add(struct device *dev) { return 0; }
9789
static inline void dpm_sysfs_remove(struct device *dev) {}
98-
static inline void rpm_sysfs_remove(struct device *dev) {}
99-
static inline int wakeup_sysfs_add(struct device *dev) { return 0; }
100-
static inline void wakeup_sysfs_remove(struct device *dev) {}
101-
static inline int pm_qos_sysfs_add(struct device *dev) { return 0; }
102-
static inline void pm_qos_sysfs_remove(struct device *dev) {}
103-
104-
static inline void dev_pm_arm_wake_irq(struct wake_irq *wirq)
105-
{
106-
}
107-
108-
static inline void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
109-
{
110-
}
111-
112-
static inline void dev_pm_enable_wake_irq_check(struct device *dev,
113-
bool can_change_status)
114-
{
115-
}
116-
117-
static inline void dev_pm_disable_wake_irq_check(struct device *dev)
118-
{
119-
}
12090

12191
#endif
12292

drivers/base/power/runtime.c

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,37 +1563,16 @@ void pm_runtime_clean_up_links(struct device *dev)
15631563
}
15641564

15651565
/**
1566-
* pm_runtime_get_suppliers - Resume and reference-count supplier devices.
1566+
* pm_runtime_resume_suppliers - Resume supplier devices.
15671567
* @dev: Consumer device.
15681568
*/
1569-
void pm_runtime_get_suppliers(struct device *dev)
1569+
void pm_runtime_resume_suppliers(struct device *dev)
15701570
{
1571-
struct device_link *link;
1572-
int idx;
1573-
1574-
idx = device_links_read_lock();
1575-
1576-
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
1577-
if (link->flags & DL_FLAG_PM_RUNTIME)
1578-
pm_runtime_get_sync(link->supplier);
1579-
1580-
device_links_read_unlock(idx);
1581-
}
1582-
1583-
/**
1584-
* pm_runtime_put_suppliers - Drop references to supplier devices.
1585-
* @dev: Consumer device.
1586-
*/
1587-
void pm_runtime_put_suppliers(struct device *dev)
1588-
{
1589-
struct device_link *link;
15901571
int idx;
15911572

15921573
idx = device_links_read_lock();
15931574

1594-
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
1595-
if (link->flags & DL_FLAG_PM_RUNTIME)
1596-
pm_runtime_put(link->supplier);
1575+
rpm_get_suppliers(dev);
15971576

15981577
device_links_read_unlock(idx);
15991578
}
@@ -1607,6 +1586,8 @@ void pm_runtime_new_link(struct device *dev)
16071586

16081587
void pm_runtime_drop_link(struct device *dev)
16091588
{
1589+
rpm_put_suppliers(dev);
1590+
16101591
spin_lock_irq(&dev->power.lock);
16111592
WARN_ON(dev->power.links_count == 0);
16121593
dev->power.links_count--;

drivers/base/power/wakeup.c

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ void wakeup_source_add(struct wakeup_source *ws)
183183
spin_lock_init(&ws->lock);
184184
timer_setup(&ws->timer, pm_wakeup_timer_fn, 0);
185185
ws->active = false;
186-
ws->last_time = ktime_get();
187186

188187
spin_lock_irqsave(&events_lock, flags);
189188
list_add_rcu(&ws->entry, &wakeup_sources);
@@ -854,7 +853,7 @@ bool pm_wakeup_pending(void)
854853
spin_unlock_irqrestore(&events_lock, flags);
855854

856855
if (ret) {
857-
pr_info("PM: Wakeup pending, aborting suspend\n");
856+
pr_debug("PM: Wakeup pending, aborting suspend\n");
858857
pm_print_active_wakeup_sources();
859858
}
860859

@@ -1029,40 +1028,83 @@ static int print_wakeup_source_stats(struct seq_file *m,
10291028
return 0;
10301029
}
10311030

1032-
/**
1033-
* wakeup_sources_stats_show - Print wakeup sources statistics information.
1034-
* @m: seq_file to print the statistics into.
1035-
*/
1036-
static int wakeup_sources_stats_show(struct seq_file *m, void *unused)
1031+
static void *wakeup_sources_stats_seq_start(struct seq_file *m,
1032+
loff_t *pos)
10371033
{
10381034
struct wakeup_source *ws;
1039-
int srcuidx;
1035+
loff_t n = *pos;
1036+
int *srcuidx = m->private;
10401037

1041-
seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
1042-
"expire_count\tactive_since\ttotal_time\tmax_time\t"
1043-
"last_change\tprevent_suspend_time\n");
1038+
if (n == 0) {
1039+
seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
1040+
"expire_count\tactive_since\ttotal_time\tmax_time\t"
1041+
"last_change\tprevent_suspend_time\n");
1042+
}
10441043

1045-
srcuidx = srcu_read_lock(&wakeup_srcu);
1046-
list_for_each_entry_rcu(ws, &wakeup_sources, entry)
1047-
print_wakeup_source_stats(m, ws);
1048-
srcu_read_unlock(&wakeup_srcu, srcuidx);
1044+
*srcuidx = srcu_read_lock(&wakeup_srcu);
1045+
list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
1046+
if (n-- <= 0)
1047+
return ws;
1048+
}
1049+
1050+
return NULL;
1051+
}
1052+
1053+
static void *wakeup_sources_stats_seq_next(struct seq_file *m,
1054+
void *v, loff_t *pos)
1055+
{
1056+
struct wakeup_source *ws = v;
1057+
struct wakeup_source *next_ws = NULL;
10491058

1050-
print_wakeup_source_stats(m, &deleted_ws);
1059+
++(*pos);
1060+
1061+
list_for_each_entry_continue_rcu(ws, &wakeup_sources, entry) {
1062+
next_ws = ws;
1063+
break;
1064+
}
1065+
1066+
return next_ws;
1067+
}
1068+
1069+
static void wakeup_sources_stats_seq_stop(struct seq_file *m, void *v)
1070+
{
1071+
int *srcuidx = m->private;
1072+
1073+
srcu_read_unlock(&wakeup_srcu, *srcuidx);
1074+
}
1075+
1076+
/**
1077+
* wakeup_sources_stats_seq_show - Print wakeup sources statistics information.
1078+
* @m: seq_file to print the statistics into.
1079+
* @v: wakeup_source of each iteration
1080+
*/
1081+
static int wakeup_sources_stats_seq_show(struct seq_file *m, void *v)
1082+
{
1083+
struct wakeup_source *ws = v;
1084+
1085+
print_wakeup_source_stats(m, ws);
10511086

10521087
return 0;
10531088
}
10541089

1090+
static const struct seq_operations wakeup_sources_stats_seq_ops = {
1091+
.start = wakeup_sources_stats_seq_start,
1092+
.next = wakeup_sources_stats_seq_next,
1093+
.stop = wakeup_sources_stats_seq_stop,
1094+
.show = wakeup_sources_stats_seq_show,
1095+
};
1096+
10551097
static int wakeup_sources_stats_open(struct inode *inode, struct file *file)
10561098
{
1057-
return single_open(file, wakeup_sources_stats_show, NULL);
1099+
return seq_open_private(file, &wakeup_sources_stats_seq_ops, sizeof(int));
10581100
}
10591101

10601102
static const struct file_operations wakeup_sources_stats_fops = {
10611103
.owner = THIS_MODULE,
10621104
.open = wakeup_sources_stats_open,
10631105
.read = seq_read,
10641106
.llseek = seq_lseek,
1065-
.release = single_release,
1107+
.release = seq_release_private,
10661108
};
10671109

10681110
static int __init wakeup_sources_debugfs_init(void)

include/linux/pm_runtime.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ extern void pm_runtime_update_max_time_suspended(struct device *dev,
5656
s64 delta_ns);
5757
extern void pm_runtime_set_memalloc_noio(struct device *dev, bool enable);
5858
extern void pm_runtime_clean_up_links(struct device *dev);
59-
extern void pm_runtime_get_suppliers(struct device *dev);
60-
extern void pm_runtime_put_suppliers(struct device *dev);
59+
extern void pm_runtime_resume_suppliers(struct device *dev);
6160
extern void pm_runtime_new_link(struct device *dev);
6261
extern void pm_runtime_drop_link(struct device *dev);
6362

@@ -173,8 +172,7 @@ static inline unsigned long pm_runtime_autosuspend_expiration(
173172
static inline void pm_runtime_set_memalloc_noio(struct device *dev,
174173
bool enable){}
175174
static inline void pm_runtime_clean_up_links(struct device *dev) {}
176-
static inline void pm_runtime_get_suppliers(struct device *dev) {}
177-
static inline void pm_runtime_put_suppliers(struct device *dev) {}
175+
static inline void pm_runtime_resume_suppliers(struct device *dev) {}
178176
static inline void pm_runtime_new_link(struct device *dev) {}
179177
static inline void pm_runtime_drop_link(struct device *dev) {}
180178

kernel/power/qos.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ static inline void pm_qos_set_value(struct pm_qos_constraints *c, s32 value)
184184
c->target_value = value;
185185
}
186186

187-
static inline int pm_qos_get_value(struct pm_qos_constraints *c);
188187
static int pm_qos_dbg_show_requests(struct seq_file *s, void *unused)
189188
{
190189
struct pm_qos_object *qos = (struct pm_qos_object *)s->private;

kernel/power/wakelock.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ static struct wakelock *wakelock_lookup_add(const char *name, size_t len,
188188
return ERR_PTR(-ENOMEM);
189189
}
190190
wl->ws.name = wl->name;
191+
wl->ws.last_time = ktime_get();
191192
wakeup_source_add(&wl->ws);
192193
rb_link_node(&wl->node, parent, node);
193194
rb_insert_color(&wl->node, &wakelocks_tree);

0 commit comments

Comments
 (0)