diff mbox series

Question about __pm_runtime_disable()

Message ID 4c65cdd3-05cd-499d-0dd1-b7d6e76372b1@hisilicon.com
State New
Headers show
Series Question about __pm_runtime_disable() | expand

Commit Message

chenxiang July 9, 2021, 2:24 a.m. UTC
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.

  }

Is it appropriate for me to use function pm_runtime_disable() to ignore 
them (i try function function pm_suspend_ignore_children(), but it 
ignores all children of the device )?
Or does it need to decrease child_count the device's parent in function 
__pm_runtime_disable() ?


Best Regard,
Xiang Chen

Comments

chenxiang July 10, 2021, 1:25 a.m. UTC | #1
在 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 mbox series

Patch

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);