From e1e081a7e3ae7c2390889688b4f8a0c7dbb6bb6b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 20 Jan 2013 12:01:41 -0800 Subject: 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: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 63 ++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index d1792d7195b..3782fda21c8 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -85,8 +85,9 @@ #define PMBUS_NAME_SIZE 24 struct pmbus_sensor { + struct pmbus_sensor *next; char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ - struct sensor_device_attribute attribute; + struct device_attribute attribute; u8 page; /* page number */ u16 reg; /* register */ enum pmbus_sensor_classes class; /* sensor class */ @@ -94,6 +95,8 @@ struct pmbus_sensor { int data; /* Sensor data. Negative if there was a read error */ }; +#define to_pmbus_sensor(_attr) \ + container_of(_attr, struct pmbus_sensor, attribute) struct pmbus_boolean { char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ @@ -127,11 +130,6 @@ struct pmbus_data { struct attribute **attributes; struct attribute_group group; - /* - * Sensors cover both sensor and limit registers. - */ - int max_sensors; - int num_sensors; struct pmbus_sensor *sensors; struct mutex update_lock; @@ -361,6 +359,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct pmbus_data *data = i2c_get_clientdata(client); const struct pmbus_driver_info *info = data->info; + struct pmbus_sensor *sensor; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { @@ -410,9 +409,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) = _pmbus_read_byte_data(client, 0, PMBUS_STATUS_INPUT); - for (i = 0; i < data->num_sensors; i++) { - struct pmbus_sensor *sensor = &data->sensors[i]; - + for (sensor = data->sensors; sensor; sensor = sensor->next) { if (!data->valid || sensor->update) sensor->data = _pmbus_read_word_data(client, @@ -748,13 +745,11 @@ static ssize_t pmbus_show_boolean(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_sensor *sensor; + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); - sensor = &data->sensors[attr->index]; if (sensor->data < 0) return sensor->data; @@ -765,10 +760,9 @@ static ssize_t pmbus_set_sensor(struct device *dev, struct device_attribute *devattr, 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 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; long val = 0; int ret; @@ -783,7 +777,7 @@ static ssize_t pmbus_set_sensor(struct device *dev, if (ret < 0) rv = ret; else - data->sensors[attr->index].data = regval; + sensor->data = regval; mutex_unlock(&data->update_lock); return rv; } @@ -863,12 +857,13 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, bool update, bool readonly) { struct pmbus_sensor *sensor; - struct sensor_device_attribute *a; + struct device_attribute *a; - BUG_ON(data->num_sensors >= data->max_sensors || - data->num_attributes >= data->max_attributes); + BUG_ON(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; snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", @@ -877,12 +872,13 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, sensor->reg = reg; sensor->class = class; sensor->update = update; - pmbus_attr_init(a, sensor->name, - readonly ? S_IRUGO : S_IRUGO | S_IWUSR, - pmbus_show_sensor, pmbus_set_sensor, data->num_sensors); + pmbus_dev_attr_init(a, sensor->name, + readonly ? S_IRUGO : S_IRUGO | S_IWUSR, + pmbus_show_sensor, pmbus_set_sensor); - data->attributes[data->num_attributes++] = &a->dev_attr.attr; - data->num_sensors++; + data->attributes[data->num_attributes++] = &a->attr; + sensor->next = data->sensors; + data->sensors = sensor; return sensor; } @@ -965,7 +961,6 @@ static void pmbus_find_max_attr(struct i2c_client *client, max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; } } - data->max_sensors = max_sensors; data->max_attributes = max_sensors + max_booleans + max_labels; } @@ -1031,6 +1026,8 @@ static int pmbus_add_limit_attrs(struct i2c_client *client, page, l->reg, attr->class, attr->update || l->update, false); + if (!curr) + return -ENOMEM; if (l->sbit && (info->func[page] & attr->sfunc)) { ret = pmbus_add_boolean(data, name, l->alarm, index, @@ -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, attr->class, true, true); + if (!base) + return -ENOMEM; if (attr->sfunc) { ret = pmbus_add_limit_attrs(client, data, info, name, index, page, base, attr); @@ -1605,9 +1604,10 @@ static int pmbus_add_fan_attributes(struct i2c_client *client, (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) continue; - pmbus_add_sensor(data, "fan", "input", index, page, - pmbus_fan_registers[f], PSC_FAN, true, - true); + if (pmbus_add_sensor(data, "fan", "input", index, + page, pmbus_fan_registers[f], + PSC_FAN, true, true) == NULL) + return -ENOMEM; /* * 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, 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->max_attributes, GFP_KERNEL); if (!data->attributes) -- cgit v1.2.3-70-g09d2