hwmon: Add OCC CAPS sensors
RFC v4 6/6 hwmon: Add OCC CAPS sensors
From: "Edward A. James" <[email protected]>
Add CAPS sensors to sysfs.
Signed-off-by Edward A. James <[email protected]>
--- drivers/hwmon/occ/power8_occ.c | 118 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-)
drivers/hwmon/occ/power8_occ.c +117 -1
@@ -659,6 +659,49 @@ static ssize_t show_label(struct device *dev,return snprintf (buf,PAGE_SIZE -1 ,"%d\n" , val); } +static ssize_t show_caps (struct device *dev, +struct device_attribute *attr,char *buf) +{ +int val; +struct caps_sensor *sensor; +struct sensor_attr_data *sdata =container_of (attr, + struct sensor_attr_data, + dev_attr); +struct power8_driver *driver =dev_get_drvdata (dev); +int n = sdata->hwmon_index -1 ; + + sensor =occ_get_sensor (driver,CAPS ); +if (!sensor) { + val =-1 ; +return snprintf (buf,PAGE_SIZE -1 ,"%d\n" , val); + } + +switch (sdata->attr_id) { +case 0 : + val = sensor[n].curr_powercap; +break ; +case 1 : + val = sensor[n].curr_powerreading; +break ; +case 2 : + val = sensor[n].norm_powercap; +break ; +case 3 : + val = sensor[n].max_powercap; +break ; +case 4 : + val = sensor[n].min_powercap; +break ; +case 5 : + val = sensor[n].user_powerlimit; +break ; +default : + val =-1 ; + } + +return snprintf (buf,PAGE_SIZE -1 ,"%d\n" , val); +} +static ssize_t show_update_interval (struct device *dev,struct device_attribute *attr,char *buf) {
@@ -822,6 +865,77 @@ err:return rc; } +static void caps_sensor_attr_init (struct sensor_attr_data *sdata, +char *attr_name,uint32_t hwmon_index, +uint32_t attr_id) +{ + sdata->type =CAPS ; + sdata->hwmon_index = hwmon_index; + sdata->attr_id = attr_id; + +snprintf (sdata->name,MAX_SENSOR_ATTR_LEN ,"%s%d_%s" , +"caps" , sdata->hwmon_index, attr_name); + +sysfs_attr_init (&sdata->dev_attr.attr); + sdata->dev_attr.attr.name = sdata->name; + sdata->dev_attr.attr.mode =S_IRUGO ; + sdata->dev_attr.show = show_caps; +} + +static char *caps_sensor_name[] = { +"curr_powercap" , +"curr_powerreading" , +"norm_powercap" , +"max_powercap" , +"min_powercap" , +"user_powerlimit" , +}; + +static int create_caps_sensor_group (struct power8_driver *driver, +int sensor_num) +{ +struct device *dev = driver->dev; +struct sensor_group *sensor_groups = driver->sensor_groups; +int field_num =ARRAY_SIZE (caps_sensor_name); +struct sensor_attr_data *sdata; +int i, j, rc; + + sensor_groups[CAPS ].group.attrs = +devm_kzalloc (dev,sizeof (struct attribute *) * sensor_num * + field_num +1 ,GFP_KERNEL ); +if (!sensor_groups[CAPS ].group.attrs) { + rc = -ENOMEM ; + goto err; + } + + sensor_groups[CAPS ].sattr = +devm_kzalloc (dev,sizeof (struct sensor_attr_data ) * + sensor_num * field_num,GFP_KERNEL ); +if (!sensor_groups[CAPS ].sattr) { + rc = -ENOMEM ; + goto err; + } + +for (j =0 ; j < sensor_num; ++j) { +for (i =0 ; i < field_num; ++i) { + sdata = &sensor_groups[CAPS ].sattr[j * field_num + i]; +caps_sensor_attr_init (sdata, caps_sensor_name[i], + j +1 , i); + sensor_groups[CAPS ].group.attrs[j * field_num + i] = + &sdata->dev_attr.attr; + } + } + + rc =sysfs_create_group (&dev->kobj, &sensor_groups[CAPS ].group); +if (rc) + goto err; + +return rc; +err: +deinit_sensor_groups (dev, sensor_groups); +return rc; +} +static void occ_remove_hwmon_attrs (struct power8_driver *driver) {struct device *dev = driver->dev;
@@ -876,7 +990,9 @@ static int occ_create_hwmon_attrs(struct power8_driver *driver)continue ; sensor_num = resp->blocks[id].sensor_num; -if (i !=CAPS ) +if (i ==CAPS ) + rc =create_caps_sensor_group (driver, sensor_num); +else rc =create_sensor_group (driver, i, sensor_num);if (rc) goto error;
Signature · 1 line
1.9.1