lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220509063010.3878134-3-clabbe@baylibre.com>
Date:   Mon,  9 May 2022 06:30:10 +0000
From:   Corentin Labbe <clabbe@...libre.com>
To:     jdelvare@...e.com, linux@...ck-us.net
Cc:     linux-hwmon@...r.kernel.org, linux-kernel@...r.kernel.org,
        Corentin Labbe <clabbe@...libre.com>
Subject: [PATCH v3 2/2] hwmon: acpi_power_meter: convert to hwmon_device_register_with_info

Booting lead to a hwmon_device_register() is deprecated. Please convert the driver to use hwmon_device_register_with_info().
So let's convert the driver to use hwmon_device_register_with_info().

Signed-off-by: Corentin Labbe <clabbe@...libre.com>
---
 drivers/hwmon/acpi_power_meter.c | 509 +++++++++++++------------------
 1 file changed, 219 insertions(+), 290 deletions(-)

diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c
index d2545a1be9fc..03a144c884aa 100644
--- a/drivers/hwmon/acpi_power_meter.c
+++ b/drivers/hwmon/acpi_power_meter.c
@@ -23,7 +23,8 @@
 #define ACPI_POWER_METER_DEVICE_NAME	"Power Meter"
 #define ACPI_POWER_METER_CLASS		"pwr_meter_resource"
 
-#define NUM_SENSORS			17
+#define TRIP_MIN 0
+#define TRIP_MAX 1
 
 #define POWER_METER_CAN_MEASURE	(1 << 0)
 #define POWER_METER_CAN_TRIP	(1 << 1)
@@ -38,11 +39,6 @@
 #define METER_NOTIFY_CAPPING	0x83
 #define METER_NOTIFY_INTERVAL	0x84
 
-#define POWER_AVERAGE_NAME	"power1_average"
-#define POWER_CAP_NAME		"power1_cap"
-#define POWER_AVG_INTERVAL_NAME	"power1_average_interval"
-#define POWER_ALARM_NAME	"power1_alarm"
-
 static int cap_in_hardware;
 static bool force_cap_on;
 
@@ -85,8 +81,6 @@ struct acpi_power_meter_resource {
 	u64		avg_interval;
 	int			sensors_valid;
 	unsigned long		sensors_last_updated;
-	struct sensor_device_attribute	sensors[NUM_SENSORS];
-	int			num_sensors;
 	s64			trip[2];
 	int			num_domain_devices;
 	struct acpi_device	**domain_devices;
@@ -122,47 +116,32 @@ static int update_avg_interval(struct acpi_power_meter_resource *resource)
 	return 0;
 }
 
-static ssize_t show_avg_interval(struct device *dev,
-				 struct device_attribute *devattr,
-				 char *buf)
+static int acpi_power_average_interval_read(struct acpi_power_meter_resource *resource)
 {
-	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);
+	return resource->avg_interval;
 }
 
-static ssize_t set_avg_interval(struct device *dev,
-				struct device_attribute *devattr,
-				const char *buf, size_t count)
+static int set_average_interval(struct acpi_power_meter_resource *resource, long val)
 {
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
-	int res;
-	unsigned long temp;
 	unsigned long long data;
 	acpi_status status;
 
-	res = kstrtoul(buf, 10, &temp);
-	if (res)
-		return res;
-
-	if (temp > resource->caps.max_avg_interval ||
-	    temp < resource->caps.min_avg_interval)
+	if (val > resource->caps.max_avg_interval ||
+	    val < resource->caps.min_avg_interval)
 		return -EINVAL;
-	arg0.integer.value = temp;
+	arg0.integer.value = val;
 
 	mutex_lock(&resource->lock);
 	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI",
 				       &args, &data);
 	if (ACPI_SUCCESS(status))
-		resource->avg_interval = temp;
+		resource->avg_interval = val;
 	mutex_unlock(&resource->lock);
 
 	if (ACPI_FAILURE(status)) {
@@ -175,7 +154,7 @@ static ssize_t set_avg_interval(struct device *dev,
 	if (data)
 		return -EINVAL;
 
-	return count;
+	return 0;
 }
 
 /* Cap functions */
@@ -196,46 +175,33 @@ static int update_cap(struct acpi_power_meter_resource *resource)
 	return 0;
 }
 
