linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv4 00/15] Thermal_framework_enhancements
@ 2012-09-18  5:34 Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 01/15] Thermal: Refactor thermal.h file Durgadoss R
                   ` (14 more replies)
  0 siblings, 15 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch series is a v4 of the series submitted here:
http://www.spinics.net/lists/linux-acpi/msg37375.html

These patches are based on Rui's tree here: (branch - next)
git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git

Changes since v3:
 * Rebase the patches on top of Rui's next branch
 * Register a separate governor for user space
 * Make step_wise governor as default (Kconfig change)
 * Synchronize policy_store method in thermal_sys.c
Changes since v2:
 * Made thermal_zone_params as argument to tzd_register()
 * Introduced Thermal governor register/unregister APIs
 * Added 'write' permission for policy sysfs attribute
 * Added function pointer based implemention for thermal
   governors.
 * Added a 'dummy' user space governor in thermal_sys.c
 * Renamed 'do_binding' and 'update_bind_info' functions as
   'bind_tz' and 'bind_cdev' respectively
 * Updated Documentation for all the changes
Changes since v1:
 * Created thermal_core.h
 * Removed get_cdev_by_name API, as it is no longer needed
 * Introduced thermal_bind_params inside thermal_zone_params
 * Use a single arbitrator by making thermal_cdev_update global
 * Added more documentation on EXPORT_SYMBOL APIs in thermal_sys.c
 * Various minor fixes based on comments from Rui and Eduardo.


Durgadoss R (15):
  Thermal: Refactor thermal.h file
  Thermal: Move thermal_instance to thermal_core.h
  Thermal: Add get trend, get instance API's to thermal_sys
  Thermal: Add platform level information to thermal.h
  Thermal: Pass zone parameters as argument to tzd_register
  Thermal: Add thermal governor registration APIs
  Thermal: Add a policy sysfs attribute
  Thermal: Update binding logic based on platform data
  Thermal: Make thermal_cdev_update as a global function
  Thermal: Introduce fair_share thermal governor
  Thermal: Introduce a step_wise thermal governor
  Thermal: Add a thermal notifier for user space
  Thermal: Remove throttling logic out of thermal_sys.c
  Thermal: Add a notification API
  Thermal: Add documentation for platform layer data

 Documentation/thermal/sysfs-api.txt                |   64 ++
 drivers/acpi/thermal.c                             |    6 +-
 drivers/platform/x86/acerhdf.c                     |    2 +-
 drivers/platform/x86/intel_mid_thermal.c           |    2 +-
 drivers/power/power_supply_core.c                  |    2 +-
 drivers/staging/omap-thermal/omap-thermal-common.c |    2 +-
 drivers/thermal/Kconfig                            |   19 +
 drivers/thermal/Makefile                           |    3 +
 drivers/thermal/exynos_thermal.c                   |    2 +-
 drivers/thermal/fair_share.c                       |  133 ++++
 drivers/thermal/rcar_thermal.c                     |    2 +-
 drivers/thermal/spear_thermal.c                    |    2 +-
 drivers/thermal/step_wise.c                        |  194 ++++++
 drivers/thermal/thermal_core.h                     |   53 ++
 drivers/thermal/thermal_sys.c                      |  705 +++++++++++++-------
 drivers/thermal/user_space.c                       |   68 ++
 include/linux/thermal.h                            |  128 +++-
 17 files changed, 1096 insertions(+), 291 deletions(-)
 create mode 100644 drivers/thermal/fair_share.c
 create mode 100644 drivers/thermal/step_wise.c
 create mode 100644 drivers/thermal/thermal_core.h
 create mode 100644 drivers/thermal/user_space.c

-- 
1.7.9.5


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

* [PATCHv4 01/15] Thermal: Refactor thermal.h file
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
@ 2012-09-18  5:34 ` Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 02/15] Thermal: Move thermal_instance to thermal_core.h Durgadoss R
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch rearranges the code in thermal.h file,
in the following order, so that it is easy to
read/maintain.
1. All #defines
2. All enums
3. All fops structures
4. All device structures
5. All function declarations

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 include/linux/thermal.h |   78 ++++++++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 35 deletions(-)

diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 91b3481..8611e3e 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -29,6 +29,23 @@
 #include <linux/device.h>
 #include <linux/workqueue.h>
 
+#define THERMAL_TRIPS_NONE	-1
+#define THERMAL_MAX_TRIPS	12
+#define THERMAL_NAME_LENGTH	20
+
+/* No upper/lower limit requirement */
+#define THERMAL_NO_LIMIT	-1UL
+
+/* Unit conversion macros */
+#define KELVIN_TO_CELSIUS(t)	(long)(((long)t-2732 >= 0) ?	\
+				((long)t-2732+5)/10 : ((long)t-2732-5)/10)
+#define CELSIUS_TO_KELVIN(t)	((t)*10+2732)
+
+/* Adding event notification support elements */
+#define THERMAL_GENL_FAMILY_NAME                "thermal_event"
+#define THERMAL_GENL_VERSION                    0x01
+#define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_group"
+
 struct thermal_zone_device;
 struct thermal_cooling_device;
 
@@ -50,6 +67,30 @@ enum thermal_trend {
 	THERMAL_TREND_DROPPING, /* temperature is dropping */
 };
 
+/* Events supported by Thermal Netlink */
+enum events {
+	THERMAL_AUX0,
+	THERMAL_AUX1,
+	THERMAL_CRITICAL,
+	THERMAL_DEV_FAULT,
+};
+
+/* attributes of thermal_genl_family */
+enum {
+	THERMAL_GENL_ATTR_UNSPEC,
+	THERMAL_GENL_ATTR_EVENT,
+	__THERMAL_GENL_ATTR_MAX,
+};
+#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
+
+/* commands supported by the thermal_genl_family */
+enum {
+	THERMAL_GENL_CMD_UNSPEC,
+	THERMAL_GENL_CMD_EVENT,
+	__THERMAL_GENL_CMD_MAX,
+};
+#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
+
 struct thermal_zone_device_ops {
 	int (*bind) (struct thermal_zone_device *,
 		     struct thermal_cooling_device *);
@@ -83,11 +124,6 @@ struct thermal_cooling_device_ops {
 	int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
 };
 
-#define THERMAL_NO_LIMIT -1UL /* no upper/lower limit requirement */
-
-#define THERMAL_TRIPS_NONE -1
-#define THERMAL_MAX_TRIPS 12
-#define THERMAL_NAME_LENGTH 20
 struct thermal_cooling_device {
 	int id;
 	char type[THERMAL_NAME_LENGTH];
@@ -100,10 +136,6 @@ struct thermal_cooling_device {
 	struct list_head node;
 };
 
-#define KELVIN_TO_CELSIUS(t)	(long)(((long)t-2732 >= 0) ?	\
-				((long)t-2732+5)/10 : ((long)t-2732-5)/10)
-#define CELSIUS_TO_KELVIN(t)	((t)*10+2732)
-
 struct thermal_attr {
 	struct device_attribute attr;
 	char name[THERMAL_NAME_LENGTH];
@@ -131,38 +163,13 @@ struct thermal_zone_device {
 	struct list_head node;
 	struct delayed_work poll_queue;
 };
-/* Adding event notification support elements */
-#define THERMAL_GENL_FAMILY_NAME                "thermal_event"
-#define THERMAL_GENL_VERSION                    0x01
-#define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_group"
-
-enum events {
-	THERMAL_AUX0,
-	THERMAL_AUX1,
-	THERMAL_CRITICAL,
-	THERMAL_DEV_FAULT,
-};
 
 struct thermal_genl_event {
 	u32 orig;
 	enum events event;
 };
-/* attributes of thermal_genl_family */
-enum {
-	THERMAL_GENL_ATTR_UNSPEC,
-	THERMAL_GENL_ATTR_EVENT,
-	__THERMAL_GENL_ATTR_MAX,
-};
-#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
-
-/* commands supported by the thermal_genl_family */
-enum {
-	THERMAL_GENL_CMD_UNSPEC,
-	THERMAL_GENL_CMD_EVENT,
-	__THERMAL_GENL_CMD_MAX,
-};
-#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
 
+/* Function declarations */
 struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
 		void *, const struct thermal_zone_device_ops *, int, int);
 void thermal_zone_device_unregister(struct thermal_zone_device *);
@@ -173,6 +180,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
 				       struct thermal_cooling_device *);
 void thermal_zone_device_update(struct thermal_zone_device *);
+
 struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
 		const struct thermal_cooling_device_ops *);
 void thermal_cooling_device_unregister(struct thermal_cooling_device *);
-- 
1.7.9.5


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

* [PATCHv4 02/15] Thermal: Move thermal_instance to thermal_core.h
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 01/15] Thermal: Refactor thermal.h file Durgadoss R
@ 2012-09-18  5:34 ` Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 03/15] Thermal: Add get trend, get instance API's to thermal_sys Durgadoss R
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch creates a thermal_core.h file which can contain
all defines used by the core thermal framework files. For
now, move the thermal_instance structure to thermal_core.h
This structure is used by files under drivers/thermal/.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_core.h |   53 ++++++++++++++++++++++++++++++++++++++++
 drivers/thermal/thermal_sys.c  |   23 ++---------------
 2 files changed, 55 insertions(+), 21 deletions(-)
 create mode 100644 drivers/thermal/thermal_core.h

diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
new file mode 100644
index 0000000..0d3205a
--- /dev/null
+++ b/drivers/thermal/thermal_core.h
@@ -0,0 +1,53 @@
+/*
+ *  thermal_core.h
+ *
+ *  Copyright (C) 2012  Intel Corp
+ *  Author: Durgadoss R <durgadoss.r@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef __THERMAL_CORE_H__
+#define __THERMAL_CORE_H__
+
+#include <linux/device.h>
+#include <linux/thermal.h>
+
+/* Initial state of a cooling device during binding */
+#define THERMAL_NO_TARGET -1UL
+
+/*
+ * This structure is used to describe the behavior of
+ * a certain cooling device on a certain trip point
+ * in a certain thermal zone
+ */
+struct thermal_instance {
+	int id;
+	char name[THERMAL_NAME_LENGTH];
+	struct thermal_zone_device *tz;
+	struct thermal_cooling_device *cdev;
+	int trip;
+	unsigned long upper;	/* Highest cooling state for this trip point */
+	unsigned long lower;	/* Lowest cooling state for this trip point */
+	unsigned long target;	/* expected cooling state */
+	char attr_name[THERMAL_NAME_LENGTH];
+	struct device_attribute attr;
+	struct list_head tz_node; /* node in tz->thermal_instances */
+	struct list_head cdev_node; /* node in cdev->thermal_instances */
+};
+
+#endif /* __THERMAL_CORE_H__ */
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 47498b8..b246d45 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -37,31 +37,12 @@
 #include <net/netlink.h>
 #include <net/genetlink.h>
 
+#include "thermal_core.h"
+
 MODULE_AUTHOR("Zhang Rui");
 MODULE_DESCRIPTION("Generic thermal management sysfs support");
 MODULE_LICENSE("GPL");
 
-#define THERMAL_NO_TARGET -1UL
-/*
- * This structure is used to describe the behavior of
- * a certain cooling device on a certain trip point
- * in a certain thermal zone
- */
-struct thermal_instance {
-	int id;
-	char name[THERMAL_NAME_LENGTH];
-	struct thermal_zone_device *tz;
-	struct thermal_cooling_device *cdev;
-	int trip;
-	unsigned long upper;	/* Highest cooling state for this trip point */
-	unsigned long lower;	/* Lowest cooling state for this trip point */
-	unsigned long target;	/* expected cooling state */
-	char attr_name[THERMAL_NAME_LENGTH];
-	struct device_attribute attr;
-	struct list_head tz_node; /* node in tz->thermal_instances */
-	struct list_head cdev_node; /* node in cdev->thermal_instances */
-};
-
 static DEFINE_IDR(thermal_tz_idr);
 static DEFINE_IDR(thermal_cdev_idr);
 static DEFINE_MUTEX(thermal_idr_lock);
-- 
1.7.9.5


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

* [PATCHv4 03/15] Thermal: Add get trend, get instance API's to thermal_sys
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 01/15] Thermal: Refactor thermal.h file Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 02/15] Thermal: Move thermal_instance to thermal_core.h Durgadoss R
@ 2012-09-18  5:34 ` Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 04/15] Thermal: Add platform level information to thermal.h Durgadoss R
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch adds the following API's to thermal_sys.c, that
can be used by other Thermal drivers.
 * get_tz_trend: obtain the trend of the given thermal zone
 * get_thermal_instance: obtain the instance corresponding
   to the given tz, cdev and the trip point.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |   40 ++++++++++++++++++++++++++++++++++++++++
 include/linux/thermal.h       |    4 ++++
 2 files changed, 44 insertions(+)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index b246d45..798c628 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -82,6 +82,46 @@ static void release_idr(struct idr *idr, struct mutex *lock, int id)
 		mutex_unlock(lock);
 }
 
+int get_tz_trend(struct thermal_zone_device *tz, int trip)
+{
+	enum thermal_trend trend;
+
+	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
+		if (tz->temperature > tz->last_temperature)
+			trend = THERMAL_TREND_RAISING;
+		else if (tz->temperature < tz->last_temperature)
+			trend = THERMAL_TREND_DROPPING;
+		else
+			trend = THERMAL_TREND_STABLE;
+	}
+
+	return trend;
+}
+EXPORT_SYMBOL(get_tz_trend);
+
+struct thermal_instance *get_thermal_instance(struct thermal_zone_device *tz,
+			struct thermal_cooling_device *cdev, int trip)
+{
+	struct thermal_instance *pos = NULL;
+	struct thermal_instance *target_instance = NULL;
+
+	mutex_lock(&tz->lock);
+	mutex_lock(&cdev->lock);
+
+	list_for_each_entry(pos, &tz->thermal_instances, tz_node) {
+		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
+			target_instance = pos;
+			break;
+		}
+	}
+
+	mutex_unlock(&cdev->lock);
+	mutex_unlock(&tz->lock);
+
+	return target_instance;
+}
+EXPORT_SYMBOL(get_thermal_instance);
+
 /* sys I/F for thermal zone */
 
 #define to_thermal_zone(_dev) \
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 8611e3e..32af124 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -185,6 +185,10 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
 		const struct thermal_cooling_device_ops *);
 void thermal_cooling_device_unregister(struct thermal_cooling_device *);
 
+int get_tz_trend(struct thermal_zone_device *, int);
+struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
+		struct thermal_cooling_device *, int);
+
 #ifdef CONFIG_NET
 extern int thermal_generate_netlink_event(u32 orig, enum events event);
 #else
-- 
1.7.9.5


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

