diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-26 20:20:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-26 20:20:18 -0500 |
commit | 98723153dc32106e5be701da15551853c9f785a9 (patch) | |
tree | a04631cbeb50703474ac4f5f20310f7ef53b2b38 | |
parent | 4cbd55188fe01f22783815cbb6d4f55a0ebf5969 (diff) | |
parent | 6335e4d56681f6f08f24f4b812a72d402793d393 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86:
toshiba_acpi: Add full hotkey support
hp-wmi: Add support for tablet rotation key
dell-laptop: Add another Dell laptop to the DMI whitelist
classmate-laptop: use a single MODULE_DEVICE_TABLE to get correct aliases
dell-laptop: Pay attention to which devices the hardware switch controls
dell-laptop: Use buffer with 32-bit physical address
dell-laptop: Blacklist machines not supporting dell-laptop
dell-laptop: Block software state changes when rfkill hard blocked
dell-laptop: Fix small memory leak
dell-laptop: Fix platform device unregistration
dell-laptop: Update rfkill state on kill switch
compal-laptop: Replace sysfs support with rfkill support
compal-laptop: Add support for known Compal made Dell laptops
MAINTAINERS: update drivers/platform/x86 information
-rw-r--r-- | MAINTAINERS | 29 | ||||
-rw-r--r-- | drivers/platform/x86/Kconfig | 1 | ||||
-rw-r--r-- | drivers/platform/x86/classmate-laptop.c | 31 | ||||
-rw-r--r-- | drivers/platform/x86/compal-laptop.c | 247 | ||||
-rw-r--r-- | drivers/platform/x86/dell-laptop.c | 256 | ||||
-rw-r--r-- | drivers/platform/x86/hp-wmi.c | 1 | ||||
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 206 |
7 files changed, 575 insertions, 196 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index a0491af7b243..2653b44f90da 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -221,6 +221,7 @@ F: drivers/net/acenic* | |||
221 | 221 | ||
222 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER | 222 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER |
223 | M: Peter Feuerer <peter@piie.net> | 223 | M: Peter Feuerer <peter@piie.net> |
224 | L: platform-driver-x86@vger.kernel.org | ||
224 | W: http://piie.net/?section=acerhdf | 225 | W: http://piie.net/?section=acerhdf |
225 | S: Maintained | 226 | S: Maintained |
226 | F: drivers/platform/x86/acerhdf.c | 227 | F: drivers/platform/x86/acerhdf.c |
@@ -228,6 +229,7 @@ F: drivers/platform/x86/acerhdf.c | |||
228 | ACER WMI LAPTOP EXTRAS | 229 | ACER WMI LAPTOP EXTRAS |
229 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | 230 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> |
230 | L: aceracpi@googlegroups.com (subscribers-only) | 231 | L: aceracpi@googlegroups.com (subscribers-only) |
232 | L: platform-driver-x86@vger.kernel.org | ||
231 | W: http://code.google.com/p/aceracpi | 233 | W: http://code.google.com/p/aceracpi |
232 | S: Maintained | 234 | S: Maintained |
233 | F: drivers/platform/x86/acer-wmi.c | 235 | F: drivers/platform/x86/acer-wmi.c |
@@ -288,7 +290,7 @@ F: drivers/acpi/video.c | |||
288 | 290 | ||
289 | ACPI WMI DRIVER | 291 | ACPI WMI DRIVER |
290 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | 292 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> |
291 | L: linux-acpi@vger.kernel.org | 293 | L: platform-driver-x86@vger.kernel.org |
292 | W: http://www.lesswatts.org/projects/acpi/ | 294 | W: http://www.lesswatts.org/projects/acpi/ |
293 | S: Maintained | 295 | S: Maintained |
294 | F: drivers/platform/x86/wmi.c | 296 | F: drivers/platform/x86/wmi.c |
@@ -968,6 +970,7 @@ ASUS ACPI EXTRAS DRIVER | |||
968 | M: Corentin Chary <corentincj@iksaif.net> | 970 | M: Corentin Chary <corentincj@iksaif.net> |
969 | M: Karol Kozimor <sziwan@users.sourceforge.net> | 971 | M: Karol Kozimor <sziwan@users.sourceforge.net> |
970 | L: acpi4asus-user@lists.sourceforge.net | 972 | L: acpi4asus-user@lists.sourceforge.net |
973 | L: platform-driver-x86@vger.kernel.org | ||
971 | W: http://acpi4asus.sf.net | 974 | W: http://acpi4asus.sf.net |
972 | S: Maintained | 975 | S: Maintained |
973 | F: drivers/platform/x86/asus_acpi.c | 976 | F: drivers/platform/x86/asus_acpi.c |
@@ -981,6 +984,7 @@ F: drivers/hwmon/asb100.c | |||
981 | ASUS LAPTOP EXTRAS DRIVER | 984 | ASUS LAPTOP EXTRAS DRIVER |
982 | M: Corentin Chary <corentincj@iksaif.net> | 985 | M: Corentin Chary <corentincj@iksaif.net> |
983 | L: acpi4asus-user@lists.sourceforge.net | 986 | L: acpi4asus-user@lists.sourceforge.net |
987 | L: platform-driver-x86@vger.kernel.org | ||
984 | W: http://acpi4asus.sf.net | 988 | W: http://acpi4asus.sf.net |
985 | S: Maintained | 989 | S: Maintained |
986 | F: drivers/platform/x86/asus-laptop.c | 990 | F: drivers/platform/x86/asus-laptop.c |
@@ -1473,6 +1477,7 @@ F: drivers/scsi/fnic/ | |||
1473 | CMPC ACPI DRIVER | 1477 | CMPC ACPI DRIVER |
1474 | M: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com> | 1478 | M: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com> |
1475 | M: Daniel Oliveira Nascimento <don@syst.com.br> | 1479 | M: Daniel Oliveira Nascimento <don@syst.com.br> |
1480 | L: platform-driver-x86@vger.kernel.org | ||
1476 | S: Supported | 1481 | S: Supported |
1477 | F: drivers/platform/x86/classmate-laptop.c | 1482 | F: drivers/platform/x86/classmate-laptop.c |
1478 | 1483 | ||
@@ -1516,6 +1521,7 @@ F: drivers/pci/hotplug/cpcihp_generic.c | |||
1516 | 1521 | ||
1517 | COMPAL LAPTOP SUPPORT | 1522 | COMPAL LAPTOP SUPPORT |
1518 | M: Cezary Jackiewicz <cezary.jackiewicz@gmail.com> | 1523 | M: Cezary Jackiewicz <cezary.jackiewicz@gmail.com> |
1524 | L: platform-driver-x86@vger.kernel.org | ||
1519 | S: Maintained | 1525 | S: Maintained |
1520 | F: drivers/platform/x86/compal-laptop.c | 1526 | F: drivers/platform/x86/compal-laptop.c |
1521 | 1527 | ||
@@ -1746,6 +1752,7 @@ F: drivers/net/defxx.* | |||
1746 | 1752 | ||
1747 | DELL LAPTOP DRIVER | 1753 | DELL LAPTOP DRIVER |
1748 | M: Matthew Garrett <mjg59@srcf.ucam.org> | 1754 | M: Matthew Garrett <mjg59@srcf.ucam.org> |
1755 | L: platform-driver-x86@vger.kernel.org | ||
1749 | S: Maintained | 1756 | S: Maintained |
1750 | F: drivers/platform/x86/dell-laptop.c | 1757 | F: drivers/platform/x86/dell-laptop.c |
1751 | 1758 | ||
@@ -2028,6 +2035,7 @@ F: drivers/edac/r82600_edac.c | |||
2028 | EEEPC LAPTOP EXTRAS DRIVER | 2035 | EEEPC LAPTOP EXTRAS DRIVER |
2029 | M: Corentin Chary <corentincj@iksaif.net> | 2036 | M: Corentin Chary <corentincj@iksaif.net> |
2030 | L: acpi4asus-user@lists.sourceforge.net | 2037 | L: acpi4asus-user@lists.sourceforge.net |
2038 | L: platform-driver-x86@vger.kernel.org | ||
2031 | W: http://acpi4asus.sf.net | 2039 | W: http://acpi4asus.sf.net |
2032 | S: Maintained | 2040 | S: Maintained |
2033 | F: drivers/platform/x86/eeepc-laptop.c | 2041 | F: drivers/platform/x86/eeepc-laptop.c |
@@ -2306,7 +2314,7 @@ F: arch/frv/ | |||
2306 | 2314 | ||
2307 | FUJITSU LAPTOP EXTRAS | 2315 | FUJITSU LAPTOP EXTRAS |
2308 | M: Jonathan Woithe <jwoithe@physics.adelaide.edu.au> | 2316 | M: Jonathan Woithe <jwoithe@physics.adelaide.edu.au> |
2309 | L: linux-acpi@vger.kernel.org | 2317 | L: platform-driver-x86@vger.kernel.org |
2310 | S: Maintained | 2318 | S: Maintained |
2311 | F: drivers/platform/x86/fujitsu-laptop.c | 2319 | F: drivers/platform/x86/fujitsu-laptop.c |
2312 | 2320 | ||
@@ -2584,6 +2592,7 @@ F: drivers/net/wireless/hostap/ | |||
2584 | 2592 | ||
2585 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER | 2593 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER |
2586 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | 2594 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> |
2595 | L: platform-driver-x86@vger.kernel.org | ||
2587 | S: Odd Fixes | 2596 | S: Odd Fixes |
2588 | F: drivers/platform/x86/tc1100-wmi.c | 2597 | F: drivers/platform/x86/tc1100-wmi.c |
2589 | 2598 | ||
@@ -2794,7 +2803,7 @@ F: drivers/video/i810/ | |||
2794 | 2803 | ||
2795 | INTEL MENLOW THERMAL DRIVER | 2804 | INTEL MENLOW THERMAL DRIVER |
2796 | M: Sujith Thomas <sujith.thomas@intel.com> | 2805 | M: Sujith Thomas <sujith.thomas@intel.com> |
2797 | L: linux-acpi@vger.kernel.org | 2806 | L: platform-driver-x86@vger.kernel.org |
2798 | W: http://www.lesswatts.org/projects/acpi/ | 2807 | W: http://www.lesswatts.org/projects/acpi/ |
2799 | S: Supported | 2808 | S: Supported |
2800 | F: drivers/platform/x86/intel_menlow.c | 2809 | F: drivers/platform/x86/intel_menlow.c |
@@ -3660,6 +3669,7 @@ F: drivers/char/mxser.* | |||
3660 | 3669 | ||
3661 | MSI LAPTOP SUPPORT | 3670 | MSI LAPTOP SUPPORT |
3662 | M: Lennart Poettering <mzxreary@0pointer.de> | 3671 | M: Lennart Poettering <mzxreary@0pointer.de> |
3672 | L: platform-driver-x86@vger.kernel.org | ||
3663 | W: https://tango.0pointer.de/mailman/listinfo/s270-linux | 3673 | W: https://tango.0pointer.de/mailman/listinfo/s270-linux |
3664 | W: http://0pointer.de/lennart/tchibo.html | 3674 | W: http://0pointer.de/lennart/tchibo.html |
3665 | S: Maintained | 3675 | S: Maintained |
@@ -3667,6 +3677,7 @@ F: drivers/platform/x86/msi-laptop.c | |||
3667 | 3677 | ||
3668 | MSI WMI SUPPORT | 3678 | MSI WMI SUPPORT |
3669 | M: Anisse Astier <anisse@astier.eu> | 3679 | M: Anisse Astier <anisse@astier.eu> |
3680 | L: platform-driver-x86@vger.kernel.org | ||
3670 | S: Supported | 3681 | S: Supported |
3671 | F: drivers/platform/x86/msi-wmi.c | 3682 | F: drivers/platform/x86/msi-wmi.c |
3672 | 3683 | ||
@@ -4119,6 +4130,7 @@ F: drivers/i2c/busses/i2c-pasemi.c | |||
4119 | 4130 | ||
4120 | PANASONIC LAPTOP ACPI EXTRAS DRIVER | 4131 | PANASONIC LAPTOP ACPI EXTRAS DRIVER |
4121 | M: Harald Welte <laforge@gnumonks.org> | 4132 | M: Harald Welte <laforge@gnumonks.org> |
4133 | L: platform-driver-x86@vger.kernel.org | ||
4122 | S: Maintained | 4134 | S: Maintained |
4123 | F: drivers/platform/x86/panasonic-laptop.c | 4135 | F: drivers/platform/x86/panasonic-laptop.c |
4124 | 4136 | ||
@@ -5064,7 +5076,7 @@ F: include/linux/ssb/ | |||
5064 | 5076 | ||
5065 | SONY VAIO CONTROL DEVICE DRIVER | 5077 | SONY VAIO CONTROL DEVICE DRIVER |
5066 | M: Mattia Dongili <malattia@linux.it> | 5078 | M: Mattia Dongili <malattia@linux.it> |
5067 | L: linux-acpi@vger.kernel.org | 5079 | L: platform-driver-x86@vger.kernel.org |
5068 | W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers | 5080 | W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers |
5069 | S: Maintained | 5081 | S: Maintained |
5070 | F: Documentation/laptops/sony-laptop.txt | 5082 | F: Documentation/laptops/sony-laptop.txt |
@@ -5270,6 +5282,7 @@ F: arch/xtensa/ | |||
5270 | THINKPAD ACPI EXTRAS DRIVER | 5282 | THINKPAD ACPI EXTRAS DRIVER |
5271 | M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> | 5283 | M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> |
5272 | L: ibm-acpi-devel@lists.sourceforge.net | 5284 | L: ibm-acpi-devel@lists.sourceforge.net |
5285 | L: platform-driver-x86@vger.kernel.org | ||
5273 | W: http://ibm-acpi.sourceforge.net | 5286 | W: http://ibm-acpi.sourceforge.net |
5274 | W: http://thinkwiki.org/wiki/Ibm-acpi | 5287 | W: http://thinkwiki.org/wiki/Ibm-acpi |
5275 | T: git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git | 5288 | T: git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git |
@@ -5323,10 +5336,12 @@ F: security/tomoyo/ | |||
5323 | 5336 | ||
5324 | TOPSTAR LAPTOP EXTRAS DRIVER | 5337 | TOPSTAR LAPTOP EXTRAS DRIVER |
5325 | M: Herton Ronaldo Krzesinski <herton@mandriva.com.br> | 5338 | M: Herton Ronaldo Krzesinski <herton@mandriva.com.br> |
5339 | L: platform-driver-x86@vger.kernel.org | ||
5326 | S: Maintained | 5340 | S: Maintained |
5327 | F: drivers/platform/x86/topstar-laptop.c | 5341 | F: drivers/platform/x86/topstar-laptop.c |
5328 | 5342 | ||
5329 | TOSHIBA ACPI EXTRAS DRIVER | 5343 | TOSHIBA ACPI EXTRAS DRIVER |
5344 | L: platform-driver-x86@vger.kernel.org | ||
5330 | S: Orphan | 5345 | S: Orphan |
5331 | F: drivers/platform/x86/toshiba_acpi.c | 5346 | F: drivers/platform/x86/toshiba_acpi.c |
5332 | 5347 | ||
@@ -6054,6 +6069,12 @@ S: Maintained | |||
6054 | F: Documentation/x86/ | 6069 | F: Documentation/x86/ |
6055 | F: arch/x86/ | 6070 | F: arch/x86/ |
6056 | 6071 | ||
6072 | X86 PLATFORM DRIVERS | ||
6073 | M: Matthew Garrett <mjg@redhat.com> | ||
6074 | L: platform-driver-x86@vger.kernel.org | ||
6075 | S: Maintained | ||
6076 | F: drivers/platform/x86 | ||
6077 | |||
6057 | XEN HYPERVISOR INTERFACE | 6078 | XEN HYPERVISOR INTERFACE |
6058 | M: Jeremy Fitzhardinge <jeremy@xensource.com> | 6079 | M: Jeremy Fitzhardinge <jeremy@xensource.com> |
6059 | M: Chris Wright <chrisw@sous-sol.org> | 6080 | M: Chris Wright <chrisw@sous-sol.org> |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index f526e735c5ab..6848f213eb53 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -79,6 +79,7 @@ config DELL_LAPTOP | |||
79 | depends on BACKLIGHT_CLASS_DEVICE | 79 | depends on BACKLIGHT_CLASS_DEVICE |
80 | depends on RFKILL || RFKILL = n | 80 | depends on RFKILL || RFKILL = n |
81 | depends on POWER_SUPPLY | 81 | depends on POWER_SUPPLY |
82 | depends on SERIO_I8042 | ||
82 | default n | 83 | default n |
83 | ---help--- | 84 | ---help--- |
84 | This driver adds support for rfkill and backlight control to Dell | 85 | This driver adds support for rfkill and backlight control to Dell |
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index ed90082cdf1d..8cb20e45bad6 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
@@ -34,6 +34,11 @@ struct cmpc_accel { | |||
34 | #define CMPC_ACCEL_SENSITIVITY_DEFAULT 5 | 34 | #define CMPC_ACCEL_SENSITIVITY_DEFAULT 5 |
35 | 35 | ||
36 | 36 | ||
37 | #define CMPC_ACCEL_HID "ACCE0000" | ||
38 | #define CMPC_TABLET_HID "TBLT0000" | ||
39 | #define CMPC_BL_HID "IPML200" | ||
40 | #define CMPC_KEYS_HID "FnBT0000" | ||
41 | |||
37 | /* | 42 | /* |
38 | * Generic input device code. | 43 | * Generic input device code. |
39 | */ | 44 | */ |
@@ -282,10 +287,9 @@ static int cmpc_accel_remove(struct acpi_device *acpi, int type) | |||
282 | } | 287 | } |
283 | 288 | ||
284 | static const struct acpi_device_id cmpc_accel_device_ids[] = { | 289 | static const struct acpi_device_id cmpc_accel_device_ids[] = { |
285 | {"ACCE0000", 0}, | 290 | {CMPC_ACCEL_HID, 0}, |
286 | {"", 0} | 291 | {"", 0} |
287 | }; | 292 | }; |
288 | MODULE_DEVICE_TABLE(acpi, cmpc_accel_device_ids); | ||
289 | 293 | ||
290 | static struct acpi_driver cmpc_accel_acpi_driver = { | 294 | static struct acpi_driver cmpc_accel_acpi_driver = { |
291 | .owner = THIS_MODULE, | 295 | .owner = THIS_MODULE, |
@@ -366,10 +370,9 @@ static int cmpc_tablet_resume(struct acpi_device *acpi) | |||
366 | } | 370 | } |
367 | 371 | ||
368 | static const struct acpi_device_id cmpc_tablet_device_ids[] = { | 372 | static const struct acpi_device_id cmpc_tablet_device_ids[] = { |
369 | {"TBLT0000", 0}, | 373 | {CMPC_TABLET_HID, 0}, |
370 | {"", 0} | 374 | {"", 0} |
371 | }; | 375 | }; |
372 | MODULE_DEVICE_TABLE(acpi, cmpc_tablet_device_ids); | ||
373 | 376 | ||
374 | static struct acpi_driver cmpc_tablet_acpi_driver = { | 377 | static struct acpi_driver cmpc_tablet_acpi_driver = { |
375 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
@@ -477,17 +480,16 @@ static int cmpc_bl_remove(struct acpi_device *acpi, int type) | |||
477 | return 0; | 480 | return 0; |
478 | } | 481 | } |
479 | 482 | ||
480 | static const struct acpi_device_id cmpc_device_ids[] = { | 483 | static const struct acpi_device_id cmpc_bl_device_ids[] = { |
481 | {"IPML200", 0}, | 484 | {CMPC_BL_HID, 0}, |
482 | {"", 0} | 485 | {"", 0} |
483 | }; | 486 | }; |
484 | MODULE_DEVICE_TABLE(acpi, cmpc_device_ids); | ||
485 | 487 | ||
486 | static struct acpi_driver cmpc_bl_acpi_driver = { | 488 | static struct acpi_driver cmpc_bl_acpi_driver = { |
487 | .owner = THIS_MODULE, | 489 | .owner = THIS_MODULE, |
488 | .name = "cmpc", | 490 | .name = "cmpc", |
489 | .class = "cmpc", | 491 | .class = "cmpc", |
490 | .ids = cmpc_device_ids, | 492 | .ids = cmpc_bl_device_ids, |
491 | .ops = { | 493 | .ops = { |
492 | .add = cmpc_bl_add, | 494 | .add = cmpc_bl_add, |
493 | .remove = cmpc_bl_remove | 495 | .remove = cmpc_bl_remove |
@@ -540,10 +542,9 @@ static int cmpc_keys_remove(struct acpi_device *acpi, int type) | |||
540 | } | 542 | } |
541 | 543 | ||
542 | static const struct acpi_device_id cmpc_keys_device_ids[] = { | 544 | static const struct acpi_device_id cmpc_keys_device_ids[] = { |
543 | {"FnBT0000", 0}, | 545 | {CMPC_KEYS_HID, 0}, |
544 | {"", 0} | 546 | {"", 0} |
545 | }; | 547 | }; |
546 | MODULE_DEVICE_TABLE(acpi, cmpc_keys_device_ids); | ||
547 | 548 | ||
548 | static struct acpi_driver cmpc_keys_acpi_driver = { | 549 | static struct acpi_driver cmpc_keys_acpi_driver = { |
549 | .owner = THIS_MODULE, | 550 | .owner = THIS_MODULE, |
@@ -607,3 +608,13 @@ static void cmpc_exit(void) | |||
607 | 608 | ||
608 | module_init(cmpc_init); | 609 | module_init(cmpc_init); |
609 | module_exit(cmpc_exit); | 610 | module_exit(cmpc_exit); |
611 | |||
612 | static const struct acpi_device_id cmpc_device_ids[] = { | ||
613 | {CMPC_ACCEL_HID, 0}, | ||
614 | {CMPC_TABLET_HID, 0}, | ||
615 | {CMPC_BL_HID, 0}, | ||
616 | {CMPC_KEYS_HID, 0}, | ||
617 | {"", 0} | ||
618 | }; | ||
619 | |||
620 | MODULE_DEVICE_TABLE(acpi, cmpc_device_ids); | ||
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 1a387e79f719..2740b40aad9b 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
@@ -26,17 +26,8 @@ | |||
26 | /* | 26 | /* |
27 | * comapl-laptop.c - Compal laptop support. | 27 | * comapl-laptop.c - Compal laptop support. |
28 | * | 28 | * |
29 | * This driver exports a few files in /sys/devices/platform/compal-laptop/: | 29 | * The driver registers itself with the rfkill subsystem and |
30 | * | 30 | * the Linux backlight control subsystem. |
31 | * wlan - wlan subsystem state: contains 0 or 1 (rw) | ||
32 | * | ||
33 | * bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw) | ||
34 | * | ||
35 | * raw - raw value taken from embedded controller register (ro) | ||
36 | * | ||
37 | * In addition to these platform device attributes the driver | ||
38 | * registers itself in the Linux backlight control subsystem and is | ||
39 | * available to userspace under /sys/class/backlight/compal-laptop/. | ||
40 | * | 31 | * |
41 | * This driver might work on other laptops produced by Compal. If you | 32 | * This driver might work on other laptops produced by Compal. If you |
42 | * want to try it you can pass force=1 as argument to the module which | 33 | * want to try it you can pass force=1 as argument to the module which |
@@ -51,6 +42,7 @@ | |||
51 | #include <linux/dmi.h> | 42 | #include <linux/dmi.h> |
52 | #include <linux/backlight.h> | 43 | #include <linux/backlight.h> |
53 | #include <linux/platform_device.h> | 44 | #include <linux/platform_device.h> |
45 | #include <linux/rfkill.h> | ||
54 | 46 | ||
55 | #define COMPAL_DRIVER_VERSION "0.2.6" | 47 | #define COMPAL_DRIVER_VERSION "0.2.6" |
56 | 48 | ||
@@ -63,6 +55,10 @@ | |||
63 | #define WLAN_MASK 0x01 | 55 | #define WLAN_MASK 0x01 |
64 | #define BT_MASK 0x02 | 56 | #define BT_MASK 0x02 |
65 | 57 | ||
58 | static struct rfkill *wifi_rfkill; | ||
59 | static struct rfkill *bt_rfkill; | ||
60 | static struct platform_device *compal_device; | ||
61 | |||
66 | static int force; | 62 | static int force; |
67 | module_param(force, bool, 0); | 63 | module_param(force, bool, 0); |
68 | MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); | 64 | MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); |
@@ -88,65 +84,75 @@ static int get_lcd_level(void) | |||
88 | return (int) result; | 84 | return (int) result; |
89 | } | 85 | } |
90 | 86 | ||
91 | static int set_wlan_state(int state) | 87 | static int compal_rfkill_set(void *data, bool blocked) |
92 | { | 88 | { |
89 | unsigned long radio = (unsigned long) data; | ||
93 | u8 result, value; | 90 | u8 result, value; |
94 | 91 | ||
95 | ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); | 92 | ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); |
96 | 93 | ||
97 | if ((result & KILLSWITCH_MASK) == 0) | 94 | if (!blocked) |
98 | return -EINVAL; | 95 | value = (u8) (result | radio); |
99 | else { | 96 | else |
100 | if (state) | 97 | value = (u8) (result & ~radio); |
101 | value = (u8) (result | WLAN_MASK); | 98 | ec_write(COMPAL_EC_COMMAND_WIRELESS, value); |
102 | else | ||
103 | value = (u8) (result & ~WLAN_MASK); | ||
104 | ec_write(COMPAL_EC_COMMAND_WIRELESS, value); | ||
105 | } | ||
106 | 99 | ||
107 | return 0; | 100 | return 0; |
108 | } | 101 | } |
109 | 102 | ||
110 | static int set_bluetooth_state(int state) | 103 | static void compal_rfkill_poll(struct rfkill *rfkill, void *data) |
111 | { | 104 | { |
112 | u8 result, value; | 105 | u8 result; |
106 | bool hw_blocked; | ||
113 | 107 | ||
114 | ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); | 108 | ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); |
115 | 109 | ||
116 | if ((result & KILLSWITCH_MASK) == 0) | 110 | hw_blocked = !(result & KILLSWITCH_MASK); |
117 | return -EINVAL; | 111 | rfkill_set_hw_state(rfkill, hw_blocked); |
118 | else { | ||
119 | if (state) | ||
120 | value = (u8) (result | BT_MASK); | ||
121 | else | ||
122 | value = (u8) (result & ~BT_MASK); | ||
123 | ec_write(COMPAL_EC_COMMAND_WIRELESS, value); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | 112 | } |
128 | 113 | ||
129 | static int get_wireless_state(int *wlan, int *bluetooth) | 114 | static const struct rfkill_ops compal_rfkill_ops = { |
115 | .poll = compal_rfkill_poll, | ||
116 | .set_block = compal_rfkill_set, | ||
117 | }; | ||
118 | |||
119 | static int setup_rfkill(void) | ||
130 | { | 120 | { |
131 | u8 result; | 121 | int ret; |
132 | 122 | ||
133 | ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); | 123 | wifi_rfkill = rfkill_alloc("compal-wifi", &compal_device->dev, |
124 | RFKILL_TYPE_WLAN, &compal_rfkill_ops, | ||
125 | (void *) WLAN_MASK); | ||
126 | if (!wifi_rfkill) | ||
127 | return -ENOMEM; | ||
134 | 128 | ||
135 | if (wlan) { | 129 | ret = rfkill_register(wifi_rfkill); |
136 | if ((result & KILLSWITCH_MASK) == 0) | 130 | if (ret) |
137 | *wlan = 0; | 131 | goto err_wifi; |
138 | else | ||
139 | *wlan = result & WLAN_MASK; | ||
140 | } | ||
141 | 132 | ||
142 | if (bluetooth) { | 133 | bt_rfkill = rfkill_alloc("compal-bluetooth", &compal_device->dev, |
143 | if ((result & KILLSWITCH_MASK) == 0) | 134 | RFKILL_TYPE_BLUETOOTH, &compal_rfkill_ops, |
144 | *bluetooth = 0; | 135 | (void *) BT_MASK); |
145 | else | 136 | if (!bt_rfkill) { |
146 | *bluetooth = (result & BT_MASK) >> 1; | 137 | ret = -ENOMEM; |
138 | goto err_allocate_bt; | ||
147 | } | 139 | } |
140 | ret = rfkill_register(bt_rfkill); | ||
141 | if (ret) | ||
142 | goto err_register_bt; | ||
148 | 143 | ||
149 | return 0; | 144 | return 0; |
145 | |||
146 | err_register_bt: | ||
147 | rfkill_destroy(bt_rfkill); | ||
148 | |||
149 | err_allocate_bt: | ||
150 | rfkill_unregister(wifi_rfkill); | ||
151 | |||
152 | err_wifi: | ||
153 | rfkill_destroy(wifi_rfkill); | ||
154 | |||
155 | return ret; | ||
150 | } | 156 | } |
151 | 157 | ||
152 | /* Backlight device stuff */ | 158 | /* Backlight device stuff */ |
@@ -169,86 +175,6 @@ static struct backlight_ops compalbl_ops = { | |||
169 | 175 | ||
170 | static struct backlight_device *compalbl_device; | 176 | static struct backlight_device *compalbl_device; |
171 | 177 | ||
172 | /* Platform device */ | ||
173 | |||
174 | static ssize_t show_wlan(struct device *dev, | ||
175 | struct device_attribute *attr, char *buf) | ||
176 | { | ||
177 | int ret, enabled; | ||
178 | |||
179 | ret = get_wireless_state(&enabled, NULL); | ||
180 | if (ret < 0) | ||
181 | return ret; | ||
182 | |||
183 | return sprintf(buf, "%i\n", enabled); | ||
184 | } | ||
185 | |||
186 | static ssize_t show_raw(struct device *dev, | ||
187 | struct device_attribute *attr, char *buf) | ||
188 | { | ||
189 | u8 result; | ||
190 | |||
191 | ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); | ||
192 | |||
193 | return sprintf(buf, "%i\n", result); | ||
194 | } | ||
195 | |||
196 | static ssize_t show_bluetooth(struct device *dev, | ||
197 | struct device_attribute *attr, char *buf) | ||
198 | { | ||
199 | int ret, enabled; | ||
200 | |||
201 | ret = get_wireless_state(NULL, &enabled); | ||
202 | if (ret < 0) | ||
203 | return ret; | ||
204 | |||
205 | return sprintf(buf, "%i\n", enabled); | ||
206 | } | ||
207 | |||
208 | static ssize_t store_wlan_state(struct device *dev, | ||
209 | struct device_attribute *attr, const char *buf, size_t count) | ||
210 | { | ||
211 | int state, ret; | ||
212 | |||
213 | if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1)) | ||
214 | return -EINVAL; | ||
215 | |||
216 | ret = set_wlan_state(state); | ||
217 | if (ret < 0) | ||
218 | return ret; | ||
219 | |||
220 | return count; | ||
221 | } | ||
222 | |||
223 | static ssize_t store_bluetooth_state(struct device *dev, | ||
224 | struct device_attribute *attr, const char *buf, size_t count) | ||
225 | { | ||
226 | int state, ret; | ||
227 | |||
228 | if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1)) | ||
229 | return -EINVAL; | ||
230 | |||
231 | ret = set_bluetooth_state(state); | ||
232 | if (ret < 0) | ||
233 | return ret; | ||
234 | |||
235 | return count; | ||
236 | } | ||
237 | |||
238 | static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state); | ||
239 | static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state); | ||
240 | static DEVICE_ATTR(raw, 0444, show_raw, NULL); | ||
241 | |||
242 | static struct attribute *compal_attributes[] = { | ||
243 | &dev_attr_bluetooth.attr, | ||
244 | &dev_attr_wlan.attr, | ||
245 | &dev_attr_raw.attr, | ||
246 | NULL | ||
247 | }; | ||
248 | |||
249 | static struct attribute_group compal_attribute_group = { | ||
250 | .attrs = compal_attributes | ||
251 | }; | ||
252 | 178 | ||
253 | static struct platform_driver compal_driver = { | 179 | static struct platform_driver compal_driver = { |
254 | .driver = { | 180 | .driver = { |
@@ -257,8 +183,6 @@ static struct platform_driver compal_driver = { | |||
257 | } | 183 | } |
258 | }; | 184 | }; |
259 | 185 | ||
260 | static struct platform_device *compal_device; | ||
261 | |||
262 | /* Initialization */ | 186 | /* Initialization */ |
263 | 187 | ||
264 | static int dmi_check_cb(const struct dmi_system_id *id) | 188 | static int dmi_check_cb(const struct dmi_system_id *id) |
@@ -310,6 +234,47 @@ static struct dmi_system_id __initdata compal_dmi_table[] = { | |||
310 | }, | 234 | }, |
311 | .callback = dmi_check_cb | 235 | .callback = dmi_check_cb |
312 | }, | 236 | }, |
237 | { | ||
238 | .ident = "Dell Mini 9", | ||
239 | .matches = { | ||
240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
241 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 910"), | ||
242 | }, | ||
243 | .callback = dmi_check_cb | ||
244 | }, | ||
245 | { | ||
246 | .ident = "Dell Mini 10", | ||
247 | .matches = { | ||
248 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
249 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1010"), | ||
250 | }, | ||
251 | .callback = dmi_check_cb | ||
252 | }, | ||
253 | { | ||
254 | .ident = "Dell Mini 10v", | ||
255 | .matches = { | ||
256 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
257 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"), | ||
258 | }, | ||
259 | .callback = dmi_check_cb | ||
260 | }, | ||
261 | { | ||
262 | .ident = "Dell Inspiron 11z", | ||
263 | .matches = { | ||
264 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
265 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1110"), | ||
266 | }, | ||
267 | .callback = dmi_check_cb | ||
268 | }, | ||
269 | { | ||
270 | .ident = "Dell Mini 12", | ||
271 | .matches = { | ||
272 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
273 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1210"), | ||
274 | }, | ||
275 | .callback = dmi_check_cb | ||
276 | }, | ||
277 | |||
313 | { } | 278 | { } |
314 | }; | 279 | }; |
315 | 280 | ||
@@ -348,23 +313,21 @@ static int __init compal_init(void) | |||
348 | 313 | ||
349 | ret = platform_device_add(compal_device); | 314 | ret = platform_device_add(compal_device); |
350 | if (ret) | 315 | if (ret) |
351 | goto fail_platform_device1; | 316 | goto fail_platform_device; |
352 | 317 | ||
353 | ret = sysfs_create_group(&compal_device->dev.kobj, | 318 | ret = setup_rfkill(); |
354 | &compal_attribute_group); | ||
355 | if (ret) | 319 | if (ret) |
356 | goto fail_platform_device2; | 320 | goto fail_rfkill; |
357 | 321 | ||
358 | printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION | 322 | printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION |
359 | " successfully loaded.\n"); | 323 | " successfully loaded.\n"); |
360 | 324 | ||
361 | return 0; | 325 | return 0; |
362 | 326 | ||
363 | fail_platform_device2: | 327 | fail_rfkill: |
364 | |||
365 | platform_device_del(compal_device); | 328 | platform_device_del(compal_device); |
366 | 329 | ||
367 | fail_platform_device1: | 330 | fail_platform_device: |
368 | 331 | ||
369 | platform_device_put(compal_device); | 332 | platform_device_put(compal_device); |
370 | 333 | ||
@@ -382,10 +345,13 @@ fail_backlight: | |||
382 | static void __exit compal_cleanup(void) | 345 | static void __exit compal_cleanup(void) |
383 | { | 346 | { |
384 | 347 | ||
385 | sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group); | ||
386 | platform_device_unregister(compal_device); | 348 | platform_device_unregister(compal_device); |
387 | platform_driver_unregister(&compal_driver); | 349 | platform_driver_unregister(&compal_driver); |
388 | backlight_device_unregister(compalbl_device); | 350 | backlight_device_unregister(compalbl_device); |
351 | rfkill_unregister(wifi_rfkill); | ||
352 | rfkill_destroy(wifi_rfkill); | ||
353 | rfkill_unregister(bt_rfkill); | ||
354 | rfkill_destroy(bt_rfkill); | ||
389 | 355 | ||
390 | printk(KERN_INFO "compal-laptop: driver unloaded.\n"); | 356 | printk(KERN_INFO "compal-laptop: driver unloaded.\n"); |
391 | } | 357 | } |
@@ -403,3 +369,8 @@ MODULE_ALIAS("dmi:*:rnIFL90:rvrREFERENCE:*"); | |||
403 | MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*"); | 369 | MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*"); |
404 | MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*"); | 370 | MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*"); |
405 | MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*"); | 371 | MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*"); |
372 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*"); | ||
373 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*"); | ||
374 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*"); | ||
375 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*"); | ||
376 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*"); | ||
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 3780994dc8f2..b7f4d2705916 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/rfkill.h> | 22 | #include <linux/rfkill.h> |
23 | #include <linux/power_supply.h> | 23 | #include <linux/power_supply.h> |
24 | #include <linux/acpi.h> | 24 | #include <linux/acpi.h> |
25 | #include <linux/mm.h> | ||
26 | #include <linux/i8042.h> | ||
25 | #include "../../firmware/dcdbas.h" | 27 | #include "../../firmware/dcdbas.h" |
26 | 28 | ||
27 | #define BRIGHTNESS_TOKEN 0x7d | 29 | #define BRIGHTNESS_TOKEN 0x7d |
@@ -79,9 +81,73 @@ static const struct dmi_system_id __initdata dell_device_table[] = { | |||
79 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), | 81 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), |
80 | }, | 82 | }, |
81 | }, | 83 | }, |
84 | { | ||
85 | .ident = "Dell Computer Corporation", | ||
86 | .matches = { | ||
87 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | ||
88 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), | ||
89 | }, | ||
90 | }, | ||
82 | { } | 91 | { } |
83 | }; | 92 | }; |
84 | 93 | ||
94 | static struct dmi_system_id __devinitdata dell_blacklist[] = { | ||
95 | /* Supported by compal-laptop */ | ||
96 | { | ||
97 | .ident = "Dell Mini 9", | ||
98 | .matches = { | ||
99 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
100 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 910"), | ||
101 | }, | ||
102 | }, | ||
103 | { | ||
104 | .ident = "Dell Mini 10", | ||
105 | .matches = { | ||
106 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
107 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1010"), | ||
108 | }, | ||
109 | }, | ||
110 | { | ||
111 | .ident = "Dell Mini 10v", | ||
112 | .matches = { | ||
113 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
114 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"), | ||
115 | }, | ||
116 | }, | ||
117 | { | ||
118 | .ident = "Dell Inspiron 11z", | ||
119 | .matches = { | ||
120 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
121 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1110"), | ||
122 | }, | ||
123 | }, | ||
124 | { | ||
125 | .ident = "Dell Mini 12", | ||
126 | .matches = { | ||
127 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
128 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1210"), | ||
129 | }, | ||
130 | }, | ||
131 | {} | ||
132 | }; | ||
133 | |||
134 | static struct calling_interface_buffer *buffer; | ||
135 | struct page *bufferpage; | ||
136 | DEFINE_MUTEX(buffer_mutex); | ||
137 | |||
138 | static int hwswitch_state; | ||
139 | |||
140 | static void get_buffer(void) | ||
141 | { | ||
142 | mutex_lock(&buffer_mutex); | ||
143 | memset(buffer, 0, sizeof(struct calling_interface_buffer)); | ||
144 | } | ||
145 | |||
146 | static void release_buffer(void) | ||
147 | { | ||
148 | mutex_unlock(&buffer_mutex); | ||
149 | } | ||
150 | |||
85 | static void __init parse_da_table(const struct dmi_header *dm) | 151 | static void __init parse_da_table(const struct dmi_header *dm) |
86 | { | 152 | { |
87 | /* Final token is a terminator, so we don't want to copy it */ | 153 | /* Final token is a terminator, so we don't want to copy it */ |
@@ -160,6 +226,8 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, | |||
160 | /* Derived from information in DellWirelessCtl.cpp: | 226 | /* Derived from information in DellWirelessCtl.cpp: |
161 | Class 17, select 11 is radio control. It returns an array of 32-bit values. | 227 | Class 17, select 11 is radio control. It returns an array of 32-bit values. |
162 | 228 | ||
229 | Input byte 0 = 0: Wireless information | ||
230 | |||
163 | result[0]: return code | 231 | result[0]: return code |
164 | result[1]: | 232 | result[1]: |
165 | Bit 0: Hardware switch supported | 233 | Bit 0: Hardware switch supported |
@@ -180,33 +248,62 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, | |||
180 | Bits 20-31: Reserved | 248 | Bits 20-31: Reserved |
181 | result[2]: NVRAM size in bytes | 249 | result[2]: NVRAM size in bytes |
182 | result[3]: NVRAM format version number | 250 | result[3]: NVRAM format version number |
251 | |||
252 | Input byte 0 = 2: Wireless switch configuration | ||
253 | result[0]: return code | ||
254 | result[1]: | ||
255 | Bit 0: Wifi controlled by switch | ||
256 | Bit 1: Bluetooth controlled by switch | ||
257 | Bit 2: WWAN controlled by switch | ||
258 | Bits 3-6: Reserved | ||
259 | Bit 7: Wireless switch config locked | ||
260 | Bit 8: Wifi locator enabled | ||
261 | Bits 9-14: Reserved | ||
262 | Bit 15: Wifi locator setting locked | ||
263 | Bits 16-31: Reserved | ||
183 | */ | 264 | */ |
184 | 265 | ||
185 | static int dell_rfkill_set(void *data, bool blocked) | 266 | static int dell_rfkill_set(void *data, bool blocked) |
186 | { | 267 | { |
187 | struct calling_interface_buffer buffer; | ||
188 | int disable = blocked ? 1 : 0; | 268 | int disable = blocked ? 1 : 0; |
189 | unsigned long radio = (unsigned long)data; | 269 | unsigned long radio = (unsigned long)data; |
270 | int hwswitch_bit = (unsigned long)data - 1; | ||
271 | int ret = 0; | ||
272 | |||
273 | get_buffer(); | ||
274 | dell_send_request(buffer, 17, 11); | ||
275 | |||
276 | /* If the hardware switch controls this radio, and the hardware | ||
277 | switch is disabled, don't allow changing the software state */ | ||
278 | if ((hwswitch_state & BIT(hwswitch_bit)) && | ||
279 | !(buffer->output[1] & BIT(16))) { | ||
280 | ret = -EINVAL; | ||
281 | goto out; | ||
282 | } | ||
190 | 283 | ||
191 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 284 | buffer->input[0] = (1 | (radio<<8) | (disable << 16)); |
192 | buffer.input[0] = (1 | (radio<<8) | (disable << 16)); | 285 | dell_send_request(buffer, 17, 11); |
193 | dell_send_request(&buffer, 17, 11); | ||
194 | 286 | ||
195 | return 0; | 287 | out: |
288 | release_buffer(); | ||
289 | return ret; | ||
196 | } | 290 | } |
197 | 291 | ||
198 | static void dell_rfkill_query(struct rfkill *rfkill, void *data) | 292 | static void dell_rfkill_query(struct rfkill *rfkill, void *data) |
199 | { | 293 | { |
200 | struct calling_interface_buffer buffer; | ||
201 | int status; | 294 | int status; |
202 | int bit = (unsigned long)data + 16; | 295 | int bit = (unsigned long)data + 16; |
296 | int hwswitch_bit = (unsigned long)data - 1; | ||
203 | 297 | ||
204 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 298 | get_buffer(); |
205 | dell_send_request(&buffer, 17, 11); | 299 | dell_send_request(buffer, 17, 11); |
206 | status = buffer.output[1]; | 300 | status = buffer->output[1]; |
301 | release_buffer(); | ||
207 | 302 | ||
208 | rfkill_set_sw_state(rfkill, !!(status & BIT(bit))); | 303 | rfkill_set_sw_state(rfkill, !!(status & BIT(bit))); |
209 | rfkill_set_hw_state(rfkill, !(status & BIT(16))); | 304 | |
305 | if (hwswitch_state & (BIT(hwswitch_bit))) | ||
306 | rfkill_set_hw_state(rfkill, !(status & BIT(16))); | ||
210 | } | 307 | } |
211 | 308 | ||
212 | static const struct rfkill_ops dell_rfkill_ops = { | 309 | static const struct rfkill_ops dell_rfkill_ops = { |
@@ -214,15 +311,36 @@ static const struct rfkill_ops dell_rfkill_ops = { | |||
214 | .query = dell_rfkill_query, | 311 | .query = dell_rfkill_query, |
215 | }; | 312 | }; |
216 | 313 | ||
314 | static void dell_update_rfkill(struct work_struct *ignored) | ||
315 | { | ||
316 | if (wifi_rfkill) | ||
317 | dell_rfkill_query(wifi_rfkill, (void *)1); | ||
318 | if (bluetooth_rfkill) | ||
319 | dell_rfkill_query(bluetooth_rfkill, (void *)2); | ||
320 | if (wwan_rfkill) | ||
321 | dell_rfkill_query(wwan_rfkill, (void *)3); | ||
322 | } | ||
323 | static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); | ||
324 | |||
325 | |||
217 | static int __init dell_setup_rfkill(void) | 326 | static int __init dell_setup_rfkill(void) |
218 | { | 327 | { |
219 | struct calling_interface_buffer buffer; | ||
220 | int status; | 328 | int status; |
221 | int ret; | 329 | int ret; |
222 | 330 | ||
223 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 331 | if (dmi_check_system(dell_blacklist)) { |
224 | dell_send_request(&buffer, 17, 11); | 332 | printk(KERN_INFO "dell-laptop: Blacklisted hardware detected - " |
225 | status = buffer.output[1]; | 333 | "not enabling rfkill\n"); |
334 | return 0; | ||
335 | } | ||
336 | |||
337 | get_buffer(); | ||
338 | dell_send_request(buffer, 17, 11); | ||
339 | status = buffer->output[1]; | ||
340 | buffer->input[0] = 0x2; | ||
341 | dell_send_request(buffer, 17, 11); | ||
342 | hwswitch_state = buffer->output[1]; | ||
343 | release_buffer(); | ||
226 | 344 | ||
227 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { | 345 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { |
228 | wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, | 346 | wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, |
@@ -298,39 +416,49 @@ static void dell_cleanup_rfkill(void) | |||
298 | 416 | ||
299 | static int dell_send_intensity(struct backlight_device *bd) | 417 | static int dell_send_intensity(struct backlight_device *bd) |
300 | { | 418 | { |
301 | struct calling_interface_buffer buffer; | 419 | int ret = 0; |
302 | 420 | ||
303 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 421 | get_buffer(); |
304 | buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); | 422 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); |
305 | buffer.input[1] = bd->props.brightness; | 423 | buffer->input[1] = bd->props.brightness; |
306 | 424 | ||
307 | if (buffer.input[0] == -1) | 425 | if (buffer->input[0] == -1) { |
308 | return -ENODEV; | 426 | ret = -ENODEV; |
427 | goto out; | ||
428 | } | ||
309 | 429 | ||
310 | if (power_supply_is_system_supplied() > 0) | 430 | if (power_supply_is_system_supplied() > 0) |
311 | dell_send_request(&buffer, 1, 2); | 431 | dell_send_request(buffer, 1, 2); |
312 | else | 432 | else |
313 | dell_send_request(&buffer, 1, 1); | 433 | dell_send_request(buffer, 1, 1); |
314 | 434 | ||
435 | out: | ||
436 | release_buffer(); | ||
315 | return 0; | 437 | return 0; |
316 | } | 438 | } |
317 | 439 | ||
318 | static int dell_get_intensity(struct backlight_device *bd) | 440 | static int dell_get_intensity(struct backlight_device *bd) |
319 | { | 441 | { |
320 | struct calling_interface_buffer buffer; | 442 | int ret = 0; |
321 | 443 | ||
322 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 444 | get_buffer(); |
323 | buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); | 445 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); |
324 | 446 | ||
325 | if (buffer.input[0] == -1) | 447 | if (buffer->input[0] == -1) { |
326 | return -ENODEV; | 448 | ret = -ENODEV; |
449 | goto out; | ||
450 | } | ||
327 | 451 | ||
328 | if (power_supply_is_system_supplied() > 0) | 452 | if (power_supply_is_system_supplied() > 0) |
329 | dell_send_request(&buffer, 0, 2); | 453 | dell_send_request(buffer, 0, 2); |
330 | else | 454 | else |
331 | dell_send_request(&buffer, 0, 1); | 455 | dell_send_request(buffer, 0, 1); |
332 | 456 | ||
333 | return buffer.output[1]; | 457 | out: |
458 | release_buffer(); | ||
459 | if (ret) | ||
460 | return ret; | ||
461 | return buffer->output[1]; | ||
334 | } | 462 | } |
335 | 463 | ||
336 | static struct backlight_ops dell_ops = { | 464 | static struct backlight_ops dell_ops = { |
@@ -338,9 +466,32 @@ static struct backlight_ops dell_ops = { | |||
338 | .update_status = dell_send_intensity, | 466 | .update_status = dell_send_intensity, |
339 | }; | 467 | }; |
340 | 468 | ||
469 | bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, | ||
470 | struct serio *port) | ||
471 | { | ||
472 | static bool extended; | ||
473 | |||
474 | if (str & 0x20) | ||
475 | return false; | ||
476 | |||
477 | if (unlikely(data == 0xe0)) { | ||
478 | extended = true; | ||
479 | return false; | ||
480 | } else if (unlikely(extended)) { | ||
481 | switch (data) { | ||
482 | case 0x8: | ||
483 | schedule_delayed_work(&dell_rfkill_work, | ||
484 | round_jiffies_relative(HZ)); | ||
485 | break; | ||
486 | } | ||
487 | extended = false; | ||
488 | } | ||
489 | |||
490 | return false; | ||
491 | } | ||
492 | |||
341 | static int __init dell_init(void) | 493 | static int __init dell_init(void) |
342 | { | 494 | { |
343 | struct calling_interface_buffer buffer; | ||
344 | int max_intensity = 0; | 495 | int max_intensity = 0; |
345 | int ret; | 496 | int ret; |
346 | 497 | ||
@@ -366,6 +517,17 @@ static int __init dell_init(void) | |||
366 | if (ret) | 517 | if (ret) |
367 | goto fail_platform_device2; | 518 | goto fail_platform_device2; |
368 | 519 | ||
520 | /* | ||
521 | * Allocate buffer below 4GB for SMI data--only 32-bit physical addr | ||
522 | * is passed to SMI handler. | ||
523 | */ | ||
524 | bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32); | ||
525 | |||
526 | if (!bufferpage) | ||
527 | goto fail_buffer; | ||
528 | buffer = page_address(bufferpage); | ||
529 | mutex_init(&buffer_mutex); | ||
530 | |||
369 | ret = dell_setup_rfkill(); | 531 | ret = dell_setup_rfkill(); |
370 | 532 | ||
371 | if (ret) { | 533 | if (ret) { |
@@ -373,6 +535,13 @@ static int __init dell_init(void) | |||
373 | goto fail_rfkill; | 535 | goto fail_rfkill; |
374 | } | 536 | } |
375 | 537 | ||
538 | ret = i8042_install_filter(dell_laptop_i8042_filter); | ||
539 | if (ret) { | ||
540 | printk(KERN_WARNING | ||
541 | "dell-laptop: Unable to install key filter\n"); | ||
542 | goto fail_filter; | ||
543 | } | ||
544 | |||
376 | #ifdef CONFIG_ACPI | 545 | #ifdef CONFIG_ACPI |
377 | /* In the event of an ACPI backlight being available, don't | 546 | /* In the event of an ACPI backlight being available, don't |
378 | * register the platform controller. | 547 | * register the platform controller. |
@@ -381,13 +550,13 @@ static int __init dell_init(void) | |||
381 | return 0; | 550 | return 0; |
382 | #endif | 551 | #endif |
383 | 552 | ||
384 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 553 | get_buffer(); |
385 | buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); | 554 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); |
386 | 555 | if (buffer->input[0] != -1) { | |
387 | if (buffer.input[0] != -1) { | 556 | dell_send_request(buffer, 0, 2); |
388 | dell_send_request(&buffer, 0, 2); | 557 | max_intensity = buffer->output[3]; |
389 | max_intensity = buffer.output[3]; | ||
390 | } | 558 | } |
559 | release_buffer(); | ||
391 | 560 | ||
392 | if (max_intensity) { | 561 | if (max_intensity) { |
393 | dell_backlight_device = backlight_device_register( | 562 | dell_backlight_device = backlight_device_register( |
@@ -410,8 +579,12 @@ static int __init dell_init(void) | |||
410 | return 0; | 579 | return 0; |
411 | 580 | ||
412 | fail_backlight: | 581 | fail_backlight: |
582 | i8042_remove_filter(dell_laptop_i8042_filter); | ||
583 | fail_filter: | ||
413 | dell_cleanup_rfkill(); | 584 | dell_cleanup_rfkill(); |
414 | fail_rfkill: | 585 | fail_rfkill: |
586 | free_page((unsigned long)bufferpage); | ||
587 | fail_buffer: | ||
415 | platform_device_del(platform_device); | 588 | platform_device_del(platform_device); |
416 | fail_platform_device2: | 589 | fail_platform_device2: |
417 | platform_device_put(platform_device); | 590 | platform_device_put(platform_device); |
@@ -424,8 +597,16 @@ fail_platform_driver: | |||
424 | 597 | ||
425 | static void __exit dell_exit(void) | 598 | static void __exit dell_exit(void) |
426 | { | 599 | { |
600 | cancel_delayed_work_sync(&dell_rfkill_work); | ||
601 | i8042_remove_filter(dell_laptop_i8042_filter); | ||
427 | backlight_device_unregister(dell_backlight_device); | 602 | backlight_device_unregister(dell_backlight_device); |
428 | dell_cleanup_rfkill(); | 603 | dell_cleanup_rfkill(); |
604 | if (platform_device) { | ||
605 | platform_device_del(platform_device); | ||
606 | platform_driver_unregister(&platform_driver); | ||
607 | } | ||
608 | kfree(da_tokens); | ||
609 | free_page((unsigned long)buffer); | ||
429 | } | 610 | } |
430 | 611 | ||
431 | module_init(dell_init); | 612 | module_init(dell_init); |
@@ -435,3 +616,4 @@ MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | |||
435 | MODULE_DESCRIPTION("Dell laptop driver"); | 616 | MODULE_DESCRIPTION("Dell laptop driver"); |
436 | MODULE_LICENSE("GPL"); | 617 | MODULE_LICENSE("GPL"); |
437 | MODULE_ALIAS("dmi:*svnDellInc.:*:ct8:*"); | 618 | MODULE_ALIAS("dmi:*svnDellInc.:*:ct8:*"); |
619 | MODULE_ALIAS("dmi:*svnDellComputerCorporation.:*:ct8:*"); | ||
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index ad4c414dbfbc..3aa57da8b43b 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -89,6 +89,7 @@ static struct key_entry hp_wmi_keymap[] = { | |||
89 | {KE_KEY, 0x20e6, KEY_PROG1}, | 89 | {KE_KEY, 0x20e6, KEY_PROG1}, |
90 | {KE_KEY, 0x2142, KEY_MEDIA}, | 90 | {KE_KEY, 0x2142, KEY_MEDIA}, |
91 | {KE_KEY, 0x213b, KEY_INFO}, | 91 | {KE_KEY, 0x213b, KEY_INFO}, |
92 | {KE_KEY, 0x2169, KEY_DIRECTION}, | ||
92 | {KE_KEY, 0x231b, KEY_HELP}, | 93 | {KE_KEY, 0x231b, KEY_HELP}, |
93 | {KE_END, 0} | 94 | {KE_END, 0} |
94 | }; | 95 | }; |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 77bf5d8f893a..26c211724acf 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/backlight.h> | 46 | #include <linux/backlight.h> |
47 | #include <linux/platform_device.h> | 47 | #include <linux/platform_device.h> |
48 | #include <linux/rfkill.h> | 48 | #include <linux/rfkill.h> |
49 | #include <linux/input.h> | ||
49 | 50 | ||
50 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
51 | 52 | ||
@@ -62,9 +63,10 @@ MODULE_LICENSE("GPL"); | |||
62 | 63 | ||
63 | /* Toshiba ACPI method paths */ | 64 | /* Toshiba ACPI method paths */ |
64 | #define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" | 65 | #define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" |
65 | #define METHOD_HCI_1 "\\_SB_.VALD.GHCI" | 66 | #define TOSH_INTERFACE_1 "\\_SB_.VALD" |
66 | #define METHOD_HCI_2 "\\_SB_.VALZ.GHCI" | 67 | #define TOSH_INTERFACE_2 "\\_SB_.VALZ" |
67 | #define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" | 68 | #define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" |
69 | #define GHCI_METHOD ".GHCI" | ||
68 | 70 | ||
69 | /* Toshiba HCI interface definitions | 71 | /* Toshiba HCI interface definitions |
70 | * | 72 | * |
@@ -116,6 +118,36 @@ static const struct acpi_device_id toshiba_device_ids[] = { | |||
116 | }; | 118 | }; |
117 | MODULE_DEVICE_TABLE(acpi, toshiba_device_ids); | 119 | MODULE_DEVICE_TABLE(acpi, toshiba_device_ids); |
118 | 120 | ||
121 | struct key_entry { | ||
122 | char type; | ||
123 | u16 code; | ||
124 | u16 keycode; | ||
125 | }; | ||
126 | |||
127 | enum {KE_KEY, KE_END}; | ||
128 | |||
129 | static struct key_entry toshiba_acpi_keymap[] = { | ||
130 | {KE_KEY, 0x101, KEY_MUTE}, | ||
131 | {KE_KEY, 0x13b, KEY_COFFEE}, | ||
132 | {KE_KEY, 0x13c, KEY_BATTERY}, | ||
133 | {KE_KEY, 0x13d, KEY_SLEEP}, | ||
134 | {KE_KEY, 0x13e, KEY_SUSPEND}, | ||
135 | {KE_KEY, 0x13f, KEY_SWITCHVIDEOMODE}, | ||
136 | {KE_KEY, 0x140, KEY_BRIGHTNESSDOWN}, | ||
137 | {KE_KEY, 0x141, KEY_BRIGHTNESSUP}, | ||
138 | {KE_KEY, 0x142, KEY_WLAN}, | ||
139 | {KE_KEY, 0x143, KEY_PROG1}, | ||
140 | {KE_KEY, 0xb05, KEY_PROG2}, | ||
141 | {KE_KEY, 0xb06, KEY_WWW}, | ||
142 | {KE_KEY, 0xb07, KEY_MAIL}, | ||
143 | {KE_KEY, 0xb30, KEY_STOP}, | ||
144 | {KE_KEY, 0xb31, KEY_PREVIOUSSONG}, | ||
145 | {KE_KEY, 0xb32, KEY_NEXTSONG}, | ||
146 | {KE_KEY, 0xb33, KEY_PLAYPAUSE}, | ||
147 | {KE_KEY, 0xb5a, KEY_MEDIA}, | ||
148 | {KE_END, 0, 0}, | ||
149 | }; | ||
150 | |||
119 | /* utility | 151 | /* utility |
120 | */ | 152 | */ |
121 | 153 | ||
@@ -251,6 +283,8 @@ static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result) | |||
251 | struct toshiba_acpi_dev { | 283 | struct toshiba_acpi_dev { |
252 | struct platform_device *p_dev; | 284 | struct platform_device *p_dev; |
253 | struct rfkill *bt_rfk; | 285 | struct rfkill *bt_rfk; |
286 | struct input_dev *hotkey_dev; | ||
287 | acpi_handle handle; | ||
254 | 288 | ||
255 | const char *bt_name; | 289 | const char *bt_name; |
256 | 290 | ||
@@ -711,8 +745,159 @@ static struct backlight_ops toshiba_backlight_data = { | |||
711 | .update_status = set_lcd_status, | 745 | .update_status = set_lcd_status, |
712 | }; | 746 | }; |
713 | 747 | ||
748 | static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code) | ||
749 | { | ||
750 | struct key_entry *key; | ||
751 | |||
752 | for (key = toshiba_acpi_keymap; key->type != KE_END; key++) | ||
753 | if (code == key->code) | ||
754 | return key; | ||
755 | |||
756 | return NULL; | ||
757 | } | ||
758 | |||
759 | static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code) | ||
760 | { | ||
761 | struct key_entry *key; | ||
762 | |||
763 | for (key = toshiba_acpi_keymap; key->type != KE_END; key++) | ||
764 | if (code == key->keycode && key->type == KE_KEY) | ||
765 | return key; | ||
766 | |||
767 | return NULL; | ||
768 | } | ||
769 | |||
770 | static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode, | ||
771 | int *keycode) | ||
772 | { | ||
773 | struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode); | ||
774 | |||
775 | if (key && key->type == KE_KEY) { | ||
776 | *keycode = key->keycode; | ||
777 | return 0; | ||
778 | } | ||
779 | |||
780 | return -EINVAL; | ||
781 | } | ||
782 | |||
783 | static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode, | ||
784 | int keycode) | ||
785 | { | ||
786 | struct key_entry *key; | ||
787 | int old_keycode; | ||
788 | |||
789 | if (keycode < 0 || keycode > KEY_MAX) | ||
790 | return -EINVAL; | ||
791 | |||
792 | key = toshiba_acpi_get_entry_by_scancode(scancode); | ||
793 | if (key && key->type == KE_KEY) { | ||
794 | old_keycode = key->keycode; | ||
795 | key->keycode = keycode; | ||
796 | set_bit(keycode, dev->keybit); | ||
797 | if (!toshiba_acpi_get_entry_by_keycode(old_keycode)) | ||
798 | clear_bit(old_keycode, dev->keybit); | ||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | return -EINVAL; | ||
803 | } | ||
804 | |||
805 | static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context) | ||
806 | { | ||
807 | u32 hci_result, value; | ||
808 | struct key_entry *key; | ||
809 | |||
810 | if (event != 0x80) | ||
811 | return; | ||
812 | do { | ||
813 | hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); | ||
814 | if (hci_result == HCI_SUCCESS) { | ||
815 | if (value == 0x100) | ||
816 | continue; | ||
817 | else if (value & 0x80) { | ||
818 | key = toshiba_acpi_get_entry_by_scancode | ||
819 | (value & ~0x80); | ||
820 | if (!key) { | ||
821 | printk(MY_INFO "Unknown key %x\n", | ||
822 | value & ~0x80); | ||
823 | continue; | ||
824 | } | ||
825 | input_report_key(toshiba_acpi.hotkey_dev, | ||
826 | key->keycode, 1); | ||
827 | input_sync(toshiba_acpi.hotkey_dev); | ||
828 | input_report_key(toshiba_acpi.hotkey_dev, | ||
829 | key->keycode, 0); | ||
830 | input_sync(toshiba_acpi.hotkey_dev); | ||
831 | } | ||
832 | } else if (hci_result == HCI_NOT_SUPPORTED) { | ||
833 | /* This is a workaround for an unresolved issue on | ||
834 | * some machines where system events sporadically | ||
835 | * become disabled. */ | ||
836 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); | ||
837 | printk(MY_NOTICE "Re-enabled hotkeys\n"); | ||
838 | } | ||
839 | } while (hci_result != HCI_EMPTY); | ||
840 | } | ||
841 | |||
842 | static int toshiba_acpi_setup_keyboard(char *device) | ||
843 | { | ||
844 | acpi_status status; | ||
845 | acpi_handle handle; | ||
846 | int result; | ||
847 | const struct key_entry *key; | ||
848 | |||
849 | status = acpi_get_handle(NULL, device, &handle); | ||
850 | if (ACPI_FAILURE(status)) { | ||
851 | printk(MY_INFO "Unable to get notification device\n"); | ||
852 | return -ENODEV; | ||
853 | } | ||
854 | |||
855 | toshiba_acpi.handle = handle; | ||
856 | |||
857 | status = acpi_evaluate_object(handle, "ENAB", NULL, NULL); | ||
858 | if (ACPI_FAILURE(status)) { | ||
859 | printk(MY_INFO "Unable to enable hotkeys\n"); | ||
860 | return -ENODEV; | ||
861 | } | ||
862 | |||
863 | status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY, | ||
864 | toshiba_acpi_notify, NULL); | ||
865 | if (ACPI_FAILURE(status)) { | ||
866 | printk(MY_INFO "Unable to install hotkey notification\n"); | ||
867 | return -ENODEV; | ||
868 | } | ||
869 | |||
870 | toshiba_acpi.hotkey_dev = input_allocate_device(); | ||
871 | if (!toshiba_acpi.hotkey_dev) { | ||
872 | printk(MY_INFO "Unable to register input device\n"); | ||
873 | return -ENOMEM; | ||
874 | } | ||
875 | |||
876 | toshiba_acpi.hotkey_dev->name = "Toshiba input device"; | ||
877 | toshiba_acpi.hotkey_dev->phys = device; | ||
878 | toshiba_acpi.hotkey_dev->id.bustype = BUS_HOST; | ||
879 | toshiba_acpi.hotkey_dev->getkeycode = toshiba_acpi_getkeycode; | ||
880 | toshiba_acpi.hotkey_dev->setkeycode = toshiba_acpi_setkeycode; | ||
881 | |||
882 | for (key = toshiba_acpi_keymap; key->type != KE_END; key++) { | ||
883 | set_bit(EV_KEY, toshiba_acpi.hotkey_dev->evbit); | ||
884 | set_bit(key->keycode, toshiba_acpi.hotkey_dev->keybit); | ||
885 | } | ||
886 | |||
887 | result = input_register_device(toshiba_acpi.hotkey_dev); | ||
888 | if (result) { | ||
889 | printk(MY_INFO "Unable to register input device\n"); | ||
890 | return result; | ||
891 | } | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
714 | static void toshiba_acpi_exit(void) | 896 | static void toshiba_acpi_exit(void) |
715 | { | 897 | { |
898 | if (toshiba_acpi.hotkey_dev) | ||
899 | input_unregister_device(toshiba_acpi.hotkey_dev); | ||
900 | |||
716 | if (toshiba_acpi.bt_rfk) { | 901 | if (toshiba_acpi.bt_rfk) { |
717 | rfkill_unregister(toshiba_acpi.bt_rfk); | 902 | rfkill_unregister(toshiba_acpi.bt_rfk); |
718 | rfkill_destroy(toshiba_acpi.bt_rfk); | 903 | rfkill_destroy(toshiba_acpi.bt_rfk); |
@@ -726,6 +911,9 @@ static void toshiba_acpi_exit(void) | |||
726 | if (toshiba_proc_dir) | 911 | if (toshiba_proc_dir) |
727 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | 912 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); |
728 | 913 | ||
914 | acpi_remove_notify_handler(toshiba_acpi.handle, ACPI_DEVICE_NOTIFY, | ||
915 | toshiba_acpi_notify); | ||
916 | |||
729 | platform_device_unregister(toshiba_acpi.p_dev); | 917 | platform_device_unregister(toshiba_acpi.p_dev); |
730 | 918 | ||
731 | return; | 919 | return; |
@@ -742,11 +930,15 @@ static int __init toshiba_acpi_init(void) | |||
742 | return -ENODEV; | 930 | return -ENODEV; |
743 | 931 | ||
744 | /* simple device detection: look for HCI method */ | 932 | /* simple device detection: look for HCI method */ |
745 | if (is_valid_acpi_path(METHOD_HCI_1)) | 933 | if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) { |
746 | method_hci = METHOD_HCI_1; | 934 | method_hci = TOSH_INTERFACE_1 GHCI_METHOD; |
747 | else if (is_valid_acpi_path(METHOD_HCI_2)) | 935 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1)) |
748 | method_hci = METHOD_HCI_2; | 936 | printk(MY_INFO "Unable to activate hotkeys\n"); |
749 | else | 937 | } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) { |
938 | method_hci = TOSH_INTERFACE_2 GHCI_METHOD; | ||
939 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2)) | ||
940 | printk(MY_INFO "Unable to activate hotkeys\n"); | ||
941 | } else | ||
750 | return -ENODEV; | 942 | return -ENODEV; |
751 | 943 | ||
752 | printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", | 944 | printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", |