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