aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/applesmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/applesmc.c')
-rw-r--r--drivers/hwmon/applesmc.c169
1 files changed, 76 insertions, 93 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index b0792361c52e..ec06b9989278 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -992,47 +992,27 @@ static struct led_classdev applesmc_backlight = {
992 .brightness_set = applesmc_brightness_set, 992 .brightness_set = applesmc_brightness_set,
993}; 993};
994 994
995static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL); 995static struct applesmc_node_group info_group[] = {
996 996 { "name", applesmc_name_show },
997static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL); 997 { "key_count", applesmc_key_count_show },
998static DEVICE_ATTR(calibrate, 0644, 998 { "key_at_index", applesmc_key_at_index_show, applesmc_key_at_index_store },
999 applesmc_calibrate_show, applesmc_calibrate_store); 999 { "key_at_index_name", applesmc_key_at_index_name_show },
1000 1000 { "key_at_index_type", applesmc_key_at_index_type_show },
1001static struct attribute *accelerometer_attributes[] = { 1001 { "key_at_index_data_length", applesmc_key_at_index_data_length_show },
1002 &dev_attr_position.attr, 1002 { "key_at_index_data", applesmc_key_at_index_read_show },
1003 &dev_attr_calibrate.attr, 1003 { }
1004 NULL
1005}; 1004};
1006 1005
1007static const struct attribute_group accelerometer_attributes_group = 1006static struct applesmc_node_group accelerometer_group[] = {
1008 { .attrs = accelerometer_attributes }; 1007 { "position", applesmc_position_show },
1009 1008 { "calibrate", applesmc_calibrate_show, applesmc_calibrate_store },
1010static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL); 1009 { }
1011
1012static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1013static DEVICE_ATTR(key_at_index, 0644,
1014 applesmc_key_at_index_show, applesmc_key_at_index_store);
1015static DEVICE_ATTR(key_at_index_name, 0444,
1016 applesmc_key_at_index_name_show, NULL);
1017static DEVICE_ATTR(key_at_index_type, 0444,
1018 applesmc_key_at_index_type_show, NULL);
1019static DEVICE_ATTR(key_at_index_data_length, 0444,
1020 applesmc_key_at_index_data_length_show, NULL);
1021static DEVICE_ATTR(key_at_index_data, 0444,
1022 applesmc_key_at_index_read_show, NULL);
1023
1024static struct attribute *key_enumeration_attributes[] = {
1025 &dev_attr_key_count.attr,
1026 &dev_attr_key_at_index.attr,
1027 &dev_attr_key_at_index_name.attr,
1028 &dev_attr_key_at_index_type.attr,
1029 &dev_attr_key_at_index_data_length.attr,
1030 &dev_attr_key_at_index_data.attr,
1031 NULL
1032}; 1010};
1033 1011
1034static const struct attribute_group key_enumeration_group = 1012static struct applesmc_node_group light_sensor_group[] = {
1035 { .attrs = key_enumeration_attributes }; 1013 { "light", applesmc_light_show },
1014 { }
1015};
1036 1016
1037static struct applesmc_node_group fan_group[] = { 1017static struct applesmc_node_group fan_group[] = {
1038 { "fan%d_label", applesmc_show_fan_position }, 1018 { "fan%d_label", applesmc_show_fan_position },
@@ -1115,8 +1095,10 @@ static int applesmc_create_accelerometer(void)
1115 struct input_dev *idev; 1095 struct input_dev *idev;
1116 int ret; 1096 int ret;
1117 1097
1118 ret = sysfs_create_group(&pdev->dev.kobj, 1098 if (!smcreg.has_accelerometer)
1119 &accelerometer_attributes_group); 1099 return 0;
1100
1101 ret = applesmc_create_nodes(accelerometer_group, 1);
1120 if (ret) 1102 if (ret)
1121 goto out; 1103 goto out;
1122 1104
@@ -1153,7 +1135,7 @@ out_idev:
1153 input_free_polled_device(applesmc_idev); 1135 input_free_polled_device(applesmc_idev);
1154 1136
1155out_sysfs: 1137out_sysfs:
1156 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); 1138 applesmc_destroy_nodes(accelerometer_group);
1157 1139
1158out: 1140out:
1159 pr_warn("driver init failed (ret=%d)!\n", ret); 1141 pr_warn("driver init failed (ret=%d)!\n", ret);
@@ -1163,10 +1145,45 @@ out:
1163/* Release all ressources used by the accelerometer */ 1145/* Release all ressources used by the accelerometer */
1164static void applesmc_release_accelerometer(void) 1146static void applesmc_release_accelerometer(void)
1165{ 1147{
1148 if (!smcreg.has_accelerometer)
1149 return;
1166 input_unregister_polled_device(applesmc_idev); 1150 input_unregister_polled_device(applesmc_idev);
1167 input_free_polled_device(applesmc_idev); 1151 input_free_polled_device(applesmc_idev);
1168 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); 1152 applesmc_destroy_nodes(accelerometer_group);
1169} 1153}
1154
1155static int applesmc_create_light_sensor(void)
1156{
1157 if (!smcreg.num_light_sensors)
1158 return 0;
1159 return applesmc_create_nodes(light_sensor_group, 1);
1160}
1161
1162static void applesmc_release_light_sensor(void)
1163{
1164 if (!smcreg.num_light_sensors)
1165 return;
1166 applesmc_destroy_nodes(light_sensor_group);
1167}
1168
1169static int applesmc_create_key_backlight(void)
1170{
1171 if (!smcreg.has_key_backlight)
1172 return 0;
1173 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1174 if (!applesmc_led_wq)
1175 return -ENOMEM;
1176 return led_classdev_register(&pdev->dev, &applesmc_backlight);
1177}
1178
1179static void applesmc_release_key_backlight(void)
1180{
1181 if (!smcreg.has_key_backlight)
1182 return;
1183 led_classdev_unregister(&applesmc_backlight);
1184 destroy_workqueue(applesmc_led_wq);
1185}
1186
1170static int applesmc_dmi_match(const struct dmi_system_id *id) 1187static int applesmc_dmi_match(const struct dmi_system_id *id)
1171{ 1188{
1172 return 1; 1189 return 1;
@@ -1234,15 +1251,10 @@ static int __init applesmc_init(void)
1234 if (ret) 1251 if (ret)
1235 goto out_device; 1252 goto out_device;
1236 1253
1237 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr); 1254 ret = applesmc_create_nodes(info_group, 1);
1238 if (ret) 1255 if (ret)
1239 goto out_smcreg; 1256 goto out_smcreg;
1240 1257
1241 /* Create key enumeration sysfs files */
1242 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1243 if (ret)
1244 goto out_name;
1245
1246 ret = applesmc_create_nodes(fan_group, smcreg.fan_count); 1258 ret = applesmc_create_nodes(fan_group, smcreg.fan_count);
1247 if (ret) 1259 if (ret)
1248 goto out_info; 1260 goto out_info;
@@ -1251,32 +1263,17 @@ static int __init applesmc_init(void)
1251 if (ret) 1263 if (ret)
1252 goto out_fans; 1264 goto out_fans;
1253 1265
1254 if (smcreg.has_accelerometer) { 1266 ret = applesmc_create_accelerometer();
1255 ret = applesmc_create_accelerometer(); 1267 if (ret)
1256 if (ret) 1268 goto out_temperature;
1257 goto out_temperature;
1258 }
1259
1260 if (smcreg.num_light_sensors) {
1261 /* Add light sensor file */
1262 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1263 if (ret)
1264 goto out_accelerometer;
1265 }
1266 1269
1267 if (smcreg.has_key_backlight) { 1270 ret = applesmc_create_light_sensor();
1268 /* Create the workqueue */ 1271 if (ret)
1269 applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); 1272 goto out_accelerometer;
1270 if (!applesmc_led_wq) {
1271 ret = -ENOMEM;
1272 goto out_light_sysfs;
1273 }
1274 1273
1275 /* register as a led device */ 1274 ret = applesmc_create_key_backlight();
1276 ret = led_classdev_register(&pdev->dev, &applesmc_backlight); 1275 if (ret)
1277 if (ret < 0) 1276 goto out_light_sysfs;
1278 goto out_light_wq;
1279 }
1280 1277
1281 hwmon_dev = hwmon_device_register(&pdev->dev); 1278 hwmon_dev = hwmon_device_register(&pdev->dev);
1282 if (IS_ERR(hwmon_dev)) { 1279 if (IS_ERR(hwmon_dev)) {
@@ -1289,25 +1286,17 @@ static int __init applesmc_init(void)
1289 return 0; 1286 return 0;
1290 1287
1291out_light_ledclass: 1288out_light_ledclass:
1292 if (smcreg.has_key_backlight) 1289 applesmc_release_key_backlight();
1293 led_classdev_unregister(&applesmc_backlight);
1294out_light_wq:
1295 if (smcreg.has_key_backlight)
1296 destroy_workqueue(applesmc_led_wq);
1297out_light_sysfs: 1290out_light_sysfs:
1298 if (smcreg.num_light_sensors) 1291 applesmc_release_light_sensor();
1299 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1300out_accelerometer: 1292out_accelerometer:
1301 if (smcreg.has_accelerometer) 1293 applesmc_release_accelerometer();
1302 applesmc_release_accelerometer();
1303out_temperature: 1294out_temperature:
1304 applesmc_destroy_nodes(temp_group); 1295 applesmc_destroy_nodes(temp_group);
1305out_fans: 1296out_fans:
1306 applesmc_destroy_nodes(fan_group); 1297 applesmc_destroy_nodes(fan_group);
1307out_info: 1298out_info:
1308 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); 1299 applesmc_destroy_nodes(info_group);
1309out_name:
1310 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1311out_smcreg: 1300out_smcreg:
1312 applesmc_destroy_smcreg(); 1301 applesmc_destroy_smcreg();
1313out_device: 1302out_device:
@@ -1324,18 +1313,12 @@ out:
1324static void __exit applesmc_exit(void) 1313static void __exit applesmc_exit(void)
1325{ 1314{
1326 hwmon_device_unregister(hwmon_dev); 1315 hwmon_device_unregister(hwmon_dev);
1327 if (smcreg.has_key_backlight) { 1316 applesmc_release_key_backlight();
1328 led_classdev_unregister(&applesmc_backlight); 1317 applesmc_release_light_sensor();
1329 destroy_workqueue(applesmc_led_wq); 1318 applesmc_release_accelerometer();
1330 }
1331 if (smcreg.num_light_sensors)
1332 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1333 if (smcreg.has_accelerometer)
1334 applesmc_release_accelerometer();
1335 applesmc_destroy_nodes(temp_group); 1319 applesmc_destroy_nodes(temp_group);
1336 applesmc_destroy_nodes(fan_group); 1320 applesmc_destroy_nodes(fan_group);
1337 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); 1321 applesmc_destroy_nodes(info_group);
1338 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1339 applesmc_destroy_smcreg(); 1322 applesmc_destroy_smcreg();
1340 platform_device_unregister(pdev); 1323 platform_device_unregister(pdev);
1341 platform_driver_unregister(&applesmc_driver); 1324 platform_driver_unregister(&applesmc_driver);