diff options
| author | Guenter Roeck <linux@roeck-us.net> | 2013-01-20 15:01:41 -0500 |
|---|---|---|
| committer | Guenter Roeck <linux@roeck-us.net> | 2013-02-06 12:58:02 -0500 |
| commit | e1e081a7e3ae7c2390889688b4f8a0c7dbb6bb6b (patch) | |
| tree | be578669a53eb43515d22eef2576649440841c92 /drivers/hwmon/pmbus | |
| parent | 663834f3b796c0a118b84cf18c759f2c2aa537b6 (diff) | |
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 <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/pmbus')
| -rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index d1792d7195bf..3782fda21c8b 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
| @@ -85,8 +85,9 @@ | |||
| 85 | #define PMBUS_NAME_SIZE 24 | 85 | #define PMBUS_NAME_SIZE 24 |
| 86 | 86 | ||
| 87 | struct pmbus_sensor { | 87 | struct pmbus_sensor { |
| 88 | struct pmbus_sensor *next; | ||
| 88 | char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ | 89 | char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ |
| 89 | struct sensor_device_attribute attribute; | 90 | struct device_attribute attribute; |
| 90 | u8 page; /* page number */ | 91 | u8 page; /* page number */ |
| 91 | u16 reg; /* register */ | 92 | u16 reg; /* register */ |
| 92 | enum pmbus_sensor_classes class; /* sensor class */ | 93 | enum pmbus_sensor_classes class; /* sensor class */ |
| @@ -94,6 +95,8 @@ struct pmbus_sensor { | |||
| 94 | int data; /* Sensor data. | 95 | int data; /* Sensor data. |
| 95 | Negative if there was a read error */ | 96 | Negative if there was a read error */ |
| 96 | }; | 97 | }; |
| 98 | #define to_pmbus_sensor(_attr) \ | ||
| 99 | container_of(_attr, struct pmbus_sensor, attribute) | ||
| 97 | 100 | ||
| 98 | struct pmbus_boolean { | 101 | struct pmbus_boolean { |
| 99 | char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ | 102 | char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ |
| @@ -127,11 +130,6 @@ struct pmbus_data { | |||
| 127 | struct attribute **attributes; | 130 | struct attribute **attributes; |
| 128 | struct attribute_group group; | 131 | struct attribute_group group; |
| 129 | 132 | ||
| 130 | /* | ||
| 131 | * Sensors cover both sensor and limit registers. | ||
| 132 | */ | ||
| 133 | int max_sensors; | ||
| 134 | int num_sensors; | ||
| 135 | struct pmbus_sensor *sensors; | 133 | struct pmbus_sensor *sensors; |
| 136 | 134 | ||
| 137 | struct mutex update_lock; | 135 | struct mutex update_lock; |
| @@ -361,6 +359,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) | |||
| 361 | struct i2c_client *client = to_i2c_client(dev); | 359 | struct i2c_client *client = to_i2c_client(dev); |
| 362 | struct pmbus_data *data = i2c_get_clientdata(client); | 360 | struct pmbus_data *data = i2c_get_clientdata(client); |
| 363 | const struct pmbus_driver_info *info = data->info; | 361 | const struct pmbus_driver_info *info = data->info; |
| 362 | struct pmbus_sensor *sensor; | ||
| 364 | 363 | ||
| 365 | mutex_lock(&data->update_lock); | 364 | mutex_lock(&data->update_lock); |
| 366 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 365 | 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 | = _pmbus_read_byte_data(client, 0, | 409 | = _pmbus_read_byte_data(client, 0, |
| 411 | PMBUS_STATUS_INPUT); | 410 | PMBUS_STATUS_INPUT); |
| 412 | 411 | ||
| 413 | for (i = 0; i < data->num_sensors; i++) { | 412 | for (sensor = data->sensors; sensor; sensor = sensor->next) { |
| 414 | struct pmbus_sensor *sensor = &data->sensors[i]; | ||
| 415 | |||
| 416 | if (!data->valid || sensor->update) | 413 | if (!data->valid || sensor->update) |
| 417 | sensor->data | 414 | sensor->data |
| 418 | = _pmbus_read_word_data(client, | 415 | = _pmbus_read_word_data(client, |
| @@ -748,13 +745,11 @@ static ssize_t pmbus_show_boolean(struct device *dev, | |||
| 748 | } | 745 | } |
| 749 | 746 | ||
| 750 | static ssize_t pmbus_show_sensor(struct device *dev, | 747 | static ssize_t pmbus_show_sensor(struct device *dev, |
| 751 | struct device_attribute *da, char *buf) | 748 | struct device_attribute *devattr, char *buf) |
| 752 | { | 749 | { |
| 753 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 754 | struct pmbus_data *data = pmbus_update_device(dev); | 750 | struct pmbus_data *data = pmbus_update_device(dev); |
| 755 | struct pmbus_sensor *sensor; | 751 | struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); |
| 756 | 752 | ||
| 757 | sensor = &data->sensors[attr->index]; | ||
| 758 | if (sensor->data < 0) | 753 | if (sensor->data < 0) |
| 759 | return sensor->data; | 754 | return sensor->data; |
| 760 | 755 | ||
| @@ -765,10 +760,9 @@ static ssize_t pmbus_set_sensor(struct device *dev, | |||
| 765 | struct device_attribute *devattr, | 760 | struct device_attribute *devattr, |
| 766 | const char *buf, size_t count) | 761 | const char *buf, size_t count) |
| 767 | { | 762 | { |
| 768 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 769 | struct i2c_client *client = to_i2c_client(dev); | 763 | struct i2c_client *client = to_i2c_client(dev); |
| 770 | struct pmbus_data *data = i2c_get_clientdata(client); | 764 | struct pmbus_data *data = i2c_get_clientdata(client); |
| 771 | struct pmbus_sensor *sensor = &data->sensors[attr->index]; | 765 | struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); |
| 772 | ssize_t rv = count; | 766 | ssize_t rv = count; |
| 773 | long val = 0; | 767 | long val = 0; |
| 774 | int ret; | 768 | int ret; |
| @@ -783,7 +777,7 @@ static ssize_t pmbus_set_sensor(struct device *dev, | |||
| 783 | if (ret < 0) | 777 | if (ret < 0) |
| 784 | rv = ret; | 778 | rv = ret; |
| 785 | else | 779 | else |
| 786 | data->sensors[attr->index].data = regval; | 780 | sensor->data = regval; |
| 787 | mutex_unlock(&data->update_lock); | 781 | mutex_unlock(&data->update_lock); |
| 788 | return rv; | 782 | return rv; |
| 789 | } | 783 | } |
| @@ -863,12 +857,13 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, | |||
| 863 | bool update, bool readonly) | 857 | bool update, bool readonly) |
| 864 | { | 858 | { |
| 865 | struct pmbus_sensor *sensor; | 859 | struct pmbus_sensor *sensor; |
| 866 | struct sensor_device_attribute *a; | 860 | struct device_attribute *a; |
| 867 | 861 | ||
| 868 | BUG_ON(data->num_sensors >= data->max_sensors || | 862 | BUG_ON(data->num_attributes >= data->max_attributes); |
| 869 | data->num_attributes >= data->max_attributes); | ||
| 870 | 863 | ||
| 871 | sensor = &data->sensors[data->num_sensors]; | 864 | sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); |
| 865 | if (!sensor) | ||
| 866 | return NULL; | ||
| 872 | a = &sensor->attribute; | 867 | a = &sensor->attribute; |
| 873 | 868 | ||
| 874 | snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", | 869 | 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 | sensor->reg = reg; | 872 | sensor->reg = reg; |
| 878 | sensor->class = class; | 873 | sensor->class = class; |
| 879 | sensor->update = update; | 874 | sensor->update = update; |
| 880 | pmbus_attr_init(a, sensor->name, | 875 | pmbus_dev_attr_init(a, sensor->name, |
| 881 | readonly ? S_IRUGO : S_IRUGO | S_IWUSR, | 876 | readonly ? S_IRUGO : S_IRUGO | S_IWUSR, |
| 882 | pmbus_show_sensor, pmbus_set_sensor, data->num_sensors); | 877 | pmbus_show_sensor, pmbus_set_sensor); |
| 883 | 878 | ||
| 884 | data->attributes[data->num_attributes++] = &a->dev_attr.attr; | 879 | data->attributes[data->num_attributes++] = &a->attr; |
| 885 | data->num_sensors++; | 880 | sensor->next = data->sensors; |
| 881 | data->sensors = sensor; | ||
| 886 | 882 | ||
| 887 | return sensor; | 883 | return sensor; |
| 888 | } | 884 | } |
| @@ -965,7 +961,6 @@ static void pmbus_find_max_attr(struct i2c_client *client, | |||
| 965 | max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; | 961 | max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; |
| 966 | } | 962 | } |
| 967 | } | 963 | } |
| 968 | data->max_sensors = max_sensors; | ||
| 969 | data->max_attributes = max_sensors + max_booleans + max_labels; | 964 | data->max_attributes = max_sensors + max_booleans + max_labels; |
| 970 | } | 965 | } |
| 971 | 966 | ||
| @@ -1031,6 +1026,8 @@ static int pmbus_add_limit_attrs(struct i2c_client *client, | |||
| 1031 | page, l->reg, attr->class, | 1026 | page, l->reg, attr->class, |
| 1032 | attr->update || l->update, | 1027 | attr->update || l->update, |
| 1033 | false); | 1028 | false); |
| 1029 | if (!curr) | ||
| 1030 | return -ENOMEM; | ||
| 1034 | if (l->sbit && (info->func[page] & attr->sfunc)) { | 1031 | if (l->sbit && (info->func[page] & attr->sfunc)) { |
| 1035 | ret = pmbus_add_boolean(data, name, | 1032 | ret = pmbus_add_boolean(data, name, |
| 1036 | l->alarm, index, | 1033 | l->alarm, index, |
| @@ -1067,6 +1064,8 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client, | |||
| 1067 | } | 1064 | } |
| 1068 | base = pmbus_add_sensor(data, name, "input", index, page, attr->reg, | 1065 | base = pmbus_add_sensor(data, name, "input", index, page, attr->reg, |
| 1069 | attr->class, true, true); | 1066 | attr->class, true, true); |
| 1067 | if (!base) | ||
| 1068 | return -ENOMEM; | ||
| 1070 | if (attr->sfunc) { | 1069 | if (attr->sfunc) { |
| 1071 | ret = pmbus_add_limit_attrs(client, data, info, name, | 1070 | ret = pmbus_add_limit_attrs(client, data, info, name, |
| 1072 | index, page, base, attr); | 1071 | index, page, base, attr); |
| @@ -1605,9 +1604,10 @@ static int pmbus_add_fan_attributes(struct i2c_client *client, | |||
| 1605 | (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) | 1604 | (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) |
| 1606 | continue; | 1605 | continue; |
| 1607 | 1606 | ||
| 1608 | pmbus_add_sensor(data, "fan", "input", index, page, | 1607 | if (pmbus_add_sensor(data, "fan", "input", index, |
| 1609 | pmbus_fan_registers[f], PSC_FAN, true, | 1608 | page, pmbus_fan_registers[f], |
| 1610 | true); | 1609 | PSC_FAN, true, true) == NULL) |
| 1610 | return -ENOMEM; | ||
| 1611 | 1611 | ||
| 1612 | /* | 1612 | /* |
| 1613 | * Each fan status register covers multiple fans, | 1613 | * 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 | return ret; | 1770 | return ret; |
| 1771 | } | 1771 | } |
| 1772 | 1772 | ||
| 1773 | data->sensors = devm_kzalloc(dev, sizeof(struct pmbus_sensor) | ||
| 1774 | * data->max_sensors, GFP_KERNEL); | ||
| 1775 | if (!data->sensors) | ||
| 1776 | return -ENOMEM; | ||
| 1777 | |||
| 1778 | data->attributes = devm_kzalloc(dev, sizeof(struct attribute *) | 1773 | data->attributes = devm_kzalloc(dev, sizeof(struct attribute *) |
| 1779 | * data->max_attributes, GFP_KERNEL); | 1774 | * data->max_attributes, GFP_KERNEL); |
| 1780 | if (!data->attributes) | 1775 | if (!data->attributes) |