* [PATCHv4 04/15] Thermal: Add platform level information to thermal.h
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (2 preceding siblings ...)
  2012-09-18  5:34 ` [PATCHv4 03/15] Thermal: Add get trend, get instance API's to thermal_sys Durgadoss R
@ 2012-09-18  5:34 ` Durgadoss R
  2012-09-21  7:12   ` Zhang Rui
  2012-09-18  5:34 ` [PATCHv4 05/15] Thermal: Pass zone parameters as argument to tzd_register Durgadoss R
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch adds platform level information to thermal.h
by introducing two structures to hold:
 * bind parameters for a thermal zone,
 * zone level platform parameters

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 include/linux/thermal.h |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 32af124..4caa32e 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -157,6 +157,7 @@ struct thermal_zone_device {
 	int passive;
 	unsigned int forced_passive;
 	const struct thermal_zone_device_ops *ops;
+	const struct thermal_zone_params *tzp;
 	struct list_head thermal_instances;
 	struct idr idr;
 	struct mutex lock; /* protect thermal_instances list */
@@ -164,6 +165,34 @@ struct thermal_zone_device {
 	struct delayed_work poll_queue;
 };
 
+/* Structure that holds binding parameters for a zone */
+struct thermal_bind_params {
+	struct thermal_cooling_device *cdev;
+
+	/*
+	 * This is a measure of 'how effectively these devices can
+	 * cool 'this' thermal zone. The shall be determined by platform
+	 * characterization. This is on a 'percentage' scale.
+	 * See Documentation/thermal/sysfs-api.txt for more information.
+	 */
+	int weight;
+
+	/*
+	 * This is a bit mask that gives the binding relation between this
+	 * thermal zone and cdev, for a particular trip point.
+	 * See Documentation/thermal/sysfs-api.txt for more information.
+	 */
+	int trip_mask;
+	int (*match) (struct thermal_zone_device *tz,
+			struct thermal_cooling_device *cdev);
+};
+
+/* Structure to define Thermal Zone parameters */
+struct thermal_zone_params {
+	int num_tbps;	/* Number of tbp entries */
+	struct thermal_bind_params *tbp;
+};
+
 struct thermal_genl_event {
 	u32 orig;
 	enum events event;
-- 
1.7.9.5


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

* [PATCHv4 05/15] Thermal: Pass zone parameters as argument to tzd_register
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (3 preceding siblings ...)
  2012-09-18  5:34 ` [PATCHv4 04/15] Thermal: Add platform level information to thermal.h Durgadoss R
@ 2012-09-18  5:34 ` Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 06/15] Thermal: Add thermal governor registration APIs Durgadoss R
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch adds the thermal zone parameter as an argument to
the tzd_register() function call; and updates other drivers
using this function.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/acpi/thermal.c                             |    6 +++---
 drivers/platform/x86/acerhdf.c                     |    2 +-
 drivers/platform/x86/intel_mid_thermal.c           |    2 +-
 drivers/power/power_supply_core.c                  |    2 +-
 drivers/staging/omap-thermal/omap-thermal-common.c |    2 +-
 drivers/thermal/exynos_thermal.c                   |    2 +-
 drivers/thermal/rcar_thermal.c                     |    2 +-
 drivers/thermal/spear_thermal.c                    |    2 +-
 drivers/thermal/thermal_sys.c                      |    3 +++
 include/linux/thermal.h                            |    3 ++-
 10 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index bd66bd2..d999eda 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -898,14 +898,14 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
 	if (tz->trips.passive.flags.valid)
 		tz->thermal_zone =
 			thermal_zone_device_register("acpitz", trips, 0, tz,
-						     &acpi_thermal_zone_ops,
+						&acpi_thermal_zone_ops, NULL,
 						     tz->trips.passive.tsp*100,
 						     tz->polling_frequency*100);
 	else
 		tz->thermal_zone =
 			thermal_zone_device_register("acpitz", trips, 0, tz,
-						     &acpi_thermal_zone_ops, 0,
-						     tz->polling_frequency*100);
+						&acpi_thermal_zone_ops, NULL,
+						0, tz->polling_frequency*100);
 	if (IS_ERR(tz->thermal_zone))
 		return -ENODEV;
 
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 84c5688..c2e3e63 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
 		return -EINVAL;
 
 	thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
