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