Commit 18f3896d authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-Thermal-and-hwmon-extensions'

Ido Schimmel says:

====================
mlxsw: Thermal and hwmon extensions

This patchset from Vadim includes various enhancements to thermal and
hwmon code in mlxsw.

Patch #1 adds a thermal zone for each inter-connect device (gearbox).
These devices are present in SN3800 systems and code to expose their
temperature via hwmon was added in commit 2e265a8b ("mlxsw: core:
Extend hwmon interface with inter-connect temperature attributes").

Currently, there are multiple thermal zones in mlxsw and only a few
cooling devices. Patch #2 detects the hottest thermal zone and the
cooling devices are switched to follow its trends. RFC was sent last
month [1].

Patch #3 allows to read and report negative temperature of the sensors
mlxsw exposes via hwmon and thermal subsystems.

v2 (Andrew Lunn):
* In patch #3, replace '%u' with '%d' in mlxsw_hwmon_module_temp_show()

[1] https://patchwork.ozlabs.org/patch/1107161/
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c04b6ea4 f485cc36
...@@ -52,8 +52,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev, ...@@ -52,8 +52,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
container_of(attr, struct mlxsw_hwmon_attr, dev_attr); container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon; struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int temp; int temp, index;
int index;
int err; int err;
index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index, index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
...@@ -65,7 +64,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev, ...@@ -65,7 +64,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
return err; return err;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
return sprintf(buf, "%u\n", temp); return sprintf(buf, "%d\n", temp);
} }
static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev, static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
...@@ -76,8 +75,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev, ...@@ -76,8 +75,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
container_of(attr, struct mlxsw_hwmon_attr, dev_attr); container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon; struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int temp_max; int temp_max, index;
int index;
int err; int err;
index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index, index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
...@@ -89,7 +87,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev, ...@@ -89,7 +87,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
return err; return err;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL);
return sprintf(buf, "%u\n", temp_max); return sprintf(buf, "%d\n", temp_max);
} }
static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev, static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
...@@ -215,8 +213,8 @@ static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev, ...@@ -215,8 +213,8 @@ static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
container_of(attr, struct mlxsw_hwmon_attr, dev_attr); container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon; struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int temp;
u8 module; u8 module;
int temp;
int err; int err;
module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count; module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
...@@ -227,7 +225,7 @@ static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev, ...@@ -227,7 +225,7 @@ static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
return err; return err;
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
return sprintf(buf, "%u\n", temp); return sprintf(buf, "%d\n", temp);
} }
static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev, static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */ #define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */
#define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2) #define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2)
#define MLXSW_THERMAL_ZONE_MAX_NAME 16 #define MLXSW_THERMAL_ZONE_MAX_NAME 16
#define MLXSW_THERMAL_TEMP_SCORE_MAX GENMASK(31, 0)
#define MLXSW_THERMAL_MAX_STATE 10 #define MLXSW_THERMAL_MAX_STATE 10
#define MLXSW_THERMAL_MAX_DUTY 255 #define MLXSW_THERMAL_MAX_DUTY 255
/* Minimum and maximum fan allowed speed in percent: from 20% to 100%. Values /* Minimum and maximum fan allowed speed in percent: from 20% to 100%. Values
...@@ -98,7 +99,7 @@ struct mlxsw_thermal_module { ...@@ -98,7 +99,7 @@ struct mlxsw_thermal_module {
struct thermal_zone_device *tzdev; struct thermal_zone_device *tzdev;
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS]; struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
enum thermal_device_mode mode; enum thermal_device_mode mode;
int module; int module; /* Module or gearbox number */
}; };
struct mlxsw_thermal { struct mlxsw_thermal {
...@@ -111,6 +112,10 @@ struct mlxsw_thermal { ...@@ -111,6 +112,10 @@ struct mlxsw_thermal {
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS]; struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
enum thermal_device_mode mode; enum thermal_device_mode mode;
struct mlxsw_thermal_module *tz_module_arr; struct mlxsw_thermal_module *tz_module_arr;
struct mlxsw_thermal_module *tz_gearbox_arr;
u8 tz_gearbox_num;
unsigned int tz_highest_score;
struct thermal_zone_device *tz_highest_dev;
}; };
static inline u8 mlxsw_state_to_duty(int state) static inline u8 mlxsw_state_to_duty(int state)
...@@ -195,6 +200,34 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core, ...@@ -195,6 +200,34 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
return 0; return 0;
} }
static void mlxsw_thermal_tz_score_update(struct mlxsw_thermal *thermal,
struct thermal_zone_device *tzdev,
struct mlxsw_thermal_trip *trips,
int temp)
{
struct mlxsw_thermal_trip *trip = trips;
unsigned int score, delta, i, shift = 1;
/* Calculate thermal zone score, if temperature is above the critical
* threshold score is set to MLXSW_THERMAL_TEMP_SCORE_MAX.
*/
score = MLXSW_THERMAL_TEMP_SCORE_MAX;
for (i = MLXSW_THERMAL_TEMP_TRIP_NORM; i < MLXSW_THERMAL_NUM_TRIPS;
i++, trip++) {
if (temp < trip->temp) {
delta = DIV_ROUND_CLOSEST(temp, trip->temp - temp);
score = delta * shift;
break;
}
shift *= 256;
}
if (score > thermal->tz_highest_score) {
thermal->tz_highest_score = score;
thermal->tz_highest_dev = tzdev;
}
}
static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev, static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
struct thermal_cooling_device *cdev) struct thermal_cooling_device *cdev)
{ {
...@@ -279,7 +312,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev, ...@@ -279,7 +312,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
struct mlxsw_thermal *thermal = tzdev->devdata; struct mlxsw_thermal *thermal = tzdev->devdata;
struct device *dev = thermal->bus_info->dev; struct device *dev = thermal->bus_info->dev;
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int temp; int temp;
int err; int err;
mlxsw_reg_mtmp_pack(mtmp_pl, 0, false, false); mlxsw_reg_mtmp_pack(mtmp_pl, 0, false, false);
...@@ -290,8 +323,11 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev, ...@@ -290,8 +323,11 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
return err; return err;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
if (temp > 0)
mlxsw_thermal_tz_score_update(thermal, tzdev, thermal->trips,
temp);
*p_temp = (int) temp; *p_temp = temp;
return 0; return 0;
} }
...@@ -351,6 +387,22 @@ static int mlxsw_thermal_set_trip_hyst(struct thermal_zone_device *tzdev, ...@@ -351,6 +387,22 @@ static int mlxsw_thermal_set_trip_hyst(struct thermal_zone_device *tzdev,
return 0; return 0;
} }
static int mlxsw_thermal_trend_get(struct thermal_zone_device *tzdev,
int trip, enum thermal_trend *trend)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
struct mlxsw_thermal *thermal = tz->parent;
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
return -EINVAL;
if (tzdev == thermal->tz_highest_dev)
return 1;
*trend = THERMAL_TREND_STABLE;
return 0;
}
static struct thermal_zone_device_ops mlxsw_thermal_ops = { 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,
...@@ -362,6 +414,7 @@ static struct thermal_zone_device_ops mlxsw_thermal_ops = { ...@@ -362,6 +414,7 @@ static struct thermal_zone_device_ops mlxsw_thermal_ops = {
.set_trip_temp = mlxsw_thermal_set_trip_temp, .set_trip_temp = mlxsw_thermal_set_trip_temp,
.get_trip_hyst = mlxsw_thermal_get_trip_hyst, .get_trip_hyst = mlxsw_thermal_get_trip_hyst,
.set_trip_hyst = mlxsw_thermal_set_trip_hyst, .set_trip_hyst = mlxsw_thermal_set_trip_hyst,
.get_trend = mlxsw_thermal_trend_get,
}; };
static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev, static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
...@@ -450,7 +503,7 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, ...@@ -450,7 +503,7 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
struct mlxsw_thermal *thermal = tz->parent; struct mlxsw_thermal *thermal = tz->parent;
struct device *dev = thermal->bus_info->dev; struct device *dev = thermal->bus_info->dev;
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int temp; int temp;
int err; int err;
/* Read module temperature. */ /* Read module temperature. */
...@@ -466,13 +519,15 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, ...@@ -466,13 +519,15 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
return 0; return 0;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
*p_temp = (int) temp; *p_temp = temp;
if (!temp) if (!temp)
return 0; return 0;
/* Update trip points. */ /* Update trip points. */
mlxsw_thermal_module_trips_update(dev, thermal->core, tz); err = mlxsw_thermal_module_trips_update(dev, thermal->core, tz);
if (!err && temp > 0)
mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
return 0; return 0;
} }
...@@ -537,10 +592,6 @@ mlxsw_thermal_module_trip_hyst_set(struct thermal_zone_device *tzdev, int trip, ...@@ -537,10 +592,6 @@ mlxsw_thermal_module_trip_hyst_set(struct thermal_zone_device *tzdev, int trip,
return 0; return 0;
} }
static struct thermal_zone_params mlxsw_thermal_module_params = {
.governor_name = "user_space",
};
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,
...@@ -552,6 +603,46 @@ static struct thermal_zone_device_ops mlxsw_thermal_module_ops = { ...@@ -552,6 +603,46 @@ static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
.set_trip_temp = mlxsw_thermal_module_trip_temp_set, .set_trip_temp = mlxsw_thermal_module_trip_temp_set,
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get, .get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set, .set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
.get_trend = mlxsw_thermal_trend_get,
};
static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
int *p_temp)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
struct mlxsw_thermal *thermal = tz->parent;
char mtmp_pl[MLXSW_REG_MTMP_LEN];
u16 index;
int temp;
int err;
index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
if (err)
return err;
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
if (temp > 0)
mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
*p_temp = temp;
return 0;
}
static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
.bind = mlxsw_thermal_module_bind,
.unbind = mlxsw_thermal_module_unbind,
.get_mode = mlxsw_thermal_module_mode_get,
.set_mode = mlxsw_thermal_module_mode_set,
.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,
.get_trend = mlxsw_thermal_trend_get,
}; };
static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev, static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
...@@ -667,13 +758,13 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz) ...@@ -667,13 +758,13 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
MLXSW_THERMAL_TRIP_MASK, MLXSW_THERMAL_TRIP_MASK,
module_tz, module_tz,
&mlxsw_thermal_module_ops, &mlxsw_thermal_module_ops,
&mlxsw_thermal_module_params, NULL, 0, 0);
0, 0);
if (IS_ERR(module_tz->tzdev)) { if (IS_ERR(module_tz->tzdev)) {
err = PTR_ERR(module_tz->tzdev); err = PTR_ERR(module_tz->tzdev);
return err; return err;
} }
module_tz->mode = THERMAL_DEVICE_ENABLED;
return 0; return 0;
} }
...@@ -779,6 +870,92 @@ mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal) ...@@ -779,6 +870,92 @@ mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
kfree(thermal->tz_module_arr); kfree(thermal->tz_module_arr);
} }
static int
mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
{
char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
gearbox_tz->module + 1);
gearbox_tz->tzdev = thermal_zone_device_register(tz_name,
MLXSW_THERMAL_NUM_TRIPS,
MLXSW_THERMAL_TRIP_MASK,
gearbox_tz,
&mlxsw_thermal_gearbox_ops,
NULL, 0, 0);
if (IS_ERR(gearbox_tz->tzdev))
return PTR_ERR(gearbox_tz->tzdev);
gearbox_tz->mode = THERMAL_DEVICE_ENABLED;
return 0;
}
static void
mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
{
thermal_zone_device_unregister(gearbox_tz->tzdev);
}
static int
mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
struct mlxsw_thermal *thermal)
{
struct mlxsw_thermal_module *gearbox_tz;
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
int i;
int err;
if (!mlxsw_core_res_query_enabled(core))
return 0;
mlxsw_reg_mgpir_pack(mgpir_pl);
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
if (err)
return err;
mlxsw_reg_mgpir_unpack(mgpir_pl, &thermal->tz_gearbox_num, NULL, NULL);
if (!thermal->tz_gearbox_num)
return 0;
thermal->tz_gearbox_arr = kcalloc(thermal->tz_gearbox_num,
sizeof(*thermal->tz_gearbox_arr),
GFP_KERNEL);
if (!thermal->tz_gearbox_arr)
return -ENOMEM;
for (i = 0; i < thermal->tz_gearbox_num; i++) {
gearbox_tz = &thermal->tz_gearbox_arr[i];
memcpy(gearbox_tz->trips, default_thermal_trips,
sizeof(thermal->trips));
gearbox_tz->module = i;
gearbox_tz->parent = thermal;
err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
if (err)
goto err_unreg_tz_gearbox;
}
return 0;
err_unreg_tz_gearbox:
for (i--; i >= 0; i--)
mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
kfree(thermal->tz_gearbox_arr);
return err;
}
static void
mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal)
{
int i;
if (!mlxsw_core_res_query_enabled(thermal->core))
return;
for (i = thermal->tz_gearbox_num - 1; i >= 0; i--)
mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
kfree(thermal->tz_gearbox_arr);
}
int mlxsw_thermal_init(struct mlxsw_core *core, int mlxsw_thermal_init(struct mlxsw_core *core,
const struct mlxsw_bus_info *bus_info, const struct mlxsw_bus_info *bus_info,
struct mlxsw_thermal **p_thermal) struct mlxsw_thermal **p_thermal)
...@@ -869,10 +1046,16 @@ int mlxsw_thermal_init(struct mlxsw_core *core, ...@@ -869,10 +1046,16 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
if (err) if (err)
goto err_unreg_tzdev; goto err_unreg_tzdev;
err = mlxsw_thermal_gearboxes_init(dev, core, thermal);
if (err)
goto err_unreg_modules_tzdev;
thermal->mode = THERMAL_DEVICE_ENABLED; thermal->mode = THERMAL_DEVICE_ENABLED;
*p_thermal = thermal; *p_thermal = thermal;
return 0; return 0;
err_unreg_modules_tzdev:
mlxsw_thermal_modules_fini(thermal);
err_unreg_tzdev: err_unreg_tzdev:
if (thermal->tzdev) { if (thermal->tzdev) {
thermal_zone_device_unregister(thermal->tzdev); thermal_zone_device_unregister(thermal->tzdev);
...@@ -891,6 +1074,7 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal) ...@@ -891,6 +1074,7 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
{ {
int i; int i;
mlxsw_thermal_gearboxes_fini(thermal);
mlxsw_thermal_modules_fini(thermal); mlxsw_thermal_modules_fini(thermal);
if (thermal->tzdev) { if (thermal->tzdev) {
thermal_zone_device_unregister(thermal->tzdev); thermal_zone_device_unregister(thermal->tzdev);
......
...@@ -8050,7 +8050,10 @@ MLXSW_REG_DEFINE(mtmp, MLXSW_REG_MTMP_ID, MLXSW_REG_MTMP_LEN); ...@@ -8050,7 +8050,10 @@ MLXSW_REG_DEFINE(mtmp, MLXSW_REG_MTMP_ID, MLXSW_REG_MTMP_LEN);
MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 12); MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 12);
/* Convert to milli degrees Celsius */ /* Convert to milli degrees Celsius */
#define MLXSW_REG_MTMP_TEMP_TO_MC(val) (val * 125) #define MLXSW_REG_MTMP_TEMP_TO_MC(val) ({ typeof(val) v_ = (val); \
((v_) >= 0) ? ((v_) * 125) : \
((s16)((GENMASK(15, 0) + (v_) + 1) \
* 125)); })
/* reg_mtmp_temperature /* reg_mtmp_temperature
* Temperature reading from the sensor. Reading is in 0.125 Celsius * Temperature reading from the sensor. Reading is in 0.125 Celsius
...@@ -8121,11 +8124,10 @@ static inline void mlxsw_reg_mtmp_pack(char *payload, u16 sensor_index, ...@@ -8121,11 +8124,10 @@ static inline void mlxsw_reg_mtmp_pack(char *payload, u16 sensor_index,
MLXSW_REG_MTMP_THRESH_HI); MLXSW_REG_MTMP_THRESH_HI);
} }
static inline void mlxsw_reg_mtmp_unpack(char *payload, unsigned int *p_temp, static inline void mlxsw_reg_mtmp_unpack(char *payload, int *p_temp,
unsigned int *p_max_temp, int *p_max_temp, char *sensor_name)
char *sensor_name)
{ {
u16 temp; s16 temp;
if (p_temp) { if (p_temp) {
temp = mlxsw_reg_mtmp_temperature_get(payload); temp = mlxsw_reg_mtmp_temperature_get(payload);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment