1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved
3  * Copyright (c) 2016 Ivan Vecera <cera@cera.cz>
4  */
5 
6 #include <linux/kernel.h>
7 #include <linux/types.h>
8 #include <linux/device.h>
9 #include <linux/sysfs.h>
10 #include <linux/thermal.h>
11 #include <linux/err.h>
12 #include <linux/sfp.h>
13 
14 #include "core.h"
15 #include "core_env.h"
16 
17 #define MLXSW_THERMAL_POLL_INT	1000	/* ms */
18 #define MLXSW_THERMAL_SLOW_POLL_INT	20000	/* ms */
19 #define MLXSW_THERMAL_ASIC_TEMP_NORM	75000	/* 75C */
20 #define MLXSW_THERMAL_ASIC_TEMP_HIGH	85000	/* 85C */
21 #define MLXSW_THERMAL_ASIC_TEMP_HOT	105000	/* 105C */
22 #define MLXSW_THERMAL_ASIC_TEMP_CRIT	110000	/* 110C */
23 #define MLXSW_THERMAL_HYSTERESIS_TEMP	5000	/* 5C */
24 #define MLXSW_THERMAL_MODULE_TEMP_SHIFT	(MLXSW_THERMAL_HYSTERESIS_TEMP * 2)
25 #define MLXSW_THERMAL_ZONE_MAX_NAME	16
26 #define MLXSW_THERMAL_TEMP_SCORE_MAX	GENMASK(31, 0)
27 #define MLXSW_THERMAL_MAX_STATE	10
28 #define MLXSW_THERMAL_MAX_DUTY	255
29 /* Minimum and maximum fan allowed speed in percent: from 20% to 100%. Values
30  * MLXSW_THERMAL_MAX_STATE + x, where x is between 2 and 10 are used for
31  * setting fan speed dynamic minimum. For example, if value is set to 14 (40%)
32  * cooling levels vector will be set to 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10 to
33  * introduce PWM speed in percent: 40, 40, 40, 40, 40, 50, 60. 70, 80, 90, 100.
34  */
35 #define MLXSW_THERMAL_SPEED_MIN		(MLXSW_THERMAL_MAX_STATE + 2)
36 #define MLXSW_THERMAL_SPEED_MAX		(MLXSW_THERMAL_MAX_STATE * 2)
37 #define MLXSW_THERMAL_SPEED_MIN_LEVEL	2		/* 20% */
38 
39 /* External cooling devices, allowed for binding to mlxsw thermal zones. */
40 static char * const mlxsw_thermal_external_allowed_cdev[] = {
41 	"mlxreg_fan",
42 };
43 
44 enum mlxsw_thermal_trips {
45 	MLXSW_THERMAL_TEMP_TRIP_NORM,
46 	MLXSW_THERMAL_TEMP_TRIP_HIGH,
47 	MLXSW_THERMAL_TEMP_TRIP_HOT,
48 	MLXSW_THERMAL_TEMP_TRIP_CRIT,
49 };
50 
51 struct mlxsw_thermal_trip {
52 	int	type;
53 	int	temp;
54 	int	hyst;
55 	int	min_state;
56 	int	max_state;
57 };
58 
59 static const struct mlxsw_thermal_trip default_thermal_trips[] = {
60 	{	/* In range - 0-40% PWM */
61 		.type		= THERMAL_TRIP_ACTIVE,
62 		.temp		= MLXSW_THERMAL_ASIC_TEMP_NORM,
63 		.hyst		= MLXSW_THERMAL_HYSTERESIS_TEMP,
64 		.min_state	= 0,
65 		.max_state	= (4 * MLXSW_THERMAL_MAX_STATE) / 10,
66 	},
67 	{
68 		/* In range - 40-100% PWM */
69 		.type		= THERMAL_TRIP_ACTIVE,
70 		.temp		= MLXSW_THERMAL_ASIC_TEMP_HIGH,
71 		.hyst		= MLXSW_THERMAL_HYSTERESIS_TEMP,
72 		.min_state	= (4 * MLXSW_THERMAL_MAX_STATE) / 10,
73 		.max_state	= MLXSW_THERMAL_MAX_STATE,
74 	},
75 	{	/* Warning */
76 		.type		= THERMAL_TRIP_HOT,
77 		.temp		= MLXSW_THERMAL_ASIC_TEMP_HOT,
78 		.hyst		= MLXSW_THERMAL_HYSTERESIS_TEMP,
79 		.min_state	= MLXSW_THERMAL_MAX_STATE,
80 		.max_state	= MLXSW_THERMAL_MAX_STATE,
81 	},
82 	{	/* Critical - soft poweroff */
83 		.type		= THERMAL_TRIP_CRITICAL,
84 		.temp		= MLXSW_THERMAL_ASIC_TEMP_CRIT,
85 		.min_state	= MLXSW_THERMAL_MAX_STATE,
86 		.max_state	= MLXSW_THERMAL_MAX_STATE,
87 	}
88 };
89 
90 #define MLXSW_THERMAL_NUM_TRIPS	ARRAY_SIZE(default_thermal_trips)
91 
92 /* Make sure all trips are writable */
93 #define MLXSW_THERMAL_TRIP_MASK	(BIT(MLXSW_THERMAL_NUM_TRIPS) - 1)
94 
95 struct mlxsw_thermal;
96 
97 struct mlxsw_thermal_module {
98 	struct mlxsw_thermal *parent;
99 	struct thermal_zone_device *tzdev;
100 	struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
101 	enum thermal_device_mode mode;
102 	int module; /* Module or gearbox number */
103 };
104 
105 struct mlxsw_thermal {
106 	struct mlxsw_core *core;
107 	const struct mlxsw_bus_info *bus_info;
108 	struct thermal_zone_device *tzdev;
109 	int polling_delay;
110 	struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
111 	u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
112 	struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
113 	enum thermal_device_mode mode;
114 	struct mlxsw_thermal_module *tz_module_arr;
115 	struct mlxsw_thermal_module *tz_gearbox_arr;
116 	u8 tz_gearbox_num;
117 	unsigned int tz_highest_score;
118 	struct thermal_zone_device *tz_highest_dev;
119 };
120 
121 static inline u8 mlxsw_state_to_duty(int state)
122 {
123 	return DIV_ROUND_CLOSEST(state * MLXSW_THERMAL_MAX_DUTY,
124 				 MLXSW_THERMAL_MAX_STATE);
125 }
126 
127 static inline int mlxsw_duty_to_state(u8 duty)
128 {
129 	return DIV_ROUND_CLOSEST(duty * MLXSW_THERMAL_MAX_STATE,
130 				 MLXSW_THERMAL_MAX_DUTY);
131 }
132 
133 static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
134 					struct thermal_cooling_device *cdev)
135 {
136 	int i;
137 
138 	for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
139 		if (thermal->cdevs[i] == cdev)
140 			return i;
141 
142 	/* Allow mlxsw thermal zone binding to an external cooling device */
143 	for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) {
144 		if (strnstr(cdev->type, mlxsw_thermal_external_allowed_cdev[i],
145 			    sizeof(cdev->type)))
146 			return 0;
147 	}
148 
149 	return -ENODEV;
150 }
151 
152 static void
153 mlxsw_thermal_module_trips_reset(struct mlxsw_thermal_module *tz)
154 {
155 	tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = 0;
156 	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = 0;
157 	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = 0;
158 	tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = 0;
159 }
160 
161 static int
162 mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
163 				  struct mlxsw_thermal_module *tz)
164 {
165 	int crit_temp, emerg_temp;
166 	int err;
167 
168 	err = mlxsw_env_module_temp_thresholds_get(core, tz->module,
169 						   SFP_TEMP_HIGH_WARN,
170 						   &crit_temp);
171 	if (err)
172 		return err;
173 
174 	err = mlxsw_env_module_temp_thresholds_get(core, tz->module,
175 						   SFP_TEMP_HIGH_ALARM,
176 						   &emerg_temp);
177 	if (err)
178 		return err;
179 
180 	/* According to the system thermal requirements, the thermal zones are
181 	 * defined with four trip points. The critical and emergency
182 	 * temperature thresholds, provided by QSFP module are set as "active"
183 	 * and "hot" trip points, "normal" and "critical" trip points are
184 	 * derived from "active" and "hot" by subtracting or adding double
185 	 * hysteresis value.
186 	 */
187 	if (crit_temp >= MLXSW_THERMAL_MODULE_TEMP_SHIFT)
188 		tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp -
189 					MLXSW_THERMAL_MODULE_TEMP_SHIFT;
190 	else
191 		tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp;
192 	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = crit_temp;
193 	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = emerg_temp;
194 	if (emerg_temp > crit_temp)
195 		tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp +
196 					MLXSW_THERMAL_MODULE_TEMP_SHIFT;
197 	else
198 		tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp;
199 
200 	return 0;
201 }
202 
203 static void mlxsw_thermal_tz_score_update(struct mlxsw_thermal *thermal,
204 					  struct thermal_zone_device *tzdev,
205 					  struct mlxsw_thermal_trip *trips,
206 					  int temp)
207 {
208 	struct mlxsw_thermal_trip *trip = trips;
209 	unsigned int score, delta, i, shift = 1;
210 
211 	/* Calculate thermal zone score, if temperature is above the critical
212 	 * threshold score is set to MLXSW_THERMAL_TEMP_SCORE_MAX.
213 	 */
214 	score = MLXSW_THERMAL_TEMP_SCORE_MAX;
215 	for (i = MLXSW_THERMAL_TEMP_TRIP_NORM; i < MLXSW_THERMAL_NUM_TRIPS;
216 	     i++, trip++) {
217 		if (temp < trip->temp) {
218 			delta = DIV_ROUND_CLOSEST(temp, trip->temp - temp);
219 			score = delta * shift;
220 			break;
221 		}
222 		shift *= 256;
223 	}
224 
225 	if (score > thermal->tz_highest_score) {
226 		thermal->tz_highest_score = score;
227 		thermal->tz_highest_dev = tzdev;
228 	}
229 }
230 
231 static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
232 			      struct thermal_cooling_device *cdev)
233 {
234 	struct mlxsw_thermal *thermal = tzdev->devdata;
235 	struct device *dev = thermal->bus_info->dev;
236 	int i, err;
237 
238 	/* If the cooling device is one of ours bind it */
239 	if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
240 		return 0;
241 
242 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
243 		const struct mlxsw_thermal_trip *trip = &thermal->trips[i];
244 
245 		err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
246 						       trip->max_state,
247 						       trip->min_state,
248 						       THERMAL_WEIGHT_DEFAULT);
249 		if (err < 0) {
250 			dev_err(dev, "Failed to bind cooling device to trip %d\n", i);
251 			return err;
252 		}
253 	}
254 	return 0;
255 }
256 
257 static int mlxsw_thermal_unbind(struct thermal_zone_device *tzdev,
258 				struct thermal_cooling_device *cdev)
259 {
260 	struct mlxsw_thermal *thermal = tzdev->devdata;
261 	struct device *dev = thermal->bus_info->dev;
262 	int i;
263 	int err;
264 
265 	/* If the cooling device is our one unbind it */
266 	if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
267 		return 0;
268 
269 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
270 		err = thermal_zone_unbind_cooling_device(tzdev, i, cdev);
271 		if (err < 0) {
272 			dev_err(dev, "Failed to unbind cooling device\n");
273 			return err;
274 		}
275 	}
276 	return 0;
277 }
278 
279 static int mlxsw_thermal_get_mode(struct thermal_zone_device *tzdev,
280 				  enum thermal_device_mode *mode)
281 {
282 	struct mlxsw_thermal *thermal = tzdev->devdata;
283 
284 	*mode = thermal->mode;
285 
286 	return 0;
287 }
288 
289 static int mlxsw_thermal_set_mode(struct thermal_zone_device *tzdev,
290 				  enum thermal_device_mode mode)
291 {
292 	struct mlxsw_thermal *thermal = tzdev->devdata;
293 
294 	mutex_lock(&tzdev->lock);
295 
296 	if (mode == THERMAL_DEVICE_ENABLED)
297 		tzdev->polling_delay = thermal->polling_delay;
298 	else
299 		tzdev->polling_delay = 0;
300 
301 	mutex_unlock(&tzdev->lock);
302 
303 	thermal->mode = mode;
304 	thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
305 
306 	return 0;
307 }
308 
309 static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
310 				  int *p_temp)
311 {
312 	struct mlxsw_thermal *thermal = tzdev->devdata;
313 	struct device *dev = thermal->bus_info->dev;
314 	char mtmp_pl[MLXSW_REG_MTMP_LEN];
315 	int temp;
316 	int err;
317 
318 	mlxsw_reg_mtmp_pack(mtmp_pl, 0, false, false);
319 
320 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
321 	if (err) {
322 		dev_err(dev, "Failed to query temp sensor\n");
323 		return err;
324 	}
325 	mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
326 	if (temp > 0)
327 		mlxsw_thermal_tz_score_update(thermal, tzdev, thermal->trips,
328 					      temp);
329 
330 	*p_temp = temp;
331 	return 0;
332 }
333 
334 static int mlxsw_thermal_get_trip_type(struct thermal_zone_device *tzdev,
335 				       int trip,
336 				       enum thermal_trip_type *p_type)
337 {
338 	struct mlxsw_thermal *thermal = tzdev->devdata;
339 
340 	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
341 		return -EINVAL;
342 
343 	*p_type = thermal->trips[trip].type;
344 	return 0;
345 }
346 
347 static int mlxsw_thermal_get_trip_temp(struct thermal_zone_device *tzdev,
348 				       int trip, int *p_temp)
349 {
350 	struct mlxsw_thermal *thermal = tzdev->devdata;
351 
352 	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
353 		return -EINVAL;
354 
355 	*p_temp = thermal->trips[trip].temp;
356 	return 0;
357 }
358 
359 static int mlxsw_thermal_set_trip_temp(struct thermal_zone_device *tzdev,
360 				       int trip, int temp)
361 {
362 	struct mlxsw_thermal *thermal = tzdev->devdata;
363 
364 	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS ||
365 	    temp > MLXSW_THERMAL_ASIC_TEMP_CRIT)
366 		return -EINVAL;
367 
368 	thermal->trips[trip].temp = temp;
369 	return 0;
370 }
371 
372 static int mlxsw_thermal_get_trip_hyst(struct thermal_zone_device *tzdev,
373 				       int trip, int *p_hyst)
374 {
375 	struct mlxsw_thermal *thermal = tzdev->devdata;
376 
377 	*p_hyst = thermal->trips[trip].hyst;
378 	return 0;
379 }
380 
381 static int mlxsw_thermal_set_trip_hyst(struct thermal_zone_device *tzdev,
382 				       int trip, int hyst)
383 {
384 	struct mlxsw_thermal *thermal = tzdev->devdata;
385 
386 	thermal->trips[trip].hyst = hyst;
387 	return 0;
388 }
389 
390 static int mlxsw_thermal_trend_get(struct thermal_zone_device *tzdev,
391 				   int trip, enum thermal_trend *trend)
392 {
393 	struct mlxsw_thermal_module *tz = tzdev->devdata;
394 	struct mlxsw_thermal *thermal = tz->parent;
395 
396 	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
397 		return -EINVAL;
398 
399 	if (tzdev == thermal->tz_highest_dev)
400 		return 1;
401 
402 	*trend = THERMAL_TREND_STABLE;
403 	return 0;
404 }
405 
406 static struct thermal_zone_device_ops mlxsw_thermal_ops = {
407 	.bind = mlxsw_thermal_bind,
408 	.unbind = mlxsw_thermal_unbind,
409 	.get_mode = mlxsw_thermal_get_mode,
410 	.set_mode = mlxsw_thermal_set_mode,
411 	.get_temp = mlxsw_thermal_get_temp,
412 	.get_trip_type	= mlxsw_thermal_get_trip_type,
413 	.get_trip_temp	= mlxsw_thermal_get_trip_temp,
414 	.set_trip_temp	= mlxsw_thermal_set_trip_temp,
415 	.get_trip_hyst	= mlxsw_thermal_get_trip_hyst,
416 	.set_trip_hyst	= mlxsw_thermal_set_trip_hyst,
417 	.get_trend	= mlxsw_thermal_trend_get,
418 };
419 
420 static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
421 				     struct thermal_cooling_device *cdev)
422 {
423 	struct mlxsw_thermal_module *tz = tzdev->devdata;
424 	struct mlxsw_thermal *thermal = tz->parent;
425 	int i, j, err;
426 
427 	/* If the cooling device is one of ours bind it */
428 	if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
429 		return 0;
430 
431 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
432 		const struct mlxsw_thermal_trip *trip = &tz->trips[i];
433 
434 		err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
435 						       trip->max_state,
436 						       trip->min_state,
437 						       THERMAL_WEIGHT_DEFAULT);
438 		if (err < 0)
439 			goto err_bind_cooling_device;
440 	}
441 	return 0;
442 
443 err_bind_cooling_device:
444 	for (j = i - 1; j >= 0; j--)
445 		thermal_zone_unbind_cooling_device(tzdev, j, cdev);
446 	return err;
447 }
448 
449 static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev,
450 				       struct thermal_cooling_device *cdev)
451 {
452 	struct mlxsw_thermal_module *tz = tzdev->devdata;
453 	struct mlxsw_thermal *thermal = tz->parent;
454 	int i;
455 	int err;
456 
457 	/* If the cooling device is one of ours unbind it */
458 	if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
459 		return 0;
460 
461 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
462 		err = thermal_zone_unbind_cooling_device(tzdev, i, cdev);
463 		WARN_ON(err);
464 	}
465 	return err;
466 }
467 
468 static int mlxsw_thermal_module_mode_get(struct thermal_zone_device *tzdev,
469 					 enum thermal_device_mode *mode)
470 {
471 	struct mlxsw_thermal_module *tz = tzdev->devdata;
472 
473 	*mode = tz->mode;
474 
475 	return 0;
476 }
477 
478 static int mlxsw_thermal_module_mode_set(struct thermal_zone_device *tzdev,
479 					 enum thermal_device_mode mode)
480 {
481 	struct mlxsw_thermal_module *tz = tzdev->devdata;
482 	struct mlxsw_thermal *thermal = tz->parent;
483 
484 	mutex_lock(&tzdev->lock);
485 
486 	if (mode == THERMAL_DEVICE_ENABLED)
487 		tzdev->polling_delay = thermal->polling_delay;
488 	else
489 		tzdev->polling_delay = 0;
490 
491 	mutex_unlock(&tzdev->lock);
492 
493 	tz->mode = mode;
494 	thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
495 
496 	return 0;
497 }
498 
499 static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
500 					 int *p_temp)
501 {
502 	struct mlxsw_thermal_module *tz = tzdev->devdata;
503 	struct mlxsw_thermal *thermal = tz->parent;
504 	struct device *dev = thermal->bus_info->dev;
505 	char mtmp_pl[MLXSW_REG_MTMP_LEN];
506 	int temp;
507 	int err;
508 
509 	/* Read module temperature. */
510 	mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN +
511 			    tz->module, false, false);
512 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
513 	if (err) {
514 		/* Do not return error - in case of broken module's sensor
515 		 * it will cause error message flooding.
516 		 */
517 		temp = 0;
518 		*p_temp = (int) temp;
519 		return 0;
520 	}
521 	mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
522 	*p_temp = temp;
523 
524 	if (!temp)
525 		return 0;
526 
527 	/* Update trip points. */
528 	err = mlxsw_thermal_module_trips_update(dev, thermal->core, tz);
529 	if (!err && temp > 0)
530 		mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
531 
532 	return 0;
533 }
534 
535 static int
536 mlxsw_thermal_module_trip_type_get(struct thermal_zone_device *tzdev, int trip,
537 				   enum thermal_trip_type *p_type)
538 {
539 	struct mlxsw_thermal_module *tz = tzdev->devdata;
540 
541 	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
542 		return -EINVAL;
543 
544 	*p_type = tz->trips[trip].type;
545 	return 0;
546 }
547 
548 static int
549 mlxsw_thermal_module_trip_temp_get(struct thermal_zone_device *tzdev,
550 				   int trip, int *p_temp)
551 {
552 	struct mlxsw_thermal_module *tz = tzdev->devdata;
553 
554 	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
555 		return -EINVAL;
556 
557 	*p_temp = tz->trips[trip].temp;
558 	return 0;
559 }
560 
561 static int
562 mlxsw_thermal_module_trip_temp_set(struct thermal_zone_device *tzdev,
563 				   int trip, int temp)
564 {
565 	struct mlxsw_thermal_module *tz = tzdev->devdata;
566 
567 	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS ||
568 	    temp > tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp)
569 		return -EINVAL;
570 
571 	tz->trips[trip].temp = temp;
572 	return 0;
573 }
574 
575 static int
576 mlxsw_thermal_module_trip_hyst_get(struct thermal_zone_device *tzdev, int trip,
577 				   int *p_hyst)
578 {
579 	struct mlxsw_thermal_module *tz = tzdev->devdata;
580 
581 	*p_hyst = tz->trips[trip].hyst;
582 	return 0;
583 }
584 
585 static int
586 mlxsw_thermal_module_trip_hyst_set(struct thermal_zone_device *tzdev, int trip,
587 				   int hyst)
588 {
589 	struct mlxsw_thermal_module *tz = tzdev->devdata;
590 
591 	tz->trips[trip].hyst = hyst;
592 	return 0;
593 }
594 
595 static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
596 	.bind		= mlxsw_thermal_module_bind,
597 	.unbind		= mlxsw_thermal_module_unbind,
598 	.get_mode	= mlxsw_thermal_module_mode_get,
599 	.set_mode	= mlxsw_thermal_module_mode_set,
600 	.get_temp	= mlxsw_thermal_module_temp_get,
601 	.get_trip_type	= mlxsw_thermal_module_trip_type_get,
602 	.get_trip_temp	= mlxsw_thermal_module_trip_temp_get,
603 	.set_trip_temp	= mlxsw_thermal_module_trip_temp_set,
604 	.get_trip_hyst	= mlxsw_thermal_module_trip_hyst_get,
605 	.set_trip_hyst	= mlxsw_thermal_module_trip_hyst_set,
606 	.get_trend	= mlxsw_thermal_trend_get,
607 };
608 
609 static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
610 					  int *p_temp)
611 {
612 	struct mlxsw_thermal_module *tz = tzdev->devdata;
613 	struct mlxsw_thermal *thermal = tz->parent;
614 	char mtmp_pl[MLXSW_REG_MTMP_LEN];
615 	u16 index;
616 	int temp;
617 	int err;
618 
619 	index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
620 	mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
621 
622 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
623 	if (err)
624 		return err;
625 
626 	mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
627 	if (temp > 0)
628 		mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
629 
630 	*p_temp = temp;
631 	return 0;
632 }
633 
634 static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
635 	.bind		= mlxsw_thermal_module_bind,
636 	.unbind		= mlxsw_thermal_module_unbind,
637 	.get_mode	= mlxsw_thermal_module_mode_get,
638 	.set_mode	= mlxsw_thermal_module_mode_set,
639 	.get_temp	= mlxsw_thermal_gearbox_temp_get,
640 	.get_trip_type	= mlxsw_thermal_module_trip_type_get,
641 	.get_trip_temp	= mlxsw_thermal_module_trip_temp_get,
642 	.set_trip_temp	= mlxsw_thermal_module_trip_temp_set,
643 	.get_trip_hyst	= mlxsw_thermal_module_trip_hyst_get,
644 	.set_trip_hyst	= mlxsw_thermal_module_trip_hyst_set,
645 	.get_trend	= mlxsw_thermal_trend_get,
646 };
647 
648 static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
649 				       unsigned long *p_state)
650 {
651 	*p_state = MLXSW_THERMAL_MAX_STATE;
652 	return 0;
653 }
654 
655 static int mlxsw_thermal_get_cur_state(struct thermal_cooling_device *cdev,
656 				       unsigned long *p_state)
657 
658 {
659 	struct mlxsw_thermal *thermal = cdev->devdata;
660 	struct device *dev = thermal->bus_info->dev;
661 	char mfsc_pl[MLXSW_REG_MFSC_LEN];
662 	int err, idx;
663 	u8 duty;
664 
665 	idx = mlxsw_get_cooling_device_idx(thermal, cdev);
666 	if (idx < 0)
667 		return idx;
668 
669 	mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0);
670 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
671 	if (err) {
672 		dev_err(dev, "Failed to query PWM duty\n");
673 		return err;
674 	}
675 
676 	duty = mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl);
677 	*p_state = mlxsw_duty_to_state(duty);
678 	return 0;
679 }
680 
681 static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
682 				       unsigned long state)
683 
684 {
685 	struct mlxsw_thermal *thermal = cdev->devdata;
686 	struct device *dev = thermal->bus_info->dev;
687 	char mfsc_pl[MLXSW_REG_MFSC_LEN];
688 	unsigned long cur_state, i;
689 	int idx;
690 	u8 duty;
691 	int err;
692 
693 	idx = mlxsw_get_cooling_device_idx(thermal, cdev);
694 	if (idx < 0)
695 		return idx;
696 
697 	/* Verify if this request is for changing allowed fan dynamical
698 	 * minimum. If it is - update cooling levels accordingly and update
699 	 * state, if current state is below the newly requested minimum state.
700 	 * For example, if current state is 5, and minimal state is to be
701 	 * changed from 4 to 6, thermal->cooling_levels[0 to 5] will be changed
702 	 * all from 4 to 6. And state 5 (thermal->cooling_levels[4]) should be
703 	 * overwritten.
704 	 */
705 	if (state >= MLXSW_THERMAL_SPEED_MIN &&
706 	    state <= MLXSW_THERMAL_SPEED_MAX) {
707 		state -= MLXSW_THERMAL_MAX_STATE;
708 		for (i = 0; i <= MLXSW_THERMAL_MAX_STATE; i++)
709 			thermal->cooling_levels[i] = max(state, i);
710 
711 		mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0);
712 		err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
713 		if (err)
714 			return err;
715 
716 		duty = mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl);
717 		cur_state = mlxsw_duty_to_state(duty);
718 
719 		/* If current fan state is lower than requested dynamical
720 		 * minimum, increase fan speed up to dynamical minimum.
721 		 */
722 		if (state < cur_state)
723 			return 0;
724 
725 		state = cur_state;
726 	}
727 
728 	if (state > MLXSW_THERMAL_MAX_STATE)
729 		return -EINVAL;
730 
731 	/* Normalize the state to the valid speed range. */
732 	state = thermal->cooling_levels[state];
733 	mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
734 	err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
735 	if (err) {
736 		dev_err(dev, "Failed to write PWM duty\n");
737 		return err;
738 	}
739 	return 0;
740 }
741 
742 static const struct thermal_cooling_device_ops mlxsw_cooling_ops = {
743 	.get_max_state	= mlxsw_thermal_get_max_state,
744 	.get_cur_state	= mlxsw_thermal_get_cur_state,
745 	.set_cur_state	= mlxsw_thermal_set_cur_state,
746 };
747 
748 static int
749 mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
750 {
751 	char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
752 	int err;
753 
754 	snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d",
755 		 module_tz->module + 1);
756 	module_tz->tzdev = thermal_zone_device_register(tz_name,
757 							MLXSW_THERMAL_NUM_TRIPS,
758 							MLXSW_THERMAL_TRIP_MASK,
759 							module_tz,
760 							&mlxsw_thermal_module_ops,
761 							NULL, 0, 0);
762 	if (IS_ERR(module_tz->tzdev)) {
763 		err = PTR_ERR(module_tz->tzdev);
764 		return err;
765 	}
766 
767 	module_tz->mode = THERMAL_DEVICE_ENABLED;
768 	return 0;
769 }
770 
771 static void mlxsw_thermal_module_tz_fini(struct thermal_zone_device *tzdev)
772 {
773 	thermal_zone_device_unregister(tzdev);
774 }
775 
776 static int
777 mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
778 			  struct mlxsw_thermal *thermal, u8 local_port)
779 {
780 	struct mlxsw_thermal_module *module_tz;
781 	char pmlp_pl[MLXSW_REG_PMLP_LEN];
782 	u8 width, module;
783 	int err;
784 
785 	mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
786 	err = mlxsw_reg_query(core, MLXSW_REG(pmlp), pmlp_pl);
787 	if (err)
788 		return err;
789 
790 	width = mlxsw_reg_pmlp_width_get(pmlp_pl);
791 	if (!width)
792 		return 0;
793 
794 	module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
795 	module_tz = &thermal->tz_module_arr[module];
796 	/* Skip if parent is already set (case of port split). */
797 	if (module_tz->parent)
798 		return 0;
799 	module_tz->module = module;
800 	module_tz->parent = thermal;
801 	memcpy(module_tz->trips, default_thermal_trips,
802 	       sizeof(thermal->trips));
803 	/* Initialize all trip point. */
804 	mlxsw_thermal_module_trips_reset(module_tz);
805 	/* Update trip point according to the module data. */
806 	return mlxsw_thermal_module_trips_update(dev, core, module_tz);
807 }
808 
809 static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz)
810 {
811 	if (module_tz && module_tz->tzdev) {
812 		mlxsw_thermal_module_tz_fini(module_tz->tzdev);
813 		module_tz->tzdev = NULL;
814 		module_tz->parent = NULL;
815 	}
816 }
817 
818 static int
819 mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
820 			   struct mlxsw_thermal *thermal)
821 {
822 	unsigned int module_count = mlxsw_core_max_ports(core);
823 	struct mlxsw_thermal_module *module_tz;
824 	int i, err;
825 
826 	if (!mlxsw_core_res_query_enabled(core))
827 		return 0;
828 
829 	thermal->tz_module_arr = kcalloc(module_count,
830 					 sizeof(*thermal->tz_module_arr),
831 					 GFP_KERNEL);
832 	if (!thermal->tz_module_arr)
833 		return -ENOMEM;
834 
835 	for (i = 1; i < module_count; i++) {
836 		err = mlxsw_thermal_module_init(dev, core, thermal, i);
837 		if (err)
838 			goto err_unreg_tz_module_arr;
839 	}
840 
841 	for (i = 0; i < module_count - 1; i++) {
842 		module_tz = &thermal->tz_module_arr[i];
843 		if (!module_tz->parent)
844 			continue;
845 		err = mlxsw_thermal_module_tz_init(module_tz);
846 		if (err)
847 			goto err_unreg_tz_module_arr;
848 	}
849 
850 	return 0;
851 
852 err_unreg_tz_module_arr:
853 	for (i = module_count - 1; i >= 0; i--)
854 		mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
855 	kfree(thermal->tz_module_arr);
856 	return err;
857 }
858 
859 static void
860 mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
861 {
862 	unsigned int module_count = mlxsw_core_max_ports(thermal->core);
863 	int i;
864 
865 	if (!mlxsw_core_res_query_enabled(thermal->core))
866 		return;
867 
868 	for (i = module_count - 1; i >= 0; i--)
869 		mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
870 	kfree(thermal->tz_module_arr);
871 }
872 
873 static int
874 mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
875 {
876 	char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
877 
878 	snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
879 		 gearbox_tz->module + 1);
880 	gearbox_tz->tzdev = thermal_zone_device_register(tz_name,
881 						MLXSW_THERMAL_NUM_TRIPS,
882 						MLXSW_THERMAL_TRIP_MASK,
883 						gearbox_tz,
884 						&mlxsw_thermal_gearbox_ops,
885 						NULL, 0, 0);
886 	if (IS_ERR(gearbox_tz->tzdev))
887 		return PTR_ERR(gearbox_tz->tzdev);
888 
889 	gearbox_tz->mode = THERMAL_DEVICE_ENABLED;
890 	return 0;
891 }
892 
893 static void
894 mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
895 {
896 	thermal_zone_device_unregister(gearbox_tz->tzdev);
897 }
898 
899 static int
900 mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
901 			     struct mlxsw_thermal *thermal)
902 {
903 	struct mlxsw_thermal_module *gearbox_tz;
904 	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
905 	int i;
906 	int err;
907 
908 	if (!mlxsw_core_res_query_enabled(core))
909 		return 0;
910 
911 	mlxsw_reg_mgpir_pack(mgpir_pl);
912 	err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
913 	if (err)
914 		return err;
915 
916 	mlxsw_reg_mgpir_unpack(mgpir_pl, &thermal->tz_gearbox_num, NULL, NULL);
917 	if (!thermal->tz_gearbox_num)
918 		return 0;
919 
920 	thermal->tz_gearbox_arr = kcalloc(thermal->tz_gearbox_num,
921 					  sizeof(*thermal->tz_gearbox_arr),
922 					  GFP_KERNEL);
923 	if (!thermal->tz_gearbox_arr)
924 		return -ENOMEM;
925 
926 	for (i = 0; i < thermal->tz_gearbox_num; i++) {
927 		gearbox_tz = &thermal->tz_gearbox_arr[i];
928 		memcpy(gearbox_tz->trips, default_thermal_trips,
929 		       sizeof(thermal->trips));
930 		gearbox_tz->module = i;
931 		gearbox_tz->parent = thermal;
932 		err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
933 		if (err)
934 			goto err_unreg_tz_gearbox;
935 	}
936 
937 	return 0;
938 
939 err_unreg_tz_gearbox:
940 	for (i--; i >= 0; i--)
941 		mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
942 	kfree(thermal->tz_gearbox_arr);
943 	return err;
944 }
945 
946 static void
947 mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal)
948 {
949 	int i;
950 
951 	if (!mlxsw_core_res_query_enabled(thermal->core))
952 		return;
953 
954 	for (i = thermal->tz_gearbox_num - 1; i >= 0; i--)
955 		mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
956 	kfree(thermal->tz_gearbox_arr);
957 }
958 
959 int mlxsw_thermal_init(struct mlxsw_core *core,
960 		       const struct mlxsw_bus_info *bus_info,
961 		       struct mlxsw_thermal **p_thermal)
962 {
963 	char mfcr_pl[MLXSW_REG_MFCR_LEN] = { 0 };
964 	enum mlxsw_reg_mfcr_pwm_frequency freq;
965 	struct device *dev = bus_info->dev;
966 	struct mlxsw_thermal *thermal;
967 	u16 tacho_active;
968 	u8 pwm_active;
969 	int err, i;
970 
971 	thermal = devm_kzalloc(dev, sizeof(*thermal),
972 			       GFP_KERNEL);
973 	if (!thermal)
974 		return -ENOMEM;
975 
976 	thermal->core = core;
977 	thermal->bus_info = bus_info;
978 	memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
979 
980 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
981 	if (err) {
982 		dev_err(dev, "Failed to probe PWMs\n");
983 		goto err_free_thermal;
984 	}
985 	mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
986 
987 	for (i = 0; i < MLXSW_MFCR_TACHOS_MAX; i++) {
988 		if (tacho_active & BIT(i)) {
989 			char mfsl_pl[MLXSW_REG_MFSL_LEN];
990 
991 			mlxsw_reg_mfsl_pack(mfsl_pl, i, 0, 0);
992 
993 			/* We need to query the register to preserve maximum */
994 			err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsl),
995 					      mfsl_pl);
996 			if (err)
997 				goto err_free_thermal;
998 
999 			/* set the minimal RPMs to 0 */
1000 			mlxsw_reg_mfsl_tach_min_set(mfsl_pl, 0);
1001 			err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsl),
1002 					      mfsl_pl);
1003 			if (err)
1004 				goto err_free_thermal;
1005 		}
1006 	}
1007 	for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
1008 		if (pwm_active & BIT(i)) {
1009 			struct thermal_cooling_device *cdev;
1010 
1011 			cdev = thermal_cooling_device_register("mlxsw_fan",
1012 							       thermal,
1013 							       &mlxsw_cooling_ops);
1014 			if (IS_ERR(cdev)) {
1015 				err = PTR_ERR(cdev);
1016 				dev_err(dev, "Failed to register cooling device\n");
1017 				goto err_unreg_cdevs;
1018 			}
1019 			thermal->cdevs[i] = cdev;
1020 		}
1021 	}
1022 
1023 	/* Initialize cooling levels per PWM state. */
1024 	for (i = 0; i < MLXSW_THERMAL_MAX_STATE; i++)
1025 		thermal->cooling_levels[i] = max(MLXSW_THERMAL_SPEED_MIN_LEVEL,
1026 						 i);
1027 
1028 	thermal->polling_delay = bus_info->low_frequency ?
1029 				 MLXSW_THERMAL_SLOW_POLL_INT :
1030 				 MLXSW_THERMAL_POLL_INT;
1031 
1032 	thermal->tzdev = thermal_zone_device_register("mlxsw",
1033 						      MLXSW_THERMAL_NUM_TRIPS,
1034 						      MLXSW_THERMAL_TRIP_MASK,
1035 						      thermal,
1036 						      &mlxsw_thermal_ops,
1037 						      NULL, 0,
1038 						      thermal->polling_delay);
1039 	if (IS_ERR(thermal->tzdev)) {
1040 		err = PTR_ERR(thermal->tzdev);
1041 		dev_err(dev, "Failed to register thermal zone\n");
1042 		goto err_unreg_cdevs;
1043 	}
1044 
1045 	err = mlxsw_thermal_modules_init(dev, core, thermal);
1046 	if (err)
1047 		goto err_unreg_tzdev;
1048 
1049 	err = mlxsw_thermal_gearboxes_init(dev, core, thermal);
1050 	if (err)
1051 		goto err_unreg_modules_tzdev;
1052 
1053 	thermal->mode = THERMAL_DEVICE_ENABLED;
1054 	*p_thermal = thermal;
1055 	return 0;
1056 
1057 err_unreg_modules_tzdev:
1058 	mlxsw_thermal_modules_fini(thermal);
1059 err_unreg_tzdev:
1060 	if (thermal->tzdev) {
1061 		thermal_zone_device_unregister(thermal->tzdev);
1062 		thermal->tzdev = NULL;
1063 	}
1064 err_unreg_cdevs:
1065 	for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
1066 		if (thermal->cdevs[i])
1067 			thermal_cooling_device_unregister(thermal->cdevs[i]);
1068 err_free_thermal:
1069 	devm_kfree(dev, thermal);
1070 	return err;
1071 }
1072 
1073 void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
1074 {
1075 	int i;
1076 
1077 	mlxsw_thermal_gearboxes_fini(thermal);
1078 	mlxsw_thermal_modules_fini(thermal);
1079 	if (thermal->tzdev) {
1080 		thermal_zone_device_unregister(thermal->tzdev);
1081 		thermal->tzdev = NULL;
1082 	}
1083 
1084 	for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
1085 		if (thermal->cdevs[i]) {
1086 			thermal_cooling_device_unregister(thermal->cdevs[i]);
1087 			thermal->cdevs[i] = NULL;
1088 		}
1089 	}
1090 
1091 	devm_kfree(thermal->bus_info->dev, thermal);
1092 }
1093