Commit f772b404 authored by Zhang Rui's avatar Zhang Rui Committed by Greg Kroah-Hartman

Thermal: Ignore invalid trip points

commit 81ad4276 upstream.

In some cases, platform thermal driver may report invalid trip points,
thermal core should not take any action for these trip points.

This fixed a regression that bogus trip point starts to screw up thermal
control on some Lenovo laptops, after
commit bb431ba2
Author: Zhang Rui <rui.zhang@intel.com>
Date:   Fri Oct 30 16:31:47 2015 +0800

    Thermal: initialize thermal zone device correctly

    After thermal zone device registered, as we have not read any
    temperature before, thus tz->temperature should not be 0,
    which actually means 0C, and thermal trend is not available.
    In this case, we need specially handling for the first
    thermal_zone_device_update().

    Both thermal core framework and step_wise governor is
    enhanced to handle this. And since the step_wise governor
    is the only one that uses trends, so it's the only thermal
    governor that needs to be updated.
Tested-by: default avatarManuel Krause <manuelkrause@netscape.net>
Tested-by: default avatarszegad <szegadlo@poczta.onet.pl>
Tested-by: default avatarprash <prash.n.rao@gmail.com>
Tested-by: default avataramish <ammdispose-arch@yahoo.com>
Tested-by: default avatarMatthias <morpheusxyz123@yahoo.de>
Reviewed-by: default avatarJavi Merino <javi.merino@arm.com>
Signed-off-by: default avatarZhang Rui <rui.zhang@intel.com>
Signed-off-by: default avatarChen Yu <yu.c.chen@intel.com>

Link: https://bugzilla.redhat.com/show_bug.cgi?id=1317190
Link: https://bugzilla.kernel.org/show_bug.cgi?id=114551Signed-off-by: default avatarZhang Rui <rui.zhang@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bcd8d145
...@@ -454,6 +454,10 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) ...@@ -454,6 +454,10 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
{ {
enum thermal_trip_type type; enum thermal_trip_type type;
/* Ignore disabled trip points */
if (test_bit(trip, &tz->trips_disabled))
return;
tz->ops->get_trip_type(tz, trip, &type); tz->ops->get_trip_type(tz, trip, &type);
if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT) if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
...@@ -1800,6 +1804,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, ...@@ -1800,6 +1804,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
{ {
struct thermal_zone_device *tz; struct thermal_zone_device *tz;
enum thermal_trip_type trip_type; enum thermal_trip_type trip_type;
int trip_temp;
int result; int result;
int count; int count;
int passive = 0; int passive = 0;
...@@ -1871,9 +1876,15 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, ...@@ -1871,9 +1876,15 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
goto unregister; goto unregister;
for (count = 0; count < trips; count++) { for (count = 0; count < trips; count++) {
tz->ops->get_trip_type(tz, count, &trip_type); if (tz->ops->get_trip_type(tz, count, &trip_type))
set_bit(count, &tz->trips_disabled);
if (trip_type == THERMAL_TRIP_PASSIVE) if (trip_type == THERMAL_TRIP_PASSIVE)
passive = 1; passive = 1;
if (tz->ops->get_trip_temp(tz, count, &trip_temp))
set_bit(count, &tz->trips_disabled);
/* Check for bogus trip points */
if (trip_temp == 0)
set_bit(count, &tz->trips_disabled);
} }
if (!passive) { if (!passive) {
......
...@@ -156,6 +156,7 @@ struct thermal_attr { ...@@ -156,6 +156,7 @@ struct thermal_attr {
* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis * @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
* @devdata: private pointer for device private data * @devdata: private pointer for device private data
* @trips: number of trip points the thermal zone supports * @trips: number of trip points the thermal zone supports
* @trips_disabled; bitmap for disabled trips
* @passive_delay: number of milliseconds to wait between polls when * @passive_delay: number of milliseconds to wait between polls when
* performing passive cooling. * performing passive cooling.
* @polling_delay: number of milliseconds to wait between polls when * @polling_delay: number of milliseconds to wait between polls when
...@@ -191,6 +192,7 @@ struct thermal_zone_device { ...@@ -191,6 +192,7 @@ struct thermal_zone_device {
struct thermal_attr *trip_hyst_attrs; struct thermal_attr *trip_hyst_attrs;
void *devdata; void *devdata;
int trips; int trips;
unsigned long trips_disabled; /* bitmap for disabled trips */
int passive_delay; int passive_delay;
int polling_delay; int polling_delay;
int temperature; int temperature;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment