aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorCorentin Chary <corentincj@iksaif.net>2010-11-29 02:14:05 -0500
committerMatthew Garrett <mjg@redhat.com>2011-01-07 17:03:42 -0500
commit27c136c8738f6bec10c26aaf0a486f19edef7bf7 (patch)
tree5de03b4c3b824e9d49ccc3acaf31f8f653eadf0a /drivers/platform
parent72135d21b587debcbcc57e0dbcc8bcfa4dacb661 (diff)
eeepc-wmi: rework eeepc_wmi_init and eeepc_wmi_exit
The old code was using platform_driver.probe to initialize eeepc_wmi context. That's a mistake because if probe fail, eeepc_platform_register() won't tell anyone, and chaos will happen. Wrap add and remove code inside eeepc_wmi_add() / eeepc_wmi_remove(), and try to use the static platform_device only in eeepc_wmi_init() and eeepc_wmi_exit() The code is now very similar to eeepc-laptop, except eeepc_laptop_add and eeepc_laptop_remove are called from acpi_driver, not module init/exit functions, but WMI doesn't provide such functionalities (yet ?). Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/eeepc-wmi.c135
1 files changed, 79 insertions, 56 deletions
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 0d50fbbe247..dfbb295326b 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -86,8 +86,10 @@ struct bios_args {
86struct eeepc_wmi { 86struct eeepc_wmi {
87 struct input_dev *inputdev; 87 struct input_dev *inputdev;
88 struct backlight_device *backlight_device; 88 struct backlight_device *backlight_device;
89 struct platform_device *platform_device;
89}; 90};
90 91
92/* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
91static struct platform_device *platform_device; 93static struct platform_device *platform_device;
92 94
93static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc) 95static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
@@ -101,7 +103,7 @@ static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
101 eeepc->inputdev->name = "Eee PC WMI hotkeys"; 103 eeepc->inputdev->name = "Eee PC WMI hotkeys";
102 eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0"; 104 eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
103 eeepc->inputdev->id.bustype = BUS_HOST; 105 eeepc->inputdev->id.bustype = BUS_HOST;
104 eeepc->inputdev->dev.parent = &platform_device->dev; 106 eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
105 107
106 err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL); 108 err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
107 if (err) 109 if (err)
@@ -234,7 +236,7 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
234 memset(&props, 0, sizeof(struct backlight_properties)); 236 memset(&props, 0, sizeof(struct backlight_properties));
235 props.max_brightness = 15; 237 props.max_brightness = 15;
236 bd = backlight_device_register(EEEPC_WMI_FILE, 238 bd = backlight_device_register(EEEPC_WMI_FILE,
237 &platform_device->dev, eeepc, 239 &eeepc->platform_device->dev, eeepc,
238 &eeepc_wmi_bl_ops, &props); 240 &eeepc_wmi_bl_ops, &props);
239 if (IS_ERR(bd)) { 241 if (IS_ERR(bd)) {
240 pr_err("Could not register backlight device\n"); 242 pr_err("Could not register backlight device\n");
@@ -337,49 +339,99 @@ static int eeepc_wmi_sysfs_init(struct platform_device *device)
337 return 0; 339 return 0;
338 340
339error_sysfs: 341error_sysfs:
340 eeepc_wmi_sysfs_exit(platform_device); 342 eeepc_wmi_sysfs_exit(device);
341 return retval; 343 return retval;
342} 344}
343 345
344static int __devinit eeepc_wmi_platform_probe(struct platform_device *device) 346/*
347 * Platform device
348 */
349static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc)
345{ 350{
346 struct eeepc_wmi *eeepc;
347 int err; 351 int err;
352
353 eeepc->platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
354 if (!eeepc->platform_device)
355 return -ENOMEM;
356 platform_set_drvdata(eeepc->platform_device, eeepc);
357
358 err = platform_device_add(eeepc->platform_device);
359 if (err)
360 goto fail_platform_device;
361
362 err = eeepc_wmi_sysfs_init(eeepc->platform_device);
363 if (err)
364 goto fail_sysfs;
365 return 0;
366
367fail_sysfs:
368 platform_device_del(eeepc->platform_device);
369fail_platform_device:
370 platform_device_put(eeepc->platform_device);
371 return err;
372}
373
374static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc)
375{
376 eeepc_wmi_sysfs_exit(eeepc->platform_device);
377 platform_device_unregister(eeepc->platform_device);
378}
379
380/*
381 * WMI Driver
382 */
383static struct platform_device * __init eeepc_wmi_add(void)
384{
385 struct eeepc_wmi *eeepc;
348 acpi_status status; 386 acpi_status status;
387 int err;
349 388
350 eeepc = platform_get_drvdata(device); 389 eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
390 if (!eeepc)
391 return ERR_PTR(-ENOMEM);
392
393 /*
394 * Register the platform device first. It is used as a parent for the
395 * sub-devices below.
396 */
397 err = eeepc_wmi_platform_init(eeepc);
398 if (err)
399 goto fail_platform;
351 400
352 err = eeepc_wmi_input_init(eeepc); 401 err = eeepc_wmi_input_init(eeepc);
353 if (err) 402 if (err)
354 goto error_input; 403 goto fail_input;
355 404
356 if (!acpi_video_backlight_support()) { 405 if (!acpi_video_backlight_support()) {
357 err = eeepc_wmi_backlight_init(eeepc); 406 err = eeepc_wmi_backlight_init(eeepc);
358 if (err) 407 if (err)
359 goto error_backlight; 408 goto fail_backlight;
360 } else 409 } else
361 pr_info("Backlight controlled by ACPI video driver\n"); 410 pr_info("Backlight controlled by ACPI video driver\n");
362 411
363 status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID, 412 status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
364 eeepc_wmi_notify, eeepc); 413 eeepc_wmi_notify, eeepc);
365 if (ACPI_FAILURE(status)) { 414 if (ACPI_FAILURE(status)) {
366 pr_err("Unable to register notify handler - %d\n", 415 pr_err("Unable to register notify handler - %d\n",
367 status); 416 status);
368 err = -ENODEV; 417 err = -ENODEV;
369 goto error_wmi; 418 goto fail_wmi_handler;
370 } 419 }
371 420
372 return 0; 421 return eeepc->platform_device;
373 422
374error_wmi: 423fail_wmi_handler:
375 eeepc_wmi_backlight_exit(eeepc); 424 eeepc_wmi_backlight_exit(eeepc);
376error_backlight: 425fail_backlight:
377 eeepc_wmi_input_exit(eeepc); 426 eeepc_wmi_input_exit(eeepc);
378error_input: 427fail_input:
379 return err; 428 eeepc_wmi_platform_exit(eeepc);
429fail_platform:
430 kfree(eeepc);
431 return ERR_PTR(err);
380} 432}
381 433
382static int __devexit eeepc_wmi_platform_remove(struct platform_device *device) 434static int eeepc_wmi_remove(struct platform_device *device)
383{ 435{
384 struct eeepc_wmi *eeepc; 436 struct eeepc_wmi *eeepc;
385 437
@@ -387,7 +439,9 @@ static int __devexit eeepc_wmi_platform_remove(struct platform_device *device)
387 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); 439 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
388 eeepc_wmi_backlight_exit(eeepc); 440 eeepc_wmi_backlight_exit(eeepc);
389 eeepc_wmi_input_exit(eeepc); 441 eeepc_wmi_input_exit(eeepc);
442 eeepc_wmi_platform_exit(eeepc);
390 443
444 kfree(eeepc);
391 return 0; 445 return 0;
392} 446}
393 447
@@ -396,13 +450,10 @@ static struct platform_driver platform_driver = {
396 .name = EEEPC_WMI_FILE, 450 .name = EEEPC_WMI_FILE,
397 .owner = THIS_MODULE, 451 .owner = THIS_MODULE,
398 }, 452 },
399 .probe = eeepc_wmi_platform_probe,
400 .remove = __devexit_p(eeepc_wmi_platform_remove),
401}; 453};
402 454
403static int __init eeepc_wmi_init(void) 455static int __init eeepc_wmi_init(void)
404{ 456{
405 struct eeepc_wmi *eeepc;
406 int err; 457 int err;
407 458
408 if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) || 459 if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
@@ -411,58 +462,30 @@ static int __init eeepc_wmi_init(void)
411 return -ENODEV; 462 return -ENODEV;
412 } 463 }
413 464
414 eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL); 465 platform_device = eeepc_wmi_add();
415 if (!eeepc) 466 if (IS_ERR(platform_device)) {
416 return -ENOMEM; 467 err = PTR_ERR(platform_device);
417 468 goto fail_eeepc_wmi;
418 platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
419 if (!platform_device) {
420 pr_warning("Unable to allocate platform device\n");
421 err = -ENOMEM;
422 goto fail_platform;
423 } 469 }
424 470
425 err = platform_device_add(platform_device);
426 if (err) {
427 pr_warning("Unable to add platform device\n");
428 goto put_dev;
429 }
430
431 platform_set_drvdata(platform_device, eeepc);
432
433 err = platform_driver_register(&platform_driver); 471 err = platform_driver_register(&platform_driver);
434 if (err) { 472 if (err) {
435 pr_warning("Unable to register platform driver\n"); 473 pr_warning("Unable to register platform driver\n");
436 goto del_dev; 474 goto fail_platform_driver;
437 } 475 }
438 476
439 err = eeepc_wmi_sysfs_init(platform_device);
440 if (err)
441 goto del_sysfs;
442
443 return 0; 477 return 0;
444 478
445del_sysfs: 479fail_platform_driver:
446 eeepc_wmi_sysfs_exit(platform_device); 480 eeepc_wmi_remove(platform_device);
447del_dev: 481fail_eeepc_wmi:
448 platform_device_del(platform_device);
449put_dev:
450 platform_device_put(platform_device);
451fail_platform:
452 kfree(eeepc);
453
454 return err; 482 return err;
455} 483}
456 484
457static void __exit eeepc_wmi_exit(void) 485static void __exit eeepc_wmi_exit(void)
458{ 486{
459 struct eeepc_wmi *eeepc; 487 eeepc_wmi_remove(platform_device);
460
461 eeepc_wmi_sysfs_exit(platform_device);
462 eeepc = platform_get_drvdata(platform_device);
463 platform_driver_unregister(&platform_driver); 488 platform_driver_unregister(&platform_driver);
464 platform_device_unregister(platform_device);
465 kfree(eeepc);
466} 489}
467 490
468module_init(eeepc_wmi_init); 491module_init(eeepc_wmi_init);