Merge tag 'block-6.5-2023-07-03' of git://git.kernel.dk/linux
[platform/kernel/linux-starfive.git] / drivers / hwmon / hp-wmi-sensors.c
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, &current_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, &current_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");