diff options
Diffstat (limited to 'drivers/hwmon/applesmc.c')
-rw-r--r-- | drivers/hwmon/applesmc.c | 169 |
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 | ||
995 | static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL); | 995 | static struct applesmc_node_group info_group[] = { |
996 | 996 | { "name", applesmc_name_show }, | |
997 | static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL); | 997 | { "key_count", applesmc_key_count_show }, |
998 | static 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 }, | |
1001 | static 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 | ||
1007 | static const struct attribute_group accelerometer_attributes_group = | 1006 | static struct applesmc_node_group accelerometer_group[] = { |
1008 | { .attrs = accelerometer_attributes }; | 1007 | { "position", applesmc_position_show }, |
1009 | 1008 | { "calibrate", applesmc_calibrate_show, applesmc_calibrate_store }, | |
1010 | static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL); | 1009 | { } |
1011 | |||
1012 | static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL); | ||
1013 | static DEVICE_ATTR(key_at_index, 0644, | ||
1014 | applesmc_key_at_index_show, applesmc_key_at_index_store); | ||
1015 | static DEVICE_ATTR(key_at_index_name, 0444, | ||
1016 | applesmc_key_at_index_name_show, NULL); | ||
1017 | static DEVICE_ATTR(key_at_index_type, 0444, | ||
1018 | applesmc_key_at_index_type_show, NULL); | ||
1019 | static DEVICE_ATTR(key_at_index_data_length, 0444, | ||
1020 | applesmc_key_at_index_data_length_show, NULL); | ||
1021 | static DEVICE_ATTR(key_at_index_data, 0444, | ||
1022 | applesmc_key_at_index_read_show, NULL); | ||
1023 | |||
1024 | static 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 | ||
1034 | static const struct attribute_group key_enumeration_group = | 1012 | static struct applesmc_node_group light_sensor_group[] = { |
1035 | { .attrs = key_enumeration_attributes }; | 1013 | { "light", applesmc_light_show }, |
1014 | { } | ||
1015 | }; | ||
1036 | 1016 | ||
1037 | static struct applesmc_node_group fan_group[] = { | 1017 | static 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 | ||
1155 | out_sysfs: | 1137 | out_sysfs: |
1156 | sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); | 1138 | applesmc_destroy_nodes(accelerometer_group); |
1157 | 1139 | ||
1158 | out: | 1140 | out: |
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 */ |
1164 | static void applesmc_release_accelerometer(void) | 1146 | static 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 | |||
1155 | static 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 | |||
1162 | static void applesmc_release_light_sensor(void) | ||
1163 | { | ||
1164 | if (!smcreg.num_light_sensors) | ||
1165 | return; | ||
1166 | applesmc_destroy_nodes(light_sensor_group); | ||
1167 | } | ||
1168 | |||
1169 | static 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 | |||
1179 | static 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 | |||
1170 | static int applesmc_dmi_match(const struct dmi_system_id *id) | 1187 | static 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 | ||
1291 | out_light_ledclass: | 1288 | out_light_ledclass: |
1292 | if (smcreg.has_key_backlight) | 1289 | applesmc_release_key_backlight(); |
1293 | led_classdev_unregister(&applesmc_backlight); | ||
1294 | out_light_wq: | ||
1295 | if (smcreg.has_key_backlight) | ||
1296 | destroy_workqueue(applesmc_led_wq); | ||
1297 | out_light_sysfs: | 1290 | out_light_sysfs: |
1298 | if (smcreg.num_light_sensors) | 1291 | applesmc_release_light_sensor(); |
1299 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); | ||
1300 | out_accelerometer: | 1292 | out_accelerometer: |
1301 | if (smcreg.has_accelerometer) | 1293 | applesmc_release_accelerometer(); |
1302 | applesmc_release_accelerometer(); | ||
1303 | out_temperature: | 1294 | out_temperature: |
1304 | applesmc_destroy_nodes(temp_group); | 1295 | applesmc_destroy_nodes(temp_group); |
1305 | out_fans: | 1296 | out_fans: |
1306 | applesmc_destroy_nodes(fan_group); | 1297 | applesmc_destroy_nodes(fan_group); |
1307 | out_info: | 1298 | out_info: |
1308 | sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); | 1299 | applesmc_destroy_nodes(info_group); |
1309 | out_name: | ||
1310 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); | ||
1311 | out_smcreg: | 1300 | out_smcreg: |
1312 | applesmc_destroy_smcreg(); | 1301 | applesmc_destroy_smcreg(); |
1313 | out_device: | 1302 | out_device: |
@@ -1324,18 +1313,12 @@ out: | |||
1324 | static void __exit applesmc_exit(void) | 1313 | static 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); |