-					      &acerhdf_dev_ops, 0,
+					      &acerhdf_dev_ops, NULL, 0,
 					      (kernelmode) ? interval*1000 : 0);
 	if (IS_ERR(thz_dev))
 		return -EINVAL;
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
index c809761..93de090 100644
--- a/drivers/platform/x86/intel_mid_thermal.c
+++ b/drivers/platform/x86/intel_mid_thermal.c
@@ -502,7 +502,7 @@ static int mid_thermal_probe(struct platform_device *pdev)
 			goto err;
 		}
 		pinfo->tzd[i] = thermal_zone_device_register(name[i],
-				0, 0, td_info, &tzd_ops, 0, 0);
+				0, 0, td_info, &tzd_ops, NULL, 0, 0);
 		if (IS_ERR(pinfo->tzd[i])) {
 			kfree(td_info);
 			ret = PTR_ERR(pinfo->tzd[i]);
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 2436f13..f77a412 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -201,7 +201,7 @@ static int psy_register_thermal(struct power_supply *psy)
 	for (i = 0; i < psy->num_properties; i++) {
 		if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
 			psy->tzd = thermal_zone_device_register(psy->name, 0, 0,
-					psy, &psy_tzd_ops, 0, 0);
+					psy, &psy_tzd_ops, NULL, 0, 0);
 			if (IS_ERR(psy->tzd))
 				return PTR_ERR(psy->tzd);
 			break;
diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c
index b4cd6cc..342be75 100644
--- a/drivers/staging/omap-thermal/omap-thermal-common.c
+++ b/drivers/staging/omap-thermal/omap-thermal-common.c
@@ -248,7 +248,7 @@ int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id,
 	/* Create thermal zone */
 	data->omap_thermal = thermal_zone_device_register(domain,
 				OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops,
-				0, FAST_TEMP_MONITORING_RATE);
+				NULL, FAST_TEMP_MONITORING_RATE, 0);
 	if (IS_ERR_OR_NULL(data->omap_thermal)) {
 		dev_err(bg_ptr->dev, "thermal zone device is NULL\n");
 		return PTR_ERR(data->omap_thermal);
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
index e84acde..4b203b6 100644
--- a/drivers/thermal/exynos_thermal.c
+++ b/drivers/thermal/exynos_thermal.c
@@ -451,7 +451,7 @@ static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
 	th_zone->cool_dev_size++;
 
 	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
-			EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, 0,
+			EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
 			IDLE_INTERVAL);
 
 	if (IS_ERR(th_zone->therm_dev)) {
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index d445271..b13fe5d 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -211,7 +211,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
 	}
 
 	zone = thermal_zone_device_register("rcar_thermal", 0, priv,
-					    &rcar_thermal_zone_ops, 0, 0);
+				    &rcar_thermal_zone_ops, NULL, 0, 0);
 	if (IS_ERR(zone)) {
 		dev_err(&pdev->dev, "thermal zone device is NULL\n");
 		ret = PTR_ERR(zone);
diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
index 9bc9692..6b2d8b2 100644
--- a/drivers/thermal/spear_thermal.c
+++ b/drivers/thermal/spear_thermal.c
@@ -147,7 +147,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
 	writel_relaxed(stdev->flags, stdev->thermal_base);
 
 	spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
-				stdev, &ops, 0, 0);
+				stdev, &ops, NULL, 0, 0);
 	if (IS_ERR(spear_thermal)) {
 		dev_err(&pdev->dev, "thermal zone device is NULL\n");
 		ret = PTR_ERR(spear_thermal);
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 798c628..980d347 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1344,6 +1344,7 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
  * @mask:	a bit string indicating the writeablility of trip points
  * @devdata:	private device data
  * @ops:	standard thermal zone device callbacks
+ * @tzp:	thermal zone platform parameters
  * @passive_delay: number of milliseconds to wait between polls when
  *		   performing passive cooling
  * @polling_delay: number of milliseconds to wait between polls when checking
@@ -1356,6 +1357,7 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
 struct thermal_zone_device *thermal_zone_device_register(const char *type,
 	int trips, int mask, void *devdata,
 	const struct thermal_zone_device_ops *ops,
+	const struct thermal_zone_params *tzp,
 	int passive_delay, int polling_delay)
 {
 	struct thermal_zone_device *tz;
@@ -1389,6 +1391,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
 
 	strcpy(tz->type, type ? : "");
 	tz->ops = ops;
+	tz->tzp = tzp;
 	tz->device.class = &thermal_class;
 	tz->devdata = devdata;
 	tz->trips = trips;
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 4caa32e..58cb1c0 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -200,7 +200,8 @@ struct thermal_genl_event {
 
 /* Function declarations */
 struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
-		void *, const struct thermal_zone_device_ops *, int, int);
+		void *, const struct thermal_zone_device_ops *,
+		const struct thermal_zone_params *, int, int);
 void thermal_zone_device_unregister(struct thermal_zone_device *);
 
 int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
-- 
1.7.9.5


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

* [PATCHv4 06/15] Thermal: Add thermal governor registration APIs
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (4 preceding siblings ...)
  2012-09-18  5:34 ` [PATCHv4 05/15] Thermal: Pass zone parameters as argument to tzd_register Durgadoss R
@ 2012-09-18  5:34 ` Durgadoss R
  2012-09-18  5:34 ` [PATCHv4 07/15] Thermal: Add a policy sysfs attribute Durgadoss R
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch creates a structure to hold platform
thermal governor information, and provides APIs
for individual thermal governors to register/unregister
with the Thermal framework.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |   90 +++++++++++++++++++++++++++++++++++++++++
 include/linux/thermal.h       |   16 ++++++++
 2 files changed, 106 insertions(+)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 980d347..a67c6c0 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -49,7 +49,86 @@ static DEFINE_MUTEX(thermal_idr_lock);
 
 static LIST_HEAD(thermal_tz_list);
 static LIST_HEAD(thermal_cdev_list);
+static LIST_HEAD(thermal_governor_list);
+
 static DEFINE_MUTEX(thermal_list_lock);
+static DEFINE_MUTEX(thermal_governor_lock);
+
+static struct thermal_governor *__find_governor(const char *name)
+{
+	struct thermal_governor *pos;
+
+	list_for_each_entry(pos, &thermal_governor_list, governor_list)
+		if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH))
+			return pos;
+
+	return NULL;
+}
+
+int thermal_register_governor(struct thermal_governor *governor)
+{
+	int err;
+	const char *name;
+	struct thermal_zone_device *pos;
+
+	if (!governor)
+		return -EINVAL;
+
+	mutex_lock(&thermal_governor_lock);
+
+	err = -EBUSY;
+	if (__find_governor(governor->name) == NULL) {
+		err = 0;
+		list_add(&governor->governor_list, &thermal_governor_list);
+	}
+
+	mutex_lock(&thermal_list_lock);
+
+	list_for_each_entry(pos, &thermal_tz_list, node) {
+		if (pos->governor)
+			continue;
+		if (pos->tzp)
+			name = pos->tzp->governor_name;
+		else
+			name = DEFAULT_THERMAL_GOVERNOR;
+		if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH))
+			pos->governor = governor;
+	}
+
+	mutex_unlock(&thermal_list_lock);
+	mutex_unlock(&thermal_governor_lock);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(thermal_register_governor);
+
+void thermal_unregister_governor(struct thermal_governor *governor)
+{
+	struct thermal_zone_device *pos;
+
+	if (!governor)
+		return;
+
+	mutex_lock(&thermal_governor_lock);
+
+	if (__find_governor(governor->name) == NULL)
+		goto exit;
+
+	mutex_lock(&thermal_list_lock);
+
+	list_for_each_entry(pos, &thermal_tz_list, node) {
+		if (!strnicmp(pos->governor->name, governor->name,
+						THERMAL_NAME_LENGTH))
+			pos->governor = NULL;
+	}
+
+	mutex_unlock(&thermal_list_lock);
+	list_del(&governor->governor_list);
+exit:
+	mutex_unlock(&thermal_governor_lock);
+	return;
+}
+EXPORT_SYMBOL_GPL(thermal_unregister_governor);
 
 static int get_idr(struct idr *idr, struct mutex *lock, int *id)
 {
@@ -1440,6 +1519,16 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
 	if (result)
 		goto unregister;
 
+	/* Update 'this' zone's governor information */
+	mutex_lock(&thermal_governor_lock);
+
+	if (tz->tzp)
+		tz->governor = __find_governor(tz->tzp->governor_name);
+	else
+		tz->governor = __find_governor(DEFAULT_THERMAL_GOVERNOR);
+
+	mutex_unlock(&thermal_governor_lock);
+
 	result = thermal_add_hwmon_sysfs(tz);
 	if (result)
 		goto unregister;
@@ -1503,6 +1592,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 	if (tz->ops->get_mode)
 		device_remove_file(&tz->device, &dev_attr_mode);
 	remove_trip_attrs(tz);
+	tz->governor = NULL;
 
 	thermal_remove_hwmon_sysfs(tz);
 	release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 58cb1c0..6182bd5 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -46,6 +46,9 @@
 #define THERMAL_GENL_VERSION                    0x01
 #define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_group"
 
+/* Default Thermal Governor: Does Linear Throttling */
+#define DEFAULT_THERMAL_GOVERNOR	"step_wise"
+
 struct thermal_zone_device;
 struct thermal_cooling_device;
 
@@ -158,6 +161,7 @@ struct thermal_zone_device {
 	unsigned int forced_passive;
 	const struct thermal_zone_device_ops *ops;
 	const struct thermal_zone_params *tzp;
+	struct thermal_governor *governor;
 	struct list_head thermal_instances;
 	struct idr idr;
 	struct mutex lock; /* protect thermal_instances list */
@@ -165,6 +169,14 @@ struct thermal_zone_device {
 	struct delayed_work poll_queue;
 };
 
+/* Structure that holds thermal governor information */
+struct thermal_governor {
+	char name[THERMAL_NAME_LENGTH];
+	int (*throttle)(struct thermal_zone_device *tz, int trip);
+	struct list_head	governor_list;
+	struct module		*owner;
+};
+
 /* Structure that holds binding parameters for a zone */
 struct thermal_bind_params {
 	struct thermal_cooling_device *cdev;
@@ -189,6 +201,7 @@ struct thermal_bind_params {
 
 /* Structure to define Thermal Zone parameters */
 struct thermal_zone_params {
+	char governor_name[THERMAL_NAME_LENGTH];
 	int num_tbps;	/* Number of tbp entries */
 	struct thermal_bind_params *tbp;
 };
@@ -219,6 +232,9 @@ int get_tz_trend(struct thermal_zone_device *, int);
 struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
 		struct thermal_cooling_device *, int);
 
+int thermal_register_governor(struct thermal_governor *);
+void thermal_unregister_governor(struct thermal_governor *);
+
 #ifdef CONFIG_NET
 extern int thermal_generate_netlink_event(u32 orig, enum events event);
 #else
-- 
1.7.9.5


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

* [PATCHv4 07/15] Thermal: Add a policy sysfs attribute
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (5 preceding siblings ...)
  2012-09-18  5:34 ` [PATCHv4 06/15] Thermal: Add thermal governor registration APIs Durgadoss R
@ 2012-09-18  5:34 ` Durgadoss R
  2012-09-21  8:07   ` Zhang Rui
  2012-09-18  5:34 ` [PATCHv4 08/15] Thermal: Update binding logic based on platform data Durgadoss R
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch adds a policy sysfs attribute to a thermal zone.
This attribute denotes the throttling governor used for the
zone. This is a RW attribute.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |   42 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index a67c6c0..0948a60 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -454,10 +454,41 @@ passive_show(struct device *dev, struct device_attribute *attr,
 	return sprintf(buf, "%d\n", tz->forced_passive);
 }
 
+static ssize_t
+policy_store(struct device *dev, struct device_attribute *attr,
+		    const char *buf, size_t count)
+{
+	int ret = -EINVAL;
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	struct thermal_governor *gov;
+
+	mutex_lock(&thermal_governor_lock);
+
+	gov = __find_governor(buf);
+	if (!gov)
+		goto exit;
+
+	tz->governor = gov;
+	ret = count;
+
+exit:
+	mutex_unlock(&thermal_governor_lock);
+	return ret;
+}
+
+static ssize_t
+policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+
+	return sprintf(buf, "%s\n", tz->governor->name);
+}
+
 static DEVICE_ATTR(type, 0444, type_show, NULL);
 static DEVICE_ATTR(temp, 0444, temp_show, NULL);
 static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
 static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
+static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store);
 
 /* sys I/F for cooling device */
 #define to_cooling_device(_dev)	\
@@ -1512,10 +1543,14 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
 			passive = 1;
 	}
 
-	if (!passive)
-		result = device_create_file(&tz->device,
-					    &dev_attr_passive);
+	if (!passive) {
+		result = device_create_file(&tz->device, &dev_attr_passive);
+		if (result)
+			goto unregister;
+	}
 
+	/* Create policy attribute */
+	result = device_create_file(&tz->device, &dev_attr_policy);
 	if (result)
 		goto unregister;
 
@@ -1591,6 +1626,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 	device_remove_file(&tz->device, &dev_attr_temp);
 	if (tz->ops->get_mode)
 		device_remove_file(&tz->device, &dev_attr_mode);
+	device_remove_file(&tz->device, &dev_attr_policy);
 	remove_trip_attrs(tz);
 	tz->governor = NULL;
 
-- 
1.7.9.5


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

* [PATCHv4 08/15] Thermal: Update binding logic based on platform data
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (6 preceding siblings ...)
  2012-09-18  5:34 ` [PATCHv4 07/15] Thermal: Add a policy sysfs attribute Durgadoss R
@ 2012-09-18  5:34 ` Durgadoss R
  2012-09-18  5:35 ` [PATCHv4 09/15] Thermal: Make thermal_cdev_update as a global function Durgadoss R
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:34 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch updates the binding logic in thermal_sys.c
It uses the platform layer data to bind a thermal zone
to a cdev for a particular trip point.

 * If we do not have platform data and do not have
   .bind defined, do not bind.
 * If we do not have platform data but .bind is
   defined, then use tz->ops->bind.
 * If we have platform data, use it to create binding.

The same logic sequence is followed for unbind also.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |  183 +++++++++++++++++++++++++++++++++++------
 1 file changed, 157 insertions(+), 26 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 0948a60..013f33b 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -201,6 +201,111 @@ struct thermal_instance *get_thermal_instance(struct thermal_zone_device *tz,
 }
 EXPORT_SYMBOL(get_thermal_instance);
 
+static void print_bind_err_msg(struct thermal_zone_device *tz,
+			struct thermal_cooling_device *cdev, int ret)
+{
+	dev_err(&tz->device, "binding zone %s with cdev %s failed:%d\n",
+				tz->type, cdev->type, ret);
+}
+
+static void __bind(struct thermal_zone_device *tz, int mask,
+			struct thermal_cooling_device *cdev)
+{
+	int i, ret;
+
+	for (i = 0; i < tz->trips; i++) {
+		if (mask & (1 << i)) {
+			ret = thermal_zone_bind_cooling_device(tz, i, cdev,
+					THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
+			if (ret)
+				print_bind_err_msg(tz, cdev, ret);
+		}
+	}
+}
+
+static void __unbind(struct thermal_zone_device *tz, int mask,
+			struct thermal_cooling_device *cdev)
+{
+	int i;
+
+	for (i = 0; i < tz->trips; i++)
+		if (mask & (1 << i))
+			thermal_zone_unbind_cooling_device(tz, i, cdev);
+}
+
+static void bind_cdev(struct thermal_cooling_device *cdev)
+{
+	int i, ret;
+	const struct thermal_zone_params *tzp;
+	struct thermal_zone_device *pos = NULL;
+
+	mutex_lock(&thermal_list_lock);
+
+	list_for_each_entry(pos, &thermal_tz_list, node) {
+		if (!pos->tzp && !pos->ops->bind)
+			continue;
+
+		if (!pos->tzp && pos->ops->bind) {
+			ret = pos->ops->bind(pos, cdev);
+			if (ret)
+				print_bind_err_msg(pos, cdev, ret);
+		}
+
+		tzp = pos->tzp;
+		if (!tzp->tbp)
+			return;
+
+		for (i = 0; i < tzp->num_tbps; i++) {
+			if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
+				continue;
+			if (tzp->tbp[i].match(pos, cdev))
+				continue;
+			tzp->tbp[i].cdev = cdev;
+			__bind(pos, tzp->tbp[i].trip_mask, cdev);
+		}
+	}
+
+	mutex_unlock(&thermal_list_lock);
+}
+
+static void bind_tz(struct thermal_zone_device *tz)
+{
+	int i, ret;
+	struct thermal_cooling_device *pos = NULL;
+	const struct thermal_zone_params *tzp = tz->tzp;
+
+	if (!tzp && !tz->ops->bind)
+		return;
+
+	mutex_lock(&thermal_list_lock);
+
+	/* If there is no platform data, try to use ops->bind */
+	if (!tzp && tz->ops->bind) {
+		list_for_each_entry(pos, &thermal_cdev_list, node) {
+			ret = tz->ops->bind(tz, pos);
+			if (ret)
+				print_bind_err_msg(tz, pos, ret);
+		}
+		goto exit;
+	}
+
+	if (!tzp->tbp)
+		goto exit;
+
+	list_for_each_entry(pos, &thermal_cdev_list, node) {
+		for (i = 0; i < tzp->num_tbps; i++) {
+			if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
+				continue;
+			if (tzp->tbp[i].match(tz, pos))
+				continue;
+			tzp->tbp[i].cdev = pos;
+			__bind(tz, tzp->tbp[i].trip_mask, pos);
+		}
+	}
+exit:
+	mutex_unlock(&thermal_list_lock);
+}
+
 /* sys I/F for thermal zone */
 
 #define to_thermal_zone(_dev) \
@@ -1029,7 +1134,6 @@ thermal_cooling_device_register(char *type, void *devdata,
 				const struct thermal_cooling_device_ops *ops)
 {
 	struct thermal_cooling_device *cdev;
-	struct thermal_zone_device *pos;
 	int result;
 
 	if (type && strlen(type) >= THERMAL_NAME_LENGTH)
@@ -1079,20 +1183,15 @@ thermal_cooling_device_register(char *type, void *devdata,
 	if (result)
 		goto unregister;
 
+	/* Add 'this' new cdev to the global cdev list */
 	mutex_lock(&thermal_list_lock);
 	list_add(&cdev->node, &thermal_cdev_list);
-	list_for_each_entry(pos, &thermal_tz_list, node) {
-		if (!pos->ops->bind)
-			continue;
-		result = pos->ops->bind(pos, cdev);
-		if (result)
-			break;
-
-	}
 	mutex_unlock(&thermal_list_lock);
 
-	if (!result)
-		return cdev;
+	/* Update binding information for 'this' new cdev */
+	bind_cdev(cdev);
+
+	return cdev;
 
 unregister:
 	release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
@@ -1108,10 +1207,10 @@ EXPORT_SYMBOL(thermal_cooling_device_register);
  * thermal_cooling_device_unregister() must be called when the device is no
  * longer needed.
  */
-void thermal_cooling_device_unregister(struct
-				       thermal_cooling_device
-				       *cdev)
+void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
 {
+	int i;
+	const struct thermal_zone_params *tzp;
 	struct thermal_zone_device *tz;
 	struct thermal_cooling_device *pos = NULL;
 
@@ -1128,12 +1227,28 @@ void thermal_cooling_device_unregister(struct
 		return;
 	}
 	list_del(&cdev->node);
+
+	/* Unbind all thermal zones associated with 'this' cdev */
 	list_for_each_entry(tz, &thermal_tz_list, node) {
-		if (!tz->ops->unbind)
+		if (tz->ops->unbind) {
+			tz->ops->unbind(tz, cdev);
+			continue;
+		}
+
+		if (!tz->tzp || !tz->tzp->tbp)
 			continue;
-		tz->ops->unbind(tz, cdev);
+
+		tzp = tz->tzp;
+		for (i = 0; i < tzp->num_tbps; i++) {
+			if (tzp->tbp[i].cdev == cdev) {
+				__unbind(tz, tzp->tbp[i].trip_mask, cdev);
+				tzp->tbp[i].cdev = NULL;
+			}
+		}
 	}
+
 	mutex_unlock(&thermal_list_lock);
+
 	if (cdev->type[0])
 		device_remove_file(&cdev->device, &dev_attr_cdev_type);
 	device_remove_file(&cdev->device, &dev_attr_max_state);
@@ -1471,7 +1586,6 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
 	int passive_delay, int polling_delay)
 {
 	struct thermal_zone_device *tz;
-	struct thermal_cooling_device *pos;
 	enum thermal_trip_type trip_type;
 	int result;
 	int count;
@@ -1570,14 +1684,11 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
 
 	mutex_lock(&thermal_list_lock);
 	list_add_tail(&tz->node, &thermal_tz_list);
-	if (ops->bind)
-		list_for_each_entry(pos, &thermal_cdev_list, node) {
-		result = ops->bind(tz, pos);
-		if (result)
-			break;
-		}
 	mutex_unlock(&thermal_list_lock);
 
+	/* Bind cooling devices for this zone */
+	bind_tz(tz);
+
 	INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
 
 	thermal_zone_device_update(tz);
@@ -1598,12 +1709,16 @@ EXPORT_SYMBOL(thermal_zone_device_register);
  */
 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 {
+	int i;
+	const struct thermal_zone_params *tzp;
 	struct thermal_cooling_device *cdev;
 	struct thermal_zone_device *pos = NULL;
 
 	if (!tz)
 		return;
 
+	tzp = tz->tzp;
+
 	mutex_lock(&thermal_list_lock);
 	list_for_each_entry(pos, &thermal_tz_list, node)
 	    if (pos == tz)
@@ -1614,9 +1729,25 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 		return;
 	}
 	list_del(&tz->node);
-	if (tz->ops->unbind)
-		list_for_each_entry(cdev, &thermal_cdev_list, node)
-		    tz->ops->unbind(tz, cdev);
+
+	/* Unbind all cdevs associated with 'this' thermal zone */
+	list_for_each_entry(cdev, &thermal_cdev_list, node) {
+		if (tz->ops->unbind) {
+			tz->ops->unbind(tz, cdev);
+			continue;
+		}
+
+		if (!tzp || !tzp->tbp)
+			break;
+
+		for (i = 0; i < tzp->num_tbps; i++) {
+			if (tzp->tbp[i].cdev == cdev) {
+				__unbind(tz, tzp->tbp[i].trip_mask, cdev);
+				tzp->tbp[i].cdev = NULL;
+			}
+		}
+	}
+
 	mutex_unlock(&thermal_list_lock);
 
 	thermal_zone_device_set_polling(tz, 0);
-- 
1.7.9.5


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

* [PATCHv4 09/15] Thermal: Make thermal_cdev_update as a global function
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (7 preceding siblings ...)
  2012-09-18  5:34 ` [PATCHv4 08/15] Thermal: Update binding logic based on platform data Durgadoss R
@ 2012-09-18  5:35 ` Durgadoss R
  2012-09-18  5:35 ` [PATCHv4 10/15] Thermal: Introduce fair_share thermal governor Durgadoss R
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:35 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch makes the thermal_cdev_update function as a
global one, so that other files can use it. This function
serves as a single arbitrator to set the state of a cooling
device.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |    5 +++--
 include/linux/thermal.h       |    1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 013f33b..eebd11d 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1260,7 +1260,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
 }
 EXPORT_SYMBOL(thermal_cooling_device_unregister);
 
-static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
+void thermal_cdev_update(struct thermal_cooling_device *cdev)
 {
 	struct thermal_instance *instance;
 	unsigned long target = 0;
@@ -1281,13 +1281,14 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
 	cdev->ops->set_cur_state(cdev, target);
 	cdev->updated = true;
 }
+EXPORT_SYMBOL(thermal_cdev_update);
 
 static void thermal_zone_do_update(struct thermal_zone_device *tz)
 {
 	struct thermal_instance *instance;
 
 	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
-		thermal_cdev_do_update(instance->cdev);
+		thermal_cdev_update(instance->cdev);
 }
 
 /*
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 6182bd5..2bd9158 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -231,6 +231,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *);
 int get_tz_trend(struct thermal_zone_device *, int);
 struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
 		struct thermal_cooling_device *, int);
+void thermal_cdev_update(struct thermal_cooling_device *);
 
 int thermal_register_governor(struct thermal_governor *);
 void thermal_unregister_governor(struct thermal_governor *);
-- 
1.7.9.5


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

* [PATCHv4 10/15] Thermal: Introduce fair_share thermal governor
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (8 preceding siblings ...)
  2012-09-18  5:35 ` [PATCHv4 09/15] Thermal: Make thermal_cdev_update as a global function Durgadoss R
@ 2012-09-18  5:35 ` Durgadoss R
  2012-09-18  5:35 ` [PATCHv4 11/15] Thermal: Introduce a step_wise " Durgadoss R
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:35 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch introduces a simple 'weight' based
governor named fair_share governor. Whenever the
thermal framework gets notified of the trip point
violation, this governor (if configured), throttles
the cooling devices associated with a thermal zone.

This mapping between a thermal zone and a cooling device
and the effectiveness of cooling are provided in the
platform layer.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/Kconfig      |    6 ++
 drivers/thermal/Makefile     |    1 +
 drivers/thermal/fair_share.c |  133 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 140 insertions(+)
 create mode 100644 drivers/thermal/fair_share.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index edfd67d..2200912 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -53,3 +53,9 @@ config EXYNOS_THERMAL
 	help
 	  If you say yes here you get support for TMU (Thermal Managment
 	  Unit) on SAMSUNG EXYNOS series of SoC.
+
+config FAIR_SHARE
+	bool "Fair-share thermal governor"
+	depends on THERMAL
+	help
+	  Enable this to manage platform thermals using fair-share governor.
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 885550d..30540dd 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_CPU_THERMAL)		+= cpu_cooling.o
 obj-$(CONFIG_SPEAR_THERMAL)		+= spear_thermal.o
 obj-$(CONFIG_RCAR_THERMAL)	+= rcar_thermal.o
 obj-$(CONFIG_EXYNOS_THERMAL)		+= exynos_thermal.o
+obj-$(CONFIG_FAIR_SHARE)		+= fair_share.o
diff --git a/drivers/thermal/fair_share.c b/drivers/thermal/fair_share.c
new file mode 100644
index 0000000..5d3a7a3
--- /dev/null
+++ b/drivers/thermal/fair_share.c
@@ -0,0 +1,133 @@
+/*
+ *  fair_share.c - A simple weight based Thermal governor
+ *
+ *  Copyright (C) 2012 Intel Corp
+ *  Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
+ *
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/thermal.h>
+
+#include "thermal_core.h"
+
+/**
+ * get_trip_level: - obtains the current trip level for a zone
+ * @tz:		thermal zone device
+ */
+static int get_trip_level(struct thermal_zone_device *tz)
+{
+	int count = 0;
+	unsigned long trip_temp;
+
+	if (tz->trips == 0 || !tz->ops->get_trip_temp)
+		return 0;
+
+	for (count = 0; count < tz->trips; count++) {
+		tz->ops->get_trip_temp(tz, count, &trip_temp);
+		if (tz->temperature < trip_temp)
+			break;
+	}
+	return count;
+}
+
+static long get_target_state(struct thermal_zone_device *tz,
+		struct thermal_cooling_device *cdev, int weight, int level)
+{
+	unsigned long max_state;
+
+	cdev->ops->get_max_state(cdev, &max_state);
+
+	return (long)(weight * level * max_state) / (100 * tz->trips);
+}
+
+/**
+ * fair_share_throttle - throttles devices asscciated with the given zone
+ * @tz - thermal_zone_device
+ *
+ * Throttling Logic: This uses three parameters to calculate the new
+ * throttle state of the cooling devices associated with the given zone.
+ *
+ * Parameters used for Throttling:
+ * P1. max_state: Maximum throttle state exposed by the cooling device.
+ * P2. weight[i]/100:
+ *	How 'effective' the 'i'th device is, in cooling the given zone.
+ * P3. cur_trip_level/max_no_of_trips:
+ *	This describes the extent to which the devices should be throttled.
+ *	We do not want to throttle too much when we trip a lower temperature,
+ *	whereas the throttling is at full swing if we trip critical levels.
+ *	(Heavily assumes the trip points are in ascending order)
+ * new_state of cooling device = P3 * P2 * P1
+ */
+int fair_share_throttle(struct thermal_zone_device *tz, int trip)
+{
+	const struct thermal_zone_params *tzp;
+	struct thermal_cooling_device *cdev;
+	struct thermal_instance *instance;
+	int i;
+	int cur_trip_level = get_trip_level(tz);
+
+	if (!tz->tzp || !tz->tzp->tbp)
+		return -EINVAL;
+
+	tzp = tz->tzp;
+
+	for (i = 0; i < tzp->num_tbps; i++) {
+		if (!tzp->tbp[i].cdev)
+			continue;
+
+		cdev = tzp->tbp[i].cdev;
+		instance = get_thermal_instance(tz, cdev, trip);
+		if (!instance)
+			continue;
+
+		instance->target = get_target_state(tz, cdev,
+					tzp->tbp[i].weight, cur_trip_level);
+
+		instance->cdev->updated = false;
+		thermal_cdev_update(cdev);
+	}
+	return 0;
+}
+
+struct thermal_governor thermal_gov_fair_share = {
+	.name		= "fair_share",
+	.throttle	= fair_share_throttle,
+	.owner		= THIS_MODULE,
+};
+
+static int __init thermal_gov_fair_share_init(void)
+{
+	return thermal_register_governor(&thermal_gov_fair_share);
+}
+
+static void __exit thermal_gov_fair_share_exit(void)
+{
+	thermal_unregister_governor(&thermal_gov_fair_share);
+}
+
+/* This should load after thermal framework */
+fs_initcall(thermal_gov_fair_share_init);
+module_exit(thermal_gov_fair_share_exit);
+
+MODULE_AUTHOR("Durgadoss R");
+MODULE_DESCRIPTION("A simple weight based thermal throttling governor");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5


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

* [PATCHv4 11/15] Thermal: Introduce a step_wise thermal governor
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (9 preceding siblings ...)
  2012-09-18  5:35 ` [PATCHv4 10/15] Thermal: Introduce fair_share thermal governor Durgadoss R
@ 2012-09-18  5:35 ` Durgadoss R
  2012-09-18  7:13   ` Zhang Rui
  2012-09-18  5:35 ` [PATCHv4 12/15] Thermal: Add a thermal notifier for user space Durgadoss R
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:35 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch adds a simple step_wise governor to the
generic thermal layer. This algorithm throttles the
cooling devices in a linear fashion. If the 'trend'
is heating, it throttles by one step. And if the
thermal trend is cooling it de-throttles by one step.

This actually moves the throttling logic from thermal_sys.c
and puts inside step_wise.c, without any change. This is
always selected as the default governor.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/Kconfig     |    7 ++
 drivers/thermal/Makefile    |    1 +
 drivers/thermal/step_wise.c |  194 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 202 insertions(+)
 create mode 100644 drivers/thermal/step_wise.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2200912..9f6a3aa 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -4,6 +4,7 @@
 
 menuconfig THERMAL
 	tristate "Generic Thermal sysfs driver"
+	select STEP_WISE
 	help
 	  Generic Thermal Sysfs driver offers a generic mechanism for
 	  thermal management. Usually it's made up of one or more thermal
@@ -59,3 +60,9 @@ config FAIR_SHARE
 	depends on THERMAL
 	help
 	  Enable this to manage platform thermals using fair-share governor.
+
+config STEP_WISE
+	bool "Step_wise thermal governor"
+	depends on THERMAL
+	help
+	  Enable this to manage platform thermals using a simple linear
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 30540dd..4e53c00 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_SPEAR_THERMAL)		+= spear_thermal.o
 obj-$(CONFIG_RCAR_THERMAL)	+= rcar_thermal.o
 obj-$(CONFIG_EXYNOS_THERMAL)		+= exynos_thermal.o
 obj-$(CONFIG_FAIR_SHARE)		+= fair_share.o
+obj-$(CONFIG_STEP_WISE)			+= step_wise.o
diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
new file mode 100644
index 0000000..3f9cfcf
--- /dev/null
+++ b/drivers/thermal/step_wise.c
@@ -0,0 +1,194 @@
+/*
+ *  step_wise.c - A step-by-step Thermal throttling governor
+ *
+ *  Copyright (C) 2012 Intel Corp
+ *  Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
+ *
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/thermal.h>
+
+#include "thermal_core.h"
+
+/*
+ * If the temperature is higher than a trip point,
+ *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
+ *       state for this trip point
+ *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
+ *       state for this trip point
+ */
+static unsigned long get_target_state(struct thermal_instance *instance,
+					enum thermal_trend trend)
+{
+	struct thermal_cooling_device *cdev = instance->cdev;
+	unsigned long cur_state;
+
+	cdev->ops->get_cur_state(cdev, &cur_state);
+
+	if (trend == THERMAL_TREND_RAISING) {
+		cur_state = cur_state < instance->upper ?
+			    (cur_state + 1) : instance->upper;
+	} else if (trend == THERMAL_TREND_DROPPING) {
+		cur_state = cur_state > instance->lower ?
+			    (cur_state - 1) : instance->lower;
+	}
+
+	return cur_state;
+}
+
+static void update_passive_instance(struct thermal_zone_device *tz,
+				enum thermal_trip_type type, int value)
+{
+	/*
+	 * If value is +1, activate a passive instance.
+	 * If value is -1, deactivate a passive instance.
+	 */
+	if (type == THERMAL_TRIP_PASSIVE || type == THERMAL_TRIPS_NONE)
+		tz->passive += value;
+}
+
+static void update_instance_for_throttle(struct thermal_zone_device *tz,
+				int trip, enum thermal_trip_type trip_type,
+				enum thermal_trend trend)
+{
+	struct thermal_instance *instance;
+
+	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+		if (instance->trip != trip)
+			continue;
+
+		instance->target = get_target_state(instance, trend);
+
+		/* Activate a passive thermal instance */
+		if (instance->target == THERMAL_NO_TARGET)
+			update_passive_instance(tz, trip_type, 1);
+
+		instance->cdev->updated = false; /* cdev needs update */
+	}
+}
+
+static void update_instance_for_dethrottle(struct thermal_zone_device *tz,
+				int trip, enum thermal_trip_type trip_type)
+{
+	struct thermal_instance *instance;
+	struct thermal_cooling_device *cdev;
+	unsigned long cur_state;
+
+	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+		if (instance->trip != trip ||
+			instance->target == THERMAL_NO_TARGET)
+			continue;
+
+		cdev = instance->cdev;
+		cdev->ops->get_cur_state(cdev, &cur_state);
+
+		instance->target = cur_state > instance->lower ?
+			    (cur_state - 1) : THERMAL_NO_TARGET;
+
+		/* Deactivate a passive thermal instance */
+		if (instance->target == THERMAL_NO_TARGET)
+			update_passive_instance(tz, trip_type, -1);
+
+		cdev->updated = false; /* cdev needs update */
+	}
+}
+
+static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
+{
+	long trip_temp;
+	enum thermal_trip_type trip_type;
+	enum thermal_trend trend;
+
+	if (trip == THERMAL_TRIPS_NONE) {
+		trip_temp = tz->forced_passive;
+		trip_type = THERMAL_TRIPS_NONE;
+	} else {
+		tz->ops->get_trip_temp(tz, trip, &trip_temp);
+		tz->ops->get_trip_type(tz, trip, &trip_type);
+	}
+
+	trend = get_tz_trend(tz, trip);
+
+	mutex_lock(&tz->lock);
+
+	if (tz->temperature >= trip_temp)
+		update_instance_for_throttle(tz, trip, trip_type, trend);
+	else
+		update_instance_for_dethrottle(tz, trip, trip_type);
+
+	mutex_unlock(&tz->lock);
+}
+
+/**
+ * step_wise_throttle - throttles devices asscciated with the given zone
+ * @tz - thermal_zone_device
+ * @trip - the trip point
+ * @trip_type - type of the trip point
+ *
+ * Throttling Logic: This uses the trend of the thermal zone to throttle.
+ * If the thermal zone is 'heating up' this throttles all the cooling
+ * devices associated with the zone and its particular trip point, by one
+ * step. If the zone is 'cooling down' it brings back the performance of
+ * the devices by one step.
+ */
+int step_wise_throttle(struct thermal_zone_device *tz, int trip)
+{
+	struct thermal_instance *instance;
+
+	thermal_zone_trip_update(tz, trip);
+
+	if (tz->forced_passive)
+		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE);
+
+	mutex_lock(&tz->lock);
+
+	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
+		thermal_cdev_update(instance->cdev);
+
+	mutex_unlock(&tz->lock);
+
+	return 0;
+}
+
+struct thermal_governor thermal_gov_step_wise = {
+	.name		= DEFAULT_THERMAL_GOVERNOR,
+	.throttle	= step_wise_throttle,
+	.owner		= THIS_MODULE,
+};
+
+static int __init thermal_gov_step_wise_init(void)
+{
+	return thermal_register_governor(&thermal_gov_step_wise);
+}
+
+static void __exit thermal_gov_step_wise_exit(void)
+{
+	thermal_unregister_governor(&thermal_gov_step_wise);
+}
+
+/* This should load after thermal framework */
+fs_initcall(thermal_gov_step_wise_init);
+module_exit(thermal_gov_step_wise_exit);
+
+MODULE_AUTHOR("Durgadoss R");
+MODULE_DESCRIPTION("A step-by-step thermal throttling governor");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5


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

