Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/x86: alienware-wmi-wmax: Improve internal AWCC API

Inline all AWCC WMI helper methods and directly return the newly
introduced awcc_wmi_command() helper to simplify implementation.

Drop awcc_thermal_control() in favor of awcc_op_activate_profile().

Add awcc_op_get_resource_id(), awcc_op_get_current_profile() and a new
failure code.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Signed-off-by: Kurt Borja <kuurtb@gmail.com>
Link: https://lore.kernel.org/r/20250329-hwm-v7-3-a14ea39d8a94@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Kurt Borja and committed by
Ilpo Järvinen
45983d19 a000da9d

+84 -46
+84 -46
drivers/platform/x86/dell/alienware-wmi-wmax.c
··· 32 32 #define AWCC_THERMAL_MODE_GMODE 0xAB 33 33 34 34 #define AWCC_FAILURE_CODE 0xFFFFFFFF 35 + #define AWCC_FAILURE_CODE_2 0xFFFFFFFE 35 36 36 37 #define AWCC_SENSOR_ID_FLAG BIT(8) 37 38 #define AWCC_THERMAL_MODE_MASK GENMASK(3, 0) ··· 445 444 }; 446 445 447 446 /* 448 - * Thermal Profile control 449 - * - Provides thermal profile control through the Platform Profile API 447 + * AWCC Helpers 450 448 */ 451 449 static bool is_awcc_thermal_profile_id(u8 code) 452 450 { ··· 464 464 return false; 465 465 } 466 466 467 - static int awcc_thermal_information(struct wmi_device *wdev, u8 operation, 468 - u8 arg, u32 *out_data) 467 + static int awcc_wmi_command(struct wmi_device *wdev, u32 method_id, 468 + struct wmax_u32_args *args, u32 *out) 469 469 { 470 - struct wmax_u32_args in_args = { 471 - .operation = operation, 472 - .arg1 = arg, 473 - .arg2 = 0, 474 - .arg3 = 0, 475 - }; 476 470 int ret; 477 471 478 - ret = alienware_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, 479 - &in_args, sizeof(in_args), out_data); 480 - if (ret < 0) 472 + ret = alienware_wmi_command(wdev, method_id, args, sizeof(*args), out); 473 + if (ret) 481 474 return ret; 482 475 483 - if (*out_data == AWCC_FAILURE_CODE) 476 + if (*out == AWCC_FAILURE_CODE || *out == AWCC_FAILURE_CODE_2) 484 477 return -EBADRQC; 485 478 486 479 return 0; 487 480 } 488 481 489 - static int awcc_thermal_control(struct wmi_device *wdev, u8 profile) 482 + static int awcc_thermal_information(struct wmi_device *wdev, u8 operation, u8 arg, 483 + u32 *out) 490 484 { 491 - struct wmax_u32_args in_args = { 492 - .operation = AWCC_OP_ACTIVATE_PROFILE, 493 - .arg1 = profile, 485 + struct wmax_u32_args args = { 486 + .operation = operation, 487 + .arg1 = arg, 488 + .arg2 = 0, 489 + .arg3 = 0, 490 + }; 491 + 492 + return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out); 493 + } 494 + 495 + static int awcc_game_shift_status(struct wmi_device *wdev, u8 operation, 496 + u32 *out) 497 + { 498 + struct wmax_u32_args args = { 499 + .operation = operation, 500 + .arg1 = 0, 501 + .arg2 = 0, 502 + .arg3 = 0, 503 + }; 504 + 505 + return awcc_wmi_command(wdev, AWCC_METHOD_GAME_SHIFT_STATUS, &args, out); 506 + } 507 + 508 + /** 509 + * awcc_op_get_resource_id - Get the resource ID at a given index 510 + * @wdev: AWCC WMI device 511 + * @index: Index 512 + * @out: Value returned by the WMI call 513 + * 514 + * Get the resource ID at a given @index. Resource IDs are listed in the 515 + * following order: 516 + * 517 + * - Fan IDs 518 + * - Sensor IDs 519 + * - Unknown IDs 520 + * - Thermal Profile IDs 521 + * 522 + * The total number of IDs of a given type can be obtained with 523 + * AWCC_OP_GET_SYSTEM_DESCRIPTION. 524 + * 525 + * Return: 0 on success, -errno on failure 526 + */ 527 + static int awcc_op_get_resource_id(struct wmi_device *wdev, u8 index, u8 *out) 528 + { 529 + struct wmax_u32_args args = { 530 + .operation = AWCC_OP_GET_RESOURCE_ID, 531 + .arg1 = index, 494 532 .arg2 = 0, 495 533 .arg3 = 0, 496 534 }; 497 535 u32 out_data; 498 536 int ret; 499 537 500 - ret = alienware_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, 501 - &in_args, sizeof(in_args), &out_data); 538 + ret = awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, &out_data); 502 539 if (ret) 503 540 return ret; 504 541 505 - if (out_data == AWCC_FAILURE_CODE) 506 - return -EBADRQC; 542 + *out = FIELD_GET(AWCC_RESOURCE_ID_MASK, out_data); 507 543 508 544 return 0; 509 545 } 510 546 511 - static int awcc_game_shift_status(struct wmi_device *wdev, u8 operation, 512 - u32 *out_data) 547 + static int awcc_op_get_current_profile(struct wmi_device *wdev, u32 *out) 513 548 { 514 - struct wmax_u32_args in_args = { 515 - .operation = operation, 549 + struct wmax_u32_args args = { 550 + .operation = AWCC_OP_GET_CURRENT_PROFILE, 516 551 .arg1 = 0, 517 552 .arg2 = 0, 518 553 .arg3 = 0, 519 554 }; 520 - int ret; 521 555 522 - ret = alienware_wmi_command(wdev, AWCC_METHOD_GAME_SHIFT_STATUS, 523 - &in_args, sizeof(in_args), out_data); 524 - if (ret < 0) 525 - return ret; 526 - 527 - if (*out_data == AWCC_FAILURE_CODE) 528 - return -EOPNOTSUPP; 529 - 530 - return 0; 556 + return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out); 531 557 } 532 558 559 + static int awcc_op_activate_profile(struct wmi_device *wdev, u8 profile) 560 + { 561 + struct wmax_u32_args args = { 562 + .operation = AWCC_OP_ACTIVATE_PROFILE, 563 + .arg1 = profile, 564 + .arg2 = 0, 565 + .arg3 = 0, 566 + }; 567 + u32 out; 568 + 569 + return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &args, &out); 570 + } 571 + 572 + /* 573 + * Thermal Profile control 574 + * - Provides thermal profile control through the Platform Profile API 575 + */ 533 576 static int awcc_platform_profile_get(struct device *dev, 534 577 enum platform_profile_option *profile) 535 578 { ··· 580 537 u32 out_data; 581 538 int ret; 582 539 583 - ret = awcc_thermal_information(priv->wdev, AWCC_OP_GET_CURRENT_PROFILE, 584 - 0, &out_data); 585 - 586 - if (ret < 0) 540 + ret = awcc_op_get_current_profile(priv->wdev, &out_data); 541 + if (ret) 587 542 return ret; 588 543 589 544 if (out_data == AWCC_THERMAL_MODE_GMODE) { ··· 625 584 } 626 585 } 627 586 628 - return awcc_thermal_control(priv->wdev, 629 - priv->supported_thermal_profiles[profile]); 587 + return awcc_op_activate_profile(priv->wdev, 588 + priv->supported_thermal_profiles[profile]); 630 589 } 631 590 632 591 static int awcc_platform_profile_probe(void *drvdata, unsigned long *choices) ··· 636 595 enum awcc_thermal_profile mode; 637 596 u8 sys_desc[4]; 638 597 u32 first_mode; 639 - u32 out_data; 640 598 int ret; 641 599 u8 id; 642 600 ··· 647 607 first_mode = sys_desc[0] + sys_desc[1]; 648 608 649 609 for (u32 i = 0; i < sys_desc[3]; i++) { 650 - ret = awcc_thermal_information(priv->wdev, AWCC_OP_GET_RESOURCE_ID, 651 - i + first_mode, &out_data); 610 + ret = awcc_op_get_resource_id(priv->wdev, i + first_mode, &id); 652 611 653 612 if (ret == -EIO) 654 613 return ret; ··· 655 616 if (ret == -EBADRQC) 656 617 break; 657 618 658 - id = FIELD_GET(AWCC_RESOURCE_ID_MASK, out_data); 659 619 if (!is_awcc_thermal_profile_id(id)) 660 620 continue; 661 621