-static ssize_t show_cap(struct device *dev,
-			struct device_attribute *devattr,
-			char *buf)
+static int acpi_power_cap_read(struct acpi_power_meter_resource *resource,
+			       long *val)
 {
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-
 	mutex_lock(&resource->lock);
 	update_cap(resource);
 	mutex_unlock(&resource->lock);
 
-	return sprintf(buf, "%llu\n", resource->cap * 1000);
+	return resource->cap * 1000;
 }
 
-static ssize_t set_cap(struct device *dev, struct device_attribute *devattr,
-		       const char *buf, size_t count)
+static int set_cap(struct acpi_power_meter_resource *resource, long val)
 {
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
-	int res;
-	unsigned long temp;
 	unsigned long long data;
 	acpi_status status;
 
-	res = kstrtoul(buf, 10, &temp);
-	if (res)
-		return res;
-
-	temp = DIV_ROUND_CLOSEST(temp, 1000);
-	if (temp > resource->caps.max_cap || temp < resource->caps.min_cap)
+	val = DIV_ROUND_CLOSEST(val, 1000);
+	if (val > resource->caps.max_cap || val < resource->caps.min_cap)
 		return -EINVAL;
-	arg0.integer.value = temp;
+	arg0.integer.value = val;
 
 	mutex_lock(&resource->lock);
 	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL",
 				       &args, &data);
 	if (ACPI_SUCCESS(status))
-		resource->cap = temp;
+		resource->cap = val;
 	mutex_unlock(&resource->lock);
 
 	if (ACPI_FAILURE(status)) {
@@ -248,7 +214,7 @@ static ssize_t set_cap(struct device *dev, struct device_attribute *devattr,
 	if (data)
 		return -EINVAL;
 
-	return count;
+	return 0;
 }
 
 /* Power meter trip points */
@@ -263,12 +229,12 @@ static int set_acpi_trip(struct acpi_power_meter_resource *resource)
 	acpi_status status;
 
 	/* Both trip levels must be set */
-	if (resource->trip[0] < 0 || resource->trip[1] < 0)
+	if (resource->trip[TRIP_MIN] < 0 || resource->trip[TRIP_MAX] < 0)
 		return 0;
 
 	/* This driver stores min, max; ACPI wants max, min. */
-	arg_objs[0].integer.value = resource->trip[1];
-	arg_objs[1].integer.value = resource->trip[0];
+	arg_objs[0].integer.value = resource->trip[TRIP_MAX];
+	arg_objs[1].integer.value = resource->trip[TRIP_MIN];
 
 	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PTP",
 				       &args, &data);
@@ -285,30 +251,18 @@ static int set_acpi_trip(struct acpi_power_meter_resource *resource)
 	return 0;
 }
 
-static ssize_t set_trip(struct device *dev, struct device_attribute *devattr,
-			const char *buf, size_t count)
+static int set_trip(struct acpi_power_meter_resource *resource, long val, int triptype)
 {
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
 	int res;
-	unsigned long temp;
 
-	res = kstrtoul(buf, 10, &temp);
-	if (res)
-		return res;
-
-	temp = DIV_ROUND_CLOSEST(temp, 1000);
+	val = DIV_ROUND_CLOSEST(val, 1000);
 
 	mutex_lock(&resource->lock);
-	resource->trip[attr->index - 7] = temp;
+	resource->trip[triptype] = val;
 	res = set_acpi_trip(resource);
 	mutex_unlock(&resource->lock);
 
-	if (res)
-		return res;
-
-	return count;
+	return res;
 }
 
 /* Power meter */
@@ -337,33 +291,26 @@ static int update_meter(struct acpi_power_meter_resource *resource)
 	return 0;
 }
 
-static ssize_t show_power(struct device *dev,
-			  struct device_attribute *devattr,
-			  char *buf)
+static int acpi_power_power_read(struct acpi_power_meter_resource *resource,
+				 long *val)
 {
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-
 	mutex_lock(&resource->lock);
 	update_meter(resource);
 	mutex_unlock(&resource->lock);
 
-	return sprintf(buf, "%llu\n", resource->power * 1000);
+	*val = resource->power * 1000;
+	return 0;
 }
 
 /* Miscellaneous */
