7955262
From 81ad4276b505e987dd8ebbdf63605f92cd172b52 Mon Sep 17 00:00:00 2001
7955262
From: Zhang Rui <rui.zhang@intel.com>
7955262
Date: Fri, 18 Mar 2016 10:03:24 +0800
7955262
Subject: [PATCH] Thermal: Ignore invalid trip points
7955262
7955262
In some cases, platform thermal driver may report invalid trip points,
7955262
thermal core should not take any action for these trip points.
7955262
7955262
CC: <stable@vger.kernel.org> #3.18+
7955262
Link: https://bugzilla.redhat.com/show_bug.cgi?id=1317190
7955262
Link: https://bugzilla.kernel.org/show_bug.cgi?id=114551
7955262
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
7955262
---
7955262
 drivers/thermal/thermal_core.c | 13 ++++++++++++-
7955262
 include/linux/thermal.h        |  2 ++
7955262
 2 files changed, 14 insertions(+), 1 deletion(-)
7955262
7955262
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
7955262
index a0a8fd1..d4b5465 100644
7955262
--- a/drivers/thermal/thermal_core.c
7955262
+++ b/drivers/thermal/thermal_core.c
7955262
@@ -454,6 +454,10 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
7955262
 {
7955262
 	enum thermal_trip_type type;
7955262
 
7955262
+	/* Ignore disabled trip points */
7955262
+	if (test_bit(trip, &tz->trips_disabled))
7955262
+		return;
7955262
+
7955262
 	tz->ops->get_trip_type(tz, trip, &type);
7955262
 
7955262
 	if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
7955262
@@ -1800,6 +1804,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
7955262
 {
7955262
 	struct thermal_zone_device *tz;
7955262
 	enum thermal_trip_type trip_type;
7955262
+	int trip_temp;
7955262
 	int result;
7955262
 	int count;
7955262
 	int passive = 0;
7955262
@@ -1871,9 +1876,15 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
7955262
 		goto unregister;
7955262
 
7955262
 	for (count = 0; count < trips; count++) {
7955262
-		tz->ops->get_trip_type(tz, count, &trip_type);
7955262
+		if (tz->ops->get_trip_type(tz, count, &trip_type))
7955262
+			set_bit(count, &tz->trips_disabled);
7955262
 		if (trip_type == THERMAL_TRIP_PASSIVE)
7955262
 			passive = 1;
7955262
+		if (tz->ops->get_trip_temp(tz, count, &trip_temp))
7955262
+			set_bit(count, &tz->trips_disabled);
7955262
+		/* Check for bogus trip points */
7955262
+		if (trip_temp == 0)
7955262
+			set_bit(count, &tz->trips_disabled);
7955262
 	}
7955262
 
7955262
 	if (!passive) {
7955262
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
7955262
index 9c48199..a55d052 100644
7955262
--- a/include/linux/thermal.h
7955262
+++ b/include/linux/thermal.h
7955262
@@ -156,6 +156,7 @@ struct thermal_attr {
7955262
  * @trip_hyst_attrs:	attributes for trip points for sysfs: trip hysteresis
7955262
  * @devdata:	private pointer for device private data
7955262
  * @trips:	number of trip points the thermal zone supports
7955262
+ * @trips_disabled;	bitmap for disabled trips
7955262
  * @passive_delay:	number of milliseconds to wait between polls when
7955262
  *			performing passive cooling.
7955262
  * @polling_delay:	number of milliseconds to wait between polls when
7955262
@@ -191,6 +192,7 @@ struct thermal_zone_device {
7955262
 	struct thermal_attr *trip_hyst_attrs;
7955262
 	void *devdata;
7955262
 	int trips;
7955262
+	unsigned long trips_disabled;	/* bitmap for disabled trips */
7955262
 	int passive_delay;
7955262
 	int polling_delay;
7955262
 	int temperature;