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_MODULE_TEMP_NORM	55000	/* 55C */
23 #define MLXSW_THERMAL_MODULE_TEMP_HIGH	65000	/* 65C */
24 #define MLXSW_THERMAL_MODULE_TEMP_HOT	80000	/* 80C */
25 #define MLXSW_THERMAL_HYSTERESIS_TEMP	5000	/* 5C */
26 #define MLXSW_THERMAL_MODULE_TEMP_SHIFT	(MLXSW_THERMAL_HYSTERESIS_TEMP * 2)
27 #define MLXSW_THERMAL_MAX_STATE	10
28 #define MLXSW_THERMAL_MIN_STATE	2
29 #define MLXSW_THERMAL_MAX_DUTY	255
30 
31 /* External cooling devices, allowed for binding to mlxsw thermal zones. */
32 static char * const mlxsw_thermal_external_allowed_cdev[] = {
33 	"mlxreg_fan",
34 };
35 
36 struct mlxsw_cooling_states {
37 	int	min_state;
38 	int	max_state;
39 };
40 
41 static const struct thermal_trip default_thermal_trips[] = {
42 	{	/* In range - 0-40% PWM */
43 		.type		= THERMAL_TRIP_ACTIVE,
44 		.temperature	= MLXSW_THERMAL_ASIC_TEMP_NORM,
45 		.hysteresis	= MLXSW_THERMAL_HYSTERESIS_TEMP,
46 	},
47 	{
48 		/* In range - 40-100% PWM */
49 		.type		= THERMAL_TRIP_ACTIVE,
50 		.temperature	= MLXSW_THERMAL_ASIC_TEMP_HIGH,
51 		.hysteresis	= MLXSW_THERMAL_HYSTERESIS_TEMP,
52 	},
53 	{	/* Warning */
54 		.type		= THERMAL_TRIP_HOT,
55 		.temperature	= MLXSW_THERMAL_ASIC_TEMP_HOT,
56 	},
57 };
58 
59 static const struct thermal_trip default_thermal_module_trips[] = {
60 	{	/* In range - 0-40% PWM */
61 		.type		= THERMAL_TRIP_ACTIVE,
62 		.temperature	= MLXSW_THERMAL_MODULE_TEMP_NORM,
63 		.hysteresis	= MLXSW_THERMAL_HYSTERESIS_TEMP,
64 	},
65 	{
66 		/* In range - 40-100% PWM */
67 		.type		= THERMAL_TRIP_ACTIVE,
68 		.temperature	= MLXSW_THERMAL_MODULE_TEMP_HIGH,
69 		.hysteresis	= MLXSW_THERMAL_HYSTERESIS_TEMP,
70 	},
71 	{	/* Warning */
72 		.type		= THERMAL_TRIP_HOT,
73 		.temperature	= MLXSW_THERMAL_MODULE_TEMP_HOT,
74 	},
75 };
76 
77 static const struct mlxsw_cooling_states default_cooling_states[] = {
78 	{
79 		.min_state	= 0,
80 		.max_state	= (4 * MLXSW_THERMAL_MAX_STATE) / 10,
81 	},
82 	{
83 		.min_state	= (4 * MLXSW_THERMAL_MAX_STATE) / 10,
84 		.max_state	= MLXSW_THERMAL_MAX_STATE,
85 	},
86 	{
87 		.min_state	= MLXSW_THERMAL_MAX_STATE,
88 		.max_state	= MLXSW_THERMAL_MAX_STATE,
89 	},
90 };
91 
92 #define MLXSW_THERMAL_NUM_TRIPS	ARRAY_SIZE(default_thermal_trips)
93 
94 /* Make sure all trips are writable */
95 #define MLXSW_THERMAL_TRIP_MASK	(BIT(MLXSW_THERMAL_NUM_TRIPS) - 1)
96 
97 struct mlxsw_thermal;
98 
99 struct mlxsw_thermal_module {
100 	struct mlxsw_thermal *parent;
101 	struct thermal_zone_device *tzdev;
102 	struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
103 	struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
104 	int module; /* Module or gearbox number */
105 	u8 slot_index;
106 };
107 
108 struct mlxsw_thermal_area {
109 	struct mlxsw_thermal_module *tz_module_arr;
110 	u8 tz_module_num;
111 	struct mlxsw_thermal_module *tz_gearbox_arr;
112 	u8 tz_gearbox_num;
113 	u8 slot_index;
114 	bool active;
115 };
116 
117 struct mlxsw_thermal {
118 	struct mlxsw_core *core;
119 	const struct mlxsw_bus_info *bus_info;
120 	struct thermal_zone_device *tzdev;
121 	int polling_delay;
122 	struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
123 	struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
124 	struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
125 	struct mlxsw_thermal_area line_cards[];
126 };
127 
mlxsw_state_to_duty(int state)128 static inline u8 mlxsw_state_to_duty(int state)
129 {
130 	return DIV_ROUND_CLOSEST(state * MLXSW_THERMAL_MAX_DUTY,
131 				 MLXSW_THERMAL_MAX_STATE);
132 }
133 
mlxsw_duty_to_state(u8 duty)134 static inline int mlxsw_duty_to_state(u8 duty)
135 {
136 	return DIV_ROUND_CLOSEST(duty * MLXSW_THERMAL_MAX_STATE,
137 				 MLXSW_THERMAL_MAX_DUTY);
138 }
139 
mlxsw_get_cooling_device_idx(struct mlxsw_thermal * thermal,struct thermal_cooling_device * cdev)140 static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
141 					struct thermal_cooling_device *cdev)
142 {
143 	int i;
144 
145 	for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
146 		if (thermal->cdevs[i] == cdev)
147 			return i;
148 
149 	/* Allow mlxsw thermal zone binding to an external cooling device */
150 	for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) {
151 		if (!strcmp(cdev->type, mlxsw_thermal_external_allowed_cdev[i]))
152 			return 0;
153 	}
154 
155 	return -ENODEV;
156 }
157 
mlxsw_thermal_bind(struct thermal_zone_device * tzdev,struct thermal_cooling_device * cdev)158 static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
159 			      struct thermal_cooling_device *cdev)
160 {
161 	struct mlxsw_thermal *thermal = thermal_zone_device_priv(tzdev);
162 	struct device *dev = thermal->bus_info->dev;
163 	int i, err;
164 
165 	/* If the cooling device is one of ours bind it */
166 	if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
167 		return 0;
168 
169 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
170 		const struct mlxsw_cooling_states *state = &thermal->cooling_states[i];
171 
172 		err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
173 						       state->max_state,
174 						       state->min_state,
175 						       THERMAL_WEIGHT_DEFAULT);
176 		if (err < 0) {
177 			dev_err(dev, "Failed to bind cooling device to trip %d\n", i);
178 			return err;
179 		}
180 	}
181 	return 0;
182 }
183 
mlxsw_thermal_unbind(struct thermal_zone_device * tzdev,struct thermal_cooling_device * cdev)184 static int mlxsw_thermal_unbind(struct thermal_zone_device *tzdev,
185 				struct thermal_cooling_device *cdev)
186 {
187 	struct mlxsw_thermal *thermal = thermal_zone_device_priv(tzdev);
188 	struct device *dev = thermal->bus_info->dev;
189 	int i;
190 	int err;
191 
192 	/* If the cooling device is our one unbind it */
193 	if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
194 		return 0;
195 
196 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
197 		err = thermal_zone_unbind_cooling_device(tzdev, i, cdev);
198 		if (err < 0) {
199 			dev_err(dev, "Failed to unbind cooling device\n");
200 			return err;
201 		}
202 	}
203 	return 0;
204 }
205 
mlxsw_thermal_get_temp(struct thermal_zone_device * tzdev,int * p_temp)206 static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
207 				  int *p_temp)
208 {
209 	struct mlxsw_thermal *thermal = thermal_zone_device_priv(tzdev);
210 	struct device *dev = thermal->bus_info->dev;
211 	char mtmp_pl[MLXSW_REG_MTMP_LEN];
212 	int temp;
213 	int err;
214 
215 	mlxsw_reg_mtmp_pack(mtmp_pl, 0, 0, false, false);
216 
217 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
218 	if (err) {
219 		dev_err(dev, "Failed to query temp sensor\n");
220 		return err;
221 	}
222 	mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL);
223 
224 	*p_temp = temp;
225 	return 0;
226 }
227 
228 static struct thermal_zone_params mlxsw_thermal_params = {
229 	.no_hwmon = true,
230 };
231 
232 static struct thermal_zone_device_ops mlxsw_thermal_ops = {
233 	.bind = mlxsw_thermal_bind,
234 	.unbind = mlxsw_thermal_unbind,
235 	.get_temp = mlxsw_thermal_get_temp,
236 };
237 
mlxsw_thermal_module_bind(struct thermal_zone_device * tzdev,struct thermal_cooling_device * cdev)238 static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
239 				     struct thermal_cooling_device *cdev)
240 {
241 	struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev);
242 	struct mlxsw_thermal *thermal = tz->parent;
243 	int i, j, err;
244 
245 	/* If the cooling device is one of ours bind it */
246 	if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
247 		return 0;
248 
249 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
250 		const struct mlxsw_cooling_states *state = &tz->cooling_states[i];
251 
252 		err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
253 						       state->max_state,
254 						       state->min_state,
255 						       THERMAL_WEIGHT_DEFAULT);
256 		if (err < 0)
257 			goto err_thermal_zone_bind_cooling_device;
258 	}
259 	return 0;
260 
261 err_thermal_zone_bind_cooling_device:
262 	for (j = i - 1; j >= 0; j--)
263 		thermal_zone_unbind_cooling_device(tzdev, j, cdev);
264 	return err;
265 }
266 
mlxsw_thermal_module_unbind(struct thermal_zone_device * tzdev,struct thermal_cooling_device * cdev)267 static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev,
268 				       struct thermal_cooling_device *cdev)
269 {
270 	struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev);
271 	struct mlxsw_thermal *thermal = tz->parent;
272 	int i;
273 	int err;
274 
275 	/* If the cooling device is one of ours unbind it */
276 	if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
277 		return 0;
278 
279 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
280 		err = thermal_zone_unbind_cooling_device(tzdev, i, cdev);
281 		WARN_ON(err);
282 	}
283 	return err;
284 }
285 
mlxsw_thermal_module_temp_get(struct thermal_zone_device * tzdev,int * p_temp)286 static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
287 					 int *p_temp)
288 {
289 	struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev);
290 	struct mlxsw_thermal *thermal = tz->parent;
291 	char mtmp_pl[MLXSW_REG_MTMP_LEN];
292 	u16 sensor_index;
293 	int err;
294 
295 	sensor_index = MLXSW_REG_MTMP_MODULE_INDEX_MIN + tz->module;
296 	mlxsw_reg_mtmp_pack(mtmp_pl, tz->slot_index, sensor_index,
297 			    false, false);
298 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
299 	if (err)
300 		return err;
301 	mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, NULL, NULL, NULL);
302 	return 0;
303 }
304 
305 static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
306 	.bind		= mlxsw_thermal_module_bind,
307 	.unbind		= mlxsw_thermal_module_unbind,
308 	.get_temp	= mlxsw_thermal_module_temp_get,
309 };
310 
mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device * tzdev,int * p_temp)311 static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
312 					  int *p_temp)
313 {
314 	struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev);
315 	struct mlxsw_thermal *thermal = tz->parent;
316 	char mtmp_pl[MLXSW_REG_MTMP_LEN];
317 	u16 index;
318 	int temp;
319 	int err;
320 
321 	index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
322 	mlxsw_reg_mtmp_pack(mtmp_pl, tz->slot_index, index, false, false);
323 
324 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
325 	if (err)
326 		return err;
327 
328 	mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL);
329 
330 	*p_temp = temp;
331 	return 0;
332 }
333 
334 static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
335 	.bind		= mlxsw_thermal_module_bind,
336 	.unbind		= mlxsw_thermal_module_unbind,
337 	.get_temp	= mlxsw_thermal_gearbox_temp_get,
338 };
339 
mlxsw_thermal_get_max_state(struct thermal_cooling_device * cdev,unsigned long * p_state)340 static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
341 				       unsigned long *p_state)
342 {
343 	*p_state = MLXSW_THERMAL_MAX_STATE;
344 	return 0;
345 }
346 
mlxsw_thermal_get_cur_state(struct thermal_cooling_device * cdev,unsigned long * p_state)347 static int mlxsw_thermal_get_cur_state(struct thermal_cooling_device *cdev,
348 				       unsigned long *p_state)
349 
350 {
351 	struct mlxsw_thermal *thermal = cdev->devdata;
352 	struct device *dev = thermal->bus_info->dev;
353 	char mfsc_pl[MLXSW_REG_MFSC_LEN];
354 	int err, idx;
355 	u8 duty;
356 
357 	idx = mlxsw_get_cooling_device_idx(thermal, cdev);
358 	if (idx < 0)
359 		return idx;
360 
361 	mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0);
362 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
363 	if (err) {
364 		dev_err(dev, "Failed to query PWM duty\n");
365 		return err;
366 	}
367 
368 	duty = mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl);
369 	*p_state = mlxsw_duty_to_state(duty);
370 	return 0;
371 }
372 
mlxsw_thermal_set_cur_state(struct thermal_cooling_device * cdev,unsigned long state)373 static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
374 				       unsigned long state)
375 
376 {
377 	struct mlxsw_thermal *thermal = cdev->devdata;
378 	struct device *dev = thermal->bus_info->dev;
379 	char mfsc_pl[MLXSW_REG_MFSC_LEN];
380 	int idx;
381 	int err;
382 
383 	if (state > MLXSW_THERMAL_MAX_STATE)
384 		return -EINVAL;
385 
386 	idx = mlxsw_get_cooling_device_idx(thermal, cdev);
387 	if (idx < 0)
388 		return idx;
389 
390 	/* Normalize the state to the valid speed range. */
391 	state = max_t(unsigned long, MLXSW_THERMAL_MIN_STATE, state);
392 	mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
393 	err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
394 	if (err) {
395 		dev_err(dev, "Failed to write PWM duty\n");
396 		return err;
397 	}
398 	return 0;
399 }
400 
401 static const struct thermal_cooling_device_ops mlxsw_cooling_ops = {
402 	.get_max_state	= mlxsw_thermal_get_max_state,
403 	.get_cur_state	= mlxsw_thermal_get_cur_state,
404 	.set_cur_state	= mlxsw_thermal_set_cur_state,
405 };
406 
407 static int
mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module * module_tz)408 mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
409 {
410 	char tz_name[THERMAL_NAME_LENGTH];
411 	int err;
412 
413 	if (module_tz->slot_index)
414 		snprintf(tz_name, sizeof(tz_name), "mlxsw-lc%d-module%d",
415 			 module_tz->slot_index, module_tz->module + 1);
416 	else
417 		snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d",
418 			 module_tz->module + 1);
419 	module_tz->tzdev = thermal_zone_device_register_with_trips(tz_name,
420 							module_tz->trips,
421 							MLXSW_THERMAL_NUM_TRIPS,
422 							MLXSW_THERMAL_TRIP_MASK,
423 							module_tz,
424 							&mlxsw_thermal_module_ops,
425 							&mlxsw_thermal_params,
426 							0,
427 							module_tz->parent->polling_delay);
428 	if (IS_ERR(module_tz->tzdev)) {
429 		err = PTR_ERR(module_tz->tzdev);
430 		return err;
431 	}
432 
433 	err = thermal_zone_device_enable(module_tz->tzdev);
434 	if (err)
435 		thermal_zone_device_unregister(module_tz->tzdev);
436 
437 	return err;
438 }
439 
mlxsw_thermal_module_tz_fini(struct thermal_zone_device * tzdev)440 static void mlxsw_thermal_module_tz_fini(struct thermal_zone_device *tzdev)
441 {
442 	thermal_zone_device_unregister(tzdev);
443 }
444 
445 static void
mlxsw_thermal_module_init(struct device * dev,struct mlxsw_core * core,struct mlxsw_thermal * thermal,struct mlxsw_thermal_area * area,u8 module)446 mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
447 			  struct mlxsw_thermal *thermal,
448 			  struct mlxsw_thermal_area *area, u8 module)
449 {
450 	struct mlxsw_thermal_module *module_tz;
451 
452 	module_tz = &area->tz_module_arr[module];
453 	/* Skip if parent is already set (case of port split). */
454 	if (module_tz->parent)
455 		return;
456 	module_tz->module = module;
457 	module_tz->slot_index = area->slot_index;
458 	module_tz->parent = thermal;
459 	BUILD_BUG_ON(ARRAY_SIZE(default_thermal_module_trips) !=
460 		     MLXSW_THERMAL_NUM_TRIPS);
461 	memcpy(module_tz->trips, default_thermal_module_trips,
462 	       sizeof(thermal->trips));
463 	memcpy(module_tz->cooling_states, default_cooling_states,
464 	       sizeof(thermal->cooling_states));
465 }
466 
mlxsw_thermal_module_fini(struct mlxsw_thermal_module * module_tz)467 static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz)
468 {
469 	if (module_tz && module_tz->tzdev) {
470 		mlxsw_thermal_module_tz_fini(module_tz->tzdev);
471 		module_tz->tzdev = NULL;
472 		module_tz->parent = NULL;
473 	}
474 }
475 
476 static int
mlxsw_thermal_modules_init(struct device * dev,struct mlxsw_core * core,struct mlxsw_thermal * thermal,struct mlxsw_thermal_area * area)477 mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
478 			   struct mlxsw_thermal *thermal,
479 			   struct mlxsw_thermal_area *area)
480 {
481 	struct mlxsw_thermal_module *module_tz;
482 	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
483 	int i, err;
484 
485 	mlxsw_reg_mgpir_pack(mgpir_pl, area->slot_index);
486 	err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
487 	if (err)
488 		return err;
489 
490 	mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
491 			       &area->tz_module_num, NULL);
492 
493 	/* For modular system module counter could be zero. */
494 	if (!area->tz_module_num)
495 		return 0;
496 
497 	area->tz_module_arr = kcalloc(area->tz_module_num,
498 				      sizeof(*area->tz_module_arr),
499 				      GFP_KERNEL);
500 	if (!area->tz_module_arr)
501 		return -ENOMEM;
502 
503 	for (i = 0; i < area->tz_module_num; i++)
504 		mlxsw_thermal_module_init(dev, core, thermal, area, i);
505 
506 	for (i = 0; i < area->tz_module_num; i++) {
507 		module_tz = &area->tz_module_arr[i];
508 		if (!module_tz->parent)
509 			continue;
510 		err = mlxsw_thermal_module_tz_init(module_tz);
511 		if (err)
512 			goto err_thermal_module_tz_init;
513 	}
514 
515 	return 0;
516 
517 err_thermal_module_tz_init:
518 	for (i = area->tz_module_num - 1; i >= 0; i--)
519 		mlxsw_thermal_module_fini(&area->tz_module_arr[i]);
520 	kfree(area->tz_module_arr);
521 	return err;
522 }
523 
524 static void
mlxsw_thermal_modules_fini(struct mlxsw_thermal * thermal,struct mlxsw_thermal_area * area)525 mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal,
526 			   struct mlxsw_thermal_area *area)
527 {
528 	int i;
529 
530 	for (i = area->tz_module_num - 1; i >= 0; i--)
531 		mlxsw_thermal_module_fini(&area->tz_module_arr[i]);
532 	kfree(area->tz_module_arr);
533 }
534 
535 static int
mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module * gearbox_tz)536 mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
537 {
538 	char tz_name[THERMAL_NAME_LENGTH];
539 	int ret;
540 
541 	if (gearbox_tz->slot_index)
542 		snprintf(tz_name, sizeof(tz_name), "mlxsw-lc%d-gearbox%d",
543 			 gearbox_tz->slot_index, gearbox_tz->module + 1);
544 	else
545 		snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
546 			 gearbox_tz->module + 1);
547 	gearbox_tz->tzdev = thermal_zone_device_register_with_trips(tz_name,
548 						gearbox_tz->trips,
549 						MLXSW_THERMAL_NUM_TRIPS,
550 						MLXSW_THERMAL_TRIP_MASK,
551 						gearbox_tz,
552 						&mlxsw_thermal_gearbox_ops,
553 						&mlxsw_thermal_params, 0,
554 						gearbox_tz->parent->polling_delay);
555 	if (IS_ERR(gearbox_tz->tzdev))
556 		return PTR_ERR(gearbox_tz->tzdev);
557 
558 	ret = thermal_zone_device_enable(gearbox_tz->tzdev);
559 	if (ret)
560 		thermal_zone_device_unregister(gearbox_tz->tzdev);
561 
562 	return ret;
563 }
564 
565 static void
mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module * gearbox_tz)566 mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
567 {
568 	thermal_zone_device_unregister(gearbox_tz->tzdev);
569 }
570 
571 static int
mlxsw_thermal_gearboxes_init(struct device * dev,struct mlxsw_core * core,struct mlxsw_thermal * thermal,struct mlxsw_thermal_area * area)572 mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
573 			     struct mlxsw_thermal *thermal,
574 			     struct mlxsw_thermal_area *area)
575 {
576 	enum mlxsw_reg_mgpir_device_type device_type;
577 	struct mlxsw_thermal_module *gearbox_tz;
578 	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
579 	u8 gbox_num;
580 	int i;
581 	int err;
582 
583 	mlxsw_reg_mgpir_pack(mgpir_pl, area->slot_index);
584 	err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
585 	if (err)
586 		return err;
587 
588 	mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL,
589 			       NULL, NULL);
590 	if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
591 	    !gbox_num)
592 		return 0;
593 
594 	area->tz_gearbox_num = gbox_num;
595 	area->tz_gearbox_arr = kcalloc(area->tz_gearbox_num,
596 				       sizeof(*area->tz_gearbox_arr),
597 				       GFP_KERNEL);
598 	if (!area->tz_gearbox_arr)
599 		return -ENOMEM;
600 
601 	for (i = 0; i < area->tz_gearbox_num; i++) {
602 		gearbox_tz = &area->tz_gearbox_arr[i];
603 		memcpy(gearbox_tz->trips, default_thermal_trips,
604 		       sizeof(thermal->trips));
605 		memcpy(gearbox_tz->cooling_states, default_cooling_states,
606 		       sizeof(thermal->cooling_states));
607 		gearbox_tz->module = i;
608 		gearbox_tz->parent = thermal;
609 		gearbox_tz->slot_index = area->slot_index;
610 		err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
611 		if (err)
612 			goto err_thermal_gearbox_tz_init;
613 	}
614 
615 	return 0;
616 
617 err_thermal_gearbox_tz_init:
618 	for (i--; i >= 0; i--)
619 		mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
620 	kfree(area->tz_gearbox_arr);
621 	return err;
622 }
623 
624 static void
mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal * thermal,struct mlxsw_thermal_area * area)625 mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal,
626 			     struct mlxsw_thermal_area *area)
627 {
628 	int i;
629 
630 	for (i = area->tz_gearbox_num - 1; i >= 0; i--)
631 		mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
632 	kfree(area->tz_gearbox_arr);
633 }
634 
635 static void
mlxsw_thermal_got_active(struct mlxsw_core * mlxsw_core,u8 slot_index,void * priv)636 mlxsw_thermal_got_active(struct mlxsw_core *mlxsw_core, u8 slot_index,
637 			 void *priv)
638 {
639 	struct mlxsw_thermal *thermal = priv;
640 	struct mlxsw_thermal_area *linecard;
641 	int err;
642 
643 	linecard = &thermal->line_cards[slot_index];
644 
645 	if (linecard->active)
646 		return;
647 
648 	linecard->slot_index = slot_index;
649 	err = mlxsw_thermal_modules_init(thermal->bus_info->dev, thermal->core,
650 					 thermal, linecard);
651 	if (err) {
652 		dev_err(thermal->bus_info->dev, "Failed to configure thermal objects for line card modules in slot %d\n",
653 			slot_index);
654 		return;
655 	}
656 
657 	err = mlxsw_thermal_gearboxes_init(thermal->bus_info->dev,
658 					   thermal->core, thermal, linecard);
659 	if (err) {
660 		dev_err(thermal->bus_info->dev, "Failed to configure thermal objects for line card gearboxes in slot %d\n",
661 			slot_index);
662 		goto err_thermal_linecard_gearboxes_init;
663 	}
664 
665 	linecard->active = true;
666 
667 	return;
668 
669 err_thermal_linecard_gearboxes_init:
670 	mlxsw_thermal_modules_fini(thermal, linecard);
671 }
672 
673 static void
mlxsw_thermal_got_inactive(struct mlxsw_core * mlxsw_core,u8 slot_index,void * priv)674 mlxsw_thermal_got_inactive(struct mlxsw_core *mlxsw_core, u8 slot_index,
675 			   void *priv)
676 {
677 	struct mlxsw_thermal *thermal = priv;
678 	struct mlxsw_thermal_area *linecard;
679 
680 	linecard = &thermal->line_cards[slot_index];
681 	if (!linecard->active)
682 		return;
683 	linecard->active = false;
684 	mlxsw_thermal_gearboxes_fini(thermal, linecard);
685 	mlxsw_thermal_modules_fini(thermal, linecard);
686 }
687 
688 static struct mlxsw_linecards_event_ops mlxsw_thermal_event_ops = {
689 	.got_active = mlxsw_thermal_got_active,
690 	.got_inactive = mlxsw_thermal_got_inactive,
691 };
692 
mlxsw_thermal_init(struct mlxsw_core * core,const struct mlxsw_bus_info * bus_info,struct mlxsw_thermal ** p_thermal)693 int mlxsw_thermal_init(struct mlxsw_core *core,
694 		       const struct mlxsw_bus_info *bus_info,
695 		       struct mlxsw_thermal **p_thermal)
696 {
697 	char mfcr_pl[MLXSW_REG_MFCR_LEN] = { 0 };
698 	enum mlxsw_reg_mfcr_pwm_frequency freq;
699 	struct device *dev = bus_info->dev;
700 	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
701 	struct mlxsw_thermal *thermal;
702 	u8 pwm_active, num_of_slots;
703 	u16 tacho_active;
704 	int err, i;
705 
706 	mlxsw_reg_mgpir_pack(mgpir_pl, 0);
707 	err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
708 	if (err)
709 		return err;
710 
711 	mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, NULL,
712 			       &num_of_slots);
713 
714 	thermal = kzalloc(struct_size(thermal, line_cards, num_of_slots + 1),
715 			  GFP_KERNEL);
716 	if (!thermal)
717 		return -ENOMEM;
718 
719 	thermal->core = core;
720 	thermal->bus_info = bus_info;
721 	memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
722 	memcpy(thermal->cooling_states, default_cooling_states, sizeof(thermal->cooling_states));
723 	thermal->line_cards[0].slot_index = 0;
724 
725 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
726 	if (err) {
727 		dev_err(dev, "Failed to probe PWMs\n");
728 		goto err_reg_query;
729 	}
730 	mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
731 
732 	for (i = 0; i < MLXSW_MFCR_TACHOS_MAX; i++) {
733 		if (tacho_active & BIT(i)) {
734 			char mfsl_pl[MLXSW_REG_MFSL_LEN];
735 
736 			mlxsw_reg_mfsl_pack(mfsl_pl, i, 0, 0);
737 
738 			/* We need to query the register to preserve maximum */
739 			err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsl),
740 					      mfsl_pl);
741 			if (err)
742 				goto err_reg_query;
743 
744 			/* set the minimal RPMs to 0 */
745 			mlxsw_reg_mfsl_tach_min_set(mfsl_pl, 0);
746 			err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsl),
747 					      mfsl_pl);
748 			if (err)
749 				goto err_reg_write;
750 		}
751 	}
752 	for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
753 		if (pwm_active & BIT(i)) {
754 			struct thermal_cooling_device *cdev;
755 
756 			cdev = thermal_cooling_device_register("mlxsw_fan",
757 							       thermal,
758 							       &mlxsw_cooling_ops);
759 			if (IS_ERR(cdev)) {
760 				err = PTR_ERR(cdev);
761 				dev_err(dev, "Failed to register cooling device\n");
762 				goto err_thermal_cooling_device_register;
763 			}
764 			thermal->cdevs[i] = cdev;
765 		}
766 	}
767 
768 	thermal->polling_delay = bus_info->low_frequency ?
769 				 MLXSW_THERMAL_SLOW_POLL_INT :
770 				 MLXSW_THERMAL_POLL_INT;
771 
772 	thermal->tzdev = thermal_zone_device_register_with_trips("mlxsw",
773 						      thermal->trips,
774 						      MLXSW_THERMAL_NUM_TRIPS,
775 						      MLXSW_THERMAL_TRIP_MASK,
776 						      thermal,
777 						      &mlxsw_thermal_ops,
778 						      &mlxsw_thermal_params, 0,
779 						      thermal->polling_delay);
780 	if (IS_ERR(thermal->tzdev)) {
781 		err = PTR_ERR(thermal->tzdev);
782 		dev_err(dev, "Failed to register thermal zone\n");
783 		goto err_thermal_zone_device_register;
784 	}
785 
786 	err = mlxsw_thermal_modules_init(dev, core, thermal,
787 					 &thermal->line_cards[0]);
788 	if (err)
789 		goto err_thermal_modules_init;
790 
791 	err = mlxsw_thermal_gearboxes_init(dev, core, thermal,
792 					   &thermal->line_cards[0]);
793 	if (err)
794 		goto err_thermal_gearboxes_init;
795 
796 	err = mlxsw_linecards_event_ops_register(core,
797 						 &mlxsw_thermal_event_ops,
798 						 thermal);
799 	if (err)
800 		goto err_linecards_event_ops_register;
801 
802 	err = thermal_zone_device_enable(thermal->tzdev);
803 	if (err)
804 		goto err_thermal_zone_device_enable;
805 
806 	thermal->line_cards[0].active = true;
807 	*p_thermal = thermal;
808 	return 0;
809 
810 err_thermal_zone_device_enable:
811 	mlxsw_linecards_event_ops_unregister(thermal->core,
812 					     &mlxsw_thermal_event_ops,
813 					     thermal);
814 err_linecards_event_ops_register:
815 	mlxsw_thermal_gearboxes_fini(thermal, &thermal->line_cards[0]);
816 err_thermal_gearboxes_init:
817 	mlxsw_thermal_modules_fini(thermal, &thermal->line_cards[0]);
818 err_thermal_modules_init:
819 	if (thermal->tzdev) {
820 		thermal_zone_device_unregister(thermal->tzdev);
821 		thermal->tzdev = NULL;
822 	}
823 err_thermal_zone_device_register:
824 err_thermal_cooling_device_register:
825 	for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
826 		if (thermal->cdevs[i])
827 			thermal_cooling_device_unregister(thermal->cdevs[i]);
828 err_reg_write:
829 err_reg_query:
830 	kfree(thermal);
831 	return err;
832 }
833 
mlxsw_thermal_fini(struct mlxsw_thermal * thermal)834 void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
835 {
836 	int i;
837 
838 	thermal->line_cards[0].active = false;
839 	mlxsw_linecards_event_ops_unregister(thermal->core,
840 					     &mlxsw_thermal_event_ops,
841 					     thermal);
842 	mlxsw_thermal_gearboxes_fini(thermal, &thermal->line_cards[0]);
843 	mlxsw_thermal_modules_fini(thermal, &thermal->line_cards[0]);
844 	if (thermal->tzdev) {
845 		thermal_zone_device_unregister(thermal->tzdev);
846 		thermal->tzdev = NULL;
847 	}
848 
849 	for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
850 		if (thermal->cdevs[i]) {
851 			thermal_cooling_device_unregister(thermal->cdevs[i]);
852 			thermal->cdevs[i] = NULL;
853 		}
854 	}
855 
856 	kfree(thermal);
857 }
858