-static ssize_t show_str(struct device *dev,
-			struct device_attribute *devattr,
-			char *buf)
+static ssize_t show_str(struct device *dev, int index, char *buf)
 {
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
+	struct acpi_power_meter_resource *resource = dev_get_drvdata(dev);
 	acpi_string val;
 	int ret;
 
 	mutex_lock(&resource->lock);
-	switch (attr->index) {
+	switch (index) {
 	case 0:
 		val = resource->model_number;
 		break;
@@ -375,7 +322,7 @@ static ssize_t show_str(struct device *dev,
 		break;
 	default:
 		WARN(1, "Implementation error: unexpected attribute index %d\n",
-		     attr->index);
+		     index);
 		val = "";
 		break;
 	}
@@ -384,141 +331,138 @@ static ssize_t show_str(struct device *dev,
 	return ret;
 }
 
-static ssize_t show_val(struct device *dev,
-			struct device_attribute *devattr,
-			char *buf)
+static ssize_t power1_is_battery_show(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
 {
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
 	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-	u64 val = 0;
+	int val;
 
-	switch (attr->index) {
-	case 0:
-		val = resource->caps.min_avg_interval;
+	if (resource->caps.flags & POWER_METER_IS_BATTERY)
+		val = 1;
+	else
+		val = 0;
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t power1_model_number_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	return show_str(dev, 0, buf);
+}
+
+static ssize_t power1_serial_number_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	return show_str(dev, 1, buf);
+}
+
+static ssize_t power1_oem_info_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	return show_str(dev, 2, buf);
+}
+
+static int acpi_power_read(struct device *dev, enum hwmon_sensor_types type,
+			   u32 attr, int channel, long *val)
+{
+	struct acpi_power_meter_resource *resource = dev_get_drvdata(dev);
+
+	switch (attr) {
+	case hwmon_power_average:
+		return acpi_power_power_read(resource, val);
+	case hwmon_power_average_interval_min:
+		*val = resource->caps.min_avg_interval;
 		break;
-	case 1:
-		val = resource->caps.max_avg_interval;
+	case hwmon_power_average_interval_max:
+		*val = resource->caps.max_avg_interval;
 		break;
-	case 2:
-		val = resource->caps.min_cap * 1000;
+	case hwmon_power_cap_min:
+		*val = resource->caps.min_cap * 1000;
 		break;
-	case 3:
-		val = resource->caps.max_cap * 1000;
+	case hwmon_power_cap_max:
+		*val = resource->caps.max_cap * 1000;
 		break;
-	case 4:
+	case hwmon_power_cap:
+		*val = acpi_power_cap_read(resource, val);
+		break;
+	case hwmon_power_cap_hyst:
 		if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS)
-			return sprintf(buf, "unknown\n");
+			return -EINVAL;
 
-		val = resource->caps.hysteresis * 1000;
+		*val = resource->caps.hysteresis * 1000;
 		break;
-	case 5:
-		if (resource->caps.flags & POWER_METER_IS_BATTERY)
-			val = 1;
-		else
-			val = 0;
-		break;
-	case 6:
+	case hwmon_power_alarm:
 		if (resource->power > resource->cap)
-			val = 1;
+			*val = 1;
 		else
-			val = 0;
+			*val = 0;
 		break;
-	case 7:
-	case 8:
-		if (resource->trip[attr->index - 7] < 0)
-			return sprintf(buf, "unknown\n");
-
-		val = resource->trip[attr->index - 7] * 1000;
+	case hwmon_power_average_min:
+		if (resource->trip[TRIP_MIN] < 0)
+			return -EINVAL;
+		*val = resource->trip[TRIP_MIN] * 1000;
+		break;
+	case hwmon_power_average_max:
+		if (resource->trip[TRIP_MAX] < 0)
+			return -EINVAL;
+		*val = resource->trip[TRIP_MAX] * 1000;
+		break;
+	case hwmon_power_average_interval:
+		*val = acpi_power_average_interval_read(resource);
+		break;
+	case hwmon_power_accuracy:
+		*val = div_u64(resource->caps.accuracy, 1000);
 		break;
 	default:
 		WARN(1, "Implementation error: unexpected attribute index %d\n",
-		     attr->index);
-		break;
+		     attr);
+		return -EOPNOTSUPP;
 	}
 
-	return sprintf(buf, "%llu\n", val);
-}
-
-static ssize_t show_accuracy(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;
-	unsigned int acc = resource->caps.accuracy;
-
-	return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000);
+	return 0;
 }
 
