summaryrefslogtreecommitdiff
path: root/drivers/thermal/thermal_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/thermal_core.c')
-rw-r--r--drivers/thermal/thermal_core.c79
1 files changed, 47 insertions, 32 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index cdc0552e8c42..6a5d0ae5d7a4 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -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) {
@@ -667,7 +663,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
dev->target = THERMAL_NO_TARGET;
dev->weight = weight;
- result = ida_simple_get(&tz->ida, 0, 0, GFP_KERNEL);
+ result = ida_alloc(&tz->ida, GFP_KERNEL);
if (result < 0)
goto free_mem;
@@ -721,7 +717,7 @@ remove_trip_file:
remove_symbol_link:
sysfs_remove_link(&tz->device.kobj, dev->name);
release_ida:
- ida_simple_remove(&tz->ida, dev->id);
+ ida_free(&tz->ida, dev->id);
free_mem:
kfree(dev);
return result;
@@ -768,7 +764,7 @@ unbind:
device_remove_file(&tz->device, &pos->weight_attr);
device_remove_file(&tz->device, &pos->attr);
sysfs_remove_link(&tz->device.kobj, pos->name);
- ida_simple_remove(&tz->ida, pos->id);
+ ida_free(&tz->ida, pos->id);
kfree(pos);
return 0;
}
@@ -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;
@@ -901,7 +897,7 @@ __thermal_cooling_device_register(struct device_node *np,
if (!cdev)
return ERR_PTR(-ENOMEM);
- ret = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
+ ret = ida_alloc(&thermal_cdev_ida, GFP_KERNEL);
if (ret < 0)
goto out_kfree_cdev;
cdev->id = ret;
@@ -952,7 +948,7 @@ out_kfree_type:
put_device(&cdev->device);
cdev = NULL;
out_ida_remove:
- ida_simple_remove(&thermal_cdev_ida, id);
+ ida_free(&thermal_cdev_ida, id);
out_kfree_cdev:
kfree(cdev);
return ERR_PTR(ret);
@@ -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);
}
@@ -1111,7 +1107,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
mutex_unlock(&thermal_list_lock);
- ida_simple_remove(&thermal_cdev_ida, cdev->id);
+ ida_free(&thermal_cdev_ida, cdev->id);
device_del(&cdev->device);
thermal_cooling_device_destroy_sysfs(cdev);
kfree(cdev->type);
@@ -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);
@@ -1228,7 +1232,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
INIT_LIST_HEAD(&tz->thermal_instances);
ida_init(&tz->ida);
mutex_init(&tz->lock);
- id = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL);
+ id = ida_alloc(&thermal_tz_ida, GFP_KERNEL);
if (id < 0) {
result = id;
goto free_tz;
@@ -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)
@@ -1319,11 +1324,21 @@ release_device:
put_device(&tz->device);
tz = NULL;
remove_id:
- ida_simple_remove(&thermal_tz_ida, id);
+ ida_free(&thermal_tz_ida, id);
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);
/**
@@ -1379,7 +1394,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
thermal_set_governor(tz, NULL);
thermal_remove_hwmon_sysfs(tz);
- ida_simple_remove(&thermal_tz_ida, tz->id);
+ ida_free(&thermal_tz_ida, tz->id);
ida_destroy(&tz->ida);
mutex_destroy(&tz->lock);
device_unregister(&tz->device);