diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2023-01-24 21:12:49 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2023-01-24 21:12:49 +0100 |
commit | 8ef0ca4a177d2dbe6680fb4388173897900a4ed1 (patch) | |
tree | c67b1e358f50bce724b61b43be885f90a229fad1 /drivers/thermal | |
parent | thermal: int340x_thermal: Use sysfs_emit_at() instead of scnprintf() (diff) | |
parent | Merge back thermal control material for 6.3. (diff) | |
download | linux-8ef0ca4a177d2dbe6680fb4388173897900a4ed1.tar.xz linux-8ef0ca4a177d2dbe6680fb4388173897900a4ed1.zip |
Merge back other thermal control material for 6.3.
* thermal: (734 commits)
thermal: core: call put_device() only after device_register() fails
Linux 6.2-rc4
kbuild: Fix CFI hash randomization with KASAN
firmware: coreboot: Check size of table entry and use flex-array
kallsyms: Fix scheduling with interrupts disabled in self-test
ata: pata_cs5535: Don't build on UML
lockref: stop doing cpu_relax in the cmpxchg loop
x86/pci: Treat EfiMemoryMappedIO as reservation of ECAM space
efi: tpm: Avoid READ_ONCE() for accessing the event log
io_uring: lock overflowing for IOPOLL
ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF
iommu/mediatek-v1: Fix an error handling path in mtk_iommu_v1_probe()
iommu/iova: Fix alloc iova overflows issue
iommu: Fix refcount leak in iommu_device_claim_dma_owner
iommu/arm-smmu-v3: Don't unregister on shutdown
iommu/arm-smmu: Don't unregister on shutdown
iommu/arm-smmu: Report IOMMU_CAP_CACHE_COHERENCY even betterer
platform/x86: thinkpad_acpi: Fix profile mode display in AMT mode
ALSA: usb-audio: Fix possible NULL pointer dereference in snd_usb_pcm_has_fixed_rate()
platform/x86: int3472/discrete: Ensure the clk/power enable pins are in output mode
...
Diffstat (limited to 'drivers/thermal')
28 files changed, 526 insertions, 755 deletions
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 52d63b3997fe..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 { @@ -785,33 +784,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) 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 <linux/platform_device.h> #include <linux/thermal.h> +#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; 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); 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); 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; } } 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); 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 a2ea22f2bffd..a1dc18be7609 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -130,10 +130,6 @@ static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, return 0; } -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; @@ -208,7 +204,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); @@ -226,10 +222,10 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) if (ACPI_FAILURE(status)) { /* there is no _TMP method, add local method */ if (intel_tcc_get_tjmax(-1) > 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 diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index 9e08d8c8f5fb..1c2de84742df 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; }; @@ -118,45 +119,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) return 0; } -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 tj_max, 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; - } - - tj_max = intel_tcc_get_tjmax(zonedev->cpu); - if (tj_max < 0) - return tj_max; - tj_max *= 1000; - - 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 = 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) { @@ -202,18 +164,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, }; @@ -313,12 +266,55 @@ 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); u32 eax, ebx, ecx, edx; struct zone_device *zonedev; int thres_count, err; + int tj_max; if (id >= max_id) return -ENOMEM; @@ -330,31 +326,34 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS); - err = intel_tcc_get_tjmax(cpu); - if (err < 0) - return err; + tj_max = intel_tcc_get_tjmax(cpu); + if (tj_max < 0) + return tj_max; zonedev = kzalloc(sizeof(*zonedev), GFP_KERNEL); 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->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); @@ -363,7 +362,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) @@ -447,8 +455,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; } diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index ad84978109e6..e2429676d0d2 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; @@ -353,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; 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; 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); diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 51874d0a284c..37465af59262 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -260,31 +260,23 @@ 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); + int num_trips = thermal_zone_get_num_trips(tzd); unsigned int status; - int ret = 0, temp, hyst; + int ret = 0, temp; - if (!trips) { - dev_err(&pdev->dev, - "Cannot get trip points from device tree!\n"); - return -ENODEV; - } - - 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; } - 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); @@ -297,25 +289,22 @@ 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); /* 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 */ @@ -562,13 +553,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 |= @@ -592,13 +584,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 |= @@ -623,13 +616,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 |= 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); diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 1efe470f31e9..220873298d77 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; } } @@ -747,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); 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 */ diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index f17ab2316dbd..c686da8b4c68 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) @@ -909,15 +905,20 @@ __thermal_cooling_device_register(struct device_node *np, cdev->devdata = devdata; ret = cdev->ops->get_max_state(cdev, &cdev->max_state); - if (ret) - goto out_kfree_type; + if (ret) { + kfree(cdev->type); + goto out_ida_remove; + } thermal_cooling_device_setup_sysfs(cdev); + ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id); if (ret) { + kfree(cdev->type); thermal_cooling_device_destroy_sysfs(cdev); - goto out_kfree_type; + goto out_ida_remove; } + ret = device_register(&cdev->device); if (ret) goto out_kfree_type; @@ -943,6 +944,8 @@ out_kfree_type: thermal_cooling_device_destroy_sysfs(cdev); kfree(cdev->type); put_device(&cdev->device); + + /* thermal_release() takes care of the rest */ cdev = NULL; out_ida_remove: ida_free(&thermal_cdev_ida, id); @@ -1159,6 +1162,119 @@ 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); +} +EXPORT_SYMBOL_GPL(__thermal_zone_get_trip); + +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); + +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 @@ -1191,8 +1307,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 +1346,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 +1397,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..26350206a98d 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 */ @@ -137,28 +139,6 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, #endif /* CONFIG_THERMAL_STATISTICS */ /* 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); -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) -{ - return 0; -} -static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, - int trip) -{ - 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); #endif /* __THERMAL_CORE_H__ */ 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_of.c b/drivers/thermal/thermal_of.c index aacba30bc10c..ff4d12ef51bc 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -19,117 +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 - * - * @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); - -/** - * 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_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) -{ - 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) -{ - 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) @@ -628,11 +517,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; of_ops->unbind = thermal_of_unbind; diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index d97f0bc0a26b..cef860deaf91 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,10 @@ 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; - - if (!tz->ops->set_trip_temp && !tz->trips) - return -EPERM; - - if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1) - return -EINVAL; + struct thermal_trip trip; + int trip_id, ret; - if (kstrtoint(buf, 10, &temperature)) + if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) return -EINVAL; mutex_lock(&tz->lock); @@ -142,36 +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, 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; - } - - 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_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 @@ -179,19 +153,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; - - if (!tz->ops->get_trip_temp) - return -EPERM; + struct thermal_trip trip; + int trip_id, ret; - 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 +171,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 @@ -208,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); @@ -227,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); @@ -248,25 +211,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; - - if (!tz->ops->get_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; 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 @@ -491,23 +451,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; } @@ -540,9 +497,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); @@ -579,8 +533,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); } 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); 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) { |