* [PATCHv4 12/15] Thermal: Add a thermal notifier for user space
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (10 preceding siblings ...)
  2012-09-18  5:35 ` [PATCHv4 11/15] Thermal: Introduce a step_wise " Durgadoss R
@ 2012-09-18  5:35 ` Durgadoss R
  2012-09-18  5:35 ` [PATCHv4 13/15] Thermal: Remove throttling logic out of thermal_sys.c Durgadoss R
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:35 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch registers a governor which will let the
user land manage the platform thermals. Whenever a
trip happens, this governor just notifies the user
space using kobj_uevent().

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/Kconfig      |    6 ++++
 drivers/thermal/Makefile     |    1 +
 drivers/thermal/user_space.c |   68 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+)
 create mode 100644 drivers/thermal/user_space.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 9f6a3aa..a3fd530 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -66,3 +66,9 @@ config STEP_WISE
 	depends on THERMAL
 	help
 	  Enable this to manage platform thermals using a simple linear
+
+config USER_SPACE
+	bool "User_space thermal governor"
+	depends on THERMAL
+	help
+	  Enable this to let the user space manage the platform thermals.
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 4e53c00..e5f7974 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_RCAR_THERMAL)	+= rcar_thermal.o
 obj-$(CONFIG_EXYNOS_THERMAL)		+= exynos_thermal.o
 obj-$(CONFIG_FAIR_SHARE)		+= fair_share.o
 obj-$(CONFIG_STEP_WISE)			+= step_wise.o
+obj-$(CONFIG_USER_SPACE)		+= user_space.o
diff --git a/drivers/thermal/user_space.c b/drivers/thermal/user_space.c
new file mode 100644
index 0000000..fb246b90
--- /dev/null
+++ b/drivers/thermal/user_space.c
@@ -0,0 +1,68 @@
+/*
+ *  user_space.c - A simple user space Thermal events notifier
+ *
+ *  Copyright (C) 2012 Intel Corp
+ *  Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
+ *
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/thermal.h>
+
+#include "thermal_core.h"
+
+/**
+ * notify_user_space - Notifies user space about thermal events
+ * @tz - thermal_zone_device
+ *
+ * This function notifies the user space through UEvents.
+ */
+int notify_user_space(struct thermal_zone_device *tz, int trip)
+{
+	mutex_lock(&tz->lock);
+	kobject_uevent(&tz->device.kobj, KOBJ_CHANGE);
+	mutex_unlock(&tz->lock);
+	return 0;
+}
+
+struct thermal_governor thermal_gov_user_space = {
+	.name		= "user_space",
+	.throttle	= notify_user_space,
+	.owner		= THIS_MODULE,
+};
+
+static int __init thermal_gov_user_space_init(void)
+{
+	return thermal_register_governor(&thermal_gov_user_space);
+}
+
+static void __exit thermal_gov_user_space_exit(void)
+{
+	thermal_unregister_governor(&thermal_gov_user_space);
+}
+
+/* This should load after thermal framework */
+fs_initcall(thermal_gov_user_space_init);
+module_exit(thermal_gov_user_space_exit);
+
+MODULE_AUTHOR("Durgadoss R");
+MODULE_DESCRIPTION("A user space Thermal notifier");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5


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

* [PATCHv4 13/15] Thermal: Remove throttling logic out of thermal_sys.c
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (11 preceding siblings ...)
  2012-09-18  5:35 ` [PATCHv4 12/15] Thermal: Add a thermal notifier for user space Durgadoss R
