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_MODULE_TEMP_NORM 55000 /* 55C */ 23 #define MLXSW_THERMAL_MODULE_TEMP_HIGH 65000 /* 65C */ 24 #define MLXSW_THERMAL_MODULE_TEMP_HOT 80000 /* 80C */ 25 #define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */ 26 #define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2) 27 #define MLXSW_THERMAL_MAX_STATE 10 28 #define MLXSW_THERMAL_MIN_STATE 2 29 #define MLXSW_THERMAL_MAX_DUTY 255 30 31 /* External cooling devices, allowed for binding to mlxsw thermal zones. */ 32 static char * const mlxsw_thermal_external_allowed_cdev[] = { 33 "mlxreg_fan", 34 }; 35 36 struct mlxsw_cooling_states { 37 int min_state; 38 int max_state; 39 }; 40 41 static const struct thermal_trip default_thermal_trips[] = { 42 { /* In range - 0-40% PWM */ 43 .type = THERMAL_TRIP_ACTIVE, 44 .temperature = MLXSW_THERMAL_ASIC_TEMP_NORM, 45 .hysteresis = MLXSW_THERMAL_HYSTERESIS_TEMP, 46 }, 47 { 48 /* In range - 40-100% PWM */ 49 .type = THERMAL_TRIP_ACTIVE, 50 .temperature = MLXSW_THERMAL_ASIC_TEMP_HIGH, 51 .hysteresis = MLXSW_THERMAL_HYSTERESIS_TEMP, 52 }, 53 { /* Warning */ 54 .type = THERMAL_TRIP_HOT, 55 .temperature = MLXSW_THERMAL_ASIC_TEMP_HOT, 56 }, 57 }; 58 59 static const struct thermal_trip default_thermal_module_trips[] = { 60 { /* In range - 0-40% PWM */ 61 .type = THERMAL_TRIP_ACTIVE, 62 .temperature = MLXSW_THERMAL_MODULE_TEMP_NORM, 63 .hysteresis = MLXSW_THERMAL_HYSTERESIS_TEMP, 64 }, 65 { 66 /* In range - 40-100% PWM */ 67 .type = THERMAL_TRIP_ACTIVE, 68 .temperature = MLXSW_THERMAL_MODULE_TEMP_HIGH, 69 .hysteresis = MLXSW_THERMAL_HYSTERESIS_TEMP, 70 }, 71 { /* Warning */ 72 .type = THERMAL_TRIP_HOT, 73 .temperature = MLXSW_THERMAL_MODULE_TEMP_HOT, 74 }, 75 }; 76 77 static const struct mlxsw_cooling_states default_cooling_states[] = { 78 { 79 .min_state = 0, 80 .max_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10, 81 }, 82 { 83 .min_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10, 84 .max_state = MLXSW_THERMAL_MAX_STATE, 85 }, 86 { 87 .min_state = MLXSW_THERMAL_MAX_STATE, 88 .max_state = MLXSW_THERMAL_MAX_STATE, 89 }, 90 }; 91 92 #define MLXSW_THERMAL_NUM_TRIPS ARRAY_SIZE(default_thermal_trips) 93 94 /* Make sure all trips are writable */ 95 #define MLXSW_THERMAL_TRIP_MASK (BIT(MLXSW_THERMAL_NUM_TRIPS) - 1) 96 97 struct mlxsw_thermal; 98 99 struct mlxsw_thermal_module { 100 struct mlxsw_thermal *parent; 101 struct thermal_zone_device *tzdev; 102 struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS]; 103 struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS]; 104 int module; /* Module or gearbox number */ 105 u8 slot_index; 106 }; 107 108 struct mlxsw_thermal_area { 109 struct mlxsw_thermal_module *tz_module_arr; 110 u8 tz_module_num; 111 struct mlxsw_thermal_module *tz_gearbox_arr; 112 u8 tz_gearbox_num; 113 u8 slot_index; 114 bool active; 115 }; 116 117 struct mlxsw_thermal { 118 struct mlxsw_core *core; 119 const struct mlxsw_bus_info *bus_info; 120 struct thermal_zone_device *tzdev; 121 int polling_delay; 122 struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX]; 123 struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS]; 124 struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS]; 125 struct mlxsw_thermal_area line_cards[]; 126 }; 127 128 static inline u8 mlxsw_state_to_duty(int state) 129 { 130 return DIV_ROUND_CLOSEST(state * MLXSW_THERMAL_MAX_DUTY, 131 MLXSW_THERMAL_MAX_STATE); 132 } 133 134 static inline int mlxsw_duty_to_state(u8 duty) 135 { 136 return DIV_ROUND_CLOSEST(duty * MLXSW_THERMAL_MAX_STATE, 137 MLXSW_THERMAL_MAX_DUTY); 138 } 139 140 static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal, 141 struct thermal_cooling_device *cdev) 142 { 143 int i; 144 145 for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) 146 if (thermal->cdevs[i] == cdev) 147 return i; 148 149 /* Allow mlxsw thermal zone binding to an external cooling device */ 150 for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) { 151 if (!strcmp(cdev->type, mlxsw_thermal_external_allowed_cdev[i])) 152 return 0; 153 } 154 155 return -ENODEV; 156 } 157 158 static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev, 159 struct thermal_cooling_device *cdev) 160 { 161 struct mlxsw_thermal *thermal = thermal_zone_device_priv(tzdev); 162 struct device *dev = thermal->bus_info->dev; 163 int i, err; 164 165 /* If the cooling device is one of ours bind it */ 166 if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0) 167 return 0; 168 169 for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) { 170 const struct mlxsw_cooling_states *state = &thermal->cooling_states[i]; 171 172 err = thermal_zone_bind_cooling_device(tzdev, i, cdev, 173 state->max_state, 174 state->min_state, 175 THERMAL_WEIGHT_DEFAULT); 176 if (err < 0) { 177 dev_err(dev, "Failed to bind cooling device to trip %d\n", i); 178 return err; 179 } 180 } 181 return 0; 182 } 183 184 static int mlxsw_thermal_unbind(struct thermal_zone_device *tzdev, 185 struct thermal_cooling_device *cdev) 186 { 187 struct mlxsw_thermal *thermal = thermal_zone_device_priv(tzdev); 188 struct device *dev = thermal->bus_info->dev; 189 int i; 190 int err; 191 192 /* If the cooling device is our one unbind it */ 193 if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0) 194 return 0; 195 196 for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) { 197 err = thermal_zone_unbind_cooling_device(tzdev, i, cdev); 198 if (err < 0) { 199 dev_err(dev, "Failed to unbind cooling device\n"); 200 return err; 201 } 202 } 203 return 0; 204 } 205 206 static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev, 207 int *p_temp) 208 { 209 struct mlxsw_thermal *thermal = thermal_zone_device_priv(tzdev); 210 struct device *dev = thermal->bus_info->dev; 211 char mtmp_pl[MLXSW_REG_MTMP_LEN]; 212 int temp; 213 int err; 214 215 mlxsw_reg_mtmp_pack(mtmp_pl, 0, 0, false, false); 216 217 err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl); 218 if (err) { 219 dev_err(dev, "Failed to query temp sensor\n"); 220 return err; 221 } 222 mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); 223 224 *p_temp = temp; 225 return 0; 226 } 227 228 static struct thermal_zone_params mlxsw_thermal_params = { 229 .no_hwmon = true, 230 }; 231 232 static struct thermal_zone_device_ops mlxsw_thermal_ops = { 233 .bind = mlxsw_thermal_bind, 234 .unbind = mlxsw_thermal_unbind, 235 .get_temp = mlxsw_thermal_get_temp, 236 }; 237 238 static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev, 239 struct thermal_cooling_device *cdev) 240 { 241 struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev); 242 struct mlxsw_thermal *thermal = tz->parent; 243 int i, j, err; 244 245 /* If the cooling device is one of ours bind it */ 246 if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0) 247 return 0; 248 249 for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) { 250 const struct mlxsw_cooling_states *state = &tz->cooling_states[i]; 251 252 err = thermal_zone_bind_cooling_device(tzdev, i, cdev, 253 state->max_state, 254 state->min_state, 255 THERMAL_WEIGHT_DEFAULT); 256 if (err < 0) 257 goto err_thermal_zone_bind_cooling_device; 258 } 259 return 0; 260 261 err_thermal_zone_bind_cooling_device: 262 for (j = i - 1; j >= 0; j--) 263 thermal_zone_unbind_cooling_device(tzdev, j, cdev); 264 return err; 265 } 266 267 static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev, 268 struct thermal_cooling_device *cdev) 269 { 270 struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev); 271 struct mlxsw_thermal *thermal = tz->parent; 272 int i; 273 int err; 274 275 /* If the cooling device is one of ours unbind it */ 276 if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0) 277 return 0; 278 279 for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) { 280 err = thermal_zone_unbind_cooling_device(tzdev, i, cdev); 281 WARN_ON(err); 282 } 283 return err; 284 } 285 286 static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, 287 int *p_temp) 288 { 289 struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev); 290 struct mlxsw_thermal *thermal = tz->parent; 291 char mtmp_pl[MLXSW_REG_MTMP_LEN]; 292 u16 sensor_index; 293 int err; 294 295 sensor_index = MLXSW_REG_MTMP_MODULE_INDEX_MIN + tz->module; 296 mlxsw_reg_mtmp_pack(mtmp_pl, tz->slot_index, sensor_index, 297 false, false); 298 err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl); 299 if (err) 300 return err; 301 mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, NULL, NULL, NULL); 302 return 0; 303 } 304 305 static struct thermal_zone_device_ops mlxsw_thermal_module_ops = { 306 .bind = mlxsw_thermal_module_bind, 307 .unbind = mlxsw_thermal_module_unbind, 308 .get_temp = mlxsw_thermal_module_temp_get, 309 }; 310 311 static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev, 312 int *p_temp) 313 { 314 struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev); 315 struct mlxsw_thermal *thermal = tz->parent; 316 char mtmp_pl[MLXSW_REG_MTMP_LEN]; 317 u16 index; 318 int temp; 319 int err; 320 321 index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module; 322 mlxsw_reg_mtmp_pack(mtmp_pl, tz->slot_index, index, false, false); 323 324 err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl); 325 if (err) 326 return err; 327 328 mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); 329 330 *p_temp = temp; 331 return 0; 332 } 333 334 static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = { 335 .bind = mlxsw_thermal_module_bind, 336 .unbind = mlxsw_thermal_module_unbind, 337 .get_temp = mlxsw_thermal_gearbox_temp_get, 338 }; 339 340 static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev, 341 unsigned long *p_state) 342 { 343 *p_state = MLXSW_THERMAL_MAX_STATE; 344 return 0; 345 } 346 347 static int mlxsw_thermal_get_cur_state(struct thermal_cooling_device *cdev, 348 unsigned long *p_state) 349 350 { 351 struct mlxsw_thermal *thermal = cdev->devdata; 352 struct device *dev = thermal->bus_info->dev; 353 char mfsc_pl[MLXSW_REG_MFSC_LEN]; 354 int err, idx; 355 u8 duty; 356 357 idx = mlxsw_get_cooling_device_idx(thermal, cdev); 358 if (idx < 0) 359 return idx; 360 361 mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0); 362 err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl); 363 if (err) { 364 dev_err(dev, "Failed to query PWM duty\n"); 365 return err; 366 } 367 368 duty = mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl); 369 *p_state = mlxsw_duty_to_state(duty); 370 return 0; 371 } 372 373 static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev, 374 unsigned long state) 375 376 { 377 struct mlxsw_thermal *thermal = cdev->devdata; 378 struct device *dev = thermal->bus_info->dev; 379 char mfsc_pl[MLXSW_REG_MFSC_LEN]; 380 int idx; 381 int err; 382 383 if (state > MLXSW_THERMAL_MAX_STATE) 384 return -EINVAL; 385 386 idx = mlxsw_get_cooling_device_idx(thermal, cdev); 387 if (idx < 0) 388 return idx; 389 390 /* Normalize the state to the valid speed range. */ 391 state = max_t(unsigned long, MLXSW_THERMAL_MIN_STATE, state); 392 mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state)); 393 err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl); 394 if (err) { 395 dev_err(dev, "Failed to write PWM duty\n"); 396 return err; 397 } 398 return 0; 399 } 400 401 static const struct thermal_cooling_device_ops mlxsw_cooling_ops = { 402 .get_max_state = mlxsw_thermal_get_max_state, 403 .get_cur_state = mlxsw_thermal_get_cur_state, 404 .set_cur_state = mlxsw_thermal_set_cur_state, 405 }; 406 407 static int 408 mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz) 409 { 410 char tz_name[THERMAL_NAME_LENGTH]; 411 int err; 412 413 if (module_tz->slot_index) 414 snprintf(tz_name, sizeof(tz_name), "mlxsw-lc%d-module%d", 415 module_tz->slot_index, module_tz->module + 1); 416 else 417 snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d", 418 module_tz->module + 1); 419 module_tz->tzdev = thermal_zone_device_register_with_trips(tz_name, 420 module_tz->trips, 421 MLXSW_THERMAL_NUM_TRIPS, 422 MLXSW_THERMAL_TRIP_MASK, 423 module_tz, 424 &mlxsw_thermal_module_ops, 425 &mlxsw_thermal_params, 426 0, 427 module_tz->parent->polling_delay); 428 if (IS_ERR(module_tz->tzdev)) { 429 err = PTR_ERR(module_tz->tzdev); 430 return err; 431 } 432 433 err = thermal_zone_device_enable(module_tz->tzdev); 434 if (err) 435 thermal_zone_device_unregister(module_tz->tzdev); 436 437 return err; 438 } 439 440 static void mlxsw_thermal_module_tz_fini(struct thermal_zone_device *tzdev) 441 { 442 thermal_zone_device_unregister(tzdev); 443 } 444 445 static void 446 mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core, 447 struct mlxsw_thermal *thermal, 448 struct mlxsw_thermal_area *area, u8 module) 449 { 450 struct mlxsw_thermal_module *module_tz; 451 452 module_tz = &area->tz_module_arr[module]; 453 /* Skip if parent is already set (case of port split). */ 454 if (module_tz->parent) 455 return; 456 module_tz->module = module; 457 module_tz->slot_index = area->slot_index; 458 module_tz->parent = thermal; 459 BUILD_BUG_ON(ARRAY_SIZE(default_thermal_module_trips) != 460 MLXSW_THERMAL_NUM_TRIPS); 461 memcpy(module_tz->trips, default_thermal_module_trips, 462 sizeof(thermal->trips)); 463 memcpy(module_tz->cooling_states, default_cooling_states, 464 sizeof(thermal->cooling_states)); 465 } 466 467 static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz) 468 { 469 if (module_tz && module_tz->tzdev) { 470 mlxsw_thermal_module_tz_fini(module_tz->tzdev); 471 module_tz->tzdev = NULL; 472 module_tz->parent = NULL; 473 } 474 } 475 476 static int 477 mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core, 478 struct mlxsw_thermal *thermal, 479 struct mlxsw_thermal_area *area) 480 { 481 struct mlxsw_thermal_module *module_tz; 482 char mgpir_pl[MLXSW_REG_MGPIR_LEN]; 483 int i, err; 484 485 mlxsw_reg_mgpir_pack(mgpir_pl, area->slot_index); 486 err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl); 487 if (err) 488 return err; 489 490 mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, 491 &area->tz_module_num, NULL); 492 493 /* For modular system module counter could be zero. */ 494 if (!area->tz_module_num) 495 return 0; 496 497 area->tz_module_arr = kcalloc(area->tz_module_num, 498 sizeof(*area->tz_module_arr), 499 GFP_KERNEL); 500 if (!area->tz_module_arr) 501 return -ENOMEM; 502 503 for (i = 0; i < area->tz_module_num; i++) 504 mlxsw_thermal_module_init(dev, core, thermal, area, i); 505 506 for (i = 0; i < area->tz_module_num; i++) { 507 module_tz = &area->tz_module_arr[i]; 508 if (!module_tz->parent) 509 continue; 510 err = mlxsw_thermal_module_tz_init(module_tz); 511 if (err) 512 goto err_thermal_module_tz_init; 513 } 514 515 return 0; 516 517 err_thermal_module_tz_init: 518 for (i = area->tz_module_num - 1; i >= 0; i--) 519 mlxsw_thermal_module_fini(&area->tz_module_arr[i]); 520 kfree(area->tz_module_arr); 521 return err; 522 } 523 524 static void 525 mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal, 526 struct mlxsw_thermal_area *area) 527 { 528 int i; 529 530 for (i = area->tz_module_num - 1; i >= 0; i--) 531 mlxsw_thermal_module_fini(&area->tz_module_arr[i]); 532 kfree(area->tz_module_arr); 533 } 534 535 static int 536 mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz) 537 { 538 char tz_name[THERMAL_NAME_LENGTH]; 539 int ret; 540 541 if (gearbox_tz->slot_index) 542 snprintf(tz_name, sizeof(tz_name), "mlxsw-lc%d-gearbox%d", 543 gearbox_tz->slot_index, gearbox_tz->module + 1); 544 else 545 snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d", 546 gearbox_tz->module + 1); 547 gearbox_tz->tzdev = thermal_zone_device_register_with_trips(tz_name, 548 gearbox_tz->trips, 549 MLXSW_THERMAL_NUM_TRIPS, 550 MLXSW_THERMAL_TRIP_MASK, 551 gearbox_tz, 552 &mlxsw_thermal_gearbox_ops, 553 &mlxsw_thermal_params, 0, 554 gearbox_tz->parent->polling_delay); 555 if (IS_ERR(gearbox_tz->tzdev)) 556 return PTR_ERR(gearbox_tz->tzdev); 557 558 ret = thermal_zone_device_enable(gearbox_tz->tzdev); 559 if (ret) 560 thermal_zone_device_unregister(gearbox_tz->tzdev); 561 562 return ret; 563 } 564 565 static void 566 mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz) 567 { 568 thermal_zone_device_unregister(gearbox_tz->tzdev); 569 } 570 571 static int 572 mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core, 573 struct mlxsw_thermal *thermal, 574 struct mlxsw_thermal_area *area) 575 { 576 enum mlxsw_reg_mgpir_device_type device_type; 577 struct mlxsw_thermal_module *gearbox_tz; 578 char mgpir_pl[MLXSW_REG_MGPIR_LEN]; 579 u8 gbox_num; 580 int i; 581 int err; 582 583 mlxsw_reg_mgpir_pack(mgpir_pl, area->slot_index); 584 err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl); 585 if (err) 586 return err; 587 588 mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL, 589 NULL, NULL); 590 if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE || 591 !gbox_num) 592 return 0; 593 594 area->tz_gearbox_num = gbox_num; 595 area->tz_gearbox_arr = kcalloc(area->tz_gearbox_num, 596 sizeof(*area->tz_gearbox_arr), 597 GFP_KERNEL); 598 if (!area->tz_gearbox_arr) 599 return -ENOMEM; 600 601 for (i = 0; i < area->tz_gearbox_num; i++) { 602 gearbox_tz = &area->tz_gearbox_arr[i]; 603 memcpy(gearbox_tz->trips, default_thermal_trips, 604 sizeof(thermal->trips)); 605 memcpy(gearbox_tz->cooling_states, default_cooling_states, 606 sizeof(thermal->cooling_states)); 607 gearbox_tz->module = i; 608 gearbox_tz->parent = thermal; 609 gearbox_tz->slot_index = area->slot_index; 610 err = mlxsw_thermal_gearbox_tz_init(gearbox_tz); 611 if (err) 612 goto err_thermal_gearbox_tz_init; 613 } 614 615 return 0; 616 617 err_thermal_gearbox_tz_init: 618 for (i--; i >= 0; i--) 619 mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]); 620 kfree(area->tz_gearbox_arr); 621 return err; 622 } 623 624 static void 625 mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal, 626 struct mlxsw_thermal_area *area) 627 { 628 int i; 629 630 for (i = area->tz_gearbox_num - 1; i >= 0; i--) 631 mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]); 632 kfree(area->tz_gearbox_arr); 633 } 634 635 static void 636 mlxsw_thermal_got_active(struct mlxsw_core *mlxsw_core, u8 slot_index, 637 void *priv) 638 { 639 struct mlxsw_thermal *thermal = priv; 640 struct mlxsw_thermal_area *linecard; 641 int err; 642 643 linecard = &thermal->line_cards[slot_index]; 644 645 if (linecard->active) 646 return; 647 648 linecard->slot_index = slot_index; 649 err = mlxsw_thermal_modules_init(thermal->bus_info->dev, thermal->core, 650 thermal, linecard); 651 if (err) { 652 dev_err(thermal->bus_info->dev, "Failed to configure thermal objects for line card modules in slot %d\n", 653 slot_index); 654 return; 655 } 656 657 err = mlxsw_thermal_gearboxes_init(thermal->bus_info->dev, 658 thermal->core, thermal, linecard); 659 if (err) { 660 dev_err(thermal->bus_info->dev, "Failed to configure thermal objects for line card gearboxes in slot %d\n", 661 slot_index); 662 goto err_thermal_linecard_gearboxes_init; 663 } 664 665 linecard->active = true; 666 667 return; 668 669 err_thermal_linecard_gearboxes_init: 670 mlxsw_thermal_modules_fini(thermal, linecard); 671 } 672 673 static void 674 mlxsw_thermal_got_inactive(struct mlxsw_core *mlxsw_core, u8 slot_index, 675 void *priv) 676 { 677 struct mlxsw_thermal *thermal = priv; 678 struct mlxsw_thermal_area *linecard; 679 680 linecard = &thermal->line_cards[slot_index]; 681 if (!linecard->active) 682 return; 683 linecard->active = false; 684 mlxsw_thermal_gearboxes_fini(thermal, linecard); 685 mlxsw_thermal_modules_fini(thermal, linecard); 686 } 687 688 static struct mlxsw_linecards_event_ops mlxsw_thermal_event_ops = { 689 .got_active = mlxsw_thermal_got_active, 690 .got_inactive = mlxsw_thermal_got_inactive, 691 }; 692 693 int mlxsw_thermal_init(struct mlxsw_core *core, 694 const struct mlxsw_bus_info *bus_info, 695 struct mlxsw_thermal **p_thermal) 696 { 697 char mfcr_pl[MLXSW_REG_MFCR_LEN] = { 0 }; 698 enum mlxsw_reg_mfcr_pwm_frequency freq; 699 struct device *dev = bus_info->dev; 700 char mgpir_pl[MLXSW_REG_MGPIR_LEN]; 701 struct mlxsw_thermal *thermal; 702 u8 pwm_active, num_of_slots; 703 u16 tacho_active; 704 int err, i; 705 706 mlxsw_reg_mgpir_pack(mgpir_pl, 0); 707 err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl); 708 if (err) 709 return err; 710 711 mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, NULL, 712 &num_of_slots); 713 714 thermal = kzalloc(struct_size(thermal, line_cards, num_of_slots + 1), 715 GFP_KERNEL); 716 if (!thermal) 717 return -ENOMEM; 718 719 thermal->core = core; 720 thermal->bus_info = bus_info; 721 memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips)); 722 memcpy(thermal->cooling_states, default_cooling_states, sizeof(thermal->cooling_states)); 723 thermal->line_cards[0].slot_index = 0; 724 725 err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl); 726 if (err) { 727 dev_err(dev, "Failed to probe PWMs\n"); 728 goto err_reg_query; 729 } 730 mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active); 731 732 for (i = 0; i < MLXSW_MFCR_TACHOS_MAX; i++) { 733 if (tacho_active & BIT(i)) { 734 char mfsl_pl[MLXSW_REG_MFSL_LEN]; 735 736 mlxsw_reg_mfsl_pack(mfsl_pl, i, 0, 0); 737 738 /* We need to query the register to preserve maximum */ 739 err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsl), 740 mfsl_pl); 741 if (err) 742 goto err_reg_query; 743 744 /* set the minimal RPMs to 0 */ 745 mlxsw_reg_mfsl_tach_min_set(mfsl_pl, 0); 746 err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsl), 747 mfsl_pl); 748 if (err) 749 goto err_reg_write; 750 } 751 } 752 for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) { 753 if (pwm_active & BIT(i)) { 754 struct thermal_cooling_device *cdev; 755 756 cdev = thermal_cooling_device_register("mlxsw_fan", 757 thermal, 758 &mlxsw_cooling_ops); 759 if (IS_ERR(cdev)) { 760 err = PTR_ERR(cdev); 761 dev_err(dev, "Failed to register cooling device\n"); 762 goto err_thermal_cooling_device_register; 763 } 764 thermal->cdevs[i] = cdev; 765 } 766 } 767 768 thermal->polling_delay = bus_info->low_frequency ? 769 MLXSW_THERMAL_SLOW_POLL_INT : 770 MLXSW_THERMAL_POLL_INT; 771 772 thermal->tzdev = thermal_zone_device_register_with_trips("mlxsw", 773 thermal->trips, 774 MLXSW_THERMAL_NUM_TRIPS, 775 MLXSW_THERMAL_TRIP_MASK, 776 thermal, 777 &mlxsw_thermal_ops, 778 &mlxsw_thermal_params, 0, 779 thermal->polling_delay); 780 if (IS_ERR(thermal->tzdev)) { 781 err = PTR_ERR(thermal->tzdev); 782 dev_err(dev, "Failed to register thermal zone\n"); 783 goto err_thermal_zone_device_register; 784 } 785 786 err = mlxsw_thermal_modules_init(dev, core, thermal, 787 &thermal->line_cards[0]); 788 if (err) 789 goto err_thermal_modules_init; 790 791 err = mlxsw_thermal_gearboxes_init(dev, core, thermal, 792 &thermal->line_cards[0]); 793 if (err) 794 goto err_thermal_gearboxes_init; 795 796 err = mlxsw_linecards_event_ops_register(core, 797 &mlxsw_thermal_event_ops, 798 thermal); 799 if (err) 800 goto err_linecards_event_ops_register; 801 802 err = thermal_zone_device_enable(thermal->tzdev); 803 if (err) 804 goto err_thermal_zone_device_enable; 805 806 thermal->line_cards[0].active = true; 807 *p_thermal = thermal; 808 return 0; 809 810 err_thermal_zone_device_enable: 811 mlxsw_linecards_event_ops_unregister(thermal->core, 812 &mlxsw_thermal_event_ops, 813 thermal); 814 err_linecards_event_ops_register: 815 mlxsw_thermal_gearboxes_fini(thermal, &thermal->line_cards[0]); 816 err_thermal_gearboxes_init: 817 mlxsw_thermal_modules_fini(thermal, &thermal->line_cards[0]); 818 err_thermal_modules_init: 819 if (thermal->tzdev) { 820 thermal_zone_device_unregister(thermal->tzdev); 821 thermal->tzdev = NULL; 822 } 823 err_thermal_zone_device_register: 824 err_thermal_cooling_device_register: 825 for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) 826 if (thermal->cdevs[i]) 827 thermal_cooling_device_unregister(thermal->cdevs[i]); 828 err_reg_write: 829 err_reg_query: 830 kfree(thermal); 831 return err; 832 } 833 834 void mlxsw_thermal_fini(struct mlxsw_thermal *thermal) 835 { 836 int i; 837 838 thermal->line_cards[0].active = false; 839 mlxsw_linecards_event_ops_unregister(thermal->core, 840 &mlxsw_thermal_event_ops, 841 thermal); 842 mlxsw_thermal_gearboxes_fini(thermal, &thermal->line_cards[0]); 843 mlxsw_thermal_modules_fini(thermal, &thermal->line_cards[0]); 844 if (thermal->tzdev) { 845 thermal_zone_device_unregister(thermal->tzdev); 846 thermal->tzdev = NULL; 847 } 848 849 for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) { 850 if (thermal->cdevs[i]) { 851 thermal_cooling_device_unregister(thermal->cdevs[i]); 852 thermal->cdevs[i] = NULL; 853 } 854 } 855 856 kfree(thermal); 857 } 858