aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/pmbus
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2013-01-20 11:13:21 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-02-06 12:58:01 -0500
commit0328461ea954cab13956aedb97f9686bfdfdf2a5 (patch)
treec9dd574505f76f5d44fdde2e3148f51a90febc33 /drivers/hwmon/pmbus
parentc2a583519dacf89fb4231e062e9804355ae2326b (diff)
hwmon: (pmbus) Simplify memory allocation for labels and booleans
Since memory is now allocated with dev_ functions, we no longer need to keep track of allocated memory. Memory allocation for booleans and labels can therefore be simplified substantially by allocating it only as needed. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/pmbus')
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c265
1 files changed, 149 insertions, 116 deletions
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 97eca0340dc0..0f51cd66ecfd 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -102,11 +102,14 @@ struct pmbus_boolean {
102 102
103struct pmbus_label { 103struct pmbus_label {
104 char name[PMBUS_NAME_SIZE]; /* sysfs label name */ 104 char name[PMBUS_NAME_SIZE]; /* sysfs label name */
105 struct sensor_device_attribute attribute; 105 struct device_attribute attribute;
106 char label[PMBUS_NAME_SIZE]; /* label */ 106 char label[PMBUS_NAME_SIZE]; /* label */
107}; 107};
108#define to_pmbus_label(_attr) \
109 container_of(_attr, struct pmbus_label, attribute)
108 110
109struct pmbus_data { 111struct pmbus_data {
112 struct device *dev;
110 struct device *hwmon_dev; 113 struct device *hwmon_dev;
111 114
112 u32 flags; /* from platform data */ 115 u32 flags; /* from platform data */
@@ -126,20 +129,6 @@ struct pmbus_data {
126 int max_sensors; 129 int max_sensors;
127 int num_sensors; 130 int num_sensors;
128 struct pmbus_sensor *sensors; 131 struct pmbus_sensor *sensors;
129 /*
130 * Booleans are used for alarms.
131 * Values are determined from status registers.
132 */
133 int max_booleans;
134 int num_booleans;
135 struct pmbus_boolean *booleans;
136 /*
137 * Labels are used to map generic names (e.g., "in1")
138 * to PMBus specific names (e.g., "vin" or "vout1").
139 */
140 int max_labels;
141 int num_labels;
142 struct pmbus_label *labels;
143 132
144 struct mutex update_lock; 133 struct mutex update_lock;
145 bool valid; 134 bool valid;
@@ -801,12 +790,26 @@ static ssize_t pmbus_set_sensor(struct device *dev,
801static ssize_t pmbus_show_label(struct device *dev, 790static ssize_t pmbus_show_label(struct device *dev,
802 struct device_attribute *da, char *buf) 791 struct device_attribute *da, char *buf)
803{ 792{
804 struct i2c_client *client = to_i2c_client(dev); 793 struct pmbus_label *label = to_pmbus_label(da);
805 struct pmbus_data *data = i2c_get_clientdata(client); 794
806 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 795 return snprintf(buf, PAGE_SIZE, "%s\n", label->label);
796}
807 797
808 return snprintf(buf, PAGE_SIZE, "%s\n", 798static void pmbus_dev_attr_init(struct device_attribute *dev_attr,
809 data->labels[attr->index].label); 799 const char *name,
800 umode_t mode,
801 ssize_t (*show)(struct device *dev,
802 struct device_attribute *attr,
803 char *buf),
804 ssize_t (*store)(struct device *dev,
805 struct device_attribute *attr,
806 const char *buf, size_t count))
807{
808 sysfs_attr_init(&dev_attr->attr);
809 dev_attr->attr.name = name;
810 dev_attr->attr.mode = mode;
811 dev_attr->show = show;
812 dev_attr->store = store;
810} 813}
811 814
812static void pmbus_attr_init(struct sensor_device_attribute *a, 815static void pmbus_attr_init(struct sensor_device_attribute *a,
@@ -820,25 +823,23 @@ static void pmbus_attr_init(struct sensor_device_attribute *a,
820 const char *buf, size_t count), 823 const char *buf, size_t count),
821 int idx) 824 int idx)
822{ 825{
823 sysfs_attr_init(&a->dev_attr.attr); 826 pmbus_dev_attr_init(&a->dev_attr, name, mode, show, store);
824 a->dev_attr.attr.name = name;
825 a->dev_attr.attr.mode = mode;
826 a->dev_attr.show = show;
827 a->dev_attr.store = store;
828 a->index = idx; 827 a->index = idx;
829} 828}
830 829
831static void pmbus_add_boolean(struct pmbus_data *data, 830static int pmbus_add_boolean(struct pmbus_data *data,
832 const char *name, const char *type, int seq, 831 const char *name, const char *type, int seq,
833 int idx) 832 int idx)
834{ 833{
835 struct pmbus_boolean *boolean; 834 struct pmbus_boolean *boolean;
836 struct sensor_device_attribute *a; 835 struct sensor_device_attribute *a;
837 836
838 BUG_ON(data->num_booleans >= data->max_booleans || 837 BUG_ON(data->num_attributes >= data->max_attributes);
839 data->num_attributes >= data->max_attributes); 838
839 boolean = devm_kzalloc(data->dev, sizeof(*boolean), GFP_KERNEL);
840 if (!boolean)
841 return -ENOMEM;
840 842
841 boolean = &data->booleans[data->num_booleans];
842 a = &boolean->attribute; 843 a = &boolean->attribute;
843 844
844 snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s", 845 snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s",
@@ -846,22 +847,23 @@ static void pmbus_add_boolean(struct pmbus_data *data,
846 pmbus_attr_init(a, boolean->name, S_IRUGO, pmbus_show_boolean, NULL, 847 pmbus_attr_init(a, boolean->name, S_IRUGO, pmbus_show_boolean, NULL,
847 idx); 848 idx);
848 data->attributes[data->num_attributes++] = &a->dev_attr.attr; 849 data->attributes[data->num_attributes++] = &a->dev_attr.attr;
849 data->num_booleans++; 850
851 return 0;
850} 852}
851 853
852static void pmbus_add_boolean_reg(struct pmbus_data *data, 854static int pmbus_add_boolean_reg(struct pmbus_data *data,
853 const char *name, const char *type, 855 const char *name, const char *type,
854 int seq, int reg, int bit) 856 int seq, int reg, int bit)
855{ 857{
856 pmbus_add_boolean(data, name, type, seq, (reg << 8) | bit); 858 return pmbus_add_boolean(data, name, type, seq, (reg << 8) | bit);
857} 859}
858 860
859static void pmbus_add_boolean_cmp(struct pmbus_data *data, 861static int pmbus_add_boolean_cmp(struct pmbus_data *data,
860 const char *name, const char *type, 862 const char *name, const char *type,
861 int seq, int i1, int i2, int reg, int mask) 863 int seq, int i1, int i2, int reg, int mask)
862{ 864{
863 pmbus_add_boolean(data, name, type, seq, 865 return pmbus_add_boolean(data, name, type, seq,
864 (i1 << 24) | (i2 << 16) | (reg << 8) | mask); 866 (i1 << 24) | (i2 << 16) | (reg << 8) | mask);
865} 867}
866 868
867static void pmbus_add_sensor(struct pmbus_data *data, 869static void pmbus_add_sensor(struct pmbus_data *data,
@@ -892,17 +894,19 @@ static void pmbus_add_sensor(struct pmbus_data *data,
892 data->num_sensors++; 894 data->num_sensors++;
893} 895}
894 896
895static void pmbus_add_label(struct pmbus_data *data, 897static int pmbus_add_label(struct pmbus_data *data,
896 const char *name, int seq, 898 const char *name, int seq,
897 const char *lstring, int index) 899 const char *lstring, int index)
898{ 900{
899 struct pmbus_label *label; 901 struct pmbus_label *label;
900 struct sensor_device_attribute *a; 902 struct device_attribute *a;
901 903
902 BUG_ON(data->num_labels >= data->max_labels || 904 BUG_ON(data->num_attributes >= data->max_attributes);
903 data->num_attributes >= data->max_attributes); 905
906 label = devm_kzalloc(data->dev, sizeof(*label), GFP_KERNEL);
907 if (!label)
908 return -ENOMEM;
904 909
905 label = &data->labels[data->num_labels];
906 a = &label->attribute; 910 a = &label->attribute;
907 911
908 snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); 912 snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq);
@@ -912,10 +916,9 @@ static void pmbus_add_label(struct pmbus_data *data,
912 snprintf(label->label, sizeof(label->label), "%s%d", lstring, 916 snprintf(label->label, sizeof(label->label), "%s%d", lstring,
913 index); 917 index);
914 918
915 pmbus_attr_init(a, label->name, S_IRUGO, pmbus_show_label, NULL, 919 pmbus_dev_attr_init(a, label->name, S_IRUGO, pmbus_show_label, NULL);
916 data->num_labels); 920 data->attributes[data->num_attributes++] = &a->attr;
917 data->attributes[data->num_attributes++] = &a->dev_attr.attr; 921 return 0;
918 data->num_labels++;
919} 922}
920 923
921/* 924/*
@@ -970,8 +973,6 @@ static void pmbus_find_max_attr(struct i2c_client *client,
970 } 973 }
971 } 974 }
972 data->max_sensors = max_sensors; 975 data->max_sensors = max_sensors;
973 data->max_booleans = max_booleans;
974 data->max_labels = max_labels;
975 data->max_attributes = max_sensors + max_booleans + max_labels; 976 data->max_attributes = max_sensors + max_booleans + max_labels;
976} 977}
977 978
@@ -1015,18 +1016,21 @@ struct pmbus_sensor_attr {
1015/* 1016/*
1016 * Add a set of limit attributes and, if supported, the associated 1017 * Add a set of limit attributes and, if supported, the associated
1017 * alarm attributes. 1018 * alarm attributes.
1019 * returns 0 if no alarm register found, 1 if an alarm register was found,
1020 * < 0 on errors.
1018 */ 1021 */
1019static bool pmbus_add_limit_attrs(struct i2c_client *client, 1022static int pmbus_add_limit_attrs(struct i2c_client *client,
1020 struct pmbus_data *data, 1023 struct pmbus_data *data,
1021 const struct pmbus_driver_info *info, 1024 const struct pmbus_driver_info *info,
1022 const char *name, int index, int page, 1025 const char *name, int index, int page,
1023 int cbase, 1026 int cbase,
1024 const struct pmbus_sensor_attr *attr) 1027 const struct pmbus_sensor_attr *attr)
1025{ 1028{
1026 const struct pmbus_limit_attr *l = attr->limit; 1029 const struct pmbus_limit_attr *l = attr->limit;
1027 int nlimit = attr->nlimit; 1030 int nlimit = attr->nlimit;
1028 bool have_alarm = false; 1031 int have_alarm = 0;
1029 int i, cindex; 1032 int i, cindex;
1033 int ret;
1030 1034
1031 for (i = 0; i < nlimit; i++) { 1035 for (i = 0; i < nlimit; i++) {
1032 if (pmbus_check_word_register(client, page, l->reg)) { 1036 if (pmbus_check_word_register(client, page, l->reg)) {
@@ -1037,17 +1041,21 @@ static bool pmbus_add_limit_attrs(struct i2c_client *client,
1037 false); 1041 false);
1038 if (l->sbit && (info->func[page] & attr->sfunc)) { 1042 if (l->sbit && (info->func[page] & attr->sfunc)) {
1039 if (attr->compare) { 1043 if (attr->compare) {
1040 pmbus_add_boolean_cmp(data, name, 1044 ret = pmbus_add_boolean_cmp(data, name,
1041 l->alarm, index, 1045 l->alarm, index,
1042 l->low ? cindex : cbase, 1046 l->low ? cindex : cbase,
1043 l->low ? cbase : cindex, 1047 l->low ? cbase : cindex,
1044 attr->sbase + page, l->sbit); 1048 attr->sbase + page, l->sbit);
1049 if (ret)
1050 return ret;
1045 } else { 1051 } else {
1046 pmbus_add_boolean_reg(data, name, 1052 ret = pmbus_add_boolean_reg(data, name,
1047 l->alarm, index, 1053 l->alarm, index,
1048 attr->sbase + page, l->sbit); 1054 attr->sbase + page, l->sbit);
1055 if (ret)
1056 return ret;
1049 } 1057 }
1050 have_alarm = true; 1058 have_alarm = 1;
1051 } 1059 }
1052 } 1060 }
1053 l++; 1061 l++;
@@ -1055,45 +1063,56 @@ static bool pmbus_add_limit_attrs(struct i2c_client *client,
1055 return have_alarm; 1063 return have_alarm;
1056} 1064}
1057 1065
1058static void pmbus_add_sensor_attrs_one(struct i2c_client *client, 1066static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
1059 struct pmbus_data *data, 1067 struct pmbus_data *data,
1060 const struct pmbus_driver_info *info, 1068 const struct pmbus_driver_info *info,
1061 const char *name, 1069 const char *name,
1062 int index, int page, 1070 int index, int page,
1063 const struct pmbus_sensor_attr *attr) 1071 const struct pmbus_sensor_attr *attr)
1064{ 1072{
1065 bool have_alarm;
1066 int cbase = data->num_sensors; 1073 int cbase = data->num_sensors;
1074 int ret;
1067 1075
1068 if (attr->label) 1076 if (attr->label) {
1069 pmbus_add_label(data, name, index, attr->label, 1077 ret = pmbus_add_label(data, name, index, attr->label,
1070 attr->paged ? page + 1 : 0); 1078 attr->paged ? page + 1 : 0);
1079 if (ret)
1080 return ret;
1081 }
1071 pmbus_add_sensor(data, name, "input", index, page, attr->reg, 1082 pmbus_add_sensor(data, name, "input", index, page, attr->reg,
1072 attr->class, true, true); 1083 attr->class, true, true);
1073 if (attr->sfunc) { 1084 if (attr->sfunc) {
1074 have_alarm = pmbus_add_limit_attrs(client, data, info, name, 1085 ret = pmbus_add_limit_attrs(client, data, info, name,
1075 index, page, cbase, attr); 1086 index, page, cbase, attr);
1087 if (ret < 0)
1088 return ret;
1076 /* 1089 /*
1077 * Add generic alarm attribute only if there are no individual 1090 * Add generic alarm attribute only if there are no individual
1078 * alarm attributes, if there is a global alarm bit, and if 1091 * alarm attributes, if there is a global alarm bit, and if
1079 * the generic status register for this page is accessible. 1092 * the generic status register for this page is accessible.
1080 */ 1093 */
1081 if (!have_alarm && attr->gbit && 1094 if (!ret && attr->gbit &&
1082 pmbus_check_byte_register(client, page, PMBUS_STATUS_BYTE)) 1095 pmbus_check_byte_register(client, page,
1083 pmbus_add_boolean_reg(data, name, "alarm", index, 1096 PMBUS_STATUS_BYTE)) {
1084 PB_STATUS_BASE + page, 1097 ret = pmbus_add_boolean_reg(data, name, "alarm", index,
1085 attr->gbit); 1098 PB_STATUS_BASE + page,
1099 attr->gbit);
1100 if (ret)
1101 return ret;
1102 }
1086 } 1103 }
1104 return 0;
1087} 1105}
1088 1106
1089static void pmbus_add_sensor_attrs(struct i2c_client *client, 1107static int pmbus_add_sensor_attrs(struct i2c_client *client,
1090 struct pmbus_data *data, 1108 struct pmbus_data *data,
1091 const char *name, 1109 const char *name,
1092 const struct pmbus_sensor_attr *attrs, 1110 const struct pmbus_sensor_attr *attrs,
1093 int nattrs) 1111 int nattrs)
1094{ 1112{
1095 const struct pmbus_driver_info *info = data->info; 1113 const struct pmbus_driver_info *info = data->info;
1096 int index, i; 1114 int index, i;
1115 int ret;
1097 1116
1098 index = 1; 1117 index = 1;
1099 for (i = 0; i < nattrs; i++) { 1118 for (i = 0; i < nattrs; i++) {
@@ -1103,12 +1122,16 @@ static void pmbus_add_sensor_attrs(struct i2c_client *client,
1103 for (page = 0; page < pages; page++) { 1122 for (page = 0; page < pages; page++) {
1104 if (!(info->func[page] & attrs->func)) 1123 if (!(info->func[page] & attrs->func))
1105 continue; 1124 continue;
1106 pmbus_add_sensor_attrs_one(client, data, info, name, 1125 ret = pmbus_add_sensor_attrs_one(client, data, info,
1107 index, page, attrs); 1126 name, index, page,
1127 attrs);
1128 if (ret)
1129 return ret;
1108 index++; 1130 index++;
1109 } 1131 }
1110 attrs++; 1132 attrs++;
1111 } 1133 }
1134 return 0;
1112} 1135}
1113 1136
1114static const struct pmbus_limit_attr vin_limit_attrs[] = { 1137static const struct pmbus_limit_attr vin_limit_attrs[] = {
@@ -1563,12 +1586,13 @@ static const u32 pmbus_fan_status_flags[] = {
1563}; 1586};
1564 1587
1565/* Fans */ 1588/* Fans */
1566static void pmbus_add_fan_attributes(struct i2c_client *client, 1589static int pmbus_add_fan_attributes(struct i2c_client *client,
1567 struct pmbus_data *data) 1590 struct pmbus_data *data)
1568{ 1591{
1569 const struct pmbus_driver_info *info = data->info; 1592 const struct pmbus_driver_info *info = data->info;
1570 int index = 1; 1593 int index = 1;
1571 int page; 1594 int page;
1595 int ret;
1572 1596
1573 for (page = 0; page < info->pages; page++) { 1597 for (page = 0; page < info->pages; page++) {
1574 int f; 1598 int f;
@@ -1611,39 +1635,55 @@ static void pmbus_add_fan_attributes(struct i2c_client *client,
1611 base = PB_STATUS_FAN34_BASE + page; 1635 base = PB_STATUS_FAN34_BASE + page;
1612 else 1636 else
1613 base = PB_STATUS_FAN_BASE + page; 1637 base = PB_STATUS_FAN_BASE + page;
1614 pmbus_add_boolean_reg(data, "fan", "alarm", 1638 ret = pmbus_add_boolean_reg(data, "fan",
1615 index, base, 1639 "alarm", index, base,
1616 PB_FAN_FAN1_WARNING >> (f & 1)); 1640 PB_FAN_FAN1_WARNING >> (f & 1));
1617 pmbus_add_boolean_reg(data, "fan", "fault", 1641 if (ret)
1618 index, base, 1642 return ret;
1643 ret = pmbus_add_boolean_reg(data, "fan",
1644 "fault", index, base,
1619 PB_FAN_FAN1_FAULT >> (f & 1)); 1645 PB_FAN_FAN1_FAULT >> (f & 1));
1646 if (ret)
1647 return ret;
1620 } 1648 }
1621 index++; 1649 index++;
1622 } 1650 }
1623 } 1651 }
1652 return 0;
1624} 1653}
1625 1654
1626static void pmbus_find_attributes(struct i2c_client *client, 1655static int pmbus_find_attributes(struct i2c_client *client,
1627 struct pmbus_data *data) 1656 struct pmbus_data *data)
1628{ 1657{
1658 int ret;
1659
1629 /* Voltage sensors */ 1660 /* Voltage sensors */
1630 pmbus_add_sensor_attrs(client, data, "in", voltage_attributes, 1661 ret = pmbus_add_sensor_attrs(client, data, "in", voltage_attributes,
1631 ARRAY_SIZE(voltage_attributes)); 1662 ARRAY_SIZE(voltage_attributes));
1663 if (ret)
1664 return ret;
1632 1665
1633 /* Current sensors */ 1666 /* Current sensors */
1634 pmbus_add_sensor_attrs(client, data, "curr", current_attributes, 1667 ret = pmbus_add_sensor_attrs(client, data, "curr", current_attributes,
1635 ARRAY_SIZE(current_attributes)); 1668 ARRAY_SIZE(current_attributes));
1669 if (ret)
1670 return ret;
1636 1671
1637 /* Power sensors */ 1672 /* Power sensors */
1638 pmbus_add_sensor_attrs(client, data, "power", power_attributes, 1673 ret = pmbus_add_sensor_attrs(client, data, "power", power_attributes,
1639 ARRAY_SIZE(power_attributes)); 1674 ARRAY_SIZE(power_attributes));
1675 if (ret)
1676 return ret;
1640 1677
1641 /* Temperature sensors */ 1678 /* Temperature sensors */
1642 pmbus_add_sensor_attrs(client, data, "temp", temp_attributes, 1679 ret = pmbus_add_sensor_attrs(client, data, "temp", temp_attributes,
1643 ARRAY_SIZE(temp_attributes)); 1680 ARRAY_SIZE(temp_attributes));
1681 if (ret)
1682 return ret;
1644 1683
1645 /* Fans */ 1684 /* Fans */
1646 pmbus_add_fan_attributes(client, data); 1685 ret = pmbus_add_fan_attributes(client, data);
1686 return ret;
1647} 1687}
1648 1688
1649/* 1689/*
@@ -1710,6 +1750,7 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
1710 1750
1711 i2c_set_clientdata(client, data); 1751 i2c_set_clientdata(client, data);
1712 mutex_init(&data->update_lock); 1752 mutex_init(&data->update_lock);
1753 data->dev = dev;
1713 1754
1714 /* Bail out if PMBus status register does not exist. */ 1755 /* Bail out if PMBus status register does not exist. */
1715 if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) { 1756 if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) {
@@ -1747,22 +1788,14 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
1747 if (!data->sensors) 1788 if (!data->sensors)
1748 return -ENOMEM; 1789 return -ENOMEM;
1749 1790
1750 data->booleans = devm_kzalloc(dev, sizeof(struct pmbus_boolean)
1751 * data->max_booleans, GFP_KERNEL);
1752 if (!data->booleans)
1753 return -ENOMEM;
1754
1755 data->labels = devm_kzalloc(dev, sizeof(struct pmbus_label)
1756 * data->max_labels, GFP_KERNEL);
1757 if (!data->labels)
1758 return -ENOMEM;
1759
1760 data->attributes = devm_kzalloc(dev, sizeof(struct attribute *) 1791 data->attributes = devm_kzalloc(dev, sizeof(struct attribute *)
1761 * data->max_attributes, GFP_KERNEL); 1792 * data->max_attributes, GFP_KERNEL);
1762 if (!data->attributes) 1793 if (!data->attributes)
1763 return -ENOMEM; 1794 return -ENOMEM;
1764 1795
1765 pmbus_find_attributes(client, data); 1796 ret = pmbus_find_attributes(client, data);
1797 if (ret)
1798 return ret;
1766 1799
1767 /* 1800 /*
1768 * If there are no attributes, something is wrong. 1801 * If there are no attributes, something is wrong.