aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c233
1 files changed, 103 insertions, 130 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 41b55a74ce89..5df0824fc832 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1014,47 +1014,100 @@ static const struct attribute_group it87_group = {
1014 .attrs = it87_attributes, 1014 .attrs = it87_attributes,
1015}; 1015};
1016 1016
1017static struct attribute *it87_attributes_opt[] = { 1017static struct attribute *it87_attributes_fan16[5][3+1] = { {
1018 &sensor_dev_attr_fan1_input16.dev_attr.attr, 1018 &sensor_dev_attr_fan1_input16.dev_attr.attr,
1019 &sensor_dev_attr_fan1_min16.dev_attr.attr, 1019 &sensor_dev_attr_fan1_min16.dev_attr.attr,
1020 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
1021 NULL
1022}, {
1020 &sensor_dev_attr_fan2_input16.dev_attr.attr, 1023 &sensor_dev_attr_fan2_input16.dev_attr.attr,
1021 &sensor_dev_attr_fan2_min16.dev_attr.attr, 1024 &sensor_dev_attr_fan2_min16.dev_attr.attr,
1025 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
1026 NULL
1027}, {
1022 &sensor_dev_attr_fan3_input16.dev_attr.attr, 1028 &sensor_dev_attr_fan3_input16.dev_attr.attr,
1023 &sensor_dev_attr_fan3_min16.dev_attr.attr, 1029 &sensor_dev_attr_fan3_min16.dev_attr.attr,
1030 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
1031 NULL
1032}, {
1024 &sensor_dev_attr_fan4_input16.dev_attr.attr, 1033 &sensor_dev_attr_fan4_input16.dev_attr.attr,
1025 &sensor_dev_attr_fan4_min16.dev_attr.attr, 1034 &sensor_dev_attr_fan4_min16.dev_attr.attr,
1035 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
1036 NULL
1037}, {
1026 &sensor_dev_attr_fan5_input16.dev_attr.attr, 1038 &sensor_dev_attr_fan5_input16.dev_attr.attr,
1027 &sensor_dev_attr_fan5_min16.dev_attr.attr, 1039 &sensor_dev_attr_fan5_min16.dev_attr.attr,
1040 &sensor_dev_attr_fan5_alarm.dev_attr.attr,
1041 NULL
1042} };
1043
1044static const struct attribute_group it87_group_fan16[5] = {
1045 { .attrs = it87_attributes_fan16[0] },
1046 { .attrs = it87_attributes_fan16[1] },
1047 { .attrs = it87_attributes_fan16[2] },
1048 { .attrs = it87_attributes_fan16[3] },
1049 { .attrs = it87_attributes_fan16[4] },
1050};
1028 1051
1052static struct attribute *it87_attributes_fan[3][4+1] = { {
1029 &sensor_dev_attr_fan1_input.dev_attr.attr, 1053 &sensor_dev_attr_fan1_input.dev_attr.attr,
1030 &sensor_dev_attr_fan1_min.dev_attr.attr, 1054 &sensor_dev_attr_fan1_min.dev_attr.attr,
1031 &sensor_dev_attr_fan1_div.dev_attr.attr, 1055 &sensor_dev_attr_fan1_div.dev_attr.attr,
1056 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
1057 NULL
1058}, {
1032 &sensor_dev_attr_fan2_input.dev_attr.attr, 1059 &sensor_dev_attr_fan2_input.dev_attr.attr,
1033 &sensor_dev_attr_fan2_min.dev_attr.attr, 1060 &sensor_dev_attr_fan2_min.dev_attr.attr,
1034 &sensor_dev_attr_fan2_div.dev_attr.attr, 1061 &sensor_dev_attr_fan2_div.dev_attr.attr,
1062 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
1063 NULL
1064}, {
1035 &sensor_dev_attr_fan3_input.dev_attr.attr, 1065 &sensor_dev_attr_fan3_input.dev_attr.attr,
1036 &sensor_dev_attr_fan3_min.dev_attr.attr, 1066 &sensor_dev_attr_fan3_min.dev_attr.attr,
1037 &sensor_dev_attr_fan3_div.dev_attr.attr, 1067 &sensor_dev_attr_fan3_div.dev_attr.attr,
1038
1039 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
1040 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
1041 &sensor_dev_attr_fan3_alarm.dev_attr.attr, 1068 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
1042 &sensor_dev_attr_fan4_alarm.dev_attr.attr, 1069 NULL
1043 &sensor_dev_attr_fan5_alarm.dev_attr.attr, 1070} };
1071
1072static const struct attribute_group it87_group_fan[3] = {
1073 { .attrs = it87_attributes_fan[0] },
1074 { .attrs = it87_attributes_fan[1] },
1075 { .attrs = it87_attributes_fan[2] },
1076};
1077
1078static const struct attribute_group *
1079it87_get_fan_group(const struct it87_data *data)
1080{
1081 return has_16bit_fans(data) ? it87_group_fan16 : it87_group_fan;
1082}
1044 1083
1084static struct attribute *it87_attributes_pwm[3][4+1] = { {
1045 &sensor_dev_attr_pwm1_enable.dev_attr.attr, 1085 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1046 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1047 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1048 &sensor_dev_attr_pwm1.dev_attr.attr, 1086 &sensor_dev_attr_pwm1.dev_attr.attr,
1049 &sensor_dev_attr_pwm2.dev_attr.attr,
1050 &sensor_dev_attr_pwm3.dev_attr.attr,
1051 &dev_attr_pwm1_freq.attr, 1087 &dev_attr_pwm1_freq.attr,
1052 &dev_attr_pwm2_freq.attr,
1053 &dev_attr_pwm3_freq.attr,
1054 &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, 1088 &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
1089 NULL
1090}, {
1091 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1092 &sensor_dev_attr_pwm2.dev_attr.attr,
1093 &dev_attr_pwm2_freq.attr,
1055 &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, 1094 &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
1095 NULL
1096}, {
1097 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1098 &sensor_dev_attr_pwm3.dev_attr.attr,
1099 &dev_attr_pwm3_freq.attr,
1056 &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, 1100 &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
1101 NULL
1102} };
1057 1103
1104static const struct attribute_group it87_group_pwm[3] = {
1105 { .attrs = it87_attributes_pwm[0] },
1106 { .attrs = it87_attributes_pwm[1] },
1107 { .attrs = it87_attributes_pwm[2] },
1108};
1109
1110static struct attribute *it87_attributes_opt[] = {
1058 &dev_attr_vrm.attr, 1111 &dev_attr_vrm.attr,
1059 &dev_attr_cpu0_vid.attr, 1112 &dev_attr_cpu0_vid.attr,
1060 NULL 1113 NULL
@@ -1179,13 +1232,35 @@ exit:
1179 return err; 1232 return err;
1180} 1233}
1181 1234
1235static void it87_remove_files(struct device *dev)
1236{
1237 struct it87_data *data = platform_get_drvdata(pdev);
1238 struct it87_sio_data *sio_data = dev->platform_data;
1239 const struct attribute_group *fan_group = it87_get_fan_group(data);
1240 int i;
1241
1242 sysfs_remove_group(&dev->kobj, &it87_group);
1243 for (i = 0; i < 5; i++) {
1244 if (!(data->has_fan & (1 << i)))
1245 continue;
1246 sysfs_remove_group(&dev->kobj, &fan_group[i]);
1247 }
1248 for (i = 0; i < 3; i++) {
1249 if (sio_data->skip_pwm & (1 << 0))
1250 continue;
1251 sysfs_remove_group(&dev->kobj, &it87_group_pwm[i]);
1252 }
1253 sysfs_remove_group(&dev->kobj, &it87_group_opt);
1254}
1255
1182static int __devinit it87_probe(struct platform_device *pdev) 1256static int __devinit it87_probe(struct platform_device *pdev)
1183{ 1257{
1184 struct it87_data *data; 1258 struct it87_data *data;
1185 struct resource *res; 1259 struct resource *res;
1186 struct device *dev = &pdev->dev; 1260 struct device *dev = &pdev->dev;
1187 struct it87_sio_data *sio_data = dev->platform_data; 1261 struct it87_sio_data *sio_data = dev->platform_data;
1188 int err = 0; 1262 const struct attribute_group *fan_group;
1263 int err = 0, i;
1189 int enable_pwm_interface; 1264 int enable_pwm_interface;
1190 static const char *names[] = { 1265 static const char *names[] = {
1191 "it87", 1266 "it87",
@@ -1236,122 +1311,22 @@ static int __devinit it87_probe(struct platform_device *pdev)
1236 goto ERROR2; 1311 goto ERROR2;
1237 1312
1238 /* Do not create fan files for disabled fans */ 1313 /* Do not create fan files for disabled fans */
1239 if (has_16bit_fans(data)) { 1314 fan_group = it87_get_fan_group(data);
1240 /* 16-bit tachometers */ 1315 for (i = 0; i < 5; i++) {
1241 if (data->has_fan & (1 << 0)) { 1316 if (!(data->has_fan & (1 << i)))
1242 if ((err = device_create_file(dev, 1317 continue;
1243 &sensor_dev_attr_fan1_input16.dev_attr)) 1318 err = sysfs_create_group(&dev->kobj, &fan_group[i]);
1244 || (err = device_create_file(dev, 1319 if (err)
1245 &sensor_dev_attr_fan1_min16.dev_attr)) 1320 goto ERROR4;
1246 || (err = device_create_file(dev,
1247 &sensor_dev_attr_fan1_alarm.dev_attr)))
1248 goto ERROR4;
1249 }
1250 if (data->has_fan & (1 << 1)) {
1251 if ((err = device_create_file(dev,
1252 &sensor_dev_attr_fan2_input16.dev_attr))
1253 || (err = device_create_file(dev,
1254 &sensor_dev_attr_fan2_min16.dev_attr))
1255 || (err = device_create_file(dev,
1256 &sensor_dev_attr_fan2_alarm.dev_attr)))
1257 goto ERROR4;
1258 }
1259 if (data->has_fan & (1 << 2)) {
1260 if ((err = device_create_file(dev,
1261 &sensor_dev_attr_fan3_input16.dev_attr))
1262 || (err = device_create_file(dev,
1263 &sensor_dev_attr_fan3_min16.dev_attr))
1264 || (err = device_create_file(dev,
1265 &sensor_dev_attr_fan3_alarm.dev_attr)))
1266 goto ERROR4;
1267 }
1268 if (data->has_fan & (1 << 3)) {
1269 if ((err = device_create_file(dev,
1270 &sensor_dev_attr_fan4_input16.dev_attr))
1271 || (err = device_create_file(dev,
1272 &sensor_dev_attr_fan4_min16.dev_attr))
1273 || (err = device_create_file(dev,
1274 &sensor_dev_attr_fan4_alarm.dev_attr)))
1275 goto ERROR4;
1276 }
1277 if (data->has_fan & (1 << 4)) {
1278 if ((err = device_create_file(dev,
1279 &sensor_dev_attr_fan5_input16.dev_attr))
1280 || (err = device_create_file(dev,
1281 &sensor_dev_attr_fan5_min16.dev_attr))
1282 || (err = device_create_file(dev,
1283 &sensor_dev_attr_fan5_alarm.dev_attr)))
1284 goto ERROR4;
1285 }
1286 } else {
1287 /* 8-bit tachometers with clock divider */
1288 if (data->has_fan & (1 << 0)) {
1289 if ((err = device_create_file(dev,
1290 &sensor_dev_attr_fan1_input.dev_attr))
1291 || (err = device_create_file(dev,
1292 &sensor_dev_attr_fan1_min.dev_attr))
1293 || (err = device_create_file(dev,
1294 &sensor_dev_attr_fan1_div.dev_attr))
1295 || (err = device_create_file(dev,
1296 &sensor_dev_attr_fan1_alarm.dev_attr)))
1297 goto ERROR4;
1298 }
1299 if (data->has_fan & (1 << 1)) {
1300 if ((err = device_create_file(dev,
1301 &sensor_dev_attr_fan2_input.dev_attr))
1302 || (err = device_create_file(dev,
1303 &sensor_dev_attr_fan2_min.dev_attr))
1304 || (err = device_create_file(dev,
1305 &sensor_dev_attr_fan2_div.dev_attr))
1306 || (err = device_create_file(dev,
1307 &sensor_dev_attr_fan2_alarm.dev_attr)))
1308 goto ERROR4;
1309 }
1310 if (data->has_fan & (1 << 2)) {
1311 if ((err = device_create_file(dev,
1312 &sensor_dev_attr_fan3_input.dev_attr))
1313 || (err = device_create_file(dev,
1314 &sensor_dev_attr_fan3_min.dev_attr))
1315 || (err = device_create_file(dev,
1316 &sensor_dev_attr_fan3_div.dev_attr))
1317 || (err = device_create_file(dev,
1318 &sensor_dev_attr_fan3_alarm.dev_attr)))
1319 goto ERROR4;
1320 }
1321 } 1321 }
1322 1322
1323 if (enable_pwm_interface) { 1323 if (enable_pwm_interface) {
1324 if (!(sio_data->skip_pwm & (1 << 0))) { 1324 for (i = 0; i < 3; i++) {
1325 if ((err = device_create_file(dev, 1325 if (sio_data->skip_pwm & (1 << i))
1326 &sensor_dev_attr_pwm1_enable.dev_attr)) 1326 continue;
1327 || (err = device_create_file(dev, 1327 err = sysfs_create_group(&dev->kobj,
1328 &sensor_dev_attr_pwm1.dev_attr)) 1328 &it87_group_pwm[i]);
1329 || (err = device_create_file(dev, 1329 if (err)
1330 &dev_attr_pwm1_freq))
1331 || (err = device_create_file(dev,
1332 &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr)))
1333 goto ERROR4;
1334 }
1335 if (!(sio_data->skip_pwm & (1 << 1))) {
1336 if ((err = device_create_file(dev,
1337 &sensor_dev_attr_pwm2_enable.dev_attr))
1338 || (err = device_create_file(dev,
1339 &sensor_dev_attr_pwm2.dev_attr))
1340 || (err = device_create_file(dev,
1341 &dev_attr_pwm2_freq))
1342 || (err = device_create_file(dev,
1343 &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr)))
1344 goto ERROR4;
1345 }
1346 if (!(sio_data->skip_pwm & (1 << 2))) {
1347 if ((err = device_create_file(dev,
1348 &sensor_dev_attr_pwm3_enable.dev_attr))
1349 || (err = device_create_file(dev,
1350 &sensor_dev_attr_pwm3.dev_attr))
1351 || (err = device_create_file(dev,
1352 &dev_attr_pwm3_freq))
1353 || (err = device_create_file(dev,
1354 &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr)))
1355 goto ERROR4; 1330 goto ERROR4;
1356 } 1331 }
1357 } 1332 }
@@ -1376,8 +1351,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1376 return 0; 1351 return 0;
1377 1352
1378ERROR4: 1353ERROR4:
1379 sysfs_remove_group(&dev->kobj, &it87_group); 1354 it87_remove_files(dev);
1380 sysfs_remove_group(&dev->kobj, &it87_group_opt);
1381ERROR2: 1355ERROR2:
1382 platform_set_drvdata(pdev, NULL); 1356 platform_set_drvdata(pdev, NULL);
1383 kfree(data); 1357 kfree(data);
@@ -1392,8 +1366,7 @@ static int __devexit it87_remove(struct platform_device *pdev)
1392 struct it87_data *data = platform_get_drvdata(pdev); 1366 struct it87_data *data = platform_get_drvdata(pdev);
1393 1367
1394 hwmon_device_unregister(data->hwmon_dev); 1368 hwmon_device_unregister(data->hwmon_dev);
1395 sysfs_remove_group(&pdev->dev.kobj, &it87_group); 1369 it87_remove_files(&pdev->dev);
1396 sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt);
1397 1370
1398 release_region(data->addr, IT87_EC_EXTENT); 1371 release_region(data->addr, IT87_EC_EXTENT);
1399 platform_set_drvdata(pdev, NULL); 1372 platform_set_drvdata(pdev, NULL);