1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * fan_core.c - ACPI Fan core Driver 4 * 5 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 6 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 7 * Copyright (C) 2022 Intel Corporation. All rights reserved. 8 */ 9 10 #include <linux/bits.h> 11 #include <linux/kernel.h> 12 #include <linux/limits.h> 13 #include <linux/math.h> 14 #include <linux/math64.h> 15 #include <linux/module.h> 16 #include <linux/init.h> 17 #include <linux/types.h> 18 #include <linux/uaccess.h> 19 #include <linux/uuid.h> 20 #include <linux/thermal.h> 21 #include <linux/acpi.h> 22 #include <linux/platform_device.h> 23 #include <linux/sort.h> 24 25 #include "fan.h" 26 27 #define ACPI_FAN_NOTIFY_STATE_CHANGED 0x80 28 29 /* 30 * Defined inside the "Fan Noise Signal" section at 31 * https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/design-guide. 32 */ 33 static const guid_t acpi_fan_microsoft_guid = GUID_INIT(0xA7611840, 0x99FE, 0x41AE, 0xA4, 0x88, 34 0x35, 0xC7, 0x59, 0x26, 0xC8, 0xEB); 35 #define ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY 1 36 #define ACPI_FAN_DSM_SET_TRIP_POINTS 2 37 #define ACPI_FAN_DSM_GET_OPERATING_RANGES 3 38 39 /* 40 * Ensures that fans with a very low trip point granularity 41 * do not send too many notifications. 42 */ 43 static uint min_trip_distance = 100; 44 module_param(min_trip_distance, uint, 0); 45 MODULE_PARM_DESC(min_trip_distance, "Minimum distance between fan speed trip points in RPM"); 46 47 static const struct acpi_device_id fan_device_ids[] = { 48 ACPI_FAN_DEVICE_IDS, 49 {"", 0}, 50 }; 51 MODULE_DEVICE_TABLE(acpi, fan_device_ids); 52 53 /* thermal cooling device callbacks */ 54 static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long 55 *state) 56 { 57 struct acpi_device *device = cdev->devdata; 58 struct acpi_fan *fan = acpi_driver_data(device); 59 60 if (fan->acpi4) { 61 if (fan->fif.fine_grain_ctrl) 62 *state = 100 / fan->fif.step_size; 63 else 64 *state = fan->fps_count - 1; 65 } else { 66 *state = 1; 67 } 68 69 return 0; 70 } 71 72 int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst) 73 { 74 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 75 union acpi_object *obj; 76 acpi_status status; 77 int ret = 0; 78 79 status = acpi_evaluate_object(handle, "_FST", NULL, &buffer); 80 if (ACPI_FAILURE(status)) 81 return -EIO; 82 83 obj = buffer.pointer; 84 if (!obj) 85 return -ENODATA; 86 87 if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3) { 88 ret = -EPROTO; 89 goto err; 90 } 91 92 if (obj->package.elements[0].type != ACPI_TYPE_INTEGER || 93 obj->package.elements[1].type != ACPI_TYPE_INTEGER || 94 obj->package.elements[2].type != ACPI_TYPE_INTEGER) { 95 ret = -EPROTO; 96 goto err; 97 } 98 99 fst->revision = obj->package.elements[0].integer.value; 100 fst->control = obj->package.elements[1].integer.value; 101 fst->speed = obj->package.elements[2].integer.value; 102 103 err: 104 kfree(obj); 105 return ret; 106 } 107 108 static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state) 109 { 110 struct acpi_fan *fan = acpi_driver_data(device); 111 struct acpi_fan_fst fst; 112 int status, i; 113 114 status = acpi_fan_get_fst(device->handle, &fst); 115 if (status) 116 return status; 117 118 if (fan->fif.fine_grain_ctrl) { 119 /* This control should be same what we set using _FSL by spec */ 120 if (fst.control > 100) { 121 dev_dbg(&device->dev, "Invalid control value returned\n"); 122 goto match_fps; 123 } 124 125 *state = (int) fst.control / fan->fif.step_size; 126 return 0; 127 } 128 129 match_fps: 130 for (i = 0; i < fan->fps_count; i++) { 131 if (fst.control == fan->fps[i].control) 132 break; 133 } 134 if (i == fan->fps_count) { 135 dev_dbg(&device->dev, "No matching fps control value\n"); 136 return -EINVAL; 137 } 138 139 *state = i; 140 141 return status; 142 } 143 144 static int fan_get_state(struct acpi_device *device, unsigned long *state) 145 { 146 int result; 147 int acpi_state = ACPI_STATE_D0; 148 149 result = acpi_device_update_power(device, &acpi_state); 150 if (result) 151 return result; 152 153 *state = acpi_state == ACPI_STATE_D3_COLD 154 || acpi_state == ACPI_STATE_D3_HOT ? 155 0 : (acpi_state == ACPI_STATE_D0 ? 1 : -1); 156 return 0; 157 } 158 159 static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long 160 *state) 161 { 162 struct acpi_device *device = cdev->devdata; 163 struct acpi_fan *fan = acpi_driver_data(device); 164 165 if (fan->acpi4) 166 return fan_get_state_acpi4(device, state); 167 else 168 return fan_get_state(device, state); 169 } 170 171 static int fan_set_state(struct acpi_device *device, unsigned long state) 172 { 173 if (state != 0 && state != 1) 174 return -EINVAL; 175 176 return acpi_device_set_power(device, 177 state ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD); 178 } 179 180 static int fan_set_state_acpi4(struct acpi_device *device, unsigned long state) 181 { 182 struct acpi_fan *fan = acpi_driver_data(device); 183 acpi_status status; 184 u64 value = state; 185 int max_state; 186 187 if (fan->fif.fine_grain_ctrl) 188 max_state = 100 / fan->fif.step_size; 189 else 190 max_state = fan->fps_count - 1; 191 192 if (state > max_state) 193 return -EINVAL; 194 195 if (fan->fif.fine_grain_ctrl) { 196 value *= fan->fif.step_size; 197 /* Spec allows compensate the last step only */ 198 if (value + fan->fif.step_size > 100) 199 value = 100; 200 } else { 201 value = fan->fps[state].control; 202 } 203 204 status = acpi_execute_simple_method(device->handle, "_FSL", value); 205 if (ACPI_FAILURE(status)) { 206 dev_dbg(&device->dev, "Failed to set state by _FSL\n"); 207 return -ENODEV; 208 } 209 210 return 0; 211 } 212 213 static int 214 fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) 215 { 216 struct acpi_device *device = cdev->devdata; 217 struct acpi_fan *fan = acpi_driver_data(device); 218 219 if (fan->acpi4) 220 return fan_set_state_acpi4(device, state); 221 else 222 return fan_set_state(device, state); 223 } 224 225 static const struct thermal_cooling_device_ops fan_cooling_ops = { 226 .get_max_state = fan_get_max_state, 227 .get_cur_state = fan_get_cur_state, 228 .set_cur_state = fan_set_cur_state, 229 }; 230 231 /* -------------------------------------------------------------------------- 232 * Driver Interface 233 * -------------------------------------------------------------------------- 234 */ 235 236 static int acpi_fan_get_fif(struct acpi_device *device) 237 { 238 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 239 struct acpi_fan *fan = acpi_driver_data(device); 240 struct acpi_buffer format = { sizeof("NNNN"), "NNNN" }; 241 u64 fields[4]; 242 struct acpi_buffer fif = { sizeof(fields), fields }; 243 union acpi_object *obj; 244 acpi_status status; 245 246 status = acpi_evaluate_object(device->handle, "_FIF", NULL, &buffer); 247 if (ACPI_FAILURE(status)) 248 return status; 249 250 obj = buffer.pointer; 251 if (!obj || obj->type != ACPI_TYPE_PACKAGE) { 252 dev_err(&device->dev, "Invalid _FIF data\n"); 253 status = -EINVAL; 254 goto err; 255 } 256 257 status = acpi_extract_package(obj, &format, &fif); 258 if (ACPI_FAILURE(status)) { 259 dev_err(&device->dev, "Invalid _FIF element\n"); 260 status = -EINVAL; 261 goto err; 262 } 263 264 fan->fif.revision = fields[0]; 265 fan->fif.fine_grain_ctrl = fields[1]; 266 fan->fif.step_size = fields[2]; 267 fan->fif.low_speed_notification = fields[3]; 268 269 /* If there is a bug in step size and set as 0, change to 1 */ 270 if (!fan->fif.step_size) 271 fan->fif.step_size = 1; 272 /* If step size > 9, change to 9 (by spec valid values 1-9) */ 273 else if (fan->fif.step_size > 9) 274 fan->fif.step_size = 9; 275 err: 276 kfree(obj); 277 return status; 278 } 279 280 static int acpi_fan_speed_cmp(const void *a, const void *b) 281 { 282 const struct acpi_fan_fps *fps1 = a; 283 const struct acpi_fan_fps *fps2 = b; 284 return fps1->speed - fps2->speed; 285 } 286 287 static int acpi_fan_get_fps(struct acpi_device *device) 288 { 289 struct acpi_fan *fan = acpi_driver_data(device); 290 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 291 union acpi_object *obj; 292 acpi_status status; 293 int i; 294 295 status = acpi_evaluate_object(device->handle, "_FPS", NULL, &buffer); 296 if (ACPI_FAILURE(status)) 297 return status; 298 299 obj = buffer.pointer; 300 if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count < 2) { 301 dev_err(&device->dev, "Invalid _FPS data\n"); 302 status = -EINVAL; 303 goto err; 304 } 305 306 fan->fps_count = obj->package.count - 1; /* minus revision field */ 307 fan->fps = devm_kcalloc(&device->dev, 308 fan->fps_count, sizeof(struct acpi_fan_fps), 309 GFP_KERNEL); 310 if (!fan->fps) { 311 dev_err(&device->dev, "Not enough memory\n"); 312 status = -ENOMEM; 313 goto err; 314 } 315 for (i = 0; i < fan->fps_count; i++) { 316 struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" }; 317 struct acpi_buffer fps = { offsetof(struct acpi_fan_fps, name), 318 &fan->fps[i] }; 319 status = acpi_extract_package(&obj->package.elements[i + 1], 320 &format, &fps); 321 if (ACPI_FAILURE(status)) { 322 dev_err(&device->dev, "Invalid _FPS element\n"); 323 goto err; 324 } 325 } 326 327 /* sort the state array according to fan speed in increase order */ 328 sort(fan->fps, fan->fps_count, sizeof(*fan->fps), 329 acpi_fan_speed_cmp, NULL); 330 331 err: 332 kfree(obj); 333 return status; 334 } 335 336 static int acpi_fan_dsm_init(struct device *dev) 337 { 338 union acpi_object dummy = { 339 .package = { 340 .type = ACPI_TYPE_PACKAGE, 341 .count = 0, 342 .elements = NULL, 343 }, 344 }; 345 struct acpi_fan *fan = dev_get_drvdata(dev); 346 union acpi_object *obj; 347 int ret = 0; 348 349 if (!acpi_check_dsm(fan->handle, &acpi_fan_microsoft_guid, 0, 350 BIT(ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY) | 351 BIT(ACPI_FAN_DSM_SET_TRIP_POINTS))) 352 return 0; 353 354 dev_info(dev, "Using Microsoft fan extensions\n"); 355 356 obj = acpi_evaluate_dsm_typed(fan->handle, &acpi_fan_microsoft_guid, 0, 357 ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY, &dummy, 358 ACPI_TYPE_INTEGER); 359 if (!obj) 360 return -EIO; 361 362 if (obj->integer.value > U32_MAX) 363 ret = -EOVERFLOW; 364 else 365 fan->fan_trip_granularity = obj->integer.value; 366 367 kfree(obj); 368 369 return ret; 370 } 371 372 static int acpi_fan_dsm_set_trip_points(struct device *dev, u64 upper, u64 lower) 373 { 374 union acpi_object args[2] = { 375 { 376 .integer = { 377 .type = ACPI_TYPE_INTEGER, 378 .value = lower, 379 }, 380 }, 381 { 382 .integer = { 383 .type = ACPI_TYPE_INTEGER, 384 .value = upper, 385 }, 386 }, 387 }; 388 struct acpi_fan *fan = dev_get_drvdata(dev); 389 union acpi_object in = { 390 .package = { 391 .type = ACPI_TYPE_PACKAGE, 392 .count = ARRAY_SIZE(args), 393 .elements = args, 394 }, 395 }; 396 union acpi_object *obj; 397 398 obj = acpi_evaluate_dsm(fan->handle, &acpi_fan_microsoft_guid, 0, 399 ACPI_FAN_DSM_SET_TRIP_POINTS, &in); 400 kfree(obj); 401 402 return 0; 403 } 404 405 static int acpi_fan_dsm_start(struct device *dev) 406 { 407 struct acpi_fan *fan = dev_get_drvdata(dev); 408 int ret; 409 410 if (!fan->fan_trip_granularity) 411 return 0; 412 413 /* 414 * Some firmware implementations only update the values returned by the 415 * _FST control method when a notification is received. This usually 416 * works with Microsoft Windows as setting up trip points will keep 417 * triggering said notifications, but will cause issues when using _FST 418 * without the Microsoft-specific trip point extension. 419 * 420 * Because of this, an initial notification needs to be triggered to 421 * start the cycle of trip points updates. This is achieved by setting 422 * the trip points sequencially to two separate ranges. As by the 423 * Microsoft specification the firmware should trigger a notification 424 * immediately if the fan speed is outside the trip point range. This 425 * _should_ result in at least one notification as both ranges do not 426 * overlap, meaning that the current fan speed needs to be outside at 427 * least one range. 428 */ 429 ret = acpi_fan_dsm_set_trip_points(dev, fan->fan_trip_granularity, 0); 430 if (ret < 0) 431 return ret; 432 433 return acpi_fan_dsm_set_trip_points(dev, fan->fan_trip_granularity * 3, 434 fan->fan_trip_granularity * 2); 435 } 436 437 static int acpi_fan_dsm_update_trips_points(struct device *dev, struct acpi_fan_fst *fst) 438 { 439 struct acpi_fan *fan = dev_get_drvdata(dev); 440 u64 upper, lower; 441 442 if (!fan->fan_trip_granularity) 443 return 0; 444 445 if (!acpi_fan_speed_valid(fst->speed)) 446 return -EINVAL; 447 448 upper = roundup_u64(fst->speed + min_trip_distance, fan->fan_trip_granularity); 449 if (fst->speed <= min_trip_distance) { 450 lower = 0; 451 } else { 452 /* 453 * Valid fan speed values cannot be larger than 32 bit, so 454 * we can safely assume that no overflow will happen here. 455 */ 456 lower = rounddown((u32)fst->speed - min_trip_distance, fan->fan_trip_granularity); 457 } 458 459 return acpi_fan_dsm_set_trip_points(dev, upper, lower); 460 } 461 462 static void acpi_fan_notify_handler(acpi_handle handle, u32 event, void *context) 463 { 464 struct device *dev = context; 465 struct acpi_fan_fst fst; 466 int ret; 467 468 switch (event) { 469 case ACPI_FAN_NOTIFY_STATE_CHANGED: 470 /* 471 * The ACPI specification says that we must evaluate _FST when we 472 * receive an ACPI event indicating that the fan state has changed. 473 */ 474 ret = acpi_fan_get_fst(handle, &fst); 475 if (ret < 0) { 476 dev_err(dev, "Error retrieving current fan status: %d\n", ret); 477 } else { 478 ret = acpi_fan_dsm_update_trips_points(dev, &fst); 479 if (ret < 0) 480 dev_err(dev, "Failed to update trip points: %d\n", ret); 481 } 482 483 acpi_fan_notify_hwmon(dev); 484 acpi_bus_generate_netlink_event("fan", dev_name(dev), event, 0); 485 break; 486 default: 487 dev_dbg(dev, "Unsupported ACPI notification 0x%x\n", event); 488 break; 489 } 490 } 491 492 static void acpi_fan_notify_remove(void *data) 493 { 494 struct acpi_fan *fan = data; 495 496 acpi_remove_notify_handler(fan->handle, ACPI_DEVICE_NOTIFY, acpi_fan_notify_handler); 497 } 498 499 static int devm_acpi_fan_notify_init(struct device *dev) 500 { 501 struct acpi_fan *fan = dev_get_drvdata(dev); 502 acpi_status status; 503 504 status = acpi_install_notify_handler(fan->handle, ACPI_DEVICE_NOTIFY, 505 acpi_fan_notify_handler, dev); 506 if (ACPI_FAILURE(status)) 507 return -EIO; 508 509 return devm_add_action_or_reset(dev, acpi_fan_notify_remove, fan); 510 } 511 512 static int acpi_fan_probe(struct platform_device *pdev) 513 { 514 int result = 0; 515 struct thermal_cooling_device *cdev; 516 struct acpi_fan *fan; 517 struct acpi_device *device = ACPI_COMPANION(&pdev->dev); 518 char *name; 519 520 if (!device) 521 return -ENODEV; 522 523 fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL); 524 if (!fan) { 525 dev_err(&device->dev, "No memory for fan\n"); 526 return -ENOMEM; 527 } 528 529 fan->handle = device->handle; 530 device->driver_data = fan; 531 platform_set_drvdata(pdev, fan); 532 533 if (acpi_has_method(device->handle, "_FST")) { 534 fan->has_fst = true; 535 fan->acpi4 = acpi_has_method(device->handle, "_FIF") && 536 acpi_has_method(device->handle, "_FPS") && 537 acpi_has_method(device->handle, "_FSL"); 538 } 539 540 if (fan->acpi4) { 541 result = acpi_fan_get_fif(device); 542 if (result) 543 return result; 544 545 result = acpi_fan_get_fps(device); 546 if (result) 547 return result; 548 } 549 550 if (fan->has_fst) { 551 result = acpi_fan_dsm_init(&pdev->dev); 552 if (result) 553 return result; 554 555 result = devm_acpi_fan_create_hwmon(&pdev->dev); 556 if (result) 557 return result; 558 559 result = devm_acpi_fan_notify_init(&pdev->dev); 560 if (result) 561 return result; 562 563 result = acpi_fan_dsm_start(&pdev->dev); 564 if (result) { 565 dev_err(&pdev->dev, "Failed to start Microsoft fan extensions\n"); 566 return result; 567 } 568 569 result = acpi_fan_create_attributes(device); 570 if (result) 571 return result; 572 } 573 574 if (!fan->acpi4) { 575 result = acpi_device_update_power(device, NULL); 576 if (result) { 577 dev_err(&device->dev, "Failed to set initial power state\n"); 578 goto err_end; 579 } 580 } 581 582 if (!strncmp(pdev->name, "PNP0C0B", strlen("PNP0C0B"))) 583 name = "Fan"; 584 else 585 name = acpi_device_bid(device); 586 587 cdev = thermal_cooling_device_register(name, device, 588 &fan_cooling_ops); 589 if (IS_ERR(cdev)) { 590 result = PTR_ERR(cdev); 591 goto err_end; 592 } 593 594 dev_dbg(&pdev->dev, "registered as cooling_device%d\n", cdev->id); 595 596 fan->cdev = cdev; 597 result = sysfs_create_link(&pdev->dev.kobj, 598 &cdev->device.kobj, 599 "thermal_cooling"); 600 if (result) { 601 dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n"); 602 goto err_unregister; 603 } 604 605 result = sysfs_create_link(&cdev->device.kobj, 606 &pdev->dev.kobj, 607 "device"); 608 if (result) { 609 dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n"); 610 goto err_remove_link; 611 } 612 613 return 0; 614 615 err_remove_link: 616 sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling"); 617 err_unregister: 618 thermal_cooling_device_unregister(cdev); 619 err_end: 620 if (fan->has_fst) 621 acpi_fan_delete_attributes(device); 622 623 return result; 624 } 625 626 static void acpi_fan_remove(struct platform_device *pdev) 627 { 628 struct acpi_fan *fan = platform_get_drvdata(pdev); 629 630 if (fan->has_fst) { 631 struct acpi_device *device = ACPI_COMPANION(&pdev->dev); 632 633 acpi_fan_delete_attributes(device); 634 } 635 sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling"); 636 sysfs_remove_link(&fan->cdev->device.kobj, "device"); 637 thermal_cooling_device_unregister(fan->cdev); 638 } 639 640 #ifdef CONFIG_PM_SLEEP 641 static int acpi_fan_suspend(struct device *dev) 642 { 643 struct acpi_fan *fan = dev_get_drvdata(dev); 644 if (fan->acpi4) 645 return 0; 646 647 acpi_device_set_power(ACPI_COMPANION(dev), ACPI_STATE_D0); 648 649 return AE_OK; 650 } 651 652 static int acpi_fan_resume(struct device *dev) 653 { 654 struct acpi_fan *fan = dev_get_drvdata(dev); 655 int result; 656 657 if (fan->has_fst) { 658 result = acpi_fan_dsm_start(dev); 659 if (result) 660 dev_err(dev, "Failed to start Microsoft fan extensions: %d\n", result); 661 } 662 663 if (fan->acpi4) 664 return 0; 665 666 result = acpi_device_update_power(ACPI_COMPANION(dev), NULL); 667 if (result) 668 dev_err(dev, "Error updating fan power state\n"); 669 670 return result; 671 } 672 673 static const struct dev_pm_ops acpi_fan_pm = { 674 .resume = acpi_fan_resume, 675 .freeze = acpi_fan_suspend, 676 .thaw = acpi_fan_resume, 677 .restore = acpi_fan_resume, 678 }; 679 #define FAN_PM_OPS_PTR (&acpi_fan_pm) 680 681 #else 682 683 #define FAN_PM_OPS_PTR NULL 684 685 #endif 686 687 static struct platform_driver acpi_fan_driver = { 688 .probe = acpi_fan_probe, 689 .remove = acpi_fan_remove, 690 .driver = { 691 .name = "acpi-fan", 692 .acpi_match_table = fan_device_ids, 693 .pm = FAN_PM_OPS_PTR, 694 }, 695 }; 696 697 module_platform_driver(acpi_fan_driver); 698 699 MODULE_AUTHOR("Paul Diefenbaugh"); 700 MODULE_DESCRIPTION("ACPI Fan Driver"); 701 MODULE_LICENSE("GPL"); 702