Merge tag 'thermal-v5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/therma...
[linux-block.git] / drivers / thermal / thermal_core.c
index 4c11a79659792199fc48d14279b429de27bdba92..6a5d0ae5d7a4c0c12ed980dd434e676878284025 100644 (file)
@@ -340,12 +340,8 @@ void thermal_zone_device_critical(struct thermal_zone_device *tz)
 EXPORT_SYMBOL(thermal_zone_device_critical);
 
 static void handle_critical_trips(struct thermal_zone_device *tz,
-                                 int trip, enum thermal_trip_type trip_type)
+                                 int trip, int trip_temp, enum thermal_trip_type trip_type)
 {
-       int trip_temp;
-
-       tz->ops->get_trip_temp(tz, trip, &trip_temp);
-
        /* If we have not crossed the trip_temp, we do not care. */
        if (trip_temp <= 0 || tz->temperature < trip_temp)
                return;
@@ -384,7 +380,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
        }
 
        if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
-               handle_critical_trips(tz, trip, type);
+               handle_critical_trips(tz, trip, trip_temp, type);
        else
                handle_non_critical_trips(tz, trip);
        /*
@@ -505,7 +501,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz,
 
        tz->notify_event = event;
 
-       for (count = 0; count < tz->trips; count++)
+       for (count = 0; count < tz->num_trips; count++)
                handle_thermal_trip(tz, count);
 }
 EXPORT_SYMBOL_GPL(thermal_zone_device_update);
@@ -630,7 +626,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
        unsigned long max_state;
        int result, ret;
 
-       if (trip >= tz->trips || trip < 0)
+       if (trip >= tz->num_trips || trip < 0)
                return -EINVAL;
 
        list_for_each_entry(pos1, &thermal_tz_list, node) {
@@ -811,7 +807,7 @@ static void __bind(struct thermal_zone_device *tz, int mask,
 {
        int i, ret;
 
-       for (i = 0; i < tz->trips; i++) {
+       for (i = 0; i < tz->num_trips; i++) {
                if (mask & (1 << i)) {
                        unsigned long upper, lower;
 
@@ -1057,7 +1053,7 @@ static void __unbind(struct thermal_zone_device *tz, int mask,
 {
        int i;
 
-       for (i = 0; i < tz->trips; i++)
+       for (i = 0; i < tz->num_trips; i++)
                if (mask & (1 << i))
                        thermal_zone_unbind_cooling_device(tz, i, cdev);
 }
@@ -1159,10 +1155,18 @@ exit:
        mutex_unlock(&thermal_list_lock);
 }
 
+static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms)
+{
+       *delay_jiffies = msecs_to_jiffies(delay_ms);
+       if (delay_ms > 1000)
+               *delay_jiffies = round_jiffies(*delay_jiffies);
+}
+
 /**
- * thermal_zone_device_register() - register a new thermal zone device
+ * thermal_zone_device_register_with_trips() - register a new thermal zone device
  * @type:      the thermal zone device type
- * @trips:     the number of trip points the thermal zone support
+ * @trips:     a pointer to an array of thermal trips
+ * @num_trips: the number of trip points the thermal zone support
  * @mask:      a bit string indicating the writeablility of trip points
  * @devdata:   private device data
  * @ops:       standard thermal zone device callbacks
@@ -1184,10 +1188,10 @@ exit:
  * IS_ERR*() helpers.
  */
 struct thermal_zone_device *
-thermal_zone_device_register(const char *type, int trips, int mask,
-                            void *devdata, struct thermal_zone_device_ops *ops,
-                            struct thermal_zone_params *tzp, int passive_delay,
-                            int polling_delay)
+thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *trips, int num_trips, int mask,
+                                       void *devdata, struct thermal_zone_device_ops *ops,
+                                       struct thermal_zone_params *tzp, int passive_delay,
+                                       int polling_delay)
 {
        struct thermal_zone_device *tz;
        enum thermal_trip_type trip_type;
@@ -1198,27 +1202,27 @@ thermal_zone_device_register(const char *type, int trips, int mask,
        struct thermal_governor *governor;
 
        if (!type || strlen(type) == 0) {
-               pr_err("Error: No thermal zone type defined\n");
+               pr_err("No thermal zone type defined\n");
                return ERR_PTR(-EINVAL);
        }
 
        if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
-               pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
+               pr_err("Thermal zone name (%s) too long, should be under %d chars\n",
                       type, THERMAL_NAME_LENGTH);
                return ERR_PTR(-EINVAL);
        }
 
-       if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) {
-               pr_err("Error: Incorrect number of thermal trips\n");
+       if (num_trips > THERMAL_MAX_TRIPS || num_trips < 0 || mask >> num_trips) {
+               pr_err("Incorrect number of thermal trips\n");
                return ERR_PTR(-EINVAL);
        }
 
        if (!ops) {
-               pr_err("Error: Thermal zone device ops not defined\n");
+               pr_err("Thermal zone device ops not defined\n");
                return ERR_PTR(-EINVAL);
        }
 
-       if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
+       if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
                return ERR_PTR(-EINVAL);
 
        tz = kzalloc(sizeof(*tz), GFP_KERNEL);
@@ -1249,6 +1253,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
        tz->device.class = &thermal_class;
        tz->devdata = devdata;
        tz->trips = trips;
+       tz->num_trips = num_trips;
 
        thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay);
        thermal_set_delay_jiffies(&tz->polling_delay_jiffies, polling_delay);
@@ -1266,7 +1271,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
        if (result)
                goto release_device;
 
-       for (count = 0; count < trips; count++) {
+       for (count = 0; count < num_trips; count++) {
                if (tz->ops->get_trip_type(tz, count, &trip_type) ||
                    tz->ops->get_trip_temp(tz, count, &trip_temp) ||
                    !trip_temp)
@@ -1324,6 +1329,16 @@ free_tz:
        kfree(tz);
        return ERR_PTR(result);
 }
+
+struct thermal_zone_device *thermal_zone_device_register(const char *type, int ntrips, int mask,
+                                                        void *devdata, struct thermal_zone_device_ops *ops,
+                                                        struct thermal_zone_params *tzp, int passive_delay,
+                                                        int polling_delay)
+{
+       return thermal_zone_device_register_with_trips(type, NULL, ntrips, mask,
+                                                      devdata, ops, tzp,
+                                                      passive_delay, polling_delay);
+}
 EXPORT_SYMBOL_GPL(thermal_zone_device_register);
 
 /**