Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (applesmc) Add temperature sensor labels to sysfs interface

The Apple SMC uses a systematic labeling scheme for the hardware
temperature sensors. This scheme is currently hidden from
userland. Since the sensor set, and consequently the numbering,
differs between models, an extensive database of configurations is
required for an application such as fan control. This patch adds the
SMC labels to the hwmon sysfs interface, allowing applications to use
the sensors more intelligibly.

[rydberg@euromail.se: fixed error handling]
Signed-off-by: Alex Murray <murray.alex@gmail.com>
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Jean Delvare <khali@linux-fr.org>

authored by

Alex Murray and committed by
Jean Delvare
fa5575cf 405eaa1c

+147 -1
+147 -1
drivers/hwmon/applesmc.c
··· 660 660 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right); 661 661 } 662 662 663 + /* Displays sensor key as label */ 664 + static ssize_t applesmc_show_sensor_label(struct device *dev, 665 + struct device_attribute *devattr, char *sysfsbuf) 666 + { 667 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 668 + const char *key = 669 + temperature_sensors_sets[applesmc_temperature_set][attr->index]; 670 + 671 + return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); 672 + } 673 + 663 674 /* Displays degree Celsius * 1000 */ 664 675 static ssize_t applesmc_show_temperature(struct device *dev, 665 676 struct device_attribute *devattr, char *sysfsbuf) ··· 1138 1127 /* 1139 1128 * Temperature sensors sysfs entries. 1140 1129 */ 1130 + static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, 1131 + applesmc_show_sensor_label, NULL, 0); 1132 + static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, 1133 + applesmc_show_sensor_label, NULL, 1); 1134 + static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, 1135 + applesmc_show_sensor_label, NULL, 2); 1136 + static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, 1137 + applesmc_show_sensor_label, NULL, 3); 1138 + static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, 1139 + applesmc_show_sensor_label, NULL, 4); 1140 + static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, 1141 + applesmc_show_sensor_label, NULL, 5); 1142 + static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, 1143 + applesmc_show_sensor_label, NULL, 6); 1144 + static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, 1145 + applesmc_show_sensor_label, NULL, 7); 1146 + static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, 1147 + applesmc_show_sensor_label, NULL, 8); 1148 + static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO, 1149 + applesmc_show_sensor_label, NULL, 9); 1150 + static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO, 1151 + applesmc_show_sensor_label, NULL, 10); 1152 + static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO, 1153 + applesmc_show_sensor_label, NULL, 11); 1154 + static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO, 1155 + applesmc_show_sensor_label, NULL, 12); 1156 + static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO, 1157 + applesmc_show_sensor_label, NULL, 13); 1158 + static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO, 1159 + applesmc_show_sensor_label, NULL, 14); 1160 + static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO, 1161 + applesmc_show_sensor_label, NULL, 15); 1162 + static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO, 1163 + applesmc_show_sensor_label, NULL, 16); 1164 + static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO, 1165 + applesmc_show_sensor_label, NULL, 17); 1166 + static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO, 1167 + applesmc_show_sensor_label, NULL, 18); 1168 + static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO, 1169 + applesmc_show_sensor_label, NULL, 19); 1170 + static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO, 1171 + applesmc_show_sensor_label, NULL, 20); 1172 + static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO, 1173 + applesmc_show_sensor_label, NULL, 21); 1174 + static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO, 1175 + applesmc_show_sensor_label, NULL, 22); 1176 + static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO, 1177 + applesmc_show_sensor_label, NULL, 23); 1178 + static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO, 1179 + applesmc_show_sensor_label, NULL, 24); 1180 + static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO, 1181 + applesmc_show_sensor_label, NULL, 25); 1182 + static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO, 1183 + applesmc_show_sensor_label, NULL, 26); 1184 + static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO, 1185 + applesmc_show_sensor_label, NULL, 27); 1186 + static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO, 1187 + applesmc_show_sensor_label, NULL, 28); 1188 + static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO, 1189 + applesmc_show_sensor_label, NULL, 29); 1190 + static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO, 1191 + applesmc_show_sensor_label, NULL, 30); 1192 + static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO, 1193 + applesmc_show_sensor_label, NULL, 31); 1194 + static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO, 1195 + applesmc_show_sensor_label, NULL, 32); 1196 + static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO, 1197 + applesmc_show_sensor_label, NULL, 33); 1198 + static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO, 1199 + applesmc_show_sensor_label, NULL, 34); 1200 + static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO, 1201 + applesmc_show_sensor_label, NULL, 35); 1202 + static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO, 1203 + applesmc_show_sensor_label, NULL, 36); 1204 + static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO, 1205 + applesmc_show_sensor_label, NULL, 37); 1206 + static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO, 1207 + applesmc_show_sensor_label, NULL, 38); 1208 + static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO, 1209 + applesmc_show_sensor_label, NULL, 39); 1141 1210 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, 1142 1211 applesmc_show_temperature, NULL, 0); 1143 1212 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, ··· 1299 1208 static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO, 1300 1209 applesmc_show_temperature, NULL, 39); 1301 1210 1211 + static struct attribute *label_attributes[] = { 1212 + &sensor_dev_attr_temp1_label.dev_attr.attr, 1213 + &sensor_dev_attr_temp2_label.dev_attr.attr, 1214 + &sensor_dev_attr_temp3_label.dev_attr.attr, 1215 + &sensor_dev_attr_temp4_label.dev_attr.attr, 1216 + &sensor_dev_attr_temp5_label.dev_attr.attr, 1217 + &sensor_dev_attr_temp6_label.dev_attr.attr, 1218 + &sensor_dev_attr_temp7_label.dev_attr.attr, 1219 + &sensor_dev_attr_temp8_label.dev_attr.attr, 1220 + &sensor_dev_attr_temp9_label.dev_attr.attr, 1221 + &sensor_dev_attr_temp10_label.dev_attr.attr, 1222 + &sensor_dev_attr_temp11_label.dev_attr.attr, 1223 + &sensor_dev_attr_temp12_label.dev_attr.attr, 1224 + &sensor_dev_attr_temp13_label.dev_attr.attr, 1225 + &sensor_dev_attr_temp14_label.dev_attr.attr, 1226 + &sensor_dev_attr_temp15_label.dev_attr.attr, 1227 + &sensor_dev_attr_temp16_label.dev_attr.attr, 1228 + &sensor_dev_attr_temp17_label.dev_attr.attr, 1229 + &sensor_dev_attr_temp18_label.dev_attr.attr, 1230 + &sensor_dev_attr_temp19_label.dev_attr.attr, 1231 + &sensor_dev_attr_temp20_label.dev_attr.attr, 1232 + &sensor_dev_attr_temp21_label.dev_attr.attr, 1233 + &sensor_dev_attr_temp22_label.dev_attr.attr, 1234 + &sensor_dev_attr_temp23_label.dev_attr.attr, 1235 + &sensor_dev_attr_temp24_label.dev_attr.attr, 1236 + &sensor_dev_attr_temp25_label.dev_attr.attr, 1237 + &sensor_dev_attr_temp26_label.dev_attr.attr, 1238 + &sensor_dev_attr_temp27_label.dev_attr.attr, 1239 + &sensor_dev_attr_temp28_label.dev_attr.attr, 1240 + &sensor_dev_attr_temp29_label.dev_attr.attr, 1241 + &sensor_dev_attr_temp30_label.dev_attr.attr, 1242 + &sensor_dev_attr_temp31_label.dev_attr.attr, 1243 + &sensor_dev_attr_temp32_label.dev_attr.attr, 1244 + &sensor_dev_attr_temp33_label.dev_attr.attr, 1245 + &sensor_dev_attr_temp34_label.dev_attr.attr, 1246 + &sensor_dev_attr_temp35_label.dev_attr.attr, 1247 + &sensor_dev_attr_temp36_label.dev_attr.attr, 1248 + &sensor_dev_attr_temp37_label.dev_attr.attr, 1249 + &sensor_dev_attr_temp38_label.dev_attr.attr, 1250 + &sensor_dev_attr_temp39_label.dev_attr.attr, 1251 + &sensor_dev_attr_temp40_label.dev_attr.attr, 1252 + NULL 1253 + }; 1254 + 1302 1255 static struct attribute *temperature_attributes[] = { 1303 1256 &sensor_dev_attr_temp1_input.dev_attr.attr, 1304 1257 &sensor_dev_attr_temp2_input.dev_attr.attr, ··· 1389 1254 1390 1255 static const struct attribute_group temperature_attributes_group = 1391 1256 { .attrs = temperature_attributes }; 1257 + 1258 + static const struct attribute_group label_attributes_group = { 1259 + .attrs = label_attributes 1260 + }; 1392 1261 1393 1262 /* Module stuff */ 1394 1263 ··· 1695 1556 for (i = 0; 1696 1557 temperature_sensors_sets[applesmc_temperature_set][i] != NULL; 1697 1558 i++) { 1698 - if (temperature_attributes[i] == NULL) { 1559 + if (temperature_attributes[i] == NULL || 1560 + label_attributes[i] == NULL) { 1699 1561 printk(KERN_ERR "applesmc: More temperature sensors " 1700 1562 "in temperature_sensors_sets (at least %i)" 1701 1563 "than available sysfs files in " ··· 1706 1566 } 1707 1567 ret = sysfs_create_file(&pdev->dev.kobj, 1708 1568 temperature_attributes[i]); 1569 + if (ret) 1570 + goto out_temperature; 1571 + ret = sysfs_create_file(&pdev->dev.kobj, 1572 + label_attributes[i]); 1709 1573 if (ret) 1710 1574 goto out_temperature; 1711 1575 } ··· 1762 1618 if (applesmc_accelerometer) 1763 1619 applesmc_release_accelerometer(); 1764 1620 out_temperature: 1621 + sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); 1765 1622 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); 1766 1623 out_fans: 1767 1624 while (fans_handled) ··· 1792 1647 } 1793 1648 if (applesmc_accelerometer) 1794 1649 applesmc_release_accelerometer(); 1650 + sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); 1795 1651 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); 1796 1652 while (fans_handled) 1797 1653 sysfs_remove_group(&pdev->dev.kobj,