From 7c3d5c20dc169e55064f7f38c1c56cfbc39ee5b2 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:34 +0200 Subject: thermal/core: Add a generic thermal_zone_get_trip() function The thermal_zone_device_ops structure defines a set of ops family, get_trip_temp(), get_trip_hyst(), get_trip_type(). Each of them is returning a property of a trip point. The result is the code is calling the ops everywhere to get a trip point which is supposed to be defined in the backend driver. It is a non-sense as a thermal trip can be generic and used by the backend driver to declare its trip points. Part of the thermal framework has been changed and all the OF thermal drivers are using the same definition for the trip point and use a thermal zone registration variant to pass those trip points which are part of the thermal zone device structure. Consequently, we can use a generic function to get the trip points when they are stored in the thermal zone device structure. This approach can be generalized to all the drivers and we can get rid of the ops->get_trip_*. That will result to a much more simpler code and make possible to rework how the thermal trip are handled in the thermal core framework as discussed previously. This change adds a function thermal_zone_get_trip() where we get the thermal trip point structure which contains all the properties (type, temp, hyst) instead of doing multiple calls to ops->get_trip_*. That opens the door for trip point extension with more attributes. For instance, replacing the trip points disabled bitmask with a 'disabled' field in the structure. Here we replace all the calls to ops->get_trip_* in the thermal core code with a call to the thermal_zone_get_trip() function. The thermal zone ops defines a callback to retrieve the critical temperature. As the trip handling is being reworked, all the trip points will be the same whatever the driver and consequently finding the critical trip temperature will be just a loop to search for a critical trip point type. Provide such a generic function, so we encapsulate the ops get_crit_temp() which can be removed when all the backend drivers are using the generic trip points handling. While at it, add the thermal_zone_get_num_trips() to encapsulate the code more and reduce the grip with the thermal framework internals. Signed-off-by: Daniel Lezcano Acked-by: Rafael J. Wysocki Reviewed-by: Zhang Rui Link: https://lore.kernel.org/r/20221003092602.1323944-2-daniel.lezcano@linaro.org --- drivers/thermal/thermal_core.c | 114 ++++++++++++++++++++++++++++++-------- drivers/thermal/thermal_core.h | 2 + drivers/thermal/thermal_helpers.c | 28 +++++----- drivers/thermal/thermal_netlink.c | 19 +++---- drivers/thermal/thermal_sysfs.c | 64 +++++++++------------ 5 files changed, 140 insertions(+), 87 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index f17ab2316dbd..b043c315c005 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -344,35 +344,31 @@ static void handle_critical_trips(struct thermal_zone_device *tz, tz->ops->critical(tz); } -static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) +static void handle_thermal_trip(struct thermal_zone_device *tz, int trip_id) { - enum thermal_trip_type type; - int trip_temp, hyst = 0; + struct thermal_trip trip; /* Ignore disabled trip points */ - if (test_bit(trip, &tz->trips_disabled)) + if (test_bit(trip_id, &tz->trips_disabled)) return; - tz->ops->get_trip_temp(tz, trip, &trip_temp); - tz->ops->get_trip_type(tz, trip, &type); - if (tz->ops->get_trip_hyst) - tz->ops->get_trip_hyst(tz, trip, &hyst); + __thermal_zone_get_trip(tz, trip_id, &trip); if (tz->last_temperature != THERMAL_TEMP_INVALID) { - if (tz->last_temperature < trip_temp && - tz->temperature >= trip_temp) - thermal_notify_tz_trip_up(tz->id, trip, + if (tz->last_temperature < trip.temperature && + tz->temperature >= trip.temperature) + thermal_notify_tz_trip_up(tz->id, trip_id, tz->temperature); - if (tz->last_temperature >= trip_temp && - tz->temperature < (trip_temp - hyst)) - thermal_notify_tz_trip_down(tz->id, trip, + if (tz->last_temperature >= trip.temperature && + tz->temperature < (trip.temperature - trip.hysteresis)) + thermal_notify_tz_trip_down(tz->id, trip_id, tz->temperature); } - if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT) - handle_critical_trips(tz, trip, trip_temp, type); + if (trip.type == THERMAL_TRIP_CRITICAL || trip.type == THERMAL_TRIP_HOT) + handle_critical_trips(tz, trip_id, trip.temperature, trip.type); else - handle_non_critical_trips(tz, trip); + handle_non_critical_trips(tz, trip_id); } static void update_temperature(struct thermal_zone_device *tz) @@ -1159,6 +1155,79 @@ static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms *delay_jiffies = round_jiffies(*delay_jiffies); } +int thermal_zone_get_num_trips(struct thermal_zone_device *tz) +{ + return tz->num_trips; +} +EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips); + +int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp) +{ + int i, ret = -EINVAL; + + if (tz->ops->get_crit_temp) + return tz->ops->get_crit_temp(tz, temp); + + if (!tz->trips) + return -EINVAL; + + mutex_lock(&tz->lock); + + for (i = 0; i < tz->num_trips; i++) { + if (tz->trips[i].type == THERMAL_TRIP_CRITICAL) { + *temp = tz->trips[i].temperature; + ret = 0; + break; + } + } + + mutex_unlock(&tz->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp); + +int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, + struct thermal_trip *trip) +{ + int ret; + + if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip) + return -EINVAL; + + if (tz->trips) { + *trip = tz->trips[trip_id]; + return 0; + } + + if (tz->ops->get_trip_hyst) { + ret = tz->ops->get_trip_hyst(tz, trip_id, &trip->hysteresis); + if (ret) + return ret; + } else { + trip->hysteresis = 0; + } + + ret = tz->ops->get_trip_temp(tz, trip_id, &trip->temperature); + if (ret) + return ret; + + return tz->ops->get_trip_type(tz, trip_id, &trip->type); +} + +int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, + struct thermal_trip *trip) +{ + int ret; + + mutex_lock(&tz->lock); + ret = __thermal_zone_get_trip(tz, trip_id, trip); + mutex_unlock(&tz->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(thermal_zone_get_trip); + /** * thermal_zone_device_register_with_trips() - register a new thermal zone device * @type: the thermal zone device type @@ -1191,8 +1260,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t int polling_delay) { struct thermal_zone_device *tz; - enum thermal_trip_type trip_type; - int trip_temp; int id; int result; int count; @@ -1232,7 +1299,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t return ERR_PTR(-EINVAL); } - if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp)) + if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp) && !trips) return ERR_PTR(-EINVAL); tz = kzalloc(sizeof(*tz), GFP_KERNEL); @@ -1283,9 +1350,10 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t goto release_device; 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) + struct thermal_trip trip; + + result = thermal_zone_get_trip(tz, count, &trip); + if (result) set_bit(count, &tz->trips_disabled); } diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index b834cb273429..5f475b0a8c2f 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -114,6 +114,8 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, /* Helpers */ void __thermal_zone_set_trips(struct thermal_zone_device *tz); +int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, + struct thermal_trip *trip); int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); /* sysfs I/F */ diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c index 56aa2e88f34f..8977d5ddc23c 100644 --- a/drivers/thermal/thermal_helpers.c +++ b/drivers/thermal/thermal_helpers.c @@ -83,7 +83,7 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) int ret = -EINVAL; int count; int crit_temp = INT_MAX; - enum thermal_trip_type type; + struct thermal_trip trip; lockdep_assert_held(&tz->lock); @@ -91,10 +91,9 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) { for (count = 0; count < tz->num_trips; count++) { - ret = tz->ops->get_trip_type(tz, count, &type); - if (!ret && type == THERMAL_TRIP_CRITICAL) { - ret = tz->ops->get_trip_temp(tz, count, - &crit_temp); + ret = __thermal_zone_get_trip(tz, count, &trip); + if (!ret && trip.type == THERMAL_TRIP_CRITICAL) { + crit_temp = trip.temperature; break; } } @@ -164,29 +163,30 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_temp); */ void __thermal_zone_set_trips(struct thermal_zone_device *tz) { - int low = -INT_MAX; - int high = INT_MAX; - int trip_temp, hysteresis; + struct thermal_trip trip; + int low = -INT_MAX, high = INT_MAX; int i, ret; lockdep_assert_held(&tz->lock); - if (!tz->ops->set_trips || !tz->ops->get_trip_hyst) + if (!tz->ops->set_trips) return; for (i = 0; i < tz->num_trips; i++) { int trip_low; - tz->ops->get_trip_temp(tz, i, &trip_temp); - tz->ops->get_trip_hyst(tz, i, &hysteresis); + ret = __thermal_zone_get_trip(tz, i , &trip); + if (ret) + return; - trip_low = trip_temp - hysteresis; + trip_low = trip.temperature - trip.hysteresis; if (trip_low < tz->temperature && trip_low > low) low = trip_low; - if (trip_temp > tz->temperature && trip_temp < high) - high = trip_temp; + if (trip.temperature > tz->temperature && + trip.temperature < high) + high = trip.temperature; } /* No need to change trip points */ diff --git a/drivers/thermal/thermal_netlink.c b/drivers/thermal/thermal_netlink.c index e2d78a996b5f..75943b06dbe7 100644 --- a/drivers/thermal/thermal_netlink.c +++ b/drivers/thermal/thermal_netlink.c @@ -452,7 +452,8 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) struct sk_buff *msg = p->msg; struct thermal_zone_device *tz; struct nlattr *start_trip; - int i, id; + struct thermal_trip trip; + int ret, i, id; if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) return -EINVAL; @@ -471,18 +472,14 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) for (i = 0; i < tz->num_trips; i++) { - enum thermal_trip_type type; - int temp, hyst = 0; - - tz->ops->get_trip_type(tz, i, &type); - tz->ops->get_trip_temp(tz, i, &temp); - if (tz->ops->get_trip_hyst) - tz->ops->get_trip_hyst(tz, i, &hyst); + ret = __thermal_zone_get_trip(tz, i, &trip); + if (ret) + goto out_cancel_nest; if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, i) || - nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, type) || - nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TEMP, temp) || - nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_HYST, hyst)) + nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, trip.type) || + nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TEMP, trip.temperature) || + nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_HYST, trip.hysteresis)) goto out_cancel_nest; } diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index d97f0bc0a26b..137bbf6adbd6 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -83,27 +83,25 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_zone_device *tz = to_thermal_zone(dev); - enum thermal_trip_type type; - int trip, result; + struct thermal_trip trip; + int trip_id, result; - if (!tz->ops->get_trip_type) - return -EPERM; - - if (sscanf(attr->attr.name, "trip_point_%d_type", &trip) != 1) + if (sscanf(attr->attr.name, "trip_point_%d_type", &trip_id) != 1) return -EINVAL; mutex_lock(&tz->lock); if (device_is_registered(dev)) - result = tz->ops->get_trip_type(tz, trip, &type); + result = __thermal_zone_get_trip(tz, trip_id, &trip); else result = -ENODEV; mutex_unlock(&tz->lock); + if (result) return result; - switch (type) { + switch (trip.type) { case THERMAL_TRIP_CRITICAL: return sprintf(buf, "critical\n"); case THERMAL_TRIP_HOT: @@ -122,17 +120,16 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip, ret; - int temperature, hyst = 0; - enum thermal_trip_type type; + struct thermal_trip trip; + int trip_id, ret; if (!tz->ops->set_trip_temp && !tz->trips) return -EPERM; - if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1) + if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) return -EINVAL; - if (kstrtoint(buf, 10, &temperature)) + if (kstrtoint(buf, 10, &trip.temperature)) return -EINVAL; mutex_lock(&tz->lock); @@ -143,25 +140,20 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, } if (tz->ops->set_trip_temp) { - ret = tz->ops->set_trip_temp(tz, trip, temperature); + ret = tz->ops->set_trip_temp(tz, trip_id, trip.temperature); if (ret) goto unlock; } if (tz->trips) - tz->trips[trip].temperature = temperature; - - if (tz->ops->get_trip_hyst) { - ret = tz->ops->get_trip_hyst(tz, trip, &hyst); - if (ret) - goto unlock; - } + tz->trips[trip_id].temperature = trip.temperature; - ret = tz->ops->get_trip_type(tz, trip, &type); + ret = __thermal_zone_get_trip(tz, trip_id, &trip); if (ret) goto unlock; - thermal_notify_tz_trip_change(tz->id, trip, type, temperature, hyst); + thermal_notify_tz_trip_change(tz->id, trip_id, trip.type, + trip.temperature, trip.hysteresis); __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); @@ -179,19 +171,16 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip, ret; - int temperature; + struct thermal_trip trip; + int trip_id, ret; - if (!tz->ops->get_trip_temp) - return -EPERM; - - if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1) + if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) return -EINVAL; mutex_lock(&tz->lock); if (device_is_registered(dev)) - ret = tz->ops->get_trip_temp(tz, trip, &temperature); + ret = __thermal_zone_get_trip(tz, trip_id, &trip); else ret = -ENODEV; @@ -200,7 +189,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, if (ret) return ret; - return sprintf(buf, "%d\n", temperature); + return sprintf(buf, "%d\n", trip.temperature); } static ssize_t @@ -248,25 +237,22 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip, ret; - int temperature; + struct thermal_trip trip; + int trip_id, ret; - if (!tz->ops->get_trip_hyst) - return -EPERM; - - if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1) + if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) return -EINVAL; mutex_lock(&tz->lock); if (device_is_registered(dev)) - ret = tz->ops->get_trip_hyst(tz, trip, &temperature); + ret = __thermal_zone_get_trip(tz, trip_id, &trip); else ret = -ENODEV; mutex_unlock(&tz->lock); - return ret ? ret : sprintf(buf, "%d\n", temperature); + return ret ? ret : sprintf(buf, "%d\n", trip.hysteresis); } static ssize_t -- cgit v1.2.3 From 0614755dbfc0ec3af59a2e09785acb009706259d Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:35 +0200 Subject: thermal/sysfs: Always expose hysteresis attributes Instead of avoiding to expose the hysteresis attributes of a thermal zone when its get_trip_hyst() operation is not defined, which is confusing, expose them always and use the default thermal_zone_get_trip() function returning 0 hysteresis when that operation is not present. The hysteresis of 0 is perfectly valid, so this change should not introduce any backwards compatibility issues. Signed-off-by: Daniel Lezcano Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221003092602.1323944-3-daniel.lezcano@linaro.org --- drivers/thermal/thermal_sysfs.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 137bbf6adbd6..d2d450076090 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -477,23 +477,20 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) return -ENOMEM; } - if (tz->ops->get_trip_hyst) { - tz->trip_hyst_attrs = kcalloc(tz->num_trips, - sizeof(*tz->trip_hyst_attrs), - GFP_KERNEL); - if (!tz->trip_hyst_attrs) { - kfree(tz->trip_type_attrs); - kfree(tz->trip_temp_attrs); - return -ENOMEM; - } + tz->trip_hyst_attrs = kcalloc(tz->num_trips, + sizeof(*tz->trip_hyst_attrs), + GFP_KERNEL); + if (!tz->trip_hyst_attrs) { + kfree(tz->trip_type_attrs); + kfree(tz->trip_temp_attrs); + return -ENOMEM; } attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL); if (!attrs) { kfree(tz->trip_type_attrs); kfree(tz->trip_temp_attrs); - if (tz->ops->get_trip_hyst) - kfree(tz->trip_hyst_attrs); + kfree(tz->trip_hyst_attrs); return -ENOMEM; } @@ -526,9 +523,6 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) } attrs[indx + tz->num_trips] = &tz->trip_temp_attrs[indx].attr.attr; - /* create Optional trip hyst attribute */ - if (!tz->ops->get_trip_hyst) - continue; snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH, "trip_point_%d_hyst", indx); @@ -565,8 +559,7 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz) kfree(tz->trip_type_attrs); kfree(tz->trip_temp_attrs); - if (tz->ops->get_trip_hyst) - kfree(tz->trip_hyst_attrs); + kfree(tz->trip_hyst_attrs); kfree(tz->trips_attribute_group.attrs); } -- cgit v1.2.3 From 2e38a2a981b24a9e86e687d32708a3d02707c8f6 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:36 +0200 Subject: thermal/core: Add a generic thermal_zone_set_trip() function The thermal zone ops defines a set_trip callback where we can invoke the backend driver to set an interrupt for the next trip point temperature being crossed the way up or down, or setting the low level with the hysteresis. The ops is only called from the thermal sysfs code where the userspace has the ability to modify a trip point characteristic. With the effort of encapsulating the thermal framework core code, let's create a thermal_zone_set_trip() which is the writable side of the thermal_zone_get_trip() and put there all the ops encapsulation. Signed-off-by: Daniel Lezcano Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221003092602.1323944-4-daniel.lezcano@linaro.org --- drivers/thermal/thermal_core.c | 39 ++++++++++++++++++++++++++++ drivers/thermal/thermal_sysfs.c | 56 +++++++++++------------------------------ include/linux/thermal.h | 3 +++ 3 files changed, 57 insertions(+), 41 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index b043c315c005..c24c9efcd175 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1228,6 +1228,45 @@ int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, } EXPORT_SYMBOL_GPL(thermal_zone_get_trip); +int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id, + const struct thermal_trip *trip) +{ + struct thermal_trip t; + int ret; + + if (!tz->ops->set_trip_temp && !tz->ops->set_trip_hyst && !tz->trips) + return -EINVAL; + + ret = __thermal_zone_get_trip(tz, trip_id, &t); + if (ret) + return ret; + + if (t.type != trip->type) + return -EINVAL; + + if (t.temperature != trip->temperature && tz->ops->set_trip_temp) { + ret = tz->ops->set_trip_temp(tz, trip_id, trip->temperature); + if (ret) + return ret; + } + + if (t.hysteresis != trip->hysteresis && tz->ops->set_trip_hyst) { + ret = tz->ops->set_trip_hyst(tz, trip_id, trip->hysteresis); + if (ret) + return ret; + } + + if (tz->trips && (t.temperature != trip->temperature || t.hysteresis != trip->hysteresis)) + tz->trips[trip_id] = *trip; + + thermal_notify_tz_trip_change(tz->id, trip_id, trip->type, + trip->temperature, trip->hysteresis); + + __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED); + + return 0; +} + /** * thermal_zone_device_register_with_trips() - register a new thermal zone device * @type: the thermal zone device type diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index d2d450076090..cef860deaf91 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -123,15 +123,9 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, struct thermal_trip trip; int trip_id, ret; - if (!tz->ops->set_trip_temp && !tz->trips) - return -EPERM; - if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) return -EINVAL; - if (kstrtoint(buf, 10, &trip.temperature)) - return -EINVAL; - mutex_lock(&tz->lock); if (!device_is_registered(dev)) { @@ -139,31 +133,19 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, goto unlock; } - if (tz->ops->set_trip_temp) { - ret = tz->ops->set_trip_temp(tz, trip_id, trip.temperature); - if (ret) - goto unlock; - } - - if (tz->trips) - tz->trips[trip_id].temperature = trip.temperature; - ret = __thermal_zone_get_trip(tz, trip_id, &trip); if (ret) goto unlock; - thermal_notify_tz_trip_change(tz->id, trip_id, trip.type, - trip.temperature, trip.hysteresis); - - __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + ret = kstrtoint(buf, 10, &trip.temperature); + if (ret) + goto unlock; + ret = thermal_zone_set_trip(tz, trip_id, &trip); unlock: mutex_unlock(&tz->lock); - - if (ret) - return ret; - - return count; + + return ret ? ret : count; } static ssize_t @@ -197,16 +179,13 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip, ret; - int temperature; - - if (!tz->ops->set_trip_hyst) - return -EPERM; + struct thermal_trip trip; + int trip_id, ret; - if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1) + if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) return -EINVAL; - if (kstrtoint(buf, 10, &temperature)) + if (kstrtoint(buf, 10, &trip.hysteresis)) return -EINVAL; mutex_lock(&tz->lock); @@ -216,16 +195,11 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, goto unlock; } - /* - * We are not doing any check on the 'temperature' value - * here. The driver implementing 'set_trip_hyst' has to - * take care of this. - */ - ret = tz->ops->set_trip_hyst(tz, trip, temperature); - - if (!ret) - __thermal_zone_set_trips(tz); - + ret = __thermal_zone_get_trip(tz, trip_id, &trip); + if (ret) + goto unlock; + + ret = thermal_zone_set_trip(tz, trip_id, &trip); unlock: mutex_unlock(&tz->lock); diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 2198b3631f61..e2797f314d99 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -337,6 +337,9 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev, int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip); +int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id, + const struct thermal_trip *trip); + int thermal_zone_get_num_trips(struct thermal_zone_device *tz); int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp); -- cgit v1.2.3 From 7f725a23f2b7bb338a3d41ce7bf96d6c99bdb0b7 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:37 +0200 Subject: thermal/core/governors: Use thermal_zone_get_trip() instead of ops functions The governors are using the ops->get_trip_* functions, Replace these calls with thermal_zone_get_trip(). Signed-off-by: Daniel Lezcano Reviewed-by: Zhang Rui Reviewed-by: Lukasz Luba # IPA Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221003092602.1323944-5-daniel.lezcano@linaro.org --- drivers/thermal/gov_bang_bang.c | 37 ++++++++++++++----------- drivers/thermal/gov_fair_share.c | 18 +++++-------- drivers/thermal/gov_power_allocator.c | 51 ++++++++++++++++------------------- drivers/thermal/gov_step_wise.c | 22 +++++++-------- 4 files changed, 61 insertions(+), 67 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c index a08bbe33be96..1b121066521f 100644 --- a/drivers/thermal/gov_bang_bang.c +++ b/drivers/thermal/gov_bang_bang.c @@ -13,26 +13,28 @@ #include "thermal_core.h" -static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) +static int thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id) { - int trip_temp, trip_hyst; + struct thermal_trip trip; struct thermal_instance *instance; + int ret; - tz->ops->get_trip_temp(tz, trip, &trip_temp); + ret = __thermal_zone_get_trip(tz, trip_id, &trip); + if (ret) { + pr_warn_once("Failed to retrieve trip point %d\n", trip_id); + return ret; + } - if (!tz->ops->get_trip_hyst) { - pr_warn_once("Undefined get_trip_hyst for thermal zone %s - " - "running with default hysteresis zero\n", tz->type); - trip_hyst = 0; - } else - tz->ops->get_trip_hyst(tz, trip, &trip_hyst); + if (!trip.hysteresis) + dev_info_once(&tz->device, + "Zero hysteresis value for thermal zone %s\n", tz->type); dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n", - trip, trip_temp, tz->temperature, - trip_hyst); + trip_id, trip.temperature, tz->temperature, + trip.hysteresis); list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != trip) + if (instance->trip != trip_id) continue; /* in case fan is in initial state, switch the fan off */ @@ -50,10 +52,10 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) * enable fan when temperature exceeds trip_temp and disable * the fan in case it falls below trip_temp minus hysteresis */ - if (instance->target == 0 && tz->temperature >= trip_temp) + if (instance->target == 0 && tz->temperature >= trip.temperature) instance->target = 1; else if (instance->target == 1 && - tz->temperature <= trip_temp - trip_hyst) + tz->temperature <= trip.temperature - trip.hysteresis) instance->target = 0; dev_dbg(&instance->cdev->device, "target=%d\n", @@ -63,6 +65,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) instance->cdev->updated = false; /* cdev needs update */ mutex_unlock(&instance->cdev->lock); } + + return 0; } /** @@ -95,10 +99,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) static int bang_bang_control(struct thermal_zone_device *tz, int trip) { struct thermal_instance *instance; + int ret; lockdep_assert_held(&tz->lock); - thermal_zone_trip_update(tz, trip); + ret = thermal_zone_trip_update(tz, trip); + if (ret) + return ret; list_for_each_entry(instance, &tz->thermal_instances, tz_node) thermal_cdev_update(instance->cdev); diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c index 1cfeac16e7ac..aad7d5fe3a14 100644 --- a/drivers/thermal/gov_fair_share.c +++ b/drivers/thermal/gov_fair_share.c @@ -21,16 +21,12 @@ */ static int get_trip_level(struct thermal_zone_device *tz) { - int count = 0; - int trip_temp; - enum thermal_trip_type trip_type; - - if (tz->num_trips == 0 || !tz->ops->get_trip_temp) - return 0; + struct thermal_trip trip; + int count; for (count = 0; count < tz->num_trips; count++) { - tz->ops->get_trip_temp(tz, count, &trip_temp); - if (tz->temperature < trip_temp) + __thermal_zone_get_trip(tz, count, &trip); + if (tz->temperature < trip.temperature) break; } @@ -38,10 +34,8 @@ static int get_trip_level(struct thermal_zone_device *tz) * count > 0 only if temperature is greater than first trip * point, in which case, trip_point = count - 1 */ - if (count > 0) { - tz->ops->get_trip_type(tz, count - 1, &trip_type); - trace_thermal_zone_trip(tz, count - 1, trip_type); - } + if (count > 0) + trace_thermal_zone_trip(tz, count - 1, trip.type); return count; } diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index d5d4eae16771..0eaf1527d3e3 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -124,16 +124,15 @@ static void estimate_pid_constants(struct thermal_zone_device *tz, u32 sustainable_power, int trip_switch_on, int control_temp) { + struct thermal_trip trip; + u32 temperature_threshold = control_temp; int ret; - int switch_on_temp; - u32 temperature_threshold; s32 k_i; - ret = tz->ops->get_trip_temp(tz, trip_switch_on, &switch_on_temp); - if (ret) - switch_on_temp = 0; + ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip); + if (!ret) + temperature_threshold -= trip.temperature; - temperature_threshold = control_temp - switch_on_temp; /* * estimate_pid_constants() tries to find appropriate default * values for thermal zones that don't provide them. If a @@ -519,10 +518,10 @@ static void get_governor_trips(struct thermal_zone_device *tz, last_passive = INVALID_TRIP; for (i = 0; i < tz->num_trips; i++) { - enum thermal_trip_type type; + struct thermal_trip trip; int ret; - ret = tz->ops->get_trip_type(tz, i, &type); + ret = __thermal_zone_get_trip(tz, i, &trip); if (ret) { dev_warn(&tz->device, "Failed to get trip point %d type: %d\n", i, @@ -530,14 +529,14 @@ static void get_governor_trips(struct thermal_zone_device *tz, continue; } - if (type == THERMAL_TRIP_PASSIVE) { + if (trip.type == THERMAL_TRIP_PASSIVE) { if (!found_first_passive) { params->trip_switch_on = i; found_first_passive = true; } else { last_passive = i; } - } else if (type == THERMAL_TRIP_ACTIVE) { + } else if (trip.type == THERMAL_TRIP_ACTIVE) { last_active = i; } else { break; @@ -632,7 +631,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz) { int ret; struct power_allocator_params *params; - int control_temp; + struct thermal_trip trip; ret = check_power_actors(tz); if (ret) @@ -658,13 +657,12 @@ static int power_allocator_bind(struct thermal_zone_device *tz) get_governor_trips(tz, params); if (tz->num_trips > 0) { - ret = tz->ops->get_trip_temp(tz, - params->trip_max_desired_temperature, - &control_temp); + ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, + &trip); if (!ret) estimate_pid_constants(tz, tz->tzp->sustainable_power, params->trip_switch_on, - control_temp); + trip.temperature); } reset_pid_controller(params); @@ -694,11 +692,11 @@ static void power_allocator_unbind(struct thermal_zone_device *tz) tz->governor_data = NULL; } -static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) +static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id) { - int ret; - int switch_on_temp, control_temp; struct power_allocator_params *params = tz->governor_data; + struct thermal_trip trip; + int ret; bool update; lockdep_assert_held(&tz->lock); @@ -707,13 +705,12 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) * We get called for every trip point but we only need to do * our calculations once */ - if (trip != params->trip_max_desired_temperature) + if (trip_id != params->trip_max_desired_temperature) return 0; - ret = tz->ops->get_trip_temp(tz, params->trip_switch_on, - &switch_on_temp); - if (!ret && (tz->temperature < switch_on_temp)) { - update = (tz->last_temperature >= switch_on_temp); + ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip); + if (!ret && (tz->temperature < trip.temperature)) { + update = (tz->last_temperature >= trip.temperature); tz->passive = 0; reset_pid_controller(params); allow_maximum_power(tz, update); @@ -722,16 +719,14 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) tz->passive = 1; - ret = tz->ops->get_trip_temp(tz, params->trip_max_desired_temperature, - &control_temp); + ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip); if (ret) { - dev_warn(&tz->device, - "Failed to get the maximum desired temperature: %d\n", + dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n", ret); return ret; } - return allocate_power(tz, control_temp); + return allocate_power(tz, trip.temperature); } static struct thermal_governor thermal_gov_power_allocator = { diff --git a/drivers/thermal/gov_step_wise.c b/drivers/thermal/gov_step_wise.c index cdd3354bc27f..31235e169c5a 100644 --- a/drivers/thermal/gov_step_wise.c +++ b/drivers/thermal/gov_step_wise.c @@ -95,30 +95,28 @@ static void update_passive_instance(struct thermal_zone_device *tz, tz->passive += value; } -static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) +static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id) { - int trip_temp; - enum thermal_trip_type trip_type; enum thermal_trend trend; struct thermal_instance *instance; + struct thermal_trip trip; bool throttle = false; int old_target; - tz->ops->get_trip_temp(tz, trip, &trip_temp); - tz->ops->get_trip_type(tz, trip, &trip_type); + __thermal_zone_get_trip(tz, trip_id, &trip); - trend = get_tz_trend(tz, trip); + trend = get_tz_trend(tz, trip_id); - if (tz->temperature >= trip_temp) { + if (tz->temperature >= trip.temperature) { throttle = true; - trace_thermal_zone_trip(tz, trip, trip_type); + trace_thermal_zone_trip(tz, trip_id, trip.type); } dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n", - trip, trip_type, trip_temp, trend, throttle); + trip_id, trip.type, trip.temperature, trend, throttle); list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != trip) + if (instance->trip != trip_id) continue; old_target = instance->target; @@ -132,11 +130,11 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) /* Activate a passive thermal instance */ if (old_target == THERMAL_NO_TARGET && instance->target != THERMAL_NO_TARGET) - update_passive_instance(tz, trip_type, 1); + update_passive_instance(tz, trip.type, 1); /* Deactivate a passive thermal instance */ else if (old_target != THERMAL_NO_TARGET && instance->target == THERMAL_NO_TARGET) - update_passive_instance(tz, trip_type, -1); + update_passive_instance(tz, trip.type, -1); instance->initialized = true; mutex_lock(&instance->cdev->lock); -- cgit v1.2.3 From 453a55a97b5bc3e4418d6b9b2f07c7899d56d1ae Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:38 +0200 Subject: thermal/of: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. The thermal OF code uses the thermal_zone_device_register_with_trips() function. It builds the trips array and pass it to the register function. That means the get_trip_* ops are duplicated with what does already the core code. Remove them. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-6-daniel.lezcano@linaro.org --- drivers/thermal/thermal_of.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index aacba30bc10c..1fdf26c19448 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -71,39 +71,6 @@ of_thermal_get_trip_points(struct thermal_zone_device *tz) } EXPORT_SYMBOL_GPL(of_thermal_get_trip_points); -static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip, - enum thermal_trip_type *type) -{ - if (trip >= tz->num_trips || trip < 0) - return -EDOM; - - *type = tz->trips[trip].type; - - return 0; -} - -static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip, - int *temp) -{ - if (trip >= tz->num_trips || trip < 0) - return -EDOM; - - *temp = tz->trips[trip].temperature; - - return 0; -} - -static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip, - int *hyst) -{ - if (trip >= tz->num_trips || trip < 0) - return -EDOM; - - *hyst = tz->trips[trip].hysteresis; - - return 0; -} - static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip, int hyst) { @@ -628,9 +595,6 @@ struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, goto out_kfree_trips; } - of_ops->get_trip_type = of_ops->get_trip_type ? : of_thermal_get_trip_type; - of_ops->get_trip_temp = of_ops->get_trip_temp ? : of_thermal_get_trip_temp; - of_ops->get_trip_hyst = of_ops->get_trip_hyst ? : of_thermal_get_trip_hyst; of_ops->set_trip_hyst = of_ops->set_trip_hyst ? : of_thermal_set_trip_hyst; of_ops->get_crit_temp = of_ops->get_crit_temp ? : of_thermal_get_crit_temp; of_ops->bind = thermal_of_bind; -- cgit v1.2.3 From 5c4855d7653372f1e311b69642e8f0cc79d63f38 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:39 +0200 Subject: thermal/of: Remove unused functions Remove the dead code: of_thermal_get_trip_points() Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-7-daniel.lezcano@linaro.org --- drivers/thermal/thermal_core.h | 7 ------- drivers/thermal/thermal_of.c | 17 ----------------- 2 files changed, 24 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 5f475b0a8c2f..ef7800a15908 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -142,8 +142,6 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, #ifdef CONFIG_THERMAL_OF int of_thermal_get_ntrips(struct thermal_zone_device *); bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); -const struct thermal_trip * -of_thermal_get_trip_points(struct thermal_zone_device *); #else static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz) { @@ -154,11 +152,6 @@ static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, { return false; } -static inline const struct thermal_trip * -of_thermal_get_trip_points(struct thermal_zone_device *tz) -{ - return NULL; -} #endif int thermal_zone_device_is_enabled(struct thermal_zone_device *tz); diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 1fdf26c19448..2e8b1d635b3b 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -54,23 +54,6 @@ bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip) } EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid); -/** - * of_thermal_get_trip_points - function to get access to a globally exported - * trip points - * - * @tz: pointer to a thermal zone - * - * This function provides a pointer to trip points table - * - * Return: pointer to trip points table, NULL otherwise - */ -const struct thermal_trip * -of_thermal_get_trip_points(struct thermal_zone_device *tz) -{ - return tz->trips; -} -EXPORT_SYMBOL_GPL(of_thermal_get_trip_points); - static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip, int hyst) { -- cgit v1.2.3 From ca38255e92112c4204dbd551934505baf25849f4 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:40 +0200 Subject: thermal/drivers/exynos: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221003092602.1323944-8-daniel.lezcano@linaro.org --- drivers/thermal/samsung/exynos_tmu.c | 41 ++++++++++++++---------------------- 1 file changed, 16 insertions(+), 25 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 51874d0a284c..7b609bd3bf17 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -260,16 +260,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct thermal_zone_device *tzd = data->tzd; - const struct thermal_trip * const trips = - of_thermal_get_trip_points(tzd); unsigned int status; - int ret = 0, temp, hyst; - - if (!trips) { - dev_err(&pdev->dev, - "Cannot get trip points from device tree!\n"); - return -ENODEV; - } + int ret = 0, temp; if (data->soc != SOC_ARCH_EXYNOS5433) /* FIXME */ ret = tzd->ops->get_crit_temp(tzd, &temp); @@ -303,19 +295,16 @@ static int exynos_tmu_initialize(struct platform_device *pdev) /* Write temperature code for rising and falling threshold */ for (i = 0; i < ntrips; i++) { - /* Write temperature code for rising threshold */ - ret = tzd->ops->get_trip_temp(tzd, i, &temp); - if (ret) - goto err; - temp /= MCELSIUS; - data->tmu_set_trip_temp(data, i, temp); - /* Write temperature code for falling threshold */ - ret = tzd->ops->get_trip_hyst(tzd, i, &hyst); + struct thermal_trip trip; + + ret = thermal_zone_get_trip(tzd, i, &trip); if (ret) goto err; - hyst /= MCELSIUS; - data->tmu_set_trip_hyst(data, i, temp, hyst); + + data->tmu_set_trip_temp(data, i, trip.temperature / MCELSIUS); + data->tmu_set_trip_hyst(data, i, trip.temperature / MCELSIUS, + trip.hysteresis / MCELSIUS); } data->tmu_clear_irqs(data); @@ -360,21 +349,23 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) } static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data, - int trip, u8 temp) + int trip_id, u8 temp) { - const struct thermal_trip * const trips = - of_thermal_get_trip_points(data->tzd); + struct thermal_trip trip; u8 ref, th_code; - ref = trips[0].temperature / MCELSIUS; + if (thermal_zone_get_trip(data->tzd, 0, &trip)) + return; + + ref = trip.temperature / MCELSIUS; - if (trip == 0) { + if (trip_id == 0) { th_code = temp_to_code(data, ref); writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); } temp -= ref; - writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip * 4); + writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip_id * 4); } /* failing thresholds are not supported on Exynos4210 */ -- cgit v1.2.3 From a3b3dd381a0806cf19dab07a16f066e64d70a32d Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:41 +0200 Subject: thermal/drivers/exynos: of_thermal_get_ntrips() The thermal core framework allows to get the number of thermal trips, use it instead of visiting the thermal core structure internals. Signed-off-by: Daniel Lezcano Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221003092602.1323944-9-daniel.lezcano@linaro.org --- drivers/thermal/samsung/exynos_tmu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 7b609bd3bf17..254138745150 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -260,6 +260,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct thermal_zone_device *tzd = data->tzd; + int num_trips = thermal_zone_get_num_trips(tzd); unsigned int status; int ret = 0, temp; @@ -271,12 +272,12 @@ static int exynos_tmu_initialize(struct platform_device *pdev) goto out; } - if (of_thermal_get_ntrips(tzd) > data->ntrip) { + if (num_trips > data->ntrip) { dev_info(&pdev->dev, "More trip points than supported by this TMU.\n"); dev_info(&pdev->dev, "%d trip points should be configured in polling mode.\n", - (of_thermal_get_ntrips(tzd) - data->ntrip)); + num_trips - data->ntrip); } mutex_lock(&data->lock); @@ -289,7 +290,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) ret = -EBUSY; } else { int i, ntrips = - min_t(int, of_thermal_get_ntrips(tzd), data->ntrip); + min_t(int, num_trips, data->ntrip); data->tmu_initialize(pdev); -- cgit v1.2.3 From 03ef4855a825f9ba7195454f6498e0f056be995a Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:42 +0200 Subject: thermal/drivers/exynos: Replace of_thermal_is_trip_valid() by thermal_zone_get_trip() The thermal_zone_get_trip() does the same check as of_thermal_is_trip_valid(). Replace the call to of_thermal_is_trip_valid() by thermal_zone_get_trip(). Signed-off-by: Daniel Lezcano Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221003092602.1323944-10-daniel.lezcano@linaro.org --- drivers/thermal/samsung/exynos_tmu.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 254138745150..5a1ffe2f3134 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -554,13 +554,14 @@ static void exynos4210_tmu_control(struct platform_device *pdev, bool on) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct thermal_zone_device *tz = data->tzd; + struct thermal_trip trip; unsigned int con, interrupt_en = 0, i; con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); if (on) { for (i = 0; i < data->ntrip; i++) { - if (!of_thermal_is_trip_valid(tz, i)) + if (thermal_zone_get_trip(tz, i, &trip)) continue; interrupt_en |= @@ -584,13 +585,14 @@ static void exynos5433_tmu_control(struct platform_device *pdev, bool on) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct thermal_zone_device *tz = data->tzd; + struct thermal_trip trip; unsigned int con, interrupt_en = 0, pd_det_en, i; con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); if (on) { for (i = 0; i < data->ntrip; i++) { - if (!of_thermal_is_trip_valid(tz, i)) + if (thermal_zone_get_trip(tz, i, &trip)) continue; interrupt_en |= @@ -615,13 +617,14 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct thermal_zone_device *tz = data->tzd; + struct thermal_trip trip; unsigned int con, interrupt_en = 0, i; con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); if (on) { for (i = 0; i < data->ntrip; i++) { - if (!of_thermal_is_trip_valid(tz, i)) + if (thermal_zone_get_trip(tz, i, &trip)) continue; interrupt_en |= -- cgit v1.2.3 From 735a968d2fea8b6516d01efce2295d4f878bbbaf Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:43 +0200 Subject: thermal/drivers/tegra: Use generic thermal_zone_get_trip() function Replace a single call to thermal_zone_get_trip() to get a trip point instead of calling the different ops->get_trip* Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-11-daniel.lezcano@linaro.org --- drivers/thermal/tegra/soctherm.c | 33 ++++++++++++++------------------- drivers/thermal/tegra/tegra30-tsensor.c | 17 ++++++++--------- 2 files changed, 22 insertions(+), 28 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 1efe470f31e9..d2e454902689 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -582,23 +582,23 @@ static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id) return temp; } -static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip, int temp) +static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) { struct tegra_thermctl_zone *zone = tz->devdata; struct tegra_soctherm *ts = zone->ts; + struct thermal_trip trip; const struct tegra_tsensor_group *sg = zone->sg; struct device *dev = zone->dev; - enum thermal_trip_type type; int ret; if (!tz) return -EINVAL; - ret = tz->ops->get_trip_type(tz, trip, &type); + ret = thermal_zone_get_trip(tz, trip_id, &trip); if (ret) return ret; - if (type == THERMAL_TRIP_CRITICAL) { + if (trip.type == THERMAL_TRIP_CRITICAL) { /* * If thermtrips property is set in DT, * doesn't need to program critical type trip to HW, @@ -609,7 +609,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip else return 0; - } else if (type == THERMAL_TRIP_HOT) { + } else if (trip.type == THERMAL_TRIP_HOT) { int i; for (i = 0; i < THROTTLE_SIZE; i++) { @@ -620,7 +620,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip continue; cdev = ts->throt_cfgs[i].cdev; - if (get_thermal_instance(tz, cdev, trip)) + if (get_thermal_instance(tz, cdev, trip_id)) stc = find_throttle_cfg_by_name(ts, cdev->type); else continue; @@ -687,25 +687,20 @@ static const struct thermal_zone_device_ops tegra_of_thermal_ops = { .set_trips = tegra_thermctl_set_trips, }; -static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp) +static int get_hot_temp(struct thermal_zone_device *tz, int *trip_id, int *temp) { - int ntrips, i, ret; - enum thermal_trip_type type; + int i, ret; + struct thermal_trip trip; - ntrips = of_thermal_get_ntrips(tz); - if (ntrips <= 0) - return -EINVAL; + for (i = 0; i < thermal_zone_get_num_trips(tz); i++) { - for (i = 0; i < ntrips; i++) { - ret = tz->ops->get_trip_type(tz, i, &type); + ret = thermal_zone_get_trip(tz, i, &trip); if (ret) return -EINVAL; - if (type == THERMAL_TRIP_HOT) { - ret = tz->ops->get_trip_temp(tz, i, temp); - if (!ret) - *trip = i; - return ret; + if (trip.type == THERMAL_TRIP_HOT) { + *trip_id = i; + return 0; } } diff --git a/drivers/thermal/tegra/tegra30-tsensor.c b/drivers/thermal/tegra/tegra30-tsensor.c index c34501287e96..0ffe37ce7df7 100644 --- a/drivers/thermal/tegra/tegra30-tsensor.c +++ b/drivers/thermal/tegra/tegra30-tsensor.c @@ -316,18 +316,17 @@ static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd, *hot_trip = 85000; *crit_trip = 90000; - for (i = 0; i < tzd->num_trips; i++) { - enum thermal_trip_type type; - int trip_temp; + for (i = 0; i < thermal_zone_get_num_trips(tzd); i++) { - tzd->ops->get_trip_temp(tzd, i, &trip_temp); - tzd->ops->get_trip_type(tzd, i, &type); + struct thermal_trip trip; - if (type == THERMAL_TRIP_HOT) - *hot_trip = trip_temp; + thermal_zone_get_trip(tzd, i, &trip); - if (type == THERMAL_TRIP_CRITICAL) - *crit_trip = trip_temp; + if (trip.type == THERMAL_TRIP_HOT) + *hot_trip = trip.temperature; + + if (trip.type == THERMAL_TRIP_CRITICAL) + *crit_trip = trip.temperature; } /* clamp hardware trips to the calibration limits */ -- cgit v1.2.3 From c7ed8cab4079ec2e762393720aba1d3075935056 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:44 +0200 Subject: thermal/drivers/uniphier: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Reviewed-by: Kunihiko Hayashi Link: https://lore.kernel.org/r/20221003092602.1323944-12-daniel.lezcano@linaro.org --- drivers/thermal/uniphier_thermal.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c index 4111d99ef50e..277ae300c5b1 100644 --- a/drivers/thermal/uniphier_thermal.c +++ b/drivers/thermal/uniphier_thermal.c @@ -248,8 +248,7 @@ static int uniphier_tm_probe(struct platform_device *pdev) struct regmap *regmap; struct device_node *parent; struct uniphier_tm_dev *tdev; - const struct thermal_trip *trips; - int i, ret, irq, ntrips, crit_temp = INT_MAX; + int i, ret, irq, crit_temp = INT_MAX; tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL); if (!tdev) @@ -296,20 +295,18 @@ static int uniphier_tm_probe(struct platform_device *pdev) return PTR_ERR(tdev->tz_dev); } - /* get trip points */ - trips = of_thermal_get_trip_points(tdev->tz_dev); - ntrips = of_thermal_get_ntrips(tdev->tz_dev); - if (ntrips > ALERT_CH_NUM) { - dev_err(dev, "thermal zone has too many trips\n"); - return -E2BIG; - } - /* set alert temperatures */ - for (i = 0; i < ntrips; i++) { - if (trips[i].type == THERMAL_TRIP_CRITICAL && - trips[i].temperature < crit_temp) - crit_temp = trips[i].temperature; - uniphier_tm_set_alert(tdev, i, trips[i].temperature); + for (i = 0; i < thermal_zone_get_num_trips(tdev->tz_dev); i++) { + struct thermal_trip trip; + + ret = thermal_zone_get_trip(tdev->tz_dev, i, &trip); + if (ret) + return ret; + + if (trip.type == THERMAL_TRIP_CRITICAL && + trip.temperature < crit_temp) + crit_temp = trip.temperature; + uniphier_tm_set_alert(tdev, i, trip.temperature); tdev->alert_en[i] = true; } if (crit_temp > CRITICAL_TEMP_LIMIT) { -- cgit v1.2.3 From 68a306cc839718d1875b46ebf73c25c8fa7f704a Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:45 +0200 Subject: thermal/drivers/hisi: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-13-daniel.lezcano@linaro.org --- drivers/thermal/hisi_thermal.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index d6974db7aaf7..45226cab466e 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -482,7 +482,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, struct hisi_thermal_sensor *sensor) { int ret, i; - const struct thermal_trip *trip; + struct thermal_trip trip; sensor->tzd = devm_thermal_of_zone_register(&pdev->dev, sensor->id, sensor, @@ -495,11 +495,12 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, return ret; } - trip = of_thermal_get_trip_points(sensor->tzd); + for (i = 0; i < thermal_zone_get_num_trips(sensor->tzd); i++) { - for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) { - if (trip[i].type == THERMAL_TRIP_PASSIVE) { - sensor->thres_temp = trip[i].temperature; + thermal_zone_get_trip(sensor->tzd, i, &trip); + + if (trip.type == THERMAL_TRIP_PASSIVE) { + sensor->thres_temp = trip.temperature; break; } } -- cgit v1.2.3 From 1fa86b0a36927ed13a1505c9ee7b80c66718c733 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:46 +0200 Subject: thermal/drivers/qcom: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Acked-by: Amit Kucheria Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20221003092602.1323944-14-daniel.lezcano@linaro.org --- drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 39 +++++++++++++---------------- 1 file changed, 17 insertions(+), 22 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index ad84978109e6..58055a7abaf6 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -264,17 +264,17 @@ skip: return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg); } -static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip, int temp) +static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) { struct qpnp_tm_chip *chip = tz->devdata; - const struct thermal_trip *trip_points; + struct thermal_trip trip; int ret; - trip_points = of_thermal_get_trip_points(chip->tz_dev); - if (!trip_points) - return -EINVAL; + ret = thermal_zone_get_trip(chip->tz_dev, trip_id, &trip); + if (ret) + return ret; - if (trip_points[trip].type != THERMAL_TRIP_CRITICAL) + if (trip.type != THERMAL_TRIP_CRITICAL) return 0; mutex_lock(&chip->lock); @@ -300,22 +300,17 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data) static int qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip *chip) { - int ntrips; - const struct thermal_trip *trips; - int i; - - ntrips = of_thermal_get_ntrips(chip->tz_dev); - if (ntrips <= 0) - return THERMAL_TEMP_INVALID; - - trips = of_thermal_get_trip_points(chip->tz_dev); - if (!trips) - return THERMAL_TEMP_INVALID; - - for (i = 0; i < ntrips; i++) { - if (of_thermal_is_trip_valid(chip->tz_dev, i) && - trips[i].type == THERMAL_TRIP_CRITICAL) - return trips[i].temperature; + struct thermal_trip trip; + int i, ret; + + for (i = 0; i < thermal_zone_get_num_trips(chip->tz_dev); i++) { + + ret = thermal_zone_get_trip(chip->tz_dev, i, &trip); + if (ret) + continue; + + if (trip.type == THERMAL_TRIP_CRITICAL) + return trip.temperature; } return THERMAL_TEMP_INVALID; -- cgit v1.2.3 From eb2bb3be1384d91b65c7ca956f6fe7bfd5391ee2 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:47 +0200 Subject: thermal/drivers/armada: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-15-daniel.lezcano@linaro.org --- drivers/thermal/armada_thermal.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 52d63b3997fe..b28695a55eea 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -785,33 +785,34 @@ static int armada_configure_overheat_int(struct armada_thermal_priv *priv, int sensor_id) { /* Retrieve the critical trip point to enable the overheat interrupt */ - const struct thermal_trip *trips = of_thermal_get_trip_points(tz); + struct thermal_trip trip; int ret; int i; - if (!trips) - return -EINVAL; + for (i = 0; i < thermal_zone_get_num_trips(tz); i++) { - for (i = 0; i < of_thermal_get_ntrips(tz); i++) - if (trips[i].type == THERMAL_TRIP_CRITICAL) - break; + ret = thermal_zone_get_trip(tz, i, &trip); + if (ret) + return ret; - if (i == of_thermal_get_ntrips(tz)) - return -EINVAL; + if (trip.type != THERMAL_TRIP_CRITICAL) + continue; - ret = armada_select_channel(priv, sensor_id); - if (ret) - return ret; + ret = armada_select_channel(priv, sensor_id); + if (ret) + return ret; - armada_set_overheat_thresholds(priv, - trips[i].temperature, - trips[i].hysteresis); - priv->overheat_sensor = tz; - priv->interrupt_source = sensor_id; + armada_set_overheat_thresholds(priv, trip.temperature, + trip.hysteresis); + priv->overheat_sensor = tz; + priv->interrupt_source = sensor_id; - armada_enable_overheat_interrupt(priv); + armada_enable_overheat_interrupt(priv); - return 0; + return 0; + } + + return -EINVAL; } static int armada_thermal_probe(struct platform_device *pdev) -- cgit v1.2.3 From d5299c1b829f4754e2fa0c62ac6b02545efe4329 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:48 +0200 Subject: thermal/drivers/rcar_gen3: Use the generic function to get the number of trips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The thermal core framework allows to get the number of thermal trips, use it instead of visiting the thermal core structure internals. Signed-off-by: Daniel Lezcano Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20221003092602.1323944-16-daniel.lezcano@linaro.org --- drivers/thermal/rcar_gen3_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c index 4c1c6f89aa2f..4ef927437842 100644 --- a/drivers/thermal/rcar_gen3_thermal.c +++ b/drivers/thermal/rcar_gen3_thermal.c @@ -529,7 +529,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev) if (ret) goto error_unregister; - ret = of_thermal_get_ntrips(tsc->zone); + ret = thermal_zone_get_num_trips(tsc->zone); if (ret < 0) goto error_unregister; -- cgit v1.2.3 From 2480b02a36cec8a71dba8fc3e4caeaed03669e62 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:49 +0200 Subject: thermal/of: Remove of_thermal_get_ntrips() The thermal OF code uses the generic trip points to initialize the thermal zone. Consequently thermal_zone_get_num_trips() can be used and the of_thermal_get_ntrips() is no longer needed. Remove it. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-17-daniel.lezcano@linaro.org --- drivers/thermal/thermal_core.h | 5 ----- drivers/thermal/thermal_of.c | 16 ---------------- 2 files changed, 21 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index ef7800a15908..6cda4a180e12 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -140,13 +140,8 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, /* device tree support */ #ifdef CONFIG_THERMAL_OF -int of_thermal_get_ntrips(struct thermal_zone_device *); bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); #else -static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz) -{ - return 0; -} static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip) { diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 2e8b1d635b3b..6cb3b59cab6d 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -19,22 +19,6 @@ #include "thermal_core.h" -/** - * of_thermal_get_ntrips - function to export number of available trip - * points. - * @tz: pointer to a thermal zone - * - * This function is a globally visible wrapper to get number of trip points - * stored in the local struct __thermal_zone - * - * Return: number of available trip points, -ENODEV when data not available - */ -int of_thermal_get_ntrips(struct thermal_zone_device *tz) -{ - return tz->num_trips; -} -EXPORT_SYMBOL_GPL(of_thermal_get_ntrips); - /** * of_thermal_is_trip_valid - function to check if trip point is valid * -- cgit v1.2.3 From f9061f4e15c5e1f322f7765a7b054bafd4d0bc59 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:50 +0200 Subject: thermal/of: Remove of_thermal_is_trip_valid() There is no benefit with the of_thermal_is_trip_valid() function as it does the check the thermal_zone_get_trip() is already doing for the sake of getting the trip point. As all the calls have been replaced by thermal_zone_get_trip(), there is no more users of of_thermal_is_trip_valid(). Remove the function. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-18-daniel.lezcano@linaro.org --- drivers/thermal/thermal_core.h | 10 ---------- drivers/thermal/thermal_of.c | 19 ------------------- 2 files changed, 29 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 6cda4a180e12..26350206a98d 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -139,16 +139,6 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, #endif /* CONFIG_THERMAL_STATISTICS */ /* device tree support */ -#ifdef CONFIG_THERMAL_OF -bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); -#else -static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, - int trip) -{ - return false; -} -#endif - int thermal_zone_device_is_enabled(struct thermal_zone_device *tz); #endif /* __THERMAL_CORE_H__ */ diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 6cb3b59cab6d..d6fe349b3c5a 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -19,25 +19,6 @@ #include "thermal_core.h" -/** - * of_thermal_is_trip_valid - function to check if trip point is valid - * - * @tz: pointer to a thermal zone - * @trip: trip point to evaluate - * - * This function is responsible for checking if passed trip point is valid - * - * Return: true if trip point is valid, false otherwise - */ -bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip) -{ - if (trip >= tz->num_trips || trip < 0) - return false; - - return true; -} -EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid); - static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip, int hyst) { -- cgit v1.2.3 From 810245133eaec213517bad835e394cbf4fb2d6cd Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:51 +0200 Subject: thermal/of: Remove of_thermal_set_trip_hyst() The thermal core is providing the generic thermal_zone_set_trip() function which does exactly what the OF ops function is doing. It is pointless to define our own version, just remove the ops and the thermal_zone_set_trip() will take care of it. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-19-daniel.lezcano@linaro.org --- drivers/thermal/thermal_of.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index d6fe349b3c5a..2fcdb3e459c0 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -19,18 +19,6 @@ #include "thermal_core.h" -static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip, - int hyst) -{ - if (trip >= tz->num_trips || trip < 0) - return -EDOM; - - /* thermal framework should take care of data->mask & (1 << trip) */ - tz->trips[trip].hysteresis = hyst; - - return 0; -} - static int of_thermal_get_crit_temp(struct thermal_zone_device *tz, int *temp) { @@ -543,7 +531,6 @@ struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, goto out_kfree_trips; } - of_ops->set_trip_hyst = of_ops->set_trip_hyst ? : of_thermal_set_trip_hyst; of_ops->get_crit_temp = of_ops->get_crit_temp ? : of_thermal_get_crit_temp; of_ops->bind = thermal_of_bind; of_ops->unbind = thermal_of_unbind; -- cgit v1.2.3 From aacfbf15e0ac2ba1e1b848fc439a9c7c7fd90934 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:52 +0200 Subject: thermal/of: Remove of_thermal_get_crit_temp() The generic version of of_thermal_get_crit_temp() can be used. Let's remove this ops which is pointless. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-20-daniel.lezcano@linaro.org --- drivers/thermal/thermal_of.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 2fcdb3e459c0..ff4d12ef51bc 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -19,20 +19,6 @@ #include "thermal_core.h" -static int of_thermal_get_crit_temp(struct thermal_zone_device *tz, - int *temp) -{ - int i; - - for (i = 0; i < tz->num_trips; i++) - if (tz->trips[i].type == THERMAL_TRIP_CRITICAL) { - *temp = tz->trips[i].temperature; - return 0; - } - - return -EINVAL; -} - /*** functions parsing device tree nodes ***/ static int of_find_trip_id(struct device_node *np, struct device_node *trip) @@ -531,7 +517,6 @@ struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, goto out_kfree_trips; } - of_ops->get_crit_temp = of_ops->get_crit_temp ? : of_thermal_get_crit_temp; of_ops->bind = thermal_of_bind; of_ops->unbind = thermal_of_unbind; -- cgit v1.2.3 From 28fd2cd9b38ba82578d21e71acd93010a77c9942 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:53 +0200 Subject: thermal/drivers/st: Use generic trip points The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert to the generic trip points Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-21-daniel.lezcano@linaro.org --- drivers/thermal/st/st_thermal.c | 47 ++++++----------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/st/st_thermal.c b/drivers/thermal/st/st_thermal.c index 1276b95604fe..1009f08e64e3 100644 --- a/drivers/thermal/st/st_thermal.c +++ b/drivers/thermal/st/st_thermal.c @@ -134,48 +134,12 @@ static int st_thermal_get_temp(struct thermal_zone_device *th, int *temperature) return 0; } -static int st_thermal_get_trip_type(struct thermal_zone_device *th, - int trip, enum thermal_trip_type *type) -{ - struct st_thermal_sensor *sensor = th->devdata; - struct device *dev = sensor->dev; - - switch (trip) { - case 0: - *type = THERMAL_TRIP_CRITICAL; - break; - default: - dev_err(dev, "invalid trip point\n"); - return -EINVAL; - } - - return 0; -} - -static int st_thermal_get_trip_temp(struct thermal_zone_device *th, - int trip, int *temp) -{ - struct st_thermal_sensor *sensor = th->devdata; - struct device *dev = sensor->dev; - - switch (trip) { - case 0: - *temp = mcelsius(sensor->cdata->crit_temp); - break; - default: - dev_err(dev, "Invalid trip point\n"); - return -EINVAL; - } - - return 0; -} - static struct thermal_zone_device_ops st_tz_ops = { .get_temp = st_thermal_get_temp, - .get_trip_type = st_thermal_get_trip_type, - .get_trip_temp = st_thermal_get_trip_temp, }; +static struct thermal_trip trip; + int st_thermal_register(struct platform_device *pdev, const struct of_device_id *st_thermal_of_match) { @@ -238,9 +202,12 @@ int st_thermal_register(struct platform_device *pdev, polling_delay = sensor->ops->register_enable_irq ? 0 : 1000; + trip.temperature = sensor->cdata->crit_temp; + trip.type = THERMAL_TRIP_CRITICAL; + sensor->thermal_dev = - thermal_zone_device_register(dev_name(dev), 1, 0, sensor, - &st_tz_ops, NULL, 0, polling_delay); + thermal_zone_device_register_with_trips(dev_name(dev), &trip, 1, 0, sensor, + &st_tz_ops, NULL, 0, polling_delay); if (IS_ERR(sensor->thermal_dev)) { dev_err(dev, "failed to register thermal zone device\n"); ret = PTR_ERR(sensor->thermal_dev); -- cgit v1.2.3 From 30233a229fdbca747896e279f88df8e66ef44a4e Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:54 +0200 Subject: thermal/drivers/imx: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-22-daniel.lezcano@linaro.org --- drivers/thermal/imx_thermal.c | 72 ++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 45 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 16663373b682..fb0d5cab70af 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -76,7 +76,6 @@ enum imx_thermal_trip { IMX_TRIP_PASSIVE, IMX_TRIP_CRITICAL, - IMX_TRIP_NUM, }; #define IMX_POLLING_DELAY 2000 /* millisecond */ @@ -115,6 +114,11 @@ struct thermal_soc_data { u32 low_alarm_shift; }; +static struct thermal_trip trips[] = { + [IMX_TRIP_PASSIVE] = { .type = THERMAL_TRIP_PASSIVE }, + [IMX_TRIP_CRITICAL] = { .type = THERMAL_TRIP_CRITICAL }, +}; + static struct thermal_soc_data thermal_imx6q_data = { .version = TEMPMON_IMX6Q, @@ -201,8 +205,6 @@ struct imx_thermal_data { struct thermal_cooling_device *cdev; struct regmap *tempmon; u32 c1, c2; /* See formula in imx_init_calib() */ - int temp_passive; - int temp_critical; int temp_max; int alarm_temp; int last_temp; @@ -279,12 +281,12 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */ if (data->socdata->version == TEMPMON_IMX6Q) { - if (data->alarm_temp == data->temp_passive && - *temp >= data->temp_passive) - imx_set_alarm_temp(data, data->temp_critical); - if (data->alarm_temp == data->temp_critical && - *temp < data->temp_passive) { - imx_set_alarm_temp(data, data->temp_passive); + if (data->alarm_temp == trips[IMX_TRIP_PASSIVE].temperature && + *temp >= trips[IMX_TRIP_PASSIVE].temperature) + imx_set_alarm_temp(data, trips[IMX_TRIP_CRITICAL].temperature); + if (data->alarm_temp == trips[IMX_TRIP_CRITICAL].temperature && + *temp < trips[IMX_TRIP_PASSIVE].temperature) { + imx_set_alarm_temp(data, trips[IMX_TRIP_PASSIVE].temperature); dev_dbg(&tz->device, "thermal alarm off: T < %d\n", data->alarm_temp / 1000); } @@ -330,29 +332,10 @@ static int imx_change_mode(struct thermal_zone_device *tz, return 0; } -static int imx_get_trip_type(struct thermal_zone_device *tz, int trip, - enum thermal_trip_type *type) -{ - *type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE : - THERMAL_TRIP_CRITICAL; - return 0; -} - static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp) { - struct imx_thermal_data *data = tz->devdata; - - *temp = data->temp_critical; - return 0; -} - -static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip, - int *temp) -{ - struct imx_thermal_data *data = tz->devdata; + *temp = trips[IMX_TRIP_CRITICAL].temperature; - *temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive : - data->temp_critical; return 0; } @@ -371,10 +354,10 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, return -EPERM; /* do not allow passive to be set higher than critical */ - if (temp < 0 || temp > data->temp_critical) + if (temp < 0 || temp > trips[IMX_TRIP_CRITICAL].temperature) return -EINVAL; - data->temp_passive = temp; + trips[IMX_TRIP_PASSIVE].temperature = temp; imx_set_alarm_temp(data, temp); @@ -423,8 +406,6 @@ static struct thermal_zone_device_ops imx_tz_ops = { .unbind = imx_unbind, .get_temp = imx_get_temp, .change_mode = imx_change_mode, - .get_trip_type = imx_get_trip_type, - .get_trip_temp = imx_get_trip_temp, .get_crit_temp = imx_get_crit_temp, .set_trip_temp = imx_set_trip_temp, }; @@ -507,8 +488,8 @@ static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0) * Set the critical trip point at 5 °C under max * Set the passive trip point at 10 °C under max (changeable via sysfs) */ - data->temp_critical = data->temp_max - (1000 * 5); - data->temp_passive = data->temp_max - (1000 * 10); + trips[IMX_TRIP_PASSIVE].temperature = data->temp_max - (1000 * 10); + trips[IMX_TRIP_CRITICAL].temperature = data->temp_max - (1000 * 5); } static int imx_init_from_tempmon_data(struct platform_device *pdev) @@ -743,12 +724,13 @@ static int imx_thermal_probe(struct platform_device *pdev) goto legacy_cleanup; } - data->tz = thermal_zone_device_register("imx_thermal_zone", - IMX_TRIP_NUM, - BIT(IMX_TRIP_PASSIVE), data, - &imx_tz_ops, NULL, - IMX_PASSIVE_DELAY, - IMX_POLLING_DELAY); + data->tz = thermal_zone_device_register_with_trips("imx_thermal_zone", + trips, + ARRAY_SIZE(trips), + BIT(IMX_TRIP_PASSIVE), data, + &imx_tz_ops, NULL, + IMX_PASSIVE_DELAY, + IMX_POLLING_DELAY); if (IS_ERR(data->tz)) { ret = PTR_ERR(data->tz); dev_err(&pdev->dev, @@ -758,8 +740,8 @@ static int imx_thermal_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC" " critical:%dC passive:%dC\n", data->temp_grade, - data->temp_max / 1000, data->temp_critical / 1000, - data->temp_passive / 1000); + data->temp_max / 1000, trips[IMX_TRIP_CRITICAL].temperature / 1000, + trips[IMX_TRIP_PASSIVE].temperature / 1000); /* Enable measurements at ~ 10 Hz */ regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR, @@ -767,10 +749,10 @@ static int imx_thermal_probe(struct platform_device *pdev) measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET, measure_freq << data->socdata->measure_freq_shift); - imx_set_alarm_temp(data, data->temp_passive); + imx_set_alarm_temp(data, trips[IMX_TRIP_PASSIVE].temperature); if (data->socdata->version == TEMPMON_IMX6SX) - imx_set_panic_temp(data, data->temp_critical); + imx_set_panic_temp(data, trips[IMX_TRIP_CRITICAL].temperature); regmap_write(map, data->socdata->sensor_ctrl + REG_CLR, data->socdata->power_down_mask); -- cgit v1.2.3 From 0b6a3e459e1e615cb2d8c2e33b63e9589ec17850 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:55 +0200 Subject: thermal/drivers/rcar: Use generic thermal_zone_get_trip() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20221003092602.1323944-23-daniel.lezcano@linaro.org --- drivers/thermal/rcar_thermal.c | 53 +++++------------------------------------- 1 file changed, 6 insertions(+), 47 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 61c2b8855cb8..436f5f9cf729 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -278,52 +278,12 @@ static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp) return rcar_thermal_get_current_temp(priv, temp); } -static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone, - int trip, enum thermal_trip_type *type) -{ - struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); - struct device *dev = rcar_priv_to_dev(priv); - - /* see rcar_thermal_get_temp() */ - switch (trip) { - case 0: /* +90 <= temp */ - *type = THERMAL_TRIP_CRITICAL; - break; - default: - dev_err(dev, "rcar driver trip error\n"); - return -EINVAL; - } - - return 0; -} - -static int rcar_thermal_get_trip_temp(struct thermal_zone_device *zone, - int trip, int *temp) -{ - struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); - struct device *dev = rcar_priv_to_dev(priv); - - /* see rcar_thermal_get_temp() */ - switch (trip) { - case 0: /* +90 <= temp */ - *temp = MCELSIUS(90); - break; - default: - dev_err(dev, "rcar driver trip error\n"); - return -EINVAL; - } - - return 0; -} - -static const struct thermal_zone_device_ops rcar_thermal_zone_of_ops = { +static struct thermal_zone_device_ops rcar_thermal_zone_ops = { .get_temp = rcar_thermal_get_temp, }; -static struct thermal_zone_device_ops rcar_thermal_zone_ops = { - .get_temp = rcar_thermal_get_temp, - .get_trip_type = rcar_thermal_get_trip_type, - .get_trip_temp = rcar_thermal_get_trip_temp, +static struct thermal_trip trips[] = { + { .type = THERMAL_TRIP_CRITICAL, .temperature = 90000 } }; /* @@ -529,11 +489,10 @@ static int rcar_thermal_probe(struct platform_device *pdev) if (chip->use_of_thermal) { priv->zone = devm_thermal_of_zone_register( dev, i, priv, - &rcar_thermal_zone_of_ops); + &rcar_thermal_zone_ops); } else { - priv->zone = thermal_zone_device_register( - "rcar_thermal", - 1, 0, priv, + priv->zone = thermal_zone_device_register_with_trips( + "rcar_thermal", trips, ARRAY_SIZE(trips), 0, priv, &rcar_thermal_zone_ops, NULL, 0, idle); -- cgit v1.2.3 From 52945c1c65fbc437a94eb0006561e7ff640cd8a8 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:56 +0200 Subject: thermal/drivers/broadcom: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/20221003092602.1323944-24-daniel.lezcano@linaro.org --- drivers/thermal/broadcom/bcm2835_thermal.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 2c67841a1115..5485e59d03a9 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -18,6 +18,7 @@ #include #include +#include "../thermal_core.h" #include "../thermal_hwmon.h" #define BCM2835_TS_TSENSCTL 0x00 @@ -224,7 +225,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) */ val = readl(data->regs + BCM2835_TS_TSENSCTL); if (!(val & BCM2835_TS_TSENSCTL_RSTB)) { - int trip_temp, offset, slope; + struct thermal_trip trip; + int offset, slope; slope = thermal_zone_get_slope(tz); offset = thermal_zone_get_offset(tz); @@ -232,7 +234,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) * For now we deal only with critical, otherwise * would need to iterate */ - err = tz->ops->get_trip_temp(tz, 0, &trip_temp); + err = thermal_zone_get_trip(tz, 0, &trip); if (err < 0) { dev_err(&pdev->dev, "Not able to read trip_temp: %d\n", @@ -249,7 +251,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT); /* trip_adc value from info */ - val |= bcm2835_thermal_temp2adc(trip_temp, + val |= bcm2835_thermal_temp2adc(trip.temperature, offset, slope) << BCM2835_TS_TSENSCTL_THOLD_SHIFT; -- cgit v1.2.3 From 060b39d934f219386478f892879231bf262f02ca Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:57 +0200 Subject: thermal/drivers/da9062: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Reviewed-by: Adam Ward Link: https://lore.kernel.org/r/20221003092602.1323944-25-daniel.lezcano@linaro.org --- drivers/thermal/da9062-thermal.c | 52 +++++++--------------------------------- 1 file changed, 8 insertions(+), 44 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/da9062-thermal.c b/drivers/thermal/da9062-thermal.c index 7dcfde7a9f2c..a805a6666c44 100644 --- a/drivers/thermal/da9062-thermal.c +++ b/drivers/thermal/da9062-thermal.c @@ -120,44 +120,6 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static int da9062_thermal_get_trip_type(struct thermal_zone_device *z, - int trip, - enum thermal_trip_type *type) -{ - struct da9062_thermal *thermal = z->devdata; - - switch (trip) { - case 0: - *type = THERMAL_TRIP_HOT; - break; - default: - dev_err(thermal->dev, - "Driver does not support more than 1 trip-wire\n"); - return -EINVAL; - } - - return 0; -} - -static int da9062_thermal_get_trip_temp(struct thermal_zone_device *z, - int trip, - int *temp) -{ - struct da9062_thermal *thermal = z->devdata; - - switch (trip) { - case 0: - *temp = DA9062_MILLI_CELSIUS(125); - break; - default: - dev_err(thermal->dev, - "Driver does not support more than 1 trip-wire\n"); - return -EINVAL; - } - - return 0; -} - static int da9062_thermal_get_temp(struct thermal_zone_device *z, int *temp) { @@ -172,8 +134,10 @@ static int da9062_thermal_get_temp(struct thermal_zone_device *z, static struct thermal_zone_device_ops da9062_thermal_ops = { .get_temp = da9062_thermal_get_temp, - .get_trip_type = da9062_thermal_get_trip_type, - .get_trip_temp = da9062_thermal_get_trip_temp, +}; + +static struct thermal_trip trips[] = { + { .temperature = DA9062_MILLI_CELSIUS(125), .type = THERMAL_TRIP_HOT }, }; static const struct da9062_thermal_config da9062_config = { @@ -228,10 +192,10 @@ static int da9062_thermal_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on); mutex_init(&thermal->lock); - thermal->zone = thermal_zone_device_register(thermal->config->name, - 1, 0, thermal, - &da9062_thermal_ops, NULL, pp_tmp, - 0); + thermal->zone = thermal_zone_device_register_with_trips(thermal->config->name, + trips, ARRAY_SIZE(trips), 0, thermal, + &da9062_thermal_ops, NULL, pp_tmp, + 0); if (IS_ERR(thermal->zone)) { dev_err(&pdev->dev, "Cannot register thermal zone device\n"); ret = PTR_ERR(thermal->zone); -- cgit v1.2.3 From 69cf4eaa681654605778262c0624274a454264a6 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:25:58 +0200 Subject: thermal/drivers/ti: Remove unused macros ti_thermal_get_trip_value() / ti_thermal_trip_is_valid() The macros: ti_thermal_get_trip_value() ti_thermal_trip_is_valid() are unused. Remove them. Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20221003092602.1323944-26-daniel.lezcano@linaro.org --- drivers/thermal/ti-soc-thermal/ti-thermal.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal.h b/drivers/thermal/ti-soc-thermal/ti-thermal.h index c388ecf31834..4fd2c20182d7 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal.h +++ b/drivers/thermal/ti-soc-thermal/ti-thermal.h @@ -38,21 +38,6 @@ /* Update rates */ #define FAST_TEMP_MONITORING_RATE 250 -/* helper macros */ -/** - * ti_thermal_get_trip_value - returns trip temperature based on index - * @i: trip index - */ -#define ti_thermal_get_trip_value(i) \ - (OMAP_TRIP_HOT + ((i) * OMAP_TRIP_STEP)) - -/** - * ti_thermal_is_valid_trip - check for trip index - * @i: trip index - */ -#define ti_thermal_is_valid_trip(trip) \ - ((trip) >= 0 && (trip) < OMAP_TRIP_NUMBER) - #ifdef CONFIG_TI_THERMAL int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, char *domain); int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id); -- cgit v1.2.3 From 0d2d586a86e85f10bd8fe47c219024b14de280b8 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:26:01 +0200 Subject: thermal/intel/int340x: Replace parameter to simplify In the process of replacing the get_trip_* ops by the generic trip points, the current code has an 'override' property to add another indirection to a different ops. Rework this approach to prevent this indirection and make the code ready for the generic trip points conversion. Actually the get_temp() is different regarding the platform, so it is pointless to add a new set of ops but just create dynamically the ops at init time. Signed-off-by: Daniel Lezcano Reviewed-by: Srinivas Pandruvada Link: https://lore.kernel.org/r/20221003092602.1323944-29-daniel.lezcano@linaro.org --- .../intel/int340x_thermal/int340x_thermal_zone.c | 33 ++++++++++------------ .../intel/int340x_thermal/int340x_thermal_zone.h | 4 +-- .../int340x_thermal/processor_thermal_device.c | 10 ++----- 3 files changed, 20 insertions(+), 27 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c index 62c0aa5d0783..228f44260b27 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -18,9 +18,6 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, unsigned long long tmp; acpi_status status; - if (d->override_ops && d->override_ops->get_temp) - return d->override_ops->get_temp(zone, temp); - status = acpi_evaluate_integer(d->adev->handle, "_TMP", NULL, &tmp); if (ACPI_FAILURE(status)) return -EIO; @@ -46,9 +43,6 @@ static int int340x_thermal_get_trip_temp(struct thermal_zone_device *zone, struct int34x_thermal_zone *d = zone->devdata; int i; - if (d->override_ops && d->override_ops->get_trip_temp) - return d->override_ops->get_trip_temp(zone, trip, temp); - if (trip < d->aux_trip_nr) *temp = d->aux_trips[trip]; else if (trip == d->crt_trip_id) @@ -79,9 +73,6 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone, struct int34x_thermal_zone *d = zone->devdata; int i; - if (d->override_ops && d->override_ops->get_trip_type) - return d->override_ops->get_trip_type(zone, trip, type); - if (trip < d->aux_trip_nr) *type = THERMAL_TRIP_PASSIVE; else if (trip == d->crt_trip_id) @@ -112,9 +103,6 @@ static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, acpi_status status; char name[10]; - if (d->override_ops && d->override_ops->set_trip_temp) - return d->override_ops->set_trip_temp(zone, trip, temp); - snprintf(name, sizeof(name), "PAT%d", trip); status = acpi_execute_simple_method(d->adev->handle, name, millicelsius_to_deci_kelvin(temp)); @@ -134,9 +122,6 @@ static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone, acpi_status status; unsigned long long hyst; - if (d->override_ops && d->override_ops->get_trip_hyst) - return d->override_ops->get_trip_hyst(zone, trip, temp); - status = acpi_evaluate_integer(d->adev->handle, "GTSH", NULL, &hyst); if (ACPI_FAILURE(status)) *temp = 0; @@ -217,7 +202,7 @@ static struct thermal_zone_params int340x_thermal_params = { }; struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, - struct thermal_zone_device_ops *override_ops) + int (*get_temp) (struct thermal_zone_device *, int *)) { struct int34x_thermal_zone *int34x_thermal_zone; acpi_status status; @@ -231,7 +216,16 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, return ERR_PTR(-ENOMEM); int34x_thermal_zone->adev = adev; - int34x_thermal_zone->override_ops = override_ops; + + int34x_thermal_zone->ops = kmemdup(&int340x_thermal_zone_ops, + sizeof(int340x_thermal_zone_ops), GFP_KERNEL); + if (!int34x_thermal_zone->ops) { + ret = -ENOMEM; + goto err_ops_alloc; + } + + if (get_temp) + int34x_thermal_zone->ops->get_temp = get_temp; status = acpi_evaluate_integer(adev->handle, "PATC", NULL, &trip_cnt); if (ACPI_FAILURE(status)) @@ -262,7 +256,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, acpi_device_bid(adev), trip_cnt, trip_mask, int34x_thermal_zone, - &int340x_thermal_zone_ops, + int34x_thermal_zone->ops, &int340x_thermal_params, 0, 0); if (IS_ERR(int34x_thermal_zone->zone)) { @@ -281,6 +275,8 @@ err_thermal_zone: acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); kfree(int34x_thermal_zone->aux_trips); err_trip_alloc: + kfree(int34x_thermal_zone->ops); +err_ops_alloc: kfree(int34x_thermal_zone); return ERR_PTR(ret); } @@ -292,6 +288,7 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone thermal_zone_device_unregister(int34x_thermal_zone->zone); acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); kfree(int34x_thermal_zone->aux_trips); + kfree(int34x_thermal_zone->ops); kfree(int34x_thermal_zone); } EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove); diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h index 3b4971df1b33..e28ab1ba5e06 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h @@ -29,13 +29,13 @@ struct int34x_thermal_zone { int hot_temp; int hot_trip_id; struct thermal_zone_device *zone; - struct thermal_zone_device_ops *override_ops; + struct thermal_zone_device_ops *ops; void *priv_data; struct acpi_lpat_conversion_table *lpat_table; }; struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *, - struct thermal_zone_device_ops *override_ops); + int (*get_temp) (struct thermal_zone_device *, int *)); void int340x_thermal_zone_remove(struct int34x_thermal_zone *); int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c index a8d98f1bd6c6..317703027ce9 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -207,10 +207,6 @@ static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, return ret; } -static struct thermal_zone_device_ops proc_thermal_local_ops = { - .get_temp = proc_thermal_get_zone_temp, -}; - static int proc_thermal_read_ppcc(struct proc_thermal_device *proc_priv) { int i; @@ -285,7 +281,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) struct acpi_device *adev; acpi_status status; unsigned long long tmp; - struct thermal_zone_device_ops *ops = NULL; + int (*get_temp) (struct thermal_zone_device *, int *) = NULL; int ret; adev = ACPI_COMPANION(dev); @@ -304,10 +300,10 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) /* there is no _TMP method, add local method */ stored_tjmax = get_tjmax(); if (stored_tjmax > 0) - ops = &proc_thermal_local_ops; + get_temp = proc_thermal_get_zone_temp; } - proc_priv->int340x_zone = int340x_thermal_zone_add(adev, ops); + proc_priv->int340x_zone = int340x_thermal_zone_add(adev, get_temp); if (IS_ERR(proc_priv->int340x_zone)) { return PTR_ERR(proc_priv->int340x_zone); } else -- cgit v1.2.3 From d3ecaf17b58607c240392e810a743fbb9e1e8262 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 11:26:02 +0200 Subject: thermal/drivers/intel: Use generic thermal_zone_get_trip() function The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed. Convert ops content logic into generic trip points and register them with the thermal zone. Signed-off-by: Daniel Lezcano Reviewed-by: Srinivas Pandruvada Link: https://lore.kernel.org/r/20221003092602.1323944-30-daniel.lezcano@linaro.org --- drivers/thermal/intel/x86_pkg_temp_thermal.c | 120 +++++++++++++++------------ 1 file changed, 67 insertions(+), 53 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index 84c3a116ed04..494f25250c2d 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -53,6 +53,7 @@ struct zone_device { u32 msr_pkg_therm_high; struct delayed_work work; struct thermal_zone_device *tzone; + struct thermal_trip *trips; struct cpumask cpumask; }; @@ -138,40 +139,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) return -EINVAL; } -static int sys_get_trip_temp(struct thermal_zone_device *tzd, - int trip, int *temp) -{ - struct zone_device *zonedev = tzd->devdata; - unsigned long thres_reg_value; - u32 mask, shift, eax, edx; - int ret; - - if (trip >= MAX_NUMBER_OF_TRIPS) - return -EINVAL; - - if (trip) { - mask = THERM_MASK_THRESHOLD1; - shift = THERM_SHIFT_THRESHOLD1; - } else { - mask = THERM_MASK_THRESHOLD0; - shift = THERM_SHIFT_THRESHOLD0; - } - - ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, - &eax, &edx); - if (ret < 0) - return ret; - - thres_reg_value = (eax & mask) >> shift; - if (thres_reg_value) - *temp = zonedev->tj_max - thres_reg_value * 1000; - else - *temp = THERMAL_TEMP_INVALID; - pr_debug("sys_get_trip_temp %d\n", *temp); - - return 0; -} - static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) { @@ -212,18 +179,9 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) l, h); } -static int sys_get_trip_type(struct thermal_zone_device *thermal, int trip, - enum thermal_trip_type *type) -{ - *type = THERMAL_TRIP_PASSIVE; - return 0; -} - /* Thermal zone callback registry */ static struct thermal_zone_device_ops tzone_ops = { .get_temp = sys_get_curr_temp, - .get_trip_temp = sys_get_trip_temp, - .get_trip_type = sys_get_trip_type, .set_trip_temp = sys_set_trip_temp, }; @@ -323,6 +281,48 @@ static int pkg_thermal_notify(u64 msr_val) return 0; } +static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int num_trips) +{ + struct thermal_trip *trips; + unsigned long thres_reg_value; + u32 mask, shift, eax, edx; + int ret, i; + + trips = kzalloc(sizeof(*trips) * num_trips, GFP_KERNEL); + if (!trips) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < num_trips; i++) { + + if (i) { + mask = THERM_MASK_THRESHOLD1; + shift = THERM_SHIFT_THRESHOLD1; + } else { + mask = THERM_MASK_THRESHOLD0; + shift = THERM_SHIFT_THRESHOLD0; + } + + ret = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, + &eax, &edx); + if (ret < 0) { + kfree(trips); + return ERR_PTR(ret); + } + + thres_reg_value = (eax & mask) >> shift; + + trips[i].temperature = thres_reg_value ? + tj_max - thres_reg_value * 1000 : THERMAL_TEMP_INVALID; + + trips[i].type = THERMAL_TRIP_PASSIVE; + + pr_debug("%s: cpu=%d, trip=%d, temp=%d\n", + __func__, cpu, i, trips[i].temperature); + } + + return trips; +} + static int pkg_temp_thermal_device_add(unsigned int cpu) { int id = topology_logical_die_id(cpu); @@ -348,24 +348,27 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) if (!zonedev) return -ENOMEM; + zonedev->trips = pkg_temp_thermal_trips_init(cpu, tj_max, thres_count); + if (IS_ERR(zonedev->trips)) { + err = PTR_ERR(zonedev->trips); + goto out_kfree_zonedev; + } + INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn); zonedev->cpu = cpu; zonedev->tj_max = tj_max; - zonedev->tzone = thermal_zone_device_register("x86_pkg_temp", - thres_count, + zonedev->tzone = thermal_zone_device_register_with_trips("x86_pkg_temp", + zonedev->trips, thres_count, (thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01, zonedev, &tzone_ops, &pkg_temp_tz_params, 0, 0); if (IS_ERR(zonedev->tzone)) { err = PTR_ERR(zonedev->tzone); - kfree(zonedev); - return err; + goto out_kfree_trips; } err = thermal_zone_device_enable(zonedev->tzone); - if (err) { - thermal_zone_device_unregister(zonedev->tzone); - kfree(zonedev); - return err; - } + if (err) + goto out_unregister_tz; + /* Store MSR value for package thermal interrupt, to restore at exit */ rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low, zonedev->msr_pkg_therm_high); @@ -374,7 +377,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) raw_spin_lock_irq(&pkg_temp_lock); zones[id] = zonedev; raw_spin_unlock_irq(&pkg_temp_lock); + return 0; + +out_unregister_tz: + thermal_zone_device_unregister(zonedev->tzone); +out_kfree_trips: + kfree(zonedev->trips); +out_kfree_zonedev: + kfree(zonedev); + return err; } static int pkg_thermal_cpu_offline(unsigned int cpu) @@ -458,8 +470,10 @@ static int pkg_thermal_cpu_offline(unsigned int cpu) raw_spin_unlock_irq(&pkg_temp_lock); /* Final cleanup if this is the last cpu */ - if (lastcpu) + if (lastcpu) { + kfree(zonedev->trips); kfree(zonedev); + } return 0; } -- cgit v1.2.3 From a1c306375b0638f37996bbda1e3a75c6f108a097 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Oct 2022 15:29:43 +0200 Subject: thermal/drivers/exynos: Fix NULL pointer dereference when getting the critical temp The driver is assuming the get_critical temperature exists as it is inherited by the thermal of ops. But this one has been removed in favor of the generic one. Use the generic thermal_zone_get_crit_temp() function instead Fixes: 13bea86623be ("thermal/of: Remove of_thermal_get_crit_temp(") Reported-by: Marek Szyprowski Reviewed-by: Krzysztof Kozlowski Tested-by: Marek Szyprowski Signed-off-by: Daniel Lezcano --- drivers/thermal/samsung/exynos_tmu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 5a1ffe2f3134..37465af59262 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -264,9 +264,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev) unsigned int status; int ret = 0, temp; - if (data->soc != SOC_ARCH_EXYNOS5433) /* FIXME */ - ret = tzd->ops->get_crit_temp(tzd, &temp); - if (ret) { + ret = thermal_zone_get_crit_temp(tzd, &temp); + if (ret && data->soc != SOC_ARCH_EXYNOS5433) { /* FIXME */ dev_err(&pdev->dev, "No CRITICAL trip point defined in device tree!\n"); goto out; -- cgit v1.2.3 From 5f28ecc1e909b2c3ab6ba4e9ba57c0f8dc66c30f Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Mon, 10 Oct 2022 16:03:11 +0100 Subject: thermal/drivers/tegra: Fix crash when getting critical temp Commit 13bea86623be ("thermal/of: Remove of_thermal_get_crit_temp()") removed the function of_thermal_get_crit_temp() and this is causing a NULL pointer deference crash when attempting to call the 'get_crit_temp' function pointer because this function pointer is no longer initialised. Fix this by replacing the call to the 'get_crit_temp' function pointer with a call to the function thermal_zone_get_crit_temp() instead. Fixes: 13bea86623be ("thermal/of: Remove of_thermal_get_crit_temp()") Signed-off-by: Jon Hunter Link: https://lore.kernel.org/r/20221010150311.40384-1-jonathanh@nvidia.com Signed-off-by: Daniel Lezcano --- drivers/thermal/tegra/soctherm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index d2e454902689..4203e74e2f79 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -742,7 +742,7 @@ static int tegra_soctherm_set_hwtrips(struct device *dev, /* Get thermtrips. If missing, try to get critical trips. */ temperature = tsensor_group_thermtrip_get(ts, sg->id); if (min_low_temp == temperature) - if (tz->ops->get_crit_temp(tz, &temperature)) + if (thermal_zone_get_crit_temp(tz, &temperature)) temperature = max_high_temp; ret = thermtrip_program(dev, sg, temperature); -- cgit v1.2.3 From e6ec64f85237b48c071158617cfc954a30285fc7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 14 Dec 2022 14:16:14 +0100 Subject: thermal/drivers/qcom: Fix set_trip_temp() deadlock The set_trip_temp() callback is used when changing the trip temperature through sysfs. As it is called with the thermal-zone-device lock held it must not use thermal_zone_get_trip() directly or it will deadlock. Fixes: 78c3e2429be8 ("thermal/drivers/qcom: Use generic thermal_zone_get_trip() function") Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20221214131617.2447-2-johan+linaro@kernel.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 2 +- drivers/thermal/thermal_core.c | 1 + include/linux/thermal.h | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index 58055a7abaf6..bfaec74f13b2 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -270,7 +270,7 @@ static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip_id, in struct thermal_trip trip; int ret; - ret = thermal_zone_get_trip(chip->tz_dev, trip_id, &trip); + ret = __thermal_zone_get_trip(chip->tz_dev, trip_id, &trip); if (ret) return ret; diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index c24c9efcd175..d9a3d9566d73 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1214,6 +1214,7 @@ int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, return tz->ops->get_trip_type(tz, trip_id, &trip->type); } +EXPORT_SYMBOL_GPL(__thermal_zone_get_trip); int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip) diff --git a/include/linux/thermal.h b/include/linux/thermal.h index e2797f314d99..30353e4b1424 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -334,6 +334,8 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev, } #endif +int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, + struct thermal_trip *trip); int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip); -- cgit v1.2.3 From b0b5d063d66e85c24c32bf169fe4879bf08ea580 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 14 Dec 2022 14:16:16 +0100 Subject: thermal/drivers/tegra: Fix set_trip_temp() deadlock The set_trip_temp() callback is used when changing the trip temperature through sysfs. As it is called with the thermal-zone-device lock held it must not use thermal_zone_get_trip() directly or it will deadlock. Fixes: 56d7b397cc29 ("thermal/drivers/tegra: Use generic thermal_zone_get_trip() function") Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20221214131617.2447-4-johan+linaro@kernel.org Signed-off-by: Daniel Lezcano --- drivers/thermal/tegra/soctherm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 4203e74e2f79..220873298d77 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -594,7 +594,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip if (!tz) return -EINVAL; - ret = thermal_zone_get_trip(tz, trip_id, &trip); + ret = __thermal_zone_get_trip(tz, trip_id, &trip); if (ret) return ret; -- cgit v1.2.3 From 59edcd91d852f88ef7d208029503f9b5310d0603 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 14 Dec 2022 14:16:17 +0100 Subject: thermal/drivers/qcom: Fix lock inversion The thermal-zone-device lock is held by core when setting trip points and the driver takes its chip lock in the corresponding callback. Fetching the thermal trip points using thermal_zone_get_trip() also involves taking the thermal-zone-device lock, which means that the chip lock can not be held when doing so. Drop the chip lock temporarily during probe to avoid the lock inversion that was detected by lockdep: ====================================================== WARNING: possible circular locking dependency detected 6.1.0-next-20221213 #122 Not tainted ------------------------------------------------------ systemd-udevd/264 is trying to acquire lock: ffff741e444a0920 (&chip->lock){+.+.}-{3:3}, at: qpnp_tm_get_temp+0xb4/0x1b0 [qcom_spmi_temp_alarm] but task is already holding lock: ffff741e44341618 (&tz->lock){+.+.}-{3:3}, at: thermal_zone_device_update+0x2c/0x70 which lock already depends on the new lock. Fixes: 78c3e2429be8 ("thermal/drivers/qcom: Use generic thermal_zone_get_trip() function") Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20221214131617.2447-5-johan+linaro@kernel.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index bfaec74f13b2..e2429676d0d2 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -348,7 +348,12 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) if (stage) chip->temp = qpnp_tm_decode_temp(chip, stage); + mutex_unlock(&chip->lock); + crit_temp = qpnp_tm_get_critical_trip_temp(chip); + + mutex_lock(&chip->lock); + ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); if (ret < 0) goto out; -- cgit v1.2.3 From 3a151494dc04c76add577ae66e8a04f900638aaf Mon Sep 17 00:00:00 2001 From: Xu Panda Date: Wed, 28 Dec 2022 09:45:49 +0800 Subject: thermal/drivers/armada: Use strscpy() to instead of strncpy() The implementation of strscpy() is more robust and safer. That's now the recommended way to copy NUL-terminated strings. Signed-off-by: Xu Panda Signed-off-by: Yang Yang Link: https://lore.kernel.org/r/202212280945491860150@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/armada_thermal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index b28695a55eea..db040dbdaa0a 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -761,8 +761,7 @@ static void armada_set_sane_name(struct platform_device *pdev, } /* Save the name locally */ - strncpy(priv->zone_name, name, THERMAL_NAME_LENGTH - 1); - priv->zone_name[THERMAL_NAME_LENGTH - 1] = '\0'; + strscpy(priv->zone_name, name, THERMAL_NAME_LENGTH); /* Then check there are no '-' or hwmon core will complain */ do { -- cgit v1.2.3 From 3291651c0ac6bfc7b7333e5bee70470d5f192d5c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 12 Jan 2023 22:44:49 -0800 Subject: thermal/drivers/mtk_thermal: Fix kernel-doc function name Use the correct function name in a kernel-doc comment to prevent a warning: drivers/thermal/mtk_thermal.c:562: warning: expecting prototype for raw_to_mcelsius(). Prototype was for raw_to_mcelsius_v1() instead Signed-off-by: Randy Dunlap Cc: "Rafael J. Wysocki" Cc: Daniel Lezcano Cc: Amit Kucheria Cc: Zhang Rui Cc: Matthias Brugger Cc: linux-pm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-mediatek@lists.infradead.org Link: https://lore.kernel.org/r/20230113064449.15061-1-rdunlap@infradead.org Signed-off-by: Daniel Lezcano --- drivers/thermal/mtk_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 8440692e3890..0084b76493d9 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -550,7 +550,7 @@ static const struct mtk_thermal_data mt8183_thermal_data = { }; /** - * raw_to_mcelsius - convert a raw ADC value to mcelsius + * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius * @mt: The thermal controller * @sensno: sensor number * @raw: raw ADC value -- cgit v1.2.3 From 6d5dad7b98cf0fa7f79fd5a565df6e6a51daf12b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 12 Jan 2023 22:45:00 -0800 Subject: thermal/drivers/rockchip: Fix kernel-doc warnings Don't use "/**" to begin non-kernel-doc comments. Convert one function description to kernel-doc format. Prevents these kernel-doc warnings: drivers/thermal/rockchip_thermal.c:64: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * The max sensors is two in rockchip SoCs. drivers/thermal/rockchip_thermal.c:179: warning: expecting prototype for TSADC Sensor Register description(). Prototype was for TSADCV2_USER_CON() instead drivers/thermal/rockchip_thermal.c:1342: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Reset TSADC Controller, reset all tsadc registers. Signed-off-by: Randy Dunlap Cc: "Rafael J. Wysocki" Cc: Daniel Lezcano Cc: Amit Kucheria Cc: Zhang Rui Cc: Heiko Stuebner Cc: linux-pm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-rockchip@lists.infradead.org Link: https://lore.kernel.org/r/20230113064500.16103-1-rdunlap@infradead.org Signed-off-by: Daniel Lezcano --- drivers/thermal/rockchip_thermal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 819e059cde71..e567d80a889b 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -60,7 +60,7 @@ enum adc_sort_mode { #include "thermal_hwmon.h" -/** +/* * The max sensors is two in rockchip SoCs. * Two sensors: CPU and GPU sensor. */ @@ -169,7 +169,7 @@ struct rockchip_thermal_data { enum tshut_polarity tshut_polarity; }; -/** +/* * TSADC Sensor Register description: * * TSADCV2_* are used for RK3288 SoCs, the other chips can reuse it. @@ -1339,7 +1339,7 @@ rockchip_thermal_register_sensor(struct platform_device *pdev, } /** - * Reset TSADC Controller, reset all tsadc registers. + * rockchip_thermal_reset_controller - Reset TSADC Controller, reset all tsadc registers. * @reset: the reset controller of tsadc */ static void rockchip_thermal_reset_controller(struct reset_control *reset) -- cgit v1.2.3 From 5bc494a8ce397efba41277463cd38d3866a78090 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 12 Jan 2023 22:45:07 -0800 Subject: thermal/drivers/uniphier: Use regular comment syntax Use "/*" comment for the file's initial comment since it is not in kernel-doc format. This prevents a kernel-doc warning: drivers/thermal/uniphier_thermal.c:26: warning: expecting prototype for uniphier_thermal.c(). Prototype was for PVTCTLEN() instead Signed-off-by: Randy Dunlap Cc: "Rafael J. Wysocki" Cc: Daniel Lezcano Cc: Amit Kucheria Cc: Zhang Rui Cc: Kunihiko Hayashi Cc: Masami Hiramatsu Cc: linux-pm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230113064507.17224-1-rdunlap@infradead.org Signed-off-by: Daniel Lezcano --- drivers/thermal/uniphier_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c index 277ae300c5b1..f8ab2ca76184 100644 --- a/drivers/thermal/uniphier_thermal.c +++ b/drivers/thermal/uniphier_thermal.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/** +/* * uniphier_thermal.c - Socionext UniPhier thermal driver * Copyright 2014 Panasonic Corporation * Copyright 2016-2017 Socionext Inc. -- cgit v1.2.3 From ca7b70b19e84ab58a91c603a0843ec1c3ad6d2db Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:18 +0200 Subject: thermal/drivers/tsens: Drop unnecessary hw_ids The tsens driver defaults to using hw_id equal to the index of the sensor. Thus it is superfluous to declare such hw_id arrays. Drop such arrays from mdm9607 and msm8976 data. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-5-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v0_1.c | 1 - drivers/thermal/qcom/tsens-v1.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 04d012e4f728..0bc4e5cec184 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -635,7 +635,6 @@ static const struct tsens_ops ops_9607 = { struct tsens_plat_data data_9607 = { .num_sensors = 5, .ops = &ops_9607, - .hw_ids = (unsigned int []){ 0, 1, 2, 3, 4 }, .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields, }; diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 1d7f8a80bd13..96ef12d47bff 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -387,7 +387,6 @@ static const struct tsens_ops ops_8976 = { struct tsens_plat_data data_8976 = { .num_sensors = 11, .ops = &ops_8976, - .hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, .feat = &tsens_v1_feat, .fields = tsens_v1_regfields, }; -- cgit v1.2.3 From 3bf0ea99e2e32b0335106b86d84404cc85bcd113 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:19 +0200 Subject: thermal/drivers/tsens: Drop msm8976-specific defines Drop msm8976-specific defines, which duplicate generic ones. Fixes: 0e580290170d ("thermal: qcom: tsens-v1: Add support for MSM8956 and MSM8976") Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-6-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v1.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 96ef12d47bff..a7f53966156b 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -78,11 +78,6 @@ #define MSM8976_CAL_SEL_MASK 0x3 -#define MSM8976_CAL_DEGC_PT1 30 -#define MSM8976_CAL_DEGC_PT2 120 -#define MSM8976_SLOPE_FACTOR 1000 -#define MSM8976_SLOPE_DEFAULT 3200 - /* eeprom layout data for qcs404/405 (v1) */ #define BASE0_MASK 0x000007f8 #define BASE1_MASK 0x0007f800 @@ -160,8 +155,8 @@ static void compute_intercept_slope_8976(struct tsens_priv *priv, priv->sensor[10].slope = 3286; for (i = 0; i < priv->num_sensors; i++) { - priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) - - (MSM8976_CAL_DEGC_PT1 * + priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) - + (CAL_DEGC_PT1 * priv->sensor[i].slope); } } -- cgit v1.2.3 From a7d3006be5ca7b04e4b84b5ceaae55a700e511bd Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:20 +0200 Subject: thermal/drivers/tsens: Sort out msm8976 vs msm8956 data Tsens driver mentions that msm8976 data should be used for both msm8976 and msm8956 SoCs. This is not quite correct, as according to the vendor kernels, msm8976 should use standard slope values (3200), while msm8956 really uses the slope values found in the driver. Add separate compatibility string for msm8956, move slope value overrides to the corresponding init function and use the standard compute_intercept_slope() function for both platforms. Fixes: 0e580290170d ("thermal: qcom: tsens-v1: Add support for MSM8956 and MSM8976") Cc: AngeloGioacchino Del Regno Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-7-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v1.c | 56 ++++++++++++++++++++++------------------- drivers/thermal/qcom/tsens.c | 3 +++ drivers/thermal/qcom/tsens.h | 2 +- 3 files changed, 34 insertions(+), 27 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index a7f53966156b..83c2853546d0 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -137,30 +137,6 @@ #define CAL_SEL_MASK 7 #define CAL_SEL_SHIFT 0 -static void compute_intercept_slope_8976(struct tsens_priv *priv, - u32 *p1, u32 *p2, u32 mode) -{ - int i; - - priv->sensor[0].slope = 3313; - priv->sensor[1].slope = 3275; - priv->sensor[2].slope = 3320; - priv->sensor[3].slope = 3246; - priv->sensor[4].slope = 3279; - priv->sensor[5].slope = 3257; - priv->sensor[6].slope = 3234; - priv->sensor[7].slope = 3269; - priv->sensor[8].slope = 3255; - priv->sensor[9].slope = 3239; - priv->sensor[10].slope = 3286; - - for (i = 0; i < priv->num_sensors; i++) { - priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) - - (CAL_DEGC_PT1 * - priv->sensor[i].slope); - } -} - static int calibrate_v1(struct tsens_priv *priv) { u32 base0 = 0, base1 = 0; @@ -286,7 +262,7 @@ static int calibrate_8976(struct tsens_priv *priv) break; } - compute_intercept_slope_8976(priv, p1, p2, mode); + compute_intercept_slope(priv, p1, p2, mode); kfree(qfprom_cdata); return 0; @@ -360,6 +336,22 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = { [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0), }; +static int __init init_8956(struct tsens_priv *priv) { + priv->sensor[0].slope = 3313; + priv->sensor[1].slope = 3275; + priv->sensor[2].slope = 3320; + priv->sensor[3].slope = 3246; + priv->sensor[4].slope = 3279; + priv->sensor[5].slope = 3257; + priv->sensor[6].slope = 3234; + priv->sensor[7].slope = 3269; + priv->sensor[8].slope = 3255; + priv->sensor[9].slope = 3239; + priv->sensor[10].slope = 3286; + + return init_common(priv); +} + static const struct tsens_ops ops_generic_v1 = { .init = init_common, .calibrate = calibrate_v1, @@ -372,13 +364,25 @@ struct tsens_plat_data data_tsens_v1 = { .fields = tsens_v1_regfields, }; +static const struct tsens_ops ops_8956 = { + .init = init_8956, + .calibrate = calibrate_8976, + .get_temp = get_temp_tsens_valid, +}; + +struct tsens_plat_data data_8956 = { + .num_sensors = 11, + .ops = &ops_8956, + .feat = &tsens_v1_feat, + .fields = tsens_v1_regfields, +}; + static const struct tsens_ops ops_8976 = { .init = init_common, .calibrate = calibrate_8976, .get_temp = get_temp_tsens_valid, }; -/* Valid for both MSM8956 and MSM8976. */ struct tsens_plat_data data_8976 = { .num_sensors = 11, .ops = &ops_8976, diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index b5b136ff323f..b191e19df93d 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -983,6 +983,9 @@ static const struct of_device_id tsens_table[] = { }, { .compatible = "qcom,msm8939-tsens", .data = &data_8939, + }, { + .compatible = "qcom,msm8956-tsens", + .data = &data_8956, }, { .compatible = "qcom,msm8960-tsens", .data = &data_8960, diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index 899af128855f..7dd5fc246894 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -594,7 +594,7 @@ extern struct tsens_plat_data data_8960; extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607; /* TSENS v1 targets */ -extern struct tsens_plat_data data_tsens_v1, data_8976; +extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956; /* TSENS v2 targets */ extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2; -- cgit v1.2.3 From 5aec3b035e0cbf3f042c2a03d654e5ad6748feb7 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:21 +0200 Subject: thermal/drivers/tsens: fix slope values for msm8939 According to the vendor kernels (msm-3.10, 3.14 and 3.18), msm8939 uses non-standard slope values for calibrating the sensors. Fill them accordingly. Fixes: 332bc8ebab2c ("thermal: qcom: tsens-v0_1: Add support for MSM8939") Cc: Bryan O'Donoghue Cc: Shawn Guo Reviewed-by: Konrad Dybcio Acked-by: Shawn Guo Signed-off-by: Dmitry Baryshkov Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20230101194034.831222-8-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v0_1.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 0bc4e5cec184..6645c98ff56c 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -534,6 +534,21 @@ static int calibrate_9607(struct tsens_priv *priv) return 0; } +static int __init init_8939(struct tsens_priv *priv) { + priv->sensor[0].slope = 2911; + priv->sensor[1].slope = 2789; + priv->sensor[2].slope = 2906; + priv->sensor[3].slope = 2763; + priv->sensor[4].slope = 2922; + priv->sensor[5].slope = 2867; + priv->sensor[6].slope = 2833; + priv->sensor[7].slope = 2838; + priv->sensor[8].slope = 2840; + priv->sensor[9].slope = 2852; + + return init_common(priv); +} + /* v0.1: 8916, 8939, 8974, 9607 */ static struct tsens_features tsens_v0_1_feat = { @@ -599,7 +614,7 @@ struct tsens_plat_data data_8916 = { }; static const struct tsens_ops ops_8939 = { - .init = init_common, + .init = init_8939, .calibrate = calibrate_8939, .get_temp = get_temp_common, }; -- cgit v1.2.3 From 903238a33c116edf5f64f7a3fd246e6169cccfa6 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:22 +0200 Subject: thermal/drivers/tsens: limit num_sensors to 9 for msm8939 On msm8939 last (hwid=10) sensor was added in the hw revision 3.0. Calibration data for it was placed outside of the main calibration data blob, so it is not accessible by the current blob-parsing code. Moreover data for the sensor's p2 is not contiguous in the fuses. This makes it hard to use nvmem_cell API to parse calibration data in a generic way. Since the sensor doesn't seem to be actually used by the existing hardware, disable the sensor for now. Fixes: 332bc8ebab2c ("thermal: qcom: tsens-v0_1: Add support for MSM8939") Cc: Bryan O'Donoghue Cc: Shawn Guo Acked-by: Shawn Guo Signed-off-by: Dmitry Baryshkov Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20230101194034.831222-9-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v0_1.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 6645c98ff56c..579028ea48f4 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -285,7 +285,7 @@ static int calibrate_8939(struct tsens_priv *priv) u32 p1[10], p2[10]; int mode = 0; u32 *qfprom_cdata; - u32 cdata[6]; + u32 cdata[4]; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) @@ -296,8 +296,6 @@ static int calibrate_8939(struct tsens_priv *priv) cdata[1] = qfprom_cdata[13]; cdata[2] = qfprom_cdata[0]; cdata[3] = qfprom_cdata[1]; - cdata[4] = qfprom_cdata[22]; - cdata[5] = qfprom_cdata[21]; mode = (cdata[0] & MSM8939_CAL_SEL_MASK) >> MSM8939_CAL_SEL_SHIFT; dev_dbg(priv->dev, "calibration mode is %d\n", mode); @@ -314,8 +312,6 @@ static int calibrate_8939(struct tsens_priv *priv) p2[6] = (cdata[2] & MSM8939_S6_P2_MASK) >> MSM8939_S6_P2_SHIFT; p2[7] = (cdata[3] & MSM8939_S7_P2_MASK) >> MSM8939_S7_P2_SHIFT; p2[8] = (cdata[3] & MSM8939_S8_P2_MASK) >> MSM8939_S8_P2_SHIFT; - p2[9] = (cdata[4] & MSM8939_S9_P2_MASK_0_4) >> MSM8939_S9_P2_SHIFT_0_4; - p2[9] |= ((cdata[5] & MSM8939_S9_P2_MASK_5) >> MSM8939_S9_P2_SHIFT_5) << 5; for (i = 0; i < priv->num_sensors; i++) p2[i] = (base1 + p2[i]) << 2; fallthrough; @@ -331,7 +327,6 @@ static int calibrate_8939(struct tsens_priv *priv) p1[6] = (cdata[2] & MSM8939_S6_P1_MASK) >> MSM8939_S6_P1_SHIFT; p1[7] = (cdata[3] & MSM8939_S7_P1_MASK) >> MSM8939_S7_P1_SHIFT; p1[8] = (cdata[3] & MSM8939_S8_P1_MASK) >> MSM8939_S8_P1_SHIFT; - p1[9] = (cdata[4] & MSM8939_S9_P1_MASK) >> MSM8939_S9_P1_SHIFT; for (i = 0; i < priv->num_sensors; i++) p1[i] = ((base0) + p1[i]) << 2; break; @@ -544,7 +539,7 @@ static int __init init_8939(struct tsens_priv *priv) { priv->sensor[6].slope = 2833; priv->sensor[7].slope = 2838; priv->sensor[8].slope = 2840; - priv->sensor[9].slope = 2852; + /* priv->sensor[9].slope = 2852; */ return init_common(priv); } @@ -620,9 +615,9 @@ static const struct tsens_ops ops_8939 = { }; struct tsens_plat_data data_8939 = { - .num_sensors = 10, + .num_sensors = 9, .ops = &ops_8939, - .hw_ids = (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10 }, + .hw_ids = (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, /* 10 */ }, .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields, -- cgit v1.2.3 From 498d245749ce35b21121cf5297547fca64bc52db Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:23 +0200 Subject: thermal/drivers/tsens: Support using nvmem cells for calibration data Add a unified function using nvmem cells for parsing the calibration data rather than parsing the calibration blob manually. Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-10-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v0_1.c | 15 ++++++++ drivers/thermal/qcom/tsens-v1.c | 11 +++++- drivers/thermal/qcom/tsens.c | 76 +++++++++++++++++++++++++++++++++++++++ drivers/thermal/qcom/tsens.h | 5 +++ 4 files changed, 106 insertions(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 579028ea48f4..6c9e491f9559 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -229,6 +229,11 @@ static int calibrate_8916(struct tsens_priv *priv) u32 p1[5], p2[5]; int mode = 0; u32 *qfprom_cdata, *qfprom_csel; + int ret; + + ret = tsens_calibrate_nvmem(priv, 3); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) @@ -286,6 +291,11 @@ static int calibrate_8939(struct tsens_priv *priv) int mode = 0; u32 *qfprom_cdata; u32 cdata[4]; + int ret; + + ret = tsens_calibrate_common(priv); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) @@ -486,6 +496,11 @@ static int calibrate_9607(struct tsens_priv *priv) u32 p1[5], p2[5]; int mode = 0; u32 *qfprom_cdata; + int ret; + + ret = tsens_calibrate_common(priv); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 83c2853546d0..5bba75a845c5 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -143,7 +143,11 @@ static int calibrate_v1(struct tsens_priv *priv) u32 p1[10], p2[10]; u32 mode = 0, lsb = 0, msb = 0; u32 *qfprom_cdata; - int i; + int i, ret; + + ret = tsens_calibrate_common(priv); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) @@ -209,6 +213,11 @@ static int calibrate_8976(struct tsens_priv *priv) u32 p1[11], p2[11]; int mode = 0, tmp = 0; u32 *qfprom_cdata; + int ret; + + ret = tsens_calibrate_common(priv); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index b191e19df93d..ce568a68de4a 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -70,6 +70,82 @@ char *qfprom_read(struct device *dev, const char *cname) return ret; } +int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) +{ + u32 mode; + u32 base1, base2; + u32 p1[MAX_SENSORS], p2[MAX_SENSORS]; + char name[] = "sXX_pY"; /* s10_p1 */ + int i, ret; + + if (priv->num_sensors > MAX_SENSORS) + return -EINVAL; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, "mode", &mode); + if (ret == -ENOENT) + dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n"); + if (ret < 0) + return ret; + + dev_dbg(priv->dev, "calibration mode is %d\n", mode); + + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base1", &base1); + if (ret < 0) + return ret; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base2", &base2); + if (ret < 0) + return ret; + + for (i = 0; i < priv->num_sensors; i++) { + ret = snprintf(name, sizeof(name), "s%d_p1", priv->sensor[i].hw_id); + if (ret < 0) + return ret; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p1[i]); + if (ret) + return ret; + + ret = snprintf(name, sizeof(name), "s%d_p2", priv->sensor[i].hw_id); + if (ret < 0) + return ret; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p2[i]); + if (ret) + return ret; + } + + switch (mode) { + case ONE_PT_CALIB: + for (i = 0; i < priv->num_sensors; i++) + p1[i] = p1[i] + (base1 << shift); + break; + case TWO_PT_CALIB: + for (i = 0; i < priv->num_sensors; i++) + p2[i] = (p2[i] + base2) << shift; + fallthrough; + case ONE_PT_CALIB2: + for (i = 0; i < priv->num_sensors; i++) + p1[i] = (p1[i] + base1) << shift; + break; + default: + dev_dbg(priv->dev, "calibrationless mode\n"); + for (i = 0; i < priv->num_sensors; i++) { + p1[i] = 500; + p2[i] = 780; + } + } + + compute_intercept_slope(priv, p1, p2, mode); + + return 0; +} + +int tsens_calibrate_common(struct tsens_priv *priv) +{ + return tsens_calibrate_nvmem(priv, 2); +} + /* * Use this function on devices where slope and offset calculations * depend on calibration data read from qfprom. On others the slope diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index 7dd5fc246894..645ae02438fa 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -6,6 +6,7 @@ #ifndef __QCOM_TSENS_H__ #define __QCOM_TSENS_H__ +#define NO_PT_CALIB 0x0 #define ONE_PT_CALIB 0x1 #define ONE_PT_CALIB2 0x2 #define TWO_PT_CALIB 0x3 @@ -17,6 +18,8 @@ #define THRESHOLD_MAX_ADC_CODE 0x3ff #define THRESHOLD_MIN_ADC_CODE 0x0 +#define MAX_SENSORS 16 + #include #include #include @@ -582,6 +585,8 @@ struct tsens_priv { }; char *qfprom_read(struct device *dev, const char *cname); +int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift); +int tsens_calibrate_common(struct tsens_priv *priv); void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode); int init_common(struct tsens_priv *priv); int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp); -- cgit v1.2.3 From 439f2409a242549b614decfccbbacecad85d2c79 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:24 +0200 Subject: thermal/drivers/tsens: Support using nvmem cells for msm8974 calibration MSM8974 has two sets of calibration data: main one and backup. Add support for parsing both sets of calibration data from nvmem cells. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-11-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v0_1.c | 50 +++++++++++++++++++++++++++++++++++++++ drivers/thermal/qcom/tsens.c | 41 +++++++++++++++++++++++++------- drivers/thermal/qcom/tsens.h | 1 + 3 files changed, 84 insertions(+), 8 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 6c9e491f9559..3c08ad640940 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -3,6 +3,7 @@ * Copyright (c) 2015, The Linux Foundation. All rights reserved. */ +#include #include #include "tsens.h" @@ -354,6 +355,50 @@ static int calibrate_8939(struct tsens_priv *priv) return 0; } +static int calibrate_8974_nvmem(struct tsens_priv *priv) +{ + int i, ret, mode; + u32 p1[11], p2[11]; + u32 backup; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, "use_backup", &backup); + if (ret == -ENOENT) + dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n"); + if (ret < 0) + return ret; + + mode = tsens_read_calibration(priv, 2, p1, p2, backup == BKP_SEL); + if (mode < 0) + return mode; + + if (mode == NO_PT_CALIB) { + p1[0] += 2; + p1[1] += 9; + p1[2] += 3; + p1[3] += 9; + p1[4] += 5; + p1[5] += 9; + p1[6] += 7; + p1[7] += 10; + p1[8] += 8; + p1[9] += 9; + p1[10] += 8; + } else { + for (i = 0; i < priv->num_sensors; i++) { + /* + * ONE_PT_CALIB requires using addition here instead of + * using OR operation. + */ + p1[i] += BIT_APPEND; + p2[i] += BIT_APPEND; + } + } + + compute_intercept_slope(priv, p1, p2, mode); + + return 0; +} + static int calibrate_8974(struct tsens_priv *priv) { int base1 = 0, base2 = 0, i; @@ -361,6 +406,11 @@ static int calibrate_8974(struct tsens_priv *priv) int mode = 0; u32 *calib, *bkp; u32 calib_redun_sel; + int ret; + + ret = calibrate_8974_nvmem(priv); + if (ret == 0) + return 0; calib = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(calib)) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index ce568a68de4a..6facdb0246a5 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -70,18 +70,21 @@ char *qfprom_read(struct device *dev, const char *cname) return ret; } -int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) +int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup) { u32 mode; u32 base1, base2; - u32 p1[MAX_SENSORS], p2[MAX_SENSORS]; - char name[] = "sXX_pY"; /* s10_p1 */ + char name[] = "sXX_pY_backup"; /* s10_p1_backup */ int i, ret; if (priv->num_sensors > MAX_SENSORS) return -EINVAL; - ret = nvmem_cell_read_variable_le_u32(priv->dev, "mode", &mode); + ret = snprintf(name, sizeof(name), "mode%s", backup ? "_backup" : ""); + if (ret < 0) + return ret; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &mode); if (ret == -ENOENT) dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n"); if (ret < 0) @@ -89,16 +92,25 @@ int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) dev_dbg(priv->dev, "calibration mode is %d\n", mode); - ret = nvmem_cell_read_variable_le_u32(priv->dev, "base1", &base1); + ret = snprintf(name, sizeof(name), "base1%s", backup ? "_backup" : ""); + if (ret < 0) + return ret; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base1); + if (ret < 0) + return ret; + + ret = snprintf(name, sizeof(name), "base2%s", backup ? "_backup" : ""); if (ret < 0) return ret; - ret = nvmem_cell_read_variable_le_u32(priv->dev, "base2", &base2); + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base2); if (ret < 0) return ret; for (i = 0; i < priv->num_sensors; i++) { - ret = snprintf(name, sizeof(name), "s%d_p1", priv->sensor[i].hw_id); + ret = snprintf(name, sizeof(name), "s%d_p1%s", priv->sensor[i].hw_id, + backup ? "_backup" : ""); if (ret < 0) return ret; @@ -106,7 +118,8 @@ int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) if (ret) return ret; - ret = snprintf(name, sizeof(name), "s%d_p2", priv->sensor[i].hw_id); + ret = snprintf(name, sizeof(name), "s%d_p2%s", priv->sensor[i].hw_id, + backup ? "_backup" : ""); if (ret < 0) return ret; @@ -136,6 +149,18 @@ int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) } } + return mode; +} + +int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) +{ + u32 p1[MAX_SENSORS], p2[MAX_SENSORS]; + int mode; + + mode = tsens_read_calibration(priv, shift, p1, p2, false); + if (mode < 0) + return mode; + compute_intercept_slope(priv, p1, p2, mode); return 0; diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index 645ae02438fa..a9ae8df9f810 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -585,6 +585,7 @@ struct tsens_priv { }; char *qfprom_read(struct device *dev, const char *cname); +int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup); int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift); int tsens_calibrate_common(struct tsens_priv *priv); void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode); -- cgit v1.2.3 From 913d32e2786c183f5b38e7f1ffb67e9120afbf83 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:25 +0200 Subject: thermal/drivers/tsens: Rework legacy calibration data parsers Rework existing calibration parsing code to use simple data structure describing data layout. This allows us to drop all the mask & shift values, replacing them with data tables. The code for msm8974 is not reworked, as it has separate calibration and backup data. Reported-by: kernel test robot Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-12-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v0_1.c | 591 ++++++++++---------------------------- drivers/thermal/qcom/tsens-v1.c | 266 ++++------------- drivers/thermal/qcom/tsens.c | 64 +++++ drivers/thermal/qcom/tsens.h | 38 +++ 4 files changed, 297 insertions(+), 662 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 3c08ad640940..f8b50bf14190 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -3,6 +3,7 @@ * Copyright (c) 2015, The Linux Foundation. All rights reserved. */ +#include #include #include #include "tsens.h" @@ -16,221 +17,113 @@ #define TM_Sn_STATUS_OFF 0x0030 #define TM_TRDY_OFF 0x005c -/* eeprom layout data for 8916 */ -#define MSM8916_BASE0_MASK 0x0000007f -#define MSM8916_BASE1_MASK 0xfe000000 -#define MSM8916_BASE0_SHIFT 0 -#define MSM8916_BASE1_SHIFT 25 - -#define MSM8916_S0_P1_MASK 0x00000f80 -#define MSM8916_S1_P1_MASK 0x003e0000 -#define MSM8916_S2_P1_MASK 0xf8000000 -#define MSM8916_S3_P1_MASK 0x000003e0 -#define MSM8916_S4_P1_MASK 0x000f8000 - -#define MSM8916_S0_P2_MASK 0x0001f000 -#define MSM8916_S1_P2_MASK 0x07c00000 -#define MSM8916_S2_P2_MASK 0x0000001f -#define MSM8916_S3_P2_MASK 0x00007c00 -#define MSM8916_S4_P2_MASK 0x01f00000 - -#define MSM8916_S0_P1_SHIFT 7 -#define MSM8916_S1_P1_SHIFT 17 -#define MSM8916_S2_P1_SHIFT 27 -#define MSM8916_S3_P1_SHIFT 5 -#define MSM8916_S4_P1_SHIFT 15 - -#define MSM8916_S0_P2_SHIFT 12 -#define MSM8916_S1_P2_SHIFT 22 -#define MSM8916_S2_P2_SHIFT 0 -#define MSM8916_S3_P2_SHIFT 10 -#define MSM8916_S4_P2_SHIFT 20 - -#define MSM8916_CAL_SEL_MASK 0xe0000000 -#define MSM8916_CAL_SEL_SHIFT 29 - -/* eeprom layout data for 8939 */ -#define MSM8939_BASE0_MASK 0x000000ff -#define MSM8939_BASE1_MASK 0xff000000 -#define MSM8939_BASE0_SHIFT 0 -#define MSM8939_BASE1_SHIFT 24 - -#define MSM8939_S0_P1_MASK 0x000001f8 -#define MSM8939_S1_P1_MASK 0x001f8000 -#define MSM8939_S2_P1_MASK_0_4 0xf8000000 -#define MSM8939_S2_P1_MASK_5 0x00000001 -#define MSM8939_S3_P1_MASK 0x00001f80 -#define MSM8939_S4_P1_MASK 0x01f80000 -#define MSM8939_S5_P1_MASK 0x00003f00 -#define MSM8939_S6_P1_MASK 0x03f00000 -#define MSM8939_S7_P1_MASK 0x0000003f -#define MSM8939_S8_P1_MASK 0x0003f000 -#define MSM8939_S9_P1_MASK 0x07e00000 - -#define MSM8939_S0_P2_MASK 0x00007e00 -#define MSM8939_S1_P2_MASK 0x07e00000 -#define MSM8939_S2_P2_MASK 0x0000007e -#define MSM8939_S3_P2_MASK 0x0007e000 -#define MSM8939_S4_P2_MASK 0x7e000000 -#define MSM8939_S5_P2_MASK 0x000fc000 -#define MSM8939_S6_P2_MASK 0xfc000000 -#define MSM8939_S7_P2_MASK 0x00000fc0 -#define MSM8939_S8_P2_MASK 0x00fc0000 -#define MSM8939_S9_P2_MASK_0_4 0xf8000000 -#define MSM8939_S9_P2_MASK_5 0x00002000 - -#define MSM8939_S0_P1_SHIFT 3 -#define MSM8939_S1_P1_SHIFT 15 -#define MSM8939_S2_P1_SHIFT_0_4 27 -#define MSM8939_S2_P1_SHIFT_5 0 -#define MSM8939_S3_P1_SHIFT 7 -#define MSM8939_S4_P1_SHIFT 19 -#define MSM8939_S5_P1_SHIFT 8 -#define MSM8939_S6_P1_SHIFT 20 -#define MSM8939_S7_P1_SHIFT 0 -#define MSM8939_S8_P1_SHIFT 12 -#define MSM8939_S9_P1_SHIFT 21 - -#define MSM8939_S0_P2_SHIFT 9 -#define MSM8939_S1_P2_SHIFT 21 -#define MSM8939_S2_P2_SHIFT 1 -#define MSM8939_S3_P2_SHIFT 13 -#define MSM8939_S4_P2_SHIFT 25 -#define MSM8939_S5_P2_SHIFT 14 -#define MSM8939_S6_P2_SHIFT 26 -#define MSM8939_S7_P2_SHIFT 6 -#define MSM8939_S8_P2_SHIFT 18 -#define MSM8939_S9_P2_SHIFT_0_4 27 -#define MSM8939_S9_P2_SHIFT_5 13 - -#define MSM8939_CAL_SEL_MASK 0x7 -#define MSM8939_CAL_SEL_SHIFT 0 - -/* eeprom layout data for 8974 */ -#define BASE1_MASK 0xff -#define S0_P1_MASK 0x3f00 -#define S1_P1_MASK 0xfc000 -#define S2_P1_MASK 0x3f00000 -#define S3_P1_MASK 0xfc000000 -#define S4_P1_MASK 0x3f -#define S5_P1_MASK 0xfc0 -#define S6_P1_MASK 0x3f000 -#define S7_P1_MASK 0xfc0000 -#define S8_P1_MASK 0x3f000000 -#define S8_P1_MASK_BKP 0x3f -#define S9_P1_MASK 0x3f -#define S9_P1_MASK_BKP 0xfc0 -#define S10_P1_MASK 0xfc0 -#define S10_P1_MASK_BKP 0x3f000 -#define CAL_SEL_0_1 0xc0000000 -#define CAL_SEL_2 0x40000000 -#define CAL_SEL_SHIFT 30 -#define CAL_SEL_SHIFT_2 28 - -#define S0_P1_SHIFT 8 -#define S1_P1_SHIFT 14 -#define S2_P1_SHIFT 20 -#define S3_P1_SHIFT 26 -#define S5_P1_SHIFT 6 -#define S6_P1_SHIFT 12 -#define S7_P1_SHIFT 18 -#define S8_P1_SHIFT 24 -#define S9_P1_BKP_SHIFT 6 -#define S10_P1_SHIFT 6 -#define S10_P1_BKP_SHIFT 12 - -#define BASE2_SHIFT 12 -#define BASE2_BKP_SHIFT 18 -#define S0_P2_SHIFT 20 -#define S0_P2_BKP_SHIFT 26 -#define S1_P2_SHIFT 26 -#define S2_P2_BKP_SHIFT 6 -#define S3_P2_SHIFT 6 -#define S3_P2_BKP_SHIFT 12 -#define S4_P2_SHIFT 12 -#define S4_P2_BKP_SHIFT 18 -#define S5_P2_SHIFT 18 -#define S5_P2_BKP_SHIFT 24 -#define S6_P2_SHIFT 24 -#define S7_P2_BKP_SHIFT 6 -#define S8_P2_SHIFT 6 -#define S8_P2_BKP_SHIFT 12 -#define S9_P2_SHIFT 12 -#define S9_P2_BKP_SHIFT 18 -#define S10_P2_SHIFT 18 -#define S10_P2_BKP_SHIFT 24 - -#define BASE2_MASK 0xff000 -#define BASE2_BKP_MASK 0xfc0000 -#define S0_P2_MASK 0x3f00000 -#define S0_P2_BKP_MASK 0xfc000000 -#define S1_P2_MASK 0xfc000000 -#define S1_P2_BKP_MASK 0x3f -#define S2_P2_MASK 0x3f -#define S2_P2_BKP_MASK 0xfc0 -#define S3_P2_MASK 0xfc0 -#define S3_P2_BKP_MASK 0x3f000 -#define S4_P2_MASK 0x3f000 -#define S4_P2_BKP_MASK 0xfc0000 -#define S5_P2_MASK 0xfc0000 -#define S5_P2_BKP_MASK 0x3f000000 -#define S6_P2_MASK 0x3f000000 -#define S6_P2_BKP_MASK 0x3f -#define S7_P2_MASK 0x3f -#define S7_P2_BKP_MASK 0xfc0 -#define S8_P2_MASK 0xfc0 -#define S8_P2_BKP_MASK 0x3f000 -#define S9_P2_MASK 0x3f000 -#define S9_P2_BKP_MASK 0xfc0000 -#define S10_P2_MASK 0xfc0000 -#define S10_P2_BKP_MASK 0x3f000000 - +/* extra data for 8974 */ #define BKP_SEL 0x3 #define BKP_REDUN_SEL 0xe0000000 -#define BKP_REDUN_SHIFT 29 #define BIT_APPEND 0x3 -/* eeprom layout data for mdm9607 */ -#define MDM9607_BASE0_MASK 0x000000ff -#define MDM9607_BASE1_MASK 0x000ff000 -#define MDM9607_BASE0_SHIFT 0 -#define MDM9607_BASE1_SHIFT 12 - -#define MDM9607_S0_P1_MASK 0x00003f00 -#define MDM9607_S1_P1_MASK 0x03f00000 -#define MDM9607_S2_P1_MASK 0x0000003f -#define MDM9607_S3_P1_MASK 0x0003f000 -#define MDM9607_S4_P1_MASK 0x0000003f - -#define MDM9607_S0_P2_MASK 0x000fc000 -#define MDM9607_S1_P2_MASK 0xfc000000 -#define MDM9607_S2_P2_MASK 0x00000fc0 -#define MDM9607_S3_P2_MASK 0x00fc0000 -#define MDM9607_S4_P2_MASK 0x00000fc0 - -#define MDM9607_S0_P1_SHIFT 8 -#define MDM9607_S1_P1_SHIFT 20 -#define MDM9607_S2_P1_SHIFT 0 -#define MDM9607_S3_P1_SHIFT 12 -#define MDM9607_S4_P1_SHIFT 0 - -#define MDM9607_S0_P2_SHIFT 14 -#define MDM9607_S1_P2_SHIFT 26 -#define MDM9607_S2_P2_SHIFT 6 -#define MDM9607_S3_P2_SHIFT 18 -#define MDM9607_S4_P2_SHIFT 6 - -#define MDM9607_CAL_SEL_MASK 0x00700000 -#define MDM9607_CAL_SEL_SHIFT 20 +struct tsens_legacy_calibration_format tsens_8916_nvmem = { + .base_len = 7, + .base_shift = 3, + .sp_len = 5, + .mode = { 0, 29, 1 }, + .invalid = { 0, 31, 1 }, + .base = { { 0, 0 }, { 1, 25 } }, + .sp = { + { { 0, 7 }, { 0, 12 } }, + { { 0, 17 }, { 0, 22 } }, + { { 0, 27 }, { 1, 0 } }, + { { 1, 5 }, { 1, 10 } }, + { { 1, 15 }, { 1, 20 } }, + }, +}; + +struct tsens_legacy_calibration_format tsens_8939_nvmem = { + .base_len = 8, + .base_shift = 2, + .sp_len = 6, + .mode = { 12, 0 }, + .invalid = { 12, 2 }, + .base = { { 0, 0 }, { 1, 24 } }, + .sp = { + { { 12, 3 }, { 12, 9 } }, + { { 12, 15 }, { 12, 21 } }, + { { 12, 27 }, { 13, 1 } }, + { { 13, 7 }, { 13, 13 } }, + { { 13, 19 }, { 13, 25 } }, + { { 0, 8 }, { 0, 14 } }, + { { 0, 20 }, { 0, 26 } }, + { { 1, 0 }, { 1, 6 } }, + { { 1, 12 }, { 1, 18 } }, + }, +}; + +struct tsens_legacy_calibration_format tsens_8974_nvmem = { + .base_len = 8, + .base_shift = 2, + .sp_len = 6, + .mode = { 1, 30 }, + .invalid = { 3, 30 }, + .base = { { 0, 0 }, { 2, 12 } }, + .sp = { + { { 0, 8 }, { 2, 20 } }, + { { 0, 14 }, { 2, 26 } }, + { { 0, 20 }, { 3, 0 } }, + { { 0, 26 }, { 3, 6 } }, + { { 1, 0 }, { 3, 12 } }, + { { 1, 6 }, { 3, 18 } }, + { { 1, 12 }, { 3, 24 } }, + { { 1, 18 }, { 4, 0 } }, + { { 1, 24 }, { 4, 6 } }, + { { 2, 0 }, { 4, 12 } }, + { { 2, 6 }, { 4, 18 } }, + }, +}; + +struct tsens_legacy_calibration_format tsens_8974_backup_nvmem = { + .base_len = 8, + .base_shift = 2, + .sp_len = 6, + .mode = { 4, 30, 1 }, + .invalid = { 5, 30, 1 }, + .base = { { 0, 0 }, { 2, 18 } }, + .sp = { + { { 0, 8 }, { 2, 26 } }, + { { 0, 14 }, { 3, 0 } }, + { { 0, 20 }, { 3, 6 } }, + { { 0, 26 }, { 3, 12 } }, + { { 1, 0 }, { 3, 18 } }, + { { 1, 6 }, { 3, 24, 1 } }, + { { 1, 12 }, { 4, 0, 1 } }, + { { 1, 18 }, { 4, 6, 1 } }, + { { 2, 0 }, { 4, 12, 1 } }, + { { 2, 6 }, { 4, 18, 1 } }, + { { 2, 12 }, { 4, 24, 1 } }, + }, +}; + +struct tsens_legacy_calibration_format tsens_9607_nvmem = { + .base_len = 8, + .base_shift = 2, + .sp_len = 6, + .mode = { 2, 20 }, + .invalid = { 2, 22 }, + .base = { { 0, 0 }, { 2, 12 } }, + .sp = { + { { 0, 8 }, { 0, 14 } }, + { { 0, 20 }, { 0, 26 } }, + { { 1, 0 }, { 1, 6 } }, + { { 1, 12 }, { 1, 18 } }, + { { 2, 0 }, { 2, 6 } }, + }, +}; static int calibrate_8916(struct tsens_priv *priv) { - int base0 = 0, base1 = 0, i; u32 p1[5], p2[5]; - int mode = 0; u32 *qfprom_cdata, *qfprom_csel; - int ret; + int mode, ret; ret = tsens_calibrate_nvmem(priv, 3); if (!ret) @@ -246,37 +139,9 @@ static int calibrate_8916(struct tsens_priv *priv) return PTR_ERR(qfprom_csel); } - mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT; - dev_dbg(priv->dev, "calibration mode is %d\n", mode); - - switch (mode) { - case TWO_PT_CALIB: - base1 = (qfprom_cdata[1] & MSM8916_BASE1_MASK) >> MSM8916_BASE1_SHIFT; - p2[0] = (qfprom_cdata[0] & MSM8916_S0_P2_MASK) >> MSM8916_S0_P2_SHIFT; - p2[1] = (qfprom_cdata[0] & MSM8916_S1_P2_MASK) >> MSM8916_S1_P2_SHIFT; - p2[2] = (qfprom_cdata[1] & MSM8916_S2_P2_MASK) >> MSM8916_S2_P2_SHIFT; - p2[3] = (qfprom_cdata[1] & MSM8916_S3_P2_MASK) >> MSM8916_S3_P2_SHIFT; - p2[4] = (qfprom_cdata[1] & MSM8916_S4_P2_MASK) >> MSM8916_S4_P2_SHIFT; - for (i = 0; i < priv->num_sensors; i++) - p2[i] = ((base1 + p2[i]) << 3); - fallthrough; - case ONE_PT_CALIB2: - base0 = (qfprom_cdata[0] & MSM8916_BASE0_MASK); - p1[0] = (qfprom_cdata[0] & MSM8916_S0_P1_MASK) >> MSM8916_S0_P1_SHIFT; - p1[1] = (qfprom_cdata[0] & MSM8916_S1_P1_MASK) >> MSM8916_S1_P1_SHIFT; - p1[2] = (qfprom_cdata[0] & MSM8916_S2_P1_MASK) >> MSM8916_S2_P1_SHIFT; - p1[3] = (qfprom_cdata[1] & MSM8916_S3_P1_MASK) >> MSM8916_S3_P1_SHIFT; - p1[4] = (qfprom_cdata[1] & MSM8916_S4_P1_MASK) >> MSM8916_S4_P1_SHIFT; - for (i = 0; i < priv->num_sensors; i++) - p1[i] = (((base0) + p1[i]) << 3); - break; - default: - for (i = 0; i < priv->num_sensors; i++) { - p1[i] = 500; - p2[i] = 780; - } - break; - } + mode = tsens_read_calibration_legacy(priv, &tsens_8916_nvmem, + p1, p2, + qfprom_cdata, qfprom_csel); compute_intercept_slope(priv, p1, p2, mode); kfree(qfprom_cdata); @@ -287,12 +152,9 @@ static int calibrate_8916(struct tsens_priv *priv) static int calibrate_8939(struct tsens_priv *priv) { - int base0 = 0, base1 = 0, i; u32 p1[10], p2[10]; - int mode = 0; u32 *qfprom_cdata; - u32 cdata[4]; - int ret; + int mode, ret; ret = tsens_calibrate_common(priv); if (!ret) @@ -302,52 +164,9 @@ static int calibrate_8939(struct tsens_priv *priv) if (IS_ERR(qfprom_cdata)) return PTR_ERR(qfprom_cdata); - /* Mapping between qfprom nvmem and calibration data */ - cdata[0] = qfprom_cdata[12]; - cdata[1] = qfprom_cdata[13]; - cdata[2] = qfprom_cdata[0]; - cdata[3] = qfprom_cdata[1]; - - mode = (cdata[0] & MSM8939_CAL_SEL_MASK) >> MSM8939_CAL_SEL_SHIFT; - dev_dbg(priv->dev, "calibration mode is %d\n", mode); - - switch (mode) { - case TWO_PT_CALIB: - base1 = (cdata[3] & MSM8939_BASE1_MASK) >> MSM8939_BASE1_SHIFT; - p2[0] = (cdata[0] & MSM8939_S0_P2_MASK) >> MSM8939_S0_P2_SHIFT; - p2[1] = (cdata[0] & MSM8939_S1_P2_MASK) >> MSM8939_S1_P2_SHIFT; - p2[2] = (cdata[1] & MSM8939_S2_P2_MASK) >> MSM8939_S2_P2_SHIFT; - p2[3] = (cdata[1] & MSM8939_S3_P2_MASK) >> MSM8939_S3_P2_SHIFT; - p2[4] = (cdata[1] & MSM8939_S4_P2_MASK) >> MSM8939_S4_P2_SHIFT; - p2[5] = (cdata[2] & MSM8939_S5_P2_MASK) >> MSM8939_S5_P2_SHIFT; - p2[6] = (cdata[2] & MSM8939_S6_P2_MASK) >> MSM8939_S6_P2_SHIFT; - p2[7] = (cdata[3] & MSM8939_S7_P2_MASK) >> MSM8939_S7_P2_SHIFT; - p2[8] = (cdata[3] & MSM8939_S8_P2_MASK) >> MSM8939_S8_P2_SHIFT; - for (i = 0; i < priv->num_sensors; i++) - p2[i] = (base1 + p2[i]) << 2; - fallthrough; - case ONE_PT_CALIB2: - base0 = (cdata[2] & MSM8939_BASE0_MASK) >> MSM8939_BASE0_SHIFT; - p1[0] = (cdata[0] & MSM8939_S0_P1_MASK) >> MSM8939_S0_P1_SHIFT; - p1[1] = (cdata[0] & MSM8939_S1_P1_MASK) >> MSM8939_S1_P1_SHIFT; - p1[2] = (cdata[0] & MSM8939_S2_P1_MASK_0_4) >> MSM8939_S2_P1_SHIFT_0_4; - p1[2] |= ((cdata[1] & MSM8939_S2_P1_MASK_5) >> MSM8939_S2_P1_SHIFT_5) << 5; - p1[3] = (cdata[1] & MSM8939_S3_P1_MASK) >> MSM8939_S3_P1_SHIFT; - p1[4] = (cdata[1] & MSM8939_S4_P1_MASK) >> MSM8939_S4_P1_SHIFT; - p1[5] = (cdata[2] & MSM8939_S5_P1_MASK) >> MSM8939_S5_P1_SHIFT; - p1[6] = (cdata[2] & MSM8939_S6_P1_MASK) >> MSM8939_S6_P1_SHIFT; - p1[7] = (cdata[3] & MSM8939_S7_P1_MASK) >> MSM8939_S7_P1_SHIFT; - p1[8] = (cdata[3] & MSM8939_S8_P1_MASK) >> MSM8939_S8_P1_SHIFT; - for (i = 0; i < priv->num_sensors; i++) - p1[i] = ((base0) + p1[i]) << 2; - break; - default: - for (i = 0; i < priv->num_sensors; i++) { - p1[i] = 500; - p2[i] = 780; - } - break; - } + mode = tsens_read_calibration_legacy(priv, &tsens_8939_nvmem, + p1, p2, + qfprom_cdata, NULL); compute_intercept_slope(priv, p1, p2, mode); kfree(qfprom_cdata); @@ -355,21 +174,9 @@ static int calibrate_8939(struct tsens_priv *priv) return 0; } -static int calibrate_8974_nvmem(struct tsens_priv *priv) +static void fixup_8974_points(int mode, u32 *p1, u32 *p2) { - int i, ret, mode; - u32 p1[11], p2[11]; - u32 backup; - - ret = nvmem_cell_read_variable_le_u32(priv->dev, "use_backup", &backup); - if (ret == -ENOENT) - dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n"); - if (ret < 0) - return ret; - - mode = tsens_read_calibration(priv, 2, p1, p2, backup == BKP_SEL); - if (mode < 0) - return mode; + int i; if (mode == NO_PT_CALIB) { p1[0] += 2; @@ -384,7 +191,7 @@ static int calibrate_8974_nvmem(struct tsens_priv *priv) p1[9] += 9; p1[10] += 8; } else { - for (i = 0; i < priv->num_sensors; i++) { + for (i = 0; i < 11; i++) { /* * ONE_PT_CALIB requires using addition here instead of * using OR operation. @@ -394,6 +201,26 @@ static int calibrate_8974_nvmem(struct tsens_priv *priv) } } +} + +static int calibrate_8974_nvmem(struct tsens_priv *priv) +{ + u32 p1[11], p2[11]; + u32 backup; + int ret, mode; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, "use_backup", &backup); + if (ret == -ENOENT) + dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n"); + if (ret < 0) + return ret; + + mode = tsens_read_calibration(priv, 2, p1, p2, backup == BKP_SEL); + if (mode < 0) + return mode; + + fixup_8974_points(mode, p1, p2); + compute_intercept_slope(priv, p1, p2, mode); return 0; @@ -401,12 +228,10 @@ static int calibrate_8974_nvmem(struct tsens_priv *priv) static int calibrate_8974(struct tsens_priv *priv) { - int base1 = 0, base2 = 0, i; u32 p1[11], p2[11]; - int mode = 0; u32 *calib, *bkp; u32 calib_redun_sel; - int ret; + int mode, ret; ret = calibrate_8974_nvmem(priv); if (ret == 0) @@ -422,116 +247,18 @@ static int calibrate_8974(struct tsens_priv *priv) return PTR_ERR(bkp); } - calib_redun_sel = bkp[1] & BKP_REDUN_SEL; - calib_redun_sel >>= BKP_REDUN_SHIFT; - - if (calib_redun_sel == BKP_SEL) { - mode = (calib[4] & CAL_SEL_0_1) >> CAL_SEL_SHIFT; - mode |= (calib[5] & CAL_SEL_2) >> CAL_SEL_SHIFT_2; - - switch (mode) { - case TWO_PT_CALIB: - base2 = (bkp[2] & BASE2_BKP_MASK) >> BASE2_BKP_SHIFT; - p2[0] = (bkp[2] & S0_P2_BKP_MASK) >> S0_P2_BKP_SHIFT; - p2[1] = (bkp[3] & S1_P2_BKP_MASK); - p2[2] = (bkp[3] & S2_P2_BKP_MASK) >> S2_P2_BKP_SHIFT; - p2[3] = (bkp[3] & S3_P2_BKP_MASK) >> S3_P2_BKP_SHIFT; - p2[4] = (bkp[3] & S4_P2_BKP_MASK) >> S4_P2_BKP_SHIFT; - p2[5] = (calib[4] & S5_P2_BKP_MASK) >> S5_P2_BKP_SHIFT; - p2[6] = (calib[5] & S6_P2_BKP_MASK); - p2[7] = (calib[5] & S7_P2_BKP_MASK) >> S7_P2_BKP_SHIFT; - p2[8] = (calib[5] & S8_P2_BKP_MASK) >> S8_P2_BKP_SHIFT; - p2[9] = (calib[5] & S9_P2_BKP_MASK) >> S9_P2_BKP_SHIFT; - p2[10] = (calib[5] & S10_P2_BKP_MASK) >> S10_P2_BKP_SHIFT; - fallthrough; - case ONE_PT_CALIB: - case ONE_PT_CALIB2: - base1 = bkp[0] & BASE1_MASK; - p1[0] = (bkp[0] & S0_P1_MASK) >> S0_P1_SHIFT; - p1[1] = (bkp[0] & S1_P1_MASK) >> S1_P1_SHIFT; - p1[2] = (bkp[0] & S2_P1_MASK) >> S2_P1_SHIFT; - p1[3] = (bkp[0] & S3_P1_MASK) >> S3_P1_SHIFT; - p1[4] = (bkp[1] & S4_P1_MASK); - p1[5] = (bkp[1] & S5_P1_MASK) >> S5_P1_SHIFT; - p1[6] = (bkp[1] & S6_P1_MASK) >> S6_P1_SHIFT; - p1[7] = (bkp[1] & S7_P1_MASK) >> S7_P1_SHIFT; - p1[8] = (bkp[2] & S8_P1_MASK_BKP) >> S8_P1_SHIFT; - p1[9] = (bkp[2] & S9_P1_MASK_BKP) >> S9_P1_BKP_SHIFT; - p1[10] = (bkp[2] & S10_P1_MASK_BKP) >> S10_P1_BKP_SHIFT; - break; - } - } else { - mode = (calib[1] & CAL_SEL_0_1) >> CAL_SEL_SHIFT; - mode |= (calib[3] & CAL_SEL_2) >> CAL_SEL_SHIFT_2; - - switch (mode) { - case TWO_PT_CALIB: - base2 = (calib[2] & BASE2_MASK) >> BASE2_SHIFT; - p2[0] = (calib[2] & S0_P2_MASK) >> S0_P2_SHIFT; - p2[1] = (calib[2] & S1_P2_MASK) >> S1_P2_SHIFT; - p2[2] = (calib[3] & S2_P2_MASK); - p2[3] = (calib[3] & S3_P2_MASK) >> S3_P2_SHIFT; - p2[4] = (calib[3] & S4_P2_MASK) >> S4_P2_SHIFT; - p2[5] = (calib[3] & S5_P2_MASK) >> S5_P2_SHIFT; - p2[6] = (calib[3] & S6_P2_MASK) >> S6_P2_SHIFT; - p2[7] = (calib[4] & S7_P2_MASK); - p2[8] = (calib[4] & S8_P2_MASK) >> S8_P2_SHIFT; - p2[9] = (calib[4] & S9_P2_MASK) >> S9_P2_SHIFT; - p2[10] = (calib[4] & S10_P2_MASK) >> S10_P2_SHIFT; - fallthrough; - case ONE_PT_CALIB: - case ONE_PT_CALIB2: - base1 = calib[0] & BASE1_MASK; - p1[0] = (calib[0] & S0_P1_MASK) >> S0_P1_SHIFT; - p1[1] = (calib[0] & S1_P1_MASK) >> S1_P1_SHIFT; - p1[2] = (calib[0] & S2_P1_MASK) >> S2_P1_SHIFT; - p1[3] = (calib[0] & S3_P1_MASK) >> S3_P1_SHIFT; - p1[4] = (calib[1] & S4_P1_MASK); - p1[5] = (calib[1] & S5_P1_MASK) >> S5_P1_SHIFT; - p1[6] = (calib[1] & S6_P1_MASK) >> S6_P1_SHIFT; - p1[7] = (calib[1] & S7_P1_MASK) >> S7_P1_SHIFT; - p1[8] = (calib[1] & S8_P1_MASK) >> S8_P1_SHIFT; - p1[9] = (calib[2] & S9_P1_MASK); - p1[10] = (calib[2] & S10_P1_MASK) >> S10_P1_SHIFT; - break; - } - } + calib_redun_sel = FIELD_GET(BKP_REDUN_SEL, bkp[1]); - switch (mode) { - case ONE_PT_CALIB: - for (i = 0; i < priv->num_sensors; i++) - p1[i] += (base1 << 2) | BIT_APPEND; - break; - case TWO_PT_CALIB: - for (i = 0; i < priv->num_sensors; i++) { - p2[i] += base2; - p2[i] <<= 2; - p2[i] |= BIT_APPEND; - } - fallthrough; - case ONE_PT_CALIB2: - for (i = 0; i < priv->num_sensors; i++) { - p1[i] += base1; - p1[i] <<= 2; - p1[i] |= BIT_APPEND; - } - break; - default: - for (i = 0; i < priv->num_sensors; i++) - p2[i] = 780; - p1[0] = 502; - p1[1] = 509; - p1[2] = 503; - p1[3] = 509; - p1[4] = 505; - p1[5] = 509; - p1[6] = 507; - p1[7] = 510; - p1[8] = 508; - p1[9] = 509; - p1[10] = 508; - break; - } + if (calib_redun_sel == BKP_SEL) + mode = tsens_read_calibration_legacy(priv, &tsens_8974_backup_nvmem, + p1, p2, + bkp, calib); + else + mode = tsens_read_calibration_legacy(priv, &tsens_8974_nvmem, + p1, p2, + calib, NULL); + + fixup_8974_points(mode, p1, p2); compute_intercept_slope(priv, p1, p2, mode); kfree(calib); @@ -542,11 +269,9 @@ static int calibrate_8974(struct tsens_priv *priv) static int calibrate_9607(struct tsens_priv *priv) { - int base, i; u32 p1[5], p2[5]; - int mode = 0; u32 *qfprom_cdata; - int ret; + int mode, ret; ret = tsens_calibrate_common(priv); if (!ret) @@ -556,37 +281,9 @@ static int calibrate_9607(struct tsens_priv *priv) if (IS_ERR(qfprom_cdata)) return PTR_ERR(qfprom_cdata); - mode = (qfprom_cdata[2] & MDM9607_CAL_SEL_MASK) >> MDM9607_CAL_SEL_SHIFT; - dev_dbg(priv->dev, "calibration mode is %d\n", mode); - - switch (mode) { - case TWO_PT_CALIB: - base = (qfprom_cdata[2] & MDM9607_BASE1_MASK) >> MDM9607_BASE1_SHIFT; - p2[0] = (qfprom_cdata[0] & MDM9607_S0_P2_MASK) >> MDM9607_S0_P2_SHIFT; - p2[1] = (qfprom_cdata[0] & MDM9607_S1_P2_MASK) >> MDM9607_S1_P2_SHIFT; - p2[2] = (qfprom_cdata[1] & MDM9607_S2_P2_MASK) >> MDM9607_S2_P2_SHIFT; - p2[3] = (qfprom_cdata[1] & MDM9607_S3_P2_MASK) >> MDM9607_S3_P2_SHIFT; - p2[4] = (qfprom_cdata[2] & MDM9607_S4_P2_MASK) >> MDM9607_S4_P2_SHIFT; - for (i = 0; i < priv->num_sensors; i++) - p2[i] = ((base + p2[i]) << 2); - fallthrough; - case ONE_PT_CALIB2: - base = (qfprom_cdata[0] & MDM9607_BASE0_MASK); - p1[0] = (qfprom_cdata[0] & MDM9607_S0_P1_MASK) >> MDM9607_S0_P1_SHIFT; - p1[1] = (qfprom_cdata[0] & MDM9607_S1_P1_MASK) >> MDM9607_S1_P1_SHIFT; - p1[2] = (qfprom_cdata[1] & MDM9607_S2_P1_MASK) >> MDM9607_S2_P1_SHIFT; - p1[3] = (qfprom_cdata[1] & MDM9607_S3_P1_MASK) >> MDM9607_S3_P1_SHIFT; - p1[4] = (qfprom_cdata[2] & MDM9607_S4_P1_MASK) >> MDM9607_S4_P1_SHIFT; - for (i = 0; i < priv->num_sensors; i++) - p1[i] = ((base + p1[i]) << 2); - break; - default: - for (i = 0; i < priv->num_sensors; i++) { - p1[i] = 500; - p2[i] = 780; - } - break; - } + mode = tsens_read_calibration_legacy(priv, &tsens_9607_nvmem, + p1, p2, + qfprom_cdata, NULL); compute_intercept_slope(priv, p1, p2, mode); kfree(qfprom_cdata); diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 5bba75a845c5..6d1ea430f90b 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -21,129 +21,54 @@ #define TM_HIGH_LOW_INT_STATUS_OFF 0x0088 #define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090 -/* eeprom layout data for msm8956/76 (v1) */ -#define MSM8976_BASE0_MASK 0xff -#define MSM8976_BASE1_MASK 0xff -#define MSM8976_BASE1_SHIFT 8 - -#define MSM8976_S0_P1_MASK 0x3f00 -#define MSM8976_S1_P1_MASK 0x3f00000 -#define MSM8976_S2_P1_MASK 0x3f -#define MSM8976_S3_P1_MASK 0x3f000 -#define MSM8976_S4_P1_MASK 0x3f00 -#define MSM8976_S5_P1_MASK 0x3f00000 -#define MSM8976_S6_P1_MASK 0x3f -#define MSM8976_S7_P1_MASK 0x3f000 -#define MSM8976_S8_P1_MASK 0x1f8 -#define MSM8976_S9_P1_MASK 0x1f8000 -#define MSM8976_S10_P1_MASK 0xf8000000 -#define MSM8976_S10_P1_MASK_1 0x1 - -#define MSM8976_S0_P2_MASK 0xfc000 -#define MSM8976_S1_P2_MASK 0xfc000000 -#define MSM8976_S2_P2_MASK 0xfc0 -#define MSM8976_S3_P2_MASK 0xfc0000 -#define MSM8976_S4_P2_MASK 0xfc000 -#define MSM8976_S5_P2_MASK 0xfc000000 -#define MSM8976_S6_P2_MASK 0xfc0 -#define MSM8976_S7_P2_MASK 0xfc0000 -#define MSM8976_S8_P2_MASK 0x7e00 -#define MSM8976_S9_P2_MASK 0x7e00000 -#define MSM8976_S10_P2_MASK 0x7e - -#define MSM8976_S0_P1_SHIFT 8 -#define MSM8976_S1_P1_SHIFT 20 -#define MSM8976_S2_P1_SHIFT 0 -#define MSM8976_S3_P1_SHIFT 12 -#define MSM8976_S4_P1_SHIFT 8 -#define MSM8976_S5_P1_SHIFT 20 -#define MSM8976_S6_P1_SHIFT 0 -#define MSM8976_S7_P1_SHIFT 12 -#define MSM8976_S8_P1_SHIFT 3 -#define MSM8976_S9_P1_SHIFT 15 -#define MSM8976_S10_P1_SHIFT 27 -#define MSM8976_S10_P1_SHIFT_1 0 - -#define MSM8976_S0_P2_SHIFT 14 -#define MSM8976_S1_P2_SHIFT 26 -#define MSM8976_S2_P2_SHIFT 6 -#define MSM8976_S3_P2_SHIFT 18 -#define MSM8976_S4_P2_SHIFT 14 -#define MSM8976_S5_P2_SHIFT 26 -#define MSM8976_S6_P2_SHIFT 6 -#define MSM8976_S7_P2_SHIFT 18 -#define MSM8976_S8_P2_SHIFT 9 -#define MSM8976_S9_P2_SHIFT 21 -#define MSM8976_S10_P2_SHIFT 1 - -#define MSM8976_CAL_SEL_MASK 0x3 - -/* eeprom layout data for qcs404/405 (v1) */ -#define BASE0_MASK 0x000007f8 -#define BASE1_MASK 0x0007f800 -#define BASE0_SHIFT 3 -#define BASE1_SHIFT 11 - -#define S0_P1_MASK 0x0000003f -#define S1_P1_MASK 0x0003f000 -#define S2_P1_MASK 0x3f000000 -#define S3_P1_MASK 0x000003f0 -#define S4_P1_MASK 0x003f0000 -#define S5_P1_MASK 0x0000003f -#define S6_P1_MASK 0x0003f000 -#define S7_P1_MASK 0x3f000000 -#define S8_P1_MASK 0x000003f0 -#define S9_P1_MASK 0x003f0000 - -#define S0_P2_MASK 0x00000fc0 -#define S1_P2_MASK 0x00fc0000 -#define S2_P2_MASK_1_0 0xc0000000 -#define S2_P2_MASK_5_2 0x0000000f -#define S3_P2_MASK 0x0000fc00 -#define S4_P2_MASK 0x0fc00000 -#define S5_P2_MASK 0x00000fc0 -#define S6_P2_MASK 0x00fc0000 -#define S7_P2_MASK_1_0 0xc0000000 -#define S7_P2_MASK_5_2 0x0000000f -#define S8_P2_MASK 0x0000fc00 -#define S9_P2_MASK 0x0fc00000 - -#define S0_P1_SHIFT 0 -#define S0_P2_SHIFT 6 -#define S1_P1_SHIFT 12 -#define S1_P2_SHIFT 18 -#define S2_P1_SHIFT 24 -#define S2_P2_SHIFT_1_0 30 - -#define S2_P2_SHIFT_5_2 0 -#define S3_P1_SHIFT 4 -#define S3_P2_SHIFT 10 -#define S4_P1_SHIFT 16 -#define S4_P2_SHIFT 22 - -#define S5_P1_SHIFT 0 -#define S5_P2_SHIFT 6 -#define S6_P1_SHIFT 12 -#define S6_P2_SHIFT 18 -#define S7_P1_SHIFT 24 -#define S7_P2_SHIFT_1_0 30 - -#define S7_P2_SHIFT_5_2 0 -#define S8_P1_SHIFT 4 -#define S8_P2_SHIFT 10 -#define S9_P1_SHIFT 16 -#define S9_P2_SHIFT 22 - -#define CAL_SEL_MASK 7 -#define CAL_SEL_SHIFT 0 +struct tsens_legacy_calibration_format tsens_qcs404_nvmem = { + .base_len = 8, + .base_shift = 2, + .sp_len = 6, + .mode = { 4, 0 }, + .invalid = { 4, 2 }, + .base = { { 4, 3 }, { 4, 11 } }, + .sp = { + { { 0, 0 }, { 0, 6 } }, + { { 0, 12 }, { 0, 18 } }, + { { 0, 24 }, { 0, 30 } }, + { { 1, 4 }, { 1, 10 } }, + { { 1, 16 }, { 1, 22 } }, + { { 2, 0 }, { 2, 6 } }, + { { 2, 12 }, { 2, 18 } }, + { { 2, 24 }, { 2, 30 } }, + { { 3, 4 }, { 3, 10 } }, + { { 3, 16 }, { 3, 22 } }, + }, +}; + +struct tsens_legacy_calibration_format tsens_8976_nvmem = { + .base_len = 8, + .base_shift = 2, + .sp_len = 6, + .mode = { 4, 0 }, + .invalid = { 4, 2 }, + .base = { { 0, 0 }, { 2, 8 } }, + .sp = { + { { 0, 8 }, { 0, 14 } }, + { { 0, 20 }, { 0, 26 } }, + { { 1, 0 }, { 1, 6 } }, + { { 1, 12 }, { 1, 18 } }, + { { 2, 8 }, { 2, 14 } }, + { { 2, 20 }, { 2, 26 } }, + { { 3, 0 }, { 3, 6 } }, + { { 3, 12 }, { 3, 18 } }, + { { 4, 2 }, { 4, 9 } }, + { { 4, 14 }, { 4, 21 } }, + { { 4, 26 }, { 5, 1 } }, + }, +}; static int calibrate_v1(struct tsens_priv *priv) { - u32 base0 = 0, base1 = 0; u32 p1[10], p2[10]; - u32 mode = 0, lsb = 0, msb = 0; u32 *qfprom_cdata; - int i, ret; + int mode, ret; ret = tsens_calibrate_common(priv); if (!ret) @@ -153,53 +78,9 @@ static int calibrate_v1(struct tsens_priv *priv) if (IS_ERR(qfprom_cdata)) return PTR_ERR(qfprom_cdata); - mode = (qfprom_cdata[4] & CAL_SEL_MASK) >> CAL_SEL_SHIFT; - dev_dbg(priv->dev, "calibration mode is %d\n", mode); - - switch (mode) { - case TWO_PT_CALIB: - base1 = (qfprom_cdata[4] & BASE1_MASK) >> BASE1_SHIFT; - p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT; - p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT; - /* This value is split over two registers, 2 bits and 4 bits */ - lsb = (qfprom_cdata[0] & S2_P2_MASK_1_0) >> S2_P2_SHIFT_1_0; - msb = (qfprom_cdata[1] & S2_P2_MASK_5_2) >> S2_P2_SHIFT_5_2; - p2[2] = msb << 2 | lsb; - p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT; - p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT; - p2[5] = (qfprom_cdata[2] & S5_P2_MASK) >> S5_P2_SHIFT; - p2[6] = (qfprom_cdata[2] & S6_P2_MASK) >> S6_P2_SHIFT; - /* This value is split over two registers, 2 bits and 4 bits */ - lsb = (qfprom_cdata[2] & S7_P2_MASK_1_0) >> S7_P2_SHIFT_1_0; - msb = (qfprom_cdata[3] & S7_P2_MASK_5_2) >> S7_P2_SHIFT_5_2; - p2[7] = msb << 2 | lsb; - p2[8] = (qfprom_cdata[3] & S8_P2_MASK) >> S8_P2_SHIFT; - p2[9] = (qfprom_cdata[3] & S9_P2_MASK) >> S9_P2_SHIFT; - for (i = 0; i < priv->num_sensors; i++) - p2[i] = ((base1 + p2[i]) << 2); - fallthrough; - case ONE_PT_CALIB2: - base0 = (qfprom_cdata[4] & BASE0_MASK) >> BASE0_SHIFT; - p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT; - p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT; - p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT; - p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT; - p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT; - p1[5] = (qfprom_cdata[2] & S5_P1_MASK) >> S5_P1_SHIFT; - p1[6] = (qfprom_cdata[2] & S6_P1_MASK) >> S6_P1_SHIFT; - p1[7] = (qfprom_cdata[2] & S7_P1_MASK) >> S7_P1_SHIFT; - p1[8] = (qfprom_cdata[3] & S8_P1_MASK) >> S8_P1_SHIFT; - p1[9] = (qfprom_cdata[3] & S9_P1_MASK) >> S9_P1_SHIFT; - for (i = 0; i < priv->num_sensors; i++) - p1[i] = (((base0) + p1[i]) << 2); - break; - default: - for (i = 0; i < priv->num_sensors; i++) { - p1[i] = 500; - p2[i] = 780; - } - break; - } + mode = tsens_read_calibration_legacy(priv, &tsens_qcs404_nvmem, + p1, p2, + qfprom_cdata, NULL); compute_intercept_slope(priv, p1, p2, mode); kfree(qfprom_cdata); @@ -209,11 +90,9 @@ static int calibrate_v1(struct tsens_priv *priv) static int calibrate_8976(struct tsens_priv *priv) { - int base0 = 0, base1 = 0, i; u32 p1[11], p2[11]; - int mode = 0, tmp = 0; u32 *qfprom_cdata; - int ret; + int mode, ret; ret = tsens_calibrate_common(priv); if (!ret) @@ -223,53 +102,10 @@ static int calibrate_8976(struct tsens_priv *priv) if (IS_ERR(qfprom_cdata)) return PTR_ERR(qfprom_cdata); - mode = (qfprom_cdata[4] & MSM8976_CAL_SEL_MASK); - dev_dbg(priv->dev, "calibration mode is %d\n", mode); - - switch (mode) { - case TWO_PT_CALIB: - base1 = (qfprom_cdata[2] & MSM8976_BASE1_MASK) >> MSM8976_BASE1_SHIFT; - p2[0] = (qfprom_cdata[0] & MSM8976_S0_P2_MASK) >> MSM8976_S0_P2_SHIFT; - p2[1] = (qfprom_cdata[0] & MSM8976_S1_P2_MASK) >> MSM8976_S1_P2_SHIFT; - p2[2] = (qfprom_cdata[1] & MSM8976_S2_P2_MASK) >> MSM8976_S2_P2_SHIFT; - p2[3] = (qfprom_cdata[1] & MSM8976_S3_P2_MASK) >> MSM8976_S3_P2_SHIFT; - p2[4] = (qfprom_cdata[2] & MSM8976_S4_P2_MASK) >> MSM8976_S4_P2_SHIFT; - p2[5] = (qfprom_cdata[2] & MSM8976_S5_P2_MASK) >> MSM8976_S5_P2_SHIFT; - p2[6] = (qfprom_cdata[3] & MSM8976_S6_P2_MASK) >> MSM8976_S6_P2_SHIFT; - p2[7] = (qfprom_cdata[3] & MSM8976_S7_P2_MASK) >> MSM8976_S7_P2_SHIFT; - p2[8] = (qfprom_cdata[4] & MSM8976_S8_P2_MASK) >> MSM8976_S8_P2_SHIFT; - p2[9] = (qfprom_cdata[4] & MSM8976_S9_P2_MASK) >> MSM8976_S9_P2_SHIFT; - p2[10] = (qfprom_cdata[5] & MSM8976_S10_P2_MASK) >> MSM8976_S10_P2_SHIFT; - - for (i = 0; i < priv->num_sensors; i++) - p2[i] = ((base1 + p2[i]) << 2); - fallthrough; - case ONE_PT_CALIB2: - base0 = qfprom_cdata[0] & MSM8976_BASE0_MASK; - p1[0] = (qfprom_cdata[0] & MSM8976_S0_P1_MASK) >> MSM8976_S0_P1_SHIFT; - p1[1] = (qfprom_cdata[0] & MSM8976_S1_P1_MASK) >> MSM8976_S1_P1_SHIFT; - p1[2] = (qfprom_cdata[1] & MSM8976_S2_P1_MASK) >> MSM8976_S2_P1_SHIFT; - p1[3] = (qfprom_cdata[1] & MSM8976_S3_P1_MASK) >> MSM8976_S3_P1_SHIFT; - p1[4] = (qfprom_cdata[2] & MSM8976_S4_P1_MASK) >> MSM8976_S4_P1_SHIFT; - p1[5] = (qfprom_cdata[2] & MSM8976_S5_P1_MASK) >> MSM8976_S5_P1_SHIFT; - p1[6] = (qfprom_cdata[3] & MSM8976_S6_P1_MASK) >> MSM8976_S6_P1_SHIFT; - p1[7] = (qfprom_cdata[3] & MSM8976_S7_P1_MASK) >> MSM8976_S7_P1_SHIFT; - p1[8] = (qfprom_cdata[4] & MSM8976_S8_P1_MASK) >> MSM8976_S8_P1_SHIFT; - p1[9] = (qfprom_cdata[4] & MSM8976_S9_P1_MASK) >> MSM8976_S9_P1_SHIFT; - p1[10] = (qfprom_cdata[4] & MSM8976_S10_P1_MASK) >> MSM8976_S10_P1_SHIFT; - tmp = (qfprom_cdata[5] & MSM8976_S10_P1_MASK_1) << MSM8976_S10_P1_SHIFT_1; - p1[10] |= tmp; - - for (i = 0; i < priv->num_sensors; i++) - p1[i] = (((base0) + p1[i]) << 2); - break; - default: - for (i = 0; i < priv->num_sensors; i++) { - p1[i] = 500; - p2[i] = 780; - } - break; - } + mode = tsens_read_calibration_legacy(priv, &tsens_8976_nvmem, + p1, p2, + qfprom_cdata, NULL); + compute_intercept_slope(priv, p1, p2, mode); kfree(qfprom_cdata); diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 6facdb0246a5..6d785ffe8fac 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -171,6 +171,70 @@ int tsens_calibrate_common(struct tsens_priv *priv) return tsens_calibrate_nvmem(priv, 2); } +static u32 tsens_read_cell(const struct tsens_single_value *cell, u8 len, u32 *data0, u32 *data1) +{ + u32 val; + u32 *data = cell->blob ? data1 : data0; + + if (cell->shift + len <= 32) { + val = data[cell->idx] >> cell->shift; + } else { + u8 part = 32 - cell->shift; + + val = data[cell->idx] >> cell->shift; + val |= data[cell->idx + 1] << part; + } + + return val & ((1 << len) - 1); +} + +int tsens_read_calibration_legacy(struct tsens_priv *priv, + const struct tsens_legacy_calibration_format *format, + u32 *p1, u32 *p2, + u32 *cdata0, u32 *cdata1) +{ + u32 mode, invalid; + u32 base1, base2; + int i; + + mode = tsens_read_cell(&format->mode, 2, cdata0, cdata1); + invalid = tsens_read_cell(&format->invalid, 1, cdata0, cdata1); + if (invalid) + mode = NO_PT_CALIB; + dev_dbg(priv->dev, "calibration mode is %d\n", mode); + + base1 = tsens_read_cell(&format->base[0], format->base_len, cdata0, cdata1); + base2 = tsens_read_cell(&format->base[1], format->base_len, cdata0, cdata1); + + for (i = 0; i < priv->num_sensors; i++) { + p1[i] = tsens_read_cell(&format->sp[i][0], format->sp_len, cdata0, cdata1); + p2[i] = tsens_read_cell(&format->sp[i][1], format->sp_len, cdata0, cdata1); + } + + switch (mode) { + case ONE_PT_CALIB: + for (i = 0; i < priv->num_sensors; i++) + p1[i] = p1[i] + (base1 << format->base_shift); + break; + case TWO_PT_CALIB: + for (i = 0; i < priv->num_sensors; i++) + p2[i] = (p2[i] + base2) << format->base_shift; + fallthrough; + case ONE_PT_CALIB2: + for (i = 0; i < priv->num_sensors; i++) + p1[i] = (p1[i] + base1) << format->base_shift; + break; + default: + dev_dbg(priv->dev, "calibrationless mode\n"); + for (i = 0; i < priv->num_sensors; i++) { + p1[i] = 500; + p2[i] = 780; + } + } + + return mode; +} + /* * Use this function on devices where slope and offset calculations * depend on calibration data read from qfprom. On others the slope diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index a9ae8df9f810..dba9cd38f637 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -584,7 +584,45 @@ struct tsens_priv { struct tsens_sensor sensor[]; }; +/** + * struct tsens_single_value - internal representation of a single field inside nvmem calibration data + * @idx: index into the u32 data array + * @shift: the shift of the first bit in the value + * @blob: index of the data blob to use for this cell + */ +struct tsens_single_value { + u8 idx; + u8 shift; + u8 blob; +}; + +/** + * struct tsens_legacy_calibration_format - description of calibration data used when parsing the legacy nvmem blob + * @base_len: the length of the base fields inside calibration data + * @base_shift: the shift to be applied to base data + * @sp_len: the length of the sN_pM fields inside calibration data + * @mode: descriptor of the calibration mode field + * @invalid: descriptor of the calibration mode invalid field + * @base: descriptors of the base0 and base1 fields + * @sp: descriptors of the sN_pM fields + */ +struct tsens_legacy_calibration_format { + unsigned int base_len; + unsigned int base_shift; + unsigned int sp_len; + /* just two bits */ + struct tsens_single_value mode; + /* on all platforms except 8974 invalid is the third bit of what downstream calls 'mode' */ + struct tsens_single_value invalid; + struct tsens_single_value base[2]; + struct tsens_single_value sp[][2]; +}; + char *qfprom_read(struct device *dev, const char *cname); +int tsens_read_calibration_legacy(struct tsens_priv *priv, + const struct tsens_legacy_calibration_format *format, + u32 *p1, u32 *p2, + u32 *cdata, u32 *csel); int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup); int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift); int tsens_calibrate_common(struct tsens_priv *priv); -- cgit v1.2.3 From 51d78b8b1beba247e1e4314420d98acb0732c4b7 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:26 +0200 Subject: thermal/drivers/tsens: Drop single-cell code for mdm9607 There is no dtsi file for mdm9607 in the kernel sources. Drop the compatibility with unofficial dtsi and remove support for handling the single-cell calibration data on mdm9607. Cc: Konrad Dybcio Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-13-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v0_1.c | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index f8b50bf14190..9488416b568c 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -267,30 +267,6 @@ static int calibrate_8974(struct tsens_priv *priv) return 0; } -static int calibrate_9607(struct tsens_priv *priv) -{ - u32 p1[5], p2[5]; - u32 *qfprom_cdata; - int mode, ret; - - ret = tsens_calibrate_common(priv); - if (!ret) - return 0; - - qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); - if (IS_ERR(qfprom_cdata)) - return PTR_ERR(qfprom_cdata); - - mode = tsens_read_calibration_legacy(priv, &tsens_9607_nvmem, - p1, p2, - qfprom_cdata, NULL); - - compute_intercept_slope(priv, p1, p2, mode); - kfree(qfprom_cdata); - - return 0; -} - static int __init init_8939(struct tsens_priv *priv) { priv->sensor[0].slope = 2911; priv->sensor[1].slope = 2789; @@ -355,6 +331,12 @@ static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = { [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0), }; +static const struct tsens_ops ops_v0_1 = { + .init = init_common, + .calibrate = tsens_calibrate_common, + .get_temp = get_temp_common, +}; + static const struct tsens_ops ops_8916 = { .init = init_common, .calibrate = calibrate_8916, @@ -398,15 +380,9 @@ struct tsens_plat_data data_8974 = { .fields = tsens_v0_1_regfields, }; -static const struct tsens_ops ops_9607 = { - .init = init_common, - .calibrate = calibrate_9607, - .get_temp = get_temp_common, -}; - struct tsens_plat_data data_9607 = { .num_sensors = 5, - .ops = &ops_9607, + .ops = &ops_v0_1, .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields, }; -- cgit v1.2.3 From dfadb4599ab0206935d5f14975b5e8112492b29c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:27 +0200 Subject: thermal/drivers/tsens: Drop single-cell code for msm8939 There is no dtsi file for msm8939 in the kernel sources. Drop the compatibility with unofficial dtsi and remove support for handling the single-cell calibration data on msm8939. Cc: Shawn Guo Cc: Bryan O'Donoghue Reviewed-by: Bryan O'Donoghue Reviewed-by: Konrad Dybcio Acked-by: Shawn Guo Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-14-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v0_1.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 9488416b568c..e89c6f39a3ae 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -150,30 +150,6 @@ static int calibrate_8916(struct tsens_priv *priv) return 0; } -static int calibrate_8939(struct tsens_priv *priv) -{ - u32 p1[10], p2[10]; - u32 *qfprom_cdata; - int mode, ret; - - ret = tsens_calibrate_common(priv); - if (!ret) - return 0; - - qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); - if (IS_ERR(qfprom_cdata)) - return PTR_ERR(qfprom_cdata); - - mode = tsens_read_calibration_legacy(priv, &tsens_8939_nvmem, - p1, p2, - qfprom_cdata, NULL); - - compute_intercept_slope(priv, p1, p2, mode); - kfree(qfprom_cdata); - - return 0; -} - static void fixup_8974_points(int mode, u32 *p1, u32 *p2) { int i; @@ -354,7 +330,7 @@ struct tsens_plat_data data_8916 = { static const struct tsens_ops ops_8939 = { .init = init_8939, - .calibrate = calibrate_8939, + .calibrate = tsens_calibrate_common, .get_temp = get_temp_common, }; -- cgit v1.2.3 From 3a908971f7cbee59c2cc07f6fc6fc02a32652a90 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:28 +0200 Subject: thermal/drivers/tsens: Drop single-cell code for msm8976/msm8956 There is no dtsi file for msm8976 in the kernel sources. Drop the compatibility with unofficial dtsi and remove support for handling the single-cell calibration data on msm8976. Cc: AngeloGioacchino Del Regno Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230101194034.831222-15-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens-v1.c | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 6d1ea430f90b..b822a426066d 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -88,31 +88,6 @@ static int calibrate_v1(struct tsens_priv *priv) return 0; } -static int calibrate_8976(struct tsens_priv *priv) -{ - u32 p1[11], p2[11]; - u32 *qfprom_cdata; - int mode, ret; - - ret = tsens_calibrate_common(priv); - if (!ret) - return 0; - - qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); - if (IS_ERR(qfprom_cdata)) - return PTR_ERR(qfprom_cdata); - - mode = tsens_read_calibration_legacy(priv, &tsens_8976_nvmem, - p1, p2, - qfprom_cdata, NULL); - - - compute_intercept_slope(priv, p1, p2, mode); - kfree(qfprom_cdata); - - return 0; -} - /* v1.x: msm8956,8976,qcs404,405 */ static struct tsens_features tsens_v1_feat = { @@ -211,7 +186,7 @@ struct tsens_plat_data data_tsens_v1 = { static const struct tsens_ops ops_8956 = { .init = init_8956, - .calibrate = calibrate_8976, + .calibrate = tsens_calibrate_common, .get_temp = get_temp_tsens_valid, }; @@ -224,7 +199,7 @@ struct tsens_plat_data data_8956 = { static const struct tsens_ops ops_8976 = { .init = init_common, - .calibrate = calibrate_8976, + .calibrate = tsens_calibrate_common, .get_temp = get_temp_tsens_valid, }; -- cgit v1.2.3 From df715f26cb7b43e3fabb4518aa65931180de8a71 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 16 Jan 2023 11:19:54 +0100 Subject: thermal/drivers/qcom: Remove duplicate set next trip point interrupt code The tsens driver reprogram the next trip points in the irq handler. This function then call thermal_zone_device_update(). However, thermal_zone_device_update() calls thermal_zone_set_trips() and from there it calls the backend 'set_trips' ops. This one in turn reprogram the next trip points (low/high). Consequently, the code setting the next trip points interrupt in the interrupt handle is not needed and could be removed. Reviewed-by: Bjorn Andersson Acked-by: Amit Kucheria Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20230116101955.3961427-1-daniel.lezcano@linaro.org --- drivers/thermal/qcom/tsens.c | 51 ++------------------------------------------ 1 file changed, 2 insertions(+), 49 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 6d785ffe8fac..8020ead2794e 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -624,12 +624,9 @@ static irqreturn_t tsens_irq_thread(int irq, void *data) { struct tsens_priv *priv = data; struct tsens_irq_data d; - bool enable = true, disable = false; - unsigned long flags; - int temp, ret, i; + int i; for (i = 0; i < priv->num_sensors; i++) { - bool trigger = false; const struct tsens_sensor *s = &priv->sensor[i]; u32 hw_id = s->hw_id; @@ -637,52 +634,8 @@ static irqreturn_t tsens_irq_thread(int irq, void *data) continue; if (!tsens_threshold_violated(priv, hw_id, &d)) continue; - ret = get_temp_tsens_valid(s, &temp); - if (ret) { - dev_err(priv->dev, "[%u] %s: error reading sensor\n", - hw_id, __func__); - continue; - } - spin_lock_irqsave(&priv->ul_lock, flags); - - tsens_read_irq_state(priv, hw_id, s, &d); - - if (d.up_viol && - !masked_irq(hw_id, d.up_irq_mask, tsens_version(priv))) { - tsens_set_interrupt(priv, hw_id, UPPER, disable); - if (d.up_thresh > temp) { - dev_dbg(priv->dev, "[%u] %s: re-arm upper\n", - hw_id, __func__); - tsens_set_interrupt(priv, hw_id, UPPER, enable); - } else { - trigger = true; - /* Keep irq masked */ - } - } else if (d.low_viol && - !masked_irq(hw_id, d.low_irq_mask, tsens_version(priv))) { - tsens_set_interrupt(priv, hw_id, LOWER, disable); - if (d.low_thresh < temp) { - dev_dbg(priv->dev, "[%u] %s: re-arm low\n", - hw_id, __func__); - tsens_set_interrupt(priv, hw_id, LOWER, enable); - } else { - trigger = true; - /* Keep irq masked */ - } - } - - spin_unlock_irqrestore(&priv->ul_lock, flags); - - if (trigger) { - dev_dbg(priv->dev, "[%u] %s: TZ update trigger (%d mC)\n", - hw_id, __func__, temp); - thermal_zone_device_update(s->tzd, - THERMAL_EVENT_UNSPECIFIED); - } else { - dev_dbg(priv->dev, "[%u] %s: no violation: %d\n", - hw_id, __func__, temp); - } + thermal_zone_device_update(s->tzd, THERMAL_EVENT_UNSPECIFIED); if (tsens_version(priv) < VER_0_1) { /* Constraint: There is only 1 interrupt control register for all -- cgit v1.2.3 From 4b26b7c9cdefdcb478047c30901d2379ef9e50fc Mon Sep 17 00:00:00 2001 From: Viorel Suman Date: Tue, 17 Jan 2023 11:19:55 +0200 Subject: thermal/drivers/imx_sc_thermal: Fix the loop condition The minimal resource ID is 0: IMX_SC_R_AP_0=0, so fix the loop condition. Aside of this - constify the array. Fixes: 31fd4b9db13b ("thermal/drivers/imx_sc: Rely on the platform data to get the resource id") Signed-off-by: Viorel Suman Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/20230117091956.61729-1-viorel.suman@oss.nxp.com Signed-off-by: Daniel Lezcano --- drivers/thermal/imx_sc_thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c index 4df925e3a80b..dfadb03580ae 100644 --- a/drivers/thermal/imx_sc_thermal.c +++ b/drivers/thermal/imx_sc_thermal.c @@ -88,7 +88,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) if (!resource_id) return -EINVAL; - for (i = 0; resource_id[i] > 0; i++) { + for (i = 0; resource_id[i] >= 0; i++) { sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL); if (!sensor) @@ -127,7 +127,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) return 0; } -static int imx_sc_sensors[] = { IMX_SC_R_SYSTEM, IMX_SC_R_PMIC_0, -1 }; +static const int imx_sc_sensors[] = { IMX_SC_R_SYSTEM, IMX_SC_R_PMIC_0, -1 }; static const struct of_device_id imx_sc_thermal_table[] = { { .compatible = "fsl,imx-sc-thermal", .data = imx_sc_sensors }, -- cgit v1.2.3 From 1cea99593c9e6991766765b8825e62da37da9ec2 Mon Sep 17 00:00:00 2001 From: Viorel Suman Date: Tue, 17 Jan 2023 11:19:56 +0200 Subject: thermal/drivers/imx_sc_thermal: Add iMX8QM sensors Add iMX8QM sensors. As stated in 31fd4b9db13b ("thermal/drivers/imx_sc: Rely on the platform data to get the resource id"): The thermal OF code returns -ENODEV if the thermal zone registration with a specific id fails because the description is not available in the DT for such a sensor id. In this case we continue with the other ids without bailing out with an error. Signed-off-by: Viorel Suman Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/20230117091956.61729-2-viorel.suman@oss.nxp.com Signed-off-by: Daniel Lezcano --- drivers/thermal/imx_sc_thermal.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c index dfadb03580ae..378f574607f7 100644 --- a/drivers/thermal/imx_sc_thermal.c +++ b/drivers/thermal/imx_sc_thermal.c @@ -127,7 +127,11 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) return 0; } -static const int imx_sc_sensors[] = { IMX_SC_R_SYSTEM, IMX_SC_R_PMIC_0, -1 }; +static const int imx_sc_sensors[] = { + IMX_SC_R_SYSTEM, IMX_SC_R_PMIC_0, + IMX_SC_R_AP_0, IMX_SC_R_AP_1, + IMX_SC_R_GPU_0_PID0, IMX_SC_R_GPU_1_PID0, + IMX_SC_R_DRC_0, -1 }; static const struct of_device_id imx_sc_thermal_table[] = { { .compatible = "fsl,imx-sc-thermal", .data = imx_sc_sensors }, -- cgit v1.2.3 From 5618f1bee2bfba8296208c6f39d8eed8509f8837 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Jan 2023 16:53:39 +0200 Subject: thermal/drivers/qcom-spmi-adc-tm5: Use asm intead of asm-generic There is no point to specify asm-generic for the unaligned.h. Drop the 'generic' suffix. Signed-off-by: Andy Shevchenko Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230103145339.40501-1-andriy.shevchenko@linux.intel.com Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c index ff47fc9ac9c5..31164ade2dd1 100644 --- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c @@ -18,7 +18,8 @@ #include #include #include -#include + +#include #include "../thermal_hwmon.h" -- cgit v1.2.3 From 780e220dc6b537de577e583aeae74983c7381af5 Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:31:36 +0800 Subject: thermal/drivers/brcmstb_thermal: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/202301181631362083446@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/broadcom/brcmstb_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c index c79c6cfdd74d..4d02c28331e3 100644 --- a/drivers/thermal/broadcom/brcmstb_thermal.c +++ b/drivers/thermal/broadcom/brcmstb_thermal.c @@ -321,7 +321,6 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) const struct thermal_zone_device_ops *of_ops; struct thermal_zone_device *thermal; struct brcmstb_thermal_priv *priv; - struct resource *res; int irq, ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -332,8 +331,7 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) if (!priv->temp_params) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->tmon_base = devm_ioremap_resource(&pdev->dev, res); + priv->tmon_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(priv->tmon_base)) return PTR_ERR(priv->tmon_base); -- cgit v1.2.3 From 142887ec975b0791d92242f5a8e18e5dc5f15800 Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:36:22 +0800 Subject: thermal/drivers/bcm2835: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/202301181636223863583@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/broadcom/bcm2835_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 5485e59d03a9..3d0710c6e004 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -167,7 +167,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) const struct of_device_id *match; struct thermal_zone_device *tz; struct bcm2835_thermal_data *data; - struct resource *res; int err = 0; u32 val; unsigned long rate; @@ -181,8 +180,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) if (!match) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - data->regs = devm_ioremap_resource(&pdev->dev, res); + data->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(data->regs)) { err = PTR_ERR(data->regs); return err; -- cgit v1.2.3 From b5d6ec4d3a7e59be371e48ae7f60a66a22e51ea5 Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:33:05 +0800 Subject: thermal/drivers/dove: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Link: https://lore.kernel.org/r/202301181633059433484@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/dove_thermal.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c index 73182eb94bc0..056622a58d00 100644 --- a/drivers/thermal/dove_thermal.c +++ b/drivers/thermal/dove_thermal.c @@ -122,20 +122,17 @@ static int dove_thermal_probe(struct platform_device *pdev) { struct thermal_zone_device *thermal = NULL; struct dove_thermal_priv *priv; - struct resource *res; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->sensor = devm_ioremap_resource(&pdev->dev, res); + priv->sensor = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(priv->sensor)) return PTR_ERR(priv->sensor); - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - priv->control = devm_ioremap_resource(&pdev->dev, res); + priv->control = devm_platform_get_and_ioremap_resource(pdev, 1, NULL); if (IS_ERR(priv->control)) return PTR_ERR(priv->control); -- cgit v1.2.3 From 9b22743b93d50a346f437fa96dfec399f35d4965 Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:34:37 +0800 Subject: thermal/drivers/armada: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Link: https://lore.kernel.org/r/202301181634379503534@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/armada_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index db040dbdaa0a..7d2682e8ef96 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -709,12 +709,10 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev, struct armada_thermal_priv *priv) { struct armada_thermal_data *data = priv->data; - struct resource *res; void __iomem *base; /* First memory region points towards the status register */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(base)) return PTR_ERR(base); -- cgit v1.2.3 From f7f6d3713282a272bd2b0fd2ad85ca320f6822b4 Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:37:47 +0800 Subject: thermal/drivers/mtk_thermal: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Link: https://lore.kernel.org/r/202301181637472073620@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/mtk_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 0084b76493d9..9a8b107900e9 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -990,7 +990,6 @@ static int mtk_thermal_probe(struct platform_device *pdev) int ret, i, ctrl_id; struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node; struct mtk_thermal *mt; - struct resource *res; u64 auxadc_phys_base, apmixed_phys_base; struct thermal_zone_device *tzdev; void __iomem *apmixed_base, *auxadc_base; @@ -1009,8 +1008,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) if (IS_ERR(mt->clk_auxadc)) return PTR_ERR(mt->clk_auxadc); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mt->thermal_base = devm_ioremap_resource(&pdev->dev, res); + mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(mt->thermal_base)) return PTR_ERR(mt->thermal_base); -- cgit v1.2.3 From 2484b632ac994b4b83b2fb817f9a3b8d4a9e0beb Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:39:30 +0800 Subject: thermal/drivers/rockchip: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Link: https://lore.kernel.org/r/202301181639300333679@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/rockchip_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index e567d80a889b..4b7c43f34d1a 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -1354,7 +1354,6 @@ static int rockchip_thermal_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct rockchip_thermal_data *thermal; const struct of_device_id *match; - struct resource *res; int irq; int i; int error; @@ -1378,8 +1377,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev) if (!thermal->chip) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - thermal->regs = devm_ioremap_resource(&pdev->dev, res); + thermal->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(thermal->regs)) return PTR_ERR(thermal->regs); -- cgit v1.2.3 From c818c6d15d3693428fa7223f21d423e39dbc33b1 Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:41:19 +0800 Subject: thermal/drivers/thermal_mmio: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Link: https://lore.kernel.org/r/202301181641194943741@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/thermal_mmio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_mmio.c b/drivers/thermal/thermal_mmio.c index 39c921415989..ea616731066c 100644 --- a/drivers/thermal/thermal_mmio.c +++ b/drivers/thermal/thermal_mmio.c @@ -39,7 +39,6 @@ static const struct thermal_zone_device_ops thermal_mmio_ops = { static int thermal_mmio_probe(struct platform_device *pdev) { - struct resource *resource; struct thermal_mmio *sensor; int (*sensor_init_func)(struct platform_device *pdev, struct thermal_mmio *sensor); @@ -51,8 +50,7 @@ static int thermal_mmio_probe(struct platform_device *pdev) if (!sensor) return -ENOMEM; - resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource); + sensor->mmio_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(sensor->mmio_base)) return PTR_ERR(sensor->mmio_base); -- cgit v1.2.3 From 821e43097966a190a0714b15cd8fdc1d202e5c21 Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:42:41 +0800 Subject: thermal/drivers/kirkwood: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Link: https://lore.kernel.org/r/202301181642412733780@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/kirkwood_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c index 7fb6e476c82a..bec7ec20e79d 100644 --- a/drivers/thermal/kirkwood_thermal.c +++ b/drivers/thermal/kirkwood_thermal.c @@ -64,15 +64,13 @@ static int kirkwood_thermal_probe(struct platform_device *pdev) { struct thermal_zone_device *thermal = NULL; struct kirkwood_thermal_priv *priv; - struct resource *res; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->sensor = devm_ioremap_resource(&pdev->dev, res); + priv->sensor = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(priv->sensor)) return PTR_ERR(priv->sensor); -- cgit v1.2.3 From f8887fdcf2a7da2d05de95a81ec35571f2323c2e Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Wed, 18 Jan 2023 16:44:43 +0800 Subject: thermal/drivers/spear: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: ye xingchen Link: https://lore.kernel.org/r/202301181644433003839@zte.com.cn Signed-off-by: Daniel Lezcano --- drivers/thermal/spear_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c index ee33ed692e4f..6a722b10d738 100644 --- a/drivers/thermal/spear_thermal.c +++ b/drivers/thermal/spear_thermal.c @@ -91,7 +91,6 @@ static int spear_thermal_probe(struct platform_device *pdev) struct thermal_zone_device *spear_thermal = NULL; struct spear_thermal_dev *stdev; struct device_node *np = pdev->dev.of_node; - struct resource *res; int ret = 0, val; if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) { @@ -104,8 +103,7 @@ static int spear_thermal_probe(struct platform_device *pdev) return -ENOMEM; /* Enable thermal sensor */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - stdev->thermal_base = devm_ioremap_resource(&pdev->dev, res); + stdev->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(stdev->thermal_base)) return PTR_ERR(stdev->thermal_base); -- cgit v1.2.3 From d69e7041a39c24de8c935b82c1edae6490be5b4d Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Mon, 23 Jan 2023 18:23:19 +0800 Subject: thermal/drivers/sun8i: Convert to use macro Use TEMP_CALIB_MASK macro instead of raw number. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230123102319.37710-1-frank.li@vivo.com Signed-off-by: Daniel Lezcano --- drivers/thermal/sun8i_thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index e64d06d1328c..497beac63e5d 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -210,7 +210,7 @@ static int sun8i_h3_ths_calibrate(struct ths_device *tmdev, regmap_update_bits(tmdev->regmap, SUN8I_THS_TEMP_CALIB + (4 * (i >> 1)), - 0xfff << offset, + TEMP_CALIB_MASK << offset, caldata[i] << offset); } @@ -271,7 +271,7 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev, offset = (i % 2) * 16; regmap_update_bits(tmdev->regmap, SUN50I_H6_THS_TEMP_CALIB + (i / 2 * 4), - 0xfff << offset, + TEMP_CALIB_MASK << offset, cdata << offset); } -- cgit v1.2.3 From 4f2ee0aa2e70622e01c06686a967a4dab6fb7f05 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Wed, 18 Jan 2023 15:40:39 +0000 Subject: thermal/drivers/mtk: Use function pointer for raw_to_mcelsius Instead of having if-else logic selecting either raw_to_mcelsius_v1 or raw_to_mcelsius_v2 in mtk_thermal_bank_temperature introduce a function pointer raw_to_mcelsius to struct mtk_thermal which is initialized in the probe function. Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Daniel Golle Reviewed-by: Matthias Brugger Link: https://lore.kernel.org/r/69c17529e8418da3eec703dde31e1b01e5b0f7e8.1674055882.git.daniel@makrotopia.org Signed-off-by: Daniel Lezcano --- drivers/thermal/mtk_thermal.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 9a8b107900e9..a200b7c0f928 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -292,6 +292,8 @@ struct mtk_thermal { const struct mtk_thermal_data *conf; struct mtk_thermal_bank banks[MAX_NUM_ZONES]; + + int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw); }; /* MT8183 thermal sensor data */ @@ -656,13 +658,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) { raw = readl(mt->thermal_base + conf->msr[i]); - if (mt->conf->version == MTK_THERMAL_V1) { - temp = raw_to_mcelsius_v1( - mt, conf->bank_data[bank->id].sensors[i], raw); - } else { - temp = raw_to_mcelsius_v2( - mt, conf->bank_data[bank->id].sensors[i], raw); - } + temp = mt->raw_to_mcelsius( + mt, conf->bank_data[bank->id].sensors[i], raw); + /* * The first read of a sensor often contains very high bogus @@ -1073,6 +1071,11 @@ static int mtk_thermal_probe(struct platform_device *pdev) mtk_thermal_release_periodic_ts(mt, auxadc_base); } + if (mt->conf->version == MTK_THERMAL_V1) + mt->raw_to_mcelsius = raw_to_mcelsius_v1; + else + mt->raw_to_mcelsius = raw_to_mcelsius_v2; + for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++) for (i = 0; i < mt->conf->num_banks; i++) mtk_thermal_init_bank(mt, i, apmixed_phys_base, -- cgit v1.2.3 From 248da1fc8418c732e98726fe570d4db01385562d Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Wed, 18 Jan 2023 15:40:58 +0000 Subject: thermal/drivers/mtk: Add support for MT7986 and MT7981 Add support for V3 generation thermal found in MT7986 and MT7981 SoCs. Brings code to assign values from efuse as well as new function to convert raw temperature to millidegree celsius, as found in MediaTek's SDK sources (but cleaned up and de-duplicated) [1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/baf36c7eef477aae1f8f2653b6c29e2caf48475b Signed-off-by: Daniel Golle Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/2d341fc45266217249586eb4bd3be3ac4ca83a12.1674055882.git.daniel@makrotopia.org Signed-off-by: Daniel Lezcano --- drivers/thermal/mtk_thermal.c | 128 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 4 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index a200b7c0f928..3c633584a88e 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -150,6 +150,20 @@ #define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1) #define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1) +/* + * Layout of the fuses providing the calibration data + * These macros can be used for MT7981 and MT7986. + */ +#define CALIB_BUF0_ADC_GE_V3(x) (((x) >> 0) & 0x3ff) +#define CALIB_BUF0_DEGC_CALI_V3(x) (((x) >> 20) & 0x3f) +#define CALIB_BUF0_O_SLOPE_V3(x) (((x) >> 26) & 0x3f) +#define CALIB_BUF1_VTS_TS1_V3(x) (((x) >> 0) & 0x1ff) +#define CALIB_BUF1_VTS_TS2_V3(x) (((x) >> 21) & 0x1ff) +#define CALIB_BUF1_VTS_TSABB_V3(x) (((x) >> 9) & 0x1ff) +#define CALIB_BUF1_VALID_V3(x) (((x) >> 18) & 0x1) +#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1) +#define CALIB_BUF1_ID_V3(x) (((x) >> 20) & 0x1) + enum { VTS1, VTS2, @@ -163,6 +177,7 @@ enum { enum mtk_thermal_version { MTK_THERMAL_V1 = 1, MTK_THERMAL_V2, + MTK_THERMAL_V3, }; /* MT2701 thermal sensors */ @@ -245,6 +260,27 @@ enum mtk_thermal_version { /* The calibration coefficient of sensor */ #define MT8183_CALIBRATION 153 +/* AUXADC channel 11 is used for the temperature sensors */ +#define MT7986_TEMP_AUXADC_CHANNEL 11 + +/* The total number of temperature sensors in the MT7986 */ +#define MT7986_NUM_SENSORS 1 + +/* The number of banks in the MT7986 */ +#define MT7986_NUM_ZONES 1 + +/* The number of sensing points per bank */ +#define MT7986_NUM_SENSORS_PER_ZONE 1 + +/* MT7986 thermal sensors */ +#define MT7986_TS1 0 + +/* The number of controller in the MT7986 */ +#define MT7986_NUM_CONTROLLER 1 + +/* The calibration coefficient of sensor */ +#define MT7986_CALIBRATION 165 + struct mtk_thermal; struct thermal_bank_cfg { @@ -388,6 +424,14 @@ static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, }; static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 }; static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, }; +/* MT7986 thermal sensor data */ +static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, }; +static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, }; +static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, }; +static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, }; +static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 }; +static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, }; + /* * The MT8173 thermal controller has four banks. Each bank can read up to * four temperature sensors simultaneously. The MT8173 has a total of 5 @@ -551,6 +595,30 @@ static const struct mtk_thermal_data mt8183_thermal_data = { .version = MTK_THERMAL_V1, }; +/* + * MT7986 uses AUXADC Channel 11 for raw data access. + */ +static const struct mtk_thermal_data mt7986_thermal_data = { + .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL, + .num_banks = MT7986_NUM_ZONES, + .num_sensors = MT7986_NUM_SENSORS, + .vts_index = mt7986_vts_index, + .cali_val = MT7986_CALIBRATION, + .num_controller = MT7986_NUM_CONTROLLER, + .controller_offset = mt7986_tc_offset, + .need_switch_bank = true, + .bank_data = { + { + .num_sensors = 1, + .sensors = mt7986_bank_data, + }, + }, + .msr = mt7986_msr, + .adcpnp = mt7986_adcpnp, + .sensor_mux_values = mt7986_mux_values, + .version = MTK_THERMAL_V3, +}; + /** * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius * @mt: The thermal controller @@ -605,6 +673,22 @@ static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw) return (format_2 - tmp) * 100; } +static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw) +{ + s32 tmp; + + if (raw == 0) + return 0; + + raw &= 0xfff; + tmp = 100000 * 15 / 16 * 10000; + tmp /= 4096 - 512 + mt->adc_ge; + tmp /= 1490; + tmp *= raw - mt->vts[sensno] - 2900; + + return mt->degc_cali * 500 - tmp; +} + /** * mtk_thermal_get_bank - get bank * @bank: The bank @@ -885,6 +969,25 @@ static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf) return 0; } +static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf) +{ + if (!CALIB_BUF1_VALID_V3(buf[1])) + return -EINVAL; + + mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]); + mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]); + mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]); + mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]); + mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]); + mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]); + mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]); + + if (CALIB_BUF1_ID_V3(buf[1]) == 0) + mt->o_slope = 0; + + return 0; +} + static int mtk_thermal_get_calibration_data(struct device *dev, struct mtk_thermal *mt) { @@ -895,6 +998,7 @@ static int mtk_thermal_get_calibration_data(struct device *dev, /* Start with default values */ mt->adc_ge = 512; + mt->adc_oe = 512; for (i = 0; i < mt->conf->num_sensors; i++) mt->vts[i] = 260; mt->degc_cali = 40; @@ -920,10 +1024,20 @@ static int mtk_thermal_get_calibration_data(struct device *dev, goto out; } - if (mt->conf->version == MTK_THERMAL_V1) + switch (mt->conf->version) { + case MTK_THERMAL_V1: ret = mtk_thermal_extract_efuse_v1(mt, buf); - else + break; + case MTK_THERMAL_V2: ret = mtk_thermal_extract_efuse_v2(mt, buf); + break; + case MTK_THERMAL_V3: + ret = mtk_thermal_extract_efuse_v3(mt, buf); + break; + default: + ret = -EINVAL; + break; + } if (ret) { dev_info(dev, "Device not calibrated, using default calibration values\n"); @@ -953,6 +1067,10 @@ static const struct of_device_id mtk_thermal_of_match[] = { .compatible = "mediatek,mt7622-thermal", .data = (void *)&mt7622_thermal_data, }, + { + .compatible = "mediatek,mt7986-thermal", + .data = (void *)&mt7986_thermal_data, + }, { .compatible = "mediatek,mt8183-thermal", .data = (void *)&mt8183_thermal_data, @@ -1066,15 +1184,17 @@ static int mtk_thermal_probe(struct platform_device *pdev) goto err_disable_clk_auxadc; } - if (mt->conf->version == MTK_THERMAL_V2) { + if (mt->conf->version != MTK_THERMAL_V1) { mtk_thermal_turn_on_buffer(apmixed_base); mtk_thermal_release_periodic_ts(mt, auxadc_base); } if (mt->conf->version == MTK_THERMAL_V1) mt->raw_to_mcelsius = raw_to_mcelsius_v1; - else + else if (mt->conf->version == MTK_THERMAL_V2) mt->raw_to_mcelsius = raw_to_mcelsius_v2; + else + mt->raw_to_mcelsius = raw_to_mcelsius_v3; for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++) for (i = 0; i < mt->conf->num_banks; i++) -- cgit v1.2.3 From 8c5ee9155f8ae133070b40ee4be03cafb35c188d Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 18 Jan 2023 23:26:10 +0100 Subject: thermal/drivers/armada: Use the thermal_zone_get_crit_temp() The driver browses the trip point to find out the critical trip temperature. However the function thermal_zone_get_crit_temp() does already that, so the routine is pointless in the driver. Use thermal_zone_get_crit_temp() instead of inspecting all the trip points. In addition, the hysteresis value is set to zero. A critical trip point does not have a hysteresis. Signed-off-by: Daniel Lezcano Reviewed-by: Miquel Raynal Link: https://lore.kernel.org/r/20230118222610.186088-1-daniel.lezcano@linaro.org --- drivers/thermal/armada_thermal.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 7d2682e8ef96..99e86484a55c 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -782,34 +782,26 @@ static int armada_configure_overheat_int(struct armada_thermal_priv *priv, int sensor_id) { /* Retrieve the critical trip point to enable the overheat interrupt */ - struct thermal_trip trip; + int temperature; int ret; - int i; - - for (i = 0; i < thermal_zone_get_num_trips(tz); i++) { - - ret = thermal_zone_get_trip(tz, i, &trip); - if (ret) - return ret; - - if (trip.type != THERMAL_TRIP_CRITICAL) - continue; - - ret = armada_select_channel(priv, sensor_id); - if (ret) - return ret; - armada_set_overheat_thresholds(priv, trip.temperature, - trip.hysteresis); - priv->overheat_sensor = tz; - priv->interrupt_source = sensor_id; + ret = thermal_zone_get_crit_temp(tz, &temperature); + if (ret) + return ret; - armada_enable_overheat_interrupt(priv); + ret = armada_select_channel(priv, sensor_id); + if (ret) + return ret; - return 0; - } + /* + * A critical temperature does not have a hysteresis + */ + armada_set_overheat_thresholds(priv, temperature, 0); + priv->overheat_sensor = tz; + priv->interrupt_source = sensor_id; + armada_enable_overheat_interrupt(priv); - return -EINVAL; + return 0; } static int armada_thermal_probe(struct platform_device *pdev) -- cgit v1.2.3