Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+40 -7
+39 -6
drivers/base/power/runtime.c
··· 305 305 return 0; 306 306 } 307 307 308 - static void rpm_put_suppliers(struct device *dev) 308 + static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend) 309 309 { 310 310 struct device_link *link; 311 311 ··· 313 313 device_links_read_lock_held()) { 314 314 315 315 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); 317 320 } 321 + } 322 + 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); 318 338 } 319 339 320 340 /** ··· 364 344 idx = device_links_read_lock(); 365 345 366 346 retval = rpm_get_suppliers(dev); 367 - if (retval) 347 + if (retval) { 348 + rpm_put_suppliers(dev); 368 349 goto fail; 350 + } 369 351 370 352 device_links_read_unlock(idx); 371 353 } ··· 390 368 || (dev->power.runtime_status == RPM_RESUMING && retval))) { 391 369 idx = device_links_read_lock(); 392 370 393 - fail: 394 - rpm_put_suppliers(dev); 371 + __rpm_put_suppliers(dev, false); 395 372 373 + fail: 396 374 device_links_read_unlock(idx); 397 375 } 398 376 ··· 664 642 goto out; 665 643 } 666 644 645 + if (dev->power.irq_safe) 646 + goto out; 647 + 667 648 /* Maybe the parent is now able to suspend. */ 668 - if (parent && !parent->power.ignore_children && !dev->power.irq_safe) { 649 + if (parent && !parent->power.ignore_children) { 669 650 spin_unlock(&dev->power.lock); 670 651 671 652 spin_lock(&parent->power.lock); ··· 676 651 spin_unlock(&parent->power.lock); 677 652 678 653 spin_lock(&dev->power.lock); 654 + } 655 + /* Maybe the suppliers are now able to suspend. */ 656 + if (dev->power.links_count > 0) { 657 + spin_unlock_irq(&dev->power.lock); 658 + 659 + rpm_suspend_suppliers(dev); 660 + 661 + spin_lock_irq(&dev->power.lock); 679 662 } 680 663 681 664 out:
+1 -1
kernel/power/energy_model.c
··· 98 98 99 99 return 0; 100 100 } 101 - core_initcall(em_debug_init); 101 + fs_initcall(em_debug_init); 102 102 #else /* CONFIG_DEBUG_FS */ 103 103 static void em_debug_create_pd(struct device *dev) {} 104 104 static void em_debug_remove_pd(struct device *dev) {}