FAILED: patch "[PATCH] OPP: Fix support for required OPPs for multiple PM domains" failed to apply to 6.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.10.y
git checkout FETCH_HEAD
git cherry-pick -x 9ec87c5957ea9bf68d36f5e098605b585b2571e4
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024090809-portion-riptide-f7d9@gregkh' --subject-prefix 'PATCH 6.10.y' HEAD^..
Possible dependencies:
9ec87c5957ea ("OPP: Fix support for required OPPs for multiple PM domains") 0d865221c8b1 ("OPP: Drop a redundant in-parameter to _set_opp_level()")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 9ec87c5957ea9bf68d36f5e098605b585b2571e4 Mon Sep 17 00:00:00 2001
From: Ulf Hansson <[email protected]>
Date: Fri, 23 Aug 2024 00:45:38 +0200
Subject: [PATCH] OPP: Fix support for required OPPs for multiple PM domains
It has turned out that having _set_required_opps() to recursively call dev_pm_opp_set_opp() to set the required OPPs, doesn't really work as well as we expected.
More precisely, at each recursive call to dev_pm_opp_set_opp() we are changing an OPP for a required_dev that belongs to a required-OPP table. The problem with this, is that we may have several devices sharing the same required-OPP table, which leads to an incorrect behaviour in regards to aggregating the per device votes.
To fix the problem for a required-OPP table belonging to a PM domain, which is the only existing usecase for now, let's simply replace the call to dev_pm_opp_set_opp() in _set_required_opps() by a call to _set_opp_level().
Moving forward we may potentially need to add support for other types of required-OPP tables. In this case, the aggregation needs to be thought of.
drivers/opp/core.c +22 -34
@@ -1061,6 +1061,27 @@ static int _set_opp_bw(const struct opp_table *opp_table,return 0 ; } +static int _set_opp_level (struct device *dev,struct dev_pm_opp *opp) +{ +unsigned int level =0 ; +int ret =0 ; + +if (opp) { +if (opp->level ==OPP_LEVEL_UNSET ) +return 0 ; + + level = opp->level; + } + +/* Request a new performance state through the device's PM domain. */ + ret =dev_pm_domain_set_performance_state (dev, level); +if (ret) +dev_err (dev,"Failed to set performance state %u (%d)\n" , level, + ret); + +return ret; +} +/* 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 +1112,7 @@ 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], required_opp);if (ret)return ret; }
@@ -1102,27 +1123,6 @@ static int _set_required_opps(struct device *dev, struct opp_table *opp_table,return 0 ; } -static int _set_opp_level (struct device *dev,struct dev_pm_opp *opp) -{ -unsigned int level =0 ; -int ret =0 ; - -if (opp) { -if (opp->level ==OPP_LEVEL_UNSET ) -return 0 ; - - level = opp->level; - } - -/* Request a new performance state through the device's PM domain. */ - ret =dev_pm_domain_set_performance_state (dev, level); -if (ret) -dev_err (dev,"Failed to set performance state %u (%d)\n" , level, - ret); - -return ret; -} -static void _find_current_opp (struct device *dev,struct opp_table *opp_table) {struct dev_pm_opp *opp =ERR_PTR (-ENODEV );
@@ -2457,18 +2457,6 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev, } } -/* -* Add the virtual genpd device as a user of the OPP table, so -* we can call dev_pm_opp_set_opp() on it directly. -* -* This will be automatically removed when the OPP table is -* removed, don't need to handle that here. -*/ -if (!_add_opp_dev (virt_dev, opp_table->required_opp_tables[index])) { - ret = -ENOMEM ; - goto err; - } - opp_table->required_devs[index] = virt_dev; index++; name++;