@ 2012-09-18  5:35 ` Durgadoss R
  2012-09-18  5:35 ` [PATCHv4 14/15] Thermal: Add a notification API Durgadoss R
  2012-09-18  5:35 ` [PATCHv4 15/15] Thermal: Add documentation for platform layer data Durgadoss R
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:35 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch removes the throttling logic out of
thermal_sys.c; also refactors the code into smaller
functions so that are easy to read/maintain.
 * Seperates the handling of critical and non-critical trips
 * Re-arranges the set_polling and device_check methods, so
   that all related functions are arranged in one place.
 * Removes the 'do_update' and 'trip_update' method, as part
   of moving the throttling logic out of thermal_sys.c

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |  313 +++++++++++++++--------------------------
 1 file changed, 112 insertions(+), 201 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index eebd11d..cde613b 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -306,6 +306,118 @@ exit:
 	mutex_unlock(&thermal_list_lock);
 }
 
+static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
+					    int delay)
+{
+	cancel_delayed_work(&(tz->poll_queue));
+
+	if (!delay)
+		return;
+
+	if (delay > 1000)
+		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
+				      round_jiffies(msecs_to_jiffies(delay)));
+	else
+		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
+				      msecs_to_jiffies(delay));
+}
+
+static void monitor_thermal_zone(struct thermal_zone_device *tz)
+{
+	mutex_lock(&tz->lock);
+
+	if (tz->passive)
+		thermal_zone_device_set_polling(tz, tz->passive_delay);
+	else if (tz->polling_delay)
+		thermal_zone_device_set_polling(tz, tz->polling_delay);
+	else
+		thermal_zone_device_set_polling(tz, 0);
+
+	mutex_unlock(&tz->lock);
+}
+
+static void handle_non_critical_trips(struct thermal_zone_device *tz,
+			int trip, enum thermal_trip_type trip_type)
+{
+	tz->governor->throttle(tz, trip);
+}
+
+static void handle_critical_trips(struct thermal_zone_device *tz,
+				int trip, enum thermal_trip_type trip_type)
+{
+	long trip_temp;
+
+	tz->ops->get_trip_temp(tz, trip, &trip_temp);
+
+	/* If we have not crossed the trip_temp, we do not care. */
+	if (tz->temperature < trip_temp)
+		return;
+
+	if (tz->ops->notify)
+		tz->ops->notify(tz, trip, trip_type);
+
+	if (trip_type == THERMAL_TRIP_CRITICAL) {
+		pr_emerg("Critical temperature reached(%d C),shutting down\n",
+			 tz->temperature / 1000);
+		orderly_poweroff(true);
+	}
+}
+
+static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
+{
+	enum thermal_trip_type type;
+
+	tz->ops->get_trip_type(tz, trip, &type);
+
+	if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
+		handle_critical_trips(tz, trip, type);
+	else
+		handle_non_critical_trips(tz, trip, type);
+	/*
+	 * Alright, we handled this trip successfully.
+	 * So, start monitoring again.
+	 */
+	monitor_thermal_zone(tz);
+}
+
+static void update_temperature(struct thermal_zone_device *tz)
+{
+	long temp;
+	int ret;
+
+	mutex_lock(&tz->lock);
+
+	ret = tz->ops->get_temp(tz, &temp);
+	if (ret) {
+		pr_warn("failed to read out thermal zone %d\n", tz->id);
+		return;
+	}
+
+	tz->last_temperature = tz->temperature;
+	tz->temperature = temp;
+
+	mutex_unlock(&tz->lock);
+}
+
+void thermal_zone_device_update(struct thermal_zone_device *tz)
+{
+	int count;
+
+	update_temperature(tz);
+
+	for (count = 0; count < tz->trips; count++)
+		handle_thermal_trip(tz, count);
+}
+EXPORT_SYMBOL(thermal_zone_device_update);
+
+static void thermal_zone_device_check(struct work_struct *work)
+{
+	struct thermal_zone_device *tz = container_of(work, struct
+						      thermal_zone_device,
+						      poll_queue.work);
+	thermal_zone_device_update(tz);
+}
+
 /* sys I/F for thermal zone */
 
 #define to_thermal_zone(_dev) \
@@ -936,30 +1048,6 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
 }
 #endif
 
-static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
-					    int delay)
-{
-	cancel_delayed_work(&(tz->poll_queue));
-
-	if (!delay)
-		return;
-
-	if (delay > 1000)
-		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
-				      round_jiffies(msecs_to_jiffies(delay)));
-	else
-		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
-				      msecs_to_jiffies(delay));
-}
-
-static void thermal_zone_device_check(struct work_struct *work)
-{
-	struct thermal_zone_device *tz = container_of(work, struct
-						      thermal_zone_device,
-						      poll_queue.work);
-	thermal_zone_device_update(tz);
-}
-
 /**
  * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
  * @tz:		thermal zone device
@@ -1283,183 +1371,6 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
 }
 EXPORT_SYMBOL(thermal_cdev_update);
 
-static void thermal_zone_do_update(struct thermal_zone_device *tz)
-{
-	struct thermal_instance *instance;
-
-	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
-		thermal_cdev_update(instance->cdev);
-}
-
-/*
- * Cooling algorithm for both active and passive cooling
- *
- * 1. if the temperature is higher than a trip point,
- *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
- *       state for this trip point
- *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
- *       state for this trip point
- *
- * 2. if the temperature is lower than a trip point, use lower
- *    cooling state for this trip point
- *
- * Note that this behaves the same as the previous passive cooling
- * algorithm.
- */
-
-static void thermal_zone_trip_update(struct thermal_zone_device *tz,
-				     int trip, long temp)
-{
-	struct thermal_instance *instance;
-	struct thermal_cooling_device *cdev = NULL;
-	unsigned long cur_state, max_state;
-	long trip_temp;
-	enum thermal_trip_type trip_type;
-	enum thermal_trend trend;
-
-	if (trip == THERMAL_TRIPS_NONE) {
-		trip_temp = tz->forced_passive;
-		trip_type = THERMAL_TRIPS_NONE;
-	} else {
-		tz->ops->get_trip_temp(tz, trip, &trip_temp);
-		tz->ops->get_trip_type(tz, trip, &trip_type);
-	}
-
-	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
-		/*
-		 * compare the current temperature and previous temperature
-		 * to get the thermal trend, if no special requirement
-		 */
-		if (tz->temperature > tz->last_temperature)
-			trend = THERMAL_TREND_RAISING;
-		else if (tz->temperature < tz->last_temperature)
-			trend = THERMAL_TREND_DROPPING;
-		else
-			trend = THERMAL_TREND_STABLE;
-	}
-
-	if (temp >= trip_temp) {
-		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
-			if (instance->trip != trip)
-				continue;
-
-			cdev = instance->cdev;
-
-			cdev->ops->get_cur_state(cdev, &cur_state);
-			cdev->ops->get_max_state(cdev, &max_state);
-
-			if (trend == THERMAL_TREND_RAISING) {
-				cur_state = cur_state < instance->upper ?
-					    (cur_state + 1) : instance->upper;
-			} else if (trend == THERMAL_TREND_DROPPING) {
-				cur_state = cur_state > instance->lower ?
-				    (cur_state - 1) : instance->lower;
-			}
-
-			/* activate a passive thermal instance */
-			if ((trip_type == THERMAL_TRIP_PASSIVE ||
-			     trip_type == THERMAL_TRIPS_NONE) &&
-			     instance->target == THERMAL_NO_TARGET)
-				tz->passive++;
-
-			instance->target = cur_state;
-			cdev->updated = false; /* cooling device needs update */
-		}
-	} else {	/* below trip */
-		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
-			if (instance->trip != trip)
-				continue;
-
-			/* Do not use the inactive thermal instance */
-			if (instance->target == THERMAL_NO_TARGET)
-				continue;
-			cdev = instance->cdev;
-			cdev->ops->get_cur_state(cdev, &cur_state);
-
-			cur_state = cur_state > instance->lower ?
-				    (cur_state - 1) : THERMAL_NO_TARGET;
-
-			/* deactivate a passive thermal instance */
-			if ((trip_type == THERMAL_TRIP_PASSIVE ||
-			     trip_type == THERMAL_TRIPS_NONE) &&
-			     cur_state == THERMAL_NO_TARGET)
-				tz->passive--;
-			instance->target = cur_state;
-			cdev->updated = false; /* cooling device needs update */
-		}
-	}
-
-	return;
-}
-/**
- * thermal_zone_device_update - force an update of a thermal zone's state
- * @ttz:	the thermal zone to update
- */
-
-void thermal_zone_device_update(struct thermal_zone_device *tz)
-{
-	int count, ret = 0;
-	long temp, trip_temp;
-	enum thermal_trip_type trip_type;
-
-	mutex_lock(&tz->lock);
-
-	if (tz->ops->get_temp(tz, &temp)) {
-		/* get_temp failed - retry it later */
-		pr_warn("failed to read out thermal zone %d\n", tz->id);
-		goto leave;
-	}
-
-	tz->last_temperature = tz->temperature;
-	tz->temperature = temp;
-
-	for (count = 0; count < tz->trips; count++) {
-		tz->ops->get_trip_type(tz, count, &trip_type);
-		tz->ops->get_trip_temp(tz, count, &trip_temp);
-
-		switch (trip_type) {
-		case THERMAL_TRIP_CRITICAL:
-			if (temp >= trip_temp) {
-				if (tz->ops->notify)
-					ret = tz->ops->notify(tz, count,
-							      trip_type);
-				if (!ret) {
-					pr_emerg("Critical temperature reached (%ld C), shutting down\n",
-						 temp/1000);
-					orderly_poweroff(true);
-				}
-			}
-			break;
-		case THERMAL_TRIP_HOT:
-			if (temp >= trip_temp)
-				if (tz->ops->notify)
-					tz->ops->notify(tz, count, trip_type);
-			break;
-		case THERMAL_TRIP_ACTIVE:
-			thermal_zone_trip_update(tz, count, temp);
-			break;
-		case THERMAL_TRIP_PASSIVE:
-			if (temp >= trip_temp || tz->passive)
-				thermal_zone_trip_update(tz, count, temp);
-			break;
-		}
-	}
-
-	if (tz->forced_passive)
-		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE, temp);
-	thermal_zone_do_update(tz);
-
-leave:
-	if (tz->passive)
-		thermal_zone_device_set_polling(tz, tz->passive_delay);
-	else if (tz->polling_delay)
-		thermal_zone_device_set_polling(tz, tz->polling_delay);
-	else
-		thermal_zone_device_set_polling(tz, 0);
-	mutex_unlock(&tz->lock);
-}
-EXPORT_SYMBOL(thermal_zone_device_update);
-
 /**
  * create_trip_attrs - create attributes for trip points
  * @tz:		the thermal zone device
-- 
1.7.9.5


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

* [PATCHv4 14/15] Thermal: Add a notification API
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (12 preceding siblings ...)
  2012-09-18  5:35 ` [PATCHv4 13/15] Thermal: Remove throttling logic out of thermal_sys.c Durgadoss R
