summaryrefslogtreecommitdiffstats
path: root/drivers/opp/of.c
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@codeaurora.org>2019-03-06 09:37:26 +0530
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-03-11 11:17:26 +0100
commit55286a29389a1a30fb2ccc83ef9315809946b365 (patch)
treedc66bd65d0cdd9f3dc2af9a20e92b41ed5288367 /drivers/opp/of.c
parentef8006846a3a97d9d8bf49e63dba948d0d2dbbf0 (diff)
downloadlinux-stable-55286a29389a1a30fb2ccc83ef9315809946b365.tar.gz
linux-stable-55286a29389a1a30fb2ccc83ef9315809946b365.tar.bz2
linux-stable-55286a29389a1a30fb2ccc83ef9315809946b365.zip
OPP: Fix handling of multiple power domains
We seem to rely on the number of phandles specified in the 'required-opps' property to identify cases where a device is associated with multiple power domains and hence would have multiple virtual devices that have to be dealt with. In cases where we do have devices with multiple power domains but with only one of them being scalable, this logic seems to fail. Instead read the number of power domains from DT to identify such cases. Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org> Reviewed-by: Stephen Boyd <sboyd@kernel.org> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/opp/of.c')
-rw-r--r--drivers/opp/of.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index 62504b18f198..c10c782d15aa 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -173,7 +173,7 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
struct opp_table **required_opp_tables;
struct device **genpd_virt_devs = NULL;
struct device_node *required_np, *np;
- int count, i;
+ int count, count_pd, i;
/* Traversing the first OPP node is all we need */
np = of_get_next_available_child(opp_np, NULL);
@@ -186,7 +186,19 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
if (!count)
goto put_np;
- if (count > 1) {
+ /*
+ * Check the number of power-domains to know if we need to deal
+ * with virtual devices. In some cases we have devices with multiple
+ * power domains but with only one of them being scalable, hence
+ * 'count' could be 1, but we still have to deal with multiple genpds
+ * and virtual devices.
+ */
+ count_pd = of_count_phandle_with_args(dev->of_node, "power-domains",
+ "#power-domain-cells");
+ if (!count_pd)
+ goto put_np;
+
+ if (count_pd > 1) {
genpd_virt_devs = kcalloc(count, sizeof(*genpd_virt_devs),
GFP_KERNEL);
if (!genpd_virt_devs)