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