diff options
-rw-r--r-- | drivers/input/misc/wistron_btns.c | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index b64798d838a2..3df30130e33c 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Wistron laptop button driver | 2 | * Wistron laptop button driver |
3 | * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> | 3 | * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> |
4 | * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> | 4 | * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> |
5 | * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru> | ||
5 | * | 6 | * |
6 | * You can redistribute and/or modify this program under the terms of the | 7 | * You can redistribute and/or modify this program under the terms of the |
7 | * GNU General Public License version 2 as published by the Free Software | 8 | * GNU General Public License version 2 as published by the Free Software |
@@ -28,6 +29,7 @@ | |||
28 | #include <linux/string.h> | 29 | #include <linux/string.h> |
29 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
30 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/platform_device.h> | ||
31 | 33 | ||
32 | /* | 34 | /* |
33 | * Number of attempts to read data from queue per poll; | 35 | * Number of attempts to read data from queue per poll; |
@@ -58,6 +60,8 @@ static char *keymap_name; /* = NULL; */ | |||
58 | module_param_named(keymap, keymap_name, charp, 0); | 60 | module_param_named(keymap, keymap_name, charp, 0); |
59 | MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected"); | 61 | MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected"); |
60 | 62 | ||
63 | static struct platform_device *wistron_device; | ||
64 | |||
61 | /* BIOS interface implementation */ | 65 | /* BIOS interface implementation */ |
62 | 66 | ||
63 | static void __iomem *bios_entry_point; /* BIOS routine entry point */ | 67 | static void __iomem *bios_entry_point; /* BIOS routine entry point */ |
@@ -356,6 +360,7 @@ static int __init setup_input_dev(void) | |||
356 | input_dev->name = "Wistron laptop buttons"; | 360 | input_dev->name = "Wistron laptop buttons"; |
357 | input_dev->phys = "wistron/input0"; | 361 | input_dev->phys = "wistron/input0"; |
358 | input_dev->id.bustype = BUS_HOST; | 362 | input_dev->id.bustype = BUS_HOST; |
363 | input_dev->cdev.dev = &wistron_device->dev; | ||
359 | 364 | ||
360 | for (key = keymap; key->type != KE_END; key++) { | 365 | for (key = keymap; key->type != KE_END; key++) { |
361 | if (key->type == KE_KEY) { | 366 | if (key->type == KE_KEY) { |
@@ -442,6 +447,34 @@ static void poll_bios(unsigned long discard) | |||
442 | mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY); | 447 | mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY); |
443 | } | 448 | } |
444 | 449 | ||
450 | static int wistron_suspend(struct platform_device *dev, pm_message_t state) | ||
451 | { | ||
452 | del_timer_sync(&poll_timer); | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | static int wistron_resume(struct platform_device *dev) | ||
458 | { | ||
459 | if (have_wifi) | ||
460 | bios_set_state(WIFI, wifi_enabled); | ||
461 | |||
462 | if (have_bluetooth) | ||
463 | bios_set_state(BLUETOOTH, bluetooth_enabled); | ||
464 | |||
465 | poll_bios(1); | ||
466 | |||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | static struct platform_driver wistron_driver = { | ||
471 | .suspend = wistron_suspend, | ||
472 | .resume = wistron_resume, | ||
473 | .driver = { | ||
474 | .name = "wistron-bios", | ||
475 | }, | ||
476 | }; | ||
477 | |||
445 | static int __init wb_module_init(void) | 478 | static int __init wb_module_init(void) |
446 | { | 479 | { |
447 | int err; | 480 | int err; |
@@ -457,6 +490,16 @@ static int __init wb_module_init(void) | |||
457 | bios_attach(); | 490 | bios_attach(); |
458 | cmos_address = bios_get_cmos_address(); | 491 | cmos_address = bios_get_cmos_address(); |
459 | 492 | ||
493 | err = platform_driver_register(&wistron_driver); | ||
494 | if (err) | ||
495 | goto err_detach_bios; | ||
496 | |||
497 | wistron_device = platform_device_register_simple("wistron-bios", -1, NULL, 0); | ||
498 | if (IS_ERR(wistron_device)) { | ||
499 | err = PTR_ERR(wistron_device); | ||
500 | goto err_unregister_driver; | ||
501 | } | ||
502 | |||
460 | if (have_wifi) { | 503 | if (have_wifi) { |
461 | u16 wifi = bios_get_default_setting(WIFI); | 504 | u16 wifi = bios_get_default_setting(WIFI); |
462 | if (wifi & 1) | 505 | if (wifi & 1) |
@@ -480,21 +523,30 @@ static int __init wb_module_init(void) | |||
480 | } | 523 | } |
481 | 524 | ||
482 | err = setup_input_dev(); | 525 | err = setup_input_dev(); |
483 | if (err) { | 526 | if (err) |
484 | bios_detach(); | 527 | goto err_unregister_device; |
485 | unmap_bios(); | ||
486 | return err; | ||
487 | } | ||
488 | 528 | ||
489 | poll_bios(1); /* Flush stale event queue and arm timer */ | 529 | poll_bios(1); /* Flush stale event queue and arm timer */ |
490 | 530 | ||
491 | return 0; | 531 | return 0; |
532 | |||
533 | err_unregister_device: | ||
534 | platform_device_unregister(wistron_device); | ||
535 | err_unregister_driver: | ||
536 | platform_driver_unregister(&wistron_driver); | ||
537 | err_detach_bios: | ||
538 | bios_detach(); | ||
539 | unmap_bios(); | ||
540 | |||
541 | return err; | ||
492 | } | 542 | } |
493 | 543 | ||
494 | static void __exit wb_module_exit(void) | 544 | static void __exit wb_module_exit(void) |
495 | { | 545 | { |
496 | del_timer_sync(&poll_timer); | 546 | del_timer_sync(&poll_timer); |
497 | input_unregister_device(input_dev); | 547 | input_unregister_device(input_dev); |
548 | platform_device_unregister(wistron_device); | ||
549 | platform_driver_unregister(&wistron_driver); | ||
498 | bios_detach(); | 550 | bios_detach(); |
499 | unmap_bios(); | 551 | unmap_bios(); |
500 | } | 552 | } |