aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 20:13:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 20:13:24 -0400
commit27a3353a4525afe984f3b793681869d636136b69 (patch)
tree6c89654b6203b5b3196c128ced8a6b6c8b60b58a
parent6f68fbaafbaa033205cd131d3e1f3c4b914e9b78 (diff)
parent785cfc0324b9321efb85b0935af2b474d615daa1 (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: (32 commits) Move N014, N051 and CR620 dmi information to load scm dmi table drivers/platform/x86/eeepc-wmi.c: fix build warning X86 platfrom wmi: Add debug facility to dump WMI data in a readable way X86 platform wmi: Also log GUID string when an event happens and debug is set X86 platform wmi: Introduce debug param to log all WMI events Clean up all objects used by scm model when driver initial fail or exit msi-laptop: fix up some coding style issues found by checkpatch msi-laptop: Add i8042 filter to sync sw state with BIOS when function key pressed msi-laptop: Set rfkill init state when msi-laptop intiial msi-laptop: Add MSI CR620 notebook dmi information to scm models table msi-laptop: Add N014 N051 dmi information to scm models table drivers/platform/x86: Use kmemdup drivers/platform/x86: Use kzalloc drivers/platform/x86: Clarify the MRST IPC driver description slightly eeepc-wmi: depends on BACKLIGHT_CLASS_DEVICE IPC driver for Intel Mobile Internet Device (MID) platforms classmate-laptop: Add RFKILL support. thinkpad-acpi: document backlight level writeback at driver init thinkpad-acpi: clean up ACPI handles handling thinkpad-acpi: don't depend on led_path for led firmware type (v2) ...
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt66
-rw-r--r--arch/x86/include/asm/intel_scu_ipc.h55
-rw-r--r--drivers/platform/x86/Kconfig10
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/classmate-laptop.c170
-rw-r--r--drivers/platform/x86/eeepc-wmi.c2
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c6
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c829
-rw-r--r--drivers/platform/x86/msi-laptop.c163
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c600
-rw-r--r--drivers/platform/x86/wmi.c103
11 files changed, 1710 insertions, 295 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 39c0a09d0105..fc15538d8b46 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -292,13 +292,13 @@ sysfs notes:
292 292
293 Warning: when in NVRAM mode, the volume up/down/mute 293 Warning: when in NVRAM mode, the volume up/down/mute
294 keys are synthesized according to changes in the mixer, 294 keys are synthesized according to changes in the mixer,
295 so you have to use volume up or volume down to unmute, 295 which uses a single volume up or volume down hotkey
296 as per the ThinkPad volume mixer user interface. When 296 press to unmute, as per the ThinkPad volume mixer user
297 in ACPI event mode, volume up/down/mute are reported as 297 interface. When in ACPI event mode, volume up/down/mute
298 separate events, but this behaviour may be corrected in 298 events are reported by the firmware and can behave
299 future releases of this driver, in which case the 299 differently (and that behaviour changes with firmware
300 ThinkPad volume mixer user interface semantics will be 300 version -- not just with firmware models -- as well as
301 enforced. 301 OSI(Linux) state).
302 302
303 hotkey_poll_freq: 303 hotkey_poll_freq:
304 frequency in Hz for hot key polling. It must be between 304 frequency in Hz for hot key polling. It must be between
@@ -309,7 +309,7 @@ sysfs notes:
309 will cause hot key presses that require NVRAM polling 309 will cause hot key presses that require NVRAM polling
310 to never be reported. 310 to never be reported.
311 311
312 Setting hotkey_poll_freq too low will cause repeated 312 Setting hotkey_poll_freq too low may cause repeated
313 pressings of the same hot key to be misreported as a 313 pressings of the same hot key to be misreported as a
314 single key press, or to not even be detected at all. 314 single key press, or to not even be detected at all.
315 The recommended polling frequency is 10Hz. 315 The recommended polling frequency is 10Hz.
@@ -397,6 +397,7 @@ ACPI Scan
397event code Key Notes 397event code Key Notes
398 398
3990x1001 0x00 FN+F1 - 3990x1001 0x00 FN+F1 -
400
4000x1002 0x01 FN+F2 IBM: battery (rare) 4010x1002 0x01 FN+F2 IBM: battery (rare)
401 Lenovo: Screen lock 402 Lenovo: Screen lock
402 403
@@ -404,7 +405,8 @@ event code Key Notes
404 this hot key, even with hot keys 405 this hot key, even with hot keys
405 disabled or with Fn+F3 masked 406 disabled or with Fn+F3 masked
406 off 407 off
407 IBM: screen lock 408 IBM: screen lock, often turns
409 off the ThinkLight as side-effect
408 Lenovo: battery 410 Lenovo: battery
409 411
4100x1004 0x03 FN+F4 Sleep button (ACPI sleep button 4120x1004 0x03 FN+F4 Sleep button (ACPI sleep button
@@ -433,7 +435,8 @@ event code Key Notes
433 Do you feel lucky today? 435 Do you feel lucky today?
434 436
4350x1008 0x07 FN+F8 IBM: toggle screen expand 4370x1008 0x07 FN+F8 IBM: toggle screen expand
436 Lenovo: configure UltraNav 438 Lenovo: configure UltraNav,
439 or toggle screen expand
437 440
4380x1009 0x08 FN+F9 - 4410x1009 0x08 FN+F9 -
439 .. .. .. 442 .. .. ..
@@ -444,7 +447,7 @@ event code Key Notes
444 either through the ACPI event, 447 either through the ACPI event,
445 or through a hotkey event. 448 or through a hotkey event.
446 The firmware may refuse to 449 The firmware may refuse to
447 generate further FN+F4 key 450 generate further FN+F12 key
448 press events until a S3 or S4 451 press events until a S3 or S4
449 ACPI sleep cycle is performed, 452 ACPI sleep cycle is performed,
450 or some time passes. 453 or some time passes.
@@ -512,15 +515,19 @@ events for switches:
512SW_RFKILL_ALL T60 and later hardware rfkill rocker switch 515SW_RFKILL_ALL T60 and later hardware rfkill rocker switch
513SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A 516SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A
514 517
515Non hot-key ACPI HKEY event map: 518Non hotkey ACPI HKEY event map:
519-------------------------------
520
521Events that are not propagated by the driver, except for legacy
522compatibility purposes when hotkey_report_mode is set to 1:
523
5160x5001 Lid closed 5240x5001 Lid closed
5170x5002 Lid opened 5250x5002 Lid opened
5180x5009 Tablet swivel: switched to tablet mode 5260x5009 Tablet swivel: switched to tablet mode
5190x500A Tablet swivel: switched to normal mode 5270x500A Tablet swivel: switched to normal mode
5200x7000 Radio Switch may have changed state 5280x7000 Radio Switch may have changed state
521 529
522The above events are not propagated by the driver, except for legacy 530Events that are never propagated by the driver:
523compatibility purposes when hotkey_report_mode is set to 1.
524 531
5250x2304 System is waking up from suspend to undock 5320x2304 System is waking up from suspend to undock
5260x2305 System is waking up from suspend to eject bay 5330x2305 System is waking up from suspend to eject bay
@@ -528,14 +535,39 @@ compatibility purposes when hotkey_report_mode is set to 1.
5280x2405 System is waking up from hibernation to eject bay 5350x2405 System is waking up from hibernation to eject bay
5290x5010 Brightness level changed/control event 5360x5010 Brightness level changed/control event
530 537
531The above events are never propagated by the driver. 538Events that are propagated by the driver to userspace:
532 539
5400x2313 ALARM: System is waking up from suspend because
541 the battery is nearly empty
5420x2413 ALARM: System is waking up from hibernation because
543 the battery is nearly empty
5330x3003 Bay ejection (see 0x2x05) complete, can sleep again 5440x3003 Bay ejection (see 0x2x05) complete, can sleep again
5450x3006 Bay hotplug request (hint to power up SATA link when
546 the optical drive tray is ejected)
5340x4003 Undocked (see 0x2x04), can sleep again 5470x4003 Undocked (see 0x2x04), can sleep again
5350x500B Tablet pen inserted into its storage bay 5480x500B Tablet pen inserted into its storage bay
5360x500C Tablet pen removed from its storage bay 5490x500C Tablet pen removed from its storage bay
537 5500x6011 ALARM: battery is too hot
538The above events are propagated by the driver. 5510x6012 ALARM: battery is extremely hot
5520x6021 ALARM: a sensor is too hot
5530x6022 ALARM: a sensor is extremely hot
5540x6030 System thermal table changed
555
556Battery nearly empty alarms are a last resort attempt to get the
557operating system to hibernate or shutdown cleanly (0x2313), or shutdown
558cleanly (0x2413) before power is lost. They must be acted upon, as the
559wake up caused by the firmware will have negated most safety nets...
560
561When any of the "too hot" alarms happen, according to Lenovo the user
562should suspend or hibernate the laptop (and in the case of battery
563alarms, unplug the AC adapter) to let it cool down. These alarms do
564signal that something is wrong, they should never happen on normal
565operating conditions.
566
567The "extremely hot" alarms are emergencies. According to Lenovo, the
568operating system is to force either an immediate suspend or hibernate
569cycle, or a system shutdown. Obviously, something is very wrong if this
570happens.
539 571
540Compatibility notes: 572Compatibility notes:
541 573
diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
new file mode 100644
index 000000000000..4470c9ad4a3e
--- /dev/null
+++ b/arch/x86/include/asm/intel_scu_ipc.h
@@ -0,0 +1,55 @@
1#ifndef _ASM_X86_INTEL_SCU_IPC_H_
2#define _ASM_X86_INTEL_SCU_IPC_H_
3
4/* Read single register */
5int intel_scu_ipc_ioread8(u16 addr, u8 *data);
6
7/* Read two sequential registers */
8int intel_scu_ipc_ioread16(u16 addr, u16 *data);
9
10/* Read four sequential registers */
11int intel_scu_ipc_ioread32(u16 addr, u32 *data);
12
13/* Read a vector */
14int intel_scu_ipc_readv(u16 *addr, u8 *data, int len);
15
16/* Write single register */
17int intel_scu_ipc_iowrite8(u16 addr, u8 data);
18
19/* Write two sequential registers */
20int intel_scu_ipc_iowrite16(u16 addr, u16 data);
21
22/* Write four sequential registers */
23int intel_scu_ipc_iowrite32(u16 addr, u32 data);
24
25/* Write a vector */
26int intel_scu_ipc_writev(u16 *addr, u8 *data, int len);
27
28/* Update single register based on the mask */
29int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask);
30
31/*
32 * Indirect register read
33 * Can be used when SCCB(System Controller Configuration Block) register
34 * HRIM(Honor Restricted IPC Messages) is set (bit 23)
35 */
36int intel_scu_ipc_register_read(u32 addr, u32 *data);
37
38/*
39 * Indirect register write
40 * Can be used when SCCB(System Controller Configuration Block) register
41 * HRIM(Honor Restricted IPC Messages) is set (bit 23)
42 */
43int intel_scu_ipc_register_write(u32 addr, u32 data);
44
45/* Issue commands to the SCU with or without data */
46int intel_scu_ipc_simple_command(int cmd, int sub);
47int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
48 u32 *out, int outlen);
49/* I2C control api */
50int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data);
51
52/* Update FW version */
53int intel_scu_ipc_fw_update(u8 *buffer, u32 length);
54
55#endif
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 6c3320d75055..3e1b8a288719 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -390,6 +390,7 @@ config EEEPC_WMI
390 depends on ACPI_WMI 390 depends on ACPI_WMI
391 depends on INPUT 391 depends on INPUT
392 depends on EXPERIMENTAL 392 depends on EXPERIMENTAL
393 depends on BACKLIGHT_CLASS_DEVICE
393 select INPUT_SPARSEKMAP 394 select INPUT_SPARSEKMAP
394 ---help--- 395 ---help---
395 Say Y here if you want to support WMI-based hotkeys on Eee PC laptops. 396 Say Y here if you want to support WMI-based hotkeys on Eee PC laptops.
@@ -527,4 +528,13 @@ config ACPI_CMPC
527 keys as input device, backlight device, tablet and accelerometer 528 keys as input device, backlight device, tablet and accelerometer
528 devices. 529 devices.
529 530
531config INTEL_SCU_IPC
532 bool "Intel SCU IPC Support"
533 depends on X86_MRST
534 default y
535 ---help---
536 IPC is used to bridge the communications between kernel and SCU on
537 some embedded Intel x86 platforms. This is not needed for PC-type
538 machines.
539
530endif # X86_PLATFORM_DEVICES 540endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index a906490e3530..8770bfe71431 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -25,3 +25,4 @@ obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
25obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o 25obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
26obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o 26obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
27obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o 27obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
28obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c
index 7f9e5ddc9498..3bf399fe2bbc 100644
--- a/drivers/platform/x86/classmate-laptop.c
+++ b/drivers/platform/x86/classmate-laptop.c
@@ -24,6 +24,7 @@
24#include <acpi/acpi_drivers.h> 24#include <acpi/acpi_drivers.h>
25#include <linux/backlight.h> 25#include <linux/backlight.h>
26#include <linux/input.h> 26#include <linux/input.h>
27#include <linux/rfkill.h>
27 28
28MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
29 30
@@ -37,7 +38,7 @@ struct cmpc_accel {
37 38
38#define CMPC_ACCEL_HID "ACCE0000" 39#define CMPC_ACCEL_HID "ACCE0000"
39#define CMPC_TABLET_HID "TBLT0000" 40#define CMPC_TABLET_HID "TBLT0000"
40#define CMPC_BL_HID "IPML200" 41#define CMPC_IPML_HID "IPML200"
41#define CMPC_KEYS_HID "FnBT0000" 42#define CMPC_KEYS_HID "FnBT0000"
42 43
43/* 44/*
@@ -461,43 +462,168 @@ static const struct backlight_ops cmpc_bl_ops = {
461 .update_status = cmpc_bl_update_status 462 .update_status = cmpc_bl_update_status
462}; 463};
463 464
464static int cmpc_bl_add(struct acpi_device *acpi) 465/*
466 * RFKILL code.
467 */
468
469static acpi_status cmpc_get_rfkill_wlan(acpi_handle handle,
470 unsigned long long *value)
465{ 471{
466 struct backlight_properties props; 472 union acpi_object param;
473 struct acpi_object_list input;
474 unsigned long long output;
475 acpi_status status;
476
477 param.type = ACPI_TYPE_INTEGER;
478 param.integer.value = 0xC1;
479 input.count = 1;
480 input.pointer = &param;
481 status = acpi_evaluate_integer(handle, "GRDI", &input, &output);
482 if (ACPI_SUCCESS(status))
483 *value = output;
484 return status;
485}
486
487static acpi_status cmpc_set_rfkill_wlan(acpi_handle handle,
488 unsigned long long value)
489{
490 union acpi_object param[2];
491 struct acpi_object_list input;
492 acpi_status status;
493 unsigned long long output;
494
495 param[0].type = ACPI_TYPE_INTEGER;
496 param[0].integer.value = 0xC1;
497 param[1].type = ACPI_TYPE_INTEGER;
498 param[1].integer.value = value;
499 input.count = 2;
500 input.pointer = param;
501 status = acpi_evaluate_integer(handle, "GWRI", &input, &output);
502 return status;
503}
504
505static void cmpc_rfkill_query(struct rfkill *rfkill, void *data)
506{
507 acpi_status status;
508 acpi_handle handle;
509 unsigned long long state;
510 bool blocked;
511
512 handle = data;
513 status = cmpc_get_rfkill_wlan(handle, &state);
514 if (ACPI_SUCCESS(status)) {
515 blocked = state & 1 ? false : true;
516 rfkill_set_sw_state(rfkill, blocked);
517 }
518}
519
520static int cmpc_rfkill_block(void *data, bool blocked)
521{
522 acpi_status status;
523 acpi_handle handle;
524 unsigned long long state;
525
526 handle = data;
527 status = cmpc_get_rfkill_wlan(handle, &state);
528 if (ACPI_FAILURE(status))
529 return -ENODEV;
530 if (blocked)
531 state &= ~1;
532 else
533 state |= 1;
534 status = cmpc_set_rfkill_wlan(handle, state);
535 if (ACPI_FAILURE(status))
536 return -ENODEV;
537 return 0;
538}
539
540static const struct rfkill_ops cmpc_rfkill_ops = {
541 .query = cmpc_rfkill_query,
542 .set_block = cmpc_rfkill_block,
543};
544
545/*
546 * Common backlight and rfkill code.
547 */
548
549struct ipml200_dev {
467 struct backlight_device *bd; 550 struct backlight_device *bd;
551 struct rfkill *rf;
552};
553
554static int cmpc_ipml_add(struct acpi_device *acpi)
555{
556 int retval;
557 struct ipml200_dev *ipml;
558 struct backlight_properties props;
559
560 ipml = kmalloc(sizeof(*ipml), GFP_KERNEL);
561 if (ipml == NULL)
562 return -ENOMEM;
468 563
469 memset(&props, 0, sizeof(struct backlight_properties)); 564 memset(&props, 0, sizeof(struct backlight_properties));
470 props.max_brightness = 7; 565 props.max_brightness = 7;
471 bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle, 566 ipml->bd = backlight_device_register("cmpc_bl", &acpi->dev,
472 &cmpc_bl_ops, &props); 567 acpi->handle, &cmpc_bl_ops,
473 if (IS_ERR(bd)) 568 &props);
474 return PTR_ERR(bd); 569 if (IS_ERR(ipml->bd)) {
475 dev_set_drvdata(&acpi->dev, bd); 570 retval = PTR_ERR(ipml->bd);
571 goto out_bd;
572 }
573
574 ipml->rf = rfkill_alloc("cmpc_rfkill", &acpi->dev, RFKILL_TYPE_WLAN,
575 &cmpc_rfkill_ops, acpi->handle);
576 /* rfkill_alloc may fail if RFKILL is disabled. We should still work
577 * anyway. */
578 if (!IS_ERR(ipml->rf)) {
579 retval = rfkill_register(ipml->rf);
580 if (retval) {
581 rfkill_destroy(ipml->rf);
582 ipml->rf = NULL;
583 }
584 } else {
585 ipml->rf = NULL;
586 }
587
588 dev_set_drvdata(&acpi->dev, ipml);
476 return 0; 589 return 0;
590
591out_bd:
592 kfree(ipml);
593 return retval;
477} 594}
478 595
479static int cmpc_bl_remove(struct acpi_device *acpi, int type) 596static int cmpc_ipml_remove(struct acpi_device *acpi, int type)
480{ 597{
481 struct backlight_device *bd; 598 struct ipml200_dev *ipml;
599
600 ipml = dev_get_drvdata(&acpi->dev);
601
602 backlight_device_unregister(ipml->bd);
603
604 if (ipml->rf) {
605 rfkill_unregister(ipml->rf);
606 rfkill_destroy(ipml->rf);
607 }
608
609 kfree(ipml);
482 610
483 bd = dev_get_drvdata(&acpi->dev);
484 backlight_device_unregister(bd);
485 return 0; 611 return 0;
486} 612}
487 613
488static const struct acpi_device_id cmpc_bl_device_ids[] = { 614static const struct acpi_device_id cmpc_ipml_device_ids[] = {
489 {CMPC_BL_HID, 0}, 615 {CMPC_IPML_HID, 0},
490 {"", 0} 616 {"", 0}
491}; 617};
492 618
493static struct acpi_driver cmpc_bl_acpi_driver = { 619static struct acpi_driver cmpc_ipml_acpi_driver = {
494 .owner = THIS_MODULE, 620 .owner = THIS_MODULE,
495 .name = "cmpc", 621 .name = "cmpc",
496 .class = "cmpc", 622 .class = "cmpc",
497 .ids = cmpc_bl_device_ids, 623 .ids = cmpc_ipml_device_ids,
498 .ops = { 624 .ops = {
499 .add = cmpc_bl_add, 625 .add = cmpc_ipml_add,
500 .remove = cmpc_bl_remove 626 .remove = cmpc_ipml_remove
501 } 627 }
502}; 628};
503 629
@@ -580,7 +706,7 @@ static int cmpc_init(void)
580 if (r) 706 if (r)
581 goto failed_keys; 707 goto failed_keys;
582 708
583 r = acpi_bus_register_driver(&cmpc_bl_acpi_driver); 709 r = acpi_bus_register_driver(&cmpc_ipml_acpi_driver);
584 if (r) 710 if (r)
585 goto failed_bl; 711 goto failed_bl;
586 712
@@ -598,7 +724,7 @@ failed_accel:
598 acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); 724 acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
599 725
600failed_tablet: 726failed_tablet:
601 acpi_bus_unregister_driver(&cmpc_bl_acpi_driver); 727 acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
602 728
603failed_bl: 729failed_bl:
604 acpi_bus_unregister_driver(&cmpc_keys_acpi_driver); 730 acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
@@ -611,7 +737,7 @@ static void cmpc_exit(void)
611{ 737{
612 acpi_bus_unregister_driver(&cmpc_accel_acpi_driver); 738 acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
613 acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); 739 acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
614 acpi_bus_unregister_driver(&cmpc_bl_acpi_driver); 740 acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
615 acpi_bus_unregister_driver(&cmpc_keys_acpi_driver); 741 acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
616} 742}
617 743
@@ -621,7 +747,7 @@ module_exit(cmpc_exit);
621static const struct acpi_device_id cmpc_device_ids[] = { 747static const struct acpi_device_id cmpc_device_ids[] = {
622 {CMPC_ACCEL_HID, 0}, 748 {CMPC_ACCEL_HID, 0},
623 {CMPC_TABLET_HID, 0}, 749 {CMPC_TABLET_HID, 0},
624 {CMPC_BL_HID, 0}, 750 {CMPC_IPML_HID, 0},
625 {CMPC_KEYS_HID, 0}, 751 {CMPC_KEYS_HID, 0},
626 {"", 0} 752 {"", 0}
627}; 753};
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index b227eb469f49..9dc50fbf3d0b 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -206,7 +206,7 @@ static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
206{ 206{
207 struct backlight_device *bd = eeepc->backlight_device; 207 struct backlight_device *bd = eeepc->backlight_device;
208 int old = bd->props.brightness; 208 int old = bd->props.brightness;
209 int new; 209 int new = old;
210 210
211 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) 211 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
212 new = code - NOTIFY_BRNUP_MIN + 1; 212 new = code - NOTIFY_BRNUP_MIN + 1;
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 47b4fd75aa34..e325aeb37d2e 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -1090,10 +1090,9 @@ static int __init fujitsu_init(void)
1090 if (acpi_disabled) 1090 if (acpi_disabled)
1091 return -ENODEV; 1091 return -ENODEV;
1092 1092
1093 fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL); 1093 fujitsu = kzalloc(sizeof(struct fujitsu_t), GFP_KERNEL);
1094 if (!fujitsu) 1094 if (!fujitsu)
1095 return -ENOMEM; 1095 return -ENOMEM;
1096 memset(fujitsu, 0, sizeof(struct fujitsu_t));
1097 fujitsu->keycode1 = KEY_PROG1; 1096 fujitsu->keycode1 = KEY_PROG1;
1098 fujitsu->keycode2 = KEY_PROG2; 1097 fujitsu->keycode2 = KEY_PROG2;
1099 fujitsu->keycode3 = KEY_PROG3; 1098 fujitsu->keycode3 = KEY_PROG3;
@@ -1150,12 +1149,11 @@ static int __init fujitsu_init(void)
1150 1149
1151 /* Register hotkey driver */ 1150 /* Register hotkey driver */
1152 1151
1153 fujitsu_hotkey = kmalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL); 1152 fujitsu_hotkey = kzalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL);
1154 if (!fujitsu_hotkey) { 1153 if (!fujitsu_hotkey) {
1155 ret = -ENOMEM; 1154 ret = -ENOMEM;
1156 goto fail_hotkey; 1155 goto fail_hotkey;
1157 } 1156 }
1158 memset(fujitsu_hotkey, 0, sizeof(struct fujitsu_hotkey_t));
1159 1157
1160 result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver); 1158 result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver);
1161 if (result < 0) { 1159 if (result < 0) {
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
new file mode 100644
index 000000000000..576c3ed92435
--- /dev/null
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -0,0 +1,829 @@
1/*
2 * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism
3 *
4 * (C) Copyright 2008-2010 Intel Corporation
5 * Author: Sreedhara DS (sreedhara.ds@intel.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 *
12 * SCU runing in ARC processor communicates with other entity running in IA
13 * core through IPC mechanism which in turn messaging between IA core ad SCU.
14 * SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and
15 * SCU where IPC-2 is used between P-Unit and SCU. This driver delas with
16 * IPC-1 Driver provides an API for power control unit registers (e.g. MSIC)
17 * along with other APIs.
18 */
19#include <linux/delay.h>
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/sysdev.h>
23#include <linux/pm.h>
24#include <linux/pci.h>
25#include <linux/interrupt.h>
26#include <asm/setup.h>
27#include <asm/intel_scu_ipc.h>
28
29/* IPC defines the following message types */
30#define IPCMSG_WATCHDOG_TIMER 0xF8 /* Set Kernel Watchdog Threshold */
31#define IPCMSG_BATTERY 0xEF /* Coulomb Counter Accumulator */
32#define IPCMSG_FW_UPDATE 0xFE /* Firmware update */
33#define IPCMSG_PCNTRL 0xFF /* Power controller unit read/write */
34#define IPCMSG_FW_REVISION 0xF4 /* Get firmware revision */
35
36/* Command id associated with message IPCMSG_PCNTRL */
37#define IPC_CMD_PCNTRL_W 0 /* Register write */
38#define IPC_CMD_PCNTRL_R 1 /* Register read */
39#define IPC_CMD_PCNTRL_M 2 /* Register read-modify-write */
40
41/* Miscelaneous Command ids */
42#define IPC_CMD_INDIRECT_RD 2 /* 32bit indirect read */
43#define IPC_CMD_INDIRECT_WR 5 /* 32bit indirect write */
44
45/*
46 * IPC register summary
47 *
48 * IPC register blocks are memory mapped at fixed address of 0xFF11C000
49 * To read or write information to the SCU, driver writes to IPC-1 memory
50 * mapped registers (base address 0xFF11C000). The following is the IPC
51 * mechanism
52 *
53 * 1. IA core cDMI interface claims this transaction and converts it to a
54 * Transaction Layer Packet (TLP) message which is sent across the cDMI.
55 *
56 * 2. South Complex cDMI block receives this message and writes it to
57 * the IPC-1 register block, causing an interrupt to the SCU
58 *
59 * 3. SCU firmware decodes this interrupt and IPC message and the appropriate
60 * message handler is called within firmware.
61 */
62
63#define IPC_BASE_ADDR 0xFF11C000 /* IPC1 base register address */
64#define IPC_MAX_ADDR 0x100 /* Maximum IPC regisers */
65#define IPC_WWBUF_SIZE 16 /* IPC Write buffer Size */
66#define IPC_RWBUF_SIZE 16 /* IPC Read buffer Size */
67#define IPC_I2C_BASE 0xFF12B000 /* I2C control register base address */
68#define IPC_I2C_MAX_ADDR 0x10 /* Maximum I2C regisers */
69
70static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id);
71static void ipc_remove(struct pci_dev *pdev);
72
73struct intel_scu_ipc_dev {
74 struct pci_dev *pdev;
75 void __iomem *ipc_base;
76 void __iomem *i2c_base;
77};
78
79static struct intel_scu_ipc_dev ipcdev; /* Only one for now */
80
81static int platform = 1;
82module_param(platform, int, 0);
83MODULE_PARM_DESC(platform, "1 for moorestown platform");
84
85
86
87
88/*
89 * IPC Read Buffer (Read Only):
90 * 16 byte buffer for receiving data from SCU, if IPC command
91 * processing results in response data
92 */
93#define IPC_READ_BUFFER 0x90
94
95#define IPC_I2C_CNTRL_ADDR 0
96#define I2C_DATA_ADDR 0x04
97
98static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
99
100/*
101 * Command Register (Write Only):
102 * A write to this register results in an interrupt to the SCU core processor
103 * Format:
104 * |rfu2(8) | size(8) | command id(4) | rfu1(3) | ioc(1) | command(8)|
105 */
106static inline void ipc_command(u32 cmd) /* Send ipc command */
107{
108 writel(cmd, ipcdev.ipc_base);
109}
110
111/*
112 * IPC Write Buffer (Write Only):
113 * 16-byte buffer for sending data associated with IPC command to
114 * SCU. Size of the data is specified in the IPC_COMMAND_REG register
115 */
116static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */
117{
118 writel(data, ipcdev.ipc_base + 0x80 + offset);
119}
120
121/*
122 * IPC destination Pointer (Write Only):
123 * Use content as pointer for destination write
124 */
125static inline void ipc_write_dptr(u32 data) /* Write dptr data */
126{
127 writel(data, ipcdev.ipc_base + 0x0C);
128}
129
130/*
131 * IPC Source Pointer (Write Only):
132 * Use content as pointer for read location
133*/
134static inline void ipc_write_sptr(u32 data) /* Write dptr data */
135{
136 writel(data, ipcdev.ipc_base + 0x08);
137}
138
139/*
140 * Status Register (Read Only):
141 * Driver will read this register to get the ready/busy status of the IPC
142 * block and error status of the IPC command that was just processed by SCU
143 * Format:
144 * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)|
145 */
146
147static inline u8 ipc_read_status(void)
148{
149 return __raw_readl(ipcdev.ipc_base + 0x04);
150}
151
152static inline u8 ipc_data_readb(u32 offset) /* Read ipc byte data */
153{
154 return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
155}
156
157static inline u8 ipc_data_readl(u32 offset) /* Read ipc u32 data */
158{
159 return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
160}
161
162static inline int busy_loop(void) /* Wait till scu status is busy */
163{
164 u32 status = 0;
165 u32 loop_count = 0;
166
167 status = ipc_read_status();
168 while (status & 1) {
169 udelay(1); /* scu processing time is in few u secods */
170 status = ipc_read_status();
171 loop_count++;
172 /* break if scu doesn't reset busy bit after huge retry */
173 if (loop_count > 100000) {
174 dev_err(&ipcdev.pdev->dev, "IPC timed out");
175 return -ETIMEDOUT;
176 }
177 }
178 return (status >> 1) & 1;
179}
180
181/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
182static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
183{
184 int nc;
185 u32 offset = 0;
186 u32 err = 0;
187 u8 cbuf[IPC_WWBUF_SIZE] = { '\0' };
188 u32 *wbuf = (u32 *)&cbuf;
189
190 mutex_lock(&ipclock);
191 if (ipcdev.pdev == NULL) {
192 mutex_unlock(&ipclock);
193 return -ENODEV;
194 }
195
196 if (platform == 1) {
197 /* Entry is 4 bytes for read/write, 5 bytes for read modify */
198 for (nc = 0; nc < count; nc++) {
199 cbuf[offset] = addr[nc];
200 cbuf[offset + 1] = addr[nc] >> 8;
201 if (id != IPC_CMD_PCNTRL_R)
202 cbuf[offset + 2] = data[nc];
203 if (id == IPC_CMD_PCNTRL_M) {
204 cbuf[offset + 3] = data[nc + 1];
205 offset += 1;
206 }
207 offset += 3;
208 }
209 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
210 ipc_data_writel(wbuf[nc], offset); /* Write wbuff */
211
212 } else {
213 for (nc = 0, offset = 0; nc < count; nc++, offset += 2)
214 ipc_data_writel(addr[nc], offset); /* Write addresses */
215 if (id != IPC_CMD_PCNTRL_R) {
216 for (nc = 0; nc < count; nc++, offset++)
217 ipc_data_writel(data[nc], offset); /* Write data */
218 if (id == IPC_CMD_PCNTRL_M)
219 ipc_data_writel(data[nc + 1], offset); /* Mask value*/
220 }
221 }
222
223 if (id != IPC_CMD_PCNTRL_M)
224 ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op);
225 else
226 ipc_command((count * 4) << 16 | id << 12 | 0 << 8 | op);
227
228 err = busy_loop();
229
230 if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
231 /* Workaround: values are read as 0 without memcpy_fromio */
232 memcpy_fromio(cbuf, ipcdev.ipc_base + IPC_READ_BUFFER, 16);
233 if (platform == 1) {
234 for (nc = 0, offset = 2; nc < count; nc++, offset += 3)
235 data[nc] = ipc_data_readb(offset);
236 } else {
237 for (nc = 0; nc < count; nc++)
238 data[nc] = ipc_data_readb(nc);
239 }
240 }
241 mutex_unlock(&ipclock);
242 return err;
243}
244
245/**
246 * intel_scu_ipc_ioread8 - read a word via the SCU
247 * @addr: register on SCU
248 * @data: return pointer for read byte
249 *
250 * Read a single register. Returns 0 on success or an error code. All
251 * locking between SCU accesses is handled for the caller.
252 *
253 * This function may sleep.
254 */
255int intel_scu_ipc_ioread8(u16 addr, u8 *data)
256{
257 return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
258}
259EXPORT_SYMBOL(intel_scu_ipc_ioread8);
260
261/**
262 * intel_scu_ipc_ioread16 - read a word via the SCU
263 * @addr: register on SCU
264 * @data: return pointer for read word
265 *
266 * Read a register pair. Returns 0 on success or an error code. All
267 * locking between SCU accesses is handled for the caller.
268 *
269 * This function may sleep.
270 */
271int intel_scu_ipc_ioread16(u16 addr, u16 *data)
272{
273 u16 x[2] = {addr, addr + 1 };
274 return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
275}
276EXPORT_SYMBOL(intel_scu_ipc_ioread16);
277
278/**
279 * intel_scu_ipc_ioread32 - read a dword via the SCU
280 * @addr: register on SCU
281 * @data: return pointer for read dword
282 *
283 * Read four registers. Returns 0 on success or an error code. All
284 * locking between SCU accesses is handled for the caller.
285 *
286 * This function may sleep.
287 */
288int intel_scu_ipc_ioread32(u16 addr, u32 *data)
289{
290 u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
291 return pwr_reg_rdwr(x, (u8 *)data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
292}
293EXPORT_SYMBOL(intel_scu_ipc_ioread32);
294
295/**
296 * intel_scu_ipc_iowrite8 - write a byte via the SCU
297 * @addr: register on SCU
298 * @data: byte to write
299 *
300 * Write a single register. Returns 0 on success or an error code. All
301 * locking between SCU accesses is handled for the caller.
302 *
303 * This function may sleep.
304 */
305int intel_scu_ipc_iowrite8(u16 addr, u8 data)
306{
307 return pwr_reg_rdwr(&addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
308}
309EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
310
311/**
312 * intel_scu_ipc_iowrite16 - write a word via the SCU
313 * @addr: register on SCU
314 * @data: word to write
315 *
316 * Write two registers. Returns 0 on success or an error code. All
317 * locking between SCU accesses is handled for the caller.
318 *
319 * This function may sleep.
320 */
321int intel_scu_ipc_iowrite16(u16 addr, u16 data)
322{
323 u16 x[2] = {addr, addr + 1 };
324 return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
325}
326EXPORT_SYMBOL(intel_scu_ipc_iowrite16);
327
328/**
329 * intel_scu_ipc_iowrite32 - write a dword via the SCU
330 * @addr: register on SCU
331 * @data: dword to write
332 *
333 * Write four registers. Returns 0 on success or an error code. All
334 * locking between SCU accesses is handled for the caller.
335 *
336 * This function may sleep.
337 */
338int intel_scu_ipc_iowrite32(u16 addr, u32 data)
339{
340 u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
341 return pwr_reg_rdwr(x, (u8 *)&data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
342}
343EXPORT_SYMBOL(intel_scu_ipc_iowrite32);
344
345/**
346 * intel_scu_ipc_readvv - read a set of registers
347 * @addr: register list
348 * @data: bytes to return
349 * @len: length of array
350 *
351 * Read registers. Returns 0 on success or an error code. All
352 * locking between SCU accesses is handled for the caller.
353 *
354 * The largest array length permitted by the hardware is 5 items.
355 *
356 * This function may sleep.
357 */
358int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
359{
360 return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
361}
362EXPORT_SYMBOL(intel_scu_ipc_readv);
363
364/**
365 * intel_scu_ipc_writev - write a set of registers
366 * @addr: register list
367 * @data: bytes to write
368 * @len: length of array
369 *
370 * Write registers. Returns 0 on success or an error code. All
371 * locking between SCU accesses is handled for the caller.
372 *
373 * The largest array length permitted by the hardware is 5 items.
374 *
375 * This function may sleep.
376 *
377 */
378int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
379{
380 return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
381}
382EXPORT_SYMBOL(intel_scu_ipc_writev);
383
384
385/**
386 * intel_scu_ipc_update_register - r/m/w a register
387 * @addr: register address
388 * @bits: bits to update
389 * @mask: mask of bits to update
390 *
391 * Read-modify-write power control unit register. The first data argument
392 * must be register value and second is mask value
393 * mask is a bitmap that indicates which bits to update.
394 * 0 = masked. Don't modify this bit, 1 = modify this bit.
395 * returns 0 on success or an error code.
396 *
397 * This function may sleep. Locking between SCU accesses is handled
398 * for the caller.
399 */
400int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
401{
402 u8 data[2] = { bits, mask };
403 return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
404}
405EXPORT_SYMBOL(intel_scu_ipc_update_register);
406
407/**
408 * intel_scu_ipc_register_read - 32bit indirect read
409 * @addr: register address
410 * @value: 32bit value return
411 *
412 * Performs IA 32 bit indirect read, returns 0 on success, or an
413 * error code.
414 *
415 * Can be used when SCCB(System Controller Configuration Block) register
416 * HRIM(Honor Restricted IPC Messages) is set (bit 23)
417 *
418 * This function may sleep. Locking for SCU accesses is handled for
419 * the caller.
420 */
421int intel_scu_ipc_register_read(u32 addr, u32 *value)
422{
423 u32 err = 0;
424
425 mutex_lock(&ipclock);
426 if (ipcdev.pdev == NULL) {
427 mutex_unlock(&ipclock);
428 return -ENODEV;
429 }
430 ipc_write_sptr(addr);
431 ipc_command(4 << 16 | IPC_CMD_INDIRECT_RD);
432 err = busy_loop();
433 *value = ipc_data_readl(0);
434 mutex_unlock(&ipclock);
435 return err;
436}
437EXPORT_SYMBOL(intel_scu_ipc_register_read);
438
439/**
440 * intel_scu_ipc_register_write - 32bit indirect write
441 * @addr: register address
442 * @value: 32bit value to write
443 *
444 * Performs IA 32 bit indirect write, returns 0 on success, or an
445 * error code.
446 *
447 * Can be used when SCCB(System Controller Configuration Block) register
448 * HRIM(Honor Restricted IPC Messages) is set (bit 23)
449 *
450 * This function may sleep. Locking for SCU accesses is handled for
451 * the caller.
452 */
453int intel_scu_ipc_register_write(u32 addr, u32 value)
454{
455 u32 err = 0;
456
457 mutex_lock(&ipclock);
458 if (ipcdev.pdev == NULL) {
459 mutex_unlock(&ipclock);
460 return -ENODEV;
461 }
462 ipc_write_dptr(addr);
463 ipc_data_writel(value, 0);
464 ipc_command(4 << 16 | IPC_CMD_INDIRECT_WR);
465 err = busy_loop();
466 mutex_unlock(&ipclock);
467 return err;
468}
469EXPORT_SYMBOL(intel_scu_ipc_register_write);
470
471/**
472 * intel_scu_ipc_simple_command - send a simple command
473 * @cmd: command
474 * @sub: sub type
475 *
476 * Issue a simple command to the SCU. Do not use this interface if
477 * you must then access data as any data values may be overwritten
478 * by another SCU access by the time this function returns.
479 *
480 * This function may sleep. Locking for SCU accesses is handled for
481 * the caller.
482 */
483int intel_scu_ipc_simple_command(int cmd, int sub)
484{
485 u32 err = 0;
486
487 mutex_lock(&ipclock);
488 if (ipcdev.pdev == NULL) {
489 mutex_unlock(&ipclock);
490 return -ENODEV;
491 }
492 ipc_command(cmd << 12 | sub);
493 err = busy_loop();
494 mutex_unlock(&ipclock);
495 return err;
496}
497EXPORT_SYMBOL(intel_scu_ipc_simple_command);
498
499/**
500 * intel_scu_ipc_command - command with data
501 * @cmd: command
502 * @sub: sub type
503 * @in: input data
504 * @inlen: input length
505 * @out: output data
506 * @outlein: output length
507 *
508 * Issue a command to the SCU which involves data transfers. Do the
509 * data copies under the lock but leave it for the caller to interpret
510 */
511
512int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
513 u32 *out, int outlen)
514{
515 u32 err = 0;
516 int i = 0;
517
518 mutex_lock(&ipclock);
519 if (ipcdev.pdev == NULL) {
520 mutex_unlock(&ipclock);
521 return -ENODEV;
522 }
523
524 for (i = 0; i < inlen; i++)
525 ipc_data_writel(*in++, 4 * i);
526
527 ipc_command(cmd << 12 | sub);
528 err = busy_loop();
529
530 for (i = 0; i < outlen; i++)
531 *out++ = ipc_data_readl(4 * i);
532
533 mutex_unlock(&ipclock);
534 return err;
535}
536EXPORT_SYMBOL(intel_scu_ipc_command);
537
538/*I2C commands */
539#define IPC_I2C_WRITE 1 /* I2C Write command */
540#define IPC_I2C_READ 2 /* I2C Read command */
541
542/**
543 * intel_scu_ipc_i2c_cntrl - I2C read/write operations
544 * @addr: I2C address + command bits
545 * @data: data to read/write
546 *
547 * Perform an an I2C read/write operation via the SCU. All locking is
548 * handled for the caller. This function may sleep.
549 *
550 * Returns an error code or 0 on success.
551 *
552 * This has to be in the IPC driver for the locking.
553 */
554int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
555{
556 u32 cmd = 0;
557
558 mutex_lock(&ipclock);
559 cmd = (addr >> 24) & 0xFF;
560 if (cmd == IPC_I2C_READ) {
561 writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR);
562 /* Write not getting updated without delay */
563 mdelay(1);
564 *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR);
565 } else if (cmd == IPC_I2C_WRITE) {
566 writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR);
567 mdelay(1);
568 writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR);
569 } else {
570 dev_err(&ipcdev.pdev->dev,
571 "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd);
572
573 mutex_unlock(&ipclock);
574 return -1;
575 }
576 mutex_unlock(&ipclock);
577 return 0;
578}
579EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
580
581#define IPC_FW_LOAD_ADDR 0xFFFC0000 /* Storage location for FW image */
582#define IPC_FW_UPDATE_MBOX_ADDR 0xFFFFDFF4 /* Mailbox between ipc and scu */
583#define IPC_MAX_FW_SIZE 262144 /* 256K storage size for loading the FW image */
584#define IPC_FW_MIP_HEADER_SIZE 2048 /* Firmware MIP header size */
585/* IPC inform SCU to get ready for update process */
586#define IPC_CMD_FW_UPDATE_READY 0x10FE
587/* IPC inform SCU to go for update process */
588#define IPC_CMD_FW_UPDATE_GO 0x20FE
589/* Status code for fw update */
590#define IPC_FW_UPDATE_SUCCESS 0x444f4e45 /* Status code 'DONE' */
591#define IPC_FW_UPDATE_BADN 0x4241444E /* Status code 'BADN' */
592#define IPC_FW_TXHIGH 0x54784849 /* Status code 'IPC_FW_TXHIGH' */
593#define IPC_FW_TXLOW 0x54784c4f /* Status code 'IPC_FW_TXLOW' */
594
595struct fw_update_mailbox {
596 u32 status;
597 u32 scu_flag;
598 u32 driver_flag;
599};
600
601
602/**
603 * intel_scu_ipc_fw_update - Firmware update utility
604 * @buffer: firmware buffer
605 * @length: size of firmware buffer
606 *
607 * This function provides an interface to load the firmware into
608 * the SCU. Returns 0 on success or -1 on failure
609 */
610int intel_scu_ipc_fw_update(u8 *buffer, u32 length)
611{
612 void __iomem *fw_update_base;
613 struct fw_update_mailbox __iomem *mailbox = NULL;
614 int retry_cnt = 0;
615 u32 status;
616
617 mutex_lock(&ipclock);
618 fw_update_base = ioremap_nocache(IPC_FW_LOAD_ADDR, (128*1024));
619 if (fw_update_base == NULL) {
620 mutex_unlock(&ipclock);
621 return -ENOMEM;
622 }
623 mailbox = ioremap_nocache(IPC_FW_UPDATE_MBOX_ADDR,
624 sizeof(struct fw_update_mailbox));
625 if (mailbox == NULL) {
626 iounmap(fw_update_base);
627 mutex_unlock(&ipclock);
628 return -ENOMEM;
629 }
630
631 ipc_command(IPC_CMD_FW_UPDATE_READY);
632
633 /* Intitialize mailbox */
634 writel(0, &mailbox->status);
635 writel(0, &mailbox->scu_flag);
636 writel(0, &mailbox->driver_flag);
637
638 /* Driver copies the 2KB MIP header to SRAM at 0xFFFC0000*/
639 memcpy_toio(fw_update_base, buffer, 0x800);
640
641 /* Driver sends "FW Update" IPC command (CMD_ID 0xFE; MSG_ID 0x02).
642 * Upon receiving this command, SCU will write the 2K MIP header
643 * from 0xFFFC0000 into NAND.
644 * SCU will write a status code into the Mailbox, and then set scu_flag.
645 */
646
647 ipc_command(IPC_CMD_FW_UPDATE_GO);
648
649 /*Driver stalls until scu_flag is set */
650 while (readl(&mailbox->scu_flag) != 1) {
651 rmb();
652 mdelay(1);
653 }
654
655 /* Driver checks Mailbox status.
656 * If the status is 'BADN', then abort (bad NAND).
657 * If the status is 'IPC_FW_TXLOW', then continue.
658 */
659 while (readl(&mailbox->status) != IPC_FW_TXLOW) {
660 rmb();
661 mdelay(10);
662 }
663 mdelay(10);
664
665update_retry:
666 if (retry_cnt > 5)
667 goto update_end;
668
669 if (readl(&mailbox->status) != IPC_FW_TXLOW)
670 goto update_end;
671 buffer = buffer + 0x800;
672 memcpy_toio(fw_update_base, buffer, 0x20000);
673 writel(1, &mailbox->driver_flag);
674 while (readl(&mailbox->scu_flag) == 1) {
675 rmb();
676 mdelay(1);
677 }
678
679 /* check for 'BADN' */
680 if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN)
681 goto update_end;
682
683 while (readl(&mailbox->status) != IPC_FW_TXHIGH) {
684 rmb();
685 mdelay(10);
686 }
687 mdelay(10);
688
689 if (readl(&mailbox->status) != IPC_FW_TXHIGH)
690 goto update_end;
691
692 buffer = buffer + 0x20000;
693 memcpy_toio(fw_update_base, buffer, 0x20000);
694 writel(0, &mailbox->driver_flag);
695
696 while (mailbox->scu_flag == 0) {
697 rmb();
698 mdelay(1);
699 }
700
701 /* check for 'BADN' */
702 if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN)
703 goto update_end;
704
705 if (readl(&mailbox->status) == IPC_FW_TXLOW) {
706 ++retry_cnt;
707 goto update_retry;
708 }
709
710update_end:
711 status = readl(&mailbox->status);
712
713 iounmap(fw_update_base);
714 iounmap(mailbox);
715 mutex_unlock(&ipclock);
716
717 if (status == IPC_FW_UPDATE_SUCCESS)
718 return 0;
719 return -1;
720}
721EXPORT_SYMBOL(intel_scu_ipc_fw_update);
722
723/*
724 * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
725 * When ioc bit is set to 1, caller api must wait for interrupt handler called
726 * which in turn unlocks the caller api. Currently this is not used
727 *
728 * This is edge triggered so we need take no action to clear anything
729 */
730static irqreturn_t ioc(int irq, void *dev_id)
731{
732 return IRQ_HANDLED;
733}
734
735/**
736 * ipc_probe - probe an Intel SCU IPC
737 * @dev: the PCI device matching
738 * @id: entry in the match table
739 *
740 * Enable and install an intel SCU IPC. This appears in the PCI space
741 * but uses some hard coded addresses as well.
742 */
743static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id)
744{
745 int err;
746 resource_size_t pci_resource;
747
748 if (ipcdev.pdev) /* We support only one SCU */
749 return -EBUSY;
750
751 ipcdev.pdev = pci_dev_get(dev);
752
753 err = pci_enable_device(dev);
754 if (err)
755 return err;
756
757 err = pci_request_regions(dev, "intel_scu_ipc");
758 if (err)
759 return err;
760
761 pci_resource = pci_resource_start(dev, 0);
762 if (!pci_resource)
763 return -ENOMEM;
764
765 if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev))
766 return -EBUSY;
767
768 ipcdev.ipc_base = ioremap_nocache(IPC_BASE_ADDR, IPC_MAX_ADDR);
769 if (!ipcdev.ipc_base)
770 return -ENOMEM;
771
772 ipcdev.i2c_base = ioremap_nocache(IPC_I2C_BASE, IPC_I2C_MAX_ADDR);
773 if (!ipcdev.i2c_base) {
774 iounmap(ipcdev.ipc_base);
775 return -ENOMEM;
776 }
777 return 0;
778}
779
780/**
781 * ipc_remove - remove a bound IPC device
782 * @pdev: PCI device
783 *
784 * In practice the SCU is not removable but this function is also
785 * called for each device on a module unload or cleanup which is the
786 * path that will get used.
787 *
788 * Free up the mappings and release the PCI resources
789 */
790static void ipc_remove(struct pci_dev *pdev)
791{
792 free_irq(pdev->irq, &ipcdev);
793 pci_release_regions(pdev);
794 pci_dev_put(ipcdev.pdev);
795 iounmap(ipcdev.ipc_base);
796 iounmap(ipcdev.i2c_base);
797 ipcdev.pdev = NULL;
798}
799
800static const struct pci_device_id pci_ids[] = {
801 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)},
802 { 0,}
803};
804MODULE_DEVICE_TABLE(pci, pci_ids);
805
806static struct pci_driver ipc_driver = {
807 .name = "intel_scu_ipc",
808 .id_table = pci_ids,
809 .probe = ipc_probe,
810 .remove = ipc_remove,
811};
812
813
814static int __init intel_scu_ipc_init(void)
815{
816 return pci_register_driver(&ipc_driver);
817}
818
819static void __exit intel_scu_ipc_exit(void)
820{
821 pci_unregister_driver(&ipc_driver);
822}
823
824MODULE_AUTHOR("Sreedhara DS <sreedhara.ds@intel.com>");
825MODULE_DESCRIPTION("Intel SCU IPC driver");
826MODULE_LICENSE("GPL");
827
828module_init(intel_scu_ipc_init);
829module_exit(intel_scu_ipc_exit);
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
index 996223a7c009..afd762b58ad9 100644
--- a/drivers/platform/x86/msi-laptop.c
+++ b/drivers/platform/x86/msi-laptop.c
@@ -59,6 +59,7 @@
59#include <linux/backlight.h> 59#include <linux/backlight.h>
60#include <linux/platform_device.h> 60#include <linux/platform_device.h>
61#include <linux/rfkill.h> 61#include <linux/rfkill.h>
62#include <linux/i8042.h>
62 63
63#define MSI_DRIVER_VERSION "0.5" 64#define MSI_DRIVER_VERSION "0.5"
64 65
@@ -118,7 +119,8 @@ static int set_lcd_level(int level)
118 buf[0] = 0x80; 119 buf[0] = 0x80;
119 buf[1] = (u8) (level*31); 120 buf[1] = (u8) (level*31);
120 121
121 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0, 1); 122 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf),
123 NULL, 0, 1);
122} 124}
123 125
124static int get_lcd_level(void) 126static int get_lcd_level(void)
@@ -126,7 +128,8 @@ static int get_lcd_level(void)
126 u8 wdata = 0, rdata; 128 u8 wdata = 0, rdata;
127 int result; 129 int result;
128 130
129 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1, 1); 131 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1,
132 &rdata, 1, 1);
130 if (result < 0) 133 if (result < 0)
131 return result; 134 return result;
132 135
@@ -138,7 +141,8 @@ static int get_auto_brightness(void)
138 u8 wdata = 4, rdata; 141 u8 wdata = 4, rdata;
139 int result; 142 int result;
140 143
141 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1, 1); 144 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1,
145 &rdata, 1, 1);
142 if (result < 0) 146 if (result < 0)
143 return result; 147 return result;
144 148
@@ -152,14 +156,16 @@ static int set_auto_brightness(int enable)
152 156
153 wdata[0] = 4; 157 wdata[0] = 4;
154 158
155 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1, 1); 159 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1,
160 &rdata, 1, 1);
156 if (result < 0) 161 if (result < 0)
157 return result; 162 return result;
158 163
159 wdata[0] = 0x84; 164 wdata[0] = 0x84;
160 wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); 165 wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0);
161 166
162 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1); 167 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2,
168 NULL, 0, 1);
163} 169}
164 170
165static ssize_t set_device_state(const char *buf, size_t count, u8 mask) 171static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
@@ -254,7 +260,7 @@ static int bl_update_status(struct backlight_device *b)
254 return set_lcd_level(b->props.brightness); 260 return set_lcd_level(b->props.brightness);
255} 261}
256 262
257static struct backlight_ops msibl_ops = { 263static const struct backlight_ops msibl_ops = {
258 .get_brightness = bl_get_brightness, 264 .get_brightness = bl_get_brightness,
259 .update_status = bl_update_status, 265 .update_status = bl_update_status,
260}; 266};
@@ -353,7 +359,8 @@ static ssize_t store_lcd_level(struct device *dev,
353 359
354 int level, ret; 360 int level, ret;
355 361
356 if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX)) 362 if (sscanf(buf, "%i", &level) != 1 ||
363 (level < 0 || level >= MSI_LCD_LEVEL_MAX))
357 return -EINVAL; 364 return -EINVAL;
358 365
359 ret = set_lcd_level(level); 366 ret = set_lcd_level(level);
@@ -393,7 +400,8 @@ static ssize_t store_auto_brightness(struct device *dev,
393} 400}
394 401
395static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); 402static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
396static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); 403static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness,
404 store_auto_brightness);
397static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); 405static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL);
398static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); 406static DEVICE_ATTR(wlan, 0444, show_wlan, NULL);
399static DEVICE_ATTR(threeg, 0444, show_threeg, NULL); 407static DEVICE_ATTR(threeg, 0444, show_threeg, NULL);
@@ -424,8 +432,9 @@ static struct platform_device *msipf_device;
424 432
425static int dmi_check_cb(const struct dmi_system_id *id) 433static int dmi_check_cb(const struct dmi_system_id *id)
426{ 434{
427 printk("msi-laptop: Identified laptop model '%s'.\n", id->ident); 435 printk(KERN_INFO "msi-laptop: Identified laptop model '%s'.\n",
428 return 0; 436 id->ident);
437 return 0;
429} 438}
430 439
431static struct dmi_system_id __initdata msi_dmi_table[] = { 440static struct dmi_system_id __initdata msi_dmi_table[] = {
@@ -435,7 +444,8 @@ static struct dmi_system_id __initdata msi_dmi_table[] = {
435 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), 444 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
436 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), 445 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
437 DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), 446 DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
438 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD") 447 DMI_MATCH(DMI_CHASSIS_VENDOR,
448 "MICRO-STAR INT'L CO.,LTD")
439 }, 449 },
440 .callback = dmi_check_cb 450 .callback = dmi_check_cb
441 }, 451 },
@@ -465,7 +475,8 @@ static struct dmi_system_id __initdata msi_dmi_table[] = {
465 DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), 475 DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
466 DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), 476 DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
467 DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), 477 DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
468 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD") 478 DMI_MATCH(DMI_CHASSIS_VENDOR,
479 "MICRO-STAR INT'L CO.,LTD")
469 }, 480 },
470 .callback = dmi_check_cb 481 .callback = dmi_check_cb
471 }, 482 },
@@ -484,6 +495,35 @@ static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = {
484 }, 495 },
485 .callback = dmi_check_cb 496 .callback = dmi_check_cb
486 }, 497 },
498 {
499 .ident = "MSI N051",
500 .matches = {
501 DMI_MATCH(DMI_SYS_VENDOR,
502 "MICRO-STAR INTERNATIONAL CO., LTD"),
503 DMI_MATCH(DMI_PRODUCT_NAME, "MS-N051"),
504 DMI_MATCH(DMI_CHASSIS_VENDOR,
505 "MICRO-STAR INTERNATIONAL CO., LTD")
506 },
507 .callback = dmi_check_cb
508 },
509 {
510 .ident = "MSI N014",
511 .matches = {
512 DMI_MATCH(DMI_SYS_VENDOR,
513 "MICRO-STAR INTERNATIONAL CO., LTD"),
514 DMI_MATCH(DMI_PRODUCT_NAME, "MS-N014"),
515 },
516 .callback = dmi_check_cb
517 },
518 {
519 .ident = "MSI CR620",
520 .matches = {
521 DMI_MATCH(DMI_SYS_VENDOR,
522 "Micro-Star International"),
523 DMI_MATCH(DMI_PRODUCT_NAME, "CR620"),
524 },
525 .callback = dmi_check_cb
526 },
487 { } 527 { }
488}; 528};
489 529
@@ -552,11 +592,71 @@ static void rfkill_cleanup(void)
552 } 592 }
553} 593}
554 594
595static void msi_update_rfkill(struct work_struct *ignored)
596{
597 get_wireless_state_ec_standard();
598
599 if (rfk_wlan)
600 rfkill_set_sw_state(rfk_wlan, !wlan_s);
601 if (rfk_bluetooth)
602 rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s);
603 if (rfk_threeg)
604 rfkill_set_sw_state(rfk_threeg, !threeg_s);
605}
606static DECLARE_DELAYED_WORK(msi_rfkill_work, msi_update_rfkill);
607
608static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
609 struct serio *port)
610{
611 static bool extended;
612
613 if (str & 0x20)
614 return false;
615
616 /* 0x54 wwan, 0x62 bluetooth, 0x76 wlan*/
617 if (unlikely(data == 0xe0)) {
618 extended = true;
619 return false;
620 } else if (unlikely(extended)) {
621 switch (data) {
622 case 0x54:
623 case 0x62:
624 case 0x76:
625 schedule_delayed_work(&msi_rfkill_work,
626 round_jiffies_relative(0.5 * HZ));
627 break;
628 }
629 extended = false;
630 }
631
632 return false;
633}
634
635static void msi_init_rfkill(struct work_struct *ignored)
636{
637 if (rfk_wlan) {
638 rfkill_set_sw_state(rfk_wlan, !wlan_s);
639 rfkill_wlan_set(NULL, !wlan_s);
640 }
641 if (rfk_bluetooth) {
642 rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s);
643 rfkill_bluetooth_set(NULL, !bluetooth_s);
644 }
645 if (rfk_threeg) {
646 rfkill_set_sw_state(rfk_threeg, !threeg_s);
647 rfkill_threeg_set(NULL, !threeg_s);
648 }
649}
650static DECLARE_DELAYED_WORK(msi_rfkill_init, msi_init_rfkill);
651
555static int rfkill_init(struct platform_device *sdev) 652static int rfkill_init(struct platform_device *sdev)
556{ 653{
557 /* add rfkill */ 654 /* add rfkill */
558 int retval; 655 int retval;
559 656
657 /* keep the hardware wireless state */
658 get_wireless_state_ec_standard();
659
560 rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev, 660 rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev,
561 RFKILL_TYPE_BLUETOOTH, 661 RFKILL_TYPE_BLUETOOTH,
562 &rfkill_bluetooth_ops, NULL); 662 &rfkill_bluetooth_ops, NULL);
@@ -590,6 +690,10 @@ static int rfkill_init(struct platform_device *sdev)
590 goto err_threeg; 690 goto err_threeg;
591 } 691 }
592 692
693 /* schedule to run rfkill state initial */
694 schedule_delayed_work(&msi_rfkill_init,
695 round_jiffies_relative(1 * HZ));
696
593 return 0; 697 return 0;
594 698
595err_threeg: 699err_threeg:
@@ -653,9 +757,24 @@ static int load_scm_model_init(struct platform_device *sdev)
653 /* initial rfkill */ 757 /* initial rfkill */
654 result = rfkill_init(sdev); 758 result = rfkill_init(sdev);
655 if (result < 0) 759 if (result < 0)
656 return result; 760 goto fail_rfkill;
761
762 result = i8042_install_filter(msi_laptop_i8042_filter);
763 if (result) {
764 printk(KERN_ERR
765 "msi-laptop: Unable to install key filter\n");
766 goto fail_filter;
767 }
657 768
658 return 0; 769 return 0;
770
771fail_filter:
772 rfkill_cleanup();
773
774fail_rfkill:
775
776 return result;
777
659} 778}
660 779
661static int __init msi_init(void) 780static int __init msi_init(void)
@@ -714,7 +833,8 @@ static int __init msi_init(void)
714 goto fail_platform_device1; 833 goto fail_platform_device1;
715 } 834 }
716 835
717 ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); 836 ret = sysfs_create_group(&msipf_device->dev.kobj,
837 &msipf_attribute_group);
718 if (ret) 838 if (ret)
719 goto fail_platform_device2; 839 goto fail_platform_device2;
720 840
@@ -739,6 +859,11 @@ static int __init msi_init(void)
739 859
740fail_platform_device2: 860fail_platform_device2:
741 861
862 if (load_scm_model) {
863 i8042_remove_filter(msi_laptop_i8042_filter);
864 cancel_delayed_work_sync(&msi_rfkill_work);
865 rfkill_cleanup();
866 }
742 platform_device_del(msipf_device); 867 platform_device_del(msipf_device);
743 868
744fail_platform_device1: 869fail_platform_device1:
@@ -758,6 +883,11 @@ fail_backlight:
758 883
759static void __exit msi_cleanup(void) 884static void __exit msi_cleanup(void)
760{ 885{
886 if (load_scm_model) {
887 i8042_remove_filter(msi_laptop_i8042_filter);
888 cancel_delayed_work_sync(&msi_rfkill_work);
889 rfkill_cleanup();
890 }
761 891
762 sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); 892 sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
763 if (!old_ec_model && threeg_exists) 893 if (!old_ec_model && threeg_exists)
@@ -766,8 +896,6 @@ static void __exit msi_cleanup(void)
766 platform_driver_unregister(&msipf_driver); 896 platform_driver_unregister(&msipf_driver);
767 backlight_device_unregister(msibl_device); 897 backlight_device_unregister(msibl_device);
768 898
769 rfkill_cleanup();
770
771 /* Enable automatic brightness control again */ 899 /* Enable automatic brightness control again */
772 if (auto_brightness != 2) 900 if (auto_brightness != 2)
773 set_auto_brightness(1); 901 set_auto_brightness(1);
@@ -788,3 +916,6 @@ MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-105
788MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); 916MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
789MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); 917MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
790MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*"); 918MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*");
919MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N051:*");
920MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N014:*");
921MODULE_ALIAS("dmi:*:svnMicro-StarInternational*:pnCR620:*");
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 63290b33c879..4bdb13796e24 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -122,8 +122,14 @@ enum {
122 TP_NVRAM_POS_LEVEL_VOLUME = 0, 122 TP_NVRAM_POS_LEVEL_VOLUME = 0,
123}; 123};
124 124
125/* Misc NVRAM-related */
126enum {
127 TP_NVRAM_LEVEL_VOLUME_MAX = 14,
128};
129
125/* ACPI HIDs */ 130/* ACPI HIDs */
126#define TPACPI_ACPI_HKEY_HID "IBM0068" 131#define TPACPI_ACPI_HKEY_HID "IBM0068"
132#define TPACPI_ACPI_EC_HID "PNP0C09"
127 133
128/* Input IDs */ 134/* Input IDs */
129#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */ 135#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */
@@ -299,8 +305,8 @@ static struct {
299 u32 hotkey_tablet:1; 305 u32 hotkey_tablet:1;
300 u32 light:1; 306 u32 light:1;
301 u32 light_status:1; 307 u32 light_status:1;
302 u32 bright_16levels:1;
303 u32 bright_acpimode:1; 308 u32 bright_acpimode:1;
309 u32 bright_unkfw:1;
304 u32 wan:1; 310 u32 wan:1;
305 u32 uwb:1; 311 u32 uwb:1;
306 u32 fan_ctrl_status_undef:1; 312 u32 fan_ctrl_status_undef:1;
@@ -363,6 +369,9 @@ struct tpacpi_led_classdev {
363 unsigned int led; 369 unsigned int led;
364}; 370};
365 371
372/* brightness level capabilities */
373static unsigned int bright_maxlvl; /* 0 = unknown */
374
366#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 375#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
367static int dbg_wlswemul; 376static int dbg_wlswemul;
368static int tpacpi_wlsw_emulstate; 377static int tpacpi_wlsw_emulstate;
@@ -480,6 +489,15 @@ static unsigned long __init tpacpi_check_quirks(
480 return 0; 489 return 0;
481} 490}
482 491
492static inline bool __pure __init tpacpi_is_lenovo(void)
493{
494 return thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO;
495}
496
497static inline bool __pure __init tpacpi_is_ibm(void)
498{
499 return thinkpad_id.vendor == PCI_VENDOR_ID_IBM;
500}
483 501
484/**************************************************************************** 502/****************************************************************************
485 **************************************************************************** 503 ****************************************************************************
@@ -494,21 +512,13 @@ static unsigned long __init tpacpi_check_quirks(
494 */ 512 */
495 513
496static acpi_handle root_handle; 514static acpi_handle root_handle;
515static acpi_handle ec_handle;
497 516
498#define TPACPI_HANDLE(object, parent, paths...) \ 517#define TPACPI_HANDLE(object, parent, paths...) \
499 static acpi_handle object##_handle; \ 518 static acpi_handle object##_handle; \
500 static acpi_handle *object##_parent = &parent##_handle; \ 519 static const acpi_handle *object##_parent __initdata = \
501 static char *object##_path; \ 520 &parent##_handle; \
502 static char *object##_paths[] = { paths } 521 static char *object##_paths[] __initdata = { paths }
503
504TPACPI_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */
505 "\\_SB.PCI.ISA.EC", /* 570 */
506 "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */
507 "\\_SB.PCI0.ISA.EC", /* A21e, A2xm/p, T20-22, X20-21 */
508 "\\_SB.PCI0.AD4S.EC0", /* i1400, R30 */
509 "\\_SB.PCI0.ICH3.EC0", /* R31 */
510 "\\_SB.PCI0.LPC.EC", /* all others */
511 );
512 522
513TPACPI_HANDLE(ecrd, ec, "ECRD"); /* 570 */ 523TPACPI_HANDLE(ecrd, ec, "ECRD"); /* 570 */
514TPACPI_HANDLE(ecwr, ec, "ECWR"); /* 570 */ 524TPACPI_HANDLE(ecwr, ec, "ECWR"); /* 570 */
@@ -528,6 +538,7 @@ TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */
528 "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ 538 "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */
529 "\\_SB.PCI0.VID0", /* 770e */ 539 "\\_SB.PCI0.VID0", /* 770e */
530 "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ 540 "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */
541 "\\_SB.PCI0.AGP.VGA", /* X100e and a few others */
531 "\\_SB.PCI0.AGP.VID", /* all others */ 542 "\\_SB.PCI0.AGP.VID", /* all others */
532 ); /* R30, R31 */ 543 ); /* R30, R31 */
533 544
@@ -594,9 +605,10 @@ static int acpi_evalf(acpi_handle handle,
594 605
595 switch (res_type) { 606 switch (res_type) {
596 case 'd': /* int */ 607 case 'd': /* int */
597 if (res) 608 success = (status == AE_OK &&
609 out_obj.type == ACPI_TYPE_INTEGER);
610 if (success && res)
598 *(int *)res = out_obj.integer.value; 611 *(int *)res = out_obj.integer.value;
599 success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER;
600 break; 612 break;
601 case 'v': /* void */ 613 case 'v': /* void */
602 success = status == AE_OK; 614 success = status == AE_OK;
@@ -609,8 +621,8 @@ static int acpi_evalf(acpi_handle handle,
609 } 621 }
610 622
611 if (!success && !quiet) 623 if (!success && !quiet)
612 printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %d\n", 624 printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %s\n",
613 method, fmt0, status); 625 method, fmt0, acpi_format_exception(status));
614 626
615 return success; 627 return success;
616} 628}
@@ -661,11 +673,11 @@ static int issue_thinkpad_cmos_command(int cmos_cmd)
661 673
662#define TPACPI_ACPIHANDLE_INIT(object) \ 674#define TPACPI_ACPIHANDLE_INIT(object) \
663 drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \ 675 drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \
664 object##_paths, ARRAY_SIZE(object##_paths), &object##_path) 676 object##_paths, ARRAY_SIZE(object##_paths))
665 677
666static void drv_acpi_handle_init(char *name, 678static void __init drv_acpi_handle_init(const char *name,
667 acpi_handle *handle, acpi_handle parent, 679 acpi_handle *handle, const acpi_handle parent,
668 char **paths, int num_paths, char **path) 680 char **paths, const int num_paths)
669{ 681{
670 int i; 682 int i;
671 acpi_status status; 683 acpi_status status;
@@ -676,10 +688,9 @@ static void drv_acpi_handle_init(char *name,
676 for (i = 0; i < num_paths; i++) { 688 for (i = 0; i < num_paths; i++) {
677 status = acpi_get_handle(parent, paths[i], handle); 689 status = acpi_get_handle(parent, paths[i], handle);
678 if (ACPI_SUCCESS(status)) { 690 if (ACPI_SUCCESS(status)) {
679 *path = paths[i];
680 dbg_printk(TPACPI_DBG_INIT, 691 dbg_printk(TPACPI_DBG_INIT,
681 "Found ACPI handle %s for %s\n", 692 "Found ACPI handle %s for %s\n",
682 *path, name); 693 paths[i], name);
683 return; 694 return;
684 } 695 }
685 } 696 }
@@ -689,6 +700,43 @@ static void drv_acpi_handle_init(char *name,
689 *handle = NULL; 700 *handle = NULL;
690} 701}
691 702
703static acpi_status __init tpacpi_acpi_handle_locate_callback(acpi_handle handle,
704 u32 level, void *context, void **return_value)
705{
706 *(acpi_handle *)return_value = handle;
707
708 return AE_CTRL_TERMINATE;
709}
710
711static void __init tpacpi_acpi_handle_locate(const char *name,
712 const char *hid,
713 acpi_handle *handle)
714{
715 acpi_status status;
716 acpi_handle device_found;
717
718 BUG_ON(!name || !hid || !handle);
719 vdbg_printk(TPACPI_DBG_INIT,
720 "trying to locate ACPI handle for %s, using HID %s\n",
721 name, hid);
722
723 memset(&device_found, 0, sizeof(device_found));
724 status = acpi_get_devices(hid, tpacpi_acpi_handle_locate_callback,
725 (void *)name, &device_found);
726
727 *handle = NULL;
728
729 if (ACPI_SUCCESS(status)) {
730 *handle = device_found;
731 dbg_printk(TPACPI_DBG_INIT,
732 "Found ACPI handle for %s\n", name);
733 } else {
734 vdbg_printk(TPACPI_DBG_INIT,
735 "Could not locate an ACPI handle for %s: %s\n",
736 name, acpi_format_exception(status));
737 }
738}
739
692static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data) 740static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
693{ 741{
694 struct ibm_struct *ibm = data; 742 struct ibm_struct *ibm = data;
@@ -736,8 +784,8 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm)
736 "handling %s events\n", ibm->name); 784 "handling %s events\n", ibm->name);
737 } else { 785 } else {
738 printk(TPACPI_ERR 786 printk(TPACPI_ERR
739 "acpi_install_notify_handler(%s) failed: %d\n", 787 "acpi_install_notify_handler(%s) failed: %s\n",
740 ibm->name, status); 788 ibm->name, acpi_format_exception(status));
741 } 789 }
742 return -ENODEV; 790 return -ENODEV;
743 } 791 }
@@ -1035,80 +1083,6 @@ static void tpacpi_disable_brightness_delay(void)
1035 "ACPI backlight control delay disabled\n"); 1083 "ACPI backlight control delay disabled\n");
1036} 1084}
1037 1085
1038static int __init tpacpi_query_bcl_levels(acpi_handle handle)
1039{
1040 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1041 union acpi_object *obj;
1042 int rc;
1043
1044 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
1045 obj = (union acpi_object *)buffer.pointer;
1046 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
1047 printk(TPACPI_ERR "Unknown _BCL data, "
1048 "please report this to %s\n", TPACPI_MAIL);
1049 rc = 0;
1050 } else {
1051 rc = obj->package.count;
1052 }
1053 } else {
1054 return 0;
1055 }
1056
1057 kfree(buffer.pointer);
1058 return rc;
1059}
1060
1061static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
1062 u32 lvl, void *context, void **rv)
1063{
1064 char name[ACPI_PATH_SEGMENT_LENGTH];
1065 struct acpi_buffer buffer = { sizeof(name), &name };
1066
1067 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
1068 !strncmp("_BCL", name, sizeof(name) - 1)) {
1069 BUG_ON(!rv || !*rv);
1070 **(int **)rv = tpacpi_query_bcl_levels(handle);
1071 return AE_CTRL_TERMINATE;
1072 } else {
1073 return AE_OK;
1074 }
1075}
1076
1077/*
1078 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
1079 */
1080static int __init tpacpi_check_std_acpi_brightness_support(void)
1081{
1082 int status;
1083 int bcl_levels = 0;
1084 void *bcl_ptr = &bcl_levels;
1085
1086 if (!vid_handle) {
1087 TPACPI_ACPIHANDLE_INIT(vid);
1088 }
1089 if (!vid_handle)
1090 return 0;
1091
1092 /*
1093 * Search for a _BCL method, and execute it. This is safe on all
1094 * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
1095 * BIOS in ACPI backlight control mode. We do NOT have to care
1096 * about calling the _BCL method in an enabled video device, any
1097 * will do for our purposes.
1098 */
1099
1100 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
1101 tpacpi_acpi_walk_find_bcl, NULL, NULL,
1102 &bcl_ptr);
1103
1104 if (ACPI_SUCCESS(status) && bcl_levels > 2) {
1105 tp_features.bright_acpimode = 1;
1106 return (bcl_levels - 2);
1107 }
1108
1109 return 0;
1110}
1111
1112static void printk_deprecated_attribute(const char * const what, 1086static void printk_deprecated_attribute(const char * const what,
1113 const char * const details) 1087 const char * const details)
1114{ 1088{
@@ -1872,34 +1846,9 @@ static bool __init tpacpi_is_fw_known(void)
1872 ****************************************************************************/ 1846 ****************************************************************************/
1873 1847
1874/************************************************************************* 1848/*************************************************************************
1875 * thinkpad-acpi init subdriver 1849 * thinkpad-acpi metadata subdriver
1876 */ 1850 */
1877 1851
1878static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
1879{
1880 printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION);
1881 printk(TPACPI_INFO "%s\n", TPACPI_URL);
1882
1883 printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n",
1884 (thinkpad_id.bios_version_str) ?
1885 thinkpad_id.bios_version_str : "unknown",
1886 (thinkpad_id.ec_version_str) ?
1887 thinkpad_id.ec_version_str : "unknown");
1888
1889 if (thinkpad_id.vendor && thinkpad_id.model_str)
1890 printk(TPACPI_INFO "%s %s, model %s\n",
1891 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
1892 "IBM" : ((thinkpad_id.vendor ==
1893 PCI_VENDOR_ID_LENOVO) ?
1894 "Lenovo" : "Unknown vendor"),
1895 thinkpad_id.model_str,
1896 (thinkpad_id.nummodel_str) ?
1897 thinkpad_id.nummodel_str : "unknown");
1898
1899 tpacpi_check_outdated_fw();
1900 return 0;
1901}
1902
1903static int thinkpad_acpi_driver_read(struct seq_file *m) 1852static int thinkpad_acpi_driver_read(struct seq_file *m)
1904{ 1853{
1905 seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC); 1854 seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC);
@@ -2405,6 +2354,36 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2405 tpacpi_hotkey_send_key(__scancode); \ 2354 tpacpi_hotkey_send_key(__scancode); \
2406 } while (0) 2355 } while (0)
2407 2356
2357 void issue_volchange(const unsigned int oldvol,
2358 const unsigned int newvol)
2359 {
2360 unsigned int i = oldvol;
2361
2362 while (i > newvol) {
2363 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
2364 i--;
2365 }
2366 while (i < newvol) {
2367 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
2368 i++;
2369 }
2370 }
2371
2372 void issue_brightnesschange(const unsigned int oldbrt,
2373 const unsigned int newbrt)
2374 {
2375 unsigned int i = oldbrt;
2376
2377 while (i > newbrt) {
2378 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
2379 i--;
2380 }
2381 while (i < newbrt) {
2382 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
2383 i++;
2384 }
2385 }
2386
2408 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle); 2387 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);
2409 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); 2388 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);
2410 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); 2389 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle);
@@ -2414,41 +2393,61 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2414 2393
2415 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle); 2394 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle);
2416 2395
2417 /* handle volume */ 2396 /*
2418 if (oldn->volume_toggle != newn->volume_toggle) { 2397 * Handle volume
2419 if (oldn->mute != newn->mute) { 2398 *
2399 * This code is supposed to duplicate the IBM firmware behaviour:
2400 * - Pressing MUTE issues mute hotkey message, even when already mute
2401 * - Pressing Volume up/down issues volume up/down hotkey messages,
2402 * even when already at maximum or minumum volume
2403 * - The act of unmuting issues volume up/down notification,
2404 * depending which key was used to unmute
2405 *
2406 * We are constrained to what the NVRAM can tell us, which is not much
2407 * and certainly not enough if more than one volume hotkey was pressed
2408 * since the last poll cycle.
2409 *
2410 * Just to make our life interesting, some newer Lenovo ThinkPads have
2411 * bugs in the BIOS and may fail to update volume_toggle properly.
2412 */
2413 if (newn->mute) {
2414 /* muted */
2415 if (!oldn->mute ||
2416 oldn->volume_toggle != newn->volume_toggle ||
2417 oldn->volume_level != newn->volume_level) {
2418 /* recently muted, or repeated mute keypress, or
2419 * multiple presses ending in mute */
2420 issue_volchange(oldn->volume_level, newn->volume_level);
2420 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE); 2421 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);
2421 } 2422 }
2422 if (oldn->volume_level > newn->volume_level) { 2423 } else {
2423 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); 2424 /* unmute */
2424 } else if (oldn->volume_level < newn->volume_level) { 2425 if (oldn->mute) {
2426 /* recently unmuted, issue 'unmute' keypress */
2425 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); 2427 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
2426 } else if (oldn->mute == newn->mute) { 2428 }
2427 /* repeated key presses that didn't change state */ 2429 if (oldn->volume_level != newn->volume_level) {
2428 if (newn->mute) { 2430 issue_volchange(oldn->volume_level, newn->volume_level);
2429 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE); 2431 } else if (oldn->volume_toggle != newn->volume_toggle) {
2430 } else if (newn->volume_level != 0) { 2432 /* repeated vol up/down keypress at end of scale ? */
2431 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); 2433 if (newn->volume_level == 0)
2432 } else {
2433 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); 2434 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
2434 } 2435 else if (newn->volume_level >= TP_NVRAM_LEVEL_VOLUME_MAX)
2436 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
2435 } 2437 }
2436 } 2438 }
2437 2439
2438 /* handle brightness */ 2440 /* handle brightness */
2439 if (oldn->brightness_toggle != newn->brightness_toggle) { 2441 if (oldn->brightness_level != newn->brightness_level) {
2440 if (oldn->brightness_level < newn->brightness_level) { 2442 issue_brightnesschange(oldn->brightness_level,
2441 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); 2443 newn->brightness_level);
2442 } else if (oldn->brightness_level > newn->brightness_level) { 2444 } else if (oldn->brightness_toggle != newn->brightness_toggle) {
2445 /* repeated key presses that didn't change state */
2446 if (newn->brightness_level == 0)
2443 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); 2447 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
2444 } else { 2448 else if (newn->brightness_level >= bright_maxlvl
2445 /* repeated key presses that didn't change state */ 2449 && !tp_features.bright_unkfw)
2446 if (newn->brightness_level != 0) { 2450 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
2447 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
2448 } else {
2449 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
2450 }
2451 }
2452 } 2451 }
2453 2452
2454#undef TPACPI_COMPARE_KEY 2453#undef TPACPI_COMPARE_KEY
@@ -3353,7 +3352,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3353 goto err_exit; 3352 goto err_exit;
3354 } 3353 }
3355 3354
3356 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { 3355 if (tpacpi_is_lenovo()) {
3357 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3356 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3358 "using Lenovo default hot key map\n"); 3357 "using Lenovo default hot key map\n");
3359 memcpy(hotkey_keycode_map, &lenovo_keycode_map, 3358 memcpy(hotkey_keycode_map, &lenovo_keycode_map,
@@ -3391,11 +3390,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3391 } 3390 }
3392 3391
3393 /* Do not issue duplicate brightness change events to 3392 /* Do not issue duplicate brightness change events to
3394 * userspace */ 3393 * userspace. tpacpi_detect_brightness_capabilities() must have
3395 if (!tp_features.bright_acpimode) 3394 * been called before this point */
3396 /* update bright_acpimode... */
3397 tpacpi_check_std_acpi_brightness_support();
3398
3399 if (tp_features.bright_acpimode && acpi_video_backlight_support()) { 3395 if (tp_features.bright_acpimode && acpi_video_backlight_support()) {
3400 printk(TPACPI_INFO 3396 printk(TPACPI_INFO
3401 "This ThinkPad has standard ACPI backlight " 3397 "This ThinkPad has standard ACPI backlight "
@@ -4422,7 +4418,8 @@ static int __init video_init(struct ibm_init_struct *iibm)
4422 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n"); 4418 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
4423 4419
4424 TPACPI_ACPIHANDLE_INIT(vid); 4420 TPACPI_ACPIHANDLE_INIT(vid);
4425 TPACPI_ACPIHANDLE_INIT(vid2); 4421 if (tpacpi_is_ibm())
4422 TPACPI_ACPIHANDLE_INIT(vid2);
4426 4423
4427 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga) 4424 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
4428 /* G41, assume IVGA doesn't change */ 4425 /* G41, assume IVGA doesn't change */
@@ -4431,10 +4428,12 @@ static int __init video_init(struct ibm_init_struct *iibm)
4431 if (!vid_handle) 4428 if (!vid_handle)
4432 /* video switching not supported on R30, R31 */ 4429 /* video switching not supported on R30, R31 */
4433 video_supported = TPACPI_VIDEO_NONE; 4430 video_supported = TPACPI_VIDEO_NONE;
4434 else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) 4431 else if (tpacpi_is_ibm() &&
4432 acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
4435 /* 570 */ 4433 /* 570 */
4436 video_supported = TPACPI_VIDEO_570; 4434 video_supported = TPACPI_VIDEO_570;
4437 else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) 4435 else if (tpacpi_is_ibm() &&
4436 acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
4438 /* 600e/x, 770e, 770x */ 4437 /* 600e/x, 770e, 770x */
4439 video_supported = TPACPI_VIDEO_770; 4438 video_supported = TPACPI_VIDEO_770;
4440 else 4439 else
@@ -4811,8 +4810,10 @@ static int __init light_init(struct ibm_init_struct *iibm)
4811 4810
4812 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); 4811 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
4813 4812
4814 TPACPI_ACPIHANDLE_INIT(ledb); 4813 if (tpacpi_is_ibm()) {
4815 TPACPI_ACPIHANDLE_INIT(lght); 4814 TPACPI_ACPIHANDLE_INIT(ledb);
4815 TPACPI_ACPIHANDLE_INIT(lght);
4816 }
4816 TPACPI_ACPIHANDLE_INIT(cmos); 4817 TPACPI_ACPIHANDLE_INIT(cmos);
4817 INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker); 4818 INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker);
4818 4819
@@ -5007,11 +5008,7 @@ enum { /* For TPACPI_LED_OLD */
5007 5008
5008static enum led_access_mode led_supported; 5009static enum led_access_mode led_supported;
5009 5010
5010TPACPI_HANDLE(led, ec, "SLED", /* 570 */ 5011static acpi_handle led_handle;
5011 "SYSL", /* 600e/x, 770e, 770x, A21e, A2xm/p, */
5012 /* T20-22, X20-21 */
5013 "LED", /* all others */
5014 ); /* R30, R31 */
5015 5012
5016#define TPACPI_LED_NUMLEDS 16 5013#define TPACPI_LED_NUMLEDS 16
5017static struct tpacpi_led_classdev *tpacpi_leds; 5014static struct tpacpi_led_classdev *tpacpi_leds;
@@ -5271,6 +5268,32 @@ static const struct tpacpi_quirk led_useful_qtable[] __initconst = {
5271#undef TPACPI_LEDQ_IBM 5268#undef TPACPI_LEDQ_IBM
5272#undef TPACPI_LEDQ_LNV 5269#undef TPACPI_LEDQ_LNV
5273 5270
5271static enum led_access_mode __init led_init_detect_mode(void)
5272{
5273 acpi_status status;
5274
5275 if (tpacpi_is_ibm()) {
5276 /* 570 */
5277 status = acpi_get_handle(ec_handle, "SLED", &led_handle);
5278 if (ACPI_SUCCESS(status))
5279 return TPACPI_LED_570;
5280
5281 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
5282 status = acpi_get_handle(ec_handle, "SYSL", &led_handle);
5283 if (ACPI_SUCCESS(status))
5284 return TPACPI_LED_OLD;
5285 }
5286
5287 /* most others */
5288 status = acpi_get_handle(ec_handle, "LED", &led_handle);
5289 if (ACPI_SUCCESS(status))
5290 return TPACPI_LED_NEW;
5291
5292 /* R30, R31, and unknown firmwares */
5293 led_handle = NULL;
5294 return TPACPI_LED_NONE;
5295}
5296
5274static int __init led_init(struct ibm_init_struct *iibm) 5297static int __init led_init(struct ibm_init_struct *iibm)
5275{ 5298{
5276 unsigned int i; 5299 unsigned int i;
@@ -5279,20 +5302,7 @@ static int __init led_init(struct ibm_init_struct *iibm)
5279 5302
5280 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); 5303 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
5281 5304
5282 TPACPI_ACPIHANDLE_INIT(led); 5305 led_supported = led_init_detect_mode();
5283
5284 if (!led_handle)
5285 /* led not supported on R30, R31 */
5286 led_supported = TPACPI_LED_NONE;
5287 else if (strlencmp(led_path, "SLED") == 0)
5288 /* 570 */
5289 led_supported = TPACPI_LED_570;
5290 else if (strlencmp(led_path, "SYSL") == 0)
5291 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
5292 led_supported = TPACPI_LED_OLD;
5293 else
5294 /* all others */
5295 led_supported = TPACPI_LED_NEW;
5296 5306
5297 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", 5307 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
5298 str_supported(led_supported), led_supported); 5308 str_supported(led_supported), led_supported);
@@ -5741,11 +5751,12 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
5741 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8; 5751 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;
5742 } 5752 }
5743 } else if (acpi_tmp7) { 5753 } else if (acpi_tmp7) {
5744 if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { 5754 if (tpacpi_is_ibm() &&
5755 acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
5745 /* 600e/x, 770e, 770x */ 5756 /* 600e/x, 770e, 770x */
5746 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT; 5757 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT;
5747 } else { 5758 } else {
5748 /* Standard ACPI TMPx access, max 8 sensors */ 5759 /* IBM/LENOVO DSDT EC.TMPx access, max 8 sensors */
5749 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; 5760 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
5750 } 5761 }
5751 } else { 5762 } else {
@@ -5954,7 +5965,7 @@ static unsigned int tpacpi_brightness_nvram_get(void)
5954 lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) 5965 lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
5955 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) 5966 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
5956 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; 5967 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
5957 lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07; 5968 lnvram &= bright_maxlvl;
5958 5969
5959 return lnvram; 5970 return lnvram;
5960} 5971}
@@ -6063,8 +6074,7 @@ static int brightness_set(unsigned int value)
6063{ 6074{
6064 int res; 6075 int res;
6065 6076
6066 if (value > ((tp_features.bright_16levels)? 15 : 7) || 6077 if (value > bright_maxlvl || value < 0)
6067 value < 0)
6068 return -EINVAL; 6078 return -EINVAL;
6069 6079
6070 vdbg_printk(TPACPI_DBG_BRGHT, 6080 vdbg_printk(TPACPI_DBG_BRGHT,
@@ -6139,6 +6149,80 @@ static struct backlight_ops ibm_backlight_data = {
6139 6149
6140/* --------------------------------------------------------------------- */ 6150/* --------------------------------------------------------------------- */
6141 6151
6152static int __init tpacpi_query_bcl_levels(acpi_handle handle)
6153{
6154 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
6155 union acpi_object *obj;
6156 int rc;
6157
6158 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
6159 obj = (union acpi_object *)buffer.pointer;
6160 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
6161 printk(TPACPI_ERR "Unknown _BCL data, "
6162 "please report this to %s\n", TPACPI_MAIL);
6163 rc = 0;
6164 } else {
6165 rc = obj->package.count;
6166 }
6167 } else {
6168 return 0;
6169 }
6170
6171 kfree(buffer.pointer);
6172 return rc;
6173}
6174
6175static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
6176 u32 lvl, void *context, void **rv)
6177{
6178 char name[ACPI_PATH_SEGMENT_LENGTH];
6179 struct acpi_buffer buffer = { sizeof(name), &name };
6180
6181 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
6182 !strncmp("_BCL", name, sizeof(name) - 1)) {
6183 BUG_ON(!rv || !*rv);
6184 **(int **)rv = tpacpi_query_bcl_levels(handle);
6185 return AE_CTRL_TERMINATE;
6186 } else {
6187 return AE_OK;
6188 }
6189}
6190
6191/*
6192 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
6193 */
6194static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
6195{
6196 int status;
6197 int bcl_levels = 0;
6198 void *bcl_ptr = &bcl_levels;
6199
6200 if (!vid_handle)
6201 TPACPI_ACPIHANDLE_INIT(vid);
6202
6203 if (!vid_handle)
6204 return 0;
6205
6206 /*
6207 * Search for a _BCL method, and execute it. This is safe on all
6208 * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
6209 * BIOS in ACPI backlight control mode. We do NOT have to care
6210 * about calling the _BCL method in an enabled video device, any
6211 * will do for our purposes.
6212 */
6213
6214 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
6215 tpacpi_acpi_walk_find_bcl, NULL, NULL,
6216 &bcl_ptr);
6217
6218 if (ACPI_SUCCESS(status) && bcl_levels > 2) {
6219 tp_features.bright_acpimode = 1;
6220 return bcl_levels - 2;
6221 }
6222
6223 return 0;
6224}
6225
6142/* 6226/*
6143 * These are only useful for models that have only one possibility 6227 * These are only useful for models that have only one possibility
6144 * of GPU. If the BIOS model handles both ATI and Intel, don't use 6228 * of GPU. If the BIOS model handles both ATI and Intel, don't use
@@ -6169,6 +6253,47 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
6169 TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC), /* X41 Tablet */ 6253 TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC), /* X41 Tablet */
6170}; 6254};
6171 6255
6256/*
6257 * Returns < 0 for error, otherwise sets tp_features.bright_*
6258 * and bright_maxlvl.
6259 */
6260static void __init tpacpi_detect_brightness_capabilities(void)
6261{
6262 unsigned int b;
6263
6264 vdbg_printk(TPACPI_DBG_INIT,
6265 "detecting firmware brightness interface capabilities\n");
6266
6267 /* we could run a quirks check here (same table used by
6268 * brightness_init) if needed */
6269
6270 /*
6271 * We always attempt to detect acpi support, so as to switch
6272 * Lenovo Vista BIOS to ACPI brightness mode even if we are not
6273 * going to publish a backlight interface
6274 */
6275 b = tpacpi_check_std_acpi_brightness_support();
6276 switch (b) {
6277 case 16:
6278 bright_maxlvl = 15;
6279 printk(TPACPI_INFO
6280 "detected a 16-level brightness capable ThinkPad\n");
6281 break;
6282 case 8:
6283 case 0:
6284 bright_maxlvl = 7;
6285 printk(TPACPI_INFO
6286 "detected a 8-level brightness capable ThinkPad\n");
6287 break;
6288 default:
6289 printk(TPACPI_ERR
6290 "Unsupported brightness interface, "
6291 "please contact %s\n", TPACPI_MAIL);
6292 tp_features.bright_unkfw = 1;
6293 bright_maxlvl = b - 1;
6294 }
6295}
6296
6172static int __init brightness_init(struct ibm_init_struct *iibm) 6297static int __init brightness_init(struct ibm_init_struct *iibm)
6173{ 6298{
6174 struct backlight_properties props; 6299 struct backlight_properties props;
@@ -6182,14 +6307,13 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6182 quirks = tpacpi_check_quirks(brightness_quirk_table, 6307 quirks = tpacpi_check_quirks(brightness_quirk_table,
6183 ARRAY_SIZE(brightness_quirk_table)); 6308 ARRAY_SIZE(brightness_quirk_table));
6184 6309
6185 /* 6310 /* tpacpi_detect_brightness_capabilities() must have run already */
6186 * We always attempt to detect acpi support, so as to switch 6311
6187 * Lenovo Vista BIOS to ACPI brightness mode even if we are not 6312 /* if it is unknown, we don't handle it: it wouldn't be safe */
6188 * going to publish a backlight interface 6313 if (tp_features.bright_unkfw)
6189 */ 6314 return 1;
6190 b = tpacpi_check_std_acpi_brightness_support();
6191 if (b > 0) {
6192 6315
6316 if (tp_features.bright_acpimode) {
6193 if (acpi_video_backlight_support()) { 6317 if (acpi_video_backlight_support()) {
6194 if (brightness_enable > 1) { 6318 if (brightness_enable > 1) {
6195 printk(TPACPI_NOTICE 6319 printk(TPACPI_NOTICE
@@ -6218,15 +6342,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6218 return 1; 6342 return 1;
6219 } 6343 }
6220 6344
6221 if (b > 16) {
6222 printk(TPACPI_ERR
6223 "Unsupported brightness interface, "
6224 "please contact %s\n", TPACPI_MAIL);
6225 return 1;
6226 }
6227 if (b == 16)
6228 tp_features.bright_16levels = 1;
6229
6230 /* 6345 /*
6231 * Check for module parameter bogosity, note that we 6346 * Check for module parameter bogosity, note that we
6232 * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be 6347 * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
@@ -6249,7 +6364,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6249 } 6364 }
6250 6365
6251 /* Safety */ 6366 /* Safety */
6252 if (thinkpad_id.vendor != PCI_VENDOR_ID_IBM && 6367 if (!tpacpi_is_ibm() &&
6253 (brightness_mode == TPACPI_BRGHT_MODE_ECNVRAM || 6368 (brightness_mode == TPACPI_BRGHT_MODE_ECNVRAM ||
6254 brightness_mode == TPACPI_BRGHT_MODE_EC)) 6369 brightness_mode == TPACPI_BRGHT_MODE_EC))
6255 return -EINVAL; 6370 return -EINVAL;
@@ -6257,12 +6372,9 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6257 if (tpacpi_brightness_get_raw(&b) < 0) 6372 if (tpacpi_brightness_get_raw(&b) < 0)
6258 return 1; 6373 return 1;
6259 6374
6260 if (tp_features.bright_16levels)
6261 printk(TPACPI_INFO
6262 "detected a 16-level brightness capable ThinkPad\n");
6263
6264 memset(&props, 0, sizeof(struct backlight_properties)); 6375 memset(&props, 0, sizeof(struct backlight_properties));
6265 props.max_brightness = (tp_features.bright_16levels) ? 15 : 7; 6376 props.max_brightness = bright_maxlvl;
6377 props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
6266 ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME, 6378 ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,
6267 NULL, NULL, 6379 NULL, NULL,
6268 &ibm_backlight_data, 6380 &ibm_backlight_data,
@@ -6285,7 +6397,10 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6285 "or not on your ThinkPad\n", TPACPI_MAIL); 6397 "or not on your ThinkPad\n", TPACPI_MAIL);
6286 } 6398 }
6287 6399
6288 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; 6400 /* Added by mistake in early 2007. Probably useless, but it could
6401 * be working around some unknown firmware problem where the value
6402 * read at startup doesn't match the real hardware state... so leave
6403 * it in place just in case */
6289 backlight_update_status(ibm_backlight_device); 6404 backlight_update_status(ibm_backlight_device);
6290 6405
6291 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, 6406 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
@@ -6328,9 +6443,8 @@ static int brightness_read(struct seq_file *m)
6328 } else { 6443 } else {
6329 seq_printf(m, "level:\t\t%d\n", level); 6444 seq_printf(m, "level:\t\t%d\n", level);
6330 seq_printf(m, "commands:\tup, down\n"); 6445 seq_printf(m, "commands:\tup, down\n");
6331 seq_printf(m, "commands:\tlevel <level>" 6446 seq_printf(m, "commands:\tlevel <level> (<level> is 0-%d)\n",
6332 " (<level> is 0-%d)\n", 6447 bright_maxlvl);
6333 (tp_features.bright_16levels) ? 15 : 7);
6334 } 6448 }
6335 6449
6336 return 0; 6450 return 0;
@@ -6341,7 +6455,6 @@ static int brightness_write(char *buf)
6341 int level; 6455 int level;
6342 int rc; 6456 int rc;
6343 char *cmd; 6457 char *cmd;
6344 int max_level = (tp_features.bright_16levels) ? 15 : 7;
6345 6458
6346 level = brightness_get(NULL); 6459 level = brightness_get(NULL);
6347 if (level < 0) 6460 if (level < 0)
@@ -6349,13 +6462,13 @@ static int brightness_write(char *buf)
6349 6462
6350 while ((cmd = next_cmd(&buf))) { 6463 while ((cmd = next_cmd(&buf))) {
6351 if (strlencmp(cmd, "up") == 0) { 6464 if (strlencmp(cmd, "up") == 0) {
6352 if (level < max_level) 6465 if (level < bright_maxlvl)
6353 level++; 6466 level++;
6354 } else if (strlencmp(cmd, "down") == 0) { 6467 } else if (strlencmp(cmd, "down") == 0) {
6355 if (level > 0) 6468 if (level > 0)
6356 level--; 6469 level--;
6357 } else if (sscanf(cmd, "level %d", &level) == 1 && 6470 } else if (sscanf(cmd, "level %d", &level) == 1 &&
6358 level >= 0 && level <= max_level) { 6471 level >= 0 && level <= bright_maxlvl) {
6359 /* new level set */ 6472 /* new level set */
6360 } else 6473 } else
6361 return -EINVAL; 6474 return -EINVAL;
@@ -6669,6 +6782,8 @@ static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
6669static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol, 6782static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
6670 struct snd_ctl_elem_value *ucontrol) 6783 struct snd_ctl_elem_value *ucontrol)
6671{ 6784{
6785 tpacpi_disclose_usertask("ALSA", "set volume to %ld\n",
6786 ucontrol->value.integer.value[0]);
6672 return volume_alsa_set_volume(ucontrol->value.integer.value[0]); 6787 return volume_alsa_set_volume(ucontrol->value.integer.value[0]);
6673} 6788}
6674 6789
@@ -6692,6 +6807,9 @@ static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
6692static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol, 6807static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
6693 struct snd_ctl_elem_value *ucontrol) 6808 struct snd_ctl_elem_value *ucontrol)
6694{ 6809{
6810 tpacpi_disclose_usertask("ALSA", "%smute\n",
6811 ucontrol->value.integer.value[0] ?
6812 "un" : "");
6695 return volume_alsa_set_mute(!ucontrol->value.integer.value[0]); 6813 return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);
6696} 6814}
6697 6815
@@ -7968,9 +8086,11 @@ static int __init fan_init(struct ibm_init_struct *iibm)
7968 tp_features.second_fan = 0; 8086 tp_features.second_fan = 0;
7969 fan_control_desired_level = 7; 8087 fan_control_desired_level = 7;
7970 8088
7971 TPACPI_ACPIHANDLE_INIT(fans); 8089 if (tpacpi_is_ibm()) {
7972 TPACPI_ACPIHANDLE_INIT(gfan); 8090 TPACPI_ACPIHANDLE_INIT(fans);
7973 TPACPI_ACPIHANDLE_INIT(sfan); 8091 TPACPI_ACPIHANDLE_INIT(gfan);
8092 TPACPI_ACPIHANDLE_INIT(sfan);
8093 }
7974 8094
7975 quirks = tpacpi_check_quirks(fan_quirk_table, 8095 quirks = tpacpi_check_quirks(fan_quirk_table,
7976 ARRAY_SIZE(fan_quirk_table)); 8096 ARRAY_SIZE(fan_quirk_table));
@@ -8662,6 +8782,10 @@ static int __init probe_for_thinkpad(void)
8662 if (acpi_disabled) 8782 if (acpi_disabled)
8663 return -ENODEV; 8783 return -ENODEV;
8664 8784
8785 /* It would be dangerous to run the driver in this case */
8786 if (!tpacpi_is_ibm() && !tpacpi_is_lenovo())
8787 return -ENODEV;
8788
8665 /* 8789 /*
8666 * Non-ancient models have better DMI tagging, but very old models 8790 * Non-ancient models have better DMI tagging, but very old models
8667 * don't. tpacpi_is_fw_known() is a cheat to help in that case. 8791 * don't. tpacpi_is_fw_known() is a cheat to help in that case.
@@ -8670,8 +8794,8 @@ static int __init probe_for_thinkpad(void)
8670 (thinkpad_id.ec_model != 0) || 8794 (thinkpad_id.ec_model != 0) ||
8671 tpacpi_is_fw_known(); 8795 tpacpi_is_fw_known();
8672 8796
8673 /* ec is required because many other handles are relative to it */ 8797 /* The EC handler is required */
8674 TPACPI_ACPIHANDLE_INIT(ec); 8798 tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle);
8675 if (!ec_handle) { 8799 if (!ec_handle) {
8676 if (is_thinkpad) 8800 if (is_thinkpad)
8677 printk(TPACPI_ERR 8801 printk(TPACPI_ERR
@@ -8685,12 +8809,34 @@ static int __init probe_for_thinkpad(void)
8685 return 0; 8809 return 0;
8686} 8810}
8687 8811
8812static void __init thinkpad_acpi_init_banner(void)
8813{
8814 printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION);
8815 printk(TPACPI_INFO "%s\n", TPACPI_URL);
8816
8817 printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n",
8818 (thinkpad_id.bios_version_str) ?
8819 thinkpad_id.bios_version_str : "unknown",
8820 (thinkpad_id.ec_version_str) ?
8821 thinkpad_id.ec_version_str : "unknown");
8822
8823 BUG_ON(!thinkpad_id.vendor);
8824
8825 if (thinkpad_id.model_str)
8826 printk(TPACPI_INFO "%s %s, model %s\n",
8827 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
8828 "IBM" : ((thinkpad_id.vendor ==
8829 PCI_VENDOR_ID_LENOVO) ?
8830 "Lenovo" : "Unknown vendor"),
8831 thinkpad_id.model_str,
8832 (thinkpad_id.nummodel_str) ?
8833 thinkpad_id.nummodel_str : "unknown");
8834}
8688 8835
8689/* Module init, exit, parameters */ 8836/* Module init, exit, parameters */
8690 8837
8691static struct ibm_init_struct ibms_init[] __initdata = { 8838static struct ibm_init_struct ibms_init[] __initdata = {
8692 { 8839 {
8693 .init = thinkpad_acpi_driver_init,
8694 .data = &thinkpad_acpi_driver_data, 8840 .data = &thinkpad_acpi_driver_data,
8695 }, 8841 },
8696 { 8842 {
@@ -8960,6 +9106,9 @@ static int __init thinkpad_acpi_module_init(void)
8960 9106
8961 /* Driver initialization */ 9107 /* Driver initialization */
8962 9108
9109 thinkpad_acpi_init_banner();
9110 tpacpi_check_outdated_fw();
9111
8963 TPACPI_ACPIHANDLE_INIT(ecrd); 9112 TPACPI_ACPIHANDLE_INIT(ecrd);
8964 TPACPI_ACPIHANDLE_INIT(ecwr); 9113 TPACPI_ACPIHANDLE_INIT(ecwr);
8965 9114
@@ -9059,13 +9208,16 @@ static int __init thinkpad_acpi_module_init(void)
9059 tpacpi_inputdev->name = "ThinkPad Extra Buttons"; 9208 tpacpi_inputdev->name = "ThinkPad Extra Buttons";
9060 tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0"; 9209 tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
9061 tpacpi_inputdev->id.bustype = BUS_HOST; 9210 tpacpi_inputdev->id.bustype = BUS_HOST;
9062 tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ? 9211 tpacpi_inputdev->id.vendor = thinkpad_id.vendor;
9063 thinkpad_id.vendor :
9064 PCI_VENDOR_ID_IBM;
9065 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; 9212 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
9066 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; 9213 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
9067 tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev; 9214 tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
9068 } 9215 }
9216
9217 /* Init subdriver dependencies */
9218 tpacpi_detect_brightness_capabilities();
9219
9220 /* Init subdrivers */
9069 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 9221 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
9070 ret = ibm_init(&ibms_init[i]); 9222 ret = ibm_init(&ibms_init[i]);
9071 if (ret >= 0 && *ibms_init[i].param) 9223 if (ret >= 0 && *ibms_init[i].param)
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 39ec5b6c2e3a..e4eaa14ed987 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -81,6 +81,16 @@ static struct wmi_block wmi_blocks;
81#define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */ 81#define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */
82#define ACPI_WMI_EVENT 0x8 /* GUID is an event */ 82#define ACPI_WMI_EVENT 0x8 /* GUID is an event */
83 83
84static int debug_event;
85module_param(debug_event, bool, 0444);
86MODULE_PARM_DESC(debug_event,
87 "Log WMI Events [0/1]");
88
89static int debug_dump_wdg;
90module_param(debug_dump_wdg, bool, 0444);
91MODULE_PARM_DESC(debug_dump_wdg,
92 "Dump available WMI interfaces [0/1]");
93
84static int acpi_wmi_remove(struct acpi_device *device, int type); 94static int acpi_wmi_remove(struct acpi_device *device, int type);
85static int acpi_wmi_add(struct acpi_device *device); 95static int acpi_wmi_add(struct acpi_device *device);
86static void acpi_wmi_notify(struct acpi_device *device, u32 event); 96static void acpi_wmi_notify(struct acpi_device *device, u32 event);
@@ -477,6 +487,64 @@ const struct acpi_buffer *in)
477} 487}
478EXPORT_SYMBOL_GPL(wmi_set_block); 488EXPORT_SYMBOL_GPL(wmi_set_block);
479 489
490static void wmi_dump_wdg(struct guid_block *g)
491{
492 char guid_string[37];
493
494 wmi_gtoa(g->guid, guid_string);
495 printk(KERN_INFO PREFIX "%s:\n", guid_string);
496 printk(KERN_INFO PREFIX "\tobject_id: %c%c\n",
497 g->object_id[0], g->object_id[1]);
498 printk(KERN_INFO PREFIX "\tnotify_id: %02X\n", g->notify_id);
499 printk(KERN_INFO PREFIX "\treserved: %02X\n", g->reserved);
500 printk(KERN_INFO PREFIX "\tinstance_count: %d\n", g->instance_count);
501 printk(KERN_INFO PREFIX "\tflags: %#x", g->flags);
502 if (g->flags) {
503 printk(" ");
504 if (g->flags & ACPI_WMI_EXPENSIVE)
505 printk("ACPI_WMI_EXPENSIVE ");
506 if (g->flags & ACPI_WMI_METHOD)
507 printk("ACPI_WMI_METHOD ");
508 if (g->flags & ACPI_WMI_STRING)
509 printk("ACPI_WMI_STRING ");
510 if (g->flags & ACPI_WMI_EVENT)
511 printk("ACPI_WMI_EVENT ");
512 }
513 printk("\n");
514
515}
516
517static void wmi_notify_debug(u32 value, void *context)
518{
519 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
520 union acpi_object *obj;
521
522 wmi_get_event_data(value, &response);
523
524 obj = (union acpi_object *)response.pointer;
525
526 if (!obj)
527 return;
528
529 printk(KERN_INFO PREFIX "DEBUG Event ");
530 switch(obj->type) {
531 case ACPI_TYPE_BUFFER:
532 printk("BUFFER_TYPE - length %d\n", obj->buffer.length);
533 break;
534 case ACPI_TYPE_STRING:
535 printk("STRING_TYPE - %s\n", obj->string.pointer);
536 break;
537 case ACPI_TYPE_INTEGER:
538 printk("INTEGER_TYPE - %llu\n", obj->integer.value);
539 break;
540 case ACPI_TYPE_PACKAGE:
541 printk("PACKAGE_TYPE - %d elements\n", obj->package.count);
542 break;
543 default:
544 printk("object type 0x%X\n", obj->type);
545 }
546}
547
480/** 548/**
481 * wmi_install_notify_handler - Register handler for WMI events 549 * wmi_install_notify_handler - Register handler for WMI events
482 * @handler: Function to handle notifications 550 * @handler: Function to handle notifications
@@ -496,7 +564,7 @@ wmi_notify_handler handler, void *data)
496 if (!find_guid(guid, &block)) 564 if (!find_guid(guid, &block))
497 return AE_NOT_EXIST; 565 return AE_NOT_EXIST;
498 566
499 if (block->handler) 567 if (block->handler && block->handler != wmi_notify_debug)
500 return AE_ALREADY_ACQUIRED; 568 return AE_ALREADY_ACQUIRED;
501 569
502 block->handler = handler; 570 block->handler = handler;
@@ -516,7 +584,7 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler);
516acpi_status wmi_remove_notify_handler(const char *guid) 584acpi_status wmi_remove_notify_handler(const char *guid)
517{ 585{
518 struct wmi_block *block; 586 struct wmi_block *block;
519 acpi_status status; 587 acpi_status status = AE_OK;
520 588
521 if (!guid) 589 if (!guid)
522 return AE_BAD_PARAMETER; 590 return AE_BAD_PARAMETER;
@@ -524,14 +592,16 @@ acpi_status wmi_remove_notify_handler(const char *guid)
524 if (!find_guid(guid, &block)) 592 if (!find_guid(guid, &block))
525 return AE_NOT_EXIST; 593 return AE_NOT_EXIST;
526 594
527 if (!block->handler) 595 if (!block->handler || block->handler == wmi_notify_debug)
528 return AE_NULL_ENTRY; 596 return AE_NULL_ENTRY;
529 597
530 status = wmi_method_enable(block, 0); 598 if (debug_event) {
531 599 block->handler = wmi_notify_debug;
532 block->handler = NULL; 600 } else {
533 block->handler_data = NULL; 601 status = wmi_method_enable(block, 0);
534 602 block->handler = NULL;
603 block->handler_data = NULL;
604 }
535 return status; 605 return status;
536} 606}
537EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); 607EXPORT_SYMBOL_GPL(wmi_remove_notify_handler);
@@ -756,12 +826,10 @@ static __init acpi_status parse_wdg(acpi_handle handle)
756 826
757 total = obj->buffer.length / sizeof(struct guid_block); 827 total = obj->buffer.length / sizeof(struct guid_block);
758 828
759 gblock = kzalloc(obj->buffer.length, GFP_KERNEL); 829 gblock = kmemdup(obj->buffer.pointer, obj->buffer.length, GFP_KERNEL);
760 if (!gblock) 830 if (!gblock)
761 return AE_NO_MEMORY; 831 return AE_NO_MEMORY;
762 832
763 memcpy(gblock, obj->buffer.pointer, obj->buffer.length);
764
765 for (i = 0; i < total; i++) { 833 for (i = 0; i < total; i++) {
766 /* 834 /*
767 Some WMI devices, like those for nVidia hooks, have a 835 Some WMI devices, like those for nVidia hooks, have a
@@ -776,12 +844,19 @@ static __init acpi_status parse_wdg(acpi_handle handle)
776 guid_string); 844 guid_string);
777 continue; 845 continue;
778 } 846 }
847 if (debug_dump_wdg)
848 wmi_dump_wdg(&gblock[i]);
849
779 wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); 850 wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
780 if (!wblock) 851 if (!wblock)
781 return AE_NO_MEMORY; 852 return AE_NO_MEMORY;
782 853
783 wblock->gblock = gblock[i]; 854 wblock->gblock = gblock[i];
784 wblock->handle = handle; 855 wblock->handle = handle;
856 if (debug_event) {
857 wblock->handler = wmi_notify_debug;
858 status = wmi_method_enable(wblock, 1);
859 }
785 list_add_tail(&wblock->list, &wmi_blocks.list); 860 list_add_tail(&wblock->list, &wmi_blocks.list);
786 } 861 }
787 862
@@ -840,6 +915,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
840 struct guid_block *block; 915 struct guid_block *block;
841 struct wmi_block *wblock; 916 struct wmi_block *wblock;
842 struct list_head *p; 917 struct list_head *p;
918 char guid_string[37];
843 919
844 list_for_each(p, &wmi_blocks.list) { 920 list_for_each(p, &wmi_blocks.list) {
845 wblock = list_entry(p, struct wmi_block, list); 921 wblock = list_entry(p, struct wmi_block, list);
@@ -849,6 +925,11 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
849 (block->notify_id == event)) { 925 (block->notify_id == event)) {
850 if (wblock->handler) 926 if (wblock->handler)
851 wblock->handler(event, wblock->handler_data); 927 wblock->handler(event, wblock->handler_data);
928 if (debug_event) {
929 wmi_gtoa(wblock->gblock.guid, guid_string);
930 printk(KERN_INFO PREFIX "DEBUG Event GUID:"
931 " %s\n", guid_string);
932 }
852 933
853 acpi_bus_generate_netlink_event( 934 acpi_bus_generate_netlink_event(
854 device->pnp.device_class, dev_name(&device->dev), 935 device->pnp.device_class, dev_name(&device->dev),