-static ssize_t show_name(struct device *dev,
-			 struct device_attribute *devattr,
-			 char *buf)
+static int acpi_power_write(struct device *dev, enum hwmon_sensor_types type,
+			    u32 attr, int channel, long val)
 {
-	return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME);
-}
-
-#define RO_SENSOR_TEMPLATE(_label, _show, _index)	\
-	{						\
-		.label = _label,			\
-		.show  = _show,				\
-		.index = _index,			\
-	}
-
-#define RW_SENSOR_TEMPLATE(_label, _show, _set, _index)	\
-	{						\
-		.label = _label,			\
-		.show  = _show,				\
-		.set   = _set,				\
-		.index = _index,			\
+	struct acpi_power_meter_resource *resource = dev_get_drvdata(dev);
+
+	switch (attr) {
+	case hwmon_power_average_min:
+		return set_trip(resource, TRIP_MIN, val);
+	case hwmon_power_average_max:
+		return set_trip(resource, TRIP_MAX, val);
+	case hwmon_power_cap:
+		if (resource->caps.configurable_cap)
+			return set_cap(resource, val);
+		else
+			return -EINVAL;
+	case hwmon_power_average_interval:
+		return set_average_interval(resource, val);
+	default:
+		return -EOPNOTSUPP;
 	}
+}
 
-/* Sensor descriptions.  If you add a sensor, update NUM_SENSORS above! */
-static struct sensor_template meter_attrs[] = {
-	RO_SENSOR_TEMPLATE(POWER_AVERAGE_NAME, show_power, 0),
-	RO_SENSOR_TEMPLATE("power1_accuracy", show_accuracy, 0),
-	RO_SENSOR_TEMPLATE("power1_average_interval_min", show_val, 0),
-	RO_SENSOR_TEMPLATE("power1_average_interval_max", show_val, 1),
-	RO_SENSOR_TEMPLATE("power1_is_battery", show_val, 5),
-	RW_SENSOR_TEMPLATE(POWER_AVG_INTERVAL_NAME, show_avg_interval,
-			   set_avg_interval, 0),
-	{},
-};
-
-static struct sensor_template misc_cap_attrs[] = {
-	RO_SENSOR_TEMPLATE("power1_cap_min", show_val, 2),
-	RO_SENSOR_TEMPLATE("power1_cap_max", show_val, 3),
-	RO_SENSOR_TEMPLATE("power1_cap_hyst", show_val, 4),
-	RO_SENSOR_TEMPLATE(POWER_ALARM_NAME, show_val, 6),
-	{},
-};
-
-static struct sensor_template ro_cap_attrs[] = {
-	RO_SENSOR_TEMPLATE(POWER_CAP_NAME, show_cap, 0),
-	{},
-};
-
-static struct sensor_template rw_cap_attrs[] = {
-	RW_SENSOR_TEMPLATE(POWER_CAP_NAME, show_cap, set_cap, 0),
-	{},
-};
-
-static struct sensor_template trip_attrs[] = {
-	RW_SENSOR_TEMPLATE("power1_average_min", show_val, set_trip, 7),
-	RW_SENSOR_TEMPLATE("power1_average_max", show_val, set_trip, 8),
-	{},
-};
-
-static struct sensor_template misc_attrs[] = {
-	RO_SENSOR_TEMPLATE("name", show_name, 0),
-	RO_SENSOR_TEMPLATE("power1_model_number", show_str, 0),
-	RO_SENSOR_TEMPLATE("power1_oem_info", show_str, 2),
-	RO_SENSOR_TEMPLATE("power1_serial_number", show_str, 1),
-	{},
+static DEVICE_ATTR_RO(power1_is_battery);
+static DEVICE_ATTR_RO(power1_model_number);
+static DEVICE_ATTR_RO(power1_oem_info);
+static DEVICE_ATTR_RO(power1_serial_number);
+
+static struct attribute *acpi_power_attrs[] = {
+	&dev_attr_power1_is_battery.attr,
+	&dev_attr_power1_model_number.attr,
+	&dev_attr_power1_oem_info.attr,
+	&dev_attr_power1_serial_number.attr,
+	NULL
 };
 
-#undef RO_SENSOR_TEMPLATE
-#undef RW_SENSOR_TEMPLATE
+ATTRIBUTE_GROUPS(acpi_power);
 
 /* Read power domain data */
 static void remove_domain_devices(struct acpi_power_meter_resource *resource)
@@ -621,55 +565,52 @@ static int read_domain_devices(struct acpi_power_meter_resource *resource)
 	return res;
 }
 
