[3/5] cpuidle: governor: Make possible to unregister a governor

Message ID 20201015144431.9979-3-daniel.lezcano@linaro.org
State New
Headers show
Series
  • [1/5] cpuidle: Remove pointless stub
Related show

Commit Message

Daniel Lezcano Oct. 15, 2020, 2:44 p.m.
This patch allows to unregister a governor. If the unregistered
governor is the current one, it will be replaced by the governor with
the highest rating. If it is the last governor, the cpuidle framework
will be switched off.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/cpuidle/governor.c | 37 +++++++++++++++++++++++++++++++++++++
 include/linux/cpuidle.h    |  1 +
 2 files changed, 38 insertions(+)

Patch

diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
index d46ab8ec2dd7..6ec27ef096f5 100644
--- a/drivers/cpuidle/governor.c
+++ b/drivers/cpuidle/governor.c
@@ -84,6 +84,43 @@  int cpuidle_switch_governor(struct cpuidle_governor *gov)
 	return 0;
 }
 
+/**
+ * cpuidle_unregister_governor - unregister a governor
+ * @gov: a pointer to a cpuidle governor structure
+ *
+ * Unregister the governor specified in parameter. If it is the
+ * current one, replace by another one in the list with the highest
+ * rating. If it is the last one, then switch off cpuidle.
+ */
+void cpuidle_unregister_governor(struct cpuidle_governor *gov)
+{
+	int rating = 0;
+	struct cpuidle_governor *new_gov = NULL;
+
+	mutex_lock(&cpuidle_lock);
+
+	list_del(&gov->governor_list);
+
+	/*
+	 * The governor is currently in use, switch to the one with
+	 * the best rating.
+	 */
+	if (cpuidle_curr_governor == gov) {
+
+		list_for_each_entry(gov, &cpuidle_governors, governor_list) {
+			if (gov->rating > rating)
+				new_gov = gov;
+		}
+
+		if (new_gov)
+			cpuidle_switch_governor(new_gov);
+		else
+			cpuidle_switch_off();
+	}
+
+	mutex_unlock(&cpuidle_lock);
+}
+
 /**
  * cpuidle_register_governor - registers a governor
  * @gov: the governor
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 74fdcc6106b1..457e0786b4f9 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -271,6 +271,7 @@  struct cpuidle_governor {
 };
 
 extern int cpuidle_register_governor(struct cpuidle_governor *gov);
+extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
 extern s64 cpuidle_governor_latency_req(unsigned int cpu);
 
 #define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter,			\