[cpuidle 2/3] add cpuidle_fore_redetect_devices API

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

 



add cpuidle_force_redetect_devices API, which force all CPU redetect idle states. Next patch will use it.

Signed-off-by: Shaohua Li <shaohua.li@xxxxxxxxx>
---
 drivers/acpi/processor_idle.c |    3 +-
 drivers/cpuidle/driver.c      |   56 +++++++++++++++++++++++++++++++++++++++---
 include/linux/cpuidle.h       |    7 +++--
 3 files changed, 59 insertions(+), 7 deletions(-)

Index: 21-rc6-mm1/drivers/cpuidle/driver.c
===================================================================
--- 21-rc6-mm1.orig/drivers/cpuidle/driver.c	2007-04-26 09:56:53.000000000 +0800
+++ 21-rc6-mm1/drivers/cpuidle/driver.c	2007-04-26 10:06:26.000000000 +0800
@@ -160,20 +160,34 @@ void cpuidle_unregister_driver(struct cp
 
 EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
 
+static void __cpuidle_force_redetect(struct cpuidle_device *dev)
+{
+	cpuidle_remove_driver_sysfs(dev);
+	cpuidle_curr_driver->redetect(dev);
+	cpuidle_add_driver_sysfs(dev);
+}
+
 /**
  * cpuidle_force_redetect - redetects the idle states of a CPU
  *
  * @dev: the CPU to redetect
+ * @drv: the target driver
  *
  * Generally, the driver will call this when the supported states set has
  * changed. (e.g. as the result of an ACPI transition to battery power)
  */
-int cpuidle_force_redetect(struct cpuidle_device *dev)
+int cpuidle_force_redetect(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv)
 {
 	int uninstalled = 0;
 
 	mutex_lock(&cpuidle_lock);
 
+	if (drv != cpuidle_curr_driver) {
+		mutex_unlock(&cpuidle_lock);
+		return 0;
+	}
+
 	if (!(dev->status & CPUIDLE_STATUS_DRIVER_ATTACHED) ||
 	    !cpuidle_curr_driver->redetect) {
 		mutex_unlock(&cpuidle_lock);
@@ -185,9 +199,7 @@ int cpuidle_force_redetect(struct cpuidl
 		cpuidle_uninstall_idle_handler();
 	}
 
-	cpuidle_remove_driver_sysfs(dev);
-	cpuidle_curr_driver->redetect(dev);
-	cpuidle_add_driver_sysfs(dev);
+	__cpuidle_force_redetect(dev);
 
 	if (cpuidle_device_can_idle(dev)) {
 		cpuidle_rescan_device(dev);
@@ -206,6 +218,42 @@ int cpuidle_force_redetect(struct cpuidl
 EXPORT_SYMBOL_GPL(cpuidle_force_redetect);
 
 /**
+ * cpuidle_force_redetect_devices - redetects the idle states of all CPUs
+ *
+ * @drv: the target driver
+ *
+ * Generally, the driver will call this when the supported states set has
+ * changed. (e.g. as the result of an ACPI transition to battery power)
+ */
+int cpuidle_force_redetect_devices(struct cpuidle_driver *drv)
+{
+	struct cpuidle_device *dev;
+	int ret = 0;
+
+	mutex_lock(&cpuidle_lock);
+
+	if (drv != cpuidle_curr_driver)
+		goto out;
+
+	if (!cpuidle_curr_driver->redetect) {
+		ret = -EIO;
+		goto out;
+	}
+
+	cpuidle_uninstall_idle_handler();
+
+	list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
+		__cpuidle_force_redetect(dev);
+
+	cpuidle_install_idle_handler();
+out:
+	mutex_unlock(&cpuidle_lock);
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_force_redetect_devices);
+
+/**
  * cpuidle_get_bm_activity - determines if BM activity has occured
  */
 int cpuidle_get_bm_activity(void)
Index: 21-rc6-mm1/include/linux/cpuidle.h
===================================================================
--- 21-rc6-mm1.orig/include/linux/cpuidle.h	2007-04-26 10:05:55.000000000 +0800
+++ 21-rc6-mm1/include/linux/cpuidle.h	2007-04-26 10:06:26.000000000 +0800
@@ -137,14 +137,17 @@ struct cpuidle_driver {
 
 extern int cpuidle_register_driver(struct cpuidle_driver *drv);
 extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
-extern int cpuidle_force_redetect(struct cpuidle_device *dev);
+extern int cpuidle_force_redetect(struct cpuidle_device *dev, struct cpuidle_driver *drv);
+extern int cpuidle_force_redetect_devices(struct cpuidle_driver *drv);
 
 #else
 
 static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
 {return 0;}
 static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
-static inline int cpuidle_force_redetect(struct cpuidle_device *dev)
+static inline int cpuidle_force_redetect(struct cpuidle_device *dev, struct cpuidle_driver *drv)
+{return 0;}
+static inline int cpuidle_force_redetect_devices(struct cpuidle_driver *drv)
 {return 0;}
 
 #endif
Index: 21-rc6-mm1/drivers/acpi/processor_idle.c
===================================================================
--- 21-rc6-mm1.orig/drivers/acpi/processor_idle.c	2007-04-26 10:05:55.000000000 +0800
+++ 21-rc6-mm1/drivers/acpi/processor_idle.c	2007-04-26 10:06:41.000000000 +0800
@@ -624,7 +624,8 @@ int acpi_processor_cst_has_changed(struc
 		return -ENODEV;
 
 	acpi_processor_get_power_info(pr);
-	return cpuidle_force_redetect(per_cpu(cpuidle_devices, pr->id));
+	return cpuidle_force_redetect(per_cpu(cpuidle_devices, pr->id),
+		&acpi_idle_driver);
 }
 
 /* proc interface */
-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux