1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Lenovo Capability Data WMI Data Block driver. 4 * 5 * Lenovo Capability Data provides information on tunable attributes used by 6 * the "Other Mode" WMI interface. 7 * 8 * Capability Data 00 includes if the attribute is supported by the hardware, 9 * and the default_value. All attributes are independent of thermal modes. 10 * 11 * Capability Data 01 includes if the attribute is supported by the hardware, 12 * and the default_value, max_value, min_value, and step increment. Each 13 * attribute has multiple pages, one for each of the thermal modes managed by 14 * the Gamezone interface. 15 * 16 * Fan Test Data includes the max/min fan speed RPM for each fan. This is 17 * reference data for self-test. If the fan is in good condition, it is capable 18 * to spin faster than max RPM or slower than min RPM. 19 * 20 * Copyright (C) 2025 Derek J. Clark <derekjohn.clark@gmail.com> 21 * - Initial implementation (formerly named lenovo-wmi-capdata01) 22 * 23 * Copyright (C) 2025 Rong Zhang <i@rong.moe> 24 * - Unified implementation 25 */ 26 27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 28 29 #include <linux/acpi.h> 30 #include <linux/bug.h> 31 #include <linux/cleanup.h> 32 #include <linux/component.h> 33 #include <linux/container_of.h> 34 #include <linux/debugfs.h> 35 #include <linux/device.h> 36 #include <linux/dev_printk.h> 37 #include <linux/err.h> 38 #include <linux/export.h> 39 #include <linux/gfp_types.h> 40 #include <linux/limits.h> 41 #include <linux/module.h> 42 #include <linux/mutex.h> 43 #include <linux/mutex_types.h> 44 #include <linux/notifier.h> 45 #include <linux/overflow.h> 46 #include <linux/seq_file.h> 47 #include <linux/stddef.h> 48 #include <linux/types.h> 49 #include <linux/wmi.h> 50 51 #include "wmi-capdata.h" 52 #include "wmi-helpers.h" 53 54 #define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E" 55 #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154" 56 #define LENOVO_FAN_TEST_DATA_GUID "B642801B-3D21-45DE-90AE-6E86F164FB21" 57 58 #define ACPI_AC_NOTIFY_STATUS 0x80 59 60 #define LWMI_FEATURE_ID_FAN_TEST 0x05 61 62 #define LWMI_ATTR_ID_FAN_TEST \ 63 lwmi_attr_id(LWMI_DEVICE_ID_FAN, LWMI_FEATURE_ID_FAN_TEST, \ 64 LWMI_GZ_THERMAL_MODE_NONE, LWMI_TYPE_ID_NONE) 65 66 enum lwmi_cd_type { 67 LENOVO_CAPABILITY_DATA_00, 68 LENOVO_CAPABILITY_DATA_01, 69 LENOVO_FAN_TEST_DATA, 70 CD_TYPE_NONE = -1, 71 }; 72 73 #define LWMI_CD_TABLE_ITEM(_type) \ 74 [_type] = { \ 75 .name = #_type, \ 76 .type = _type, \ 77 } 78 79 static const struct lwmi_cd_info { 80 const char *name; 81 enum lwmi_cd_type type; 82 } lwmi_cd_table[] = { 83 LWMI_CD_TABLE_ITEM(LENOVO_CAPABILITY_DATA_00), 84 LWMI_CD_TABLE_ITEM(LENOVO_CAPABILITY_DATA_01), 85 LWMI_CD_TABLE_ITEM(LENOVO_FAN_TEST_DATA), 86 }; 87 88 struct lwmi_cd_priv { 89 struct notifier_block acpi_nb; /* ACPI events */ 90 struct wmi_device *wdev; 91 struct cd_list *list; 92 struct dentry *debugfs_dir; 93 94 /* 95 * A capdata device may be a component master of another capdata device. 96 * E.g., lenovo-wmi-other <-> capdata00 <-> capdata_fan 97 * |- master |- component 98 * |- sub-master 99 * |- sub-component 100 */ 101 struct lwmi_cd_sub_master_priv { 102 struct device *master_dev; 103 cd_list_cb_t master_cb; 104 struct cd_list *sub_component_list; /* ERR_PTR(-ENODEV) implies no sub-component. */ 105 bool registered; /* Has the sub-master been registered? */ 106 } *sub_master; 107 }; 108 109 struct cd_list { 110 struct mutex list_mutex; /* list R/W mutex */ 111 enum lwmi_cd_type type; 112 u8 count; 113 114 union { 115 DECLARE_FLEX_ARRAY(struct capdata00, cd00); 116 DECLARE_FLEX_ARRAY(struct capdata01, cd01); 117 DECLARE_FLEX_ARRAY(struct capdata_fan, cd_fan); 118 }; 119 }; 120 121 static struct wmi_driver lwmi_cd_driver; 122 123 /* ======== Device components ======== */ 124 125 /** 126 * lwmi_cd_match() - Match rule for the master driver. 127 * @dev: Pointer to the capability data parent device. 128 * @type: Pointer to capability data type (enum lwmi_cd_type *) to match. 129 * 130 * Return: int. 131 */ 132 static int lwmi_cd_match(struct device *dev, void *type) 133 { 134 struct lwmi_cd_priv *priv; 135 136 if (dev->driver != &lwmi_cd_driver.driver) 137 return false; 138 139 priv = dev_get_drvdata(dev); 140 return priv->list->type == *(enum lwmi_cd_type *)type; 141 } 142 143 /** 144 * lwmi_cd_match_add_all() - Add all match rule for the master driver. 145 * @master: Pointer to the master device. 146 * @matchptr: Pointer to the returned component_match pointer. 147 * 148 * Adds all component matches to the list stored in @matchptr for the @master 149 * device. @matchptr must be initialized to NULL. 150 */ 151 void lwmi_cd_match_add_all(struct device *master, struct component_match **matchptr) 152 { 153 int i; 154 155 if (WARN_ON(*matchptr)) 156 return; 157 158 for (i = 0; i < ARRAY_SIZE(lwmi_cd_table); i++) { 159 /* Skip sub-components. */ 160 if (lwmi_cd_table[i].type == LENOVO_FAN_TEST_DATA) 161 continue; 162 163 component_match_add(master, matchptr, lwmi_cd_match, 164 (void *)&lwmi_cd_table[i].type); 165 if (IS_ERR(*matchptr)) 166 return; 167 } 168 } 169 EXPORT_SYMBOL_NS_GPL(lwmi_cd_match_add_all, "LENOVO_WMI_CAPDATA"); 170 171 /** 172 * lwmi_cd_call_master_cb() - Call the master callback for the sub-component. 173 * @priv: Pointer to the capability data private data. 174 * 175 * Call the master callback and pass the sub-component list to it if the 176 * dependency chain (master <-> sub-master <-> sub-component) is complete. 177 */ 178 static void lwmi_cd_call_master_cb(struct lwmi_cd_priv *priv) 179 { 180 struct cd_list *sub_component_list = priv->sub_master->sub_component_list; 181 182 /* 183 * Call the callback only if the dependency chain is ready: 184 * - Binding between master and sub-master: fills master_dev and master_cb 185 * - Binding between sub-master and sub-component: fills sub_component_list 186 * 187 * If a binding has been unbound before the other binding is bound, the 188 * corresponding members filled by the former are guaranteed to be cleared. 189 * 190 * This function is only called in bind callbacks, and the component 191 * framework guarantees bind/unbind callbacks may never execute 192 * simultaneously, which implies that it's impossible to have a race 193 * condition. 194 * 195 * Hence, this check is sufficient to ensure that the callback is called 196 * at most once and with the correct state, without relying on a specific 197 * sequence of binding establishment. 198 */ 199 if (!sub_component_list || 200 !priv->sub_master->master_dev || 201 !priv->sub_master->master_cb) 202 return; 203 204 if (PTR_ERR(sub_component_list) == -ENODEV) 205 sub_component_list = NULL; 206 else if (WARN_ON(IS_ERR(sub_component_list))) 207 return; 208 209 priv->sub_master->master_cb(priv->sub_master->master_dev, 210 sub_component_list); 211 212 /* 213 * Userspace may unbind a device from its driver and bind it again 214 * through sysfs. Let's call this operation "reprobe" to distinguish it 215 * from component "rebind". 216 * 217 * When reprobing capdata00/01 or the master device, the master device 218 * is unbound from us with appropriate cleanup before we bind to it and 219 * call master_cb. Everything is fine in this case. 220 * 221 * When reprobing capdata_fan, the master device has never been unbound 222 * from us (hence no cleanup is done)[1], but we call master_cb the 223 * second time. To solve this issue, we clear master_cb and master_dev 224 * so we won't call master_cb twice while a binding is still complete. 225 * 226 * Note that we can't clear sub_component_list, otherwise reprobing 227 * capdata01 or the master device causes master_cb to be never called 228 * after we rebind to the master device. 229 * 230 * [1]: The master device does not need capdata_fan in run time, so 231 * losing capdata_fan will not break the binding to the master device. 232 */ 233 priv->sub_master->master_cb = NULL; 234 priv->sub_master->master_dev = NULL; 235 } 236 237 /** 238 * lwmi_cd_component_bind() - Bind component to master device. 239 * @cd_dev: Pointer to the lenovo-wmi-capdata driver parent device. 240 * @om_dev: Pointer to the lenovo-wmi-other driver parent device. 241 * @data: lwmi_cd_binder object pointer used to return the capability data. 242 * 243 * On lenovo-wmi-other's master bind, provide a pointer to the local capdata 244 * list. This is used to call lwmi_cd*_get_data to look up attribute data 245 * from the lenovo-wmi-other driver. 246 * 247 * If cd_dev is a sub-master, try to call the master callback. 248 * 249 * Return: 0 250 */ 251 static int lwmi_cd_component_bind(struct device *cd_dev, 252 struct device *om_dev, void *data) 253 { 254 struct lwmi_cd_priv *priv = dev_get_drvdata(cd_dev); 255 struct lwmi_cd_binder *binder = data; 256 257 switch (priv->list->type) { 258 case LENOVO_CAPABILITY_DATA_00: 259 binder->cd00_list = priv->list; 260 261 priv->sub_master->master_dev = om_dev; 262 priv->sub_master->master_cb = binder->cd_fan_list_cb; 263 lwmi_cd_call_master_cb(priv); 264 265 break; 266 case LENOVO_CAPABILITY_DATA_01: 267 binder->cd01_list = priv->list; 268 break; 269 default: 270 return -EINVAL; 271 } 272 273 return 0; 274 } 275 276 /** 277 * lwmi_cd_component_unbind() - Unbind component to master device. 278 * @cd_dev: Pointer to the lenovo-wmi-capdata driver parent device. 279 * @om_dev: Pointer to the lenovo-wmi-other driver parent device. 280 * @data: Unused. 281 * 282 * If cd_dev is a sub-master, clear the collected data from the master device to 283 * prevent the binding establishment between the sub-master and the sub- 284 * component (if it's about to happen) from calling the master callback. 285 */ 286 static void lwmi_cd_component_unbind(struct device *cd_dev, 287 struct device *om_dev, void *data) 288 { 289 struct lwmi_cd_priv *priv = dev_get_drvdata(cd_dev); 290 291 switch (priv->list->type) { 292 case LENOVO_CAPABILITY_DATA_00: 293 priv->sub_master->master_dev = NULL; 294 priv->sub_master->master_cb = NULL; 295 return; 296 default: 297 return; 298 } 299 } 300 301 static const struct component_ops lwmi_cd_component_ops = { 302 .bind = lwmi_cd_component_bind, 303 .unbind = lwmi_cd_component_unbind, 304 }; 305 306 /** 307 * lwmi_cd_sub_master_bind() - Bind sub-component of sub-master device 308 * @dev: The sub-master capdata basic device. 309 * 310 * Call component_bind_all to bind the sub-component device to the sub-master 311 * device. On success, collect the pointer to the sub-component list and try 312 * to call the master callback. 313 * 314 * Return: 0 on success, or an error code. 315 */ 316 static int lwmi_cd_sub_master_bind(struct device *dev) 317 { 318 struct lwmi_cd_priv *priv = dev_get_drvdata(dev); 319 struct cd_list *sub_component_list; 320 int ret; 321 322 ret = component_bind_all(dev, &sub_component_list); 323 if (ret) 324 return ret; 325 326 priv->sub_master->sub_component_list = sub_component_list; 327 lwmi_cd_call_master_cb(priv); 328 329 return 0; 330 } 331 332 /** 333 * lwmi_cd_sub_master_unbind() - Unbind sub-component of sub-master device 334 * @dev: The sub-master capdata basic device 335 * 336 * Clear the collected pointer to the sub-component list to prevent the binding 337 * establishment between the sub-master and the sub-component (if it's about to 338 * happen) from calling the master callback. Then, call component_unbind_all to 339 * unbind the sub-component device from the sub-master device. 340 */ 341 static void lwmi_cd_sub_master_unbind(struct device *dev) 342 { 343 struct lwmi_cd_priv *priv = dev_get_drvdata(dev); 344 345 priv->sub_master->sub_component_list = NULL; 346 347 component_unbind_all(dev, NULL); 348 } 349 350 static const struct component_master_ops lwmi_cd_sub_master_ops = { 351 .bind = lwmi_cd_sub_master_bind, 352 .unbind = lwmi_cd_sub_master_unbind, 353 }; 354 355 /** 356 * lwmi_cd_sub_master_add() - Register a sub-master with its sub-component 357 * @priv: Pointer to the sub-master capdata device private data. 358 * @sub_component_type: Type of the sub-component. 359 * 360 * Match the sub-component type and register the current capdata device as a 361 * sub-master. If the given sub-component type is CD_TYPE_NONE, mark the sub- 362 * component as non-existent without registering sub-master. 363 * 364 * Return: 0 on success, or an error code. 365 */ 366 static int lwmi_cd_sub_master_add(struct lwmi_cd_priv *priv, 367 enum lwmi_cd_type sub_component_type) 368 { 369 struct component_match *master_match = NULL; 370 int ret; 371 372 priv->sub_master = devm_kzalloc(&priv->wdev->dev, sizeof(*priv->sub_master), GFP_KERNEL); 373 if (!priv->sub_master) 374 return -ENOMEM; 375 376 if (sub_component_type == CD_TYPE_NONE) { 377 /* The master callback will be called with NULL on bind. */ 378 priv->sub_master->sub_component_list = ERR_PTR(-ENODEV); 379 priv->sub_master->registered = false; 380 return 0; 381 } 382 383 /* 384 * lwmi_cd_match() needs a pointer to enum lwmi_cd_type, but on-stack 385 * data cannot be used here. Steal one from lwmi_cd_table. 386 */ 387 component_match_add(&priv->wdev->dev, &master_match, lwmi_cd_match, 388 (void *)&lwmi_cd_table[sub_component_type].type); 389 if (IS_ERR(master_match)) 390 return PTR_ERR(master_match); 391 392 ret = component_master_add_with_match(&priv->wdev->dev, &lwmi_cd_sub_master_ops, 393 master_match); 394 if (ret) 395 return ret; 396 397 priv->sub_master->registered = true; 398 return 0; 399 } 400 401 /** 402 * lwmi_cd_sub_master_del() - Unregister a sub-master if it's registered 403 * @priv: Pointer to the sub-master capdata device private data. 404 */ 405 static void lwmi_cd_sub_master_del(struct lwmi_cd_priv *priv) 406 { 407 if (!priv->sub_master->registered) 408 return; 409 410 component_master_del(&priv->wdev->dev, &lwmi_cd_sub_master_ops); 411 priv->sub_master->registered = false; 412 } 413 414 /** 415 * lwmi_cd_sub_component_bind() - Bind sub-component to sub-master device. 416 * @sc_dev: Pointer to the sub-component capdata parent device. 417 * @sm_dev: Pointer to the sub-master capdata parent device. 418 * @data: Pointer used to return the capability data list pointer. 419 * 420 * On sub-master's bind, provide a pointer to the local capdata list. 421 * This is used by the sub-master to call the master callback. 422 * 423 * Return: 0 424 */ 425 static int lwmi_cd_sub_component_bind(struct device *sc_dev, 426 struct device *sm_dev, void *data) 427 { 428 struct lwmi_cd_priv *priv = dev_get_drvdata(sc_dev); 429 struct cd_list **listp = data; 430 431 *listp = priv->list; 432 433 return 0; 434 } 435 436 static const struct component_ops lwmi_cd_sub_component_ops = { 437 .bind = lwmi_cd_sub_component_bind, 438 }; 439 440 /* 441 * lwmi_cd*_get_data - Get the data of the specified attribute 442 * @list: The lenovo-wmi-capdata pointer to its cd_list struct. 443 * @attribute_id: The capdata attribute ID to be found. 444 * @output: Pointer to a capdata* struct to return the data. 445 * 446 * Retrieves the capability data struct pointer for the given 447 * attribute. 448 * 449 * Return: 0 on success, or -EINVAL. 450 */ 451 #define DEF_LWMI_CDXX_GET_DATA(_cdxx, _cd_type, _output_t) \ 452 int lwmi_##_cdxx##_get_data(struct cd_list *list, u32 attribute_id, _output_t *output) \ 453 { \ 454 u8 idx; \ 455 \ 456 if (WARN_ON(list->type != _cd_type)) \ 457 return -EINVAL; \ 458 \ 459 guard(mutex)(&list->list_mutex); \ 460 for (idx = 0; idx < list->count; idx++) { \ 461 if (list->_cdxx[idx].id != attribute_id) \ 462 continue; \ 463 memcpy(output, &list->_cdxx[idx], sizeof(list->_cdxx[idx])); \ 464 return 0; \ 465 } \ 466 return -EINVAL; \ 467 } 468 469 DEF_LWMI_CDXX_GET_DATA(cd00, LENOVO_CAPABILITY_DATA_00, struct capdata00); 470 EXPORT_SYMBOL_NS_GPL(lwmi_cd00_get_data, "LENOVO_WMI_CAPDATA"); 471 472 DEF_LWMI_CDXX_GET_DATA(cd01, LENOVO_CAPABILITY_DATA_01, struct capdata01); 473 EXPORT_SYMBOL_NS_GPL(lwmi_cd01_get_data, "LENOVO_WMI_CAPDATA"); 474 475 DEF_LWMI_CDXX_GET_DATA(cd_fan, LENOVO_FAN_TEST_DATA, struct capdata_fan); 476 EXPORT_SYMBOL_NS_GPL(lwmi_cd_fan_get_data, "LENOVO_WMI_CAPDATA"); 477 478 /* ======== debugfs ======== */ 479 480 /** 481 * lwmi_cd00_show() - Dump capdata00 482 * @s: Pointer to seq_file where the capdata00 is dumped. 483 * @cd00: Pointer to a capdata00 struct to be dumped. 484 */ 485 static void lwmi_cd00_show(struct seq_file *s, struct capdata00 *cd00) 486 { 487 u8 dev = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id); 488 u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id); 489 u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id); 490 u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id); 491 bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID); 492 bool get = cd00->supported & LWMI_SUPP_GET; 493 bool set = cd00->supported & LWMI_SUPP_SET; 494 bool valid = cd00->supported & LWMI_SUPP_VALID; 495 496 seq_printf(s, " id: 0x%08x [dev: %2u, feat: %2u, mode: %2u, type: %2u]\n", 497 cd00->id, dev, feat, mode, type); 498 499 seq_printf(s, " supported: 0x%08x [%c%c%c%c]\n", cd00->supported, 500 extra ? '+' : ' ', 501 get ? 'R' : ' ', 502 set ? 'W' : ' ', 503 valid ? 'V' : ' '); 504 505 seq_printf(s, " default_value: %u\n", cd00->default_value); 506 } 507 508 /** 509 * lwmi_cd01_show() - Dump capdata01 510 * @s: Pointer to seq_file where the capdata01 is dumped. 511 * @cd01: Pointer to a capdata01 struct to be dumped. 512 */ 513 static void lwmi_cd01_show(struct seq_file *s, struct capdata01 *cd01) 514 { 515 /* capdata01 is an extension to capdata00. */ 516 lwmi_cd00_show(s, &cd01->cd00); 517 518 seq_printf(s, " step: %u\n", cd01->step); 519 seq_printf(s, " min_value: %u\n", cd01->min_value); 520 seq_printf(s, " max_value: %u\n", cd01->max_value); 521 } 522 523 /** 524 * lwmi_cd_fan_show() - Dump capdata_fan 525 * @s: Pointer to seq_file where the capdata_fan is dumped. 526 * @cd_fan: Pointer to a capdata_fan struct to be dumped. 527 */ 528 static void lwmi_cd_fan_show(struct seq_file *s, struct capdata_fan *cd_fan) 529 { 530 seq_printf(s, " id: %u\n", cd_fan->id); 531 seq_printf(s, " min_rpm: %u\n", cd_fan->min_rpm); 532 seq_printf(s, " max_rpm: %u\n", cd_fan->max_rpm); 533 } 534 535 /** 536 * lwmi_cd_debugfs_show() - Dump capability data to debugfs 537 * @s: Pointer to seq_file where the capability data is dumped. 538 * @data: unused. 539 * 540 * Return: 0 541 */ 542 static int lwmi_cd_debugfs_show(struct seq_file *s, void *data) 543 { 544 struct lwmi_cd_priv *priv = s->private; 545 u8 idx; 546 547 guard(mutex)(&priv->list->list_mutex); 548 549 /* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */ 550 for (idx = 0; idx < priv->list->count; idx++) { 551 seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx); 552 553 if (priv->list->type == LENOVO_CAPABILITY_DATA_00) 554 lwmi_cd00_show(s, &priv->list->cd00[idx]); 555 else if (priv->list->type == LENOVO_CAPABILITY_DATA_01) 556 lwmi_cd01_show(s, &priv->list->cd01[idx]); 557 else if (priv->list->type == LENOVO_FAN_TEST_DATA) 558 lwmi_cd_fan_show(s, &priv->list->cd_fan[idx]); 559 } 560 561 return 0; 562 } 563 DEFINE_SHOW_ATTRIBUTE(lwmi_cd_debugfs); 564 565 /** 566 * lwmi_cd_debugfs_add() - Create debugfs directory and files for a device 567 * @priv: lenovo-wmi-capdata driver data. 568 */ 569 static void lwmi_cd_debugfs_add(struct lwmi_cd_priv *priv) 570 { 571 priv->debugfs_dir = lwmi_debugfs_create_dir(priv->wdev); 572 573 debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_fops); 574 } 575 576 /** 577 * lwmi_cd_debugfs_remove() - Remove debugfs directory for a device 578 * @priv: lenovo-wmi-capdata driver data. 579 */ 580 static void lwmi_cd_debugfs_remove(struct lwmi_cd_priv *priv) 581 { 582 debugfs_remove_recursive(priv->debugfs_dir); 583 priv->debugfs_dir = NULL; 584 } 585 586 /* ======== WMI interface ======== */ 587 588 /** 589 * lwmi_cd_cache() - Cache all WMI data block information 590 * @priv: lenovo-wmi-capdata driver data. 591 * 592 * Loop through each WMI data block and cache the data. 593 * 594 * Return: 0 on success, or an error. 595 */ 596 static int lwmi_cd_cache(struct lwmi_cd_priv *priv) 597 { 598 size_t size; 599 int idx; 600 void *p; 601 602 switch (priv->list->type) { 603 case LENOVO_CAPABILITY_DATA_00: 604 p = &priv->list->cd00[0]; 605 size = sizeof(priv->list->cd00[0]); 606 break; 607 case LENOVO_CAPABILITY_DATA_01: 608 p = &priv->list->cd01[0]; 609 size = sizeof(priv->list->cd01[0]); 610 break; 611 case LENOVO_FAN_TEST_DATA: 612 /* Done by lwmi_cd_alloc() => lwmi_cd_fan_list_alloc_cache(). */ 613 return 0; 614 default: 615 return -EINVAL; 616 } 617 618 guard(mutex)(&priv->list->list_mutex); 619 for (idx = 0; idx < priv->list->count; idx++, p += size) { 620 union acpi_object *ret_obj __free(kfree) = NULL; 621 622 ret_obj = wmidev_block_query(priv->wdev, idx); 623 if (!ret_obj) 624 return -ENODEV; 625 626 if (ret_obj->type != ACPI_TYPE_BUFFER || 627 ret_obj->buffer.length < size) 628 continue; 629 630 memcpy(p, ret_obj->buffer.pointer, size); 631 } 632 633 return 0; 634 } 635 636 /** 637 * lwmi_cd_fan_list_alloc_cache() - Alloc and cache Fan Test Data list 638 * @priv: lenovo-wmi-capdata driver data. 639 * @listptr: Pointer to returned cd_list pointer. 640 * 641 * Return: count of fans found, or an error. 642 */ 643 static int lwmi_cd_fan_list_alloc_cache(struct lwmi_cd_priv *priv, struct cd_list **listptr) 644 { 645 struct cd_list *list; 646 size_t size; 647 u32 count; 648 int idx; 649 650 /* Emit unaligned access to u8 buffer with __packed. */ 651 struct cd_fan_block { 652 u32 nr; 653 u32 data[]; /* id[nr], max_rpm[nr], min_rpm[nr] */ 654 } __packed * block; 655 656 union acpi_object *ret_obj __free(kfree) = wmidev_block_query(priv->wdev, 0); 657 if (!ret_obj) 658 return -ENODEV; 659 660 if (ret_obj->type == ACPI_TYPE_BUFFER) { 661 block = (struct cd_fan_block *)ret_obj->buffer.pointer; 662 size = ret_obj->buffer.length; 663 664 count = size >= sizeof(*block) ? block->nr : 0; 665 if (size < struct_size(block, data, count * 3)) { 666 dev_warn(&priv->wdev->dev, 667 "incomplete fan test data block: %zu < %zu, ignoring\n", 668 size, struct_size(block, data, count * 3)); 669 count = 0; 670 } else if (count > U8_MAX) { 671 dev_warn(&priv->wdev->dev, 672 "too many fans reported: %u > %u, truncating\n", 673 count, U8_MAX); 674 count = U8_MAX; 675 } 676 } else { 677 /* 678 * This is usually caused by a dummy ACPI method. Do not return an error 679 * as failing to probe this device will result in sub-master device being 680 * unbound. This behavior aligns with lwmi_cd_cache(). 681 */ 682 count = 0; 683 } 684 685 list = devm_kzalloc(&priv->wdev->dev, struct_size(list, cd_fan, count), GFP_KERNEL); 686 if (!list) 687 return -ENOMEM; 688 689 for (idx = 0; idx < count; idx++) { 690 /* Do not calculate array index using count, as it may be truncated. */ 691 list->cd_fan[idx] = (struct capdata_fan) { 692 .id = block->data[idx], 693 .max_rpm = block->data[idx + block->nr], 694 .min_rpm = block->data[idx + (2 * block->nr)], 695 }; 696 } 697 698 *listptr = list; 699 return count; 700 } 701 702 /** 703 * lwmi_cd_alloc() - Allocate a cd_list struct in drvdata 704 * @priv: lenovo-wmi-capdata driver data. 705 * @type: The type of capability data. 706 * 707 * Allocate a cd_list struct large enough to contain data from all WMI data 708 * blocks provided by the interface. 709 * 710 * Return: 0 on success, or an error. 711 */ 712 static int lwmi_cd_alloc(struct lwmi_cd_priv *priv, enum lwmi_cd_type type) 713 { 714 struct cd_list *list; 715 size_t list_size; 716 int count, ret; 717 718 count = wmidev_instance_count(priv->wdev); 719 720 switch (type) { 721 case LENOVO_CAPABILITY_DATA_00: 722 list_size = struct_size(list, cd00, count); 723 break; 724 case LENOVO_CAPABILITY_DATA_01: 725 list_size = struct_size(list, cd01, count); 726 break; 727 case LENOVO_FAN_TEST_DATA: 728 count = lwmi_cd_fan_list_alloc_cache(priv, &list); 729 if (count < 0) 730 return count; 731 732 goto got_list; 733 default: 734 return -EINVAL; 735 } 736 737 list = devm_kzalloc(&priv->wdev->dev, list_size, GFP_KERNEL); 738 if (!list) 739 return -ENOMEM; 740 741 got_list: 742 ret = devm_mutex_init(&priv->wdev->dev, &list->list_mutex); 743 if (ret) 744 return ret; 745 746 list->type = type; 747 list->count = count; 748 priv->list = list; 749 750 return 0; 751 } 752 753 /** 754 * lwmi_cd_setup() - Cache all WMI data block information 755 * @priv: lenovo-wmi-capdata driver data. 756 * @type: The type of capability data. 757 * 758 * Allocate a cd_list struct large enough to contain data from all WMI data 759 * blocks provided by the interface. Then loop through each data block and 760 * cache the data. 761 * 762 * Return: 0 on success, or an error code. 763 */ 764 static int lwmi_cd_setup(struct lwmi_cd_priv *priv, enum lwmi_cd_type type) 765 { 766 int ret; 767 768 ret = lwmi_cd_alloc(priv, type); 769 if (ret) 770 return ret; 771 772 return lwmi_cd_cache(priv); 773 } 774 775 /** 776 * lwmi_cd01_notifier_call() - Call method for cd01 notifier. 777 * block call chain. 778 * @nb: The notifier_block registered to lenovo-wmi-events driver. 779 * @action: Unused. 780 * @data: The ACPI event. 781 * 782 * For LWMI_EVENT_THERMAL_MODE, set current_mode and notify platform_profile 783 * of a change. 784 * 785 * Return: notifier_block status. 786 */ 787 static int lwmi_cd01_notifier_call(struct notifier_block *nb, unsigned long action, 788 void *data) 789 { 790 struct acpi_bus_event *event = data; 791 struct lwmi_cd_priv *priv; 792 int ret; 793 794 if (strcmp(event->device_class, ACPI_AC_CLASS) != 0) 795 return NOTIFY_DONE; 796 797 priv = container_of(nb, struct lwmi_cd_priv, acpi_nb); 798 799 switch (event->type) { 800 case ACPI_AC_NOTIFY_STATUS: 801 ret = lwmi_cd_cache(priv); 802 if (ret) 803 return NOTIFY_BAD; 804 805 return NOTIFY_OK; 806 default: 807 return NOTIFY_DONE; 808 } 809 } 810 811 /** 812 * lwmi_cd01_unregister() - Unregister the cd01 ACPI notifier_block. 813 * @data: The ACPI event notifier_block to unregister. 814 */ 815 static void lwmi_cd01_unregister(void *data) 816 { 817 struct notifier_block *acpi_nb = data; 818 819 unregister_acpi_notifier(acpi_nb); 820 } 821 822 static int lwmi_cd_probe(struct wmi_device *wdev, const void *context) 823 { 824 const struct lwmi_cd_info *info = context; 825 struct lwmi_cd_priv *priv; 826 int ret; 827 828 if (!info) 829 return -EINVAL; 830 831 priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL); 832 if (!priv) 833 return -ENOMEM; 834 835 priv->wdev = wdev; 836 dev_set_drvdata(&wdev->dev, priv); 837 838 ret = lwmi_cd_setup(priv, info->type); 839 if (ret) 840 goto out; 841 842 switch (info->type) { 843 case LENOVO_CAPABILITY_DATA_00: { 844 enum lwmi_cd_type sub_component_type = LENOVO_FAN_TEST_DATA; 845 struct capdata00 capdata00; 846 847 ret = lwmi_cd00_get_data(priv->list, LWMI_ATTR_ID_FAN_TEST, &capdata00); 848 if (ret || !(capdata00.supported & LWMI_SUPP_VALID)) { 849 dev_dbg(&wdev->dev, "capdata00 declares no fan test support\n"); 850 sub_component_type = CD_TYPE_NONE; 851 } 852 853 /* Sub-master (capdata00) <-> sub-component (capdata_fan) */ 854 ret = lwmi_cd_sub_master_add(priv, sub_component_type); 855 if (ret) 856 goto out; 857 858 /* Master (lenovo-wmi-other) <-> sub-master (capdata00) */ 859 ret = component_add(&wdev->dev, &lwmi_cd_component_ops); 860 if (ret) 861 lwmi_cd_sub_master_del(priv); 862 863 goto out; 864 } 865 case LENOVO_CAPABILITY_DATA_01: 866 priv->acpi_nb.notifier_call = lwmi_cd01_notifier_call; 867 868 ret = register_acpi_notifier(&priv->acpi_nb); 869 if (ret) 870 goto out; 871 872 ret = devm_add_action_or_reset(&wdev->dev, lwmi_cd01_unregister, 873 &priv->acpi_nb); 874 if (ret) 875 goto out; 876 877 ret = component_add(&wdev->dev, &lwmi_cd_component_ops); 878 goto out; 879 case LENOVO_FAN_TEST_DATA: 880 ret = component_add(&wdev->dev, &lwmi_cd_sub_component_ops); 881 goto out; 882 default: 883 return -EINVAL; 884 } 885 out: 886 if (ret) { 887 dev_err(&wdev->dev, "failed to register %s: %d\n", 888 info->name, ret); 889 } else { 890 lwmi_cd_debugfs_add(priv); 891 892 dev_dbg(&wdev->dev, "registered %s with %u items\n", 893 info->name, priv->list->count); 894 } 895 return ret; 896 } 897 898 static void lwmi_cd_remove(struct wmi_device *wdev) 899 { 900 struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev); 901 902 lwmi_cd_debugfs_remove(priv); 903 904 switch (priv->list->type) { 905 case LENOVO_CAPABILITY_DATA_00: 906 lwmi_cd_sub_master_del(priv); 907 fallthrough; 908 case LENOVO_CAPABILITY_DATA_01: 909 component_del(&wdev->dev, &lwmi_cd_component_ops); 910 break; 911 case LENOVO_FAN_TEST_DATA: 912 component_del(&wdev->dev, &lwmi_cd_sub_component_ops); 913 break; 914 default: 915 WARN_ON(1); 916 } 917 } 918 919 #define LWMI_CD_WDEV_ID(_type) \ 920 .guid_string = _type##_GUID, \ 921 .context = &lwmi_cd_table[_type], 922 923 static const struct wmi_device_id lwmi_cd_id_table[] = { 924 { LWMI_CD_WDEV_ID(LENOVO_CAPABILITY_DATA_00) }, 925 { LWMI_CD_WDEV_ID(LENOVO_CAPABILITY_DATA_01) }, 926 { LWMI_CD_WDEV_ID(LENOVO_FAN_TEST_DATA) }, 927 {} 928 }; 929 930 static struct wmi_driver lwmi_cd_driver = { 931 .driver = { 932 .name = "lenovo_wmi_capdata", 933 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 934 }, 935 .id_table = lwmi_cd_id_table, 936 .probe = lwmi_cd_probe, 937 .remove = lwmi_cd_remove, 938 .no_singleton = true, 939 }; 940 941 module_wmi_driver(lwmi_cd_driver); 942 943 MODULE_IMPORT_NS("LENOVO_WMI_HELPERS"); 944 MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table); 945 MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>"); 946 MODULE_AUTHOR("Rong Zhang <i@rong.moe>"); 947 MODULE_DESCRIPTION("Lenovo Capability Data WMI Driver"); 948 MODULE_LICENSE("GPL"); 949