1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * hwmon driver for HP (and some HP Compaq) business-class computers that 4 * report numeric sensor data via Windows Management Instrumentation (WMI). 5 * 6 * Copyright (C) 2023 James Seo <james@equiv.tech> 7 * 8 * References: 9 * [1] Hewlett-Packard Development Company, L.P., 10 * "HP Client Management Interface Technical White Paper", 2005. [Online]. 11 * Available: https://h20331.www2.hp.com/hpsub/downloads/cmi_whitepaper.pdf 12 * [2] Hewlett-Packard Development Company, L.P., 13 * "HP Retail Manageability", 2012. [Online]. 14 * Available: http://h10032.www1.hp.com/ctg/Manual/c03291135.pdf 15 * [3] Linux Hardware Project, A. Ponomarenko et al., 16 * "linuxhw/ACPI - Collect ACPI table dumps", 2018. [Online]. 17 * Available: https://github.com/linuxhw/ACPI 18 * [4] P. Rohár, "bmfdec - Decompile binary MOF file (BMF) from WMI buffer", 19 * 2017. [Online]. Available: https://github.com/pali/bmfdec 20 */ 21 22 #include <linux/acpi.h> 23 #include <linux/debugfs.h> 24 #include <linux/hwmon.h> 25 #include <linux/jiffies.h> 26 #include <linux/mutex.h> 27 #include <linux/units.h> 28 #include <linux/wmi.h> 29 30 #define HP_WMI_EVENT_NAMESPACE "root\\WMI" 31 #define HP_WMI_EVENT_CLASS "HPBIOS_BIOSEvent" 32 #define HP_WMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" 33 #define HP_WMI_NUMERIC_SENSOR_GUID "8F1F6435-9F42-42C8-BADC-0E9424F20C9A" 34 #define HP_WMI_PLATFORM_EVENTS_GUID "41227C2D-80E1-423F-8B8E-87E32755A0EB" 35 36 /* Patterns for recognizing sensors and matching events to channels. */ 37 38 #define HP_WMI_PATTERN_SYS_TEMP "Chassis Thermal Index" 39 #define HP_WMI_PATTERN_SYS_TEMP2 "System Ambient Temperature" 40 #define HP_WMI_PATTERN_CPU_TEMP "CPU Thermal Index" 41 #define HP_WMI_PATTERN_CPU_TEMP2 "CPU Temperature" 42 #define HP_WMI_PATTERN_TEMP_SENSOR "Thermal Index" 43 #define HP_WMI_PATTERN_TEMP_ALARM "Thermal Critical" 44 #define HP_WMI_PATTERN_INTRUSION_ALARM "Hood Intrusion" 45 #define HP_WMI_PATTERN_FAN_ALARM "Stall" 46 #define HP_WMI_PATTERN_TEMP "Temperature" 47 #define HP_WMI_PATTERN_CPU "CPU" 48 49 /* These limits are arbitrary. The WMI implementation may vary by system. */ 50 51 #define HP_WMI_MAX_STR_SIZE 128U 52 #define HP_WMI_MAX_PROPERTIES 32U 53 #define HP_WMI_MAX_INSTANCES 32U 54 55 enum hp_wmi_type { 56 HP_WMI_TYPE_OTHER = 1, 57 HP_WMI_TYPE_TEMPERATURE = 2, 58 HP_WMI_TYPE_VOLTAGE = 3, 59 HP_WMI_TYPE_CURRENT = 4, 60 HP_WMI_TYPE_AIR_FLOW = 12, 61 HP_WMI_TYPE_INTRUSION = 0xabadb01, /* Custom. */ 62 }; 63 64 enum hp_wmi_category { 65 HP_WMI_CATEGORY_SENSOR = 3, 66 }; 67 68 enum hp_wmi_severity { 69 HP_WMI_SEVERITY_UNKNOWN = 0, 70 HP_WMI_SEVERITY_OK = 5, 71 HP_WMI_SEVERITY_DEGRADED_WARNING = 10, 72 HP_WMI_SEVERITY_MINOR_FAILURE = 15, 73 HP_WMI_SEVERITY_MAJOR_FAILURE = 20, 74 HP_WMI_SEVERITY_CRITICAL_FAILURE = 25, 75 HP_WMI_SEVERITY_NON_RECOVERABLE_ERROR = 30, 76 }; 77 78 enum hp_wmi_status { 79 HP_WMI_STATUS_OK = 2, 80 HP_WMI_STATUS_DEGRADED = 3, 81 HP_WMI_STATUS_STRESSED = 4, 82 HP_WMI_STATUS_PREDICTIVE_FAILURE = 5, 83 HP_WMI_STATUS_ERROR = 6, 84 HP_WMI_STATUS_NON_RECOVERABLE_ERROR = 7, 85 HP_WMI_STATUS_NO_CONTACT = 12, 86 HP_WMI_STATUS_LOST_COMMUNICATION = 13, 87 HP_WMI_STATUS_ABORTED = 14, 88 HP_WMI_STATUS_SUPPORTING_ENTITY_IN_ERROR = 16, 89 90 /* Occurs combined with one of "OK", "Degraded", and "Error" [1]. */ 91 HP_WMI_STATUS_COMPLETED = 17, 92 }; 93 94 enum hp_wmi_units { 95 HP_WMI_UNITS_OTHER = 1, 96 HP_WMI_UNITS_DEGREES_C = 2, 97 HP_WMI_UNITS_DEGREES_F = 3, 98 HP_WMI_UNITS_DEGREES_K = 4, 99 HP_WMI_UNITS_VOLTS = 5, 100 HP_WMI_UNITS_AMPS = 6, 101 HP_WMI_UNITS_RPM = 19, 102 }; 103 104 enum hp_wmi_property { 105 HP_WMI_PROPERTY_NAME = 0, 106 HP_WMI_PROPERTY_DESCRIPTION = 1, 107 HP_WMI_PROPERTY_SENSOR_TYPE = 2, 108 HP_WMI_PROPERTY_OTHER_SENSOR_TYPE = 3, 109 HP_WMI_PROPERTY_OPERATIONAL_STATUS = 4, 110 HP_WMI_PROPERTY_SIZE = 5, 111 HP_WMI_PROPERTY_POSSIBLE_STATES = 6, 112 HP_WMI_PROPERTY_CURRENT_STATE = 7, 113 HP_WMI_PROPERTY_BASE_UNITS = 8, 114 HP_WMI_PROPERTY_UNIT_MODIFIER = 9, 115 HP_WMI_PROPERTY_CURRENT_READING = 10, 116 HP_WMI_PROPERTY_RATE_UNITS = 11, 117 }; 118 119 static const acpi_object_type hp_wmi_property_map[] = { 120 [HP_WMI_PROPERTY_NAME] = ACPI_TYPE_STRING, 121 [HP_WMI_PROPERTY_DESCRIPTION] = ACPI_TYPE_STRING, 122 [HP_WMI_PROPERTY_SENSOR_TYPE] = ACPI_TYPE_INTEGER, 123 [HP_WMI_PROPERTY_OTHER_SENSOR_TYPE] = ACPI_TYPE_STRING, 124 [HP_WMI_PROPERTY_OPERATIONAL_STATUS] = ACPI_TYPE_INTEGER, 125 [HP_WMI_PROPERTY_SIZE] = ACPI_TYPE_INTEGER, 126 [HP_WMI_PROPERTY_POSSIBLE_STATES] = ACPI_TYPE_STRING, 127 [HP_WMI_PROPERTY_CURRENT_STATE] = ACPI_TYPE_STRING, 128 [HP_WMI_PROPERTY_BASE_UNITS] = ACPI_TYPE_INTEGER, 129 [HP_WMI_PROPERTY_UNIT_MODIFIER] = ACPI_TYPE_INTEGER, 130 [HP_WMI_PROPERTY_CURRENT_READING] = ACPI_TYPE_INTEGER, 131 [HP_WMI_PROPERTY_RATE_UNITS] = ACPI_TYPE_INTEGER, 132 }; 133 134 enum hp_wmi_platform_events_property { 135 HP_WMI_PLATFORM_EVENTS_PROPERTY_NAME = 0, 136 HP_WMI_PLATFORM_EVENTS_PROPERTY_DESCRIPTION = 1, 137 HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_NAMESPACE = 2, 138 HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_CLASS = 3, 139 HP_WMI_PLATFORM_EVENTS_PROPERTY_CATEGORY = 4, 140 HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_SEVERITY = 5, 141 HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS = 6, 142 }; 143 144 static const acpi_object_type hp_wmi_platform_events_property_map[] = { 145 [HP_WMI_PLATFORM_EVENTS_PROPERTY_NAME] = ACPI_TYPE_STRING, 146 [HP_WMI_PLATFORM_EVENTS_PROPERTY_DESCRIPTION] = ACPI_TYPE_STRING, 147 [HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_NAMESPACE] = ACPI_TYPE_STRING, 148 [HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_CLASS] = ACPI_TYPE_STRING, 149 [HP_WMI_PLATFORM_EVENTS_PROPERTY_CATEGORY] = ACPI_TYPE_INTEGER, 150 [HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_SEVERITY] = ACPI_TYPE_INTEGER, 151 [HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS] = ACPI_TYPE_INTEGER, 152 }; 153 154 enum hp_wmi_event_property { 155 HP_WMI_EVENT_PROPERTY_NAME = 0, 156 HP_WMI_EVENT_PROPERTY_DESCRIPTION = 1, 157 HP_WMI_EVENT_PROPERTY_CATEGORY = 2, 158 HP_WMI_EVENT_PROPERTY_SEVERITY = 3, 159 HP_WMI_EVENT_PROPERTY_STATUS = 4, 160 }; 161 162 static const acpi_object_type hp_wmi_event_property_map[] = { 163 [HP_WMI_EVENT_PROPERTY_NAME] = ACPI_TYPE_STRING, 164 [HP_WMI_EVENT_PROPERTY_DESCRIPTION] = ACPI_TYPE_STRING, 165 [HP_WMI_EVENT_PROPERTY_CATEGORY] = ACPI_TYPE_INTEGER, 166 [HP_WMI_EVENT_PROPERTY_SEVERITY] = ACPI_TYPE_INTEGER, 167 [HP_WMI_EVENT_PROPERTY_STATUS] = ACPI_TYPE_INTEGER, 168 }; 169 170 static const enum hwmon_sensor_types hp_wmi_hwmon_type_map[] = { 171 [HP_WMI_TYPE_TEMPERATURE] = hwmon_temp, 172 [HP_WMI_TYPE_VOLTAGE] = hwmon_in, 173 [HP_WMI_TYPE_CURRENT] = hwmon_curr, 174 [HP_WMI_TYPE_AIR_FLOW] = hwmon_fan, 175 }; 176 177 static const u32 hp_wmi_hwmon_attributes[hwmon_max] = { 178 [hwmon_chip] = HWMON_C_REGISTER_TZ, 179 [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_FAULT, 180 [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL, 181 [hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL, 182 [hwmon_fan] = HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_FAULT, 183 [hwmon_intrusion] = HWMON_INTRUSION_ALARM, 184 }; 185 186 /* 187 * struct hp_wmi_numeric_sensor - a HPBIOS_BIOSNumericSensor instance 188 * 189 * Two variants of HPBIOS_BIOSNumericSensor are known. The first is specified 190 * in [1] and appears to be much more widespread. The second was discovered by 191 * decoding BMOF blobs [4], seems to be found only in some newer ZBook systems 192 * [3], and has two new properties and a slightly different property order. 193 * 194 * These differences don't matter on Windows, where WMI object properties are 195 * accessed by name. For us, supporting both variants gets ugly and hacky at 196 * times. The fun begins now; this struct is defined as per the new variant. 197 * 198 * Effective MOF definition: 199 * 200 * #pragma namespace("\\\\.\\root\\HP\\InstrumentedBIOS"); 201 * class HPBIOS_BIOSNumericSensor { 202 * [read] string Name; 203 * [read] string Description; 204 * [read, ValueMap {"0","1","2","3","4","5","6","7","8","9", 205 * "10","11","12"}, Values {"Unknown","Other","Temperature", 206 * "Voltage","Current","Tachometer","Counter","Switch","Lock", 207 * "Humidity","Smoke Detection","Presence","Air Flow"}] 208 * uint32 SensorType; 209 * [read] string OtherSensorType; 210 * [read, ValueMap {"0","1","2","3","4","5","6","7","8","9", 211 * "10","11","12","13","14","15","16","17","18","..", 212 * "0x8000.."}, Values {"Unknown","Other","OK","Degraded", 213 * "Stressed","Predictive Failure","Error", 214 * "Non-Recoverable Error","Starting","Stopping","Stopped", 215 * "In Service","No Contact","Lost Communication","Aborted", 216 * "Dormant","Supporting Entity in Error","Completed", 217 * "Power Mode","DMTF Reserved","Vendor Reserved"}] 218 * uint32 OperationalStatus; 219 * [read] uint32 Size; 220 * [read] string PossibleStates[]; 221 * [read] string CurrentState; 222 * [read, ValueMap {"0","1","2","3","4","5","6","7","8","9", 223 * "10","11","12","13","14","15","16","17","18","19","20", 224 * "21","22","23","24","25","26","27","28","29","30","31", 225 * "32","33","34","35","36","37","38","39","40","41","42", 226 * "43","44","45","46","47","48","49","50","51","52","53", 227 * "54","55","56","57","58","59","60","61","62","63","64", 228 * "65"}, Values {"Unknown","Other","Degrees C","Degrees F", 229 * "Degrees K","Volts","Amps","Watts","Joules","Coulombs", 230 * "VA","Nits","Lumens","Lux","Candelas","kPa","PSI", 231 * "Newtons","CFM","RPM","Hertz","Seconds","Minutes", 232 * "Hours","Days","Weeks","Mils","Inches","Feet", 233 * "Cubic Inches","Cubic Feet","Meters","Cubic Centimeters", 234 * "Cubic Meters","Liters","Fluid Ounces","Radians", 235 * "Steradians","Revolutions","Cycles","Gravities","Ounces", 236 * "Pounds","Foot-Pounds","Ounce-Inches","Gauss","Gilberts", 237 * "Henries","Farads","Ohms","Siemens","Moles","Becquerels", 238 * "PPM (parts/million)","Decibels","DbA","DbC","Grays", 239 * "Sieverts","Color Temperature Degrees K","Bits","Bytes", 240 * "Words (data)","DoubleWords","QuadWords","Percentage"}] 241 * uint32 BaseUnits; 242 * [read] sint32 UnitModifier; 243 * [read] uint32 CurrentReading; 244 * [read] uint32 RateUnits; 245 * }; 246 * 247 * Effective MOF definition of old variant [1] (sans redundant info): 248 * 249 * class HPBIOS_BIOSNumericSensor { 250 * [read] string Name; 251 * [read] string Description; 252 * [read] uint32 SensorType; 253 * [read] string OtherSensorType; 254 * [read] uint32 OperationalStatus; 255 * [read] string CurrentState; 256 * [read] string PossibleStates[]; 257 * [read] uint32 BaseUnits; 258 * [read] sint32 UnitModifier; 259 * [read] uint32 CurrentReading; 260 * }; 261 */ 262 struct hp_wmi_numeric_sensor { 263 const char *name; 264 const char *description; 265 u32 sensor_type; 266 const char *other_sensor_type; /* Explains "Other" SensorType. */ 267 u32 operational_status; 268 u8 size; /* Count of PossibleStates[]. */ 269 const char **possible_states; 270 const char *current_state; 271 u32 base_units; 272 s32 unit_modifier; 273 u32 current_reading; 274 u32 rate_units; 275 }; 276 277 /* 278 * struct hp_wmi_platform_events - a HPBIOS_PlatformEvents instance 279 * 280 * Instances of this object reveal the set of possible HPBIOS_BIOSEvent 281 * instances for the current system, but it may not always be present. 282 * 283 * Effective MOF definition: 284 * 285 * #pragma namespace("\\\\.\\root\\HP\\InstrumentedBIOS"); 286 * class HPBIOS_PlatformEvents { 287 * [read] string Name; 288 * [read] string Description; 289 * [read] string SourceNamespace; 290 * [read] string SourceClass; 291 * [read, ValueMap {"0","1","2","3","4",".."}, Values { 292 * "Unknown","Configuration Change","Button Pressed", 293 * "Sensor","BIOS Settings","Reserved"}] 294 * uint32 Category; 295 * [read, ValueMap{"0","5","10","15","20","25","30",".."}, 296 * Values{"Unknown","OK","Degraded/Warning","Minor Failure", 297 * "Major Failure","Critical Failure","Non-recoverable Error", 298 * "DMTF Reserved"}] 299 * uint32 PossibleSeverity; 300 * [read, ValueMap {"0","1","2","3","4","5","6","7","8","9", 301 * "10","11","12","13","14","15","16","17","18","..", 302 * "0x8000.."}, Values {"Unknown","Other","OK","Degraded", 303 * "Stressed","Predictive Failure","Error", 304 * "Non-Recoverable Error","Starting","Stopping","Stopped", 305 * "In Service","No Contact","Lost Communication","Aborted", 306 * "Dormant","Supporting Entity in Error","Completed", 307 * "Power Mode","DMTF Reserved","Vendor Reserved"}] 308 * uint32 PossibleStatus; 309 * }; 310 */ 311 struct hp_wmi_platform_events { 312 const char *name; 313 const char *description; 314 const char *source_namespace; 315 const char *source_class; 316 u32 category; 317 u32 possible_severity; 318 u32 possible_status; 319 }; 320 321 /* 322 * struct hp_wmi_event - a HPBIOS_BIOSEvent instance 323 * 324 * Effective MOF definition [1] (corrected below from original): 325 * 326 * #pragma namespace("\\\\.\\root\\WMI"); 327 * class HPBIOS_BIOSEvent : WMIEvent { 328 * [read] string Name; 329 * [read] string Description; 330 * [read ValueMap {"0","1","2","3","4"}, Values {"Unknown", 331 * "Configuration Change","Button Pressed","Sensor", 332 * "BIOS Settings"}] 333 * uint32 Category; 334 * [read, ValueMap {"0","5","10","15","20","25","30"}, 335 * Values {"Unknown","OK","Degraded/Warning", 336 * "Minor Failure","Major Failure","Critical Failure", 337 * "Non-recoverable Error"}] 338 * uint32 Severity; 339 * [read, ValueMap {"0","1","2","3","4","5","6","7","8", 340 * "9","10","11","12","13","14","15","16","17","18","..", 341 * "0x8000.."}, Values {"Unknown","Other","OK","Degraded", 342 * "Stressed","Predictive Failure","Error", 343 * "Non-Recoverable Error","Starting","Stopping","Stopped", 344 * "In Service","No Contact","Lost Communication","Aborted", 345 * "Dormant","Supporting Entity in Error","Completed", 346 * "Power Mode","DMTF Reserved","Vendor Reserved"}] 347 * uint32 Status; 348 * }; 349 */ 350 struct hp_wmi_event { 351 const char *name; 352 const char *description; 353 u32 category; 354 }; 355 356 /* 357 * struct hp_wmi_info - sensor info 358 * @nsensor: numeric sensor properties 359 * @instance: its WMI instance number 360 * @state: pointer to driver state 361 * @has_alarm: whether sensor has an alarm flag 362 * @alarm: alarm flag 363 * @type: its hwmon sensor type 364 * @cached_val: current sensor reading value, scaled for hwmon 365 * @last_updated: when these readings were last updated 366 */ 367 struct hp_wmi_info { 368 struct hp_wmi_numeric_sensor nsensor; 369 u8 instance; 370 void *state; /* void *: Avoid forward declaration. */ 371 bool has_alarm; 372 bool alarm; 373 enum hwmon_sensor_types type; 374 long cached_val; 375 unsigned long last_updated; /* In jiffies. */ 376 377 }; 378 379 /* 380 * struct hp_wmi_sensors - driver state 381 * @wdev: pointer to the parent WMI device 382 * @info_map: sensor info structs by hwmon type and channel number 383 * @channel_count: count of hwmon channels by hwmon type 384 * @has_intrusion: whether an intrusion sensor is present 385 * @intrusion: intrusion flag 386 * @lock: mutex to lock polling WMI and changes to driver state 387 */ 388 struct hp_wmi_sensors { 389 struct wmi_device *wdev; 390 struct hp_wmi_info **info_map[hwmon_max]; 391 u8 channel_count[hwmon_max]; 392 bool has_intrusion; 393 bool intrusion; 394 395 struct mutex lock; /* Lock polling WMI and driver state changes. */ 396 }; 397 398 /* hp_wmi_strdup - devm_kstrdup, but length-limited */ 399 static char *hp_wmi_strdup(struct device *dev, const char *src) 400 { 401 char *dst; 402 size_t len; 403 404 len = strnlen(src, HP_WMI_MAX_STR_SIZE - 1); 405 406 dst = devm_kmalloc(dev, (len + 1) * sizeof(*dst), GFP_KERNEL); 407 if (!dst) 408 return NULL; 409 410 strscpy(dst, src, len + 1); 411 412 return dst; 413 } 414 415 /* 416 * hp_wmi_get_wobj - poll WMI for a WMI object instance 417 * @guid: WMI object GUID 418 * @instance: WMI object instance number 419 * 420 * Returns a new WMI object instance on success, or NULL on error. 421 * Caller must kfree() the result. 422 */ 423 static union acpi_object *hp_wmi_get_wobj(const char *guid, u8 instance) 424 { 425 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 426 acpi_status err; 427 428 err = wmi_query_block(guid, instance, &out); 429 if (ACPI_FAILURE(err)) 430 return NULL; 431 432 return out.pointer; 433 } 434 435 /* hp_wmi_wobj_instance_count - find count of WMI object instances */ 436 static u8 hp_wmi_wobj_instance_count(const char *guid) 437 { 438 u8 hi = HP_WMI_MAX_INSTANCES; 439 union acpi_object *wobj; 440 u8 lo = 0; 441 u8 mid; 442 443 while (lo < hi) { 444 mid = (lo + hi) / 2; 445 446 wobj = hp_wmi_get_wobj(guid, mid); 447 if (!wobj) { 448 hi = mid; 449 continue; 450 } 451 452 lo = mid + 1; 453 kfree(wobj); 454 } 455 456 return lo; 457 } 458 459 static int check_wobj(const union acpi_object *wobj, 460 const acpi_object_type property_map[], int last_prop) 461 { 462 acpi_object_type type = wobj->type; 463 acpi_object_type valid_type; 464 union acpi_object *elements; 465 u32 elem_count; 466 int prop; 467 468 if (type != ACPI_TYPE_PACKAGE) 469 return -EINVAL; 470 471 elem_count = wobj->package.count; 472 if (elem_count != last_prop + 1) 473 return -EINVAL; 474 475 elements = wobj->package.elements; 476 for (prop = 0; prop <= last_prop; prop++) { 477 type = elements[prop].type; 478 valid_type = property_map[prop]; 479 if (type != valid_type) 480 return -EINVAL; 481 } 482 483 return 0; 484 } 485 486 static int extract_acpi_value(struct device *dev, 487 union acpi_object *element, 488 acpi_object_type type, 489 u32 *out_value, char **out_string) 490 { 491 switch (type) { 492 case ACPI_TYPE_INTEGER: 493 *out_value = element->integer.value; 494 break; 495 496 case ACPI_TYPE_STRING: 497 *out_string = hp_wmi_strdup(dev, strim(element->string.pointer)); 498 if (!*out_string) 499 return -ENOMEM; 500 break; 501 502 default: 503 return -EINVAL; 504 } 505 506 return 0; 507 } 508 509 /* 510 * check_numeric_sensor_wobj - validate a HPBIOS_BIOSNumericSensor instance 511 * @wobj: pointer to WMI object instance to check 512 * @out_size: out pointer to count of possible states 513 * @out_is_new: out pointer to whether this is a "new" variant object 514 * 515 * Returns 0 on success, or a negative error code on error. 516 */ 517 static int check_numeric_sensor_wobj(const union acpi_object *wobj, 518 u8 *out_size, bool *out_is_new) 519 { 520 acpi_object_type type = wobj->type; 521 int prop = HP_WMI_PROPERTY_NAME; 522 acpi_object_type valid_type; 523 union acpi_object *elements; 524 u32 elem_count; 525 int last_prop; 526 bool is_new; 527 u8 count; 528 u32 j; 529 u32 i; 530 531 if (type != ACPI_TYPE_PACKAGE) 532 return -EINVAL; 533 534 /* 535 * elements is a variable-length array of ACPI objects, one for 536 * each property of the WMI object instance, except that the 537 * strings in PossibleStates[] are flattened into this array 538 * as if each individual string were a property by itself. 539 */ 540 elements = wobj->package.elements; 541 542 elem_count = wobj->package.count; 543 if (elem_count <= HP_WMI_PROPERTY_SIZE || 544 elem_count > HP_WMI_MAX_PROPERTIES) 545 return -EINVAL; 546 547 type = elements[HP_WMI_PROPERTY_SIZE].type; 548 switch (type) { 549 case ACPI_TYPE_INTEGER: 550 is_new = true; 551 last_prop = HP_WMI_PROPERTY_RATE_UNITS; 552 break; 553 554 case ACPI_TYPE_STRING: 555 is_new = false; 556 last_prop = HP_WMI_PROPERTY_CURRENT_READING; 557 break; 558 559 default: 560 return -EINVAL; 561 } 562 563 /* 564 * In general, the count of PossibleStates[] must be > 0. 565 * Also, the old variant lacks the Size property, so we may need to 566 * reduce the value of last_prop by 1 when doing arithmetic with it. 567 */ 568 if (elem_count < last_prop - !is_new + 1) 569 return -EINVAL; 570 571 count = elem_count - (last_prop - !is_new); 572 573 for (i = 0; i < elem_count && prop <= last_prop; i++, prop++) { 574 type = elements[i].type; 575 valid_type = hp_wmi_property_map[prop]; 576 if (type != valid_type) 577 return -EINVAL; 578 579 switch (prop) { 580 case HP_WMI_PROPERTY_OPERATIONAL_STATUS: 581 /* Old variant: CurrentState follows OperationalStatus. */ 582 if (!is_new) 583 prop = HP_WMI_PROPERTY_CURRENT_STATE - 1; 584 break; 585 586 case HP_WMI_PROPERTY_SIZE: 587 /* New variant: Size == count of PossibleStates[]. */ 588 if (count != elements[i].integer.value) 589 return -EINVAL; 590 break; 591 592 case HP_WMI_PROPERTY_POSSIBLE_STATES: 593 /* PossibleStates[0] has already been type-checked. */ 594 for (j = 0; i + 1 < elem_count && j + 1 < count; j++) { 595 type = elements[++i].type; 596 if (type != valid_type) 597 return -EINVAL; 598 } 599 600 /* Old variant: BaseUnits follows PossibleStates[]. */ 601 if (!is_new) 602 prop = HP_WMI_PROPERTY_BASE_UNITS - 1; 603 break; 604 605 case HP_WMI_PROPERTY_CURRENT_STATE: 606 /* Old variant: PossibleStates[] follows CurrentState. */ 607 if (!is_new) 608 prop = HP_WMI_PROPERTY_POSSIBLE_STATES - 1; 609 break; 610 } 611 } 612 613 if (prop != last_prop + 1) 614 return -EINVAL; 615 616 *out_size = count; 617 *out_is_new = is_new; 618 619 return 0; 620 } 621 622 static int 623 numeric_sensor_is_connected(const struct hp_wmi_numeric_sensor *nsensor) 624 { 625 u32 operational_status = nsensor->operational_status; 626 627 return operational_status != HP_WMI_STATUS_NO_CONTACT; 628 } 629 630 static int numeric_sensor_has_fault(const struct hp_wmi_numeric_sensor *nsensor) 631 { 632 u32 operational_status = nsensor->operational_status; 633 634 switch (operational_status) { 635 case HP_WMI_STATUS_DEGRADED: 636 case HP_WMI_STATUS_STRESSED: /* e.g. Overload, overtemp. */ 637 case HP_WMI_STATUS_PREDICTIVE_FAILURE: /* e.g. Fan removed. */ 638 case HP_WMI_STATUS_ERROR: 639 case HP_WMI_STATUS_NON_RECOVERABLE_ERROR: 640 case HP_WMI_STATUS_NO_CONTACT: 641 case HP_WMI_STATUS_LOST_COMMUNICATION: 642 case HP_WMI_STATUS_ABORTED: 643 case HP_WMI_STATUS_SUPPORTING_ENTITY_IN_ERROR: 644 645 /* Assume combination by addition; bitwise OR doesn't make sense. */ 646 case HP_WMI_STATUS_COMPLETED + HP_WMI_STATUS_DEGRADED: 647 case HP_WMI_STATUS_COMPLETED + HP_WMI_STATUS_ERROR: 648 return true; 649 } 650 651 return false; 652 } 653 654 /* scale_numeric_sensor - scale sensor reading for hwmon */ 655 static long scale_numeric_sensor(const struct hp_wmi_numeric_sensor *nsensor) 656 { 657 u32 current_reading = nsensor->current_reading; 658 s32 unit_modifier = nsensor->unit_modifier; 659 u32 sensor_type = nsensor->sensor_type; 660 u32 base_units = nsensor->base_units; 661 s32 target_modifier; 662 long val; 663 664 /* Fan readings are in RPM units; others are in milliunits. */ 665 target_modifier = sensor_type == HP_WMI_TYPE_AIR_FLOW ? 0 : -3; 666 667 val = current_reading; 668 669 for (; unit_modifier < target_modifier; unit_modifier++) 670 val = DIV_ROUND_CLOSEST(val, 10); 671 672 for (; unit_modifier > target_modifier; unit_modifier--) { 673 if (val > LONG_MAX / 10) { 674 val = LONG_MAX; 675 break; 676 } 677 val *= 10; 678 } 679 680 if (sensor_type == HP_WMI_TYPE_TEMPERATURE) { 681 switch (base_units) { 682 case HP_WMI_UNITS_DEGREES_F: 683 val -= MILLI * 32; 684 val = val <= LONG_MAX / 5 ? 685 DIV_ROUND_CLOSEST(val * 5, 9) : 686 DIV_ROUND_CLOSEST(val, 9) * 5; 687 break; 688 689 case HP_WMI_UNITS_DEGREES_K: 690 val = milli_kelvin_to_millicelsius(val); 691 break; 692 } 693 } 694 695 return val; 696 } 697 698 /* 699 * classify_numeric_sensor - classify a numeric sensor 700 * @nsensor: pointer to numeric sensor struct 701 * 702 * Returns an enum hp_wmi_type value on success, 703 * or a negative value if the sensor type is unsupported. 704 */ 705 static int classify_numeric_sensor(const struct hp_wmi_numeric_sensor *nsensor) 706 { 707 u32 sensor_type = nsensor->sensor_type; 708 u32 base_units = nsensor->base_units; 709 const char *name = nsensor->name; 710 711 switch (sensor_type) { 712 case HP_WMI_TYPE_TEMPERATURE: 713 /* 714 * Some systems have sensors named "X Thermal Index" in "Other" 715 * units. Tested CPU sensor examples were found to be in °C, 716 * albeit perhaps "differently" accurate; e.g. readings were 717 * reliably -6°C vs. coretemp on a HP Compaq Elite 8300, and 718 * +8°C on an EliteOne G1 800. But this is still within the 719 * realm of plausibility for cheaply implemented motherboard 720 * sensors, and chassis readings were about as expected. 721 */ 722 if ((base_units == HP_WMI_UNITS_OTHER && 723 strstr(name, HP_WMI_PATTERN_TEMP_SENSOR)) || 724 base_units == HP_WMI_UNITS_DEGREES_C || 725 base_units == HP_WMI_UNITS_DEGREES_F || 726 base_units == HP_WMI_UNITS_DEGREES_K) 727 return HP_WMI_TYPE_TEMPERATURE; 728 break; 729 730 case HP_WMI_TYPE_VOLTAGE: 731 if (base_units == HP_WMI_UNITS_VOLTS) 732 return HP_WMI_TYPE_VOLTAGE; 733 break; 734 735 case HP_WMI_TYPE_CURRENT: 736 if (base_units == HP_WMI_UNITS_AMPS) 737 return HP_WMI_TYPE_CURRENT; 738 break; 739 740 case HP_WMI_TYPE_AIR_FLOW: 741 /* 742 * Strangely, HP considers fan RPM sensor type to be 743 * "Air Flow" instead of the more intuitive "Tachometer". 744 */ 745 if (base_units == HP_WMI_UNITS_RPM) 746 return HP_WMI_TYPE_AIR_FLOW; 747 break; 748 } 749 750 return -EINVAL; 751 } 752 753 static int 754 populate_numeric_sensor_from_wobj(struct device *dev, 755 struct hp_wmi_numeric_sensor *nsensor, 756 union acpi_object *wobj, bool *out_is_new) 757 { 758 int last_prop = HP_WMI_PROPERTY_RATE_UNITS; 759 int prop = HP_WMI_PROPERTY_NAME; 760 const char **possible_states; 761 union acpi_object *element; 762 acpi_object_type type; 763 char *string; 764 bool is_new; 765 u32 value; 766 u8 size; 767 int err; 768 769 err = check_numeric_sensor_wobj(wobj, &size, &is_new); 770 if (err) 771 return err; 772 773 possible_states = devm_kcalloc(dev, size, sizeof(*possible_states), 774 GFP_KERNEL); 775 if (!possible_states) 776 return -ENOMEM; 777 778 element = wobj->package.elements; 779 nsensor->possible_states = possible_states; 780 nsensor->size = size; 781 782 if (!is_new) 783 last_prop = HP_WMI_PROPERTY_CURRENT_READING; 784 785 for (; prop <= last_prop; prop++) { 786 type = hp_wmi_property_map[prop]; 787 788 err = extract_acpi_value(dev, element, type, &value, &string); 789 if (err) 790 return err; 791 792 element++; 793 794 switch (prop) { 795 case HP_WMI_PROPERTY_NAME: 796 nsensor->name = string; 797 break; 798 799 case HP_WMI_PROPERTY_DESCRIPTION: 800 nsensor->description = string; 801 break; 802 803 case HP_WMI_PROPERTY_SENSOR_TYPE: 804 if (value > HP_WMI_TYPE_AIR_FLOW) 805 return -EINVAL; 806 807 nsensor->sensor_type = value; 808 break; 809 810 case HP_WMI_PROPERTY_OTHER_SENSOR_TYPE: 811 nsensor->other_sensor_type = string; 812 break; 813 814 case HP_WMI_PROPERTY_OPERATIONAL_STATUS: 815 nsensor->operational_status = value; 816 817 /* Old variant: CurrentState follows OperationalStatus. */ 818 if (!is_new) 819 prop = HP_WMI_PROPERTY_CURRENT_STATE - 1; 820 break; 821 822 case HP_WMI_PROPERTY_SIZE: 823 break; /* Already set. */ 824 825 case HP_WMI_PROPERTY_POSSIBLE_STATES: 826 *possible_states++ = string; 827 if (--size) 828 prop--; 829 830 /* Old variant: BaseUnits follows PossibleStates[]. */ 831 if (!is_new && !size) 832 prop = HP_WMI_PROPERTY_BASE_UNITS - 1; 833 break; 834 835 case HP_WMI_PROPERTY_CURRENT_STATE: 836 nsensor->current_state = string; 837 838 /* Old variant: PossibleStates[] follows CurrentState. */ 839 if (!is_new) 840 prop = HP_WMI_PROPERTY_POSSIBLE_STATES - 1; 841 break; 842 843 case HP_WMI_PROPERTY_BASE_UNITS: 844 nsensor->base_units = value; 845 break; 846 847 case HP_WMI_PROPERTY_UNIT_MODIFIER: 848 /* UnitModifier is signed. */ 849 nsensor->unit_modifier = (s32)value; 850 break; 851 852 case HP_WMI_PROPERTY_CURRENT_READING: 853 nsensor->current_reading = value; 854 break; 855 856 case HP_WMI_PROPERTY_RATE_UNITS: 857 nsensor->rate_units = value; 858 break; 859 860 default: 861 return -EINVAL; 862 } 863 } 864 865 *out_is_new = is_new; 866 867 return 0; 868 } 869 870 /* update_numeric_sensor_from_wobj - update fungible sensor properties */ 871 static void 872 update_numeric_sensor_from_wobj(struct device *dev, 873 struct hp_wmi_numeric_sensor *nsensor, 874 const union acpi_object *wobj) 875 { 876 const union acpi_object *elements; 877 const union acpi_object *element; 878 const char *string; 879 bool is_new; 880 int offset; 881 u8 size; 882 int err; 883 884 err = check_numeric_sensor_wobj(wobj, &size, &is_new); 885 if (err) 886 return; 887 888 elements = wobj->package.elements; 889 890 element = &elements[HP_WMI_PROPERTY_OPERATIONAL_STATUS]; 891 nsensor->operational_status = element->integer.value; 892 893 /* 894 * In general, an index offset is needed after PossibleStates[0]. 895 * On a new variant, CurrentState is after PossibleStates[]. This is 896 * not the case on an old variant, but we still need to offset the 897 * read because CurrentState is where Size would be on a new variant. 898 */ 899 offset = is_new ? size - 1 : -2; 900 901 element = &elements[HP_WMI_PROPERTY_CURRENT_STATE + offset]; 902 string = strim(element->string.pointer); 903 904 if (strcmp(string, nsensor->current_state)) { 905 devm_kfree(dev, nsensor->current_state); 906 nsensor->current_state = hp_wmi_strdup(dev, string); 907 } 908 909 /* Old variant: -2 (not -1) because it lacks the Size property. */ 910 if (!is_new) 911 offset = (int)size - 2; /* size is > 0, i.e. may be 1. */ 912 913 element = &elements[HP_WMI_PROPERTY_UNIT_MODIFIER + offset]; 914 nsensor->unit_modifier = (s32)element->integer.value; 915 916 element = &elements[HP_WMI_PROPERTY_CURRENT_READING + offset]; 917 nsensor->current_reading = element->integer.value; 918 } 919 920 /* 921 * check_platform_events_wobj - validate a HPBIOS_PlatformEvents instance 922 * @wobj: pointer to WMI object instance to check 923 * 924 * Returns 0 on success, or a negative error code on error. 925 */ 926 static int check_platform_events_wobj(const union acpi_object *wobj) 927 { 928 return check_wobj(wobj, hp_wmi_platform_events_property_map, 929 HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS); 930 } 931 932 static int 933 populate_platform_events_from_wobj(struct device *dev, 934 struct hp_wmi_platform_events *pevents, 935 union acpi_object *wobj) 936 { 937 int last_prop = HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS; 938 int prop = HP_WMI_PLATFORM_EVENTS_PROPERTY_NAME; 939 union acpi_object *element; 940 acpi_object_type type; 941 char *string; 942 u32 value; 943 int err; 944 945 err = check_platform_events_wobj(wobj); 946 if (err) 947 return err; 948 949 element = wobj->package.elements; 950 951 for (; prop <= last_prop; prop++, element++) { 952 type = hp_wmi_platform_events_property_map[prop]; 953 954 err = extract_acpi_value(dev, element, type, &value, &string); 955 if (err) 956 return err; 957 958 switch (prop) { 959 case HP_WMI_PLATFORM_EVENTS_PROPERTY_NAME: 960 pevents->name = string; 961 break; 962 963 case HP_WMI_PLATFORM_EVENTS_PROPERTY_DESCRIPTION: 964 pevents->description = string; 965 break; 966 967 case HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_NAMESPACE: 968 if (strcasecmp(HP_WMI_EVENT_NAMESPACE, string)) 969 return -EINVAL; 970 971 pevents->source_namespace = string; 972 break; 973 974 case HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_CLASS: 975 if (strcasecmp(HP_WMI_EVENT_CLASS, string)) 976 return -EINVAL; 977 978 pevents->source_class = string; 979 break; 980 981 case HP_WMI_PLATFORM_EVENTS_PROPERTY_CATEGORY: 982 pevents->category = value; 983 break; 984 985 case HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_SEVERITY: 986 pevents->possible_severity = value; 987 break; 988 989 case HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS: 990 pevents->possible_status = value; 991 break; 992 993 default: 994 return -EINVAL; 995 } 996 } 997 998 return 0; 999 } 1000 1001 /* 1002 * check_event_wobj - validate a HPBIOS_BIOSEvent instance 1003 * @wobj: pointer to WMI object instance to check 1004 * 1005 * Returns 0 on success, or a negative error code on error. 1006 */ 1007 static int check_event_wobj(const union acpi_object *wobj) 1008 { 1009 return check_wobj(wobj, hp_wmi_event_property_map, 1010 HP_WMI_EVENT_PROPERTY_STATUS); 1011 } 1012 1013 static int populate_event_from_wobj(struct hp_wmi_event *event, 1014 union acpi_object *wobj) 1015 { 1016 int prop = HP_WMI_EVENT_PROPERTY_NAME; 1017 union acpi_object *element; 1018 int err; 1019 1020 err = check_event_wobj(wobj); 1021 if (err) 1022 return err; 1023 1024 element = wobj->package.elements; 1025 1026 /* Extracted strings are NOT device-managed copies. */ 1027 1028 for (; prop <= HP_WMI_EVENT_PROPERTY_CATEGORY; prop++, element++) { 1029 switch (prop) { 1030 case HP_WMI_EVENT_PROPERTY_NAME: 1031 event->name = strim(element->string.pointer); 1032 break; 1033 1034 case HP_WMI_EVENT_PROPERTY_DESCRIPTION: 1035 event->description = strim(element->string.pointer); 1036 break; 1037 1038 case HP_WMI_EVENT_PROPERTY_CATEGORY: 1039 event->category = element->integer.value; 1040 break; 1041 1042 default: 1043 return -EINVAL; 1044 } 1045 } 1046 1047 return 0; 1048 } 1049 1050 /* 1051 * classify_event - classify an event 1052 * @name: event name 1053 * @category: event category 1054 * 1055 * Classify instances of both HPBIOS_PlatformEvents and HPBIOS_BIOSEvent from 1056 * property values. Recognition criteria are based on multiple ACPI dumps [3]. 1057 * 1058 * Returns an enum hp_wmi_type value on success, 1059 * or a negative value if the event type is unsupported. 1060 */ 1061 static int classify_event(const char *event_name, u32 category) 1062 { 1063 if (category != HP_WMI_CATEGORY_SENSOR) 1064 return -EINVAL; 1065 1066 /* Fan events have Name "X Stall". */ 1067 if (strstr(event_name, HP_WMI_PATTERN_FAN_ALARM)) 1068 return HP_WMI_TYPE_AIR_FLOW; 1069 1070 /* Intrusion events have Name "Hood Intrusion". */ 1071 if (!strcmp(event_name, HP_WMI_PATTERN_INTRUSION_ALARM)) 1072 return HP_WMI_TYPE_INTRUSION; 1073 1074 /* 1075 * Temperature events have Name either "Thermal Caution" or 1076 * "Thermal Critical". Deal only with "Thermal Critical" events. 1077 * 1078 * "Thermal Caution" events have Status "Stressed", informing us that 1079 * the OperationalStatus of the related sensor has become "Stressed". 1080 * However, this is already a fault condition that will clear itself 1081 * when the sensor recovers, so we have no further interest in them. 1082 */ 1083 if (!strcmp(event_name, HP_WMI_PATTERN_TEMP_ALARM)) 1084 return HP_WMI_TYPE_TEMPERATURE; 1085 1086 return -EINVAL; 1087 } 1088 1089 /* 1090 * interpret_info - interpret sensor for hwmon 1091 * @info: pointer to sensor info struct 1092 * 1093 * Should be called after the numeric sensor member has been updated. 1094 */ 1095 static void interpret_info(struct hp_wmi_info *info) 1096 { 1097 const struct hp_wmi_numeric_sensor *nsensor = &info->nsensor; 1098 1099 info->cached_val = scale_numeric_sensor(nsensor); 1100 info->last_updated = jiffies; 1101 } 1102 1103 /* 1104 * hp_wmi_update_info - poll WMI to update sensor info 1105 * @state: pointer to driver state 1106 * @info: pointer to sensor info struct 1107 * 1108 * Returns 0 on success, or a negative error code on error. 1109 */ 1110 static int hp_wmi_update_info(struct hp_wmi_sensors *state, 1111 struct hp_wmi_info *info) 1112 { 1113 struct hp_wmi_numeric_sensor *nsensor = &info->nsensor; 1114 struct device *dev = &state->wdev->dev; 1115 const union acpi_object *wobj; 1116 u8 instance = info->instance; 1117 int ret = 0; 1118 1119 if (time_after(jiffies, info->last_updated + HZ)) { 1120 mutex_lock(&state->lock); 1121 1122 wobj = hp_wmi_get_wobj(HP_WMI_NUMERIC_SENSOR_GUID, instance); 1123 if (!wobj) { 1124 ret = -EIO; 1125 goto out_unlock; 1126 } 1127 1128 update_numeric_sensor_from_wobj(dev, nsensor, wobj); 1129 1130 interpret_info(info); 1131 1132 kfree(wobj); 1133 1134 out_unlock: 1135 mutex_unlock(&state->lock); 1136 } 1137 1138 return ret; 1139 } 1140 1141 static int basic_string_show(struct seq_file *seqf, void *ignored) 1142 { 1143 const char *str = seqf->private; 1144 1145 seq_printf(seqf, "%s\n", str); 1146 1147 return 0; 1148 } 1149 DEFINE_SHOW_ATTRIBUTE(basic_string); 1150 1151 static int fungible_show(struct seq_file *seqf, enum hp_wmi_property prop) 1152 { 1153 struct hp_wmi_numeric_sensor *nsensor; 1154 struct hp_wmi_sensors *state; 1155 struct hp_wmi_info *info; 1156 int err; 1157 1158 info = seqf->private; 1159 state = info->state; 1160 nsensor = &info->nsensor; 1161 1162 err = hp_wmi_update_info(state, info); 1163 if (err) 1164 return err; 1165 1166 switch (prop) { 1167 case HP_WMI_PROPERTY_OPERATIONAL_STATUS: 1168 seq_printf(seqf, "%u\n", nsensor->operational_status); 1169 break; 1170 1171 case HP_WMI_PROPERTY_CURRENT_STATE: 1172 seq_printf(seqf, "%s\n", nsensor->current_state); 1173 break; 1174 1175 case HP_WMI_PROPERTY_UNIT_MODIFIER: 1176 seq_printf(seqf, "%d\n", nsensor->unit_modifier); 1177 break; 1178 1179 case HP_WMI_PROPERTY_CURRENT_READING: 1180 seq_printf(seqf, "%u\n", nsensor->current_reading); 1181 break; 1182 1183 default: 1184 return -EOPNOTSUPP; 1185 } 1186 1187 return 0; 1188 } 1189 1190 static int operational_status_show(struct seq_file *seqf, void *ignored) 1191 { 1192 return fungible_show(seqf, HP_WMI_PROPERTY_OPERATIONAL_STATUS); 1193 } 1194 DEFINE_SHOW_ATTRIBUTE(operational_status); 1195 1196 static int current_state_show(struct seq_file *seqf, void *ignored) 1197 { 1198 return fungible_show(seqf, HP_WMI_PROPERTY_CURRENT_STATE); 1199 } 1200 DEFINE_SHOW_ATTRIBUTE(current_state); 1201 1202 static int possible_states_show(struct seq_file *seqf, void *ignored) 1203 { 1204 struct hp_wmi_numeric_sensor *nsensor = seqf->private; 1205 u8 i; 1206 1207 for (i = 0; i < nsensor->size; i++) 1208 seq_printf(seqf, "%s%s", i ? "," : "", 1209 nsensor->possible_states[i]); 1210 1211 seq_puts(seqf, "\n"); 1212 1213 return 0; 1214 } 1215 DEFINE_SHOW_ATTRIBUTE(possible_states); 1216 1217 static int unit_modifier_show(struct seq_file *seqf, void *ignored) 1218 { 1219 return fungible_show(seqf, HP_WMI_PROPERTY_UNIT_MODIFIER); 1220 } 1221 DEFINE_SHOW_ATTRIBUTE(unit_modifier); 1222 1223 static int current_reading_show(struct seq_file *seqf, void *ignored) 1224 { 1225 return fungible_show(seqf, HP_WMI_PROPERTY_CURRENT_READING); 1226 } 1227 DEFINE_SHOW_ATTRIBUTE(current_reading); 1228 1229 /* hp_wmi_devm_debugfs_remove - devm callback for debugfs cleanup */ 1230 static void hp_wmi_devm_debugfs_remove(void *res) 1231 { 1232 debugfs_remove_recursive(res); 1233 } 1234 1235 /* hp_wmi_debugfs_init - create and populate debugfs directory tree */ 1236 static void hp_wmi_debugfs_init(struct device *dev, struct hp_wmi_info *info, 1237 struct hp_wmi_platform_events *pevents, 1238 u8 icount, u8 pcount, bool is_new) 1239 { 1240 struct hp_wmi_numeric_sensor *nsensor; 1241 char buf[HP_WMI_MAX_STR_SIZE]; 1242 struct dentry *debugfs; 1243 struct dentry *entries; 1244 struct dentry *dir; 1245 int err; 1246 u8 i; 1247 1248 /* dev_name() gives a not-very-friendly GUID for WMI devices. */ 1249 scnprintf(buf, sizeof(buf), "hp-wmi-sensors-%u", dev->id); 1250 1251 debugfs = debugfs_create_dir(buf, NULL); 1252 if (IS_ERR(debugfs)) 1253 return; 1254 1255 err = devm_add_action_or_reset(dev, hp_wmi_devm_debugfs_remove, 1256 debugfs); 1257 if (err) 1258 return; 1259 1260 entries = debugfs_create_dir("sensor", debugfs); 1261 1262 for (i = 0; i < icount; i++, info++) { 1263 nsensor = &info->nsensor; 1264 1265 scnprintf(buf, sizeof(buf), "%u", i); 1266 dir = debugfs_create_dir(buf, entries); 1267 1268 debugfs_create_file("name", 0444, dir, 1269 (void *)nsensor->name, 1270 &basic_string_fops); 1271 1272 debugfs_create_file("description", 0444, dir, 1273 (void *)nsensor->description, 1274 &basic_string_fops); 1275 1276 debugfs_create_u32("sensor_type", 0444, dir, 1277 &nsensor->sensor_type); 1278 1279 debugfs_create_file("other_sensor_type", 0444, dir, 1280 (void *)nsensor->other_sensor_type, 1281 &basic_string_fops); 1282 1283 debugfs_create_file("operational_status", 0444, dir, 1284 info, &operational_status_fops); 1285 1286 debugfs_create_file("possible_states", 0444, dir, 1287 nsensor, &possible_states_fops); 1288 1289 debugfs_create_file("current_state", 0444, dir, 1290 info, ¤t_state_fops); 1291 1292 debugfs_create_u32("base_units", 0444, dir, 1293 &nsensor->base_units); 1294 1295 debugfs_create_file("unit_modifier", 0444, dir, 1296 info, &unit_modifier_fops); 1297 1298 debugfs_create_file("current_reading", 0444, dir, 1299 info, ¤t_reading_fops); 1300 1301 if (is_new) 1302 debugfs_create_u32("rate_units", 0444, dir, 1303 &nsensor->rate_units); 1304 } 1305 1306 if (!pcount) 1307 return; 1308 1309 entries = debugfs_create_dir("platform_events", debugfs); 1310 1311 for (i = 0; i < pcount; i++, pevents++) { 1312 scnprintf(buf, sizeof(buf), "%u", i); 1313 dir = debugfs_create_dir(buf, entries); 1314 1315 debugfs_create_file("name", 0444, dir, 1316 (void *)pevents->name, 1317 &basic_string_fops); 1318 1319 debugfs_create_file("description", 0444, dir, 1320 (void *)pevents->description, 1321 &basic_string_fops); 1322 1323 debugfs_create_file("source_namespace", 0444, dir, 1324 (void *)pevents->source_namespace, 1325 &basic_string_fops); 1326 1327 debugfs_create_file("source_class", 0444, dir, 1328 (void *)pevents->source_class, 1329 &basic_string_fops); 1330 1331 debugfs_create_u32("category", 0444, dir, 1332 &pevents->category); 1333 1334 debugfs_create_u32("possible_severity", 0444, dir, 1335 &pevents->possible_severity); 1336 1337 debugfs_create_u32("possible_status", 0444, dir, 1338 &pevents->possible_status); 1339 } 1340 } 1341 1342 static umode_t hp_wmi_hwmon_is_visible(const void *drvdata, 1343 enum hwmon_sensor_types type, 1344 u32 attr, int channel) 1345 { 1346 const struct hp_wmi_sensors *state = drvdata; 1347 const struct hp_wmi_info *info; 1348 1349 if (type == hwmon_intrusion) 1350 return state->has_intrusion ? 0644 : 0; 1351 1352 if (!state->info_map[type] || !state->info_map[type][channel]) 1353 return 0; 1354 1355 info = state->info_map[type][channel]; 1356 1357 if ((type == hwmon_temp && attr == hwmon_temp_alarm) || 1358 (type == hwmon_fan && attr == hwmon_fan_alarm)) 1359 return info->has_alarm ? 0444 : 0; 1360 1361 return 0444; 1362 } 1363 1364 static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 1365 u32 attr, int channel, long *out_val) 1366 { 1367 struct hp_wmi_sensors *state = dev_get_drvdata(dev); 1368 const struct hp_wmi_numeric_sensor *nsensor; 1369 struct hp_wmi_info *info; 1370 int err; 1371 1372 if (type == hwmon_intrusion) { 1373 *out_val = state->intrusion ? 1 : 0; 1374 1375 return 0; 1376 } 1377 1378 info = state->info_map[type][channel]; 1379 1380 if ((type == hwmon_temp && attr == hwmon_temp_alarm) || 1381 (type == hwmon_fan && attr == hwmon_fan_alarm)) { 1382 *out_val = info->alarm ? 1 : 0; 1383 info->alarm = false; 1384 1385 return 0; 1386 } 1387 1388 nsensor = &info->nsensor; 1389 1390 err = hp_wmi_update_info(state, info); 1391 if (err) 1392 return err; 1393 1394 if ((type == hwmon_temp && attr == hwmon_temp_fault) || 1395 (type == hwmon_fan && attr == hwmon_fan_fault)) 1396 *out_val = numeric_sensor_has_fault(nsensor); 1397 else 1398 *out_val = info->cached_val; 1399 1400 return 0; 1401 } 1402 1403 static int hp_wmi_hwmon_read_string(struct device *dev, 1404 enum hwmon_sensor_types type, u32 attr, 1405 int channel, const char **out_str) 1406 { 1407 const struct hp_wmi_sensors *state = dev_get_drvdata(dev); 1408 const struct hp_wmi_info *info; 1409 1410 info = state->info_map[type][channel]; 1411 *out_str = info->nsensor.name; 1412 1413 return 0; 1414 } 1415 1416 static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type, 1417 u32 attr, int channel, long val) 1418 { 1419 struct hp_wmi_sensors *state = dev_get_drvdata(dev); 1420 1421 if (val) 1422 return -EINVAL; 1423 1424 mutex_lock(&state->lock); 1425 1426 state->intrusion = false; 1427 1428 mutex_unlock(&state->lock); 1429 1430 return 0; 1431 } 1432 1433 static const struct hwmon_ops hp_wmi_hwmon_ops = { 1434 .is_visible = hp_wmi_hwmon_is_visible, 1435 .read = hp_wmi_hwmon_read, 1436 .read_string = hp_wmi_hwmon_read_string, 1437 .write = hp_wmi_hwmon_write, 1438 }; 1439 1440 static struct hwmon_chip_info hp_wmi_chip_info = { 1441 .ops = &hp_wmi_hwmon_ops, 1442 .info = NULL, 1443 }; 1444 1445 static struct hp_wmi_info *match_fan_event(struct hp_wmi_sensors *state, 1446 const char *event_description) 1447 { 1448 struct hp_wmi_info **ptr_info = state->info_map[hwmon_fan]; 1449 u8 fan_count = state->channel_count[hwmon_fan]; 1450 struct hp_wmi_info *info; 1451 const char *name; 1452 u8 i; 1453 1454 /* Fan event has Description "X Speed". Sensor has Name "X[ Speed]". */ 1455 1456 for (i = 0; i < fan_count; i++, ptr_info++) { 1457 info = *ptr_info; 1458 name = info->nsensor.name; 1459 1460 if (strstr(event_description, name)) 1461 return info; 1462 } 1463 1464 return NULL; 1465 } 1466 1467 static u8 match_temp_events(struct hp_wmi_sensors *state, 1468 const char *event_description, 1469 struct hp_wmi_info *temp_info[]) 1470 { 1471 struct hp_wmi_info **ptr_info = state->info_map[hwmon_temp]; 1472 u8 temp_count = state->channel_count[hwmon_temp]; 1473 struct hp_wmi_info *info; 1474 const char *name; 1475 u8 count = 0; 1476 bool is_cpu; 1477 bool is_sys; 1478 u8 i; 1479 1480 /* Description is either "CPU Thermal Index" or "Chassis Thermal Index". */ 1481 1482 is_cpu = !strcmp(event_description, HP_WMI_PATTERN_CPU_TEMP); 1483 is_sys = !strcmp(event_description, HP_WMI_PATTERN_SYS_TEMP); 1484 if (!is_cpu && !is_sys) 1485 return 0; 1486 1487 /* 1488 * CPU event: Match one sensor with Name either "CPU Thermal Index" or 1489 * "CPU Temperature", or multiple with Name(s) "CPU[#] Temperature". 1490 * 1491 * Chassis event: Match one sensor with Name either 1492 * "Chassis Thermal Index" or "System Ambient Temperature". 1493 */ 1494 1495 for (i = 0; i < temp_count; i++, ptr_info++) { 1496 info = *ptr_info; 1497 name = info->nsensor.name; 1498 1499 if ((is_cpu && (!strcmp(name, HP_WMI_PATTERN_CPU_TEMP) || 1500 !strcmp(name, HP_WMI_PATTERN_CPU_TEMP2))) || 1501 (is_sys && (!strcmp(name, HP_WMI_PATTERN_SYS_TEMP) || 1502 !strcmp(name, HP_WMI_PATTERN_SYS_TEMP2)))) { 1503 temp_info[0] = info; 1504 return 1; 1505 } 1506 1507 if (is_cpu && (strstr(name, HP_WMI_PATTERN_CPU) && 1508 strstr(name, HP_WMI_PATTERN_TEMP))) 1509 temp_info[count++] = info; 1510 } 1511 1512 return count; 1513 } 1514 1515 /* hp_wmi_devm_debugfs_remove - devm callback for WMI event handler removal */ 1516 static void hp_wmi_devm_notify_remove(void *ignored) 1517 { 1518 wmi_remove_notify_handler(HP_WMI_EVENT_GUID); 1519 } 1520 1521 /* hp_wmi_notify - WMI event notification handler */ 1522 static void hp_wmi_notify(u32 value, void *context) 1523 { 1524 struct hp_wmi_info *temp_info[HP_WMI_MAX_INSTANCES] = {}; 1525 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 1526 struct hp_wmi_sensors *state = context; 1527 struct device *dev = &state->wdev->dev; 1528 struct hp_wmi_info *fan_info; 1529 struct hp_wmi_event event; 1530 union acpi_object *wobj; 1531 acpi_status err; 1532 int event_type; 1533 u8 count; 1534 1535 /* 1536 * The following warning may occur in the kernel log: 1537 * 1538 * ACPI Warning: \_SB.WMID._WED: Return type mismatch - 1539 * found Package, expected Integer/String/Buffer 1540 * 1541 * After using [4] to decode BMOF blobs found in [3], careless copying 1542 * of BIOS code seems the most likely explanation for this warning. 1543 * HP_WMI_EVENT_GUID refers to \\.\root\WMI\HPBIOS_BIOSEvent on 1544 * business-class systems, but it refers to \\.\root\WMI\hpqBEvnt on 1545 * non-business-class systems. Per the existing hp-wmi driver, it 1546 * looks like an instance of hpqBEvnt delivered as event data may 1547 * indeed take the form of a raw ACPI_BUFFER on non-business-class 1548 * systems ("may" because ASL shows some BIOSes do strange things). 1549 * 1550 * In any case, we can ignore this warning, because we always validate 1551 * the event data to ensure it is an ACPI_PACKAGE containing a 1552 * HPBIOS_BIOSEvent instance. 1553 */ 1554 1555 mutex_lock(&state->lock); 1556 1557 err = wmi_get_event_data(value, &out); 1558 if (ACPI_FAILURE(err)) 1559 goto out_unlock; 1560 1561 wobj = out.pointer; 1562 1563 err = populate_event_from_wobj(&event, wobj); 1564 if (err) { 1565 dev_warn(dev, "Bad event data (ACPI type %d)\n", wobj->type); 1566 goto out_free_wobj; 1567 } 1568 1569 event_type = classify_event(event.name, event.category); 1570 switch (event_type) { 1571 case HP_WMI_TYPE_AIR_FLOW: 1572 fan_info = match_fan_event(state, event.description); 1573 if (fan_info) 1574 fan_info->alarm = true; 1575 break; 1576 1577 case HP_WMI_TYPE_INTRUSION: 1578 state->intrusion = true; 1579 break; 1580 1581 case HP_WMI_TYPE_TEMPERATURE: 1582 count = match_temp_events(state, event.description, temp_info); 1583 while (count) 1584 temp_info[--count]->alarm = true; 1585 break; 1586 1587 default: 1588 break; 1589 } 1590 1591 out_free_wobj: 1592 kfree(wobj); 1593 1594 out_unlock: 1595 mutex_unlock(&state->lock); 1596 } 1597 1598 static int init_platform_events(struct device *dev, 1599 struct hp_wmi_platform_events **out_pevents, 1600 u8 *out_pcount) 1601 { 1602 struct hp_wmi_platform_events *pevents_arr; 1603 struct hp_wmi_platform_events *pevents; 1604 union acpi_object *wobj; 1605 u8 count; 1606 int err; 1607 u8 i; 1608 1609 count = hp_wmi_wobj_instance_count(HP_WMI_PLATFORM_EVENTS_GUID); 1610 if (!count) { 1611 *out_pcount = 0; 1612 1613 dev_dbg(dev, "No platform events\n"); 1614 1615 return 0; 1616 } 1617 1618 pevents_arr = devm_kcalloc(dev, count, sizeof(*pevents), GFP_KERNEL); 1619 if (!pevents_arr) 1620 return -ENOMEM; 1621 1622 for (i = 0, pevents = pevents_arr; i < count; i++, pevents++) { 1623 wobj = hp_wmi_get_wobj(HP_WMI_PLATFORM_EVENTS_GUID, i); 1624 if (!wobj) 1625 return -EIO; 1626 1627 err = populate_platform_events_from_wobj(dev, pevents, wobj); 1628 1629 kfree(wobj); 1630 1631 if (err) 1632 return err; 1633 } 1634 1635 *out_pevents = pevents_arr; 1636 *out_pcount = count; 1637 1638 dev_dbg(dev, "Found %u platform events\n", count); 1639 1640 return 0; 1641 } 1642 1643 static int init_numeric_sensors(struct hp_wmi_sensors *state, 1644 struct hp_wmi_info *connected[], 1645 struct hp_wmi_info **out_info, 1646 u8 *out_icount, u8 *out_count, 1647 bool *out_is_new) 1648 { 1649 struct hp_wmi_info ***info_map = state->info_map; 1650 u8 *channel_count = state->channel_count; 1651 struct device *dev = &state->wdev->dev; 1652 struct hp_wmi_numeric_sensor *nsensor; 1653 u8 channel_index[hwmon_max] = {}; 1654 enum hwmon_sensor_types type; 1655 struct hp_wmi_info *info_arr; 1656 struct hp_wmi_info *info; 1657 union acpi_object *wobj; 1658 u8 count = 0; 1659 bool is_new; 1660 u8 icount; 1661 int wtype; 1662 int err; 1663 u8 c; 1664 u8 i; 1665 1666 icount = hp_wmi_wobj_instance_count(HP_WMI_NUMERIC_SENSOR_GUID); 1667 if (!icount) 1668 return -ENODATA; 1669 1670 info_arr = devm_kcalloc(dev, icount, sizeof(*info), GFP_KERNEL); 1671 if (!info_arr) 1672 return -ENOMEM; 1673 1674 for (i = 0, info = info_arr; i < icount; i++, info++) { 1675 wobj = hp_wmi_get_wobj(HP_WMI_NUMERIC_SENSOR_GUID, i); 1676 if (!wobj) 1677 return -EIO; 1678 1679 info->instance = i; 1680 info->state = state; 1681 nsensor = &info->nsensor; 1682 1683 err = populate_numeric_sensor_from_wobj(dev, nsensor, wobj, 1684 &is_new); 1685 1686 kfree(wobj); 1687 1688 if (err) 1689 return err; 1690 1691 if (!numeric_sensor_is_connected(nsensor)) 1692 continue; 1693 1694 wtype = classify_numeric_sensor(nsensor); 1695 if (wtype < 0) 1696 continue; 1697 1698 type = hp_wmi_hwmon_type_map[wtype]; 1699 1700 channel_count[type]++; 1701 1702 info->type = type; 1703 1704 interpret_info(info); 1705 1706 connected[count++] = info; 1707 } 1708 1709 dev_dbg(dev, "Found %u sensors (%u connected)\n", i, count); 1710 1711 for (i = 0; i < count; i++) { 1712 info = connected[i]; 1713 type = info->type; 1714 c = channel_index[type]++; 1715 1716 if (!info_map[type]) { 1717 info_map[type] = devm_kcalloc(dev, channel_count[type], 1718 sizeof(*info_map), 1719 GFP_KERNEL); 1720 if (!info_map[type]) 1721 return -ENOMEM; 1722 } 1723 1724 info_map[type][c] = info; 1725 } 1726 1727 *out_info = info_arr; 1728 *out_icount = icount; 1729 *out_count = count; 1730 *out_is_new = is_new; 1731 1732 return 0; 1733 } 1734 1735 static bool find_event_attributes(struct hp_wmi_sensors *state, 1736 struct hp_wmi_platform_events *pevents, 1737 u8 pevents_count) 1738 { 1739 /* 1740 * The existence of this HPBIOS_PlatformEvents instance: 1741 * 1742 * { 1743 * Name = "Rear Chassis Fan0 Stall"; 1744 * Description = "Rear Chassis Fan0 Speed"; 1745 * Category = 3; // "Sensor" 1746 * PossibleSeverity = 25; // "Critical Failure" 1747 * PossibleStatus = 5; // "Predictive Failure" 1748 * [...] 1749 * } 1750 * 1751 * means that this HPBIOS_BIOSEvent instance may occur: 1752 * 1753 * { 1754 * Name = "Rear Chassis Fan0 Stall"; 1755 * Description = "Rear Chassis Fan0 Speed"; 1756 * Category = 3; // "Sensor" 1757 * Severity = 25; // "Critical Failure" 1758 * Status = 5; // "Predictive Failure" 1759 * } 1760 * 1761 * After the event occurs (e.g. because the fan was unplugged), 1762 * polling the related HPBIOS_BIOSNumericSensor instance gives: 1763 * 1764 * { 1765 * Name = "Rear Chassis Fan0"; 1766 * Description = "Reports rear chassis fan0 speed"; 1767 * OperationalStatus = 5; // "Predictive Failure", was 3 ("OK") 1768 * CurrentReading = 0; 1769 * [...] 1770 * } 1771 * 1772 * In this example, the hwmon fan channel for "Rear Chassis Fan0" 1773 * should support the alarm flag and have it be set if the related 1774 * HPBIOS_BIOSEvent instance occurs. 1775 * 1776 * In addition to fan events, temperature (CPU/chassis) and intrusion 1777 * events are relevant to hwmon [2]. Note that much information in [2] 1778 * is unreliable; it is referenced in addition to ACPI dumps [3] merely 1779 * to support the conclusion that sensor and event names/descriptions 1780 * are systematic enough to allow this driver to match them. 1781 * 1782 * Complications and limitations: 1783 * 1784 * - Strings are freeform and may vary, cf. sensor Name "CPU0 Fan" 1785 * on a Z420 vs. "CPU Fan Speed" on an EliteOne 800 G1. 1786 * - Leading/trailing whitespace is a rare but real possibility [3]. 1787 * - The HPBIOS_PlatformEvents object may not exist or its instances 1788 * may show that the system only has e.g. BIOS setting-related 1789 * events (cf. the ProBook 4540s and ProBook 470 G0 [3]). 1790 */ 1791 1792 struct hp_wmi_info *temp_info[HP_WMI_MAX_INSTANCES] = {}; 1793 const char *event_description; 1794 struct hp_wmi_info *fan_info; 1795 bool has_events = false; 1796 const char *event_name; 1797 u32 event_category; 1798 int event_type; 1799 u8 count; 1800 u8 i; 1801 1802 for (i = 0; i < pevents_count; i++, pevents++) { 1803 event_name = pevents->name; 1804 event_description = pevents->description; 1805 event_category = pevents->category; 1806 1807 event_type = classify_event(event_name, event_category); 1808 switch (event_type) { 1809 case HP_WMI_TYPE_AIR_FLOW: 1810 fan_info = match_fan_event(state, event_description); 1811 if (!fan_info) 1812 break; 1813 1814 fan_info->has_alarm = true; 1815 has_events = true; 1816 break; 1817 1818 case HP_WMI_TYPE_INTRUSION: 1819 state->has_intrusion = true; 1820 has_events = true; 1821 break; 1822 1823 case HP_WMI_TYPE_TEMPERATURE: 1824 count = match_temp_events(state, event_description, 1825 temp_info); 1826 if (!count) 1827 break; 1828 1829 while (count) 1830 temp_info[--count]->has_alarm = true; 1831 has_events = true; 1832 break; 1833 1834 default: 1835 break; 1836 } 1837 } 1838 1839 return has_events; 1840 } 1841 1842 static int make_chip_info(struct hp_wmi_sensors *state, bool has_events) 1843 { 1844 const struct hwmon_channel_info **ptr_channel_info; 1845 struct hp_wmi_info ***info_map = state->info_map; 1846 u8 *channel_count = state->channel_count; 1847 struct hwmon_channel_info *channel_info; 1848 struct device *dev = &state->wdev->dev; 1849 enum hwmon_sensor_types type; 1850 u8 type_count = 0; 1851 u32 *config; 1852 u32 attr; 1853 u8 count; 1854 u8 i; 1855 1856 if (channel_count[hwmon_temp]) 1857 channel_count[hwmon_chip] = 1; 1858 1859 if (has_events && state->has_intrusion) 1860 channel_count[hwmon_intrusion] = 1; 1861 1862 for (type = hwmon_chip; type < hwmon_max; type++) 1863 if (channel_count[type]) 1864 type_count++; 1865 1866 channel_info = devm_kcalloc(dev, type_count, 1867 sizeof(*channel_info), GFP_KERNEL); 1868 if (!channel_info) 1869 return -ENOMEM; 1870 1871 ptr_channel_info = devm_kcalloc(dev, type_count + 1, 1872 sizeof(*ptr_channel_info), GFP_KERNEL); 1873 if (!ptr_channel_info) 1874 return -ENOMEM; 1875 1876 hp_wmi_chip_info.info = ptr_channel_info; 1877 1878 for (type = hwmon_chip; type < hwmon_max; type++) { 1879 count = channel_count[type]; 1880 if (!count) 1881 continue; 1882 1883 config = devm_kcalloc(dev, count + 1, 1884 sizeof(*config), GFP_KERNEL); 1885 if (!config) 1886 return -ENOMEM; 1887 1888 attr = hp_wmi_hwmon_attributes[type]; 1889 channel_info->type = type; 1890 channel_info->config = config; 1891 memset32(config, attr, count); 1892 1893 *ptr_channel_info++ = channel_info++; 1894 1895 if (!has_events || (type != hwmon_temp && type != hwmon_fan)) 1896 continue; 1897 1898 attr = type == hwmon_temp ? HWMON_T_ALARM : HWMON_F_ALARM; 1899 1900 for (i = 0; i < count; i++) 1901 if (info_map[type][i]->has_alarm) 1902 config[i] |= attr; 1903 } 1904 1905 return 0; 1906 } 1907 1908 static bool add_event_handler(struct hp_wmi_sensors *state) 1909 { 1910 struct device *dev = &state->wdev->dev; 1911 int err; 1912 1913 err = wmi_install_notify_handler(HP_WMI_EVENT_GUID, 1914 hp_wmi_notify, state); 1915 if (err) { 1916 dev_info(dev, "Failed to subscribe to WMI event\n"); 1917 return false; 1918 } 1919 1920 err = devm_add_action_or_reset(dev, hp_wmi_devm_notify_remove, NULL); 1921 if (err) 1922 return false; 1923 1924 return true; 1925 } 1926 1927 static int hp_wmi_sensors_init(struct hp_wmi_sensors *state) 1928 { 1929 struct hp_wmi_info *connected[HP_WMI_MAX_INSTANCES]; 1930 struct hp_wmi_platform_events *pevents; 1931 struct device *dev = &state->wdev->dev; 1932 struct hp_wmi_info *info; 1933 struct device *hwdev; 1934 bool has_events; 1935 bool is_new; 1936 u8 icount; 1937 u8 pcount; 1938 u8 count; 1939 int err; 1940 1941 err = init_platform_events(dev, &pevents, &pcount); 1942 if (err) 1943 return err; 1944 1945 err = init_numeric_sensors(state, connected, &info, 1946 &icount, &count, &is_new); 1947 if (err) 1948 return err; 1949 1950 if (IS_ENABLED(CONFIG_DEBUG_FS)) 1951 hp_wmi_debugfs_init(dev, info, pevents, icount, pcount, is_new); 1952 1953 if (!count) 1954 return 0; /* No connected sensors; debugfs only. */ 1955 1956 has_events = find_event_attributes(state, pevents, pcount); 1957 1958 /* Survive failure to install WMI event handler. */ 1959 if (has_events && !add_event_handler(state)) 1960 has_events = false; 1961 1962 err = make_chip_info(state, has_events); 1963 if (err) 1964 return err; 1965 1966 hwdev = devm_hwmon_device_register_with_info(dev, "hp_wmi_sensors", 1967 state, &hp_wmi_chip_info, 1968 NULL); 1969 return PTR_ERR_OR_ZERO(hwdev); 1970 } 1971 1972 static int hp_wmi_sensors_probe(struct wmi_device *wdev, const void *context) 1973 { 1974 struct device *dev = &wdev->dev; 1975 struct hp_wmi_sensors *state; 1976 1977 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); 1978 if (!state) 1979 return -ENOMEM; 1980 1981 state->wdev = wdev; 1982 1983 mutex_init(&state->lock); 1984 1985 dev_set_drvdata(dev, state); 1986 1987 return hp_wmi_sensors_init(state); 1988 } 1989 1990 static const struct wmi_device_id hp_wmi_sensors_id_table[] = { 1991 { HP_WMI_NUMERIC_SENSOR_GUID, NULL }, 1992 {}, 1993 }; 1994 1995 static struct wmi_driver hp_wmi_sensors_driver = { 1996 .driver = { .name = "hp-wmi-sensors" }, 1997 .id_table = hp_wmi_sensors_id_table, 1998 .probe = hp_wmi_sensors_probe, 1999 }; 2000 module_wmi_driver(hp_wmi_sensors_driver); 2001 2002 MODULE_AUTHOR("James Seo <james@equiv.tech>"); 2003 MODULE_DESCRIPTION("HP WMI Sensors driver"); 2004 MODULE_LICENSE("GPL"); 2005