Re: [PATCH v2] opp: Power on (virtual) power domains managed by the OPP core

From: Stephan Gerhold
Date: Thu Aug 27 2020 - 11:11:07 EST


On Thu, Aug 27, 2020 at 03:31:04PM +0530, Viresh Kumar wrote:
> On 26-08-20, 11:33, Stephan Gerhold wrote:
> > diff --git a/drivers/opp/core.c b/drivers/opp/core.c
> > index 8b3c3986f589..7e53a7b94c59 100644
> > --- a/drivers/opp/core.c
> > +++ b/drivers/opp/core.c
> > @@ -17,6 +17,7 @@
> > #include <linux/device.h>
> > #include <linux/export.h>
> > #include <linux/pm_domain.h>
> > +#include <linux/pm_runtime.h>
> > #include <linux/regulator/consumer.h>
> >
> > #include "opp.h"
> > @@ -1964,10 +1965,13 @@ static void _opp_detach_genpd(struct opp_table *opp_table)
> > if (!opp_table->genpd_virt_devs[index])
> > continue;
> >
> > + if (opp_table->genpd_virt_links && opp_table->genpd_virt_links[index])
> > + device_link_del(opp_table->genpd_virt_links[index]);
> > dev_pm_domain_detach(opp_table->genpd_virt_devs[index], false);
> > opp_table->genpd_virt_devs[index] = NULL;
> > }
> >
> > + kfree(opp_table->genpd_virt_links);
> > kfree(opp_table->genpd_virt_devs);
> > opp_table->genpd_virt_devs = NULL;
> > }
> > @@ -1999,8 +2003,10 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev,
> > {
> > struct opp_table *opp_table;
> > struct device *virt_dev;
> > - int index = 0, ret = -EINVAL;
> > + struct device_link *dev_link;
> > + int index = 0, ret = -EINVAL, num_devs;
> > const char **name = names;
> > + u32 flags;
> >
> > opp_table = dev_pm_opp_get_opp_table(dev);
> > if (IS_ERR(opp_table))
> > @@ -2049,6 +2055,32 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev,
>
> I was about to apply this patch when I noticed that this routine does
> return the array of virtual devices back to the caller, like the qcom
> cpufreq driver in this case. IIRC we did it this way as a generic
> solution for this in the OPP core wasn't preferable.
>

Hmm. Actually I was using this parameter for initial testing, and forced
on the power domains from the qcom-cpufreq-nvmem driver. For my v1 patch
I wanted to enable the power domains in dev_pm_opp_set_rate(), so there
using the virt_devs parameter was not possible.

On the other hand, creating the device links would be possible from the
platform driver by using the parameter.

> And so I think again if this patch should be picked instead of letting
> the platform handle this ?
>

It seems like originally the motivation for the parameter was that
cpufreq consumers do *not* need to power on the power domains:

Commit 17a8f868ae3e ("opp: Return genpd virtual devices from dev_pm_opp_attach_genpd()"):
"The cpufreq drivers don't need to do runtime PM operations on
the virtual devices returned by dev_pm_domain_attach_by_name() and so
the virtual devices weren't shared with the callers of
dev_pm_opp_attach_genpd() earlier.

But the IO device drivers would want to do that. This patch updates
the prototype of dev_pm_opp_attach_genpd() to accept another argument
to return the pointer to the array of genpd virtual devices."

But the reason why I made this patch is that actually something *should*
enable the power domains even for the cpufreq case.
If every user of dev_pm_opp_attach_genpd() ends up creating these device
links we might as well manage those directly from the OPP core.

I cannot think of any use case where you would not want to manage those
power domains using device links. And if there is such a use case,
chances are good that this use case is so special that using the OPP API
to set the performance states would not work either. In either case,
this seems like something that should be discussed once there is such a
use case.

At the moment, there are only two users of dev_pm_opp_attach_genpd():

- cpufreq (qcom-cpufreq-nvmem)
- I/O (venus, recently added in linux-next [1])

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=9a538b83612c8b5848bf840c2ddcd86dda1c8c76

In fact, venus adds the device link exactly the same way as in my patch.
So we could move that to the OPP core, simplify the venus code and
remove the virt_devs parameter. That would be my suggestion.

I can submit a v3 with that if you agree (or we take this patch as-is
and remove the parameter separately - I just checked and creating a
device link twice does not seem to cause any problems...)

Thanks!
Stephan