Commit e1e081a7 authored by Guenter Roeck's avatar Guenter Roeck

hwmon: (pmbus) Simplify memory allocation for sensor attributes

Since memory is now allocated with dev_ functions, we no longer need to keep
track of allocated memory. Sensor memory allocation can therefore be
simplified significantly.
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent 663834f3
...@@ -85,8 +85,9 @@ ...@@ -85,8 +85,9 @@
#define PMBUS_NAME_SIZE 24 #define PMBUS_NAME_SIZE 24
struct pmbus_sensor { struct pmbus_sensor {
struct pmbus_sensor *next;
char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */
struct sensor_device_attribute attribute; struct device_attribute attribute;
u8 page; /* page number */ u8 page; /* page number */
u16 reg; /* register */ u16 reg; /* register */
enum pmbus_sensor_classes class; /* sensor class */ enum pmbus_sensor_classes class; /* sensor class */
...@@ -94,6 +95,8 @@ struct pmbus_sensor { ...@@ -94,6 +95,8 @@ struct pmbus_sensor {
int data; /* Sensor data. int data; /* Sensor data.
Negative if there was a read error */ Negative if there was a read error */
}; };
#define to_pmbus_sensor(_attr) \
container_of(_attr, struct pmbus_sensor, attribute)
struct pmbus_boolean { struct pmbus_boolean {
char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */
...@@ -127,11 +130,6 @@ struct pmbus_data { ...@@ -127,11 +130,6 @@ struct pmbus_data {
struct attribute **attributes; struct attribute **attributes;
struct attribute_group group; struct attribute_group group;
/*
* Sensors cover both sensor and limit registers.
*/
int max_sensors;
int num_sensors;
struct pmbus_sensor *sensors; struct pmbus_sensor *sensors;
struct mutex update_lock; struct mutex update_lock;
...@@ -361,6 +359,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) ...@@ -361,6 +359,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct pmbus_data *data = i2c_get_clientdata(client); struct pmbus_data *data = i2c_get_clientdata(client);
const struct pmbus_driver_info *info = data->info; const struct pmbus_driver_info *info = data->info;
struct pmbus_sensor *sensor;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
...@@ -410,9 +409,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) ...@@ -410,9 +409,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)
= _pmbus_read_byte_data(client, 0, = _pmbus_read_byte_data(client, 0,
PMBUS_STATUS_INPUT); PMBUS_STATUS_INPUT);
for (i = 0; i < data->num_sensors; i++) { for (sensor = data->sensors; sensor; sensor = sensor->next) {
struct pmbus_sensor *sensor = &data->sensors[i];
if (!data->valid || sensor->update) if (!data->valid || sensor->update)
sensor->data sensor->data
= _pmbus_read_word_data(client, = _pmbus_read_word_data(client,
...@@ -748,13 +745,11 @@ static ssize_t pmbus_show_boolean(struct device *dev, ...@@ -748,13 +745,11 @@ static ssize_t pmbus_show_boolean(struct device *dev,
} }
static ssize_t pmbus_show_sensor(struct device *dev, static ssize_t pmbus_show_sensor(struct device *dev,
struct device_attribute *da, char *buf) struct device_attribute *devattr, char *buf)
{ {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct pmbus_data *data = pmbus_update_device(dev); struct pmbus_data *data = pmbus_update_device(dev);
struct pmbus_sensor *sensor; struct pmbus_sensor *sensor = to_pmbus_sensor(devattr);
sensor = &data->sensors[attr->index];
if (sensor->data < 0) if (sensor->data < 0)
return sensor->data; return sensor->data;
...@@ -765,10 +760,9 @@ static ssize_t pmbus_set_sensor(struct device *dev, ...@@ -765,10 +760,9 @@ static ssize_t pmbus_set_sensor(struct device *dev,
struct device_attribute *devattr, struct device_attribute *devattr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct pmbus_data *data = i2c_get_clientdata(client); struct pmbus_data *data = i2c_get_clientdata(client);
struct pmbus_sensor *sensor = &data->sensors[attr->index]; struct pmbus_sensor *sensor = to_pmbus_sensor(devattr);
ssize_t rv = count; ssize_t rv = count;
long val = 0; long val = 0;
int ret; int ret;
...@@ -783,7 +777,7 @@ static ssize_t pmbus_set_sensor(struct device *dev, ...@@ -783,7 +777,7 @@ static ssize_t pmbus_set_sensor(struct device *dev,
if (ret < 0) if (ret < 0)
rv = ret; rv = ret;
else else
data->sensors[attr->index].data = regval; sensor->data = regval;
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return rv; return rv;
} }
...@@ -863,12 +857,13 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, ...@@ -863,12 +857,13 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
bool update, bool readonly) bool update, bool readonly)
{ {
struct pmbus_sensor *sensor; struct pmbus_sensor *sensor;
struct sensor_device_attribute *a; struct device_attribute *a;
BUG_ON(data->num_sensors >= data->max_sensors || BUG_ON(data->num_attributes >= data->max_attributes);
data->num_attributes >= data->max_attributes);
sensor = &data->sensors[data->num_sensors]; sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL);
if (!sensor)
return NULL;
a = &sensor->attribute; a = &sensor->attribute;
snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s",
...@@ -877,12 +872,13 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, ...@@ -877,12 +872,13 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
sensor->reg = reg; sensor->reg = reg;
sensor->class = class; sensor->class = class;
sensor->update = update; sensor->update = update;
pmbus_attr_init(a, sensor->name, pmbus_dev_attr_init(a, sensor->name,
readonly ? S_IRUGO : S_IRUGO | S_IWUSR, readonly ? S_IRUGO : S_IRUGO | S_IWUSR,
pmbus_show_sensor, pmbus_set_sensor, data->num_sensors); pmbus_show_sensor, pmbus_set_sensor);
data->attributes[data->num_attributes++] = &a->dev_attr.attr; data->attributes[data->num_attributes++] = &a->attr;
data->num_sensors++; sensor->next = data->sensors;
data->sensors = sensor;
return sensor; return sensor;
} }
...@@ -965,7 +961,6 @@ static void pmbus_find_max_attr(struct i2c_client *client, ...@@ -965,7 +961,6 @@ static void pmbus_find_max_attr(struct i2c_client *client,
max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP;
} }
} }
data->max_sensors = max_sensors;
data->max_attributes = max_sensors + max_booleans + max_labels; data->max_attributes = max_sensors + max_booleans + max_labels;
} }
...@@ -1031,6 +1026,8 @@ static int pmbus_add_limit_attrs(struct i2c_client *client, ...@@ -1031,6 +1026,8 @@ static int pmbus_add_limit_attrs(struct i2c_client *client,
page, l->reg, attr->class, page, l->reg, attr->class,
attr->update || l->update, attr->update || l->update,
false); false);
if (!curr)
return -ENOMEM;
if (l->sbit && (info->func[page] & attr->sfunc)) { if (l->sbit && (info->func[page] & attr->sfunc)) {
ret = pmbus_add_boolean(data, name, ret = pmbus_add_boolean(data, name,
l->alarm, index, l->alarm, index,
...@@ -1067,6 +1064,8 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client, ...@@ -1067,6 +1064,8 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
} }
base = pmbus_add_sensor(data, name, "input", index, page, attr->reg, base = pmbus_add_sensor(data, name, "input", index, page, attr->reg,
attr->class, true, true); attr->class, true, true);
if (!base)
return -ENOMEM;
if (attr->sfunc) { if (attr->sfunc) {
ret = pmbus_add_limit_attrs(client, data, info, name, ret = pmbus_add_limit_attrs(client, data, info, name,
index, page, base, attr); index, page, base, attr);
...@@ -1605,9 +1604,10 @@ static int pmbus_add_fan_attributes(struct i2c_client *client, ...@@ -1605,9 +1604,10 @@ static int pmbus_add_fan_attributes(struct i2c_client *client,
(!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4)))))
continue; continue;
pmbus_add_sensor(data, "fan", "input", index, page, if (pmbus_add_sensor(data, "fan", "input", index,
pmbus_fan_registers[f], PSC_FAN, true, page, pmbus_fan_registers[f],
true); PSC_FAN, true, true) == NULL)
return -ENOMEM;
/* /*
* Each fan status register covers multiple fans, * Each fan status register covers multiple fans,
...@@ -1770,11 +1770,6 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, ...@@ -1770,11 +1770,6 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
return ret; return ret;
} }
data->sensors = devm_kzalloc(dev, sizeof(struct pmbus_sensor)
* data->max_sensors, GFP_KERNEL);
if (!data->sensors)
return -ENOMEM;
data->attributes = devm_kzalloc(dev, sizeof(struct attribute *) data->attributes = devm_kzalloc(dev, sizeof(struct attribute *)
* data->max_attributes, GFP_KERNEL); * data->max_attributes, GFP_KERNEL);
if (!data->attributes) if (!data->attributes)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment