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