aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@codeaurora.org>2019-03-05 23:07:26 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-03-11 06:17:26 -0400
commit55286a29389a1a30fb2ccc83ef9315809946b365 (patch)
treedc66bd65d0cdd9f3dc2af9a20e92b41ed5288367
parentef8006846a3a97d9d8bf49e63dba948d0d2dbbf0 (diff)
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>
-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,
173 struct opp_table **required_opp_tables; 173 struct opp_table **required_opp_tables;
174 struct device **genpd_virt_devs = NULL; 174 struct device **genpd_virt_devs = NULL;
175 struct device_node *required_np, *np; 175 struct device_node *required_np, *np;
176 int count, i; 176 int count, count_pd, i;
177 177
178 /* Traversing the first OPP node is all we need */ 178 /* Traversing the first OPP node is all we need */
179 np = of_get_next_available_child(opp_np, NULL); 179 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,
186 if (!count) 186 if (!count)
187 goto put_np; 187 goto put_np;
188 188
189 if (count > 1) { 189 /*
190 * Check the number of power-domains to know if we need to deal
191 * with virtual devices. In some cases we have devices with multiple
192 * power domains but with only one of them being scalable, hence
193 * 'count' could be 1, but we still have to deal with multiple genpds
194 * and virtual devices.
195 */
196 count_pd = of_count_phandle_with_args(dev->of_node, "power-domains",
197 "#power-domain-cells");
198 if (!count_pd)
199 goto put_np;
200
201 if (count_pd > 1) {
190 genpd_virt_devs = kcalloc(count, sizeof(*genpd_virt_devs), 202 genpd_virt_devs = kcalloc(count, sizeof(*genpd_virt_devs),
191 GFP_KERNEL); 203 GFP_KERNEL);
192 if (!genpd_virt_devs) 204 if (!genpd_virt_devs)