All of lore.kernel.org
 help / color / mirror / Atom feed
* Question about __pm_runtime_disable()
@ 2021-07-09  2:24 chenxiang (M)
  2021-07-09 15:50 ` Rafael J. Wysocki
  0 siblings, 1 reply; 3+ messages in thread
From: chenxiang (M) @ 2021-07-09  2:24 UTC (permalink / raw)
  To: rafael.j.wysocki; +Cc: linuxarm, Linux PM, John Garry

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 (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



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: Question about __pm_runtime_disable()
  2021-07-09  2:24 Question about __pm_runtime_disable() chenxiang (M)
@ 2021-07-09 15:50 ` Rafael J. Wysocki
  2021-07-10  1:25   ` chenxiang (M)
  0 siblings, 1 reply; 3+ messages in thread
From: Rafael J. Wysocki @ 2021-07-09 15:50 UTC (permalink / raw)
  To: chenxiang (M); +Cc: Rafael Wysocki, Linuxarm, Linux PM, John Garry

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.

> Or does it need to decrease child_count the device's parent in function
> __pm_runtime_disable() ?

Doing this is not recommended.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Question about __pm_runtime_disable()
  2021-07-09 15:50 ` Rafael J. Wysocki
@ 2021-07-10  1:25   ` chenxiang (M)
  0 siblings, 0 replies; 3+ messages in thread
From: chenxiang (M) @ 2021-07-10  1:25 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Rafael Wysocki, Linuxarm, Linux PM, John Garry



在 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.
>
> .
>



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-07-10  1:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-09  2:24 Question about __pm_runtime_disable() chenxiang (M)
2021-07-09 15:50 ` Rafael J. Wysocki
2021-07-10  1:25   ` chenxiang (M)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.