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