static ssize_t show_avg_interval(struct device *dev, struct device_attribute *devattr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_power_meter_resource *resource = acpi_dev->driver_data; mutex_lock(&resource->lock); update_avg_interval(resource); mutex_unlock(&resource->lock); return sprintf(buf, "%llu\n", resource->avg_interval); }
/* Handle ACPI event notifications */ static void acpi_power_meter_notify(struct acpi_device *device, u32 event) { struct acpi_power_meter_resource *resource; int res; if (!device || !acpi_driver_data(device)) return; resource = acpi_driver_data(device); mutex_lock(&resource->lock); switch (event) { case METER_NOTIFY_CONFIG: free_capabilities(resource); res = read_capabilities(resource); if (res) break; remove_attrs(resource); setup_attrs(resource); break; case METER_NOTIFY_TRIP: sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME); update_meter(resource); break; case METER_NOTIFY_CAP: sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME); update_cap(resource); break; case METER_NOTIFY_INTERVAL: sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME); update_avg_interval(resource); break; case METER_NOTIFY_CAPPING: sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME); dev_info(&device->dev, "Capping in progress.\n"); break; default: WARN(1, "Unexpected event %d\n", event); break; } mutex_unlock(&resource->lock); acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS, dev_name(&device->dev), event, 0); }