@@ -28,6 +28,7 @@ struct cros_ec_hwmon_priv {
2828 const char * temp_sensor_names [EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES ];
2929 u8 usable_fans ;
3030 bool fan_control_supported ;
31+ bool temp_threshold_supported ;
3132 u8 manual_fans ; /* bits to indicate whether the fan is set to manual */
3233 u8 manual_fan_pwm [EC_FAN_SPEED_ENTRIES ];
3334};
@@ -116,6 +117,23 @@ static int cros_ec_hwmon_read_temp(struct cros_ec_device *cros_ec, u8 index, u8
116117 return 0 ;
117118}
118119
120+ static int cros_ec_hwmon_read_temp_threshold (struct cros_ec_device * cros_ec , u8 index ,
121+ enum ec_temp_thresholds threshold , u32 * temp )
122+ {
123+ struct ec_params_thermal_get_threshold_v1 req = {};
124+ struct ec_thermal_config resp ;
125+ int ret ;
126+
127+ req .sensor_num = index ;
128+ ret = cros_ec_cmd (cros_ec , 1 , EC_CMD_THERMAL_GET_THRESHOLD ,
129+ & req , sizeof (req ), & resp , sizeof (resp ));
130+ if (ret < 0 )
131+ return ret ;
132+
133+ * temp = resp .temp_host [threshold ];
134+ return 0 ;
135+ }
136+
119137static bool cros_ec_hwmon_is_error_fan (u16 speed )
120138{
121139 return speed == EC_FAN_SPEED_NOT_PRESENT || speed == EC_FAN_SPEED_STALLED ;
@@ -134,12 +152,29 @@ static long cros_ec_hwmon_temp_to_millicelsius(u8 temp)
134152 return kelvin_to_millicelsius ((((long )temp ) + EC_TEMP_SENSOR_OFFSET ));
135153}
136154
155+ static bool cros_ec_hwmon_attr_is_temp_threshold (u32 attr )
156+ {
157+ return attr == hwmon_temp_max ||
158+ attr == hwmon_temp_crit ||
159+ attr == hwmon_temp_emergency ;
160+ }
161+
162+ static enum ec_temp_thresholds cros_ec_hwmon_attr_to_thres (u32 attr )
163+ {
164+ if (attr == hwmon_temp_max )
165+ return EC_TEMP_THRESH_WARN ;
166+ else if (attr == hwmon_temp_crit )
167+ return EC_TEMP_THRESH_HIGH ;
168+ return EC_TEMP_THRESH_HALT ; /* attr == hwmon_temp_emergency */
169+ }
170+
137171static int cros_ec_hwmon_read (struct device * dev , enum hwmon_sensor_types type ,
138172 u32 attr , int channel , long * val )
139173{
140174 struct cros_ec_hwmon_priv * priv = dev_get_drvdata (dev );
141175 int ret = - EOPNOTSUPP ;
142176 u8 control_method ;
177+ u32 threshold ;
143178 u8 pwm_value ;
144179 u16 speed ;
145180 u8 temp ;
@@ -187,6 +222,13 @@ static int cros_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
187222 ret = cros_ec_hwmon_read_temp (priv -> cros_ec , channel , & temp );
188223 if (ret == 0 )
189224 * val = cros_ec_hwmon_is_error_temp (temp );
225+
226+ } else if (cros_ec_hwmon_attr_is_temp_threshold (attr )) {
227+ ret = cros_ec_hwmon_read_temp_threshold (priv -> cros_ec , channel ,
228+ cros_ec_hwmon_attr_to_thres (attr ),
229+ & threshold );
230+ if (ret == 0 )
231+ * val = kelvin_to_millicelsius (threshold );
190232 }
191233 }
192234
@@ -291,8 +333,14 @@ static umode_t cros_ec_hwmon_is_visible(const void *data, enum hwmon_sensor_type
291333 if (priv -> fan_control_supported && priv -> usable_fans & BIT (channel ))
292334 return 0644 ;
293335 } else if (type == hwmon_temp ) {
294- if (priv -> temp_sensor_names [channel ])
295- return 0444 ;
336+ if (priv -> temp_sensor_names [channel ]) {
337+ if (cros_ec_hwmon_attr_is_temp_threshold (attr )) {
338+ if (priv -> temp_threshold_supported )
339+ return 0444 ;
340+ } else {
341+ return 0444 ;
342+ }
343+ }
296344 }
297345
298346 return 0 ;
@@ -310,7 +358,8 @@ static const struct hwmon_channel_info * const cros_ec_hwmon_info[] = {
310358 HWMON_PWM_INPUT | HWMON_PWM_ENABLE ,
311359 HWMON_PWM_INPUT | HWMON_PWM_ENABLE ,
312360 HWMON_PWM_INPUT | HWMON_PWM_ENABLE ),
313- #define CROS_EC_HWMON_TEMP_PARAMS (HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL )
361+ #define CROS_EC_HWMON_TEMP_PARAMS (HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL | \
362+ HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_EMERGENCY )
314363 HWMON_CHANNEL_INFO (temp ,
315364 CROS_EC_HWMON_TEMP_PARAMS ,
316365 CROS_EC_HWMON_TEMP_PARAMS ,
@@ -520,6 +569,8 @@ static int cros_ec_hwmon_probe(struct platform_device *pdev)
520569 cros_ec_hwmon_probe_temp_sensors (dev , priv , thermal_version );
521570 cros_ec_hwmon_probe_fans (priv );
522571 priv -> fan_control_supported = cros_ec_hwmon_probe_fan_control_supported (priv -> cros_ec );
572+ priv -> temp_threshold_supported = is_cros_ec_cmd_available (priv -> cros_ec ,
573+ EC_CMD_THERMAL_GET_THRESHOLD , 1 );
523574 cros_ec_hwmon_register_fan_cooling_devices (dev , priv );
524575
525576 hwmon_dev = devm_hwmon_device_register_with_info (dev , "cros_ec" , priv ,
0 commit comments