linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] PM / OPP: fix CPU device to be removed from OPP table in wrong order
@ 2016-11-24  7:49 Joonyoung Shim
  2016-11-24  8:34 ` Viresh Kumar
  0 siblings, 1 reply; 5+ messages in thread
From: Joonyoung Shim @ 2016-11-24  7:49 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, vireshk, nm, sboyd, rjw, len.brown, pavel, gregkh,
	jy0922.shim

The device that creates OPP table first should be removed from dev_list
of OPP table in last because it can be used by other resources
(supported_hw, prop_name, regulator), but not now. If OPP table is
shared by several CPUs, the CPU device that creates OPP table can be
removed earlier than other CPU devices.

This patch makes that the CPU device that creates OPP table is removed
last.

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
---
 drivers/base/power/opp/cpu.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/base/power/opp/cpu.c b/drivers/base/power/opp/cpu.c
index 8c3434bdb26d..9d0773a237f8 100644
--- a/drivers/base/power/opp/cpu.c
+++ b/drivers/base/power/opp/cpu.c
@@ -118,9 +118,36 @@ void dev_pm_opp_free_cpufreq_table(struct device *dev,
 EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table);
 #endif	/* CONFIG_CPU_FREQ */
 
+static bool dev_pm_opp_is_removed_last(struct device *dev)
+{
+	struct opp_device *opp_dev;
+	struct opp_table *opp_table;
+	bool ret = false;
+
+	mutex_lock(&opp_table_lock);
+
+	opp_table = _find_opp_table(dev);
+	if (IS_ERR(opp_table))
+		goto unlock;
+
+	if (list_is_singular(&opp_table->dev_list))
+		goto unlock;
+
+	opp_dev = list_last_entry(&opp_table->dev_list, struct opp_device,
+				  node);
+	if (opp_dev->dev == dev)
+		ret = true;
+
+unlock:
+	mutex_unlock(&opp_table_lock);
+
+	return ret;
+}
+
 void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of)
 {
 	struct device *cpu_dev;
+	struct device *last = NULL;
 	int cpu;
 
 	WARN_ON(cpumask_empty(cpumask));
@@ -133,11 +160,23 @@ void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of)
 			continue;
 		}
 
+		if (!last && dev_pm_opp_is_removed_last(cpu_dev)) {
+			last = cpu_dev;
+			continue;
+		}
+
 		if (of)
 			dev_pm_opp_of_remove_table(cpu_dev);
 		else
 			dev_pm_opp_remove_table(cpu_dev);
 	}
+
+	if (last) {
+		if (of)
+			dev_pm_opp_of_remove_table(last);
+		else
+			dev_pm_opp_remove_table(last);
+	}
 }
 
 /**
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-11-25  7:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-24  7:49 [PATCH] PM / OPP: fix CPU device to be removed from OPP table in wrong order Joonyoung Shim
2016-11-24  8:34 ` Viresh Kumar
2016-11-25  1:54   ` Joonyoung Shim
2016-11-25  6:57     ` Viresh Kumar
2016-11-25  7:30       ` Joonyoung Shim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).