@ 2012-09-18  5:35 ` Durgadoss R
  2012-09-18  5:35 ` [PATCHv4 15/15] Thermal: Add documentation for platform layer data Durgadoss R
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:35 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch adds a notification API which the sensor drivers'
can use to notify the framework. The framework then takes
care of the throttling according to the configured policy.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |   18 ++++++++++++++++++
 include/linux/thermal.h       |    1 +
 2 files changed, 19 insertions(+)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index cde613b..4f77d89 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1372,6 +1372,24 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
 EXPORT_SYMBOL(thermal_cdev_update);
 
 /**
+ * notify_thermal_framework - Sensor drivers use this API to notify framework
+ * @tz:		thermal zone device
+ * @trip:	indicates which trip point has been crossed
+ *
+ * This function handles the trip events from sensor drivers. It starts
+ * throttling the cooling devices according to the policy configured.
+ * For CRITICAL and HOT trip points, this notifies the respective drivers,
+ * and does actual throttling for other trip points i.e ACTIVE and PASSIVE.
+ * The throttling policy is based on the configured platform data; if no
+ * platform data is provided, this uses the step_wise throttling policy.
+ */
+void notify_thermal_framework(struct thermal_zone_device *tz, int trip)
+{
+	handle_thermal_trip(tz, trip);
+}
+EXPORT_SYMBOL(notify_thermal_framework);
+
+/**
  * create_trip_attrs - create attributes for trip points
  * @tz:		the thermal zone device
  * @mask:	Writeable trip point bitmap.
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 2bd9158..807f214 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -232,6 +232,7 @@ int get_tz_trend(struct thermal_zone_device *, int);
 struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
 		struct thermal_cooling_device *, int);
 void thermal_cdev_update(struct thermal_cooling_device *);
+void notify_thermal_framework(struct thermal_zone_device *, int);
 
 int thermal_register_governor(struct thermal_governor *);
 void thermal_unregister_governor(struct thermal_governor *);
-- 
1.7.9.5


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

* [PATCHv4 15/15] Thermal: Add documentation for platform layer data
  2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
                   ` (13 preceding siblings ...)
  2012-09-18  5:35 ` [PATCHv4 14/15] Thermal: Add a notification API Durgadoss R
@ 2012-09-18  5:35 ` Durgadoss R
  14 siblings, 0 replies; 26+ messages in thread
From: Durgadoss R @ 2012-09-18  5:35 UTC (permalink / raw)
  To: lenb, rui.zhang; +Cc: linux-acpi, eduardo.valentin, Durgadoss R

This patch adds documentation for thermal_bind_params
and thermal_zone_params structures. Also, adds details
on EXPORT_SYMBOL APIs.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 Documentation/thermal/sysfs-api.txt |   64 +++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index ca1a1a3..88c0233 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -112,6 +112,29 @@ temperature) and throttle appropriate devices.
     trip: indicates which trip point the cooling devices is associated with
 	  in this thermal zone.
 
+1.4 Thermal Zone Parameters
+1.4.1 struct thermal_bind_params
+    This structure defines the following parameters that are used to bind
+    a zone with a cooling device for a particular trip point.
+    .cdev: The cooling device pointer
+    .weight: The 'influence' of a particular cooling device on this zone.
+             This is on a percentage scale. The sum of all these weights
+             (for a particular zone) cannot exceed 100.
+    .trip_mask:This is a bit mask that gives the binding relation between
+               this thermal zone and cdev, for a particular trip point.
+               If nth bit is set, then the cdev and thermal zone are bound
+               for trip point n.
+    .match: This call back returns success(0) if the 'tz and cdev' need to
+	    be bound, as per platform data.
+1.4.2 struct thermal_zone_params
+    This structure defines the platform level parameters for a thermal zone.
+    This data, for each thermal zone should come from the platform layer.
+    This is an optional feature where some platforms can choose not to
+    provide this data.
+    .governor_name: Name of the thermal governor used for this zone
+    .num_tbps: Number of thermal_bind_params entries for this zone
+    .tbp: thermal_bind_params entries
+
 2. sysfs attributes structure
 
 RO	read only value
@@ -126,6 +149,7 @@ Thermal zone device sys I/F, created once it's registered:
     |---type:			Type of the thermal zone
     |---temp:			Current temperature
     |---mode:			Working mode of the thermal zone
+    |---policy:			Thermal governor used for this zone
     |---trip_point_[0-*]_temp:	Trip point temperature
     |---trip_point_[0-*]_type:	Trip point type
     |---trip_point_[0-*]_hyst:	Hysteresis value for this trip point
@@ -187,6 +211,10 @@ mode
 			  charge of the thermal management.
 	RW, Optional
 
+policy
+	One of the various thermal governors used for a particular zone.
+	RW, Required
+
 trip_point_[0-*]_temp
 	The temperature above which trip point will be fired.
 	Unit: millidegree Celsius
@@ -264,6 +292,7 @@ method, the sys I/F structure will be built like this:
     |---type:			acpitz
     |---temp:			37000
     |---mode:			enabled
+    |---policy:			step_wise
     |---trip_point_0_temp:	100000
     |---trip_point_0_type:	critical
     |---trip_point_1_temp:	80000
@@ -305,3 +334,38 @@ to a thermal_zone_device when it registers itself with the framework. The
 event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL,
 THERMAL_DEV_FAULT}. Notification can be sent when the current temperature
 crosses any of the configured thresholds.
+
+5. Export Symbol APIs:
+
+5.1: get_tz_trend:
+This function returns the trend of a thermal zone, i.e the rate of change
+of temperature of the thermal zone. Ideally, the thermal sensor drivers
+are supposed to implement the callback. If they don't, the thermal
+framework calculated the trend by comparing the previous and the current
+temperature values.
+
+5.2:get_thermal_instance:
+This function returns the thermal_instance corresponding to a given
+{thermal_zone, cooling_device, trip_point} combination. Returns NULL
+if such an instance does not exist.
+
+5.3:notify_thermal_framework:
+This function handles the trip events from sensor drivers. It starts
+throttling the cooling devices according to the policy configured.
+For CRITICAL and HOT trip points, this notifies the respective drivers,
+and does actual throttling for other trip points i.e ACTIVE and PASSIVE.
+The throttling policy is based on the configured platform data; if no
+platform data is provided, this uses the step_wise throttling policy.
+
+5.4:thermal_cdev_update:
+This function serves as an arbitrator to set the state of a cooling
+device. It sets the cooling device to the deepest cooling state if
+possible.
+
+5.5:thermal_register_governor:
+This function lets the various thermal governors to register themselves
+with the Thermal framework. At run time, depending on a zone's platform
+data, a particular governor is used for throttling.
+
+5.6:thermal_unregister_governor:
+This function unregisters a governor from the thermal framework.
-- 
1.7.9.5


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

* Re: [PATCHv4 11/15] Thermal: Introduce a step_wise thermal governor
  2012-09-18  5:35 ` [PATCHv4 11/15] Thermal: Introduce a step_wise " Durgadoss R
@ 2012-09-18  7:13   ` Zhang Rui
  2012-09-18  8:11     ` R, Durgadoss
  0 siblings, 1 reply; 26+ messages in thread
From: Zhang Rui @ 2012-09-18  7:13 UTC (permalink / raw)
  To: Durgadoss R; +Cc: lenb, linux-acpi, eduardo.valentin

On 二, 2012-09-18 at 11:05 +0530, Durgadoss R wrote:
> This patch adds a simple step_wise governor to the
> generic thermal layer. This algorithm throttles the
> cooling devices in a linear fashion. If the 'trend'
> is heating, it throttles by one step. And if the
> thermal trend is cooling it de-throttles by one step.
> 
> This actually moves the throttling logic from thermal_sys.c
> and puts inside step_wise.c, without any change. This is
> always selected as the default governor.
> 
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> ---
>  drivers/thermal/Kconfig     |    7 ++
>  drivers/thermal/Makefile    |    1 +
>  drivers/thermal/step_wise.c |  194 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 202 insertions(+)
>  create mode 100644 drivers/thermal/step_wise.c
> 
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 2200912..9f6a3aa 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -4,6 +4,7 @@
>  
>  menuconfig THERMAL
>  	tristate "Generic Thermal sysfs driver"
> +	select STEP_WISE
>  	help
>  	  Generic Thermal Sysfs driver offers a generic mechanism for
>  	  thermal management. Usually it's made up of one or more thermal
> @@ -59,3 +60,9 @@ config FAIR_SHARE
>  	depends on THERMAL
>  	help
>  	  Enable this to manage platform thermals using fair-share governor.
> +
> +config STEP_WISE
> +	bool "Step_wise thermal governor"
> +	depends on THERMAL
> +	help
> +	  Enable this to manage platform thermals using a simple linear

if we always wants CONFIG_STEP_WISE built in, why bother to export this
config option to users?

IMO, something like
 menuconfig THERMAL
  	tristate "Generic Thermal sysfs driver"
	select STEP_WISE

 config STEP_WISE
	bool
	depends on THERMAL

is enough, SETP_WISE will always be selected.

further more, we even do not need a config option for this governor,
just "obj-y += step_wise.o" in Makefile.

another question would be,
as this governor registration function is fs_initcall(),
what if a platform thermal driver is registered and gets a thermal event
before this governor being registered?

thanks,
rui

> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 30540dd..4e53c00 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_SPEAR_THERMAL)		+= spear_thermal.o
>  obj-$(CONFIG_RCAR_THERMAL)	+= rcar_thermal.o
>  obj-$(CONFIG_EXYNOS_THERMAL)		+= exynos_thermal.o
>  obj-$(CONFIG_FAIR_SHARE)		+= fair_share.o
> +obj-$(CONFIG_STEP_WISE)			+= step_wise.o
> diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
> new file mode 100644
> index 0000000..3f9cfcf
> --- /dev/null
> +++ b/drivers/thermal/step_wise.c
> @@ -0,0 +1,194 @@
> +/*
> + *  step_wise.c - A step-by-step Thermal throttling governor
> + *
> + *  Copyright (C) 2012 Intel Corp
> + *  Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
> + *
> + *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; version 2 of the License.
> + *
> + *  This program is distributed in the hope that it will be useful, but
> + *  WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + *  General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License along
> + *  with this program; if not, write to the Free Software Foundation, Inc.,
> + *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/module.h>
> +#include <linux/thermal.h>
> +
> +#include "thermal_core.h"
> +
> +/*
> + * If the temperature is higher than a trip point,
> + *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
> + *       state for this trip point
> + *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
> + *       state for this trip point
> + */
> +static unsigned long get_target_state(struct thermal_instance *instance,
> +					enum thermal_trend trend)
> +{
> +	struct thermal_cooling_device *cdev = instance->cdev;
> +	unsigned long cur_state;
> +
> +	cdev->ops->get_cur_state(cdev, &cur_state);
> +
> +	if (trend == THERMAL_TREND_RAISING) {
> +		cur_state = cur_state < instance->upper ?
> +			    (cur_state + 1) : instance->upper;
> +	} else if (trend == THERMAL_TREND_DROPPING) {
> +		cur_state = cur_state > instance->lower ?
> +			    (cur_state - 1) : instance->lower;
> +	}
> +
> +	return cur_state;
> +}
> +
> +static void update_passive_instance(struct thermal_zone_device *tz,
> +				enum thermal_trip_type type, int value)
> +{
> +	/*
> +	 * If value is +1, activate a passive instance.
> +	 * If value is -1, deactivate a passive instance.
> +	 */
> +	if (type == THERMAL_TRIP_PASSIVE || type == THERMAL_TRIPS_NONE)
> +		tz->passive += value;
> +}
> +
> +static void update_instance_for_throttle(struct thermal_zone_device *tz,
> +				int trip, enum thermal_trip_type trip_type,
> +				enum thermal_trend trend)
> +{
> +	struct thermal_instance *instance;
> +
> +	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> +		if (instance->trip != trip)
> +			continue;
> +
> +		instance->target = get_target_state(instance, trend);
> +
> +		/* Activate a passive thermal instance */
> +		if (instance->target == THERMAL_NO_TARGET)
> +			update_passive_instance(tz, trip_type, 1);
> +
> +		instance->cdev->updated = false; /* cdev needs update */
> +	}
> +}
> +
> +static void update_instance_for_dethrottle(struct thermal_zone_device *tz,
> +				int trip, enum thermal_trip_type trip_type)
> +{
> +	struct thermal_instance *instance;
> +	struct thermal_cooling_device *cdev;
> +	unsigned long cur_state;
> +
> +	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> +		if (instance->trip != trip ||
> +			instance->target == THERMAL_NO_TARGET)
> +			continue;
> +
> +		cdev = instance->cdev;
> +		cdev->ops->get_cur_state(cdev, &cur_state);
> +
> +		instance->target = cur_state > instance->lower ?
> +			    (cur_state - 1) : THERMAL_NO_TARGET;
> +
> +		/* Deactivate a passive thermal instance */
> +		if (instance->target == THERMAL_NO_TARGET)
> +			update_passive_instance(tz, trip_type, -1);
> +
> +		cdev->updated = false; /* cdev needs update */
> +	}
> +}
> +
> +static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
> +{
> +	long trip_temp;
> +	enum thermal_trip_type trip_type;
> +	enum thermal_trend trend;
> +
> +	if (trip == THERMAL_TRIPS_NONE) {
> +		trip_temp = tz->forced_passive;
> +		trip_type = THERMAL_TRIPS_NONE;
> +	} else {
> +		tz->ops->get_trip_temp(tz, trip, &trip_temp);
> +		tz->ops->get_trip_type(tz, trip, &trip_type);
> +	}
> +
> +	trend = get_tz_trend(tz, trip);
> +
> +	mutex_lock(&tz->lock);
> +
> +	if (tz->temperature >= trip_temp)
> +		update_instance_for_throttle(tz, trip, trip_type, trend);
> +	else
> +		update_instance_for_dethrottle(tz, trip, trip_type);
> +
> +	mutex_unlock(&tz->lock);
> +}
> +
> +/**
> + * step_wise_throttle - throttles devices asscciated with the given zone
> + * @tz - thermal_zone_device
> + * @trip - the trip point
> + * @trip_type - type of the trip point
> + *
> + * Throttling Logic: This uses the trend of the thermal zone to throttle.
> + * If the thermal zone is 'heating up' this throttles all the cooling
> + * devices associated with the zone and its particular trip point, by one
> + * step. If the zone is 'cooling down' it brings back the performance of
> + * the devices by one step.
> + */
> +int step_wise_throttle(struct thermal_zone_device *tz, int trip)
> +{
> +	struct thermal_instance *instance;
> +
> +	thermal_zone_trip_update(tz, trip);
> +
> +	if (tz->forced_passive)
> +		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE);
> +
> +	mutex_lock(&tz->lock);
> +
> +	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
> +		thermal_cdev_update(instance->cdev);
> +
> +	mutex_unlock(&tz->lock);
> +
> +	return 0;
> +}
> +
> +struct thermal_governor thermal_gov_step_wise = {
> +	.name		= DEFAULT_THERMAL_GOVERNOR,
> +	.throttle	= step_wise_throttle,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static int __init thermal_gov_step_wise_init(void)
> +{
> +	return thermal_register_governor(&thermal_gov_step_wise);
> +}
> +
> +static void __exit thermal_gov_step_wise_exit(void)
> +{
> +	thermal_unregister_governor(&thermal_gov_step_wise);
> +}
> +
> +/* This should load after thermal framework */
> +fs_initcall(thermal_gov_step_wise_init);
> +module_exit(thermal_gov_step_wise_exit);
> +
> +MODULE_AUTHOR("Durgadoss R");
> +MODULE_DESCRIPTION("A step-by-step thermal throttling governor");
> +MODULE_LICENSE("GPL");


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

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

* RE: [PATCHv4 11/15] Thermal: Introduce a step_wise thermal governor
  2012-09-18  7:13   ` Zhang Rui
@ 2012-09-18  8:11     ` R, Durgadoss
  2012-09-18  8:22       ` Zhang Rui
  0 siblings, 1 reply; 26+ messages in thread
From: R, Durgadoss @ 2012-09-18  8:11 UTC (permalink / raw)
  To: Zhang, Rui
  Cc: lenb@kernel.org, linux-acpi@vger.kernel.org,
	eduardo.valentin@ti.com

Hi Rui,


> -----Original Message-----
> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> owner@vger.kernel.org] On Behalf Of Zhang Rui
> Sent: Tuesday, September 18, 2012 12:44 PM
> To: R, Durgadoss
> Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com
> Subject: Re: [PATCHv4 11/15] Thermal: Introduce a step_wise thermal
> governor
> 
> On 二, 2012-09-18 at 11:05 +0530, Durgadoss R wrote:
> > This patch adds a simple step_wise governor to the
> > generic thermal layer. This algorithm throttles the
> > cooling devices in a linear fashion. If the 'trend'
> > is heating, it throttles by one step. And if the
> > thermal trend is cooling it de-throttles by one step.
> >
> > This actually moves the throttling logic from thermal_sys.c
> > and puts inside step_wise.c, without any change. This is
> > always selected as the default governor.
> >
> > Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> > ---
> >  drivers/thermal/Kconfig     |    7 ++
> >  drivers/thermal/Makefile    |    1 +
> >  drivers/thermal/step_wise.c |  194
> +++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 202 insertions(+)
> >  create mode 100644 drivers/thermal/step_wise.c
> >
> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > index 2200912..9f6a3aa 100644
> > --- a/drivers/thermal/Kconfig
> > +++ b/drivers/thermal/Kconfig
> > @@ -4,6 +4,7 @@
> >
> >  menuconfig THERMAL
> >  	tristate "Generic Thermal sysfs driver"
> > +	select STEP_WISE
> >  	help
> >  	  Generic Thermal Sysfs driver offers a generic mechanism for
> >  	  thermal management. Usually it's made up of one or more thermal
> > @@ -59,3 +60,9 @@ config FAIR_SHARE
> >  	depends on THERMAL
> >  	help
> >  	  Enable this to manage platform thermals using fair-share governor.
> > +
> > +config STEP_WISE
> > +	bool "Step_wise thermal governor"
> > +	depends on THERMAL
> > +	help
> > +	  Enable this to manage platform thermals using a simple linear
> 
> if we always wants CONFIG_STEP_WISE built in, why bother to export this
> config option to users?
> 
> IMO, something like
>  menuconfig THERMAL
>   	tristate "Generic Thermal sysfs driver"
> 	select STEP_WISE
> 
>  config STEP_WISE
> 	bool
> 	depends on THERMAL
> 
> is enough, SETP_WISE will always be selected.
> 
> further more, we even do not need a config option for this governor,
> just "obj-y += step_wise.o" in Makefile.

Yes, Thought through this. But I thought it would be good to align this
with the rest of the governors.

> 
> another question would be,
> as this governor registration function is fs_initcall(),
> what if a platform thermal driver is registered and gets a thermal event
> before this governor being registered?

Wonder if this can happen with the current code, since the
thermal_sys.c also loads with fs_initcall.

Thanks,
Durga

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

* RE: [PATCHv4 11/15] Thermal: Introduce a step_wise thermal governor
  2012-09-18  8:11     ` R, Durgadoss
@ 2012-09-18  8:22       ` Zhang Rui
  2012-09-18  8:32         ` R, Durgadoss
  0 siblings, 1 reply; 26+ messages in thread
From: Zhang Rui @ 2012-09-18  8:22 UTC (permalink / raw)
  To: R, Durgadoss
  Cc: lenb@kernel.org, linux-acpi@vger.kernel.org,
	eduardo.valentin@ti.com

On 二, 2012-09-18 at 02:11 -0600, R, Durgadoss wrote:
> Hi Rui,
> 
> 
> > -----Original Message-----
> > From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> > owner@vger.kernel.org] On Behalf Of Zhang Rui
> > Sent: Tuesday, September 18, 2012 12:44 PM
> > To: R, Durgadoss
> > Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com
> > Subject: Re: [PATCHv4 11/15] Thermal: Introduce a step_wise thermal
> > governor
> > 
> > On 二, 2012-09-18 at 11:05 +0530, Durgadoss R wrote:
> > > This patch adds a simple step_wise governor to the
> > > generic thermal layer. This algorithm throttles the
> > > cooling devices in a linear fashion. If the 'trend'
> > > is heating, it throttles by one step. And if the
> > > thermal trend is cooling it de-throttles by one step.
> > >
> > > This actually moves the throttling logic from thermal_sys.c
> > > and puts inside step_wise.c, without any change. This is
> > > always selected as the default governor.
> > >
> > > Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> > > ---
> > >  drivers/thermal/Kconfig     |    7 ++
> > >  drivers/thermal/Makefile    |    1 +
> > >  drivers/thermal/step_wise.c |  194
> > +++++++++++++++++++++++++++++++++++++++++++
> > >  3 files changed, 202 insertions(+)
> > >  create mode 100644 drivers/thermal/step_wise.c
> > >
> > > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > > index 2200912..9f6a3aa 100644
> > > --- a/drivers/thermal/Kconfig
> > > +++ b/drivers/thermal/Kconfig
> > > @@ -4,6 +4,7 @@
> > >
> > >  menuconfig THERMAL
> > >  	tristate "Generic Thermal sysfs driver"
> > > +	select STEP_WISE
> > >  	help
> > >  	  Generic Thermal Sysfs driver offers a generic mechanism for
> > >  	  thermal management. Usually it's made up of one or more thermal
> > > @@ -59,3 +60,9 @@ config FAIR_SHARE
> > >  	depends on THERMAL
> > >  	help
> > >  	  Enable this to manage platform thermals using fair-share governor.
> > > +
> > > +config STEP_WISE
> > > +	bool "Step_wise thermal governor"
> > > +	depends on THERMAL
> > > +	help
> > > +	  Enable this to manage platform thermals using a simple linear
> > 
> > if we always wants CONFIG_STEP_WISE built in, why bother to export this
> > config option to users?
> > 
> > IMO, something like
> >  menuconfig THERMAL
> >   	tristate "Generic Thermal sysfs driver"
> > 	select STEP_WISE
> > 
> >  config STEP_WISE
> > 	bool
> > 	depends on THERMAL
> > 
> > is enough, SETP_WISE will always be selected.
> > 
> > further more, we even do not need a config option for this governor,
> > just "obj-y += step_wise.o" in Makefile.
> 
> Yes, Thought through this. But I thought it would be good to align this
> with the rest of the governors.
> 

