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