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