Skip to content

Commit 7532e68

Browse files
LiHuiSong1groeck
authored andcommitted
hwmon: (acpi_power_meter) Fix uninitialized variables
The 'power1_alarm' attribute uses the 'power' and 'cap' in the acpi_power_meter_resource structure. Currently, these two fields are just updated when user query 'power' and 'cap' attribute. If user directly query the 'power1_alarm' attribute without queryng above two attributes, driver will use uninitialized variables to judge. So this patch adds the setting of alarm state and update 'cap' in the notification callback and update 'power' and 'cap' if needed to show the real alarm state. Signed-off-by: Huisong Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]>
1 parent c909e68 commit 7532e68

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

drivers/hwmon/acpi_power_meter.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct acpi_power_meter_resource {
8484
u64 power;
8585
u64 cap;
8686
u64 avg_interval;
87+
bool power_alarm;
8788
int sensors_valid;
8889
unsigned long sensors_last_updated;
8990
struct sensor_device_attribute sensors[NUM_SENSORS];
@@ -396,6 +397,9 @@ static ssize_t show_val(struct device *dev,
396397
struct acpi_device *acpi_dev = to_acpi_device(dev);
397398
struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
398399
u64 val = 0;
400+
int ret;
401+
402+
guard(mutex)(&resource->lock);
399403

400404
switch (attr->index) {
401405
case 0:
@@ -423,10 +427,17 @@ static ssize_t show_val(struct device *dev,
423427
val = 0;
424428
break;
425429
case 6:
426-
if (resource->power > resource->cap)
427-
val = 1;
428-
else
429-
val = 0;
430+
ret = update_meter(resource);
431+
if (ret)
432+
return ret;
433+
/* need to update cap if not to support the notification. */
434+
if (!(resource->caps.flags & POWER_METER_CAN_NOTIFY)) {
435+
ret = update_cap(resource);
436+
if (ret)
437+
return ret;
438+
}
439+
val = resource->power_alarm || resource->power > resource->cap;
440+
resource->power_alarm = resource->power > resource->cap;
430441
break;
431442
case 7:
432443
case 8:
@@ -847,12 +858,20 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
847858
sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME);
848859
break;
849860
case METER_NOTIFY_CAP:
861+
mutex_lock(&resource->lock);
862+
res = update_cap(resource);
863+
if (res)
864+
dev_err_once(&device->dev, "update cap failed when capping value is changed.\n");
865+
mutex_unlock(&resource->lock);
850866
sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME);
851867
break;
852868
case METER_NOTIFY_INTERVAL:
853869
sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME);
854870
break;
855871
case METER_NOTIFY_CAPPING:
872+
mutex_lock(&resource->lock);
873+
resource->power_alarm = true;
874+
mutex_unlock(&resource->lock);
856875
sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME);
857876
dev_info(&device->dev, "Capping in progress.\n");
858877
break;

0 commit comments

Comments
 (0)