===================================================================
@@ -300,6 +300,14 @@ static void monitor_thermal_zone(struct
thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies);
else if (tz->polling_delay_jiffies)
thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies);
+ else if (tz->temperature == THERMAL_TEMP_INVALID &&
+ tz->recheck_delay_jiffies <= THERMAL_MAX_RECHECK_DELAY) {
+ thermal_zone_device_set_polling(tz, tz->recheck_delay_jiffies);
+ /* Double the recheck delay for the next attempt. */
+ tz->recheck_delay_jiffies += tz->recheck_delay_jiffies;
+ if (tz->recheck_delay_jiffies > THERMAL_MAX_RECHECK_DELAY)
+ dev_info(&tz->device, "Temperature unknown, giving up\n");
+ }
}
static struct thermal_governor *thermal_get_tz_governor(struct thermal_zone_device *tz)
@@ -430,6 +438,7 @@ static void update_temperature(struct th
tz->last_temperature = tz->temperature;
tz->temperature = temp;
+ tz->recheck_delay_jiffies = 1;
trace_thermal_temperature(tz);
@@ -514,7 +523,7 @@ void __thermal_zone_device_update(struct
update_temperature(tz);
if (tz->temperature == THERMAL_TEMP_INVALID)
- return;
+ goto monitor;
tz->notify_event = event;
@@ -536,6 +545,7 @@ void __thermal_zone_device_update(struct
thermal_debug_update_trip_stats(tz);
+monitor:
monitor_thermal_zone(tz);
}
@@ -1438,6 +1448,7 @@ thermal_zone_device_register_with_trips(
thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay);
thermal_set_delay_jiffies(&tz->polling_delay_jiffies, polling_delay);
+ tz->recheck_delay_jiffies = 1;
/* sys I/F */
/* Add nodes that are always present via .groups */
===================================================================
@@ -67,6 +67,8 @@ struct thermal_governor {
* @polling_delay_jiffies: number of jiffies to wait between polls when
* checking whether trip points have been crossed (0 for
* interrupt driven systems)
+ * @recheck_delay_jiffies: delay after a failed thermal zone temperature check
+ * before attempting to check it again
* @temperature: current temperature. This is only for core code,
* drivers should use thermal_zone_get_temp() to get the
* current temperature
@@ -108,6 +110,7 @@ struct thermal_zone_device {
int num_trips;
unsigned long passive_delay_jiffies;
unsigned long polling_delay_jiffies;
+ unsigned long recheck_delay_jiffies;
int temperature;
int last_temperature;
int emul_temperature;
@@ -133,6 +136,12 @@ struct thermal_zone_device {
struct thermal_trip_desc trips[] __counted_by(num_trips);
};
+/*
+ * Maximum delay after a failing thermal zone temperature check before
+ * attempting to check it again (in jiffies).
+ */
+#define THERMAL_MAX_RECHECK_DELAY (30 * HZ)
+
/* Default Thermal Governor */
#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
#define DEFAULT_THERMAL_GOVERNOR "step_wise"