-/* Registration and deregistration */
-static int register_attrs(struct acpi_power_meter_resource *resource,
-			  struct sensor_template *attrs)
-{
-	struct device *dev = &resource->acpi_dev->dev;
-	struct sensor_device_attribute *sensors =
-		&resource->sensors[resource->num_sensors];
-	int res = 0;
-
-	while (attrs->label) {
-		sensors->dev_attr.attr.name = attrs->label;
-		sensors->dev_attr.attr.mode = 0444;
-		sensors->dev_attr.show = attrs->show;
-		sensors->index = attrs->index;
-
-		if (attrs->set) {
-			sensors->dev_attr.attr.mode |= 0200;
-			sensors->dev_attr.store = attrs->set;
-		}
-
-		sysfs_attr_init(&sensors->dev_attr.attr);
-		res = device_create_file(dev, &sensors->dev_attr);
-		if (res) {
-			sensors->dev_attr.attr.name = NULL;
-			goto error;
-		}
-		sensors++;
-		resource->num_sensors++;
-		attrs++;
-	}
-
-error:
-	return res;
-}
-
-static void remove_attrs(struct acpi_power_meter_resource *resource)
+static umode_t acpi_power_is_visible(const void *data,
+				     enum hwmon_sensor_types type,
+				     u32 attr, int channel)
 {
-	int i;
+	const struct acpi_power_meter_resource *resource = data;
 
-	for (i = 0; i < resource->num_sensors; i++) {
-		if (!resource->sensors[i].dev_attr.attr.name)
-			continue;
-		device_remove_file(&resource->acpi_dev->dev,
-				   &resource->sensors[i].dev_attr);
+	switch (attr) {
+	case hwmon_power_average_min:
+	case hwmon_power_average_max:
+		if (resource->caps.flags & POWER_METER_CAN_TRIP)
+			return 0644;
+		break;
+	case hwmon_power_average:
+	case hwmon_power_accuracy:
+	case hwmon_power_average_interval_min:
+	case hwmon_power_average_interval_max:
+		if (resource->caps.flags & POWER_METER_CAN_MEASURE)
+			return 0444;
+		break;
+	case hwmon_power_average_interval:
+		if (resource->caps.flags & POWER_METER_CAN_MEASURE)
+			return 0644;
+		break;
+	case hwmon_power_cap:
+		if (!can_cap_in_hardware())
+			return 0;
+		if (!(resource->caps.flags & POWER_METER_CAN_CAP))
+			return 0;
+		if (resource->caps.configurable_cap)
+			return 0644;
+		return 0444;
+		break;
+	case hwmon_power_cap_min:
+	case hwmon_power_cap_max:
+	case hwmon_power_cap_hyst:
+	case hwmon_power_cap_alarm:
+		if (!can_cap_in_hardware())
+			return 0;
+		if (resource->caps.flags & POWER_METER_CAN_CAP)
+			return 0444;
+		break;
+	default:
+		break;
 	}
 
-	remove_domain_devices(resource);
-
-	resource->num_sensors = 0;
+	return 0;
 }
 
 static int setup_attrs(struct acpi_power_meter_resource *resource)
@@ -680,47 +621,11 @@ static int setup_attrs(struct acpi_power_meter_resource *resource)
 	if (res)
 		return res;
 
-	if (resource->caps.flags & POWER_METER_CAN_MEASURE) {
-		res = register_attrs(resource, meter_attrs);
-		if (res)
-			goto error;
+	if (resource->caps.flags & POWER_METER_CAN_CAP && !can_cap_in_hardware()) {
+		dev_warn(&resource->acpi_dev->dev,
+			 "Ignoring unsafe software power cap!\n");
 	}
-
-	if (resource->caps.flags & POWER_METER_CAN_CAP) {
-		if (!can_cap_in_hardware()) {
-			dev_warn(&resource->acpi_dev->dev,
-				 "Ignoring unsafe software power cap!\n");
-			goto skip_unsafe_cap;
-		}
-
-		if (resource->caps.configurable_cap)
-			res = register_attrs(resource, rw_cap_attrs);
-		else
-			res = register_attrs(resource, ro_cap_attrs);
-
-		if (res)
-			goto error;
-
-		res = register_attrs(resource, misc_cap_attrs);
-		if (res)
-			goto error;
-	}
-
-skip_unsafe_cap:
-	if (resource->caps.flags & POWER_METER_CAN_TRIP) {
-		res = register_attrs(resource, trip_attrs);
-		if (res)
-			goto error;
-	}
-
-	res = register_attrs(resource, misc_attrs);
-	if (res)
-		goto error;
-
-	return res;
-error:
-	remove_attrs(resource);
-	return res;
+	return 0;
 }
 
 static void free_capabilities(struct acpi_power_meter_resource *resource)
@@ -795,7 +700,6 @@ static int read_capabilities(struct acpi_power_meter_resource *resource)
 			res = -EINVAL;
 			goto error;
 		}
