[PATCH v2 18/19] OMAP4: cpuidle: Add CPU hotplug notifier and prepare() hook.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On OMAP4 CPUidle, the low power states are triggered when CPU1
is offlined to OFF power state. When the CPU1 is online, no
low power states are supported.

The patch adds CPU hotplug notifier to manage the C-state
states using CPUidle prepare() hook and CPUIDLE_FLAG_IGNORE
c-state flag.

This was suggested by Kevin Hilman <khilman@xxxxxx> during
OMAP4 PM code review.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@xxxxxx>
Cc: Kevin Hilman <khilman@xxxxxx>
---
 arch/arm/mach-omap2/cpuidle44xx.c |   64 +++++++++++++++++++++++++++++++++++++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index daf41e1..83b7f95 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -13,6 +13,8 @@
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
 #include <linux/clockchips.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
 
 #include <asm/proc-fns.h>
 
@@ -51,6 +53,8 @@ struct omap4_processor_cx {
 
 struct omap4_processor_cx omap4_power_states[OMAP4_MAX_STATES];
 static struct powerdomain *mpu_pd, *cpu1_pd, *core_pd;
+static int needs_state_data_update;
+static unsigned int state_flags = CPUIDLE_FLAG_IGNORE;
 
 /*
  * FIXME: Full latency numbers needs to be updated as part of
@@ -72,6 +76,31 @@ static struct cpuidle_params cpuidle_params_table[] = {
 };
 
 /**
+ * omap4_prepare_idle - Update C-state parameters dynamically
+ * @dev: cpuidle device
+ *
+ * Called from the CPUidle framework to prepare the device
+ * for idle before before calling the governor's select function.
+ */
+static int omap4_prepare_idle(struct cpuidle_device *dev)
+{
+	int i, ret = 0;
+
+	if (!needs_state_data_update)
+		return ret;
+
+	/*
+	 * Update the C-state flags based on CPU1 online
+	 * or offline state. On OMAP4, the low power C-states
+	 * are made available when only CPU1 is offline.
+	 */
+	for (i = OMAP4_STATE_C2; i < OMAP4_MAX_STATES; i++)
+		dev->states[i].flags = state_flags;
+
+	return ret;
+}
+
+/**
  * omap4_enter_idle - Programs OMAP4 to enter the specified state
  * @dev: cpuidle device
  * @state: The target state to be programmed
@@ -227,6 +256,36 @@ struct cpuidle_driver omap4_idle_driver = {
 	.owner =	THIS_MODULE,
 };
 
+/*
+ * CPU hotplug notifier to update the C-states when
+ * CPU1 is offline or onine. While updating C-state flag,
+ * keep the cpuidle disabled.
+ */
+static int __cpuinit omap_cpu_hotplug_notify(struct notifier_block *self,
+					 unsigned long action, void *unused)
+{
+	switch (action) {
+	case CPU_ONLINE:
+		disable_hlt();
+		needs_state_data_update = 1;
+		state_flags = CPUIDLE_FLAG_IGNORE;
+		enable_hlt();
+		break;
+	case CPU_DEAD:
+		disable_hlt();
+		needs_state_data_update = 1;
+		state_flags = CPUIDLE_FLAG_TIME_VALID;
+		enable_hlt();
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata omap_ilde_hotplug_notifier = {
+	.notifier_call = omap_cpu_hotplug_notify,
+};
+
 /**
  * omap4_idle_init - Init routine for OMAP4 idle
  *
@@ -272,12 +331,17 @@ int __init omap4_idle_init(void)
 	if (!count)
 		return -EINVAL;
 	dev->state_count = count;
+	dev->prepare = omap4_prepare_idle;
 
 	if (cpuidle_register_device(dev)) {
 		pr_err("%s: CPUidle register device failed\n", __func__);
 			return -EIO;
 		}
 
+	ret = register_hotcpu_notifier(&omap_ilde_hotplug_notifier);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 #else
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux