On 18-06-24, 17:50, Ulf Hansson wrote: > In _set_opp() we are normally bailing out when trying to set an OPP that is > the current one. This make perfect sense, but becomes a problem when > _set_required_opps() calls it recursively. > > More precisely, when a required OPP is being shared by multiple PM domains, > we end up skipping to request the corresponding performance-state for all > of the PM domains, but the first one. Let's fix the problem, by calling > _set_opp_level() from _set_required_opps() instead. > > Fixes: e37440e7e2c2 ("OPP: Call dev_pm_opp_set_opp() for required OPPs") > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx> > --- > drivers/opp/core.c | 47 +++++++++++++++++++++++----------------------- > 1 file changed, 24 insertions(+), 23 deletions(-) > /* This is only called for PM domain for now */ > static int _set_required_opps(struct device *dev, struct opp_table *opp_table, > struct dev_pm_opp *opp, bool up) > @@ -1091,7 +1113,8 @@ static int _set_required_opps(struct device *dev, struct opp_table *opp_table, > if (devs[index]) { > required_opp = opp ? opp->required_opps[index] : NULL; > > - ret = dev_pm_opp_set_opp(devs[index], required_opp); > + ret = _set_opp_level(devs[index], opp_table, > + required_opp); No, we won't be doing this I guess. Its like going back instead of moving forward :) The required OPPs is not just a performance domain thing, but specially with devs[] here, it can be used to set OPP for any device type and so dev_pm_opp_set_opp() is the right call here. Coming back to the problem you are pointing to, I am not very clear of the whole picture here. Can you please help me get some details on that ?