we'd better follow cpufreq governor to allow users to select the default
governor, or else this configure option is needless because we never
want it to be cleared with CONFIG_THERMAL=y.

> > 
> > another question would be,
> > as this governor registration function is fs_initcall(),
> > what if a platform thermal driver is registered and gets a thermal event
> > before this governor being registered?
> 
> Wonder if this can happen with the current code, since the
> thermal_sys.c also loads with fs_initcall.
> 
you're right. this is not a problem.

thanks,
rui

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

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

* RE: [PATCHv4 11/15] Thermal: Introduce a step_wise thermal governor
  2012-09-18  8:22       ` Zhang Rui
@ 2012-09-18  8:32         ` R, Durgadoss
  0 siblings, 0 replies; 26+ messages in thread
From: R, Durgadoss @ 2012-09-18  8:32 UTC (permalink / raw)
  To: Zhang, Rui
  Cc: lenb@kernel.org, linux-acpi@vger.kernel.org,
	eduardo.valentin@ti.com

Hi Rui,


> -----Original Message-----
> From: Zhang, Rui
> Sent: Tuesday, September 18, 2012 1:52 PM
> To: R, Durgadoss
> Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com
> Subject: RE: [PATCHv4 11/15] Thermal: Introduce a step_wise thermal
> governor
> 
> On 二, 2012-09-18 at 02:11 -0600, R, Durgadoss wrote:
> > Hi Rui,
> >
> >
> > > -----Original Message-----
> > > From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> > > owner@vger.kernel.org] On Behalf Of Zhang Rui
> > > Sent: Tuesday, September 18, 2012 12:44 PM
> > > To: R, Durgadoss
> > > Cc: lenb@kernel.org; linux-acpi@vger.kernel.org;
> eduardo.valentin@ti.com
> > > Subject: Re: [PATCHv4 11/15] Thermal: Introduce a step_wise thermal
> > > governor
> > >
> > > On 二, 2012-09-18 at 11:05 +0530, Durgadoss R wrote:
> > > > This patch adds a simple step_wise governor to the
> > > > generic thermal layer. This algorithm throttles the
> > > > cooling devices in a linear fashion. If the 'trend'
> > > > is heating, it throttles by one step. And if the
> > > > thermal trend is cooling it de-throttles by one step.
> > > >
> > > > This actually moves the throttling logic from thermal_sys.c
> > > > and puts inside step_wise.c, without any change. This is
> > > > always selected as the default governor.
> > > >
> > > > Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> > > > ---
> > > >  drivers/thermal/Kconfig     |    7 ++
> > > >  drivers/thermal/Makefile    |    1 +
> > > >  drivers/thermal/step_wise.c |  194
> > > +++++++++++++++++++++++++++++++++++++++++++
> > > >  3 files changed, 202 insertions(+)
> > > >  create mode 100644 drivers/thermal/step_wise.c
> > > >
> > > > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > > > index 2200912..9f6a3aa 100644
> > > > --- a/drivers/thermal/Kconfig
> > > > +++ b/drivers/thermal/Kconfig
> > > > @@ -4,6 +4,7 @@
> > > >
> > > >  menuconfig THERMAL
> > > >  	tristate "Generic Thermal sysfs driver"
> > > > +	select STEP_WISE
> > > >  	help
> > > >  	  Generic Thermal Sysfs driver offers a generic mechanism for
> > > >  	  thermal management. Usually it's made up of one or more thermal
> > > > @@ -59,3 +60,9 @@ config FAIR_SHARE
> > > >  	depends on THERMAL
> > > >  	help
> > > >  	  Enable this to manage platform thermals using fair-share governor.
> > > > +
> > > > +config STEP_WISE
> > > > +	bool "Step_wise thermal governor"
> > > > +	depends on THERMAL
> > > > +	help
> > > > +	  Enable this to manage platform thermals using a simple linear
> > >
> > > if we always wants CONFIG_STEP_WISE built in, why bother to export
> this
> > > config option to users?
> > >
> > > IMO, something like
> > >  menuconfig THERMAL
> > >   	tristate "Generic Thermal sysfs driver"
> > > 	select STEP_WISE
> > >
> > >  config STEP_WISE
> > > 	bool
> > > 	depends on THERMAL
> > >
> > > is enough, SETP_WISE will always be selected.
> > >
> > > further more, we even do not need a config option for this governor,
> > > just "obj-y += step_wise.o" in Makefile.
> >
> > Yes, Thought through this. But I thought it would be good to align this
> > with the rest of the governors.
> >
> 
> we'd better follow cpufreq governor to allow users to select the default
> governor, or else this configure option is needless because we never
> want it to be cleared with CONFIG_THERMAL=y.

I would prefer not to give any configure option, which exactly
is our old behavior. In this case, you want me to fix it and
re-send 11/15 or you are reviewing and should I wait for
comments on other patches ?

Thanks,
Durga

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

* Re: [PATCHv4 04/15] Thermal: Add platform level information to thermal.h
  2012-09-18  5:34 ` [PATCHv4 04/15] Thermal: Add platform level information to thermal.h Durgadoss R
@ 2012-09-21  7:12   ` Zhang Rui
  2012-09-21  8:07     ` R, Durgadoss
  0 siblings, 1 reply; 26+ messages in thread
From: Zhang Rui @ 2012-09-21  7:12 UTC (permalink / raw)
  To: Durgadoss R; +Cc: lenb, linux-acpi, eduardo.valentin

On 二, 2012-09-18 at 11:04 +0530, Durgadoss R wrote:
> This patch adds platform level information to thermal.h
> by introducing two structures to hold:
>  * bind parameters for a thermal zone,
>  * zone level platform parameters
> 
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> ---
>  include/linux/thermal.h |   29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 32af124..4caa32e 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -157,6 +157,7 @@ struct thermal_zone_device {
>  	int passive;
>  	unsigned int forced_passive;
>  	const struct thermal_zone_device_ops *ops;
> +	const struct thermal_zone_params *tzp;
>  	struct list_head thermal_instances;
>  	struct idr idr;
>  	struct mutex lock; /* protect thermal_instances list */
> @@ -164,6 +165,34 @@ struct thermal_zone_device {
>  	struct delayed_work poll_queue;
>  };
>  
> +/* Structure that holds binding parameters for a zone */
> +struct thermal_bind_params {
> +	struct thermal_cooling_device *cdev;
> +
> +	/*
> +	 * This is a measure of 'how effectively these devices can
> +	 * cool 'this' thermal zone. The shall be determined by platform
> +	 * characterization. This is on a 'percentage' scale.
> +	 * See Documentation/thermal/sysfs-api.txt for more information.
> +	 */
> +	int weight;
> +
> +	/*
> +	 * This is a bit mask that gives the binding relation between this
> +	 * thermal zone and cdev, for a particular trip point.
> +	 * See Documentation/thermal/sysfs-api.txt for more information.
> +	 */
> +	int trip_mask;
> +	int (*match) (struct thermal_zone_device *tz,
> +			struct thermal_cooling_device *cdev);
> +};

we do not have field to describe the upper and lower limit?

thanks.
rui
> +
> +/* Structure to define Thermal Zone parameters */
> +struct thermal_zone_params {
> +	int num_tbps;	/* Number of tbp entries */
> +	struct thermal_bind_params *tbp;
> +};
> +
>  struct thermal_genl_event {
>  	u32 orig;
>  	enum events event;


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

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

* Re: [PATCHv4 07/15] Thermal: Add a policy sysfs attribute
  2012-09-18  5:34 ` [PATCHv4 07/15] Thermal: Add a policy sysfs attribute Durgadoss R
@ 2012-09-21  8:07   ` Zhang Rui
  2012-09-21  8:09     ` R, Durgadoss
  0 siblings, 1 reply; 26+ messages in thread
From: Zhang Rui @ 2012-09-21  8:07 UTC (permalink / raw)
  To: Durgadoss R; +Cc: lenb, linux-acpi, eduardo.valentin

On 二, 2012-09-18 at 11:04 +0530, Durgadoss R wrote:
> This patch adds a policy sysfs attribute to a thermal zone.
> This attribute denotes the throttling governor used for the
> zone. This is a RW attribute.
> 
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> ---
>  drivers/thermal/thermal_sys.c |   42 ++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index a67c6c0..0948a60 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -454,10 +454,41 @@ passive_show(struct device *dev, struct device_attribute *attr,
>  	return sprintf(buf, "%d\n", tz->forced_passive);
>  }
>  
> +static ssize_t
> +policy_store(struct device *dev, struct device_attribute *attr,
> +		    const char *buf, size_t count)
> +{
> +	int ret = -EINVAL;
> +	struct thermal_zone_device *tz = to_thermal_zone(dev);
> +	struct thermal_governor *gov;
> +
> +	mutex_lock(&thermal_governor_lock);
> +
> +	gov = __find_governor(buf);
> +	if (!gov)
> +		goto exit;
> +
> +	tz->governor = gov;
> +	ret = count;
> +
> +exit:
> +	mutex_unlock(&thermal_governor_lock);
> +	return ret;
> +}
> +
> +static ssize_t
> +policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
> +{
> +	struct thermal_zone_device *tz = to_thermal_zone(dev);
> +
> +	return sprintf(buf, "%s\n", tz->governor->name);
> +}
> +

we should introduce an API for platform thermal drivers to switch their
policy.
say they may want to switch to "userspace" to disable the kernel thermal
control.
and policy_store should invoke that function directly.

BTW, IMO, deactiving all the thermal_instances and updating the cooling
devices when a thermal zone switches to "userspace" governor is
reasonable.

thanks,
rui
>  static DEVICE_ATTR(type, 0444, type_show, NULL);
>  static DEVICE_ATTR(temp, 0444, temp_show, NULL);
>  static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
>  static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
> +static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store);
>  
>  /* sys I/F for cooling device */
>  #define to_cooling_device(_dev)	\
> @@ -1512,10 +1543,14 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
>  			passive = 1;
>  	}
>  
> -	if (!passive)
> -		result = device_create_file(&tz->device,
> -					    &dev_attr_passive);
> +	if (!passive) {
> +		result = device_create_file(&tz->device, &dev_attr_passive);
> +		if (result)
> +			goto unregister;
> +	}
>  
> +	/* Create policy attribute */
> +	result = device_create_file(&tz->device, &dev_attr_policy);
>  	if (result)
>  		goto unregister;
>  
> @@ -1591,6 +1626,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
>  	device_remove_file(&tz->device, &dev_attr_temp);
>  	if (tz->ops->get_mode)
>  		device_remove_file(&tz->device, &dev_attr_mode);
> +	device_remove_file(&tz->device, &dev_attr_policy);
>  	remove_trip_attrs(tz);
>  	tz->governor = NULL;
>  


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

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

* RE: [PATCHv4 04/15] Thermal: Add platform level information to thermal.h
  2012-09-21  7:12   ` Zhang Rui
@ 2012-09-21  8:07     ` R, Durgadoss
  2012-09-24  5:43       ` Zhang Rui
  0 siblings, 1 reply; 26+ messages in thread
From: R, Durgadoss @ 2012-09-21  8:07 UTC (permalink / raw)
  To: Zhang, Rui
  Cc: lenb@kernel.org, linux-acpi@vger.kernel.org,
	eduardo.valentin@ti.com

Hi Rui,

> -----Original Message-----
> From: Zhang, Rui
> Sent: Friday, September 21, 2012 12:43 PM
> To: R, Durgadoss
> Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com
> Subject: Re: [PATCHv4 04/15] Thermal: Add platform level information to
> thermal.h
> 
> On 二, 2012-09-18 at 11:04 +0530, Durgadoss R wrote:
> > This patch adds platform level information to thermal.h
> > by introducing two structures to hold:
> >  * bind parameters for a thermal zone,
> >  * zone level platform parameters
> >
> > Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> > ---
> >  include/linux/thermal.h |   29 +++++++++++++++++++++++++++++
> >  1 file changed, 29 insertions(+)
> >
> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > index 32af124..4caa32e 100644
> > --- a/include/linux/thermal.h
> > +++ b/include/linux/thermal.h
> > @@ -157,6 +157,7 @@ struct thermal_zone_device {
> >  	int passive;
> >  	unsigned int forced_passive;
> >  	const struct thermal_zone_device_ops *ops;
> > +	const struct thermal_zone_params *tzp;
> >  	struct list_head thermal_instances;
> >  	struct idr idr;
> >  	struct mutex lock; /* protect thermal_instances list */
> > @@ -164,6 +165,34 @@ struct thermal_zone_device {
> >  	struct delayed_work poll_queue;
> >  };
> >
> > +/* Structure that holds binding parameters for a zone */
> > +struct thermal_bind_params {
> > +	struct thermal_cooling_device *cdev;
> > +
> > +	/*
> > +	 * This is a measure of 'how effectively these devices can
> > +	 * cool 'this' thermal zone. The shall be determined by platform
> > +	 * characterization. This is on a 'percentage' scale.
> > +	 * See Documentation/thermal/sysfs-api.txt for more information.
> > +	 */
> > +	int weight;
> > +
> > +	/*
> > +	 * This is a bit mask that gives the binding relation between this
> > +	 * thermal zone and cdev, for a particular trip point.
> > +	 * See Documentation/thermal/sysfs-api.txt for more information.
> > +	 */
> > +	int trip_mask;
> > +	int (*match) (struct thermal_zone_device *tz,
> > +			struct thermal_cooling_device *cdev);
> > +};
> 
> we do not have field to describe the upper and lower limit?

Looks like I missed it here :-(
But, IMO, we need an array of 'upper' and 'lower' limits here .. correct ?
Let me know how you would want to address it ?
a separate patch or fix here ?

Thanks,
Durga

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

* RE: [PATCHv4 07/15] Thermal: Add a policy sysfs attribute
  2012-09-21  8:07   ` Zhang Rui