-
 		*str = kcalloc(element->string.length + 1, sizeof(u8),
 			       GFP_KERNEL);
 		if (!*str) {
@@ -836,20 +740,20 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
 		if (res)
 			break;
 
-		remove_attrs(resource);
+		remove_domain_devices(resource);
 		setup_attrs(resource);
 		break;
 	case METER_NOTIFY_TRIP:
-		sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME);
+		hwmon_notify_event(&device->dev, hwmon_power, hwmon_power_average, 0);
 		break;
 	case METER_NOTIFY_CAP:
-		sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME);
+		hwmon_notify_event(&device->dev, hwmon_power, hwmon_power_cap, 0);
 		break;
 	case METER_NOTIFY_INTERVAL:
-		sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME);
+		hwmon_notify_event(&device->dev, hwmon_power, hwmon_power_average_interval, 0);
 		break;
 	case METER_NOTIFY_CAPPING:
-		sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME);
+		hwmon_notify_event(&device->dev, hwmon_power, hwmon_power_alarm, 0);
 		dev_info(&device->dev, "Capping in progress.\n");
 		break;
 	default:
@@ -861,6 +765,28 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
 					dev_name(&device->dev), event, 0);
 }
 
+static const struct hwmon_channel_info *acpi_power_info[] = {
+	HWMON_CHANNEL_INFO(power,
+			   HWMON_P_AVERAGE | HWMON_P_AVERAGE_INTERVAL |
+			   HWMON_P_AVERAGE_MIN | HWMON_P_AVERAGE_MAX |
+			   HWMON_P_CAP | HWMON_P_CAP_HYST |
+			   HWMON_P_CAP_MIN | HWMON_P_CAP_MAX |
+			   HWMON_P_ACCURACY
+			   ),
+	NULL,
+};
+
+static const struct hwmon_ops acpi_power_hwmon_ops = {
+	.is_visible = acpi_power_is_visible,
+	.read = acpi_power_read,
+	.write = acpi_power_write,
+};
+
+static const struct hwmon_chip_info acpi_power_chip_info = {
+	.ops = &acpi_power_hwmon_ops,
+	.info = acpi_power_info,
+};
+
 static int acpi_power_meter_add(struct acpi_device *device)
 {
 	int res;
@@ -891,7 +817,10 @@ static int acpi_power_meter_add(struct acpi_device *device)
 	if (res)
 		goto exit_free_capability;
 
-	resource->hwmon_dev = hwmon_device_register(&device->dev);
+	resource->hwmon_dev = hwmon_device_register_with_info(&device->dev,
+							      ACPI_POWER_METER_NAME,
+							      resource, &acpi_power_chip_info,
+							      acpi_power_groups);
 	if (IS_ERR(resource->hwmon_dev)) {
 		res = PTR_ERR(resource->hwmon_dev);
 		goto exit_remove;
@@ -901,7 +830,7 @@ static int acpi_power_meter_add(struct acpi_device *device)
 	goto exit;
 
 exit_remove:
-	remove_attrs(resource);
+	remove_domain_devices(resource);
 exit_free_capability:
 	free_capabilities(resource);
 exit_free:
@@ -920,7 +849,7 @@ static int acpi_power_meter_remove(struct acpi_device *device)
 	resource = acpi_driver_data(device);
 	hwmon_device_unregister(resource->hwmon_dev);
 
-	remove_attrs(resource);
+	remove_domain_devices(resource);
 	free_capabilities(resource);
 
 	kfree(resource);
-- 
2.35.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