aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-08-26 03:12:19 -0400
committerMatthew Garrett <mjg@redhat.com>2010-10-21 09:36:46 -0400
commitac9b1e5b63d5d9829ecf2294f0486ccd270c5db4 (patch)
tree44038c936ea0ab24c4761cc9fd1aac1f1651dcc4 /drivers/platform
parent209009b2cb29124ad707fbb3ba4c95d3d100a1c4 (diff)
asus-laptop: use attribute group to manage attributes
Instead of registering (and removing) every attribute individually switch to using sysfs attribute group. This makes sure that we properly unwind and do not try to remove non-existent attributes which may not be safe to do in the future. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/asus-laptop.c111
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
1201static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL); 1201static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL);
1202static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan); 1202static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan);
1203static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, show_bluetooth, 1203static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR,
1204 store_bluetooth); 1204 show_bluetooth, store_bluetooth);
1205static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp); 1205static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
1206static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); 1206static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
1207static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); 1207static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
1208static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw); 1208static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw);
1209static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps); 1209static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps);
1210 1210
1211static void asus_sysfs_exit(struct asus_laptop *asus) 1211static 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
1225static int asus_sysfs_init(struct asus_laptop *asus) 1223static 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
1262static const struct attribute_group asus_attr_group = {
1263 .is_visible = asus_sysfs_is_visible,
1264 .attrs = asus_attributes,
1265};
1266
1279static int asus_platform_init(struct asus_laptop *asus) 1267static 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
1297fail_sysfs: 1287fail_sysfs:
1298 asus_sysfs_exit(asus);
1299 platform_device_del(asus->platform_device); 1288 platform_device_del(asus->platform_device);
1300fail_platform_device: 1289fail_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
1305static void asus_platform_exit(struct asus_laptop *asus) 1294static 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