@ 2012-09-21  8:09     ` R, Durgadoss
  2012-09-24  5:44       ` Zhang Rui
  0 siblings, 1 reply; 26+ messages in thread
From: R, Durgadoss @ 2012-09-21  8:09 UTC (permalink / raw)
  To: Zhang, Rui
  Cc: lenb@kernel.org, linux-acpi@vger.kernel.org,
	eduardo.valentin@ti.com

Hi Rui,

> -----Original Message-----
> From: Zhang, Rui
> Sent: Friday, September 21, 2012 1:37 PM
> To: R, Durgadoss
> Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com
> Subject: Re: [PATCHv4 07/15] Thermal: Add a policy sysfs attribute
> 
> On 二, 2012-09-18 at 11:04 +0530, Durgadoss R wrote:
> > This patch adds a policy sysfs attribute to a thermal zone.
> > This attribute denotes the throttling governor used for the
> > zone. This is a RW attribute.
> >
> > Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> > ---
> >  drivers/thermal/thermal_sys.c |   42
> ++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 39 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> > index a67c6c0..0948a60 100644
> > --- a/drivers/thermal/thermal_sys.c
> > +++ b/drivers/thermal/thermal_sys.c
> > @@ -454,10 +454,41 @@ passive_show(struct device *dev, struct
> device_attribute *attr,
> >  	return sprintf(buf, "%d\n", tz->forced_passive);
> >  }
> >
> > +static ssize_t
> > +policy_store(struct device *dev, struct device_attribute *attr,
> > +		    const char *buf, size_t count)
> > +{
> > +	int ret = -EINVAL;
> > +	struct thermal_zone_device *tz = to_thermal_zone(dev);
> > +	struct thermal_governor *gov;
> > +
> > +	mutex_lock(&thermal_governor_lock);
> > +
> > +	gov = __find_governor(buf);
> > +	if (!gov)
> > +		goto exit;
> > +
> > +	tz->governor = gov;
> > +	ret = count;
> > +
> > +exit:
> > +	mutex_unlock(&thermal_governor_lock);
> > +	return ret;
> > +}
> > +
> > +static ssize_t
> > +policy_show(struct device *dev, struct device_attribute *devattr, char
> *buf)
> > +{
> > +	struct thermal_zone_device *tz = to_thermal_zone(dev);
> > +
> > +	return sprintf(buf, "%s\n", tz->governor->name);
> > +}
> > +
> 
> we should introduce an API for platform thermal drivers to switch their
> policy.
> say they may want to switch to "userspace" to disable the kernel thermal
> control.
> and policy_store should invoke that function directly.

Yes, makes sense, we can introduce an EXPORT_SYMBOL API.

Thanks,
Durga

> BTW, IMO, deactiving all the thermal_instances and updating the cooling
> devices when a thermal zone switches to "userspace" governor is
> reasonable.
> 
> thanks,
> rui
> >  static DEVICE_ATTR(type, 0444, type_show, NULL);
> >  static DEVICE_ATTR(temp, 0444, temp_show, NULL);
> >  static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
> >  static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show,
> passive_store);
> > +static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show,
> policy_store);
> >
> >  /* sys I/F for cooling device */
> >  #define to_cooling_device(_dev)	\
> > @@ -1512,10 +1543,14 @@ struct thermal_zone_device
> *thermal_zone_device_register(const char *type,
> >  			passive = 1;
> >  	}
> >
> > -	if (!passive)
> > -		result = device_create_file(&tz->device,
> > -					    &dev_attr_passive);
> > +	if (!passive) {
> > +		result = device_create_file(&tz->device, &dev_attr_passive);
> > +		if (result)
> > +			goto unregister;
> > +	}
> >
> > +	/* Create policy attribute */
> > +	result = device_create_file(&tz->device, &dev_attr_policy);
> >  	if (result)
> >  		goto unregister;
> >
> > @@ -1591,6 +1626,7 @@ void thermal_zone_device_unregister(struct
> thermal_zone_device *tz)
> >  	device_remove_file(&tz->device, &dev_attr_temp);
> >  	if (tz->ops->get_mode)
> >  		device_remove_file(&tz->device, &dev_attr_mode);
> > +	device_remove_file(&tz->device, &dev_attr_policy);
> >  	remove_trip_attrs(tz);
> >  	tz->governor = NULL;
> >
> 


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

* RE: [PATCHv4 04/15] Thermal: Add platform level information to thermal.h
  2012-09-21  8:07     ` R, Durgadoss
@ 2012-09-24  5:43       ` Zhang Rui
  0 siblings, 0 replies; 26+ messages in thread
From: Zhang Rui @ 2012-09-24  5:43 UTC (permalink / raw)
  To: R, Durgadoss
  Cc: lenb@kernel.org, linux-acpi@vger.kernel.org,
	eduardo.valentin@ti.com

On 五, 2012-09-21 at 02:07 -0600, R, Durgadoss wrote:
> Hi Rui,
> 
> > -----Original Message-----
> > From: Zhang, Rui
> > Sent: Friday, September 21, 2012 12:43 PM
> > To: R, Durgadoss
> > Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com
> > Subject: Re: [PATCHv4 04/15] Thermal: Add platform level information to
> > thermal.h
> > 
> > On 二, 2012-09-18 at 11:04 +0530, Durgadoss R wrote:
> > > This patch adds platform level information to thermal.h
> > > by introducing two structures to hold:
> > >  * bind parameters for a thermal zone,
> > >  * zone level platform parameters
> > >
> > > Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> > > ---
> > >  include/linux/thermal.h |   29 +++++++++++++++++++++++++++++
> > >  1 file changed, 29 insertions(+)
> > >
> > > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > > index 32af124..4caa32e 100644
> > > --- a/include/linux/thermal.h
> > > +++ b/include/linux/thermal.h
> > > @@ -157,6 +157,7 @@ struct thermal_zone_device {
> > >  	int passive;
> > >  	unsigned int forced_passive;
> > >  	const struct thermal_zone_device_ops *ops;
> > > +	const struct thermal_zone_params *tzp;
> > >  	struct list_head thermal_instances;
> > >  	struct idr idr;
> > >  	struct mutex lock; /* protect thermal_instances list */
> > > @@ -164,6 +165,34 @@ struct thermal_zone_device {
> > >  	struct delayed_work poll_queue;
> > >  };
> > >
> > > +/* Structure that holds binding parameters for a zone */
> > > +struct thermal_bind_params {
> > > +	struct thermal_cooling_device *cdev;
> > > +
> > > +	/*
> > > +	 * This is a measure of 'how effectively these devices can
> > > +	 * cool 'this' thermal zone. The shall be determined by platform
> > > +	 * characterization. This is on a 'percentage' scale.
> > > +	 * See Documentation/thermal/sysfs-api.txt for more information.
> > > +	 */
> > > +	int weight;
> > > +
> > > +	/*
> > > +	 * This is a bit mask that gives the binding relation between this
> > > +	 * thermal zone and cdev, for a particular trip point.
> > > +	 * See Documentation/thermal/sysfs-api.txt for more information.
> > > +	 */
> > > +	int trip_mask;
> > > +	int (*match) (struct thermal_zone_device *tz,
> > > +			struct thermal_cooling_device *cdev);
> > > +};
> > 
> > we do not have field to describe the upper and lower limit?
> 
> Looks like I missed it here :-(
> But, IMO, we need an array of 'upper' and 'lower' limits here .. correct ?

either is ok.
if we are using two integers, we need different bind params for trip
points that have different upper and lower limit.
we can still use one bind params to describe multiple trip points if
they do not have any upper and lower limit.

> Let me know how you would want to address it ?
> a separate patch or fix here ?
> 
we can have an incremental patch for it.

thanks,
rui

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

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

* RE: [PATCHv4 07/15] Thermal: Add a policy sysfs attribute
  2012-09-21  8:09     ` R, Durgadoss
@ 2012-09-24  5:44       ` Zhang Rui
  0 siblings, 0 replies; 26+ messages in thread
From: Zhang Rui @ 2012-09-24  5:44 UTC (permalink / raw)
  To: R, Durgadoss
  Cc: lenb@kernel.org, linux-acpi@vger.kernel.org,
	eduardo.valentin@ti.com

On 五, 2012-09-21 at 02:09 -0600, R, Durgadoss wrote:
> Hi Rui,
> 
> > -----Original Message-----
> > From: Zhang, Rui
> > Sent: Friday, September 21, 2012 1:37 PM
> > To: R, Durgadoss
> > Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com
> > Subject: Re: [PATCHv4 07/15] Thermal: Add a policy sysfs attribute
> > 
> > On 二, 2012-09-18 at 11:04 +0530, Durgadoss R wrote:
> > > This patch adds a policy sysfs attribute to a thermal zone.
> > > This attribute denotes the throttling governor used for the
> > > zone. This is a RW attribute.
> > >
> > > Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> > > ---
> > >  drivers/thermal/thermal_sys.c |   42
> > ++++++++++++++++++++++++++++++++++++++---
> > >  1 file changed, 39 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> > > index a67c6c0..0948a60 100644
> > > --- a/drivers/thermal/thermal_sys.c
> > > +++ b/drivers/thermal/thermal_sys.c
> > > @@ -454,10 +454,41 @@ passive_show(struct device *dev, struct
> > device_attribute *attr,
> > >  	return sprintf(buf, "%d\n", tz->forced_passive);
> > >  }
> > >
> > > +static ssize_t
> > > +policy_store(struct device *dev, struct device_attribute *attr,
> > > +		    const char *buf, size_t count)
> > > +{
> > > +	int ret = -EINVAL;
> > > +	struct thermal_zone_device *tz = to_thermal_zone(dev);
> > > +	struct thermal_governor *gov;
> > > +
> > > +	mutex_lock(&thermal_governor_lock);
> > > +
> > > +	gov = __find_governor(buf);
> > > +	if (!gov)
> > > +		goto exit;
> > > +
> > > +	tz->governor = gov;
> > > +	ret = count;
> > > +
> > > +exit:
> > > +	mutex_unlock(&thermal_governor_lock);
> > > +	return ret;
> > > +}
> > > +
> > > +static ssize_t
> > > +policy_show(struct device *dev, struct device_attribute *devattr, char
> > *buf)
> > > +{
> > > +	struct thermal_zone_device *tz = to_thermal_zone(dev);
> > > +
> > > +	return sprintf(buf, "%s\n", tz->governor->name);
> > > +}
> > > +
> > 
> > we should introduce an API for platform thermal drivers to switch their
> > policy.
> > say they may want to switch to "userspace" to disable the kernel thermal
> > control.
> > and policy_store should invoke that function directly.
> 
> Yes, makes sense, we can introduce an EXPORT_SYMBOL API.

yes, we can have an incremental path for this.

thanks,
rui
> 
> Thanks,
> Durga
> 
> > BTW, IMO, deactiving all the thermal_instances and updating the cooling
> > devices when a thermal zone switches to "userspace" governor is
> > reasonable.
> > 
> > thanks,
> > rui
> > >  static DEVICE_ATTR(type, 0444, type_show, NULL);
> > >  static DEVICE_ATTR(temp, 0444, temp_show, NULL);
> > >  static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
> > >  static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show,
> > passive_store);
> > > +static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show,
> > policy_store);
> > >
> > >  /* sys I/F for cooling device */
> > >  #define to_cooling_device(_dev)	\
> > > @@ -1512,10 +1543,14 @@ struct thermal_zone_device
> > *thermal_zone_device_register(const char *type,
> > >  			passive = 1;
> > >  	}
> > >
> > > -	if (!passive)
> > > -		result = device_create_file(&tz->device,
> > > -					    &dev_attr_passive);
> > > +	if (!passive) {
> > > +		result = device_create_file(&tz->device, &dev_attr_passive);
> > > +		if (result)
> > > +			goto unregister;
> > > +	}
> > >
> > > +	/* Create policy attribute */
> > > +	result = device_create_file(&tz->device, &dev_attr_policy);
> > >  	if (result)
> > >  		goto unregister;
> > >
> > > @@ -1591,6 +1626,7 @@ void thermal_zone_device_unregister(struct
> > thermal_zone_device *tz)
> > >  	device_remove_file(&tz->device, &dev_attr_temp);
> > >  	if (tz->ops->get_mode)
> > >  		device_remove_file(&tz->device, &dev_attr_mode);
> > > +	device_remove_file(&tz->device, &dev_attr_policy);
> > >  	remove_trip_attrs(tz);
> > >  	tz->governor = NULL;
> > >
> > 
> 


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

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

end of thread, other threads:[~2012-09-24  5:43 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-18  5:34 [PATCHv4 00/15] Thermal_framework_enhancements Durgadoss R
2012-09-18  5:34 ` [PATCHv4 01/15] Thermal: Refactor thermal.h file Durgadoss R
2012-09-18  5:34 ` [PATCHv4 02/15] Thermal: Move thermal_instance to thermal_core.h Durgadoss R
2012-09-18  5:34 ` [PATCHv4 03/15] Thermal: Add get trend, get instance API's to thermal_sys Durgadoss R
2012-09-18  5:34 ` [PATCHv4 04/15] Thermal: Add platform level information to thermal.h Durgadoss R
2012-09-21  7:12   ` Zhang Rui
2012-09-21  8:07     ` R, Durgadoss
2012-09-24  5:43       ` Zhang Rui
2012-09-18  5:34 ` [PATCHv4 05/15] Thermal: Pass zone parameters as argument to tzd_register Durgadoss R
2012-09-18  5:34 ` [PATCHv4 06/15] Thermal: Add thermal governor registration APIs Durgadoss R
2012-09-18  5:34 ` [PATCHv4 07/15] Thermal: Add a policy sysfs attribute Durgadoss R
2012-09-21  8:07   ` Zhang Rui
2012-09-21  8:09     ` R, Durgadoss
2012-09-24  5:44       ` Zhang Rui
2012-09-18  5:34 ` [PATCHv4 08/15] Thermal: Update binding logic based on platform data Durgadoss R
2012-09-18  5:35 ` [PATCHv4 09/15] Thermal: Make thermal_cdev_update as a global function Durgadoss R
2012-09-18  5:35 ` [PATCHv4 10/15] Thermal: Introduce fair_share thermal governor Durgadoss R
2012-09-18  5:35 ` [PATCHv4 11/15] Thermal: Introduce a step_wise " Durgadoss R
2012-09-18  7:13   ` Zhang Rui
2012-09-18  8:11     ` R, Durgadoss
2012-09-18  8:22       ` Zhang Rui
2012-09-18  8:32         ` R, Durgadoss
2012-09-18  5:35 ` [PATCHv4 12/15] Thermal: Add a thermal notifier for user space Durgadoss R
2012-09-18  5:35 ` [PATCHv4 13/15] Thermal: Remove throttling logic out of thermal_sys.c Durgadoss R
2012-09-18  5:35 ` [PATCHv4 14/15] Thermal: Add a notification API Durgadoss R
2012-09-18  5:35 ` [PATCHv4 15/15] Thermal: Add documentation for platform layer data Durgadoss R

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).