diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index 04b1be7..bfccea5 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -89,6 +89,7 @@ struct __thermal_zone {
 	/* trip data */
 	int ntrips;
 	struct __thermal_trip *trips;
+	long prev_low_trip, prev_high_trip;
 
 	/* cooling binding data */
 	int num_tbps;
@@ -98,19 +99,66 @@ struct __thermal_zone {
 	void *sensor_data;
 	int (*get_temp)(void *, long *);
 	int (*get_trend)(void *, long *);
+	int (*set_trips)(void *, long, long);
 };
 
+/***   Automatic trip handling   ***/
+
+static int of_thermal_set_trips(struct thermal_zone_device *tz, long temp)
+{
+	struct __thermal_zone *data = tz->devdata;
+	long low = LONG_MIN, high = LONG_MAX;
+	int i;
+
+	/* Hardware trip points not supported */
+	if (!data->set_trips)
+		return 0;
+
+	/* No need to change trip points */
+	if (temp > data->prev_low_trip && temp < data->prev_high_trip)
+		return 0;
+
+	for (i = 0; i < data->ntrips; ++i) {
+		struct __thermal_trip *trip = data->trips + i;
+		long trip_low = trip->temperature - trip->hysteresis;
+
+		if (trip_low < temp && trip_low > low)
+			low = trip_low;
+
+		if (trip->temperature > temp && trip->temperature < high)
+			high = trip->temperature;
+	}
+
+	dev_dbg(&tz->device,
+		"temperature %ld, updating trip points to %ld, %ld\n",
+		temp, low, high);
+
+	data->prev_low_trip = low;
+	data->prev_high_trip = high;
+
+	return data->set_trips(data->sensor_data, low, high);
+}
+
 /***   DT thermal zone device callbacks   ***/
 
 static int of_thermal_get_temp(struct thermal_zone_device *tz,
 			       unsigned long *temp)
 {
 	struct __thermal_zone *data = tz->devdata;
+	int err;
 
 	if (!data->get_temp)
 		return -EINVAL;
 
-	return data->get_temp(data->sensor_data, temp);
+	err = data->get_temp(data->sensor_data, temp);
+	if (err)
+		return err;
+
+	err = of_thermal_set_trips(tz, *temp);
+	if (err)
+		return err;
+
+	return 0;
 }
 
 static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
@@ -222,6 +270,22 @@ static int of_thermal_set_mode(struct thermal_zone_device *tz,
 	return 0;
 }
 
+static int of_thermal_update_trips(struct thermal_zone_device *tz)
+{
+	long temp;
+	int err;
+
+	err = of_thermal_get_temp(tz, &temp);
+	if (err)
+		return err;
+
+	err = of_thermal_set_trips(tz, temp);
+	if (err)
+		return err;
+
+	return 0;
+}
+
 static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
 				    enum thermal_trip_type *type)
 {
@@ -252,6 +316,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
 				    unsigned long temp)
 {
 	struct __thermal_zone *data = tz->devdata;
+	int err;
 
 	if (trip >= data->ntrips || trip < 0)
 		return -EDOM;
@@ -259,6 +324,10 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
 	/* thermal framework should take care of data->mask & (1 << trip) */
 	data->trips[trip].temperature = temp;
 
+	err = of_thermal_update_trips(tz);
+	if (err)
+		return err;
+
 	return 0;
 }
 
@@ -279,6 +348,7 @@ static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
 				    unsigned long hyst)
 {
 	struct __thermal_zone *data = tz->devdata;
+	int err;
 
 	if (trip >= data->ntrips || trip < 0)
 		return -EDOM;
@@ -286,6 +356,10 @@ static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
 	/* thermal framework should take care of data->mask & (1 << trip) */
 	data->trips[trip].hysteresis = hyst;
 
+	err = of_thermal_update_trips(tz);
+	if (err)
+		return err;
+
 	return 0;
 }
 
@@ -325,10 +399,12 @@ static struct thermal_zone_device *
 thermal_zone_of_add_sensor(struct device_node *zone,
 			   struct device_node *sensor, void *data,
 			   int (*get_temp)(void *, long *),
-			   int (*get_trend)(void *, long *))
+			   int (*get_trend)(void *, long *),
+			   int (*set_trips)(void *, long, long))
 {
 	struct thermal_zone_device *tzd;
 	struct __thermal_zone *tz;
+	int err;
 
 	tzd = thermal_zone_get_zone_by_name(zone->name);
 	if (IS_ERR(tzd))
@@ -339,8 +415,15 @@ thermal_zone_of_add_sensor(struct device_node *zone,
 	mutex_lock(&tzd->lock);
 	tz->get_temp = get_temp;
 	tz->get_trend = get_trend;
+	tz->set_trips = set_trips;
 	tz->sensor_data = data;
 
+	err = of_thermal_update_trips(tzd);
+	if (err) {
+		mutex_unlock(&tzd->lock);
+		return ERR_PTR(err);
+	}
+
 	tzd->ops->get_temp = of_thermal_get_temp;
 	tzd->ops->get_trend = of_thermal_get_trend;
 	mutex_unlock(&tzd->lock);
@@ -384,7 +467,8 @@ thermal_zone_of_add_sensor(struct device_node *zone,
 struct thermal_zone_device *
 thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
 				void *data, int (*get_temp)(void *, long *),
-				int (*get_trend)(void *, long *))
+				int (*get_trend)(void *, long *),
+				int (*set_trips)(void *, long, long))
 {
 	struct device_node *np, *child, *sensor_np;
 
@@ -422,7 +506,8 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
 			return thermal_zone_of_add_sensor(child, sensor_np,
 							  data,
 							  get_temp,
-							  get_trend);
+							  get_trend,
+							  set_trips);
 		}
 	}
 	of_node_put(np);
@@ -466,6 +551,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
 
 	tz->get_temp = NULL;
 	tz->get_trend = NULL;
+	tz->set_trips = NULL;
 	tz->sensor_data = NULL;
 	mutex_unlock(&tzd->lock);
 }
@@ -671,6 +757,9 @@ thermal_of_build_thermal_zone(struct device_node *np)
 	/* trips */
 	child = of_get_child_by_name(np, "trips");
 
+	tz->prev_high_trip = LONG_MIN;
+	tz->prev_low_trip = LONG_MAX;
+
 	/* No trips provided */
 	if (!child)
 		goto finish;
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index f7e11c7..2f8951c 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -248,7 +248,8 @@ struct thermal_genl_event {
 struct thermal_zone_device *
 thermal_zone_of_sensor_register(struct device *dev, int id,
 				void *data, int (*get_temp)(void *, long *),
-				int (*get_trend)(void *, long *));
+				int (*get_trend)(void *, long *),
+				int (*set_trips)(void *, long, long));
 void thermal_zone_of_sensor_unregister(struct device *dev,
 				       struct thermal_zone_device *tz);
 #else
