Message ID | 4c65cdd3-05cd-499d-0dd1-b7d6e76372b1@hisilicon.com |
---|---|
State | New |
Headers | show |
Series | Question about __pm_runtime_disable() | expand |
在 2021/7/9 23:50, Rafael J. Wysocki 写道: > On Fri, Jul 9, 2021 at 4:24 AM chenxiang (M) <chenxiang66@hisilicon.com> wrote: >> Hi Rafael and other guys, >> >> I encounter a runtime PM issue: there are four devices, and device 0 is >> the parent device, and device 1/2/3 are the children devices of device 0. >> >> All of them supports runtime PM. But i want to ignore device2 and >> device3, so that if device 1 is suspended, then device0 can >> >> be suspended. I use function pm_runtime_disable() to disable device2 and >> device3, and device 1 is suspended but device0 is still active. >> >> I find that runtime_active_kids of device0 is still 2 though >> runtime_usage = 0, so it doesn't enter suspend status. >> >> And i hack the code of funciton __pm_runtime_disable() to decrease >> child_count of device's parent as follows, and it works. >> >> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c >> index b570848..6ba224b 100644 >> --- a/drivers/base/power/runtime.c >> +++ b/drivers/base/power/runtime.c >> @@ -1382,6 +1382,8 @@ EXPORT_SYMBOL_GPL(pm_runtime_barrier); >> */ >> void __pm_runtime_disable(struct device *dev, bool check_resume) >> { >> + struct device *parent = NULL; >> + >> spin_lock_irq(&dev->power.lock); >> >> if (dev->power.disable_depth > 0) { >> @@ -1413,6 +1415,10 @@ void __pm_runtime_disable(struct device *dev, >> bool check_resume) >> if (!dev->power.disable_depth++) >> __pm_runtime_barrier(dev); >> >> + if (dev->parent) { >> + parent = dev->parent; >> + atomic_add_unless(&parent->power.child_count, -1, 0); >> + } >> out: >> spin_unlock_irq(&dev->power.lock); >> } >> >> Is it appropriate for me to use function pm_runtime_disable() to ignore >> them > No, it is not. > >> (i try function function pm_suspend_ignore_children(), but it >> ignores all children of the device )? > IMV you still need to use ignore_children (and yes, all of the > children will be ignored in that case) and use pm_runtime_get_*() and > pm_runtime_put_*() on the parent in the child 1 driver to make the > parent automatically resume and suspend, respectively. Ok, thanks for the suggestion. > >> Or does it need to decrease child_count the device's parent in function >> __pm_runtime_disable() ? > Doing this is not recommended. > > . >
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index b570848..6ba224b 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1382,6 +1382,8 @@ EXPORT_SYMBOL_GPL(pm_runtime_barrier); */ void __pm_runtime_disable(struct device *dev, bool check_resume) { + struct device *parent = NULL; + spin_lock_irq(&dev->power.lock); if (dev->power.disable_depth > 0) { @@ -1413,6 +1415,10 @@ void __pm_runtime_disable(struct device *dev, bool check_resume) if (!dev->power.disable_depth++) __pm_runtime_barrier(dev); + if (dev->parent) { + parent = dev->parent; + atomic_add_unless(&parent->power.child_count, -1, 0); + } out: spin_unlock_irq(&dev->power.lock);