diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/platform/x86/asus-laptop.c | 111 |
1 files changed, 50 insertions, 61 deletions
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index e3b5e0604edd..60a5a5c6b50a 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -1200,82 +1200,70 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event) | |||
1200 | 1200 | ||
1201 | static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL); | 1201 | static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL); |
1202 | static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan); | 1202 | static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan); |
1203 | static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, show_bluetooth, | 1203 | static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, |
1204 | store_bluetooth); | 1204 | show_bluetooth, store_bluetooth); |
1205 | static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp); | 1205 | static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp); |
1206 | static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); | 1206 | static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); |
1207 | static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); | 1207 | static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); |
1208 | static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw); | 1208 | static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw); |
1209 | static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps); | 1209 | static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps); |
1210 | 1210 | ||
1211 | static void asus_sysfs_exit(struct asus_laptop *asus) | 1211 | static struct attribute *asus_attributes[] = { |
1212 | { | 1212 | &dev_attr_infos.attr, |
1213 | struct platform_device *device = asus->platform_device; | 1213 | &dev_attr_wlan.attr, |
1214 | 1214 | &dev_attr_bluetooth.attr, | |
1215 | device_remove_file(&device->dev, &dev_attr_infos); | 1215 | &dev_attr_display.attr, |
1216 | device_remove_file(&device->dev, &dev_attr_wlan); | 1216 | &dev_attr_ledd.attr, |
1217 | device_remove_file(&device->dev, &dev_attr_bluetooth); | 1217 | &dev_attr_ls_level.attr, |
1218 | device_remove_file(&device->dev, &dev_attr_display); | 1218 | &dev_attr_ls_switch.attr, |
1219 | device_remove_file(&device->dev, &dev_attr_ledd); | 1219 | &dev_attr_gps.attr, |
1220 | device_remove_file(&device->dev, &dev_attr_ls_switch); | 1220 | NULL |
1221 | device_remove_file(&device->dev, &dev_attr_ls_level); | 1221 | }; |
1222 | device_remove_file(&device->dev, &dev_attr_gps); | ||
1223 | } | ||
1224 | 1222 | ||
1225 | static int asus_sysfs_init(struct asus_laptop *asus) | 1223 | static mode_t asus_sysfs_is_visible(struct kobject *kobj, |
1224 | struct attribute *attr, | ||
1225 | int idx) | ||
1226 | { | 1226 | { |
1227 | struct platform_device *device = asus->platform_device; | 1227 | struct device *dev = container_of(kobj, struct device, kobj); |
1228 | int err; | 1228 | struct platform_device *pdev = to_platform_device(dev); |
1229 | struct asus_laptop *asus = platform_get_drvdata(pdev); | ||
1230 | acpi_handle handle = asus->handle; | ||
1231 | bool supported; | ||
1229 | 1232 | ||
1230 | err = device_create_file(&device->dev, &dev_attr_infos); | 1233 | if (attr == &dev_attr_wlan.attr) { |
1231 | if (err) | 1234 | supported = !acpi_check_handle(handle, METHOD_WLAN, NULL); |
1232 | return err; | ||
1233 | 1235 | ||
1234 | if (!acpi_check_handle(asus->handle, METHOD_WLAN, NULL)) { | 1236 | } else if (attr == &dev_attr_bluetooth.attr) { |
1235 | err = device_create_file(&device->dev, &dev_attr_wlan); | 1237 | supported = !acpi_check_handle(handle, METHOD_BLUETOOTH, NULL); |
1236 | if (err) | ||
1237 | return err; | ||
1238 | } | ||
1239 | |||
1240 | if (!acpi_check_handle(asus->handle, METHOD_BLUETOOTH, NULL)) { | ||
1241 | err = device_create_file(&device->dev, &dev_attr_bluetooth); | ||
1242 | if (err) | ||
1243 | return err; | ||
1244 | } | ||
1245 | 1238 | ||
1246 | if (!acpi_check_handle(asus->handle, METHOD_SWITCH_DISPLAY, NULL)) { | 1239 | } else if (attr == &dev_attr_display.attr) { |
1247 | err = device_create_file(&device->dev, &dev_attr_display); | 1240 | supported = !acpi_check_handle(handle, METHOD_SWITCH_DISPLAY, NULL); |
1248 | if (err) | ||
1249 | return err; | ||
1250 | } | ||
1251 | 1241 | ||
1252 | if (!acpi_check_handle(asus->handle, METHOD_LEDD, NULL)) { | 1242 | } else if (attr == &dev_attr_ledd.attr) { |
1253 | err = device_create_file(&device->dev, &dev_attr_ledd); | 1243 | supported = !acpi_check_handle(handle, METHOD_LEDD, NULL); |
1254 | if (err) | ||
1255 | return err; | ||
1256 | } | ||
1257 | 1244 | ||
1258 | if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) && | 1245 | } else if (attr == &dev_attr_ls_switch.attr || |
1259 | !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) { | 1246 | attr == &dev_attr_ls_level.attr) { |
1260 | err = device_create_file(&device->dev, &dev_attr_ls_switch); | 1247 | supported = !acpi_check_handle(handle, METHOD_ALS_CONTROL, NULL) && |
1261 | if (err) | 1248 | !acpi_check_handle(handle, METHOD_ALS_LEVEL, NULL); |
1262 | return err; | ||
1263 | err = device_create_file(&device->dev, &dev_attr_ls_level); | ||
1264 | if (err) | ||
1265 | return err; | ||
1266 | } | ||
1267 | 1249 | ||
1268 | if (!acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) && | 1250 | } else if (attr == &dev_attr_gps.attr) { |
1269 | !acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) && | 1251 | supported = !acpi_check_handle(handle, METHOD_GPS_ON, NULL) && |
1270 | !acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL)) { | 1252 | !acpi_check_handle(handle, METHOD_GPS_OFF, NULL) && |
1271 | err = device_create_file(&device->dev, &dev_attr_gps); | 1253 | !acpi_check_handle(handle, METHOD_GPS_STATUS, NULL); |
1272 | if (err) | 1254 | } else { |
1273 | return err; | 1255 | supported = true; |
1274 | } | 1256 | } |
1275 | 1257 | ||
1276 | return err; | 1258 | return supported ? attr->mode : 0; |
1277 | } | 1259 | } |
1278 | 1260 | ||
1261 | |||
1262 | static const struct attribute_group asus_attr_group = { | ||
1263 | .is_visible = asus_sysfs_is_visible, | ||
1264 | .attrs = asus_attributes, | ||
1265 | }; | ||
1266 | |||
1279 | static int asus_platform_init(struct asus_laptop *asus) | 1267 | static int asus_platform_init(struct asus_laptop *asus) |
1280 | { | 1268 | { |
1281 | int result; | 1269 | int result; |
@@ -1289,13 +1277,14 @@ static int asus_platform_init(struct asus_laptop *asus) | |||
1289 | if (result) | 1277 | if (result) |
1290 | goto fail_platform_device; | 1278 | goto fail_platform_device; |
1291 | 1279 | ||
1292 | result = asus_sysfs_init(asus); | 1280 | result = sysfs_create_group(&asus->platform_device->dev.kobj, |
1281 | &asus_attr_group); | ||
1293 | if (result) | 1282 | if (result) |
1294 | goto fail_sysfs; | 1283 | goto fail_sysfs; |
1284 | |||
1295 | return 0; | 1285 | return 0; |
1296 | 1286 | ||
1297 | fail_sysfs: | 1287 | fail_sysfs: |
1298 | asus_sysfs_exit(asus); | ||
1299 | platform_device_del(asus->platform_device); | 1288 | platform_device_del(asus->platform_device); |
1300 | fail_platform_device: | 1289 | fail_platform_device: |
1301 | platform_device_put(asus->platform_device); | 1290 | platform_device_put(asus->platform_device); |
@@ -1304,7 +1293,7 @@ fail_platform_device: | |||
1304 | 1293 | ||
1305 | static void asus_platform_exit(struct asus_laptop *asus) | 1294 | static void asus_platform_exit(struct asus_laptop *asus) |
1306 | { | 1295 | { |
1307 | asus_sysfs_exit(asus); | 1296 | sysfs_remove_group(&asus->platform_device->dev.kobj, &asus_attr_group); |
1308 | platform_device_unregister(asus->platform_device); | 1297 | platform_device_unregister(asus->platform_device); |
1309 | } | 1298 | } |
1310 | 1299 | ||