summaryrefslogtreecommitdiff
path: root/drivers/thermal
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2023-01-27 17:55:23 +0300
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2023-01-27 17:55:23 +0300
commit79b2027097dd3046ff95a2701af441405f1ff298 (patch)
tree5db999f6a71d652b2e3a64150ab96a987d38421f /drivers/thermal
parentacd7e9ee57c880b99671dd99680cb707b7b5b0ee (diff)
parent02be605946b64df6d328811eb2488f7a245a5206 (diff)
downloadlinux-79b2027097dd3046ff95a2701af441405f1ff298.tar.xz
Merge back thermal control material for 6.3.
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/armada_thermal.c30
-rw-r--r--drivers/thermal/broadcom/bcm2835_thermal.c12
-rw-r--r--drivers/thermal/broadcom/brcmstb_thermal.c4
-rw-r--r--drivers/thermal/da9062-thermal.c52
-rw-r--r--drivers/thermal/dove_thermal.c7
-rw-r--r--drivers/thermal/gov_bang_bang.c37
-rw-r--r--drivers/thermal/gov_fair_share.c18
-rw-r--r--drivers/thermal/gov_power_allocator.c51
-rw-r--r--drivers/thermal/gov_step_wise.c22
-rw-r--r--drivers/thermal/hisi_thermal.c11
-rw-r--r--drivers/thermal/imx_sc_thermal.c8
-rw-r--r--drivers/thermal/imx_thermal.c72
-rw-r--r--drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c33
-rw-r--r--drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h4
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_device.c10
-rw-r--r--drivers/thermal/intel/x86_pkg_temp_thermal.c120
-rw-r--r--drivers/thermal/kirkwood_thermal.c4
-rw-r--r--drivers/thermal/mtk_thermal.c149
-rw-r--r--drivers/thermal/qcom/qcom-spmi-adc-tm5.c3
-rw-r--r--drivers/thermal/qcom/qcom-spmi-temp-alarm.c44
-rw-r--r--drivers/thermal/qcom/tsens-v0_1.c655
-rw-r--r--drivers/thermal/qcom/tsens-v1.c340
-rw-r--r--drivers/thermal/qcom/tsens.c219
-rw-r--r--drivers/thermal/qcom/tsens.h46
-rw-r--r--drivers/thermal/rcar_gen3_thermal.c2
-rw-r--r--drivers/thermal/rcar_thermal.c53
-rw-r--r--drivers/thermal/rockchip_thermal.c10
-rw-r--r--drivers/thermal/samsung/exynos_tmu.c62
-rw-r--r--drivers/thermal/spear_thermal.c4
-rw-r--r--drivers/thermal/st/st_thermal.c47
-rw-r--r--drivers/thermal/sun8i_thermal.c4
-rw-r--r--drivers/thermal/tegra/soctherm.c35
-rw-r--r--drivers/thermal/tegra/tegra30-tsensor.c17
-rw-r--r--drivers/thermal/thermal_core.c154
-rw-r--r--drivers/thermal/thermal_core.h24
-rw-r--r--drivers/thermal/thermal_helpers.c28
-rw-r--r--drivers/thermal/thermal_mmio.c4
-rw-r--r--drivers/thermal/thermal_netlink.c19
-rw-r--r--drivers/thermal/thermal_of.c116
-rw-r--r--drivers/thermal/thermal_sysfs.c135
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-thermal.h15
-rw-r--r--drivers/thermal/uniphier_thermal.c29
42 files changed, 1142 insertions, 1567 deletions
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 52d63b3997fe..99e86484a55c 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);
@@ -761,8 +759,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,30 +782,23 @@ 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);
+ int temperature;
int ret;
- int i;
-
- if (!trips)
- return -EINVAL;
-
- for (i = 0; i < of_thermal_get_ntrips(tz); i++)
- if (trips[i].type == THERMAL_TRIP_CRITICAL)
- break;
- if (i == of_thermal_get_ntrips(tz))
- return -EINVAL;
+ ret = thermal_zone_get_crit_temp(tz, &temperature);
+ 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);
+ /*
+ * 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 0;
diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c
index 2c67841a1115..3d0710c6e004 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
@@ -166,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;
@@ -180,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;
@@ -224,7 +223,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 +232,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 +249,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/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);
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/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);
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_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c
index 4df925e3a80b..378f574607f7 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,11 @@ 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,
+ 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 },
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 0a4eaa307156..40c1e8a8bc1b 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, ret = 0;
- if (d->override_ops && d->override_ops->get_trip_temp)
- return d->override_ops->get_trip_temp(zone, trip, temp);
-
mutex_lock(&d->trip_mutex);
if (trip < d->aux_trip_nr)
@@ -83,9 +77,6 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone,
struct int34x_thermal_zone *d = zone->devdata;
int i, ret = 0;
- if (d->override_ops && d->override_ops->get_trip_type)
- return d->override_ops->get_trip_type(zone, trip, type);
-
mutex_lock(&d->trip_mutex);
if (trip < d->aux_trip_nr)
@@ -120,9 +111,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));
@@ -142,9 +130,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;
@@ -229,7 +214,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;
@@ -245,7 +230,16 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
mutex_init(&int34x_thermal_zone->trip_mutex);
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))
@@ -276,7 +270,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)) {
@@ -295,6 +289,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:
mutex_destroy(&int34x_thermal_zone->trip_mutex);
kfree(int34x_thermal_zone);
return ERR_PTR(ret);
@@ -307,6 +303,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);
mutex_destroy(&int34x_thermal_zone->trip_mutex);
kfree(int34x_thermal_zone);
}
diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
index 8f9872afd0d3..6610a9cc441b 100644
--- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
+++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
@@ -29,14 +29,14 @@ 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 mutex trip_mutex;
};
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
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;
}
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);
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index 8440692e3890..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 {
@@ -292,6 +328,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 */
@@ -386,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
@@ -549,8 +595,32 @@ 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 - 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
@@ -603,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
@@ -656,13 +742,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
@@ -887,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)
{
@@ -897,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;
@@ -922,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");
@@ -956,6 +1068,10 @@ static const struct of_device_id mtk_thermal_of_match[] = {
.data = (void *)&mt7622_thermal_data,
},
{
+ .compatible = "mediatek,mt7986-thermal",
+ .data = (void *)&mt7986_thermal_data,
+ },
+ {
.compatible = "mediatek,mt8183-thermal",
.data = (void *)&mt8183_thermal_data,
}, {
@@ -990,7 +1106,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 +1124,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);
@@ -1070,11 +1184,18 @@ 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 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++)
mtk_thermal_init_bank(mt, i, apmixed_phys_base,
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 <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/thermal.h>
-#include <asm-generic/unaligned.h>
+
+#include <asm/unaligned.h>
#include "../thermal_hwmon.h"
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/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index 04d012e4f728..e89c6f39a3ae 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -3,6 +3,8 @@
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
*/
+#include <linux/bitfield.h>
+#include <linux/nvmem-consumer.h>
#include <linux/platform_device.h>
#include "tsens.h"
@@ -15,220 +17,117 @@
#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 mode, ret;
+
+ ret = tsens_calibrate_nvmem(priv, 3);
+ if (!ret)
+ return 0;
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
if (IS_ERR(qfprom_cdata))
@@ -240,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);
@@ -279,83 +150,68 @@ static int calibrate_8916(struct tsens_priv *priv)
return 0;
}
-static int calibrate_8939(struct tsens_priv *priv)
+static void fixup_8974_points(int mode, u32 *p1, u32 *p2)
{
- int base0 = 0, base1 = 0, i;
- u32 p1[10], p2[10];
- int mode = 0;
- u32 *qfprom_cdata;
- u32 cdata[6];
-
- qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
- 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];
- 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);
-
- 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;
- 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;
- 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;
- 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;
- default:
- for (i = 0; i < priv->num_sensors; i++) {
- p1[i] = 500;
- p2[i] = 780;
+ int i;
+
+ 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 < 11; i++) {
+ /*
+ * ONE_PT_CALIB requires using addition here instead of
+ * using OR operation.
+ */
+ p1[i] += BIT_APPEND;
+ p2[i] += BIT_APPEND;
}
- break;
}
+}
+
+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);
- kfree(qfprom_cdata);
return 0;
}
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 mode, ret;
+
+ ret = calibrate_8974_nvmem(priv);
+ if (ret == 0)
+ return 0;
calib = (u32 *)qfprom_read(priv->dev, "calib");
if (IS_ERR(calib))
@@ -367,116 +223,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);
@@ -485,53 +243,19 @@ static int calibrate_8974(struct tsens_priv *priv)
return 0;
}
-static int calibrate_9607(struct tsens_priv *priv)
-{
- int base, i;
- u32 p1[5], p2[5];
- int mode = 0;
- u32 *qfprom_cdata;
-
- qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
- 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;
- }
-
- 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;
+ 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 */
@@ -583,6 +307,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,
@@ -599,15 +329,15 @@ struct tsens_plat_data data_8916 = {
};
static const struct tsens_ops ops_8939 = {
- .init = init_common,
- .calibrate = calibrate_8939,
+ .init = init_8939,
+ .calibrate = tsens_calibrate_common,
.get_temp = get_temp_common,
};
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,
@@ -626,16 +356,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,
- .hw_ids = (unsigned int []){ 0, 1, 2, 3, 4 },
+ .ops = &ops_v0_1,
.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..b822a426066d 100644
--- a/drivers/thermal/qcom/tsens-v1.c
+++ b/drivers/thermal/qcom/tsens-v1.c
@@ -21,277 +21,68 @@
#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
-
-#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
-#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
-
-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;
+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 } },
+ },
+};
- for (i = 0; i < priv->num_sensors; i++) {
- priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) -
- (MSM8976_CAL_DEGC_PT1 *
- priv->sensor[i].slope);
- }
-}
+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;
-
- qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
- 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);
+ int mode, ret;
- 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;
- }
-
- compute_intercept_slope(priv, p1, p2, mode);
- kfree(qfprom_cdata);
-
- return 0;
-}
-
-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;
+ 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 = (qfprom_cdata[4] & MSM8976_CAL_SEL_MASK);
- dev_dbg(priv->dev, "calibration mode is %d\n", mode);
+ mode = tsens_read_calibration_legacy(priv, &tsens_qcs404_nvmem,
+ p1, p2,
+ qfprom_cdata, NULL);
- 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;
- }
-
- compute_intercept_slope_8976(priv, p1, p2, mode);
+ compute_intercept_slope(priv, p1, p2, mode);
kfree(qfprom_cdata);
return 0;
@@ -365,6 +156,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,
@@ -377,17 +184,28 @@ struct tsens_plat_data data_tsens_v1 = {
.fields = tsens_v1_regfields,
};
+static const struct tsens_ops ops_8956 = {
+ .init = init_8956,
+ .calibrate = tsens_calibrate_common,
+ .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,
+ .calibrate = tsens_calibrate_common,
.get_temp = get_temp_tsens_valid,
};
-/* Valid for both MSM8956 and MSM8976. */
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,
};
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index b5b136ff323f..8020ead2794e 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -70,6 +70,171 @@ char *qfprom_read(struct device *dev, const char *cname)
return ret;
}
+int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup)
+{
+ u32 mode;
+ u32 base1, base2;
+ char name[] = "sXX_pY_backup"; /* s10_p1_backup */
+ int i, ret;
+
+ if (priv->num_sensors > MAX_SENSORS)
+ return -EINVAL;
+
+ 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)
+ return ret;
+
+ dev_dbg(priv->dev, "calibration mode is %d\n", mode);
+
+ 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, name, &base2);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < priv->num_sensors; i++) {
+ ret = snprintf(name, sizeof(name), "s%d_p1%s", priv->sensor[i].hw_id,
+ backup ? "_backup" : "");
+ 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%s", priv->sensor[i].hw_id,
+ backup ? "_backup" : "");
+ 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;
+ }
+ }
+
+ 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;
+}
+
+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
@@ -459,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;
@@ -472,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
@@ -984,6 +1102,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..dba9cd38f637 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 <linux/interrupt.h>
#include <linux/thermal.h>
#include <linux/regmap.h>
@@ -581,7 +584,48 @@ 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);
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);
@@ -594,7 +638,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;
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/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 819e059cde71..4b7c43f34d1a 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)
@@ -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);
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/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);
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/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);
}
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 77bd47d976a2..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)
@@ -1166,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
@@ -1198,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;
@@ -1239,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);
@@ -1290,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_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);
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..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.
@@ -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) {