提交 79b20270 编写于 作者: R Rafael J. Wysocki

Merge back thermal control material for 6.3.

...@@ -13,6 +13,7 @@ properties: ...@@ -13,6 +13,7 @@ properties:
enum: enum:
- qcom,spmi-adc-tm5 - qcom,spmi-adc-tm5
- qcom,spmi-adc-tm5-gen2 - qcom,spmi-adc-tm5-gen2
- qcom,adc-tm7 # Incomplete / subject to change
reg: reg:
maxItems: 1 maxItems: 1
......
...@@ -37,6 +37,7 @@ properties: ...@@ -37,6 +37,7 @@ properties:
- description: v1 of TSENS - description: v1 of TSENS
items: items:
- enum: - enum:
- qcom,msm8956-tsens
- qcom,msm8976-tsens - qcom,msm8976-tsens
- qcom,qcs404-tsens - qcom,qcs404-tsens
- const: qcom,tsens-v1 - const: qcom,tsens-v1
...@@ -80,18 +81,120 @@ properties: ...@@ -80,18 +81,120 @@ properties:
maxItems: 2 maxItems: 2
nvmem-cells: nvmem-cells:
minItems: 1 oneOf:
- minItems: 1
maxItems: 2 maxItems: 2
description: description:
Reference to an nvmem node for the calibration data Reference to an nvmem node for the calibration data
- minItems: 5
maxItems: 35
description: |
Reference to nvmem cells for the calibration mode, two calibration
bases and two cells per each sensor
# special case for msm8974 / apq8084
- maxItems: 51
description: |
Reference to nvmem cells for the calibration mode, two calibration
bases and two cells per each sensor, main and backup copies, plus use_backup cell
nvmem-cell-names: nvmem-cell-names:
minItems: 1 oneOf:
- minItems: 1
items: items:
- const: calib - const: calib
- enum: - enum:
- calib_backup - calib_backup
- calib_sel - calib_sel
- minItems: 5
items:
- const: mode
- const: base1
- const: base2
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
- pattern: '^s[0-9]+_p1$'
- pattern: '^s[0-9]+_p2$'
# special case for msm8974 / apq8084
- items:
- const: mode
- const: base1
- const: base2
- const: use_backup
- const: mode_backup
- const: base1_backup
- const: base2_backup
- const: s0_p1
- const: s0_p2
- const: s1_p1
- const: s1_p2
- const: s2_p1
- const: s2_p2
- const: s3_p1
- const: s3_p2
- const: s4_p1
- const: s4_p2
- const: s5_p1
- const: s5_p2
- const: s6_p1
- const: s6_p2
- const: s7_p1
- const: s7_p2
- const: s8_p1
- const: s8_p2
- const: s9_p1
- const: s9_p2
- const: s10_p1
- const: s10_p2
- const: s0_p1_backup
- const: s0_p2_backup
- const: s1_p1_backup
- const: s1_p2_backup
- const: s2_p1_backup
- const: s2_p2_backup
- const: s3_p1_backup
- const: s3_p2_backup
- const: s4_p1_backup
- const: s4_p2_backup
- const: s5_p1_backup
- const: s5_p2_backup
- const: s6_p1_backup
- const: s6_p2_backup
- const: s7_p1_backup
- const: s7_p2_backup
- const: s8_p1_backup
- const: s8_p2_backup
- const: s9_p1_backup
- const: s9_p2_backup
- const: s10_p1_backup
- const: s10_p2_backup
"#qcom,sensors": "#qcom,sensors":
description: description:
...@@ -220,6 +323,36 @@ examples: ...@@ -220,6 +323,36 @@ examples:
}; };
}; };
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
// Example 1 (new calbiration data: for pre v1 IP):
thermal-sensor@900000 {
compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1";
reg = <0x4a9000 0x1000>, /* TM */
<0x4a8000 0x1000>; /* SROT */
nvmem-cells = <&tsens_mode>,
<&tsens_base1>, <&tsens_base2>,
<&tsens_s0_p1>, <&tsens_s0_p2>,
<&tsens_s1_p1>, <&tsens_s1_p2>,
<&tsens_s2_p1>, <&tsens_s2_p2>,
<&tsens_s4_p1>, <&tsens_s4_p2>,
<&tsens_s5_p1>, <&tsens_s5_p2>;
nvmem-cell-names = "mode",
"base1", "base2",
"s0_p1", "s0_p2",
"s1_p1", "s1_p2",
"s2_p1", "s2_p2",
"s4_p1", "s4_p2",
"s5_p1", "s5_p2";
interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uplow";
#qcom,sensors = <5>;
#thermal-sensor-cells = <1>;
};
- | - |
#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/interrupt-controller/arm-gic.h>
// Example 1 (legacy: for pre v1 IP): // Example 1 (legacy: for pre v1 IP):
......
...@@ -1079,8 +1079,6 @@ struct mbox_list { ...@@ -1079,8 +1079,6 @@ struct mbox_list {
#if IS_ENABLED(CONFIG_THERMAL) #if IS_ENABLED(CONFIG_THERMAL)
struct ch_thermal { struct ch_thermal {
struct thermal_zone_device *tzdev; struct thermal_zone_device *tzdev;
int trip_temp;
int trip_type;
}; };
#endif #endif
......
...@@ -29,36 +29,12 @@ static int cxgb4_thermal_get_temp(struct thermal_zone_device *tzdev, ...@@ -29,36 +29,12 @@ static int cxgb4_thermal_get_temp(struct thermal_zone_device *tzdev,
return 0; return 0;
} }
static int cxgb4_thermal_get_trip_type(struct thermal_zone_device *tzdev,
int trip, enum thermal_trip_type *type)
{
struct adapter *adap = tzdev->devdata;
if (!adap->ch_thermal.trip_temp)
return -EINVAL;
*type = adap->ch_thermal.trip_type;
return 0;
}
static int cxgb4_thermal_get_trip_temp(struct thermal_zone_device *tzdev,
int trip, int *temp)
{
struct adapter *adap = tzdev->devdata;
if (!adap->ch_thermal.trip_temp)
return -EINVAL;
*temp = adap->ch_thermal.trip_temp;
return 0;
}
static struct thermal_zone_device_ops cxgb4_thermal_ops = { static struct thermal_zone_device_ops cxgb4_thermal_ops = {
.get_temp = cxgb4_thermal_get_temp, .get_temp = cxgb4_thermal_get_temp,
.get_trip_type = cxgb4_thermal_get_trip_type,
.get_trip_temp = cxgb4_thermal_get_trip_temp,
}; };
static struct thermal_trip trip = { .type = THERMAL_TRIP_CRITICAL } ;
int cxgb4_thermal_init(struct adapter *adap) int cxgb4_thermal_init(struct adapter *adap)
{ {
struct ch_thermal *ch_thermal = &adap->ch_thermal; struct ch_thermal *ch_thermal = &adap->ch_thermal;
...@@ -79,12 +55,11 @@ int cxgb4_thermal_init(struct adapter *adap) ...@@ -79,12 +55,11 @@ int cxgb4_thermal_init(struct adapter *adap)
if (ret < 0) { if (ret < 0) {
num_trip = 0; /* could not get trip temperature */ num_trip = 0; /* could not get trip temperature */
} else { } else {
ch_thermal->trip_temp = val * 1000; trip.temperature = val * 1000;
ch_thermal->trip_type = THERMAL_TRIP_CRITICAL;
} }
snprintf(ch_tz_name, sizeof(ch_tz_name), "cxgb4_%s", adap->name); snprintf(ch_tz_name, sizeof(ch_tz_name), "cxgb4_%s", adap->name);
ch_thermal->tzdev = thermal_zone_device_register(ch_tz_name, num_trip, ch_thermal->tzdev = thermal_zone_device_register_with_trips(ch_tz_name, &trip, num_trip,
0, adap, 0, adap,
&cxgb4_thermal_ops, &cxgb4_thermal_ops,
NULL, 0, 0); NULL, 0, 0);
......
...@@ -36,33 +36,39 @@ enum mlxsw_thermal_trips { ...@@ -36,33 +36,39 @@ enum mlxsw_thermal_trips {
MLXSW_THERMAL_TEMP_TRIP_HOT, MLXSW_THERMAL_TEMP_TRIP_HOT,
}; };
struct mlxsw_thermal_trip { struct mlxsw_cooling_states {
int type;
int temp;
int hyst;
int min_state; int min_state;
int max_state; int max_state;
}; };
static const struct mlxsw_thermal_trip default_thermal_trips[] = { static const struct thermal_trip default_thermal_trips[] = {
{ /* In range - 0-40% PWM */ { /* In range - 0-40% PWM */
.type = THERMAL_TRIP_ACTIVE, .type = THERMAL_TRIP_ACTIVE,
.temp = MLXSW_THERMAL_ASIC_TEMP_NORM, .temperature = MLXSW_THERMAL_ASIC_TEMP_NORM,
.hyst = MLXSW_THERMAL_HYSTERESIS_TEMP, .hysteresis = MLXSW_THERMAL_HYSTERESIS_TEMP,
.min_state = 0,
.max_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
}, },
{ {
/* In range - 40-100% PWM */ /* In range - 40-100% PWM */
.type = THERMAL_TRIP_ACTIVE, .type = THERMAL_TRIP_ACTIVE,
.temp = MLXSW_THERMAL_ASIC_TEMP_HIGH, .temperature = MLXSW_THERMAL_ASIC_TEMP_HIGH,
.hyst = MLXSW_THERMAL_HYSTERESIS_TEMP, .hysteresis = MLXSW_THERMAL_HYSTERESIS_TEMP,
.min_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
.max_state = MLXSW_THERMAL_MAX_STATE,
}, },
{ /* Warning */ { /* Warning */
.type = THERMAL_TRIP_HOT, .type = THERMAL_TRIP_HOT,
.temp = MLXSW_THERMAL_ASIC_TEMP_HOT, .temperature = MLXSW_THERMAL_ASIC_TEMP_HOT,
},
};
static const struct mlxsw_cooling_states default_cooling_states[] = {
{
.min_state = 0,
.max_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
},
{
.min_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
.max_state = MLXSW_THERMAL_MAX_STATE,
},
{
.min_state = MLXSW_THERMAL_MAX_STATE, .min_state = MLXSW_THERMAL_MAX_STATE,
.max_state = MLXSW_THERMAL_MAX_STATE, .max_state = MLXSW_THERMAL_MAX_STATE,
}, },
...@@ -78,7 +84,8 @@ struct mlxsw_thermal; ...@@ -78,7 +84,8 @@ struct mlxsw_thermal;
struct mlxsw_thermal_module { struct mlxsw_thermal_module {
struct mlxsw_thermal *parent; struct mlxsw_thermal *parent;
struct thermal_zone_device *tzdev; struct thermal_zone_device *tzdev;
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS]; struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
int module; /* Module or gearbox number */ int module; /* Module or gearbox number */
u8 slot_index; u8 slot_index;
}; };
...@@ -99,7 +106,8 @@ struct mlxsw_thermal { ...@@ -99,7 +106,8 @@ struct mlxsw_thermal {
int polling_delay; int polling_delay;
struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX]; struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1]; u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS]; struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
struct mlxsw_thermal_area line_cards[]; struct mlxsw_thermal_area line_cards[];
}; };
...@@ -136,9 +144,9 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal, ...@@ -136,9 +144,9 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
static void static void
mlxsw_thermal_module_trips_reset(struct mlxsw_thermal_module *tz) mlxsw_thermal_module_trips_reset(struct mlxsw_thermal_module *tz)
{ {
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = 0; tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = 0;
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = 0; tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temperature = 0;
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = 0; tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temperature = 0;
} }
static int static int
...@@ -180,12 +188,12 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core, ...@@ -180,12 +188,12 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
* by subtracting double hysteresis value. * by subtracting double hysteresis value.
*/ */
if (crit_temp >= MLXSW_THERMAL_MODULE_TEMP_SHIFT) if (crit_temp >= MLXSW_THERMAL_MODULE_TEMP_SHIFT)
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp - tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = crit_temp -
MLXSW_THERMAL_MODULE_TEMP_SHIFT; MLXSW_THERMAL_MODULE_TEMP_SHIFT;
else else
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp; tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = crit_temp;
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = crit_temp; tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temperature = crit_temp;
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = emerg_temp; tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temperature = emerg_temp;
return 0; return 0;
} }
...@@ -202,11 +210,11 @@ static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev, ...@@ -202,11 +210,11 @@ static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
return 0; return 0;
for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) { for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
const struct mlxsw_thermal_trip *trip = &thermal->trips[i]; const struct mlxsw_cooling_states *state = &thermal->cooling_states[i];
err = thermal_zone_bind_cooling_device(tzdev, i, cdev, err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
trip->max_state, state->max_state,
trip->min_state, state->min_state,
THERMAL_WEIGHT_DEFAULT); THERMAL_WEIGHT_DEFAULT);
if (err < 0) { if (err < 0) {
dev_err(dev, "Failed to bind cooling device to trip %d\n", i); dev_err(dev, "Failed to bind cooling device to trip %d\n", i);
...@@ -260,61 +268,6 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev, ...@@ -260,61 +268,6 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
return 0; return 0;
} }
static int mlxsw_thermal_get_trip_type(struct thermal_zone_device *tzdev,
int trip,
enum thermal_trip_type *p_type)
{
struct mlxsw_thermal *thermal = tzdev->devdata;
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
return -EINVAL;
*p_type = thermal->trips[trip].type;
return 0;
}
static int mlxsw_thermal_get_trip_temp(struct thermal_zone_device *tzdev,
int trip, int *p_temp)
{
struct mlxsw_thermal *thermal = tzdev->devdata;
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
return -EINVAL;
*p_temp = thermal->trips[trip].temp;
return 0;
}
static int mlxsw_thermal_set_trip_temp(struct thermal_zone_device *tzdev,
int trip, int temp)
{
struct mlxsw_thermal *thermal = tzdev->devdata;
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
return -EINVAL;
thermal->trips[trip].temp = temp;
return 0;
}
static int mlxsw_thermal_get_trip_hyst(struct thermal_zone_device *tzdev,
int trip, int *p_hyst)
{
struct mlxsw_thermal *thermal = tzdev->devdata;
*p_hyst = thermal->trips[trip].hyst;
return 0;
}
static int mlxsw_thermal_set_trip_hyst(struct thermal_zone_device *tzdev,
int trip, int hyst)
{
struct mlxsw_thermal *thermal = tzdev->devdata;
thermal->trips[trip].hyst = hyst;
return 0;
}
static struct thermal_zone_params mlxsw_thermal_params = { static struct thermal_zone_params mlxsw_thermal_params = {
.no_hwmon = true, .no_hwmon = true,
}; };
...@@ -323,11 +276,6 @@ static struct thermal_zone_device_ops mlxsw_thermal_ops = { ...@@ -323,11 +276,6 @@ static struct thermal_zone_device_ops mlxsw_thermal_ops = {
.bind = mlxsw_thermal_bind, .bind = mlxsw_thermal_bind,
.unbind = mlxsw_thermal_unbind, .unbind = mlxsw_thermal_unbind,
.get_temp = mlxsw_thermal_get_temp, .get_temp = mlxsw_thermal_get_temp,
.get_trip_type = mlxsw_thermal_get_trip_type,
.get_trip_temp = mlxsw_thermal_get_trip_temp,
.set_trip_temp = mlxsw_thermal_set_trip_temp,
.get_trip_hyst = mlxsw_thermal_get_trip_hyst,
.set_trip_hyst = mlxsw_thermal_set_trip_hyst,
}; };
static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev, static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
...@@ -342,11 +290,11 @@ static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev, ...@@ -342,11 +290,11 @@ static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
return 0; return 0;
for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) { for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
const struct mlxsw_thermal_trip *trip = &tz->trips[i]; const struct mlxsw_cooling_states *state = &tz->cooling_states[i];
err = thermal_zone_bind_cooling_device(tzdev, i, cdev, err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
trip->max_state, state->max_state,
trip->min_state, state->min_state,
THERMAL_WEIGHT_DEFAULT); THERMAL_WEIGHT_DEFAULT);
if (err < 0) if (err < 0)
goto err_thermal_zone_bind_cooling_device; goto err_thermal_zone_bind_cooling_device;
...@@ -434,74 +382,10 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, ...@@ -434,74 +382,10 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
return 0; return 0;
} }
static int
mlxsw_thermal_module_trip_type_get(struct thermal_zone_device *tzdev, int trip,
enum thermal_trip_type *p_type)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
return -EINVAL;
*p_type = tz->trips[trip].type;
return 0;
}
static int
mlxsw_thermal_module_trip_temp_get(struct thermal_zone_device *tzdev,
int trip, int *p_temp)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
return -EINVAL;
*p_temp = tz->trips[trip].temp;
return 0;
}
static int
mlxsw_thermal_module_trip_temp_set(struct thermal_zone_device *tzdev,
int trip, int temp)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
return -EINVAL;
tz->trips[trip].temp = temp;
return 0;
}
static int
mlxsw_thermal_module_trip_hyst_get(struct thermal_zone_device *tzdev, int trip,
int *p_hyst)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
*p_hyst = tz->trips[trip].hyst;
return 0;
}
static int
mlxsw_thermal_module_trip_hyst_set(struct thermal_zone_device *tzdev, int trip,
int hyst)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
tz->trips[trip].hyst = hyst;
return 0;
}
static struct thermal_zone_device_ops mlxsw_thermal_module_ops = { static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
.bind = mlxsw_thermal_module_bind, .bind = mlxsw_thermal_module_bind,
.unbind = mlxsw_thermal_module_unbind, .unbind = mlxsw_thermal_module_unbind,
.get_temp = mlxsw_thermal_module_temp_get, .get_temp = mlxsw_thermal_module_temp_get,
.get_trip_type = mlxsw_thermal_module_trip_type_get,
.get_trip_temp = mlxsw_thermal_module_trip_temp_get,
.set_trip_temp = mlxsw_thermal_module_trip_temp_set,
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
}; };
static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev, static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
...@@ -531,11 +415,6 @@ static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = { ...@@ -531,11 +415,6 @@ static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
.bind = mlxsw_thermal_module_bind, .bind = mlxsw_thermal_module_bind,
.unbind = mlxsw_thermal_module_unbind, .unbind = mlxsw_thermal_module_unbind,
.get_temp = mlxsw_thermal_gearbox_temp_get, .get_temp = mlxsw_thermal_gearbox_temp_get,
.get_trip_type = mlxsw_thermal_module_trip_type_get,
.get_trip_temp = mlxsw_thermal_module_trip_temp_get,
.set_trip_temp = mlxsw_thermal_module_trip_temp_set,
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
}; };
static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev, static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
...@@ -617,7 +496,8 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz) ...@@ -617,7 +496,8 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
else else
snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d", snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d",
module_tz->module + 1); module_tz->module + 1);
module_tz->tzdev = thermal_zone_device_register(tz_name, module_tz->tzdev = thermal_zone_device_register_with_trips(tz_name,
module_tz->trips,
MLXSW_THERMAL_NUM_TRIPS, MLXSW_THERMAL_NUM_TRIPS,
MLXSW_THERMAL_TRIP_MASK, MLXSW_THERMAL_TRIP_MASK,
module_tz, module_tz,
...@@ -661,6 +541,8 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core, ...@@ -661,6 +541,8 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
module_tz->parent = thermal; module_tz->parent = thermal;
memcpy(module_tz->trips, default_thermal_trips, memcpy(module_tz->trips, default_thermal_trips,
sizeof(thermal->trips)); sizeof(thermal->trips));
memcpy(module_tz->cooling_states, default_cooling_states,
sizeof(thermal->cooling_states));
/* Initialize all trip point. */ /* Initialize all trip point. */
mlxsw_thermal_module_trips_reset(module_tz); mlxsw_thermal_module_trips_reset(module_tz);
/* Read module temperature and thresholds. */ /* Read module temperature and thresholds. */
...@@ -756,7 +638,8 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz) ...@@ -756,7 +638,8 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
else else
snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d", snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
gearbox_tz->module + 1); gearbox_tz->module + 1);
gearbox_tz->tzdev = thermal_zone_device_register(tz_name, gearbox_tz->tzdev = thermal_zone_device_register_with_trips(tz_name,
gearbox_tz->trips,
MLXSW_THERMAL_NUM_TRIPS, MLXSW_THERMAL_NUM_TRIPS,
MLXSW_THERMAL_TRIP_MASK, MLXSW_THERMAL_TRIP_MASK,
gearbox_tz, gearbox_tz,
...@@ -813,6 +696,8 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core, ...@@ -813,6 +696,8 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
gearbox_tz = &area->tz_gearbox_arr[i]; gearbox_tz = &area->tz_gearbox_arr[i];
memcpy(gearbox_tz->trips, default_thermal_trips, memcpy(gearbox_tz->trips, default_thermal_trips,
sizeof(thermal->trips)); sizeof(thermal->trips));
memcpy(gearbox_tz->cooling_states, default_cooling_states,
sizeof(thermal->cooling_states));
gearbox_tz->module = i; gearbox_tz->module = i;
gearbox_tz->parent = thermal; gearbox_tz->parent = thermal;
gearbox_tz->slot_index = area->slot_index; gearbox_tz->slot_index = area->slot_index;
...@@ -928,6 +813,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core, ...@@ -928,6 +813,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
thermal->core = core; thermal->core = core;
thermal->bus_info = bus_info; thermal->bus_info = bus_info;
memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips)); memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
memcpy(thermal->cooling_states, default_cooling_states, sizeof(thermal->cooling_states));
thermal->line_cards[0].slot_index = 0; thermal->line_cards[0].slot_index = 0;
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl); err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
...@@ -981,7 +867,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core, ...@@ -981,7 +867,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
MLXSW_THERMAL_SLOW_POLL_INT : MLXSW_THERMAL_SLOW_POLL_INT :
MLXSW_THERMAL_POLL_INT; MLXSW_THERMAL_POLL_INT;
thermal->tzdev = thermal_zone_device_register("mlxsw", thermal->tzdev = thermal_zone_device_register_with_trips("mlxsw",
thermal->trips,
MLXSW_THERMAL_NUM_TRIPS, MLXSW_THERMAL_NUM_TRIPS,
MLXSW_THERMAL_TRIP_MASK, MLXSW_THERMAL_TRIP_MASK,
thermal, thermal,
......
...@@ -501,7 +501,7 @@ struct iwl_mvm_tt_mgmt { ...@@ -501,7 +501,7 @@ struct iwl_mvm_tt_mgmt {
* @tzone: thermal zone device data * @tzone: thermal zone device data
*/ */
struct iwl_mvm_thermal_device { struct iwl_mvm_thermal_device {
s16 temp_trips[IWL_MAX_DTS_TRIPS]; struct thermal_trip trips[IWL_MAX_DTS_TRIPS];
u8 fw_trips_index[IWL_MAX_DTS_TRIPS]; u8 fw_trips_index[IWL_MAX_DTS_TRIPS];
struct thermal_zone_device *tzone; struct thermal_zone_device *tzone;
}; };
......
...@@ -573,11 +573,11 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm) ...@@ -573,11 +573,11 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
* and uncompressed, the FW should get it compressed and sorted * and uncompressed, the FW should get it compressed and sorted
*/ */
/* compress temp_trips to cmd array, remove uninitialized values*/ /* compress trips to cmd array, remove uninitialized values*/
for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) { for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
if (mvm->tz_device.temp_trips[i] != S16_MIN) { if (mvm->tz_device.trips[i].temperature != INT_MIN) {
cmd.thresholds[idx++] = cmd.thresholds[idx++] =
cpu_to_le16(mvm->tz_device.temp_trips[i]); cpu_to_le16((s16)(mvm->tz_device.trips[i].temperature / 1000));
} }
} }
cmd.num_temps = cpu_to_le32(idx); cmd.num_temps = cpu_to_le32(idx);
...@@ -593,8 +593,8 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm) ...@@ -593,8 +593,8 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
*/ */
for (i = 0; i < idx; i++) { for (i = 0; i < idx; i++) {
for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) { for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) {
if (le16_to_cpu(cmd.thresholds[i]) == if ((int)(le16_to_cpu(cmd.thresholds[i]) * 1000) ==
mvm->tz_device.temp_trips[j]) mvm->tz_device.trips[j].temperature)
mvm->tz_device.fw_trips_index[i] = j; mvm->tz_device.fw_trips_index[i] = j;
} }
} }
...@@ -638,37 +638,12 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device, ...@@ -638,37 +638,12 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device,
return ret; return ret;
} }
static int iwl_mvm_tzone_get_trip_temp(struct thermal_zone_device *device,
int trip, int *temp)
{
struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
return -EINVAL;
*temp = mvm->tz_device.temp_trips[trip] * 1000;
return 0;
}
static int iwl_mvm_tzone_get_trip_type(struct thermal_zone_device *device,
int trip, enum thermal_trip_type *type)
{
if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
return -EINVAL;
*type = THERMAL_TRIP_PASSIVE;
return 0;
}
static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device, static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
int trip, int temp) int trip, int temp)
{ {
struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata; struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
struct iwl_mvm_thermal_device *tzone; struct iwl_mvm_thermal_device *tzone;
int i, ret; int ret;
s16 temperature;
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
...@@ -678,40 +653,17 @@ static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device, ...@@ -678,40 +653,17 @@ static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
goto out; goto out;
} }
if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) {
ret = -EINVAL;
goto out;
}
if ((temp / 1000) > S16_MAX) { if ((temp / 1000) > S16_MAX) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
temperature = (s16)(temp / 1000);
tzone = &mvm->tz_device; tzone = &mvm->tz_device;
if (!tzone) { if (!tzone) {
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
/* no updates*/
if (tzone->temp_trips[trip] == temperature) {
ret = 0;
goto out;
}
/* already existing temperature */
for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
if (tzone->temp_trips[i] == temperature) {
ret = -EINVAL;
goto out;
}
}
tzone->temp_trips[trip] = temperature;
ret = iwl_mvm_send_temp_report_ths_cmd(mvm); ret = iwl_mvm_send_temp_report_ths_cmd(mvm);
out: out:
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
...@@ -720,8 +672,6 @@ static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device, ...@@ -720,8 +672,6 @@ static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
static struct thermal_zone_device_ops tzone_ops = { static struct thermal_zone_device_ops tzone_ops = {
.get_temp = iwl_mvm_tzone_get_temp, .get_temp = iwl_mvm_tzone_get_temp,
.get_trip_temp = iwl_mvm_tzone_get_trip_temp,
.get_trip_type = iwl_mvm_tzone_get_trip_type,
.set_trip_temp = iwl_mvm_tzone_set_trip_temp, .set_trip_temp = iwl_mvm_tzone_set_trip_temp,
}; };
...@@ -743,7 +693,8 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm) ...@@ -743,7 +693,8 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH); BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF); sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
mvm->tz_device.tzone = thermal_zone_device_register(name, mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
mvm->tz_device.trips,
IWL_MAX_DTS_TRIPS, IWL_MAX_DTS_TRIPS,
IWL_WRITABLE_TRIPS_MSK, IWL_WRITABLE_TRIPS_MSK,
mvm, &tzone_ops, mvm, &tzone_ops,
...@@ -766,8 +717,10 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm) ...@@ -766,8 +717,10 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
/* 0 is a valid temperature, /* 0 is a valid temperature,
* so initialize the array with S16_MIN which invalid temperature * so initialize the array with S16_MIN which invalid temperature
*/ */
for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) {
mvm->tz_device.temp_trips[i] = S16_MIN; mvm->tz_device.trips[i].temperature = INT_MIN;
mvm->tz_device.trips[i].type = THERMAL_TRIP_PASSIVE;
}
} }
static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev, static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
* measured by the on-die thermal monitor are within 0 <= Tj <= 90. So, * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So,
* assume 89°C is critical temperature. * assume 89°C is critical temperature.
*/ */
#define ACERHDF_DEFAULT_TEMP_FANON 60000
#define ACERHDF_DEFAULT_TEMP_FANOFF 53000
#define ACERHDF_TEMP_CRIT 89000 #define ACERHDF_TEMP_CRIT 89000
#define ACERHDF_FAN_OFF 0 #define ACERHDF_FAN_OFF 0
#define ACERHDF_FAN_AUTO 1 #define ACERHDF_FAN_AUTO 1
...@@ -70,8 +72,8 @@ static int kernelmode; ...@@ -70,8 +72,8 @@ static int kernelmode;
#endif #endif
static unsigned int interval = 10; static unsigned int interval = 10;
static unsigned int fanon = 60000; static unsigned int fanon = ACERHDF_DEFAULT_TEMP_FANON;
static unsigned int fanoff = 53000; static unsigned int fanoff = ACERHDF_DEFAULT_TEMP_FANOFF;
static unsigned int verbose; static unsigned int verbose;
static unsigned int list_supported; static unsigned int list_supported;
static unsigned int fanstate = ACERHDF_FAN_AUTO; static unsigned int fanstate = ACERHDF_FAN_AUTO;
...@@ -137,6 +139,15 @@ struct ctrl_settings { ...@@ -137,6 +139,15 @@ struct ctrl_settings {
int mcmd_enable; int mcmd_enable;
}; };
static struct thermal_trip trips[] = {
[0] = { .temperature = ACERHDF_DEFAULT_TEMP_FANON,
.hysteresis = ACERHDF_DEFAULT_TEMP_FANON - ACERHDF_DEFAULT_TEMP_FANOFF,
.type = THERMAL_TRIP_ACTIVE },
[1] = { .temperature = ACERHDF_TEMP_CRIT,
.type = THERMAL_TRIP_CRITICAL }
};
static struct ctrl_settings ctrl_cfg __read_mostly; static struct ctrl_settings ctrl_cfg __read_mostly;
/* Register addresses and values for different BIOS versions */ /* Register addresses and values for different BIOS versions */
...@@ -326,6 +337,15 @@ static void acerhdf_check_param(struct thermal_zone_device *thermal) ...@@ -326,6 +337,15 @@ static void acerhdf_check_param(struct thermal_zone_device *thermal)
fanon = ACERHDF_MAX_FANON; fanon = ACERHDF_MAX_FANON;
} }
if (fanon < fanoff) {
pr_err("fanoff temperature (%d) is above fanon temperature (%d), clamping to %d\n",
fanoff, fanon, fanon);
fanoff = fanon;
};
trips[0].temperature = fanon;
trips[0].hysteresis = fanon - fanoff;
if (kernelmode && prev_interval != interval) { if (kernelmode && prev_interval != interval) {
if (interval > ACERHDF_MAX_INTERVAL) { if (interval > ACERHDF_MAX_INTERVAL) {
pr_err("interval too high, set to %d\n", pr_err("interval too high, set to %d\n",
...@@ -424,43 +444,6 @@ static int acerhdf_change_mode(struct thermal_zone_device *thermal, ...@@ -424,43 +444,6 @@ static int acerhdf_change_mode(struct thermal_zone_device *thermal,
return 0; return 0;
} }
static int acerhdf_get_trip_type(struct thermal_zone_device *thermal, int trip,
enum thermal_trip_type *type)
{
if (trip == 0)
*type = THERMAL_TRIP_ACTIVE;
else if (trip == 1)
*type = THERMAL_TRIP_CRITICAL;
else
return -EINVAL;
return 0;
}
static int acerhdf_get_trip_hyst(struct thermal_zone_device *thermal, int trip,
int *temp)
{
if (trip != 0)
return -EINVAL;
*temp = fanon - fanoff;
return 0;
}
static int acerhdf_get_trip_temp(struct thermal_zone_device *thermal, int trip,
int *temp)
{
if (trip == 0)
*temp = fanon;
else if (trip == 1)
*temp = ACERHDF_TEMP_CRIT;
else
return -EINVAL;
return 0;
}
static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal, static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal,
int *temperature) int *temperature)
{ {
...@@ -474,13 +457,9 @@ static struct thermal_zone_device_ops acerhdf_dev_ops = { ...@@ -474,13 +457,9 @@ static struct thermal_zone_device_ops acerhdf_dev_ops = {
.unbind = acerhdf_unbind, .unbind = acerhdf_unbind,
.get_temp = acerhdf_get_ec_temp, .get_temp = acerhdf_get_ec_temp,
.change_mode = acerhdf_change_mode, .change_mode = acerhdf_change_mode,
.get_trip_type = acerhdf_get_trip_type,
.get_trip_hyst = acerhdf_get_trip_hyst,
.get_trip_temp = acerhdf_get_trip_temp,
.get_crit_temp = acerhdf_get_crit_temp, .get_crit_temp = acerhdf_get_crit_temp,
}; };
/* /*
* cooling device callback functions * cooling device callback functions
* get maximal fan cooling state * get maximal fan cooling state
...@@ -710,8 +689,8 @@ static int __init acerhdf_register_thermal(void) ...@@ -710,8 +689,8 @@ static int __init acerhdf_register_thermal(void)
if (IS_ERR(cl_dev)) if (IS_ERR(cl_dev))
return -EINVAL; return -EINVAL;
thz_dev = thermal_zone_device_register("acerhdf", 2, 0, NULL, thz_dev = thermal_zone_device_register_with_trips("acerhdf", trips, ARRAY_SIZE(trips),
&acerhdf_dev_ops, 0, NULL, &acerhdf_dev_ops,
&acerhdf_zone_params, 0, &acerhdf_zone_params, 0,
(kernelmode) ? interval*1000 : 0); (kernelmode) ? interval*1000 : 0);
if (IS_ERR(thz_dev)) if (IS_ERR(thz_dev))
......
...@@ -709,12 +709,10 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev, ...@@ -709,12 +709,10 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
struct armada_thermal_priv *priv) struct armada_thermal_priv *priv)
{ {
struct armada_thermal_data *data = priv->data; struct armada_thermal_data *data = priv->data;
struct resource *res;
void __iomem *base; void __iomem *base;
/* First memory region points towards the status register */ /* First memory region points towards the status register */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
...@@ -761,8 +759,7 @@ static void armada_set_sane_name(struct platform_device *pdev, ...@@ -761,8 +759,7 @@ static void armada_set_sane_name(struct platform_device *pdev,
} }
/* Save the name locally */ /* Save the name locally */
strncpy(priv->zone_name, name, THERMAL_NAME_LENGTH - 1); strscpy(priv->zone_name, name, THERMAL_NAME_LENGTH);
priv->zone_name[THERMAL_NAME_LENGTH - 1] = '\0';
/* Then check there are no '-' or hwmon core will complain */ /* Then check there are no '-' or hwmon core will complain */
do { do {
...@@ -785,30 +782,23 @@ static int armada_configure_overheat_int(struct armada_thermal_priv *priv, ...@@ -785,30 +782,23 @@ static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
int sensor_id) int sensor_id)
{ {
/* Retrieve the critical trip point to enable the overheat interrupt */ /* 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 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)) ret = thermal_zone_get_crit_temp(tz, &temperature);
return -EINVAL; if (ret)
return ret;
ret = armada_select_channel(priv, sensor_id); ret = armada_select_channel(priv, sensor_id);
if (ret) if (ret)
return ret; return ret;
armada_set_overheat_thresholds(priv, /*
trips[i].temperature, * A critical temperature does not have a hysteresis
trips[i].hysteresis); */
armada_set_overheat_thresholds(priv, temperature, 0);
priv->overheat_sensor = tz; priv->overheat_sensor = tz;
priv->interrupt_source = sensor_id; priv->interrupt_source = sensor_id;
armada_enable_overheat_interrupt(priv); armada_enable_overheat_interrupt(priv);
return 0; return 0;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#include "../thermal_core.h"
#include "../thermal_hwmon.h" #include "../thermal_hwmon.h"
#define BCM2835_TS_TSENSCTL 0x00 #define BCM2835_TS_TSENSCTL 0x00
...@@ -166,7 +167,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) ...@@ -166,7 +167,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
const struct of_device_id *match; const struct of_device_id *match;
struct thermal_zone_device *tz; struct thermal_zone_device *tz;
struct bcm2835_thermal_data *data; struct bcm2835_thermal_data *data;
struct resource *res;
int err = 0; int err = 0;
u32 val; u32 val;
unsigned long rate; unsigned long rate;
...@@ -180,8 +180,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) ...@@ -180,8 +180,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
if (!match) if (!match)
return -EINVAL; return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
data->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(data->regs)) { if (IS_ERR(data->regs)) {
err = PTR_ERR(data->regs); err = PTR_ERR(data->regs);
return err; return err;
...@@ -224,7 +223,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) ...@@ -224,7 +223,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
*/ */
val = readl(data->regs + BCM2835_TS_TSENSCTL); val = readl(data->regs + BCM2835_TS_TSENSCTL);
if (!(val & BCM2835_TS_TSENSCTL_RSTB)) { if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
int trip_temp, offset, slope; struct thermal_trip trip;
int offset, slope;
slope = thermal_zone_get_slope(tz); slope = thermal_zone_get_slope(tz);
offset = thermal_zone_get_offset(tz); offset = thermal_zone_get_offset(tz);
...@@ -232,7 +232,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) ...@@ -232,7 +232,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
* For now we deal only with critical, otherwise * For now we deal only with critical, otherwise
* would need to iterate * 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) { if (err < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Not able to read trip_temp: %d\n", "Not able to read trip_temp: %d\n",
...@@ -249,7 +249,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) ...@@ -249,7 +249,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT); val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);
/* trip_adc value from info */ /* trip_adc value from info */
val |= bcm2835_thermal_temp2adc(trip_temp, val |= bcm2835_thermal_temp2adc(trip.temperature,
offset, offset,
slope) slope)
<< BCM2835_TS_TSENSCTL_THOLD_SHIFT; << BCM2835_TS_TSENSCTL_THOLD_SHIFT;
......
...@@ -321,7 +321,6 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) ...@@ -321,7 +321,6 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
const struct thermal_zone_device_ops *of_ops; const struct thermal_zone_device_ops *of_ops;
struct thermal_zone_device *thermal; struct thermal_zone_device *thermal;
struct brcmstb_thermal_priv *priv; struct brcmstb_thermal_priv *priv;
struct resource *res;
int irq, ret; int irq, ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
...@@ -332,8 +331,7 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) ...@@ -332,8 +331,7 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
if (!priv->temp_params) if (!priv->temp_params)
return -EINVAL; return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->tmon_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
priv->tmon_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->tmon_base)) if (IS_ERR(priv->tmon_base))
return PTR_ERR(priv->tmon_base); return PTR_ERR(priv->tmon_base);
......
...@@ -120,44 +120,6 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data) ...@@ -120,44 +120,6 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
return IRQ_HANDLED; 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, static int da9062_thermal_get_temp(struct thermal_zone_device *z,
int *temp) int *temp)
{ {
...@@ -172,8 +134,10 @@ static int da9062_thermal_get_temp(struct thermal_zone_device *z, ...@@ -172,8 +134,10 @@ static int da9062_thermal_get_temp(struct thermal_zone_device *z,
static struct thermal_zone_device_ops da9062_thermal_ops = { static struct thermal_zone_device_ops da9062_thermal_ops = {
.get_temp = da9062_thermal_get_temp, .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 = { static const struct da9062_thermal_config da9062_config = {
...@@ -228,8 +192,8 @@ static int da9062_thermal_probe(struct platform_device *pdev) ...@@ -228,8 +192,8 @@ static int da9062_thermal_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on); INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on);
mutex_init(&thermal->lock); mutex_init(&thermal->lock);
thermal->zone = thermal_zone_device_register(thermal->config->name, thermal->zone = thermal_zone_device_register_with_trips(thermal->config->name,
1, 0, thermal, trips, ARRAY_SIZE(trips), 0, thermal,
&da9062_thermal_ops, NULL, pp_tmp, &da9062_thermal_ops, NULL, pp_tmp,
0); 0);
if (IS_ERR(thermal->zone)) { if (IS_ERR(thermal->zone)) {
......
...@@ -122,20 +122,17 @@ static int dove_thermal_probe(struct platform_device *pdev) ...@@ -122,20 +122,17 @@ static int dove_thermal_probe(struct platform_device *pdev)
{ {
struct thermal_zone_device *thermal = NULL; struct thermal_zone_device *thermal = NULL;
struct dove_thermal_priv *priv; struct dove_thermal_priv *priv;
struct resource *res;
int ret; int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->sensor = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
priv->sensor = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->sensor)) if (IS_ERR(priv->sensor))
return PTR_ERR(priv->sensor); return PTR_ERR(priv->sensor);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); priv->control = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
priv->control = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->control)) if (IS_ERR(priv->control))
return PTR_ERR(priv->control); return PTR_ERR(priv->control);
......
...@@ -13,26 +13,28 @@ ...@@ -13,26 +13,28 @@
#include "thermal_core.h" #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; 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) { if (!trip.hysteresis)
pr_warn_once("Undefined get_trip_hyst for thermal zone %s - " dev_info_once(&tz->device,
"running with default hysteresis zero\n", tz->type); "Zero hysteresis value for thermal zone %s\n", tz->type);
trip_hyst = 0;
} else
tz->ops->get_trip_hyst(tz, trip, &trip_hyst);
dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n", dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n",
trip, trip_temp, tz->temperature, trip_id, trip.temperature, tz->temperature,
trip_hyst); trip.hysteresis);
list_for_each_entry(instance, &tz->thermal_instances, tz_node) { list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
if (instance->trip != trip) if (instance->trip != trip_id)
continue; continue;
/* in case fan is in initial state, switch the fan off */ /* 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) ...@@ -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 * enable fan when temperature exceeds trip_temp and disable
* the fan in case it falls below trip_temp minus hysteresis * 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; instance->target = 1;
else if (instance->target == 1 && else if (instance->target == 1 &&
tz->temperature <= trip_temp - trip_hyst) tz->temperature <= trip.temperature - trip.hysteresis)
instance->target = 0; instance->target = 0;
dev_dbg(&instance->cdev->device, "target=%d\n", 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) ...@@ -63,6 +65,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
instance->cdev->updated = false; /* cdev needs update */ instance->cdev->updated = false; /* cdev needs update */
mutex_unlock(&instance->cdev->lock); mutex_unlock(&instance->cdev->lock);
} }
return 0;
} }
/** /**
...@@ -95,10 +99,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) ...@@ -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) static int bang_bang_control(struct thermal_zone_device *tz, int trip)
{ {
struct thermal_instance *instance; struct thermal_instance *instance;
int ret;
lockdep_assert_held(&tz->lock); 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) list_for_each_entry(instance, &tz->thermal_instances, tz_node)
thermal_cdev_update(instance->cdev); thermal_cdev_update(instance->cdev);
......
...@@ -21,16 +21,12 @@ ...@@ -21,16 +21,12 @@
*/ */
static int get_trip_level(struct thermal_zone_device *tz) static int get_trip_level(struct thermal_zone_device *tz)
{ {
int count = 0; struct thermal_trip trip;
int trip_temp; int count;
enum thermal_trip_type trip_type;
if (tz->num_trips == 0 || !tz->ops->get_trip_temp)
return 0;
for (count = 0; count < tz->num_trips; count++) { for (count = 0; count < tz->num_trips; count++) {
tz->ops->get_trip_temp(tz, count, &trip_temp); __thermal_zone_get_trip(tz, count, &trip);
if (tz->temperature < trip_temp) if (tz->temperature < trip.temperature)
break; break;
} }
...@@ -38,10 +34,8 @@ static int get_trip_level(struct thermal_zone_device *tz) ...@@ -38,10 +34,8 @@ static int get_trip_level(struct thermal_zone_device *tz)
* count > 0 only if temperature is greater than first trip * count > 0 only if temperature is greater than first trip
* point, in which case, trip_point = count - 1 * point, in which case, trip_point = count - 1
*/ */
if (count > 0) { if (count > 0)
tz->ops->get_trip_type(tz, count - 1, &trip_type); trace_thermal_zone_trip(tz, count - 1, trip.type);
trace_thermal_zone_trip(tz, count - 1, trip_type);
}
return count; return count;
} }
......
...@@ -124,16 +124,15 @@ static void estimate_pid_constants(struct thermal_zone_device *tz, ...@@ -124,16 +124,15 @@ static void estimate_pid_constants(struct thermal_zone_device *tz,
u32 sustainable_power, int trip_switch_on, u32 sustainable_power, int trip_switch_on,
int control_temp) int control_temp)
{ {
struct thermal_trip trip;
u32 temperature_threshold = control_temp;
int ret; int ret;
int switch_on_temp;
u32 temperature_threshold;
s32 k_i; s32 k_i;
ret = tz->ops->get_trip_temp(tz, trip_switch_on, &switch_on_temp); ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip);
if (ret) if (!ret)
switch_on_temp = 0; temperature_threshold -= trip.temperature;
temperature_threshold = control_temp - switch_on_temp;
/* /*
* estimate_pid_constants() tries to find appropriate default * estimate_pid_constants() tries to find appropriate default
* values for thermal zones that don't provide them. If a * 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, ...@@ -519,10 +518,10 @@ static void get_governor_trips(struct thermal_zone_device *tz,
last_passive = INVALID_TRIP; last_passive = INVALID_TRIP;
for (i = 0; i < tz->num_trips; i++) { for (i = 0; i < tz->num_trips; i++) {
enum thermal_trip_type type; struct thermal_trip trip;
int ret; int ret;
ret = tz->ops->get_trip_type(tz, i, &type); ret = __thermal_zone_get_trip(tz, i, &trip);
if (ret) { if (ret) {
dev_warn(&tz->device, dev_warn(&tz->device,
"Failed to get trip point %d type: %d\n", i, "Failed to get trip point %d type: %d\n", i,
...@@ -530,14 +529,14 @@ static void get_governor_trips(struct thermal_zone_device *tz, ...@@ -530,14 +529,14 @@ static void get_governor_trips(struct thermal_zone_device *tz,
continue; continue;
} }
if (type == THERMAL_TRIP_PASSIVE) { if (trip.type == THERMAL_TRIP_PASSIVE) {
if (!found_first_passive) { if (!found_first_passive) {
params->trip_switch_on = i; params->trip_switch_on = i;
found_first_passive = true; found_first_passive = true;
} else { } else {
last_passive = i; last_passive = i;
} }
} else if (type == THERMAL_TRIP_ACTIVE) { } else if (trip.type == THERMAL_TRIP_ACTIVE) {
last_active = i; last_active = i;
} else { } else {
break; break;
...@@ -632,7 +631,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz) ...@@ -632,7 +631,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
{ {
int ret; int ret;
struct power_allocator_params *params; struct power_allocator_params *params;
int control_temp; struct thermal_trip trip;
ret = check_power_actors(tz); ret = check_power_actors(tz);
if (ret) if (ret)
...@@ -658,13 +657,12 @@ static int power_allocator_bind(struct thermal_zone_device *tz) ...@@ -658,13 +657,12 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
get_governor_trips(tz, params); get_governor_trips(tz, params);
if (tz->num_trips > 0) { if (tz->num_trips > 0) {
ret = tz->ops->get_trip_temp(tz, ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature,
params->trip_max_desired_temperature, &trip);
&control_temp);
if (!ret) if (!ret)
estimate_pid_constants(tz, tz->tzp->sustainable_power, estimate_pid_constants(tz, tz->tzp->sustainable_power,
params->trip_switch_on, params->trip_switch_on,
control_temp); trip.temperature);
} }
reset_pid_controller(params); reset_pid_controller(params);
...@@ -694,11 +692,11 @@ static void power_allocator_unbind(struct thermal_zone_device *tz) ...@@ -694,11 +692,11 @@ static void power_allocator_unbind(struct thermal_zone_device *tz)
tz->governor_data = NULL; 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 power_allocator_params *params = tz->governor_data;
struct thermal_trip trip;
int ret;
bool update; bool update;
lockdep_assert_held(&tz->lock); lockdep_assert_held(&tz->lock);
...@@ -707,13 +705,12 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) ...@@ -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 * We get called for every trip point but we only need to do
* our calculations once * our calculations once
*/ */
if (trip != params->trip_max_desired_temperature) if (trip_id != params->trip_max_desired_temperature)
return 0; return 0;
ret = tz->ops->get_trip_temp(tz, params->trip_switch_on, ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip);
&switch_on_temp); if (!ret && (tz->temperature < trip.temperature)) {
if (!ret && (tz->temperature < switch_on_temp)) { update = (tz->last_temperature >= trip.temperature);
update = (tz->last_temperature >= switch_on_temp);
tz->passive = 0; tz->passive = 0;
reset_pid_controller(params); reset_pid_controller(params);
allow_maximum_power(tz, update); allow_maximum_power(tz, update);
...@@ -722,16 +719,14 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) ...@@ -722,16 +719,14 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
tz->passive = 1; tz->passive = 1;
ret = tz->ops->get_trip_temp(tz, params->trip_max_desired_temperature, ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip);
&control_temp);
if (ret) { if (ret) {
dev_warn(&tz->device, dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n",
"Failed to get the maximum desired temperature: %d\n",
ret); ret);
return ret; return ret;
} }
return allocate_power(tz, control_temp); return allocate_power(tz, trip.temperature);
} }
static struct thermal_governor thermal_gov_power_allocator = { static struct thermal_governor thermal_gov_power_allocator = {
......
...@@ -95,30 +95,28 @@ static void update_passive_instance(struct thermal_zone_device *tz, ...@@ -95,30 +95,28 @@ static void update_passive_instance(struct thermal_zone_device *tz,
tz->passive += value; 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; enum thermal_trend trend;
struct thermal_instance *instance; struct thermal_instance *instance;
struct thermal_trip trip;
bool throttle = false; bool throttle = false;
int old_target; int old_target;
tz->ops->get_trip_temp(tz, trip, &trip_temp); __thermal_zone_get_trip(tz, trip_id, &trip);
tz->ops->get_trip_type(tz, trip, &trip_type);
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; 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", 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) { list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
if (instance->trip != trip) if (instance->trip != trip_id)
continue; continue;
old_target = instance->target; old_target = instance->target;
...@@ -132,11 +130,11 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) ...@@ -132,11 +130,11 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
/* Activate a passive thermal instance */ /* Activate a passive thermal instance */
if (old_target == THERMAL_NO_TARGET && if (old_target == THERMAL_NO_TARGET &&
instance->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 */ /* Deactivate a passive thermal instance */
else if (old_target != THERMAL_NO_TARGET && else if (old_target != THERMAL_NO_TARGET &&
instance->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; instance->initialized = true;
mutex_lock(&instance->cdev->lock); mutex_lock(&instance->cdev->lock);
......
...@@ -482,7 +482,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, ...@@ -482,7 +482,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
struct hisi_thermal_sensor *sensor) struct hisi_thermal_sensor *sensor)
{ {
int ret, i; int ret, i;
const struct thermal_trip *trip; struct thermal_trip trip;
sensor->tzd = devm_thermal_of_zone_register(&pdev->dev, sensor->tzd = devm_thermal_of_zone_register(&pdev->dev,
sensor->id, sensor, sensor->id, sensor,
...@@ -495,11 +495,12 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, ...@@ -495,11 +495,12 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
return ret; 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++) { thermal_zone_get_trip(sensor->tzd, i, &trip);
if (trip[i].type == THERMAL_TRIP_PASSIVE) {
sensor->thres_temp = trip[i].temperature; if (trip.type == THERMAL_TRIP_PASSIVE) {
sensor->thres_temp = trip.temperature;
break; break;
} }
} }
......
...@@ -88,7 +88,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) ...@@ -88,7 +88,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
if (!resource_id) if (!resource_id)
return -EINVAL; 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); sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
if (!sensor) if (!sensor)
...@@ -127,7 +127,11 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) ...@@ -127,7 +127,11 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
return 0; 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[] = { static const struct of_device_id imx_sc_thermal_table[] = {
{ .compatible = "fsl,imx-sc-thermal", .data = imx_sc_sensors }, { .compatible = "fsl,imx-sc-thermal", .data = imx_sc_sensors },
......
...@@ -76,7 +76,6 @@ ...@@ -76,7 +76,6 @@
enum imx_thermal_trip { enum imx_thermal_trip {
IMX_TRIP_PASSIVE, IMX_TRIP_PASSIVE,
IMX_TRIP_CRITICAL, IMX_TRIP_CRITICAL,
IMX_TRIP_NUM,
}; };
#define IMX_POLLING_DELAY 2000 /* millisecond */ #define IMX_POLLING_DELAY 2000 /* millisecond */
...@@ -115,6 +114,11 @@ struct thermal_soc_data { ...@@ -115,6 +114,11 @@ struct thermal_soc_data {
u32 low_alarm_shift; 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 = { static struct thermal_soc_data thermal_imx6q_data = {
.version = TEMPMON_IMX6Q, .version = TEMPMON_IMX6Q,
...@@ -201,8 +205,6 @@ struct imx_thermal_data { ...@@ -201,8 +205,6 @@ struct imx_thermal_data {
struct thermal_cooling_device *cdev; struct thermal_cooling_device *cdev;
struct regmap *tempmon; struct regmap *tempmon;
u32 c1, c2; /* See formula in imx_init_calib() */ u32 c1, c2; /* See formula in imx_init_calib() */
int temp_passive;
int temp_critical;
int temp_max; int temp_max;
int alarm_temp; int alarm_temp;
int last_temp; int last_temp;
...@@ -279,12 +281,12 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *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 */ /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
if (data->socdata->version == TEMPMON_IMX6Q) { if (data->socdata->version == TEMPMON_IMX6Q) {
if (data->alarm_temp == data->temp_passive && if (data->alarm_temp == trips[IMX_TRIP_PASSIVE].temperature &&
*temp >= data->temp_passive) *temp >= trips[IMX_TRIP_PASSIVE].temperature)
imx_set_alarm_temp(data, data->temp_critical); imx_set_alarm_temp(data, trips[IMX_TRIP_CRITICAL].temperature);
if (data->alarm_temp == data->temp_critical && if (data->alarm_temp == trips[IMX_TRIP_CRITICAL].temperature &&
*temp < data->temp_passive) { *temp < trips[IMX_TRIP_PASSIVE].temperature) {
imx_set_alarm_temp(data, data->temp_passive); imx_set_alarm_temp(data, trips[IMX_TRIP_PASSIVE].temperature);
dev_dbg(&tz->device, "thermal alarm off: T < %d\n", dev_dbg(&tz->device, "thermal alarm off: T < %d\n",
data->alarm_temp / 1000); data->alarm_temp / 1000);
} }
...@@ -330,29 +332,10 @@ static int imx_change_mode(struct thermal_zone_device *tz, ...@@ -330,29 +332,10 @@ static int imx_change_mode(struct thermal_zone_device *tz,
return 0; 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) static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp)
{ {
struct imx_thermal_data *data = tz->devdata; *temp = trips[IMX_TRIP_CRITICAL].temperature;
*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 = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive :
data->temp_critical;
return 0; return 0;
} }
...@@ -371,10 +354,10 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, ...@@ -371,10 +354,10 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
return -EPERM; return -EPERM;
/* do not allow passive to be set higher than critical */ /* 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; return -EINVAL;
data->temp_passive = temp; trips[IMX_TRIP_PASSIVE].temperature = temp;
imx_set_alarm_temp(data, temp); imx_set_alarm_temp(data, temp);
...@@ -423,8 +406,6 @@ static struct thermal_zone_device_ops imx_tz_ops = { ...@@ -423,8 +406,6 @@ static struct thermal_zone_device_ops imx_tz_ops = {
.unbind = imx_unbind, .unbind = imx_unbind,
.get_temp = imx_get_temp, .get_temp = imx_get_temp,
.change_mode = imx_change_mode, .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, .get_crit_temp = imx_get_crit_temp,
.set_trip_temp = imx_set_trip_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) ...@@ -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 critical trip point at 5 °C under max
* Set the passive trip point at 10 °C under max (changeable via sysfs) * Set the passive trip point at 10 °C under max (changeable via sysfs)
*/ */
data->temp_critical = data->temp_max - (1000 * 5); trips[IMX_TRIP_PASSIVE].temperature = data->temp_max - (1000 * 10);
data->temp_passive = 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) static int imx_init_from_tempmon_data(struct platform_device *pdev)
...@@ -743,8 +724,9 @@ static int imx_thermal_probe(struct platform_device *pdev) ...@@ -743,8 +724,9 @@ static int imx_thermal_probe(struct platform_device *pdev)
goto legacy_cleanup; goto legacy_cleanup;
} }
data->tz = thermal_zone_device_register("imx_thermal_zone", data->tz = thermal_zone_device_register_with_trips("imx_thermal_zone",
IMX_TRIP_NUM, trips,
ARRAY_SIZE(trips),
BIT(IMX_TRIP_PASSIVE), data, BIT(IMX_TRIP_PASSIVE), data,
&imx_tz_ops, NULL, &imx_tz_ops, NULL,
IMX_PASSIVE_DELAY, IMX_PASSIVE_DELAY,
...@@ -758,8 +740,8 @@ static int imx_thermal_probe(struct platform_device *pdev) ...@@ -758,8 +740,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC" dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
" critical:%dC passive:%dC\n", data->temp_grade, " critical:%dC passive:%dC\n", data->temp_grade,
data->temp_max / 1000, data->temp_critical / 1000, data->temp_max / 1000, trips[IMX_TRIP_CRITICAL].temperature / 1000,
data->temp_passive / 1000); trips[IMX_TRIP_PASSIVE].temperature / 1000);
/* Enable measurements at ~ 10 Hz */ /* Enable measurements at ~ 10 Hz */
regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR, regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
...@@ -767,10 +749,10 @@ static int imx_thermal_probe(struct platform_device *pdev) ...@@ -767,10 +749,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET, regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET,
measure_freq << data->socdata->measure_freq_shift); 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) 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, regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
data->socdata->power_down_mask); data->socdata->power_down_mask);
......
...@@ -18,9 +18,6 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, ...@@ -18,9 +18,6 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone,
unsigned long long tmp; unsigned long long tmp;
acpi_status status; 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); status = acpi_evaluate_integer(d->adev->handle, "_TMP", NULL, &tmp);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -EIO; return -EIO;
...@@ -46,9 +43,6 @@ static int int340x_thermal_get_trip_temp(struct thermal_zone_device *zone, ...@@ -46,9 +43,6 @@ static int int340x_thermal_get_trip_temp(struct thermal_zone_device *zone,
struct int34x_thermal_zone *d = zone->devdata; struct int34x_thermal_zone *d = zone->devdata;
int i, ret = 0; 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); mutex_lock(&d->trip_mutex);
if (trip < d->aux_trip_nr) if (trip < d->aux_trip_nr)
...@@ -83,9 +77,6 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone, ...@@ -83,9 +77,6 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone,
struct int34x_thermal_zone *d = zone->devdata; struct int34x_thermal_zone *d = zone->devdata;
int i, ret = 0; 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); mutex_lock(&d->trip_mutex);
if (trip < d->aux_trip_nr) if (trip < d->aux_trip_nr)
...@@ -120,9 +111,6 @@ static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, ...@@ -120,9 +111,6 @@ static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone,
acpi_status status; acpi_status status;
char name[10]; 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); snprintf(name, sizeof(name), "PAT%d", trip);
status = acpi_execute_simple_method(d->adev->handle, name, status = acpi_execute_simple_method(d->adev->handle, name,
millicelsius_to_deci_kelvin(temp)); millicelsius_to_deci_kelvin(temp));
...@@ -142,9 +130,6 @@ static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone, ...@@ -142,9 +130,6 @@ static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone,
acpi_status status; acpi_status status;
unsigned long long hyst; 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); status = acpi_evaluate_integer(d->adev->handle, "GTSH", NULL, &hyst);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
*temp = 0; *temp = 0;
...@@ -229,7 +214,7 @@ static struct thermal_zone_params int340x_thermal_params = { ...@@ -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 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; struct int34x_thermal_zone *int34x_thermal_zone;
acpi_status status; acpi_status status;
...@@ -245,7 +230,16 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, ...@@ -245,7 +230,16 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
mutex_init(&int34x_thermal_zone->trip_mutex); mutex_init(&int34x_thermal_zone->trip_mutex);
int34x_thermal_zone->adev = adev; 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); status = acpi_evaluate_integer(adev->handle, "PATC", NULL, &trip_cnt);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
...@@ -276,7 +270,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, ...@@ -276,7 +270,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
acpi_device_bid(adev), acpi_device_bid(adev),
trip_cnt, trip_cnt,
trip_mask, int34x_thermal_zone, trip_mask, int34x_thermal_zone,
&int340x_thermal_zone_ops, int34x_thermal_zone->ops,
&int340x_thermal_params, &int340x_thermal_params,
0, 0); 0, 0);
if (IS_ERR(int34x_thermal_zone->zone)) { if (IS_ERR(int34x_thermal_zone->zone)) {
...@@ -295,6 +289,8 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, ...@@ -295,6 +289,8 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table);
kfree(int34x_thermal_zone->aux_trips); kfree(int34x_thermal_zone->aux_trips);
err_trip_alloc: err_trip_alloc:
kfree(int34x_thermal_zone->ops);
err_ops_alloc:
mutex_destroy(&int34x_thermal_zone->trip_mutex); mutex_destroy(&int34x_thermal_zone->trip_mutex);
kfree(int34x_thermal_zone); kfree(int34x_thermal_zone);
return ERR_PTR(ret); return ERR_PTR(ret);
...@@ -307,6 +303,7 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone ...@@ -307,6 +303,7 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone
thermal_zone_device_unregister(int34x_thermal_zone->zone); thermal_zone_device_unregister(int34x_thermal_zone->zone);
acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table);
kfree(int34x_thermal_zone->aux_trips); kfree(int34x_thermal_zone->aux_trips);
kfree(int34x_thermal_zone->ops);
mutex_destroy(&int34x_thermal_zone->trip_mutex); mutex_destroy(&int34x_thermal_zone->trip_mutex);
kfree(int34x_thermal_zone); kfree(int34x_thermal_zone);
} }
......
...@@ -29,14 +29,14 @@ struct int34x_thermal_zone { ...@@ -29,14 +29,14 @@ struct int34x_thermal_zone {
int hot_temp; int hot_temp;
int hot_trip_id; int hot_trip_id;
struct thermal_zone_device *zone; struct thermal_zone_device *zone;
struct thermal_zone_device_ops *override_ops; struct thermal_zone_device_ops *ops;
void *priv_data; void *priv_data;
struct acpi_lpat_conversion_table *lpat_table; struct acpi_lpat_conversion_table *lpat_table;
struct mutex trip_mutex; struct mutex trip_mutex;
}; };
struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *, 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 *); void int340x_thermal_zone_remove(struct int34x_thermal_zone *);
int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone); int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone);
......
...@@ -207,10 +207,6 @@ static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, ...@@ -207,10 +207,6 @@ static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone,
return ret; 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) static int proc_thermal_read_ppcc(struct proc_thermal_device *proc_priv)
{ {
int i; int i;
...@@ -285,7 +281,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) ...@@ -285,7 +281,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv)
struct acpi_device *adev; struct acpi_device *adev;
acpi_status status; acpi_status status;
unsigned long long tmp; unsigned long long tmp;
struct thermal_zone_device_ops *ops = NULL; int (*get_temp) (struct thermal_zone_device *, int *) = NULL;
int ret; int ret;
adev = ACPI_COMPANION(dev); adev = ACPI_COMPANION(dev);
...@@ -304,10 +300,10 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) ...@@ -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 */ /* there is no _TMP method, add local method */
stored_tjmax = get_tjmax(); stored_tjmax = get_tjmax();
if (stored_tjmax > 0) 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)) { if (IS_ERR(proc_priv->int340x_zone)) {
return PTR_ERR(proc_priv->int340x_zone); return PTR_ERR(proc_priv->int340x_zone);
} else } else
......
...@@ -53,6 +53,7 @@ struct zone_device { ...@@ -53,6 +53,7 @@ struct zone_device {
u32 msr_pkg_therm_high; u32 msr_pkg_therm_high;
struct delayed_work work; struct delayed_work work;
struct thermal_zone_device *tzone; struct thermal_zone_device *tzone;
struct thermal_trip *trips;
struct cpumask cpumask; struct cpumask cpumask;
}; };
...@@ -138,40 +139,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) ...@@ -138,40 +139,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
return -EINVAL; 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 static int
sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) 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) ...@@ -212,18 +179,9 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
l, h); 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 */ /* Thermal zone callback registry */
static struct thermal_zone_device_ops tzone_ops = { static struct thermal_zone_device_ops tzone_ops = {
.get_temp = sys_get_curr_temp, .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, .set_trip_temp = sys_set_trip_temp,
}; };
...@@ -323,6 +281,48 @@ static int pkg_thermal_notify(u64 msr_val) ...@@ -323,6 +281,48 @@ static int pkg_thermal_notify(u64 msr_val)
return 0; 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) static int pkg_temp_thermal_device_add(unsigned int cpu)
{ {
int id = topology_logical_die_id(cpu); int id = topology_logical_die_id(cpu);
...@@ -348,24 +348,27 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) ...@@ -348,24 +348,27 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
if (!zonedev) if (!zonedev)
return -ENOMEM; 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); INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn);
zonedev->cpu = cpu; zonedev->cpu = cpu;
zonedev->tj_max = tj_max; zonedev->tj_max = tj_max;
zonedev->tzone = thermal_zone_device_register("x86_pkg_temp", zonedev->tzone = thermal_zone_device_register_with_trips("x86_pkg_temp",
thres_count, zonedev->trips, thres_count,
(thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01, (thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01,
zonedev, &tzone_ops, &pkg_temp_tz_params, 0, 0); zonedev, &tzone_ops, &pkg_temp_tz_params, 0, 0);
if (IS_ERR(zonedev->tzone)) { if (IS_ERR(zonedev->tzone)) {
err = PTR_ERR(zonedev->tzone); err = PTR_ERR(zonedev->tzone);
kfree(zonedev); goto out_kfree_trips;
return err;
} }
err = thermal_zone_device_enable(zonedev->tzone); err = thermal_zone_device_enable(zonedev->tzone);
if (err) { if (err)
thermal_zone_device_unregister(zonedev->tzone); goto out_unregister_tz;
kfree(zonedev);
return err;
}
/* Store MSR value for package thermal interrupt, to restore at exit */ /* Store MSR value for package thermal interrupt, to restore at exit */
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low, rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low,
zonedev->msr_pkg_therm_high); zonedev->msr_pkg_therm_high);
...@@ -374,7 +377,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) ...@@ -374,7 +377,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
raw_spin_lock_irq(&pkg_temp_lock); raw_spin_lock_irq(&pkg_temp_lock);
zones[id] = zonedev; zones[id] = zonedev;
raw_spin_unlock_irq(&pkg_temp_lock); raw_spin_unlock_irq(&pkg_temp_lock);
return 0; 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) static int pkg_thermal_cpu_offline(unsigned int cpu)
...@@ -458,8 +470,10 @@ 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); raw_spin_unlock_irq(&pkg_temp_lock);
/* Final cleanup if this is the last cpu */ /* Final cleanup if this is the last cpu */
if (lastcpu) if (lastcpu) {
kfree(zonedev->trips);
kfree(zonedev); kfree(zonedev);
}
return 0; return 0;
} }
......
...@@ -64,15 +64,13 @@ static int kirkwood_thermal_probe(struct platform_device *pdev) ...@@ -64,15 +64,13 @@ static int kirkwood_thermal_probe(struct platform_device *pdev)
{ {
struct thermal_zone_device *thermal = NULL; struct thermal_zone_device *thermal = NULL;
struct kirkwood_thermal_priv *priv; struct kirkwood_thermal_priv *priv;
struct resource *res;
int ret; int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->sensor = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
priv->sensor = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->sensor)) if (IS_ERR(priv->sensor))
return PTR_ERR(priv->sensor); return PTR_ERR(priv->sensor);
......
...@@ -150,6 +150,20 @@ ...@@ -150,6 +150,20 @@
#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1) #define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 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 { enum {
VTS1, VTS1,
VTS2, VTS2,
...@@ -163,6 +177,7 @@ enum { ...@@ -163,6 +177,7 @@ enum {
enum mtk_thermal_version { enum mtk_thermal_version {
MTK_THERMAL_V1 = 1, MTK_THERMAL_V1 = 1,
MTK_THERMAL_V2, MTK_THERMAL_V2,
MTK_THERMAL_V3,
}; };
/* MT2701 thermal sensors */ /* MT2701 thermal sensors */
...@@ -245,6 +260,27 @@ enum mtk_thermal_version { ...@@ -245,6 +260,27 @@ enum mtk_thermal_version {
/* The calibration coefficient of sensor */ /* The calibration coefficient of sensor */
#define MT8183_CALIBRATION 153 #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 mtk_thermal;
struct thermal_bank_cfg { struct thermal_bank_cfg {
...@@ -292,6 +328,8 @@ struct mtk_thermal { ...@@ -292,6 +328,8 @@ struct mtk_thermal {
const struct mtk_thermal_data *conf; const struct mtk_thermal_data *conf;
struct mtk_thermal_bank banks[MAX_NUM_ZONES]; struct mtk_thermal_bank banks[MAX_NUM_ZONES];
int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
}; };
/* MT8183 thermal sensor data */ /* MT8183 thermal sensor data */
...@@ -386,6 +424,14 @@ static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, }; ...@@ -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_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, }; 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 * The MT8173 thermal controller has four banks. Each bank can read up to
* four temperature sensors simultaneously. The MT8173 has a total of 5 * four temperature sensors simultaneously. The MT8173 has a total of 5
...@@ -549,8 +595,32 @@ static const struct mtk_thermal_data mt8183_thermal_data = { ...@@ -549,8 +595,32 @@ static const struct mtk_thermal_data mt8183_thermal_data = {
.version = MTK_THERMAL_V1, .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 * @mt: The thermal controller
* @sensno: sensor number * @sensno: sensor number
* @raw: raw ADC value * @raw: raw ADC value
...@@ -603,6 +673,22 @@ static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw) ...@@ -603,6 +673,22 @@ static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
return (format_2 - tmp) * 100; 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 * mtk_thermal_get_bank - get bank
* @bank: The bank * @bank: The bank
...@@ -656,13 +742,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *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++) { for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
raw = readl(mt->thermal_base + conf->msr[i]); raw = readl(mt->thermal_base + conf->msr[i]);
if (mt->conf->version == MTK_THERMAL_V1) { temp = mt->raw_to_mcelsius(
temp = raw_to_mcelsius_v1(
mt, conf->bank_data[bank->id].sensors[i], raw); mt, conf->bank_data[bank->id].sensors[i], raw);
} else {
temp = raw_to_mcelsius_v2(
mt, conf->bank_data[bank->id].sensors[i], raw);
}
/* /*
* The first read of a sensor often contains very high bogus * 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) ...@@ -887,6 +969,25 @@ static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
return 0; 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, static int mtk_thermal_get_calibration_data(struct device *dev,
struct mtk_thermal *mt) struct mtk_thermal *mt)
{ {
...@@ -897,6 +998,7 @@ static int mtk_thermal_get_calibration_data(struct device *dev, ...@@ -897,6 +998,7 @@ static int mtk_thermal_get_calibration_data(struct device *dev,
/* Start with default values */ /* Start with default values */
mt->adc_ge = 512; mt->adc_ge = 512;
mt->adc_oe = 512;
for (i = 0; i < mt->conf->num_sensors; i++) for (i = 0; i < mt->conf->num_sensors; i++)
mt->vts[i] = 260; mt->vts[i] = 260;
mt->degc_cali = 40; mt->degc_cali = 40;
...@@ -922,10 +1024,20 @@ static int mtk_thermal_get_calibration_data(struct device *dev, ...@@ -922,10 +1024,20 @@ static int mtk_thermal_get_calibration_data(struct device *dev,
goto out; 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); ret = mtk_thermal_extract_efuse_v1(mt, buf);
else break;
case MTK_THERMAL_V2:
ret = mtk_thermal_extract_efuse_v2(mt, buf); 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) { if (ret) {
dev_info(dev, "Device not calibrated, using default calibration values\n"); dev_info(dev, "Device not calibrated, using default calibration values\n");
...@@ -955,6 +1067,10 @@ static const struct of_device_id mtk_thermal_of_match[] = { ...@@ -955,6 +1067,10 @@ static const struct of_device_id mtk_thermal_of_match[] = {
.compatible = "mediatek,mt7622-thermal", .compatible = "mediatek,mt7622-thermal",
.data = (void *)&mt7622_thermal_data, .data = (void *)&mt7622_thermal_data,
}, },
{
.compatible = "mediatek,mt7986-thermal",
.data = (void *)&mt7986_thermal_data,
},
{ {
.compatible = "mediatek,mt8183-thermal", .compatible = "mediatek,mt8183-thermal",
.data = (void *)&mt8183_thermal_data, .data = (void *)&mt8183_thermal_data,
...@@ -990,7 +1106,6 @@ static int mtk_thermal_probe(struct platform_device *pdev) ...@@ -990,7 +1106,6 @@ static int mtk_thermal_probe(struct platform_device *pdev)
int ret, i, ctrl_id; int ret, i, ctrl_id;
struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node; struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
struct mtk_thermal *mt; struct mtk_thermal *mt;
struct resource *res;
u64 auxadc_phys_base, apmixed_phys_base; u64 auxadc_phys_base, apmixed_phys_base;
struct thermal_zone_device *tzdev; struct thermal_zone_device *tzdev;
void __iomem *apmixed_base, *auxadc_base; void __iomem *apmixed_base, *auxadc_base;
...@@ -1009,8 +1124,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) ...@@ -1009,8 +1124,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
if (IS_ERR(mt->clk_auxadc)) if (IS_ERR(mt->clk_auxadc))
return PTR_ERR(mt->clk_auxadc); return PTR_ERR(mt->clk_auxadc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
mt->thermal_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mt->thermal_base)) if (IS_ERR(mt->thermal_base))
return PTR_ERR(mt->thermal_base); return PTR_ERR(mt->thermal_base);
...@@ -1070,11 +1184,18 @@ static int mtk_thermal_probe(struct platform_device *pdev) ...@@ -1070,11 +1184,18 @@ static int mtk_thermal_probe(struct platform_device *pdev)
goto err_disable_clk_auxadc; 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_turn_on_buffer(apmixed_base);
mtk_thermal_release_periodic_ts(mt, auxadc_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 (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
for (i = 0; i < mt->conf->num_banks; i++) for (i = 0; i < mt->conf->num_banks; i++)
mtk_thermal_init_bank(mt, i, apmixed_phys_base, mtk_thermal_init_bank(mt, i, apmixed_phys_base,
......
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#include <asm-generic/unaligned.h>
#include <asm/unaligned.h>
#include "../thermal_hwmon.h" #include "../thermal_hwmon.h"
......
...@@ -264,17 +264,17 @@ static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip, ...@@ -264,17 +264,17 @@ static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg); 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; struct qpnp_tm_chip *chip = tz->devdata;
const struct thermal_trip *trip_points; struct thermal_trip trip;
int ret; int ret;
trip_points = of_thermal_get_trip_points(chip->tz_dev); ret = __thermal_zone_get_trip(chip->tz_dev, trip_id, &trip);
if (!trip_points) if (ret)
return -EINVAL; return ret;
if (trip_points[trip].type != THERMAL_TRIP_CRITICAL) if (trip.type != THERMAL_TRIP_CRITICAL)
return 0; return 0;
mutex_lock(&chip->lock); mutex_lock(&chip->lock);
...@@ -300,22 +300,17 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data) ...@@ -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) static int qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip *chip)
{ {
int ntrips; struct thermal_trip trip;
const struct thermal_trip *trips; int i, ret;
int i;
ntrips = of_thermal_get_ntrips(chip->tz_dev); for (i = 0; i < thermal_zone_get_num_trips(chip->tz_dev); i++) {
if (ntrips <= 0)
return THERMAL_TEMP_INVALID;
trips = of_thermal_get_trip_points(chip->tz_dev); ret = thermal_zone_get_trip(chip->tz_dev, i, &trip);
if (!trips) if (ret)
return THERMAL_TEMP_INVALID; continue;
for (i = 0; i < ntrips; i++) { if (trip.type == THERMAL_TRIP_CRITICAL)
if (of_thermal_is_trip_valid(chip->tz_dev, i) && return trip.temperature;
trips[i].type == THERMAL_TRIP_CRITICAL)
return trips[i].temperature;
} }
return THERMAL_TEMP_INVALID; return THERMAL_TEMP_INVALID;
...@@ -353,7 +348,12 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) ...@@ -353,7 +348,12 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip)
if (stage) if (stage)
chip->temp = qpnp_tm_decode_temp(chip, stage); chip->temp = qpnp_tm_decode_temp(chip, stage);
mutex_unlock(&chip->lock);
crit_temp = qpnp_tm_get_critical_trip_temp(chip); crit_temp = qpnp_tm_get_critical_trip_temp(chip);
mutex_lock(&chip->lock);
ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp);
if (ret < 0) if (ret < 0)
goto out; goto out;
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
* Copyright (c) 2015, The Linux Foundation. All rights reserved. * Copyright (c) 2015, The Linux Foundation. All rights reserved.
*/ */
#include <linux/bitfield.h>
#include <linux/nvmem-consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include "tsens.h" #include "tsens.h"
...@@ -15,220 +17,117 @@ ...@@ -15,220 +17,117 @@
#define TM_Sn_STATUS_OFF 0x0030 #define TM_Sn_STATUS_OFF 0x0030
#define TM_TRDY_OFF 0x005c #define TM_TRDY_OFF 0x005c
/* eeprom layout data for 8916 */ /* extra data for 8974 */
#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
#define BKP_SEL 0x3 #define BKP_SEL 0x3
#define BKP_REDUN_SEL 0xe0000000 #define BKP_REDUN_SEL 0xe0000000
#define BKP_REDUN_SHIFT 29
#define BIT_APPEND 0x3 #define BIT_APPEND 0x3
/* eeprom layout data for mdm9607 */ struct tsens_legacy_calibration_format tsens_8916_nvmem = {
#define MDM9607_BASE0_MASK 0x000000ff .base_len = 7,
#define MDM9607_BASE1_MASK 0x000ff000 .base_shift = 3,
#define MDM9607_BASE0_SHIFT 0 .sp_len = 5,
#define MDM9607_BASE1_SHIFT 12 .mode = { 0, 29, 1 },
.invalid = { 0, 31, 1 },
#define MDM9607_S0_P1_MASK 0x00003f00 .base = { { 0, 0 }, { 1, 25 } },
#define MDM9607_S1_P1_MASK 0x03f00000 .sp = {
#define MDM9607_S2_P1_MASK 0x0000003f { { 0, 7 }, { 0, 12 } },
#define MDM9607_S3_P1_MASK 0x0003f000 { { 0, 17 }, { 0, 22 } },
#define MDM9607_S4_P1_MASK 0x0000003f { { 0, 27 }, { 1, 0 } },
{ { 1, 5 }, { 1, 10 } },
#define MDM9607_S0_P2_MASK 0x000fc000 { { 1, 15 }, { 1, 20 } },
#define MDM9607_S1_P2_MASK 0xfc000000 },
#define MDM9607_S2_P2_MASK 0x00000fc0 };
#define MDM9607_S3_P2_MASK 0x00fc0000
#define MDM9607_S4_P2_MASK 0x00000fc0 struct tsens_legacy_calibration_format tsens_8939_nvmem = {
.base_len = 8,
#define MDM9607_S0_P1_SHIFT 8 .base_shift = 2,
#define MDM9607_S1_P1_SHIFT 20 .sp_len = 6,
#define MDM9607_S2_P1_SHIFT 0 .mode = { 12, 0 },
#define MDM9607_S3_P1_SHIFT 12 .invalid = { 12, 2 },
#define MDM9607_S4_P1_SHIFT 0 .base = { { 0, 0 }, { 1, 24 } },
.sp = {
#define MDM9607_S0_P2_SHIFT 14 { { 12, 3 }, { 12, 9 } },
#define MDM9607_S1_P2_SHIFT 26 { { 12, 15 }, { 12, 21 } },
#define MDM9607_S2_P2_SHIFT 6 { { 12, 27 }, { 13, 1 } },
#define MDM9607_S3_P2_SHIFT 18 { { 13, 7 }, { 13, 13 } },
#define MDM9607_S4_P2_SHIFT 6 { { 13, 19 }, { 13, 25 } },
{ { 0, 8 }, { 0, 14 } },
#define MDM9607_CAL_SEL_MASK 0x00700000 { { 0, 20 }, { 0, 26 } },
#define MDM9607_CAL_SEL_SHIFT 20 { { 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) static int calibrate_8916(struct tsens_priv *priv)
{ {
int base0 = 0, base1 = 0, i;
u32 p1[5], p2[5]; u32 p1[5], p2[5];
int mode = 0;
u32 *qfprom_cdata, *qfprom_csel; 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"); qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
if (IS_ERR(qfprom_cdata)) if (IS_ERR(qfprom_cdata))
...@@ -240,37 +139,9 @@ static int calibrate_8916(struct tsens_priv *priv) ...@@ -240,37 +139,9 @@ static int calibrate_8916(struct tsens_priv *priv)
return PTR_ERR(qfprom_csel); return PTR_ERR(qfprom_csel);
} }
mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT; mode = tsens_read_calibration_legacy(priv, &tsens_8916_nvmem,
dev_dbg(priv->dev, "calibration mode is %d\n", mode); p1, p2,
qfprom_cdata, qfprom_csel);
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;
}
compute_intercept_slope(priv, p1, p2, mode); compute_intercept_slope(priv, p1, p2, mode);
kfree(qfprom_cdata); kfree(qfprom_cdata);
...@@ -279,83 +150,68 @@ static int calibrate_8916(struct tsens_priv *priv) ...@@ -279,83 +150,68 @@ static int calibrate_8916(struct tsens_priv *priv)
return 0; 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; int i;
u32 p1[10], p2[10];
int mode = 0; if (mode == NO_PT_CALIB) {
u32 *qfprom_cdata; p1[0] += 2;
u32 cdata[6]; p1[1] += 9;
p1[2] += 3;
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); p1[3] += 9;
if (IS_ERR(qfprom_cdata)) p1[4] += 5;
return PTR_ERR(qfprom_cdata); p1[5] += 9;
p1[6] += 7;
/* Mapping between qfprom nvmem and calibration data */ p1[7] += 10;
cdata[0] = qfprom_cdata[12]; p1[8] += 8;
cdata[1] = qfprom_cdata[13]; p1[9] += 9;
cdata[2] = qfprom_cdata[0]; p1[10] += 8;
cdata[3] = qfprom_cdata[1]; } else {
cdata[4] = qfprom_cdata[22]; for (i = 0; i < 11; i++) {
cdata[5] = qfprom_cdata[21]; /*
* ONE_PT_CALIB requires using addition here instead of
mode = (cdata[0] & MSM8939_CAL_SEL_MASK) >> MSM8939_CAL_SEL_SHIFT; * using OR operation.
dev_dbg(priv->dev, "calibration mode is %d\n", mode); */
p1[i] += BIT_APPEND;
switch (mode) { p2[i] += BIT_APPEND;
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;
} }
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); compute_intercept_slope(priv, p1, p2, mode);
kfree(qfprom_cdata);
return 0; return 0;
} }
static int calibrate_8974(struct tsens_priv *priv) static int calibrate_8974(struct tsens_priv *priv)
{ {
int base1 = 0, base2 = 0, i;
u32 p1[11], p2[11]; u32 p1[11], p2[11];
int mode = 0;
u32 *calib, *bkp; u32 *calib, *bkp;
u32 calib_redun_sel; u32 calib_redun_sel;
int mode, ret;
ret = calibrate_8974_nvmem(priv);
if (ret == 0)
return 0;
calib = (u32 *)qfprom_read(priv->dev, "calib"); calib = (u32 *)qfprom_read(priv->dev, "calib");
if (IS_ERR(calib)) if (IS_ERR(calib))
...@@ -367,116 +223,18 @@ static int calibrate_8974(struct tsens_priv *priv) ...@@ -367,116 +223,18 @@ static int calibrate_8974(struct tsens_priv *priv)
return PTR_ERR(bkp); return PTR_ERR(bkp);
} }
calib_redun_sel = bkp[1] & BKP_REDUN_SEL; calib_redun_sel = FIELD_GET(BKP_REDUN_SEL, bkp[1]);
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;
}
}
switch (mode) { if (calib_redun_sel == BKP_SEL)
case ONE_PT_CALIB: mode = tsens_read_calibration_legacy(priv, &tsens_8974_backup_nvmem,
for (i = 0; i < priv->num_sensors; i++) p1, p2,
p1[i] += (base1 << 2) | BIT_APPEND; bkp, calib);
break; else
case TWO_PT_CALIB: mode = tsens_read_calibration_legacy(priv, &tsens_8974_nvmem,
for (i = 0; i < priv->num_sensors; i++) { p1, p2,
p2[i] += base2; calib, NULL);
p2[i] <<= 2;
p2[i] |= BIT_APPEND; fixup_8974_points(mode, p1, p2);
}
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;
}
compute_intercept_slope(priv, p1, p2, mode); compute_intercept_slope(priv, p1, p2, mode);
kfree(calib); kfree(calib);
...@@ -485,53 +243,19 @@ static int calibrate_8974(struct tsens_priv *priv) ...@@ -485,53 +243,19 @@ static int calibrate_8974(struct tsens_priv *priv)
return 0; return 0;
} }
static int calibrate_9607(struct tsens_priv *priv) static int __init init_8939(struct tsens_priv *priv) {
{ priv->sensor[0].slope = 2911;
int base, i; priv->sensor[1].slope = 2789;
u32 p1[5], p2[5]; priv->sensor[2].slope = 2906;
int mode = 0; priv->sensor[3].slope = 2763;
u32 *qfprom_cdata; priv->sensor[4].slope = 2922;
priv->sensor[5].slope = 2867;
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); priv->sensor[6].slope = 2833;
if (IS_ERR(qfprom_cdata)) priv->sensor[7].slope = 2838;
return PTR_ERR(qfprom_cdata); priv->sensor[8].slope = 2840;
/* priv->sensor[9].slope = 2852; */
mode = (qfprom_cdata[2] & MDM9607_CAL_SEL_MASK) >> MDM9607_CAL_SEL_SHIFT;
dev_dbg(priv->dev, "calibration mode is %d\n", mode); return init_common(priv);
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;
} }
/* v0.1: 8916, 8939, 8974, 9607 */ /* v0.1: 8916, 8939, 8974, 9607 */
...@@ -583,6 +307,12 @@ static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = { ...@@ -583,6 +307,12 @@ static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
[TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0), [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 = { static const struct tsens_ops ops_8916 = {
.init = init_common, .init = init_common,
.calibrate = calibrate_8916, .calibrate = calibrate_8916,
...@@ -599,15 +329,15 @@ struct tsens_plat_data data_8916 = { ...@@ -599,15 +329,15 @@ struct tsens_plat_data data_8916 = {
}; };
static const struct tsens_ops ops_8939 = { static const struct tsens_ops ops_8939 = {
.init = init_common, .init = init_8939,
.calibrate = calibrate_8939, .calibrate = tsens_calibrate_common,
.get_temp = get_temp_common, .get_temp = get_temp_common,
}; };
struct tsens_plat_data data_8939 = { struct tsens_plat_data data_8939 = {
.num_sensors = 10, .num_sensors = 9,
.ops = &ops_8939, .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, .feat = &tsens_v0_1_feat,
.fields = tsens_v0_1_regfields, .fields = tsens_v0_1_regfields,
...@@ -626,16 +356,9 @@ struct tsens_plat_data data_8974 = { ...@@ -626,16 +356,9 @@ struct tsens_plat_data data_8974 = {
.fields = tsens_v0_1_regfields, .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 = { struct tsens_plat_data data_9607 = {
.num_sensors = 5, .num_sensors = 5,
.ops = &ops_9607, .ops = &ops_v0_1,
.hw_ids = (unsigned int []){ 0, 1, 2, 3, 4 },
.feat = &tsens_v0_1_feat, .feat = &tsens_v0_1_feat,
.fields = tsens_v0_1_regfields, .fields = tsens_v0_1_regfields,
}; };
...@@ -21,277 +21,68 @@ ...@@ -21,277 +21,68 @@
#define TM_HIGH_LOW_INT_STATUS_OFF 0x0088 #define TM_HIGH_LOW_INT_STATUS_OFF 0x0088
#define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090 #define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090
/* eeprom layout data for msm8956/76 (v1) */ struct tsens_legacy_calibration_format tsens_qcs404_nvmem = {
#define MSM8976_BASE0_MASK 0xff .base_len = 8,
#define MSM8976_BASE1_MASK 0xff .base_shift = 2,
#define MSM8976_BASE1_SHIFT 8 .sp_len = 6,
.mode = { 4, 0 },
#define MSM8976_S0_P1_MASK 0x3f00 .invalid = { 4, 2 },
#define MSM8976_S1_P1_MASK 0x3f00000 .base = { { 4, 3 }, { 4, 11 } },
#define MSM8976_S2_P1_MASK 0x3f .sp = {
#define MSM8976_S3_P1_MASK 0x3f000 { { 0, 0 }, { 0, 6 } },
#define MSM8976_S4_P1_MASK 0x3f00 { { 0, 12 }, { 0, 18 } },
#define MSM8976_S5_P1_MASK 0x3f00000 { { 0, 24 }, { 0, 30 } },
#define MSM8976_S6_P1_MASK 0x3f { { 1, 4 }, { 1, 10 } },
#define MSM8976_S7_P1_MASK 0x3f000 { { 1, 16 }, { 1, 22 } },
#define MSM8976_S8_P1_MASK 0x1f8 { { 2, 0 }, { 2, 6 } },
#define MSM8976_S9_P1_MASK 0x1f8000 { { 2, 12 }, { 2, 18 } },
#define MSM8976_S10_P1_MASK 0xf8000000 { { 2, 24 }, { 2, 30 } },
#define MSM8976_S10_P1_MASK_1 0x1 { { 3, 4 }, { 3, 10 } },
{ { 3, 16 }, { 3, 22 } },
#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;
for (i = 0; i < priv->num_sensors; i++) { struct tsens_legacy_calibration_format tsens_8976_nvmem = {
priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) - .base_len = 8,
(MSM8976_CAL_DEGC_PT1 * .base_shift = 2,
priv->sensor[i].slope); .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) static int calibrate_v1(struct tsens_priv *priv)
{ {
u32 base0 = 0, base1 = 0;
u32 p1[10], p2[10]; u32 p1[10], p2[10];
u32 mode = 0, lsb = 0, msb = 0;
u32 *qfprom_cdata; u32 *qfprom_cdata;
int i; int mode, ret;
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);
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);
ret = tsens_calibrate_common(priv);
if (!ret)
return 0; 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;
qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
if (IS_ERR(qfprom_cdata)) if (IS_ERR(qfprom_cdata))
return PTR_ERR(qfprom_cdata); return PTR_ERR(qfprom_cdata);
mode = (qfprom_cdata[4] & MSM8976_CAL_SEL_MASK); mode = tsens_read_calibration_legacy(priv, &tsens_qcs404_nvmem,
dev_dbg(priv->dev, "calibration mode is %d\n", mode); p1, p2,
qfprom_cdata, NULL);
switch (mode) { compute_intercept_slope(priv, p1, p2, 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);
kfree(qfprom_cdata); kfree(qfprom_cdata);
return 0; return 0;
...@@ -365,6 +156,22 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = { ...@@ -365,6 +156,22 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
[TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0), [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 = { static const struct tsens_ops ops_generic_v1 = {
.init = init_common, .init = init_common,
.calibrate = calibrate_v1, .calibrate = calibrate_v1,
...@@ -377,17 +184,28 @@ struct tsens_plat_data data_tsens_v1 = { ...@@ -377,17 +184,28 @@ struct tsens_plat_data data_tsens_v1 = {
.fields = tsens_v1_regfields, .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 = { static const struct tsens_ops ops_8976 = {
.init = init_common, .init = init_common,
.calibrate = calibrate_8976, .calibrate = tsens_calibrate_common,
.get_temp = get_temp_tsens_valid, .get_temp = get_temp_tsens_valid,
}; };
/* Valid for both MSM8956 and MSM8976. */
struct tsens_plat_data data_8976 = { struct tsens_plat_data data_8976 = {
.num_sensors = 11, .num_sensors = 11,
.ops = &ops_8976, .ops = &ops_8976,
.hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
.feat = &tsens_v1_feat, .feat = &tsens_v1_feat,
.fields = tsens_v1_regfields, .fields = tsens_v1_regfields,
}; };
...@@ -70,6 +70,171 @@ char *qfprom_read(struct device *dev, const char *cname) ...@@ -70,6 +70,171 @@ char *qfprom_read(struct device *dev, const char *cname)
return ret; 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 * Use this function on devices where slope and offset calculations
* depend on calibration data read from qfprom. On others the slope * 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) ...@@ -459,12 +624,9 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
{ {
struct tsens_priv *priv = data; struct tsens_priv *priv = data;
struct tsens_irq_data d; struct tsens_irq_data d;
bool enable = true, disable = false; int i;
unsigned long flags;
int temp, ret, i;
for (i = 0; i < priv->num_sensors; i++) { for (i = 0; i < priv->num_sensors; i++) {
bool trigger = false;
const struct tsens_sensor *s = &priv->sensor[i]; const struct tsens_sensor *s = &priv->sensor[i];
u32 hw_id = s->hw_id; u32 hw_id = s->hw_id;
...@@ -472,52 +634,8 @@ static irqreturn_t tsens_irq_thread(int irq, void *data) ...@@ -472,52 +634,8 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
continue; continue;
if (!tsens_threshold_violated(priv, hw_id, &d)) if (!tsens_threshold_violated(priv, hw_id, &d))
continue; 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 && thermal_zone_device_update(s->tzd, THERMAL_EVENT_UNSPECIFIED);
!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);
}
if (tsens_version(priv) < VER_0_1) { if (tsens_version(priv) < VER_0_1) {
/* Constraint: There is only 1 interrupt control register for all /* Constraint: There is only 1 interrupt control register for all
...@@ -983,6 +1101,9 @@ static const struct of_device_id tsens_table[] = { ...@@ -983,6 +1101,9 @@ static const struct of_device_id tsens_table[] = {
}, { }, {
.compatible = "qcom,msm8939-tsens", .compatible = "qcom,msm8939-tsens",
.data = &data_8939, .data = &data_8939,
}, {
.compatible = "qcom,msm8956-tsens",
.data = &data_8956,
}, { }, {
.compatible = "qcom,msm8960-tsens", .compatible = "qcom,msm8960-tsens",
.data = &data_8960, .data = &data_8960,
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#ifndef __QCOM_TSENS_H__ #ifndef __QCOM_TSENS_H__
#define __QCOM_TSENS_H__ #define __QCOM_TSENS_H__
#define NO_PT_CALIB 0x0
#define ONE_PT_CALIB 0x1 #define ONE_PT_CALIB 0x1
#define ONE_PT_CALIB2 0x2 #define ONE_PT_CALIB2 0x2
#define TWO_PT_CALIB 0x3 #define TWO_PT_CALIB 0x3
...@@ -17,6 +18,8 @@ ...@@ -17,6 +18,8 @@
#define THRESHOLD_MAX_ADC_CODE 0x3ff #define THRESHOLD_MAX_ADC_CODE 0x3ff
#define THRESHOLD_MIN_ADC_CODE 0x0 #define THRESHOLD_MIN_ADC_CODE 0x0
#define MAX_SENSORS 16
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#include <linux/regmap.h> #include <linux/regmap.h>
...@@ -581,7 +584,48 @@ struct tsens_priv { ...@@ -581,7 +584,48 @@ struct tsens_priv {
struct tsens_sensor sensor[]; 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); 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); void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode);
int init_common(struct tsens_priv *priv); int init_common(struct tsens_priv *priv);
int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp); int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp);
...@@ -594,7 +638,7 @@ extern struct tsens_plat_data data_8960; ...@@ -594,7 +638,7 @@ extern struct tsens_plat_data data_8960;
extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607; extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;
/* TSENS v1 targets */ /* 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 */ /* TSENS v2 targets */
extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2; extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;
......
...@@ -529,7 +529,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev) ...@@ -529,7 +529,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
if (ret) if (ret)
goto error_unregister; goto error_unregister;
ret = of_thermal_get_ntrips(tsc->zone); ret = thermal_zone_get_num_trips(tsc->zone);
if (ret < 0) if (ret < 0)
goto error_unregister; goto error_unregister;
......
...@@ -278,52 +278,12 @@ static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp) ...@@ -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); return rcar_thermal_get_current_temp(priv, temp);
} }
static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone, static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
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 = {
.get_temp = rcar_thermal_get_temp, .get_temp = rcar_thermal_get_temp,
}; };
static struct thermal_zone_device_ops rcar_thermal_zone_ops = { static struct thermal_trip trips[] = {
.get_temp = rcar_thermal_get_temp, { .type = THERMAL_TRIP_CRITICAL, .temperature = 90000 }
.get_trip_type = rcar_thermal_get_trip_type,
.get_trip_temp = rcar_thermal_get_trip_temp,
}; };
/* /*
...@@ -529,11 +489,10 @@ static int rcar_thermal_probe(struct platform_device *pdev) ...@@ -529,11 +489,10 @@ static int rcar_thermal_probe(struct platform_device *pdev)
if (chip->use_of_thermal) { if (chip->use_of_thermal) {
priv->zone = devm_thermal_of_zone_register( priv->zone = devm_thermal_of_zone_register(
dev, i, priv, dev, i, priv,
&rcar_thermal_zone_of_ops); &rcar_thermal_zone_ops);
} else { } else {
priv->zone = thermal_zone_device_register( priv->zone = thermal_zone_device_register_with_trips(
"rcar_thermal", "rcar_thermal", trips, ARRAY_SIZE(trips), 0, priv,
1, 0, priv,
&rcar_thermal_zone_ops, NULL, 0, &rcar_thermal_zone_ops, NULL, 0,
idle); idle);
......
...@@ -60,7 +60,7 @@ enum adc_sort_mode { ...@@ -60,7 +60,7 @@ enum adc_sort_mode {
#include "thermal_hwmon.h" #include "thermal_hwmon.h"
/** /*
* The max sensors is two in rockchip SoCs. * The max sensors is two in rockchip SoCs.
* Two sensors: CPU and GPU sensor. * Two sensors: CPU and GPU sensor.
*/ */
...@@ -169,7 +169,7 @@ struct rockchip_thermal_data { ...@@ -169,7 +169,7 @@ struct rockchip_thermal_data {
enum tshut_polarity tshut_polarity; enum tshut_polarity tshut_polarity;
}; };
/** /*
* TSADC Sensor Register description: * TSADC Sensor Register description:
* *
* TSADCV2_* are used for RK3288 SoCs, the other chips can reuse it. * TSADCV2_* are used for RK3288 SoCs, the other chips can reuse it.
...@@ -1339,7 +1339,7 @@ rockchip_thermal_register_sensor(struct platform_device *pdev, ...@@ -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 * @reset: the reset controller of tsadc
*/ */
static void rockchip_thermal_reset_controller(struct reset_control *reset) static void rockchip_thermal_reset_controller(struct reset_control *reset)
...@@ -1354,7 +1354,6 @@ static int rockchip_thermal_probe(struct platform_device *pdev) ...@@ -1354,7 +1354,6 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct rockchip_thermal_data *thermal; struct rockchip_thermal_data *thermal;
const struct of_device_id *match; const struct of_device_id *match;
struct resource *res;
int irq; int irq;
int i; int i;
int error; int error;
...@@ -1378,8 +1377,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev) ...@@ -1378,8 +1377,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
if (!thermal->chip) if (!thermal->chip)
return -EINVAL; return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); thermal->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
thermal->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(thermal->regs)) if (IS_ERR(thermal->regs))
return PTR_ERR(thermal->regs); return PTR_ERR(thermal->regs);
......
...@@ -260,31 +260,23 @@ static int exynos_tmu_initialize(struct platform_device *pdev) ...@@ -260,31 +260,23 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
{ {
struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tzd = data->tzd; struct thermal_zone_device *tzd = data->tzd;
const struct thermal_trip * const trips = int num_trips = thermal_zone_get_num_trips(tzd);
of_thermal_get_trip_points(tzd);
unsigned int status; unsigned int status;
int ret = 0, temp, hyst; int ret = 0, temp;
if (!trips) { ret = thermal_zone_get_crit_temp(tzd, &temp);
dev_err(&pdev->dev, if (ret && data->soc != SOC_ARCH_EXYNOS5433) { /* FIXME */
"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) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"No CRITICAL trip point defined in device tree!\n"); "No CRITICAL trip point defined in device tree!\n");
goto out; goto out;
} }
if (of_thermal_get_ntrips(tzd) > data->ntrip) { if (num_trips > data->ntrip) {
dev_info(&pdev->dev, dev_info(&pdev->dev,
"More trip points than supported by this TMU.\n"); "More trip points than supported by this TMU.\n");
dev_info(&pdev->dev, dev_info(&pdev->dev,
"%d trip points should be configured in polling mode.\n", "%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); mutex_lock(&data->lock);
...@@ -297,25 +289,22 @@ static int exynos_tmu_initialize(struct platform_device *pdev) ...@@ -297,25 +289,22 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
ret = -EBUSY; ret = -EBUSY;
} else { } else {
int i, ntrips = int i, ntrips =
min_t(int, of_thermal_get_ntrips(tzd), data->ntrip); min_t(int, num_trips, data->ntrip);
data->tmu_initialize(pdev); data->tmu_initialize(pdev);
/* Write temperature code for rising and falling threshold */ /* Write temperature code for rising and falling threshold */
for (i = 0; i < ntrips; i++) { 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 */ struct thermal_trip trip;
ret = tzd->ops->get_trip_hyst(tzd, i, &hyst);
ret = thermal_zone_get_trip(tzd, i, &trip);
if (ret) if (ret)
goto err; 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); data->tmu_clear_irqs(data);
...@@ -360,21 +349,23 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) ...@@ -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, 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 = struct thermal_trip trip;
of_thermal_get_trip_points(data->tzd);
u8 ref, th_code; 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); th_code = temp_to_code(data, ref);
writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
} }
temp -= ref; 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 */ /* failing thresholds are not supported on Exynos4210 */
...@@ -562,13 +553,14 @@ static void exynos4210_tmu_control(struct platform_device *pdev, bool on) ...@@ -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 exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tz = data->tzd; struct thermal_zone_device *tz = data->tzd;
struct thermal_trip trip;
unsigned int con, interrupt_en = 0, i; unsigned int con, interrupt_en = 0, i;
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
if (on) { if (on) {
for (i = 0; i < data->ntrip; i++) { for (i = 0; i < data->ntrip; i++) {
if (!of_thermal_is_trip_valid(tz, i)) if (thermal_zone_get_trip(tz, i, &trip))
continue; continue;
interrupt_en |= interrupt_en |=
...@@ -592,13 +584,14 @@ static void exynos5433_tmu_control(struct platform_device *pdev, bool on) ...@@ -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 exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tz = data->tzd; struct thermal_zone_device *tz = data->tzd;
struct thermal_trip trip;
unsigned int con, interrupt_en = 0, pd_det_en, i; unsigned int con, interrupt_en = 0, pd_det_en, i;
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
if (on) { if (on) {
for (i = 0; i < data->ntrip; i++) { for (i = 0; i < data->ntrip; i++) {
if (!of_thermal_is_trip_valid(tz, i)) if (thermal_zone_get_trip(tz, i, &trip))
continue; continue;
interrupt_en |= interrupt_en |=
...@@ -623,13 +616,14 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) ...@@ -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 exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tz = data->tzd; struct thermal_zone_device *tz = data->tzd;
struct thermal_trip trip;
unsigned int con, interrupt_en = 0, i; unsigned int con, interrupt_en = 0, i;
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
if (on) { if (on) {
for (i = 0; i < data->ntrip; i++) { for (i = 0; i < data->ntrip; i++) {
if (!of_thermal_is_trip_valid(tz, i)) if (thermal_zone_get_trip(tz, i, &trip))
continue; continue;
interrupt_en |= interrupt_en |=
......
...@@ -91,7 +91,6 @@ static int spear_thermal_probe(struct platform_device *pdev) ...@@ -91,7 +91,6 @@ static int spear_thermal_probe(struct platform_device *pdev)
struct thermal_zone_device *spear_thermal = NULL; struct thermal_zone_device *spear_thermal = NULL;
struct spear_thermal_dev *stdev; struct spear_thermal_dev *stdev;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct resource *res;
int ret = 0, val; int ret = 0, val;
if (!np || !of_property_read_u32(np, "st,thermal-flags", &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) ...@@ -104,8 +103,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
/* Enable thermal sensor */ /* Enable thermal sensor */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); stdev->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
stdev->thermal_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(stdev->thermal_base)) if (IS_ERR(stdev->thermal_base))
return PTR_ERR(stdev->thermal_base); return PTR_ERR(stdev->thermal_base);
......
...@@ -134,48 +134,12 @@ static int st_thermal_get_temp(struct thermal_zone_device *th, int *temperature) ...@@ -134,48 +134,12 @@ static int st_thermal_get_temp(struct thermal_zone_device *th, int *temperature)
return 0; 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 = { static struct thermal_zone_device_ops st_tz_ops = {
.get_temp = st_thermal_get_temp, .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, int st_thermal_register(struct platform_device *pdev,
const struct of_device_id *st_thermal_of_match) const struct of_device_id *st_thermal_of_match)
{ {
...@@ -238,8 +202,11 @@ int st_thermal_register(struct platform_device *pdev, ...@@ -238,8 +202,11 @@ int st_thermal_register(struct platform_device *pdev,
polling_delay = sensor->ops->register_enable_irq ? 0 : 1000; polling_delay = sensor->ops->register_enable_irq ? 0 : 1000;
trip.temperature = sensor->cdata->crit_temp;
trip.type = THERMAL_TRIP_CRITICAL;
sensor->thermal_dev = sensor->thermal_dev =
thermal_zone_device_register(dev_name(dev), 1, 0, sensor, thermal_zone_device_register_with_trips(dev_name(dev), &trip, 1, 0, sensor,
&st_tz_ops, NULL, 0, polling_delay); &st_tz_ops, NULL, 0, polling_delay);
if (IS_ERR(sensor->thermal_dev)) { if (IS_ERR(sensor->thermal_dev)) {
dev_err(dev, "failed to register thermal zone device\n"); dev_err(dev, "failed to register thermal zone device\n");
......
...@@ -210,7 +210,7 @@ static int sun8i_h3_ths_calibrate(struct ths_device *tmdev, ...@@ -210,7 +210,7 @@ static int sun8i_h3_ths_calibrate(struct ths_device *tmdev,
regmap_update_bits(tmdev->regmap, regmap_update_bits(tmdev->regmap,
SUN8I_THS_TEMP_CALIB + (4 * (i >> 1)), SUN8I_THS_TEMP_CALIB + (4 * (i >> 1)),
0xfff << offset, TEMP_CALIB_MASK << offset,
caldata[i] << offset); caldata[i] << offset);
} }
...@@ -271,7 +271,7 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev, ...@@ -271,7 +271,7 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
offset = (i % 2) * 16; offset = (i % 2) * 16;
regmap_update_bits(tmdev->regmap, regmap_update_bits(tmdev->regmap,
SUN50I_H6_THS_TEMP_CALIB + (i / 2 * 4), SUN50I_H6_THS_TEMP_CALIB + (i / 2 * 4),
0xfff << offset, TEMP_CALIB_MASK << offset,
cdata << offset); cdata << offset);
} }
......
...@@ -582,23 +582,23 @@ static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id) ...@@ -582,23 +582,23 @@ static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id)
return temp; 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_thermctl_zone *zone = tz->devdata;
struct tegra_soctherm *ts = zone->ts; struct tegra_soctherm *ts = zone->ts;
struct thermal_trip trip;
const struct tegra_tsensor_group *sg = zone->sg; const struct tegra_tsensor_group *sg = zone->sg;
struct device *dev = zone->dev; struct device *dev = zone->dev;
enum thermal_trip_type type;
int ret; int ret;
if (!tz) if (!tz)
return -EINVAL; return -EINVAL;
ret = tz->ops->get_trip_type(tz, trip, &type); ret = __thermal_zone_get_trip(tz, trip_id, &trip);
if (ret) if (ret)
return ret; return ret;
if (type == THERMAL_TRIP_CRITICAL) { if (trip.type == THERMAL_TRIP_CRITICAL) {
/* /*
* If thermtrips property is set in DT, * If thermtrips property is set in DT,
* doesn't need to program critical type trip to HW, * 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 ...@@ -609,7 +609,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip
else else
return 0; return 0;
} else if (type == THERMAL_TRIP_HOT) { } else if (trip.type == THERMAL_TRIP_HOT) {
int i; int i;
for (i = 0; i < THROTTLE_SIZE; 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 ...@@ -620,7 +620,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip
continue; continue;
cdev = ts->throt_cfgs[i].cdev; 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); stc = find_throttle_cfg_by_name(ts, cdev->type);
else else
continue; continue;
...@@ -687,25 +687,20 @@ static const struct thermal_zone_device_ops tegra_of_thermal_ops = { ...@@ -687,25 +687,20 @@ static const struct thermal_zone_device_ops tegra_of_thermal_ops = {
.set_trips = tegra_thermctl_set_trips, .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; int i, ret;
enum thermal_trip_type type; struct thermal_trip trip;
ntrips = of_thermal_get_ntrips(tz); for (i = 0; i < thermal_zone_get_num_trips(tz); i++) {
if (ntrips <= 0)
return -EINVAL;
for (i = 0; i < ntrips; i++) { ret = thermal_zone_get_trip(tz, i, &trip);
ret = tz->ops->get_trip_type(tz, i, &type);
if (ret) if (ret)
return -EINVAL; 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, ...@@ -747,7 +742,7 @@ static int tegra_soctherm_set_hwtrips(struct device *dev,
/* Get thermtrips. If missing, try to get critical trips. */ /* Get thermtrips. If missing, try to get critical trips. */
temperature = tsensor_group_thermtrip_get(ts, sg->id); temperature = tsensor_group_thermtrip_get(ts, sg->id);
if (min_low_temp == temperature) 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; temperature = max_high_temp;
ret = thermtrip_program(dev, sg, temperature); ret = thermtrip_program(dev, sg, temperature);
......
...@@ -316,18 +316,17 @@ static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd, ...@@ -316,18 +316,17 @@ static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
*hot_trip = 85000; *hot_trip = 85000;
*crit_trip = 90000; *crit_trip = 90000;
for (i = 0; i < tzd->num_trips; i++) { for (i = 0; i < thermal_zone_get_num_trips(tzd); i++) {
enum thermal_trip_type type;
int trip_temp;
tzd->ops->get_trip_temp(tzd, i, &trip_temp); struct thermal_trip trip;
tzd->ops->get_trip_type(tzd, i, &type);
if (type == THERMAL_TRIP_HOT) thermal_zone_get_trip(tzd, i, &trip);
*hot_trip = trip_temp;
if (type == THERMAL_TRIP_CRITICAL) if (trip.type == THERMAL_TRIP_HOT)
*crit_trip = trip_temp; *hot_trip = trip.temperature;
if (trip.type == THERMAL_TRIP_CRITICAL)
*crit_trip = trip.temperature;
} }
/* clamp hardware trips to the calibration limits */ /* clamp hardware trips to the calibration limits */
......
...@@ -344,35 +344,31 @@ static void handle_critical_trips(struct thermal_zone_device *tz, ...@@ -344,35 +344,31 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
tz->ops->critical(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; struct thermal_trip trip;
int trip_temp, hyst = 0;
/* Ignore disabled trip points */ /* Ignore disabled trip points */
if (test_bit(trip, &tz->trips_disabled)) if (test_bit(trip_id, &tz->trips_disabled))
return; return;
tz->ops->get_trip_temp(tz, trip, &trip_temp); __thermal_zone_get_trip(tz, trip_id, &trip);
tz->ops->get_trip_type(tz, trip, &type);
if (tz->ops->get_trip_hyst)
tz->ops->get_trip_hyst(tz, trip, &hyst);
if (tz->last_temperature != THERMAL_TEMP_INVALID) { if (tz->last_temperature != THERMAL_TEMP_INVALID) {
if (tz->last_temperature < trip_temp && if (tz->last_temperature < trip.temperature &&
tz->temperature >= trip_temp) tz->temperature >= trip.temperature)
thermal_notify_tz_trip_up(tz->id, trip, thermal_notify_tz_trip_up(tz->id, trip_id,
tz->temperature); tz->temperature);
if (tz->last_temperature >= trip_temp && if (tz->last_temperature >= trip.temperature &&
tz->temperature < (trip_temp - hyst)) tz->temperature < (trip.temperature - trip.hysteresis))
thermal_notify_tz_trip_down(tz->id, trip, thermal_notify_tz_trip_down(tz->id, trip_id,
tz->temperature); tz->temperature);
} }
if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT) if (trip.type == THERMAL_TRIP_CRITICAL || trip.type == THERMAL_TRIP_HOT)
handle_critical_trips(tz, trip, trip_temp, type); handle_critical_trips(tz, trip_id, trip.temperature, trip.type);
else else
handle_non_critical_trips(tz, trip); handle_non_critical_trips(tz, trip_id);
} }
static void update_temperature(struct thermal_zone_device *tz) 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 ...@@ -1166,6 +1162,119 @@ static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms
*delay_jiffies = round_jiffies(*delay_jiffies); *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 * thermal_zone_device_register_with_trips() - register a new thermal zone device
* @type: the thermal zone device type * @type: the thermal zone device type
...@@ -1198,8 +1307,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t ...@@ -1198,8 +1307,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
int polling_delay) int polling_delay)
{ {
struct thermal_zone_device *tz; struct thermal_zone_device *tz;
enum thermal_trip_type trip_type;
int trip_temp;
int id; int id;
int result; int result;
int count; int count;
...@@ -1239,7 +1346,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t ...@@ -1239,7 +1346,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
return ERR_PTR(-EINVAL); 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); return ERR_PTR(-EINVAL);
tz = kzalloc(sizeof(*tz), GFP_KERNEL); tz = kzalloc(sizeof(*tz), GFP_KERNEL);
...@@ -1290,9 +1397,10 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t ...@@ -1290,9 +1397,10 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
goto release_device; goto release_device;
for (count = 0; count < num_trips; count++) { for (count = 0; count < num_trips; count++) {
if (tz->ops->get_trip_type(tz, count, &trip_type) || struct thermal_trip trip;
tz->ops->get_trip_temp(tz, count, &trip_temp) ||
!trip_temp) result = thermal_zone_get_trip(tz, count, &trip);
if (result)
set_bit(count, &tz->trips_disabled); set_bit(count, &tz->trips_disabled);
} }
......
...@@ -114,6 +114,8 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, ...@@ -114,6 +114,8 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
/* Helpers */ /* Helpers */
void __thermal_zone_set_trips(struct thermal_zone_device *tz); 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); int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
/* sysfs I/F */ /* sysfs I/F */
...@@ -137,28 +139,6 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, ...@@ -137,28 +139,6 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
#endif /* CONFIG_THERMAL_STATISTICS */ #endif /* CONFIG_THERMAL_STATISTICS */
/* device tree support */ /* 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); int thermal_zone_device_is_enabled(struct thermal_zone_device *tz);
#endif /* __THERMAL_CORE_H__ */ #endif /* __THERMAL_CORE_H__ */
...@@ -83,7 +83,7 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) ...@@ -83,7 +83,7 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
int ret = -EINVAL; int ret = -EINVAL;
int count; int count;
int crit_temp = INT_MAX; int crit_temp = INT_MAX;
enum thermal_trip_type type; struct thermal_trip trip;
lockdep_assert_held(&tz->lock); lockdep_assert_held(&tz->lock);
...@@ -91,10 +91,9 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) ...@@ -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) { if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) {
for (count = 0; count < tz->num_trips; count++) { for (count = 0; count < tz->num_trips; count++) {
ret = tz->ops->get_trip_type(tz, count, &type); ret = __thermal_zone_get_trip(tz, count, &trip);
if (!ret && type == THERMAL_TRIP_CRITICAL) { if (!ret && trip.type == THERMAL_TRIP_CRITICAL) {
ret = tz->ops->get_trip_temp(tz, count, crit_temp = trip.temperature;
&crit_temp);
break; break;
} }
} }
...@@ -164,29 +163,30 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_temp); ...@@ -164,29 +163,30 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
*/ */
void __thermal_zone_set_trips(struct thermal_zone_device *tz) void __thermal_zone_set_trips(struct thermal_zone_device *tz)
{ {
int low = -INT_MAX; struct thermal_trip trip;
int high = INT_MAX; int low = -INT_MAX, high = INT_MAX;
int trip_temp, hysteresis;
int i, ret; int i, ret;
lockdep_assert_held(&tz->lock); lockdep_assert_held(&tz->lock);
if (!tz->ops->set_trips || !tz->ops->get_trip_hyst) if (!tz->ops->set_trips)
return; return;
for (i = 0; i < tz->num_trips; i++) { for (i = 0; i < tz->num_trips; i++) {
int trip_low; int trip_low;
tz->ops->get_trip_temp(tz, i, &trip_temp); ret = __thermal_zone_get_trip(tz, i , &trip);
tz->ops->get_trip_hyst(tz, i, &hysteresis); if (ret)
return;
trip_low = trip_temp - hysteresis; trip_low = trip.temperature - trip.hysteresis;
if (trip_low < tz->temperature && trip_low > low) if (trip_low < tz->temperature && trip_low > low)
low = trip_low; low = trip_low;
if (trip_temp > tz->temperature && trip_temp < high) if (trip.temperature > tz->temperature &&
high = trip_temp; trip.temperature < high)
high = trip.temperature;
} }
/* No need to change trip points */ /* No need to change trip points */
......
...@@ -39,7 +39,6 @@ static const struct thermal_zone_device_ops thermal_mmio_ops = { ...@@ -39,7 +39,6 @@ static const struct thermal_zone_device_ops thermal_mmio_ops = {
static int thermal_mmio_probe(struct platform_device *pdev) static int thermal_mmio_probe(struct platform_device *pdev)
{ {
struct resource *resource;
struct thermal_mmio *sensor; struct thermal_mmio *sensor;
int (*sensor_init_func)(struct platform_device *pdev, int (*sensor_init_func)(struct platform_device *pdev,
struct thermal_mmio *sensor); struct thermal_mmio *sensor);
...@@ -51,8 +50,7 @@ static int thermal_mmio_probe(struct platform_device *pdev) ...@@ -51,8 +50,7 @@ static int thermal_mmio_probe(struct platform_device *pdev)
if (!sensor) if (!sensor)
return -ENOMEM; return -ENOMEM;
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); sensor->mmio_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource);
if (IS_ERR(sensor->mmio_base)) if (IS_ERR(sensor->mmio_base))
return PTR_ERR(sensor->mmio_base); return PTR_ERR(sensor->mmio_base);
......
...@@ -452,7 +452,8 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) ...@@ -452,7 +452,8 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
struct sk_buff *msg = p->msg; struct sk_buff *msg = p->msg;
struct thermal_zone_device *tz; struct thermal_zone_device *tz;
struct nlattr *start_trip; struct nlattr *start_trip;
int i, id; struct thermal_trip trip;
int ret, i, id;
if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID])
return -EINVAL; return -EINVAL;
...@@ -471,18 +472,14 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) ...@@ -471,18 +472,14 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
for (i = 0; i < tz->num_trips; i++) { for (i = 0; i < tz->num_trips; i++) {
enum thermal_trip_type type; ret = __thermal_zone_get_trip(tz, i, &trip);
int temp, hyst = 0; if (ret)
goto out_cancel_nest;
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);
if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, i) || 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_TYPE, trip.type) ||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TEMP, temp) || nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TEMP, trip.temperature) ||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_HYST, hyst)) nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_HYST, trip.hysteresis))
goto out_cancel_nest; goto out_cancel_nest;
} }
......
...@@ -19,117 +19,6 @@ ...@@ -19,117 +19,6 @@
#include "thermal_core.h" #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 ***/ /*** functions parsing device tree nodes ***/
static int of_find_trip_id(struct device_node *np, struct device_node *trip) 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, ...@@ -628,11 +517,6 @@ struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor,
goto out_kfree_trips; 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->bind = thermal_of_bind;
of_ops->unbind = thermal_of_unbind; of_ops->unbind = thermal_of_unbind;
......
...@@ -83,27 +83,25 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr, ...@@ -83,27 +83,25 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct thermal_zone_device *tz = to_thermal_zone(dev); struct thermal_zone_device *tz = to_thermal_zone(dev);
enum thermal_trip_type type; struct thermal_trip trip;
int trip, result; int trip_id, result;
if (!tz->ops->get_trip_type) if (sscanf(attr->attr.name, "trip_point_%d_type", &trip_id) != 1)
return -EPERM;
if (sscanf(attr->attr.name, "trip_point_%d_type", &trip) != 1)
return -EINVAL; return -EINVAL;
mutex_lock(&tz->lock); mutex_lock(&tz->lock);
if (device_is_registered(dev)) if (device_is_registered(dev))
result = tz->ops->get_trip_type(tz, trip, &type); result = __thermal_zone_get_trip(tz, trip_id, &trip);
else else
result = -ENODEV; result = -ENODEV;
mutex_unlock(&tz->lock); mutex_unlock(&tz->lock);
if (result) if (result)
return result; return result;
switch (type) { switch (trip.type) {
case THERMAL_TRIP_CRITICAL: case THERMAL_TRIP_CRITICAL:
return sprintf(buf, "critical\n"); return sprintf(buf, "critical\n");
case THERMAL_TRIP_HOT: case THERMAL_TRIP_HOT:
...@@ -122,17 +120,10 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, ...@@ -122,17 +120,10 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct thermal_zone_device *tz = to_thermal_zone(dev); struct thermal_zone_device *tz = to_thermal_zone(dev);
int trip, ret; struct thermal_trip trip;
int temperature, hyst = 0; int trip_id, ret;
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) if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1)
return -EINVAL;
if (kstrtoint(buf, 10, &temperature))
return -EINVAL; return -EINVAL;
mutex_lock(&tz->lock); mutex_lock(&tz->lock);
...@@ -142,36 +133,19 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, ...@@ -142,36 +133,19 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
goto unlock; goto unlock;
} }
if (tz->ops->set_trip_temp) { ret = __thermal_zone_get_trip(tz, trip_id, &trip);
ret = tz->ops->set_trip_temp(tz, trip, temperature);
if (ret) if (ret)
goto unlock; goto unlock;
}
if (tz->trips) ret = kstrtoint(buf, 10, &trip.temperature);
tz->trips[trip].temperature = temperature;
if (tz->ops->get_trip_hyst) {
ret = tz->ops->get_trip_hyst(tz, trip, &hyst);
if (ret) if (ret)
goto unlock; goto unlock;
}
ret = tz->ops->get_trip_type(tz, trip, &type);
if (ret)
goto unlock;
thermal_notify_tz_trip_change(tz->id, trip, type, temperature, hyst);
__thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
ret = thermal_zone_set_trip(tz, trip_id, &trip);
unlock: unlock:
mutex_unlock(&tz->lock); mutex_unlock(&tz->lock);
if (ret) return ret ? ret : count;
return ret;
return count;
} }
static ssize_t static ssize_t
...@@ -179,19 +153,16 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, ...@@ -179,19 +153,16 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct thermal_zone_device *tz = to_thermal_zone(dev); struct thermal_zone_device *tz = to_thermal_zone(dev);
int trip, ret; struct thermal_trip trip;
int temperature; int trip_id, ret;
if (!tz->ops->get_trip_temp)
return -EPERM;
if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1) if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1)
return -EINVAL; return -EINVAL;
mutex_lock(&tz->lock); mutex_lock(&tz->lock);
if (device_is_registered(dev)) if (device_is_registered(dev))
ret = tz->ops->get_trip_temp(tz, trip, &temperature); ret = __thermal_zone_get_trip(tz, trip_id, &trip);
else else
ret = -ENODEV; ret = -ENODEV;
...@@ -200,7 +171,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, ...@@ -200,7 +171,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
if (ret) if (ret)
return ret; return ret;
return sprintf(buf, "%d\n", temperature); return sprintf(buf, "%d\n", trip.temperature);
} }
static ssize_t static ssize_t
...@@ -208,16 +179,13 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, ...@@ -208,16 +179,13 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct thermal_zone_device *tz = to_thermal_zone(dev); struct thermal_zone_device *tz = to_thermal_zone(dev);
int trip, ret; struct thermal_trip trip;
int temperature; int trip_id, ret;
if (!tz->ops->set_trip_hyst) if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1)
return -EPERM;
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1)
return -EINVAL; return -EINVAL;
if (kstrtoint(buf, 10, &temperature)) if (kstrtoint(buf, 10, &trip.hysteresis))
return -EINVAL; return -EINVAL;
mutex_lock(&tz->lock); mutex_lock(&tz->lock);
...@@ -227,16 +195,11 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, ...@@ -227,16 +195,11 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
goto unlock; goto unlock;
} }
/* ret = __thermal_zone_get_trip(tz, trip_id, &trip);
* We are not doing any check on the 'temperature' value if (ret)
* here. The driver implementing 'set_trip_hyst' has to goto unlock;
* take care of this.
*/
ret = tz->ops->set_trip_hyst(tz, trip, temperature);
if (!ret)
__thermal_zone_set_trips(tz);
ret = thermal_zone_set_trip(tz, trip_id, &trip);
unlock: unlock:
mutex_unlock(&tz->lock); mutex_unlock(&tz->lock);
...@@ -248,25 +211,22 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, ...@@ -248,25 +211,22 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct thermal_zone_device *tz = to_thermal_zone(dev); struct thermal_zone_device *tz = to_thermal_zone(dev);
int trip, ret; struct thermal_trip trip;
int temperature; int trip_id, ret;
if (!tz->ops->get_trip_hyst) if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1)
return -EPERM;
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1)
return -EINVAL; return -EINVAL;
mutex_lock(&tz->lock); mutex_lock(&tz->lock);
if (device_is_registered(dev)) if (device_is_registered(dev))
ret = tz->ops->get_trip_hyst(tz, trip, &temperature); ret = __thermal_zone_get_trip(tz, trip_id, &trip);
else else
ret = -ENODEV; ret = -ENODEV;
mutex_unlock(&tz->lock); mutex_unlock(&tz->lock);
return ret ? ret : sprintf(buf, "%d\n", temperature); return ret ? ret : sprintf(buf, "%d\n", trip.hysteresis);
} }
static ssize_t static ssize_t
...@@ -491,7 +451,6 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) ...@@ -491,7 +451,6 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
return -ENOMEM; return -ENOMEM;
} }
if (tz->ops->get_trip_hyst) {
tz->trip_hyst_attrs = kcalloc(tz->num_trips, tz->trip_hyst_attrs = kcalloc(tz->num_trips,
sizeof(*tz->trip_hyst_attrs), sizeof(*tz->trip_hyst_attrs),
GFP_KERNEL); GFP_KERNEL);
...@@ -500,13 +459,11 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) ...@@ -500,13 +459,11 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
kfree(tz->trip_temp_attrs); kfree(tz->trip_temp_attrs);
return -ENOMEM; return -ENOMEM;
} }
}
attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL); attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
if (!attrs) { if (!attrs) {
kfree(tz->trip_type_attrs); kfree(tz->trip_type_attrs);
kfree(tz->trip_temp_attrs); kfree(tz->trip_temp_attrs);
if (tz->ops->get_trip_hyst)
kfree(tz->trip_hyst_attrs); kfree(tz->trip_hyst_attrs);
return -ENOMEM; return -ENOMEM;
} }
...@@ -540,9 +497,6 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) ...@@ -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; 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, snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH,
"trip_point_%d_hyst", indx); "trip_point_%d_hyst", indx);
...@@ -579,7 +533,6 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz) ...@@ -579,7 +533,6 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz)
kfree(tz->trip_type_attrs); kfree(tz->trip_type_attrs);
kfree(tz->trip_temp_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); kfree(tz->trips_attribute_group.attrs);
} }
......
...@@ -38,21 +38,6 @@ ...@@ -38,21 +38,6 @@
/* Update rates */ /* Update rates */
#define FAST_TEMP_MONITORING_RATE 250 #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 #ifdef CONFIG_TI_THERMAL
int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, char *domain); int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, char *domain);
int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id); int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id);
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/** /*
* uniphier_thermal.c - Socionext UniPhier thermal driver * uniphier_thermal.c - Socionext UniPhier thermal driver
* Copyright 2014 Panasonic Corporation * Copyright 2014 Panasonic Corporation
* Copyright 2016-2017 Socionext Inc. * Copyright 2016-2017 Socionext Inc.
...@@ -248,8 +248,7 @@ static int uniphier_tm_probe(struct platform_device *pdev) ...@@ -248,8 +248,7 @@ static int uniphier_tm_probe(struct platform_device *pdev)
struct regmap *regmap; struct regmap *regmap;
struct device_node *parent; struct device_node *parent;
struct uniphier_tm_dev *tdev; struct uniphier_tm_dev *tdev;
const struct thermal_trip *trips; int i, ret, irq, crit_temp = INT_MAX;
int i, ret, irq, ntrips, crit_temp = INT_MAX;
tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL); tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL);
if (!tdev) if (!tdev)
...@@ -296,20 +295,18 @@ static int uniphier_tm_probe(struct platform_device *pdev) ...@@ -296,20 +295,18 @@ static int uniphier_tm_probe(struct platform_device *pdev)
return PTR_ERR(tdev->tz_dev); 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 */ /* set alert temperatures */
for (i = 0; i < ntrips; i++) { for (i = 0; i < thermal_zone_get_num_trips(tdev->tz_dev); i++) {
if (trips[i].type == THERMAL_TRIP_CRITICAL && struct thermal_trip trip;
trips[i].temperature < crit_temp)
crit_temp = trips[i].temperature; ret = thermal_zone_get_trip(tdev->tz_dev, i, &trip);
uniphier_tm_set_alert(tdev, i, trips[i].temperature); 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; tdev->alert_en[i] = true;
} }
if (crit_temp > CRITICAL_TEMP_LIMIT) { if (crit_temp > CRITICAL_TEMP_LIMIT) {
......
...@@ -334,6 +334,18 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev, ...@@ -334,6 +334,18 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev,
} }
#endif #endif
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
struct thermal_trip *trip);
int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
struct thermal_trip *trip);
int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id,
const struct thermal_trip *trip);
int thermal_zone_get_num_trips(struct thermal_zone_device *tz);
int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp);
#ifdef CONFIG_THERMAL #ifdef CONFIG_THERMAL
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int, struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
void *, struct thermal_zone_device_ops *, void *, struct thermal_zone_device_ops *,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册