Skip to content

Commit 8a3cbdd

Browse files
committed
Merge tag 'pm-5.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These fix an issue related to device links in the runtime PM framework and debugfs usage in the Energy Model code. Specifics: - Modify the runtime PM device suspend to avoid suspending supplier devices before the consumer device's status changes to RPM_SUSPENDED (Rafael Wysocki) - Change the Energy Model code to prevent it from attempting to create its main debugfs directory too early (Lukasz Luba)" * tag 'pm-5.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM: EM: postpone creating the debugfs dir till fs_initcall PM: runtime: Defer suspending suppliers
2 parents eb3991e + 6f3a283 commit 8a3cbdd

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

drivers/base/power/runtime.c

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,18 +305,38 @@ static int rpm_get_suppliers(struct device *dev)
305305
return 0;
306306
}
307307

308-
static void rpm_put_suppliers(struct device *dev)
308+
static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend)
309309
{
310310
struct device_link *link;
311311

312312
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
313313
device_links_read_lock_held()) {
314314

315315
while (refcount_dec_not_one(&link->rpm_active))
316-
pm_runtime_put(link->supplier);
316+
pm_runtime_put_noidle(link->supplier);
317+
318+
if (try_to_suspend)
319+
pm_request_idle(link->supplier);
317320
}
318321
}
319322

323+
static void rpm_put_suppliers(struct device *dev)
324+
{
325+
__rpm_put_suppliers(dev, true);
326+
}
327+
328+
static void rpm_suspend_suppliers(struct device *dev)
329+
{
330+
struct device_link *link;
331+
int idx = device_links_read_lock();
332+
333+
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
334+
device_links_read_lock_held())
335+
pm_request_idle(link->supplier);
336+
337+
device_links_read_unlock(idx);
338+
}
339+
320340
/**
321341
* __rpm_callback - Run a given runtime PM callback for a given device.
322342
* @cb: Runtime PM callback to run.
@@ -344,8 +364,10 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
344364
idx = device_links_read_lock();
345365

346366
retval = rpm_get_suppliers(dev);
347-
if (retval)
367+
if (retval) {
368+
rpm_put_suppliers(dev);
348369
goto fail;
370+
}
349371

350372
device_links_read_unlock(idx);
351373
}
@@ -368,9 +390,9 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
368390
|| (dev->power.runtime_status == RPM_RESUMING && retval))) {
369391
idx = device_links_read_lock();
370392

371-
fail:
372-
rpm_put_suppliers(dev);
393+
__rpm_put_suppliers(dev, false);
373394

395+
fail:
374396
device_links_read_unlock(idx);
375397
}
376398

@@ -642,8 +664,11 @@ static int rpm_suspend(struct device *dev, int rpmflags)
642664
goto out;
643665
}
644666

667+
if (dev->power.irq_safe)
668+
goto out;
669+
645670
/* Maybe the parent is now able to suspend. */
646-
if (parent && !parent->power.ignore_children && !dev->power.irq_safe) {
671+
if (parent && !parent->power.ignore_children) {
647672
spin_unlock(&dev->power.lock);
648673

649674
spin_lock(&parent->power.lock);
@@ -652,6 +677,14 @@ static int rpm_suspend(struct device *dev, int rpmflags)
652677

653678
spin_lock(&dev->power.lock);
654679
}
680+
/* Maybe the suppliers are now able to suspend. */
681+
if (dev->power.links_count > 0) {
682+
spin_unlock_irq(&dev->power.lock);
683+
684+
rpm_suspend_suppliers(dev);
685+
686+
spin_lock_irq(&dev->power.lock);
687+
}
655688

656689
out:
657690
trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval);

kernel/power/energy_model.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static int __init em_debug_init(void)
9898

9999
return 0;
100100
}
101-
core_initcall(em_debug_init);
101+
fs_initcall(em_debug_init);
102102
#else /* CONFIG_DEBUG_FS */
103103
static void em_debug_create_pd(struct device *dev) {}
104104
static void em_debug_remove_pd(struct device *dev) {}

0 commit comments

Comments
 (0)