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