aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig26
-rw-r--r--drivers/platform/x86/acer-wmi.c2
-rw-r--r--drivers/platform/x86/eeepc-laptop.c355
-rw-r--r--drivers/platform/x86/hp-wmi.c14
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c390
5 files changed, 301 insertions, 486 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 7232fe7104aa..77c6097ced80 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -277,31 +277,6 @@ config THINKPAD_ACPI_UNSAFE_LEDS
277 Say N here, unless you are building a kernel for your own 277 Say N here, unless you are building a kernel for your own
278 use, and need to control the important firmware LEDs. 278 use, and need to control the important firmware LEDs.
279 279
280config THINKPAD_ACPI_DOCK
281 bool "Legacy Docking Station Support"
282 depends on THINKPAD_ACPI
283 depends on ACPI_DOCK=n
284 default n
285 ---help---
286 Allows the thinkpad_acpi driver to handle docking station events.
287 This support was made obsolete by the generic ACPI docking station
288 support (CONFIG_ACPI_DOCK). It will allow locking and removing the
289 laptop from the docking station, but will not properly connect PCI
290 devices.
291
292 If you are not sure, say N here.
293
294config THINKPAD_ACPI_BAY
295 bool "Legacy Removable Bay Support"
296 depends on THINKPAD_ACPI
297 default y
298 ---help---
299 Allows the thinkpad_acpi driver to handle removable bays. It will
300 electrically disable the device in the bay, and also generate
301 notifications when the bay lever is ejected or inserted.
302
303 If you are not sure, say Y here.
304
305config THINKPAD_ACPI_VIDEO 280config THINKPAD_ACPI_VIDEO
306 bool "Video output control support" 281 bool "Video output control support"
307 depends on THINKPAD_ACPI 282 depends on THINKPAD_ACPI
@@ -355,6 +330,7 @@ config EEEPC_LAPTOP
355 depends on INPUT 330 depends on INPUT
356 depends on EXPERIMENTAL 331 depends on EXPERIMENTAL
357 depends on RFKILL || RFKILL = n 332 depends on RFKILL || RFKILL = n
333 depends on HOTPLUG_PCI
358 select BACKLIGHT_CLASS_DEVICE 334 select BACKLIGHT_CLASS_DEVICE
359 select HWMON 335 select HWMON
360 ---help--- 336 ---help---
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index be2fd6f91639..fb45f5ee8df1 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -973,7 +973,7 @@ static int acer_rfkill_set(void *data, bool blocked)
973{ 973{
974 acpi_status status; 974 acpi_status status;
975 u32 cap = (unsigned long)data; 975 u32 cap = (unsigned long)data;
976 status = set_u32(!!blocked, cap); 976 status = set_u32(!blocked, cap);
977 if (ACPI_FAILURE(status)) 977 if (ACPI_FAILURE(status))
978 return -ENODEV; 978 return -ENODEV;
979 return 0; 979 return 0;
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 4207b26ff990..222ffb892f22 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -16,6 +16,8 @@
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 */ 17 */
18 18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
19#include <linux/kernel.h> 21#include <linux/kernel.h>
20#include <linux/module.h> 22#include <linux/module.h>
21#include <linux/init.h> 23#include <linux/init.h>
@@ -31,6 +33,7 @@
31#include <linux/input.h> 33#include <linux/input.h>
32#include <linux/rfkill.h> 34#include <linux/rfkill.h>
33#include <linux/pci.h> 35#include <linux/pci.h>
36#include <linux/pci_hotplug.h>
34 37
35#define EEEPC_LAPTOP_VERSION "0.1" 38#define EEEPC_LAPTOP_VERSION "0.1"
36 39
@@ -40,11 +43,6 @@
40#define EEEPC_HOTK_DEVICE_NAME "Hotkey" 43#define EEEPC_HOTK_DEVICE_NAME "Hotkey"
41#define EEEPC_HOTK_HID "ASUS010" 44#define EEEPC_HOTK_HID "ASUS010"
42 45
43#define EEEPC_LOG EEEPC_HOTK_FILE ": "
44#define EEEPC_ERR KERN_ERR EEEPC_LOG
45#define EEEPC_WARNING KERN_WARNING EEEPC_LOG
46#define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG
47#define EEEPC_INFO KERN_INFO EEEPC_LOG
48 46
49/* 47/*
50 * Definitions for Asus EeePC 48 * Definitions for Asus EeePC
@@ -141,8 +139,11 @@ struct eeepc_hotk {
141 u16 event_count[128]; /* count for each event */ 139 u16 event_count[128]; /* count for each event */
142 struct input_dev *inputdev; 140 struct input_dev *inputdev;
143 u16 *keycode_map; 141 u16 *keycode_map;
144 struct rfkill *eeepc_wlan_rfkill; 142 struct rfkill *wlan_rfkill;
145 struct rfkill *eeepc_bluetooth_rfkill; 143 struct rfkill *bluetooth_rfkill;
144 struct rfkill *wwan3g_rfkill;
145 struct hotplug_slot *hotplug_slot;
146 struct work_struct hotplug_work;
146}; 147};
147 148
148/* The actual device the driver binds to */ 149/* The actual device the driver binds to */
@@ -213,6 +214,15 @@ static struct acpi_driver eeepc_hotk_driver = {
213 }, 214 },
214}; 215};
215 216
217/* PCI hotplug ops */
218static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
219
220static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
221 .owner = THIS_MODULE,
222 .get_adapter_status = eeepc_get_adapter_status,
223 .get_power_status = eeepc_get_adapter_status,
224};
225
216/* The backlight device /sys/class/backlight */ 226/* The backlight device /sys/class/backlight */
217static struct backlight_device *eeepc_backlight_device; 227static struct backlight_device *eeepc_backlight_device;
218 228
@@ -274,20 +284,20 @@ static int set_acpi(int cm, int value)
274 if (method == NULL) 284 if (method == NULL)
275 return -ENODEV; 285 return -ENODEV;
276 if (write_acpi_int(ehotk->handle, method, value, NULL)) 286 if (write_acpi_int(ehotk->handle, method, value, NULL))
277 printk(EEEPC_WARNING "Error writing %s\n", method); 287 pr_warning("Error writing %s\n", method);
278 } 288 }
279 return 0; 289 return 0;
280} 290}
281 291
282static int get_acpi(int cm) 292static int get_acpi(int cm)
283{ 293{
284 int value = -1; 294 int value = -ENODEV;
285 if ((ehotk->cm_supported & (0x1 << cm))) { 295 if ((ehotk->cm_supported & (0x1 << cm))) {
286 const char *method = cm_getv[cm]; 296 const char *method = cm_getv[cm];
287 if (method == NULL) 297 if (method == NULL)
288 return -ENODEV; 298 return -ENODEV;
289 if (read_acpi_int(ehotk->handle, method, &value)) 299 if (read_acpi_int(ehotk->handle, method, &value))
290 printk(EEEPC_WARNING "Error reading %s\n", method); 300 pr_warning("Error reading %s\n", method);
291 } 301 }
292 return value; 302 return value;
293} 303}
@@ -359,13 +369,19 @@ static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
359 369
360 rv = parse_arg(buf, count, &value); 370 rv = parse_arg(buf, count, &value);
361 if (rv > 0) 371 if (rv > 0)
362 set_acpi(cm, value); 372 value = set_acpi(cm, value);
373 if (value < 0)
374 return value;
363 return rv; 375 return rv;
364} 376}
365 377
366static ssize_t show_sys_acpi(int cm, char *buf) 378static ssize_t show_sys_acpi(int cm, char *buf)
367{ 379{
368 return sprintf(buf, "%d\n", get_acpi(cm)); 380 int value = get_acpi(cm);
381
382 if (value < 0)
383 return value;
384 return sprintf(buf, "%d\n", value);
369} 385}
370 386
371#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ 387#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
@@ -539,6 +555,28 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
539 return -EINVAL; 555 return -EINVAL;
540} 556}
541 557
558static void cmsg_quirk(int cm, const char *name)
559{
560 int dummy;
561
562 /* Some BIOSes do not report cm although it is avaliable.
563 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
564 if (!(ehotk->cm_supported & (1 << cm))
565 && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) {
566 pr_info("%s (%x) not reported by BIOS,"
567 " enabling anyway\n", name, 1 << cm);
568 ehotk->cm_supported |= 1 << cm;
569 }
570}
571
572static void cmsg_quirks(void)
573{
574 cmsg_quirk(CM_ASL_LID, "LID");
575 cmsg_quirk(CM_ASL_TYPE, "TYPE");
576 cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER");
577 cmsg_quirk(CM_ASL_TPD, "TPD");
578}
579
542static int eeepc_hotk_check(void) 580static int eeepc_hotk_check(void)
543{ 581{
544 const struct key_entry *key; 582 const struct key_entry *key;
@@ -551,26 +589,24 @@ static int eeepc_hotk_check(void)
551 if (ehotk->device->status.present) { 589 if (ehotk->device->status.present) {
552 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, 590 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
553 &buffer)) { 591 &buffer)) {
554 printk(EEEPC_ERR "Hotkey initialization failed\n"); 592 pr_err("Hotkey initialization failed\n");
555 return -ENODEV; 593 return -ENODEV;
556 } else { 594 } else {
557 printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", 595 pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
558 ehotk->init_flag);
559 } 596 }
560 /* get control methods supported */ 597 /* get control methods supported */
561 if (read_acpi_int(ehotk->handle, "CMSG" 598 if (read_acpi_int(ehotk->handle, "CMSG"
562 , &ehotk->cm_supported)) { 599 , &ehotk->cm_supported)) {
563 printk(EEEPC_ERR 600 pr_err("Get control methods supported failed\n");
564 "Get control methods supported failed\n");
565 return -ENODEV; 601 return -ENODEV;
566 } else { 602 } else {
567 printk(EEEPC_INFO 603 cmsg_quirks();
568 "Get control methods supported: 0x%x\n", 604 pr_info("Get control methods supported: 0x%x\n",
569 ehotk->cm_supported); 605 ehotk->cm_supported);
570 } 606 }
571 ehotk->inputdev = input_allocate_device(); 607 ehotk->inputdev = input_allocate_device();
572 if (!ehotk->inputdev) { 608 if (!ehotk->inputdev) {
573 printk(EEEPC_INFO "Unable to allocate input device\n"); 609 pr_info("Unable to allocate input device\n");
574 return 0; 610 return 0;
575 } 611 }
576 ehotk->inputdev->name = "Asus EeePC extra buttons"; 612 ehotk->inputdev->name = "Asus EeePC extra buttons";
@@ -589,12 +625,12 @@ static int eeepc_hotk_check(void)
589 } 625 }
590 result = input_register_device(ehotk->inputdev); 626 result = input_register_device(ehotk->inputdev);
591 if (result) { 627 if (result) {
592 printk(EEEPC_INFO "Unable to register input device\n"); 628 pr_info("Unable to register input device\n");
593 input_free_device(ehotk->inputdev); 629 input_free_device(ehotk->inputdev);
594 return 0; 630 return 0;
595 } 631 }
596 } else { 632 } else {
597 printk(EEEPC_ERR "Hotkey device not present, aborting\n"); 633 pr_err("Hotkey device not present, aborting\n");
598 return -EINVAL; 634 return -EINVAL;
599 } 635 }
600 return 0; 636 return 0;
@@ -612,14 +648,27 @@ static int notify_brn(void)
612 return -1; 648 return -1;
613} 649}
614 650
615static void eeepc_rfkill_hotplug(void) 651static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
652 u8 *value)
653{
654 int val = get_acpi(CM_ASL_WLAN);
655
656 if (val == 1 || val == 0)
657 *value = val;
658 else
659 return -EINVAL;
660
661 return 0;
662}
663
664static void eeepc_hotplug_work(struct work_struct *work)
616{ 665{
617 struct pci_dev *dev; 666 struct pci_dev *dev;
618 struct pci_bus *bus = pci_find_bus(0, 1); 667 struct pci_bus *bus = pci_find_bus(0, 1);
619 bool blocked; 668 bool blocked;
620 669
621 if (!bus) { 670 if (!bus) {
622 printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); 671 pr_warning("Unable to find PCI bus 1?\n");
623 return; 672 return;
624 } 673 }
625 674
@@ -635,7 +684,7 @@ static void eeepc_rfkill_hotplug(void)
635 if (dev) { 684 if (dev) {
636 pci_bus_assign_resources(bus); 685 pci_bus_assign_resources(bus);
637 if (pci_bus_add_device(dev)) 686 if (pci_bus_add_device(dev))
638 printk(EEEPC_ERR "Unable to hotplug wifi\n"); 687 pr_err("Unable to hotplug wifi\n");
639 } 688 }
640 } else { 689 } else {
641 dev = pci_get_slot(bus, 0); 690 dev = pci_get_slot(bus, 0);
@@ -645,7 +694,7 @@ static void eeepc_rfkill_hotplug(void)
645 } 694 }
646 } 695 }
647 696
648 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); 697 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
649} 698}
650 699
651static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) 700static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
@@ -653,7 +702,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
653 if (event != ACPI_NOTIFY_BUS_CHECK) 702 if (event != ACPI_NOTIFY_BUS_CHECK)
654 return; 703 return;
655 704
656 eeepc_rfkill_hotplug(); 705 schedule_work(&ehotk->hotplug_work);
657} 706}
658 707
659static void eeepc_hotk_notify(struct acpi_device *device, u32 event) 708static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
@@ -718,8 +767,7 @@ static int eeepc_register_rfkill_notifier(char *node)
718 eeepc_rfkill_notify, 767 eeepc_rfkill_notify,
719 NULL); 768 NULL);
720 if (ACPI_FAILURE(status)) 769 if (ACPI_FAILURE(status))
721 printk(EEEPC_WARNING 770 pr_warning("Failed to register notify on %s\n", node);
722 "Failed to register notify on %s\n", node);
723 } else 771 } else
724 return -ENODEV; 772 return -ENODEV;
725 773
@@ -738,19 +786,66 @@ static void eeepc_unregister_rfkill_notifier(char *node)
738 ACPI_SYSTEM_NOTIFY, 786 ACPI_SYSTEM_NOTIFY,
739 eeepc_rfkill_notify); 787 eeepc_rfkill_notify);
740 if (ACPI_FAILURE(status)) 788 if (ACPI_FAILURE(status))
741 printk(EEEPC_ERR 789 pr_err("Error removing rfkill notify handler %s\n",
742 "Error removing rfkill notify handler %s\n",
743 node); 790 node);
744 } 791 }
745} 792}
746 793
794static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
795{
796 kfree(hotplug_slot->info);
797 kfree(hotplug_slot);
798}
799
800static int eeepc_setup_pci_hotplug(void)
801{
802 int ret = -ENOMEM;
803 struct pci_bus *bus = pci_find_bus(0, 1);
804
805 if (!bus) {
806 pr_err("Unable to find wifi PCI bus\n");
807 return -ENODEV;
808 }
809
810 ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
811 if (!ehotk->hotplug_slot)
812 goto error_slot;
813
814 ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
815 GFP_KERNEL);
816 if (!ehotk->hotplug_slot->info)
817 goto error_info;
818
819 ehotk->hotplug_slot->private = ehotk;
820 ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
821 ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
822 eeepc_get_adapter_status(ehotk->hotplug_slot,
823 &ehotk->hotplug_slot->info->adapter_status);
824
825 ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
826 if (ret) {
827 pr_err("Unable to register hotplug slot - %d\n", ret);
828 goto error_register;
829 }
830
831 return 0;
832
833error_register:
834 kfree(ehotk->hotplug_slot->info);
835error_info:
836 kfree(ehotk->hotplug_slot);
837 ehotk->hotplug_slot = NULL;
838error_slot:
839 return ret;
840}
841
747static int eeepc_hotk_add(struct acpi_device *device) 842static int eeepc_hotk_add(struct acpi_device *device)
748{ 843{
749 int result; 844 int result;
750 845
751 if (!device) 846 if (!device)
752 return -EINVAL; 847 return -EINVAL;
753 printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); 848 pr_notice(EEEPC_HOTK_NAME "\n");
754 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); 849 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
755 if (!ehotk) 850 if (!ehotk)
756 return -ENOMEM; 851 return -ENOMEM;
@@ -764,53 +859,8 @@ static int eeepc_hotk_add(struct acpi_device *device)
764 if (result) 859 if (result)
765 goto ehotk_fail; 860 goto ehotk_fail;
766 861
767 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
768 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
769
770 if (get_acpi(CM_ASL_WLAN) != -1) {
771 ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
772 &device->dev,
773 RFKILL_TYPE_WLAN,
774 &eeepc_rfkill_ops,
775 (void *)CM_ASL_WLAN);
776
777 if (!ehotk->eeepc_wlan_rfkill)
778 goto wlan_fail;
779
780 rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill,
781 get_acpi(CM_ASL_WLAN) != 1);
782 result = rfkill_register(ehotk->eeepc_wlan_rfkill);
783 if (result)
784 goto wlan_fail;
785 }
786
787 if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
788 ehotk->eeepc_bluetooth_rfkill =
789 rfkill_alloc("eeepc-bluetooth",
790 &device->dev,
791 RFKILL_TYPE_BLUETOOTH,
792 &eeepc_rfkill_ops,
793 (void *)CM_ASL_BLUETOOTH);
794
795 if (!ehotk->eeepc_bluetooth_rfkill)
796 goto bluetooth_fail;
797
798 rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill,
799 get_acpi(CM_ASL_BLUETOOTH) != 1);
800 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
801 if (result)
802 goto bluetooth_fail;
803 }
804
805 return 0; 862 return 0;
806 863
807 bluetooth_fail:
808 rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
809 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
810 wlan_fail:
811 rfkill_destroy(ehotk->eeepc_wlan_rfkill);
812 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
813 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
814 ehotk_fail: 864 ehotk_fail:
815 kfree(ehotk); 865 kfree(ehotk);
816 ehotk = NULL; 866 ehotk = NULL;
@@ -823,16 +873,13 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
823 if (!device || !acpi_driver_data(device)) 873 if (!device || !acpi_driver_data(device))
824 return -EINVAL; 874 return -EINVAL;
825 875
826 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
827 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
828
829 kfree(ehotk); 876 kfree(ehotk);
830 return 0; 877 return 0;
831} 878}
832 879
833static int eeepc_hotk_resume(struct acpi_device *device) 880static int eeepc_hotk_resume(struct acpi_device *device)
834{ 881{
835 if (ehotk->eeepc_wlan_rfkill) { 882 if (ehotk->wlan_rfkill) {
836 bool wlan; 883 bool wlan;
837 884
838 /* Workaround - it seems that _PTS disables the wireless 885 /* Workaround - it seems that _PTS disables the wireless
@@ -844,14 +891,13 @@ static int eeepc_hotk_resume(struct acpi_device *device)
844 wlan = get_acpi(CM_ASL_WLAN); 891 wlan = get_acpi(CM_ASL_WLAN);
845 set_acpi(CM_ASL_WLAN, wlan); 892 set_acpi(CM_ASL_WLAN, wlan);
846 893
847 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, 894 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
848 wlan != 1);
849 895
850 eeepc_rfkill_hotplug(); 896 schedule_work(&ehotk->hotplug_work);
851 } 897 }
852 898
853 if (ehotk->eeepc_bluetooth_rfkill) 899 if (ehotk->bluetooth_rfkill)
854 rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, 900 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
855 get_acpi(CM_ASL_BLUETOOTH) != 1); 901 get_acpi(CM_ASL_BLUETOOTH) != 1);
856 902
857 return 0; 903 return 0;
@@ -973,10 +1019,16 @@ static void eeepc_backlight_exit(void)
973 1019
974static void eeepc_rfkill_exit(void) 1020static void eeepc_rfkill_exit(void)
975{ 1021{
976 if (ehotk->eeepc_wlan_rfkill) 1022 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
977 rfkill_unregister(ehotk->eeepc_wlan_rfkill); 1023 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
978 if (ehotk->eeepc_bluetooth_rfkill) 1024 if (ehotk->wlan_rfkill)
979 rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); 1025 rfkill_unregister(ehotk->wlan_rfkill);
1026 if (ehotk->bluetooth_rfkill)
1027 rfkill_unregister(ehotk->bluetooth_rfkill);
1028 if (ehotk->wwan3g_rfkill)
1029 rfkill_unregister(ehotk->wwan3g_rfkill);
1030 if (ehotk->hotplug_slot)
1031 pci_hp_deregister(ehotk->hotplug_slot);
980} 1032}
981 1033
982static void eeepc_input_exit(void) 1034static void eeepc_input_exit(void)
@@ -1011,6 +1063,77 @@ static void __exit eeepc_laptop_exit(void)
1011 platform_driver_unregister(&platform_driver); 1063 platform_driver_unregister(&platform_driver);
1012} 1064}
1013 1065
1066static int eeepc_new_rfkill(struct rfkill **rfkill,
1067 const char *name, struct device *dev,
1068 enum rfkill_type type, int cm)
1069{
1070 int result;
1071
1072 result = get_acpi(cm);
1073 if (result < 0)
1074 return result;
1075
1076 *rfkill = rfkill_alloc(name, dev, type,
1077 &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1078
1079 if (!*rfkill)
1080 return -EINVAL;
1081
1082 rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1083 result = rfkill_register(*rfkill);
1084 if (result) {
1085 rfkill_destroy(*rfkill);
1086 *rfkill = NULL;
1087 return result;
1088 }
1089 return 0;
1090}
1091
1092
1093static int eeepc_rfkill_init(struct device *dev)
1094{
1095 int result = 0;
1096
1097 INIT_WORK(&ehotk->hotplug_work, eeepc_hotplug_work);
1098
1099 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1100 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1101
1102 result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1103 "eeepc-wlan", dev,
1104 RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1105
1106 if (result && result != -ENODEV)
1107 goto exit;
1108
1109 result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1110 "eeepc-bluetooth", dev,
1111 RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1112
1113 if (result && result != -ENODEV)
1114 goto exit;
1115
1116 result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill,
1117 "eeepc-wwan3g", dev,
1118 RFKILL_TYPE_WWAN, CM_ASL_3G);
1119
1120 if (result && result != -ENODEV)
1121 goto exit;
1122
1123 result = eeepc_setup_pci_hotplug();
1124 /*
1125 * If we get -EBUSY then something else is handling the PCI hotplug -
1126 * don't fail in this case
1127 */
1128 if (result == -EBUSY)
1129 result = 0;
1130
1131exit:
1132 if (result && result != -ENODEV)
1133 eeepc_rfkill_exit();
1134 return result;
1135}
1136
1014static int eeepc_backlight_init(struct device *dev) 1137static int eeepc_backlight_init(struct device *dev)
1015{ 1138{
1016 struct backlight_device *bd; 1139 struct backlight_device *bd;
@@ -1018,8 +1141,7 @@ static int eeepc_backlight_init(struct device *dev)
1018 bd = backlight_device_register(EEEPC_HOTK_FILE, dev, 1141 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1019 NULL, &eeepcbl_ops); 1142 NULL, &eeepcbl_ops);
1020 if (IS_ERR(bd)) { 1143 if (IS_ERR(bd)) {
1021 printk(EEEPC_ERR 1144 pr_err("Could not register eeepc backlight device\n");
1022 "Could not register eeepc backlight device\n");
1023 eeepc_backlight_device = NULL; 1145 eeepc_backlight_device = NULL;
1024 return PTR_ERR(bd); 1146 return PTR_ERR(bd);
1025 } 1147 }
@@ -1038,8 +1160,7 @@ static int eeepc_hwmon_init(struct device *dev)
1038 1160
1039 hwmon = hwmon_device_register(dev); 1161 hwmon = hwmon_device_register(dev);
1040 if (IS_ERR(hwmon)) { 1162 if (IS_ERR(hwmon)) {
1041 printk(EEEPC_ERR 1163 pr_err("Could not register eeepc hwmon device\n");
1042 "Could not register eeepc hwmon device\n");
1043 eeepc_hwmon_device = NULL; 1164 eeepc_hwmon_device = NULL;
1044 return PTR_ERR(hwmon); 1165 return PTR_ERR(hwmon);
1045 } 1166 }
@@ -1065,19 +1186,6 @@ static int __init eeepc_laptop_init(void)
1065 acpi_bus_unregister_driver(&eeepc_hotk_driver); 1186 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1066 return -ENODEV; 1187 return -ENODEV;
1067 } 1188 }
1068 dev = acpi_get_physical_device(ehotk->device->handle);
1069
1070 if (!acpi_video_backlight_support()) {
1071 result = eeepc_backlight_init(dev);
1072 if (result)
1073 goto fail_backlight;
1074 } else
1075 printk(EEEPC_INFO "Backlight controlled by ACPI video "
1076 "driver\n");
1077
1078 result = eeepc_hwmon_init(dev);
1079 if (result)
1080 goto fail_hwmon;
1081 1189
1082 eeepc_enable_camera(); 1190 eeepc_enable_camera();
1083 1191
@@ -1097,7 +1205,33 @@ static int __init eeepc_laptop_init(void)
1097 &platform_attribute_group); 1205 &platform_attribute_group);
1098 if (result) 1206 if (result)
1099 goto fail_sysfs; 1207 goto fail_sysfs;
1208
1209 dev = &platform_device->dev;
1210
1211 if (!acpi_video_backlight_support()) {
1212 result = eeepc_backlight_init(dev);
1213 if (result)
1214 goto fail_backlight;
1215 } else
1216 pr_info("Backlight controlled by ACPI video "
1217 "driver\n");
1218
1219 result = eeepc_hwmon_init(dev);
1220 if (result)
1221 goto fail_hwmon;
1222
1223 result = eeepc_rfkill_init(dev);
1224 if (result)
1225 goto fail_rfkill;
1226
1100 return 0; 1227 return 0;
1228fail_rfkill:
1229 eeepc_hwmon_exit();
1230fail_hwmon:
1231 eeepc_backlight_exit();
1232fail_backlight:
1233 sysfs_remove_group(&platform_device->dev.kobj,
1234 &platform_attribute_group);
1101fail_sysfs: 1235fail_sysfs:
1102 platform_device_del(platform_device); 1236 platform_device_del(platform_device);
1103fail_platform_device2: 1237fail_platform_device2:
@@ -1105,12 +1239,7 @@ fail_platform_device2:
1105fail_platform_device1: 1239fail_platform_device1:
1106 platform_driver_unregister(&platform_driver); 1240 platform_driver_unregister(&platform_driver);
1107fail_platform_driver: 1241fail_platform_driver:
1108 eeepc_hwmon_exit();
1109fail_hwmon:
1110 eeepc_backlight_exit();
1111fail_backlight:
1112 eeepc_input_exit(); 1242 eeepc_input_exit();
1113 eeepc_rfkill_exit();
1114 return result; 1243 return result;
1115} 1244}
1116 1245
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 4ac2311c00af..a2ad53e15874 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -171,7 +171,7 @@ static int hp_wmi_tablet_state(void)
171static int hp_wmi_set_block(void *data, bool blocked) 171static int hp_wmi_set_block(void *data, bool blocked)
172{ 172{
173 unsigned long b = (unsigned long) data; 173 unsigned long b = (unsigned long) data;
174 int query = BIT(b + 8) | ((!!blocked) << b); 174 int query = BIT(b + 8) | ((!blocked) << b);
175 175
176 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query); 176 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query);
177} 177}
@@ -520,11 +520,13 @@ static int hp_wmi_resume_handler(struct platform_device *device)
520 * the input layer will only actually pass it on if the state 520 * the input layer will only actually pass it on if the state
521 * changed. 521 * changed.
522 */ 522 */
523 523 if (hp_wmi_input_dev) {
524 input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state()); 524 input_report_switch(hp_wmi_input_dev, SW_DOCK,
525 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, 525 hp_wmi_dock_state());
526 hp_wmi_tablet_state()); 526 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
527 input_sync(hp_wmi_input_dev); 527 hp_wmi_tablet_state());
528 input_sync(hp_wmi_input_dev);
529 }
528 530
529 return 0; 531 return 0;
530} 532}
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index a463fd72c495..e85600852502 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -239,12 +239,6 @@ struct ibm_init_struct {
239}; 239};
240 240
241static struct { 241static struct {
242#ifdef CONFIG_THINKPAD_ACPI_BAY
243 u32 bay_status:1;
244 u32 bay_eject:1;
245 u32 bay_status2:1;
246 u32 bay_eject2:1;
247#endif
248 u32 bluetooth:1; 242 u32 bluetooth:1;
249 u32 hotkey:1; 243 u32 hotkey:1;
250 u32 hotkey_mask:1; 244 u32 hotkey_mask:1;
@@ -589,18 +583,6 @@ static int acpi_ec_write(int i, u8 v)
589 return 1; 583 return 1;
590} 584}
591 585
592#if defined(CONFIG_THINKPAD_ACPI_DOCK) || defined(CONFIG_THINKPAD_ACPI_BAY)
593static int _sta(acpi_handle handle)
594{
595 int status;
596
597 if (!handle || !acpi_evalf(handle, &status, "_STA", "d"))
598 status = 0;
599
600 return status;
601}
602#endif
603
604static int issue_thinkpad_cmos_command(int cmos_cmd) 586static int issue_thinkpad_cmos_command(int cmos_cmd)
605{ 587{
606 if (!cmos_handle) 588 if (!cmos_handle)
@@ -784,6 +766,8 @@ static int dispatch_procfs_write(struct file *file,
784 766
785 if (!ibm || !ibm->write) 767 if (!ibm || !ibm->write)
786 return -EINVAL; 768 return -EINVAL;
769 if (count > PAGE_SIZE - 2)
770 return -EINVAL;
787 771
788 kernbuf = kmalloc(count + 2, GFP_KERNEL); 772 kernbuf = kmalloc(count + 2, GFP_KERNEL);
789 if (!kernbuf) 773 if (!kernbuf)
@@ -4442,293 +4426,6 @@ static struct ibm_struct light_driver_data = {
4442}; 4426};
4443 4427
4444/************************************************************************* 4428/*************************************************************************
4445 * Dock subdriver
4446 */
4447
4448#ifdef CONFIG_THINKPAD_ACPI_DOCK
4449
4450static void dock_notify(struct ibm_struct *ibm, u32 event);
4451static int dock_read(char *p);
4452static int dock_write(char *buf);
4453
4454TPACPI_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
4455 "\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
4456 "\\_SB.PCI0.PCI1.DOCK", /* all others */
4457 "\\_SB.PCI.ISA.SLCE", /* 570 */
4458 ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
4459
4460/* don't list other alternatives as we install a notify handler on the 570 */
4461TPACPI_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */
4462
4463static const struct acpi_device_id ibm_pci_device_ids[] = {
4464 {PCI_ROOT_HID_STRING, 0},
4465 {"", 0},
4466};
4467
4468static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
4469 {
4470 .notify = dock_notify,
4471 .handle = &dock_handle,
4472 .type = ACPI_SYSTEM_NOTIFY,
4473 },
4474 {
4475 /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING.
4476 * We just use it to get notifications of dock hotplug
4477 * in very old thinkpads */
4478 .hid = ibm_pci_device_ids,
4479 .notify = dock_notify,
4480 .handle = &pci_handle,
4481 .type = ACPI_SYSTEM_NOTIFY,
4482 },
4483};
4484
4485static struct ibm_struct dock_driver_data[2] = {
4486 {
4487 .name = "dock",
4488 .read = dock_read,
4489 .write = dock_write,
4490 .acpi = &ibm_dock_acpidriver[0],
4491 },
4492 {
4493 .name = "dock",
4494 .acpi = &ibm_dock_acpidriver[1],
4495 },
4496};
4497
4498#define dock_docked() (_sta(dock_handle) & 1)
4499
4500static int __init dock_init(struct ibm_init_struct *iibm)
4501{
4502 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
4503
4504 TPACPI_ACPIHANDLE_INIT(dock);
4505
4506 vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
4507 str_supported(dock_handle != NULL));
4508
4509 return (dock_handle)? 0 : 1;
4510}
4511
4512static int __init dock_init2(struct ibm_init_struct *iibm)
4513{
4514 int dock2_needed;
4515
4516 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n");
4517
4518 if (dock_driver_data[0].flags.acpi_driver_registered &&
4519 dock_driver_data[0].flags.acpi_notify_installed) {
4520 TPACPI_ACPIHANDLE_INIT(pci);
4521 dock2_needed = (pci_handle != NULL);
4522 vdbg_printk(TPACPI_DBG_INIT,
4523 "dock PCI handler for the TP 570 is %s\n",
4524 str_supported(dock2_needed));
4525 } else {
4526 vdbg_printk(TPACPI_DBG_INIT,
4527 "dock subdriver part 2 not required\n");
4528 dock2_needed = 0;
4529 }
4530
4531 return (dock2_needed)? 0 : 1;
4532}
4533
4534static void dock_notify(struct ibm_struct *ibm, u32 event)
4535{
4536 int docked = dock_docked();
4537 int pci = ibm->acpi->hid && ibm->acpi->device &&
4538 acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids);
4539 int data;
4540
4541 if (event == 1 && !pci) /* 570 */
4542 data = 1; /* button */
4543 else if (event == 1 && pci) /* 570 */
4544 data = 3; /* dock */
4545 else if (event == 3 && docked)
4546 data = 1; /* button */
4547 else if (event == 3 && !docked)
4548 data = 2; /* undock */
4549 else if (event == 0 && docked)
4550 data = 3; /* dock */
4551 else {
4552 printk(TPACPI_ERR "unknown dock event %d, status %d\n",
4553 event, _sta(dock_handle));
4554 data = 0; /* unknown */
4555 }
4556 acpi_bus_generate_proc_event(ibm->acpi->device, event, data);
4557 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
4558 dev_name(&ibm->acpi->device->dev),
4559 event, data);
4560}
4561
4562static int dock_read(char *p)
4563{
4564 int len = 0;
4565 int docked = dock_docked();
4566
4567 if (!dock_handle)
4568 len += sprintf(p + len, "status:\t\tnot supported\n");
4569 else if (!docked)
4570 len += sprintf(p + len, "status:\t\tundocked\n");
4571 else {
4572 len += sprintf(p + len, "status:\t\tdocked\n");
4573 len += sprintf(p + len, "commands:\tdock, undock\n");
4574 }
4575
4576 return len;
4577}
4578
4579static int dock_write(char *buf)
4580{
4581 char *cmd;
4582
4583 if (!dock_docked())
4584 return -ENODEV;
4585
4586 while ((cmd = next_cmd(&buf))) {
4587 if (strlencmp(cmd, "undock") == 0) {
4588 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) ||
4589 !acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1))
4590 return -EIO;
4591 } else if (strlencmp(cmd, "dock") == 0) {
4592 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1))
4593 return -EIO;
4594 } else
4595 return -EINVAL;
4596 }
4597
4598 return 0;
4599}
4600
4601#endif /* CONFIG_THINKPAD_ACPI_DOCK */
4602
4603/*************************************************************************
4604 * Bay subdriver
4605 */
4606
4607#ifdef CONFIG_THINKPAD_ACPI_BAY
4608
4609TPACPI_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
4610 "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
4611 "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */
4612 "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
4613 ); /* A21e, R30, R31 */
4614TPACPI_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */
4615 "_EJ0", /* all others */
4616 ); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
4617TPACPI_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
4618 "\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */
4619 ); /* all others */
4620TPACPI_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */
4621 "_EJ0", /* 770x */
4622 ); /* all others */
4623
4624static int __init bay_init(struct ibm_init_struct *iibm)
4625{
4626 vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
4627
4628 TPACPI_ACPIHANDLE_INIT(bay);
4629 if (bay_handle)
4630 TPACPI_ACPIHANDLE_INIT(bay_ej);
4631 TPACPI_ACPIHANDLE_INIT(bay2);
4632 if (bay2_handle)
4633 TPACPI_ACPIHANDLE_INIT(bay2_ej);
4634
4635 tp_features.bay_status = bay_handle &&
4636 acpi_evalf(bay_handle, NULL, "_STA", "qv");
4637 tp_features.bay_status2 = bay2_handle &&
4638 acpi_evalf(bay2_handle, NULL, "_STA", "qv");
4639
4640 tp_features.bay_eject = bay_handle && bay_ej_handle &&
4641 (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental);
4642 tp_features.bay_eject2 = bay2_handle && bay2_ej_handle &&
4643 (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
4644
4645 vdbg_printk(TPACPI_DBG_INIT,
4646 "bay 1: status %s, eject %s; bay 2: status %s, eject %s\n",
4647 str_supported(tp_features.bay_status),
4648 str_supported(tp_features.bay_eject),
4649 str_supported(tp_features.bay_status2),
4650 str_supported(tp_features.bay_eject2));
4651
4652 return (tp_features.bay_status || tp_features.bay_eject ||
4653 tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1;
4654}
4655
4656static void bay_notify(struct ibm_struct *ibm, u32 event)
4657{
4658 acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
4659 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
4660 dev_name(&ibm->acpi->device->dev),
4661 event, 0);
4662}
4663
4664#define bay_occupied(b) (_sta(b##_handle) & 1)
4665
4666static int bay_read(char *p)
4667{
4668 int len = 0;
4669 int occupied = bay_occupied(bay);
4670 int occupied2 = bay_occupied(bay2);
4671 int eject, eject2;
4672
4673 len += sprintf(p + len, "status:\t\t%s\n",
4674 tp_features.bay_status ?
4675 (occupied ? "occupied" : "unoccupied") :
4676 "not supported");
4677 if (tp_features.bay_status2)
4678 len += sprintf(p + len, "status2:\t%s\n", occupied2 ?
4679 "occupied" : "unoccupied");
4680
4681 eject = tp_features.bay_eject && occupied;
4682 eject2 = tp_features.bay_eject2 && occupied2;
4683
4684 if (eject && eject2)
4685 len += sprintf(p + len, "commands:\teject, eject2\n");
4686 else if (eject)
4687 len += sprintf(p + len, "commands:\teject\n");
4688 else if (eject2)
4689 len += sprintf(p + len, "commands:\teject2\n");
4690
4691 return len;
4692}
4693
4694static int bay_write(char *buf)
4695{
4696 char *cmd;
4697
4698 if (!tp_features.bay_eject && !tp_features.bay_eject2)
4699 return -ENODEV;
4700
4701 while ((cmd = next_cmd(&buf))) {
4702 if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) {
4703 if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1))
4704 return -EIO;
4705 } else if (tp_features.bay_eject2 &&
4706 strlencmp(cmd, "eject2") == 0) {
4707 if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1))
4708 return -EIO;
4709 } else
4710 return -EINVAL;
4711 }
4712
4713 return 0;
4714}
4715
4716static struct tp_acpi_drv_struct ibm_bay_acpidriver = {
4717 .notify = bay_notify,
4718 .handle = &bay_handle,
4719 .type = ACPI_SYSTEM_NOTIFY,
4720};
4721
4722static struct ibm_struct bay_driver_data = {
4723 .name = "bay",
4724 .read = bay_read,
4725 .write = bay_write,
4726 .acpi = &ibm_bay_acpidriver,
4727};
4728
4729#endif /* CONFIG_THINKPAD_ACPI_BAY */
4730
4731/*************************************************************************
4732 * CMOS subdriver 4429 * CMOS subdriver
4733 */ 4430 */
4734 4431
@@ -5945,14 +5642,48 @@ static struct backlight_ops ibm_backlight_data = {
5945 5642
5946/* --------------------------------------------------------------------- */ 5643/* --------------------------------------------------------------------- */
5947 5644
5645/*
5646 * These are only useful for models that have only one possibility
5647 * of GPU. If the BIOS model handles both ATI and Intel, don't use
5648 * these quirks.
5649 */
5650#define TPACPI_BRGHT_Q_NOEC 0x0001 /* Must NOT use EC HBRV */
5651#define TPACPI_BRGHT_Q_EC 0x0002 /* Should or must use EC HBRV */
5652#define TPACPI_BRGHT_Q_ASK 0x8000 /* Ask for user report */
5653
5654static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
5655 /* Models with ATI GPUs known to require ECNVRAM mode */
5656 TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */
5657
5658 /* Models with ATI GPUs (waiting confirmation) */
5659 TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
5660 TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
5661 TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
5662 TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
5663
5664 /* Models with Intel Extreme Graphics 2 (waiting confirmation) */
5665 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
5666 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
5667 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
5668
5669 /* Models with Intel GMA900 */
5670 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */
5671 TPACPI_Q_IBM('7', '4', TPACPI_BRGHT_Q_NOEC), /* X41 */
5672 TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC), /* X41 Tablet */
5673};
5674
5948static int __init brightness_init(struct ibm_init_struct *iibm) 5675static int __init brightness_init(struct ibm_init_struct *iibm)
5949{ 5676{
5950 int b; 5677 int b;
5678 unsigned long quirks;
5951 5679
5952 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); 5680 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
5953 5681
5954 mutex_init(&brightness_mutex); 5682 mutex_init(&brightness_mutex);
5955 5683
5684 quirks = tpacpi_check_quirks(brightness_quirk_table,
5685 ARRAY_SIZE(brightness_quirk_table));
5686
5956 /* 5687 /*
5957 * We always attempt to detect acpi support, so as to switch 5688 * We always attempt to detect acpi support, so as to switch
5958 * Lenovo Vista BIOS to ACPI brightness mode even if we are not 5689 * Lenovo Vista BIOS to ACPI brightness mode even if we are not
@@ -6009,23 +5740,13 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6009 /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */ 5740 /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
6010 if (brightness_mode == TPACPI_BRGHT_MODE_AUTO || 5741 if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
6011 brightness_mode == TPACPI_BRGHT_MODE_MAX) { 5742 brightness_mode == TPACPI_BRGHT_MODE_MAX) {
6012 if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) { 5743 if (quirks & TPACPI_BRGHT_Q_EC)
6013 /* 5744 brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
6014 * IBM models that define HBRV probably have 5745 else
6015 * EC-based backlight level control
6016 */
6017 if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
6018 /* T40-T43, R50-R52, R50e, R51e, X31-X41 */
6019 brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
6020 else
6021 /* all other IBM ThinkPads */
6022 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
6023 } else
6024 /* All Lenovo ThinkPads */
6025 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP; 5746 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
6026 5747
6027 dbg_printk(TPACPI_DBG_BRGHT, 5748 dbg_printk(TPACPI_DBG_BRGHT,
6028 "selected brightness_mode=%d\n", 5749 "driver auto-selected brightness_mode=%d\n",
6029 brightness_mode); 5750 brightness_mode);
6030 } 5751 }
6031 5752
@@ -6052,6 +5773,15 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6052 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, 5773 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6053 "brightness is supported\n"); 5774 "brightness is supported\n");
6054 5775
5776 if (quirks & TPACPI_BRGHT_Q_ASK) {
5777 printk(TPACPI_NOTICE
5778 "brightness: will use unverified default: "
5779 "brightness_mode=%d\n", brightness_mode);
5780 printk(TPACPI_NOTICE
5781 "brightness: please report to %s whether it works well "
5782 "or not on your ThinkPad\n", TPACPI_MAIL);
5783 }
5784
6055 ibm_backlight_device->props.max_brightness = 5785 ibm_backlight_device->props.max_brightness =
6056 (tp_features.bright_16levels)? 15 : 7; 5786 (tp_features.bright_16levels)? 15 : 7;
6057 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; 5787 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
@@ -7854,22 +7584,6 @@ static struct ibm_init_struct ibms_init[] __initdata = {
7854 .init = light_init, 7584 .init = light_init,
7855 .data = &light_driver_data, 7585 .data = &light_driver_data,
7856 }, 7586 },
7857#ifdef CONFIG_THINKPAD_ACPI_DOCK
7858 {
7859 .init = dock_init,
7860 .data = &dock_driver_data[0],
7861 },
7862 {
7863 .init = dock_init2,
7864 .data = &dock_driver_data[1],
7865 },
7866#endif
7867#ifdef CONFIG_THINKPAD_ACPI_BAY
7868 {
7869 .init = bay_init,
7870 .data = &bay_driver_data,
7871 },
7872#endif
7873 { 7587 {
7874 .init = cmos_init, 7588 .init = cmos_init,
7875 .data = &cmos_driver_data, 7589 .data = &cmos_driver_data,
@@ -7968,12 +7682,6 @@ TPACPI_PARAM(hotkey);
7968TPACPI_PARAM(bluetooth); 7682TPACPI_PARAM(bluetooth);
7969TPACPI_PARAM(video); 7683TPACPI_PARAM(video);
7970TPACPI_PARAM(light); 7684TPACPI_PARAM(light);
7971#ifdef CONFIG_THINKPAD_ACPI_DOCK
7972TPACPI_PARAM(dock);
7973#endif
7974#ifdef CONFIG_THINKPAD_ACPI_BAY
7975TPACPI_PARAM(bay);
7976#endif /* CONFIG_THINKPAD_ACPI_BAY */
7977TPACPI_PARAM(cmos); 7685TPACPI_PARAM(cmos);
7978TPACPI_PARAM(led); 7686TPACPI_PARAM(led);
7979TPACPI_PARAM(beep); 7687TPACPI_PARAM(beep);