mlxsw: core: Add support for negative temperature readout
authorVadim Pasternak <vadimp@mellanox.com>
Mon, 24 Jun 2019 10:32:03 +0000 (13:32 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 24 Jun 2019 15:15:42 +0000 (08:15 -0700)
Extend macros MLXSW_REG_MTMP_TEMP_TO_MC() to allow support of negative
temperature readout, since chip and others thermal components are
capable of operating within the negative temperature.
With no such support negative temperature will be consider as very high
temperature and it will cause wrong readout and thermal shutdown.
For negative values 2`s complement is used.
Tested in chamber.
Example of chip ambient temperature readout with chamber temperature:
-10 Celsius:
temp1:             -6.0C  (highest =  -5.0C)
-5 Celsius:
temp1:             -1.0C  (highest =  -1.0C)

v2 (Andrew Lunn):
* Replace '%u' with '%d' in mlxsw_hwmon_module_temp_show()

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
drivers/net/ethernet/mellanox/mlxsw/reg.h

index 056e3f55ae6cc68c32f7ef4b8e77dd3ba6be90e3..5b00726c434615c4a7a0e4e9a5735280000a1934 100644 (file)
@@ -52,8 +52,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
                        container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
        struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
        char mtmp_pl[MLXSW_REG_MTMP_LEN];
-       unsigned int temp;
-       int index;
+       int temp, index;
        int err;
 
        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,
                return err;
        }
        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,
@@ -76,8 +75,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
                        container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
        struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
        char mtmp_pl[MLXSW_REG_MTMP_LEN];
-       unsigned int temp_max;
-       int index;
+       int temp_max, index;
        int err;
 
        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,
                return err;
        }
        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,
@@ -215,8 +213,8 @@ static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
                        container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
        struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
        char mtmp_pl[MLXSW_REG_MTMP_LEN];
-       unsigned int temp;
        u8 module;
+       int temp;
        int err;
 
        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,
                return err;
        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,
index 504a34d240f78489c297cec11282446efbbc86ea..35a1dc89c28a9bb06a7f4e6598dddf12152c6680 100644 (file)
@@ -312,7 +312,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
        struct mlxsw_thermal *thermal = tzdev->devdata;
        struct device *dev = thermal->bus_info->dev;
        char mtmp_pl[MLXSW_REG_MTMP_LEN];
-       unsigned int temp;
+       int temp;
        int err;
 
        mlxsw_reg_mtmp_pack(mtmp_pl, 0, false, false);
@@ -327,7 +327,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
                mlxsw_thermal_tz_score_update(thermal, tzdev, thermal->trips,
                                              temp);
 
-       *p_temp = (int) temp;
+       *p_temp = temp;
        return 0;
 }
 
@@ -503,7 +503,7 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
        struct mlxsw_thermal *thermal = tz->parent;
        struct device *dev = thermal->bus_info->dev;
        char mtmp_pl[MLXSW_REG_MTMP_LEN];
-       unsigned int temp;
+       int temp;
        int err;
 
        /* Read module temperature. */
@@ -519,14 +519,14 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
                return 0;
        }
        mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
-       *p_temp = (int) temp;
+       *p_temp = temp;
 
        if (!temp)
                return 0;
 
        /* Update trip points. */
        err = mlxsw_thermal_module_trips_update(dev, thermal->core, tz);
-       if (!err)
+       if (!err && temp > 0)
                mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
 
        return 0;
@@ -612,8 +612,8 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
        struct mlxsw_thermal_module *tz = tzdev->devdata;
        struct mlxsw_thermal *thermal = tz->parent;
        char mtmp_pl[MLXSW_REG_MTMP_LEN];
-       unsigned int temp;
        u16 index;
+       int temp;
        int err;
 
        index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
@@ -627,7 +627,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
        if (temp > 0)
                mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
 
-       *p_temp = (int) temp;
+       *p_temp = temp;
        return 0;
 }
 
index 452f645fa040c20bdb1e60da40218aa163035a6f..e5f6bfd8a35aa30476e45c5cfe14a6b7449a270d 100644 (file)
@@ -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);
 
 /* 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
  * 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,
                                                    MLXSW_REG_MTMP_THRESH_HI);
 }
 
-static inline void mlxsw_reg_mtmp_unpack(char *payload, unsigned int *p_temp,
-                                        unsigned int *p_max_temp,
-                                        char *sensor_name)
+static inline void mlxsw_reg_mtmp_unpack(char *payload, int *p_temp,
+                                        int *p_max_temp, char *sensor_name)
 {
-       u16 temp;
+       s16 temp;
 
        if (p_temp) {
                temp = mlxsw_reg_mtmp_temperature_get(payload);