Merge tag 'net-next-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev...
[platform/kernel/linux-rpi.git] / drivers / net / ethernet / mellanox / mlxsw / core_thermal.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }