Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
eeepc-laptop: fix hot-unplug on resume
ACPI: Ingore the memory block with zero block size in course of memory hotplug
ACPI: Don't treat generic error as ACPI error code in acpi memory hotplug driver
ACPI: bind workqueues to CPU 0 to avoid SMI corruption
ACPI: root-only read protection on /sys/firmware/acpi/tables/*
thinkpad-acpi: fix incorrect use of TPACPI_BRGHT_MODE_ECNVRAM
thinkpad-acpi: restrict procfs count value to sane upper limit
thinkpad-acpi: remove dock and bay subdrivers
thinkpad-acpi: disable broken bay and dock subdrivers
hp-wmi: check that an input device exists in resume handler
Revert "ACPICA: Remove obsolete acpi_os_validate_address interface"

+148 -511
-127
Documentation/laptops/thinkpad-acpi.txt
··· 36 - Bluetooth enable and disable 37 - video output switching, expansion control 38 - ThinkLight on and off 39 - - limited docking and undocking 40 - - UltraBay eject 41 - CMOS/UCMS control 42 - LED control 43 - ACPI sounds ··· 725 Due to limitations in the sysfs LED class, if the status of the ThinkLight 726 cannot be read or if it is unknown, thinkpad-acpi will report it as "off". 727 It is impossible to know if the status returned through sysfs is valid. 728 - 729 - 730 - Docking / undocking -- /proc/acpi/ibm/dock 731 - ------------------------------------------ 732 - 733 - Docking and undocking (e.g. with the X4 UltraBase) requires some 734 - actions to be taken by the operating system to safely make or break 735 - the electrical connections with the dock. 736 - 737 - The docking feature of this driver generates the following ACPI events: 738 - 739 - ibm/dock GDCK 00000003 00000001 -- eject request 740 - ibm/dock GDCK 00000003 00000002 -- undocked 741 - ibm/dock GDCK 00000000 00000003 -- docked 742 - 743 - NOTE: These events will only be generated if the laptop was docked 744 - when originally booted. This is due to the current lack of support for 745 - hot plugging of devices in the Linux ACPI framework. If the laptop was 746 - booted while not in the dock, the following message is shown in the 747 - logs: 748 - 749 - Mar 17 01:42:34 aero kernel: thinkpad_acpi: dock device not present 750 - 751 - In this case, no dock-related events are generated but the dock and 752 - undock commands described below still work. They can be executed 753 - manually or triggered by Fn key combinations (see the example acpid 754 - configuration files included in the driver tarball package available 755 - on the web site). 756 - 757 - When the eject request button on the dock is pressed, the first event 758 - above is generated. The handler for this event should issue the 759 - following command: 760 - 761 - echo undock > /proc/acpi/ibm/dock 762 - 763 - After the LED on the dock goes off, it is safe to eject the laptop. 764 - Note: if you pressed this key by mistake, go ahead and eject the 765 - laptop, then dock it back in. Otherwise, the dock may not function as 766 - expected. 767 - 768 - When the laptop is docked, the third event above is generated. The 769 - handler for this event should issue the following command to fully 770 - enable the dock: 771 - 772 - echo dock > /proc/acpi/ibm/dock 773 - 774 - The contents of the /proc/acpi/ibm/dock file shows the current status 775 - of the dock, as provided by the ACPI framework. 776 - 777 - The docking support in this driver does not take care of enabling or 778 - disabling any other devices you may have attached to the dock. For 779 - example, a CD drive plugged into the UltraBase needs to be disabled or 780 - enabled separately. See the provided example acpid configuration files 781 - for how this can be accomplished. 782 - 783 - There is no support yet for PCI devices that may be attached to a 784 - docking station, e.g. in the ThinkPad Dock II. The driver currently 785 - does not recognize, enable or disable such devices. This means that 786 - the only docking stations currently supported are the X-series 787 - UltraBase docks and "dumb" port replicators like the Mini Dock (the 788 - latter don't need any ACPI support, actually). 789 - 790 - 791 - UltraBay eject -- /proc/acpi/ibm/bay 792 - ------------------------------------ 793 - 794 - Inserting or ejecting an UltraBay device requires some actions to be 795 - taken by the operating system to safely make or break the electrical 796 - connections with the device. 797 - 798 - This feature generates the following ACPI events: 799 - 800 - ibm/bay MSTR 00000003 00000000 -- eject request 801 - ibm/bay MSTR 00000001 00000000 -- eject lever inserted 802 - 803 - NOTE: These events will only be generated if the UltraBay was present 804 - when the laptop was originally booted (on the X series, the UltraBay 805 - is in the dock, so it may not be present if the laptop was undocked). 806 - This is due to the current lack of support for hot plugging of devices 807 - in the Linux ACPI framework. If the laptop was booted without the 808 - UltraBay, the following message is shown in the logs: 809 - 810 - Mar 17 01:42:34 aero kernel: thinkpad_acpi: bay device not present 811 - 812 - In this case, no bay-related events are generated but the eject 813 - command described below still works. It can be executed manually or 814 - triggered by a hot key combination. 815 - 816 - Sliding the eject lever generates the first event shown above. The 817 - handler for this event should take whatever actions are necessary to 818 - shut down the device in the UltraBay (e.g. call idectl), then issue 819 - the following command: 820 - 821 - echo eject > /proc/acpi/ibm/bay 822 - 823 - After the LED on the UltraBay goes off, it is safe to pull out the 824 - device. 825 - 826 - When the eject lever is inserted, the second event above is 827 - generated. The handler for this event should take whatever actions are 828 - necessary to enable the UltraBay device (e.g. call idectl). 829 - 830 - The contents of the /proc/acpi/ibm/bay file shows the current status 831 - of the UltraBay, as provided by the ACPI framework. 832 - 833 - EXPERIMENTAL warm eject support on the 600e/x, A22p and A3x (To use 834 - this feature, you need to supply the experimental=1 parameter when 835 - loading the module): 836 - 837 - These models do not have a button near the UltraBay device to request 838 - a hot eject but rather require the laptop to be put to sleep 839 - (suspend-to-ram) before the bay device is ejected or inserted). 840 - The sequence of steps to eject the device is as follows: 841 - 842 - echo eject > /proc/acpi/ibm/bay 843 - put the ThinkPad to sleep 844 - remove the drive 845 - resume from sleep 846 - cat /proc/acpi/ibm/bay should show that the drive was removed 847 - 848 - On the A3x, both the UltraBay 2000 and UltraBay Plus devices are 849 - supported. Use "eject2" instead of "eject" for the second bay. 850 - 851 - Note: the UltraBay eject support on the 600e/x, A22p and A3x is 852 - EXPERIMENTAL and may not work as expected. USE WITH CAUTION! 853 854 855 CMOS/UCMS control
··· 36 - Bluetooth enable and disable 37 - video output switching, expansion control 38 - ThinkLight on and off 39 - CMOS/UCMS control 40 - LED control 41 - ACPI sounds ··· 727 Due to limitations in the sysfs LED class, if the status of the ThinkLight 728 cannot be read or if it is unknown, thinkpad-acpi will report it as "off". 729 It is impossible to know if the status returned through sysfs is valid. 730 731 732 CMOS/UCMS control
+25 -9
drivers/acpi/acpi_memhotplug.c
··· 38 39 #define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT 40 41 ACPI_MODULE_NAME("acpi_memhotplug"); 42 MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>"); 43 MODULE_DESCRIPTION("Hotplug Mem Driver"); ··· 156 acpi_handle phandle; 157 struct acpi_device *device = NULL; 158 struct acpi_device *pdevice = NULL; 159 160 161 if (!acpi_bus_get_device(handle, &device) && device) ··· 169 } 170 171 /* Get the parent device */ 172 - status = acpi_bus_get_device(phandle, &pdevice); 173 - if (ACPI_FAILURE(status)) { 174 - ACPI_EXCEPTION((AE_INFO, status, "Cannot get acpi bus device")); 175 return -EINVAL; 176 } 177 ··· 179 * Now add the notified device. This creates the acpi_device 180 * and invokes .add function 181 */ 182 - status = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); 183 - if (ACPI_FAILURE(status)) { 184 - ACPI_EXCEPTION((AE_INFO, status, "Cannot add acpi bus")); 185 return -EINVAL; 186 } 187 ··· 242 num_enabled++; 243 continue; 244 } 245 - 246 if (node < 0) 247 node = memory_add_physaddr_to_nid(info->start_addr); 248 ··· 262 mem_device->state = MEMORY_INVALID_STATE; 263 return -EINVAL; 264 } 265 - 266 - return result; 267 } 268 269 static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
··· 38 39 #define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT 40 41 + #undef PREFIX 42 + #define PREFIX "ACPI:memory_hp:" 43 + 44 ACPI_MODULE_NAME("acpi_memhotplug"); 45 MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>"); 46 MODULE_DESCRIPTION("Hotplug Mem Driver"); ··· 153 acpi_handle phandle; 154 struct acpi_device *device = NULL; 155 struct acpi_device *pdevice = NULL; 156 + int result; 157 158 159 if (!acpi_bus_get_device(handle, &device) && device) ··· 165 } 166 167 /* Get the parent device */ 168 + result = acpi_bus_get_device(phandle, &pdevice); 169 + if (result) { 170 + printk(KERN_WARNING PREFIX "Cannot get acpi bus device"); 171 return -EINVAL; 172 } 173 ··· 175 * Now add the notified device. This creates the acpi_device 176 * and invokes .add function 177 */ 178 + result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); 179 + if (result) { 180 + printk(KERN_WARNING PREFIX "Cannot add acpi bus"); 181 return -EINVAL; 182 } 183 ··· 238 num_enabled++; 239 continue; 240 } 241 + /* 242 + * If the memory block size is zero, please ignore it. 243 + * Don't try to do the following memory hotplug flowchart. 244 + */ 245 + if (!info->length) 246 + continue; 247 if (node < 0) 248 node = memory_add_physaddr_to_nid(info->start_addr); 249 ··· 253 mem_device->state = MEMORY_INVALID_STATE; 254 return -EINVAL; 255 } 256 + /* 257 + * Sometimes the memory device will contain several memory blocks. 258 + * When one memory block is hot-added to the system memory, it will 259 + * be regarded as a success. 260 + * Otherwise if the last memory block can't be hot-added to the system 261 + * memory, it will be failure and the memory device can't be bound with 262 + * driver. 263 + */ 264 + return 0; 265 } 266 267 static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
+1
drivers/acpi/acpica/acobject.h
··· 97 #define AOPOBJ_OBJECT_INITIALIZED 0x08 98 #define AOPOBJ_SETUP_COMPLETE 0x10 99 #define AOPOBJ_SINGLE_DATUM 0x20 100 101 /****************************************************************************** 102 *
··· 97 #define AOPOBJ_OBJECT_INITIALIZED 0x08 98 #define AOPOBJ_SETUP_COMPLETE 0x10 99 #define AOPOBJ_SINGLE_DATUM 0x20 100 + #define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ 101 102 /****************************************************************************** 103 *
+24
drivers/acpi/acpica/dsopcode.c
··· 397 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), 398 extra_desc->extra.aml_length, 399 extra_desc->extra.aml_start); 400 return_ACPI_STATUS(status); 401 } 402
··· 397 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), 398 extra_desc->extra.aml_length, 399 extra_desc->extra.aml_start); 400 + if (ACPI_FAILURE(status)) { 401 + return_ACPI_STATUS(status); 402 + } 403 + 404 + /* Validate the region address/length via the host OS */ 405 + 406 + status = acpi_os_validate_address(obj_desc->region.space_id, 407 + obj_desc->region.address, 408 + (acpi_size) obj_desc->region.length, 409 + acpi_ut_get_node_name(node)); 410 + 411 + if (ACPI_FAILURE(status)) { 412 + /* 413 + * Invalid address/length. We will emit an error message and mark 414 + * the region as invalid, so that it will cause an additional error if 415 + * it is ever used. Then return AE_OK. 416 + */ 417 + ACPI_EXCEPTION((AE_INFO, status, 418 + "During address validation of OpRegion [%4.4s]", 419 + node->name.ascii)); 420 + obj_desc->common.flags |= AOPOBJ_INVALID; 421 + status = AE_OK; 422 + } 423 + 424 return_ACPI_STATUS(status); 425 } 426
+6
drivers/acpi/acpica/exfldio.c
··· 113 } 114 } 115 116 /* 117 * Exit now for SMBus address space, it has a non-linear address space 118 * and the request cannot be directly validated
··· 113 } 114 } 115 116 + /* Exit if Address/Length have been disallowed by the host OS */ 117 + 118 + if (rgn_desc->common.flags & AOPOBJ_INVALID) { 119 + return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); 120 + } 121 + 122 /* 123 * Exit now for SMBus address space, it has a non-linear address space 124 * and the request cannot be directly validated
+25
drivers/acpi/osl.c
··· 189 return AE_OK; 190 } 191 192 acpi_status acpi_os_initialize1(void) 193 { 194 kacpid_wq = create_singlethread_workqueue("kacpid"); 195 kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); 196 kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); 197 BUG_ON(!kacpid_wq); 198 BUG_ON(!kacpi_notify_wq); 199 BUG_ON(!kacpi_hotplug_wq);
··· 189 return AE_OK; 190 } 191 192 + static void bind_to_cpu0(struct work_struct *work) 193 + { 194 + set_cpus_allowed(current, cpumask_of_cpu(0)); 195 + kfree(work); 196 + } 197 + 198 + static void bind_workqueue(struct workqueue_struct *wq) 199 + { 200 + struct work_struct *work; 201 + 202 + work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); 203 + INIT_WORK(work, bind_to_cpu0); 204 + queue_work(wq, work); 205 + } 206 + 207 acpi_status acpi_os_initialize1(void) 208 { 209 + /* 210 + * On some machines, a software-initiated SMI causes corruption unless 211 + * the SMI runs on CPU 0. An SMI can be initiated by any AML, but 212 + * typically it's done in GPE-related methods that are run via 213 + * workqueues, so we can avoid the known corruption cases by binding 214 + * the workqueues to CPU 0. 215 + */ 216 kacpid_wq = create_singlethread_workqueue("kacpid"); 217 + bind_workqueue(kacpid_wq); 218 kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); 219 + bind_workqueue(kacpi_notify_wq); 220 kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); 221 + bind_workqueue(kacpi_hotplug_wq); 222 BUG_ON(!kacpid_wq); 223 BUG_ON(!kacpi_notify_wq); 224 BUG_ON(!kacpi_hotplug_wq);
+1 -1
drivers/acpi/system.c
··· 121 table_attr->attr.size = 0; 122 table_attr->attr.read = acpi_table_show; 123 table_attr->attr.attr.name = table_attr->name; 124 - table_attr->attr.attr.mode = 0444; 125 126 return; 127 }
··· 121 table_attr->attr.size = 0; 122 table_attr->attr.read = acpi_table_show; 123 table_attr->attr.attr.name = table_attr->name; 124 + table_attr->attr.attr.mode = 0400; 125 126 return; 127 }
-25
drivers/platform/x86/Kconfig
··· 277 Say N here, unless you are building a kernel for your own 278 use, and need to control the important firmware LEDs. 279 280 - config 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 - 294 - config 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 - 305 config THINKPAD_ACPI_VIDEO 306 bool "Video output control support" 307 depends on THINKPAD_ACPI
··· 277 Say N here, unless you are building a kernel for your own 278 use, and need to control the important firmware LEDs. 279 280 config THINKPAD_ACPI_VIDEO 281 bool "Video output control support" 282 depends on THINKPAD_ACPI
+6 -3
drivers/platform/x86/eeepc-laptop.c
··· 143 struct rfkill *bluetooth_rfkill; 144 struct rfkill *wwan3g_rfkill; 145 struct hotplug_slot *hotplug_slot; 146 }; 147 148 /* The actual device the driver binds to */ ··· 661 return 0; 662 } 663 664 - static void eeepc_rfkill_hotplug(void) 665 { 666 struct pci_dev *dev; 667 struct pci_bus *bus = pci_find_bus(0, 1); ··· 702 if (event != ACPI_NOTIFY_BUS_CHECK) 703 return; 704 705 - eeepc_rfkill_hotplug(); 706 } 707 708 static void eeepc_hotk_notify(struct acpi_device *device, u32 event) ··· 893 894 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); 895 896 - eeepc_rfkill_hotplug(); 897 } 898 899 if (ehotk->bluetooth_rfkill) ··· 1093 static int eeepc_rfkill_init(struct device *dev) 1094 { 1095 int result = 0; 1096 1097 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); 1098 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
··· 143 struct rfkill *bluetooth_rfkill; 144 struct rfkill *wwan3g_rfkill; 145 struct hotplug_slot *hotplug_slot; 146 + struct work_struct hotplug_work; 147 }; 148 149 /* The actual device the driver binds to */ ··· 660 return 0; 661 } 662 663 + static void eeepc_hotplug_work(struct work_struct *work) 664 { 665 struct pci_dev *dev; 666 struct pci_bus *bus = pci_find_bus(0, 1); ··· 701 if (event != ACPI_NOTIFY_BUS_CHECK) 702 return; 703 704 + schedule_work(&ehotk->hotplug_work); 705 } 706 707 static void eeepc_hotk_notify(struct acpi_device *device, u32 event) ··· 892 893 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); 894 895 + schedule_work(&ehotk->hotplug_work); 896 } 897 898 if (ehotk->bluetooth_rfkill) ··· 1092 static int eeepc_rfkill_init(struct device *dev) 1093 { 1094 int result = 0; 1095 + 1096 + INIT_WORK(&ehotk->hotplug_work, eeepc_hotplug_work); 1097 1098 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); 1099 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
+7 -5
drivers/platform/x86/hp-wmi.c
··· 520 * the input layer will only actually pass it on if the state 521 * changed. 522 */ 523 - 524 - input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state()); 525 - input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, 526 - hp_wmi_tablet_state()); 527 - input_sync(hp_wmi_input_dev); 528 529 return 0; 530 }
··· 520 * the input layer will only actually pass it on if the state 521 * changed. 522 */ 523 + if (hp_wmi_input_dev) { 524 + input_report_switch(hp_wmi_input_dev, SW_DOCK, 525 + hp_wmi_dock_state()); 526 + input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, 527 + hp_wmi_tablet_state()); 528 + input_sync(hp_wmi_input_dev); 529 + } 530 531 return 0; 532 }
+49 -341
drivers/platform/x86/thinkpad_acpi.c
··· 239 }; 240 241 static 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; 249 u32 hotkey:1; 250 u32 hotkey_mask:1; ··· 583 return 1; 584 } 585 586 - #if defined(CONFIG_THINKPAD_ACPI_DOCK) || defined(CONFIG_THINKPAD_ACPI_BAY) 587 - static int _sta(acpi_handle handle) 588 - { 589 - int status; 590 - 591 - if (!handle || !acpi_evalf(handle, &status, "_STA", "d")) 592 - status = 0; 593 - 594 - return status; 595 - } 596 - #endif 597 - 598 static int issue_thinkpad_cmos_command(int cmos_cmd) 599 { 600 if (!cmos_handle) ··· 765 int ret; 766 767 if (!ibm || !ibm->write) 768 return -EINVAL; 769 770 kernbuf = kmalloc(count + 2, GFP_KERNEL); ··· 4426 }; 4427 4428 /************************************************************************* 4429 - * Dock subdriver 4430 - */ 4431 - 4432 - #ifdef CONFIG_THINKPAD_ACPI_DOCK 4433 - 4434 - static void dock_notify(struct ibm_struct *ibm, u32 event); 4435 - static int dock_read(char *p); 4436 - static int dock_write(char *buf); 4437 - 4438 - TPACPI_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ 4439 - "\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */ 4440 - "\\_SB.PCI0.PCI1.DOCK", /* all others */ 4441 - "\\_SB.PCI.ISA.SLCE", /* 570 */ 4442 - ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */ 4443 - 4444 - /* don't list other alternatives as we install a notify handler on the 570 */ 4445 - TPACPI_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */ 4446 - 4447 - static const struct acpi_device_id ibm_pci_device_ids[] = { 4448 - {PCI_ROOT_HID_STRING, 0}, 4449 - {"", 0}, 4450 - }; 4451 - 4452 - static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = { 4453 - { 4454 - .notify = dock_notify, 4455 - .handle = &dock_handle, 4456 - .type = ACPI_SYSTEM_NOTIFY, 4457 - }, 4458 - { 4459 - /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING. 4460 - * We just use it to get notifications of dock hotplug 4461 - * in very old thinkpads */ 4462 - .hid = ibm_pci_device_ids, 4463 - .notify = dock_notify, 4464 - .handle = &pci_handle, 4465 - .type = ACPI_SYSTEM_NOTIFY, 4466 - }, 4467 - }; 4468 - 4469 - static struct ibm_struct dock_driver_data[2] = { 4470 - { 4471 - .name = "dock", 4472 - .read = dock_read, 4473 - .write = dock_write, 4474 - .acpi = &ibm_dock_acpidriver[0], 4475 - }, 4476 - { 4477 - .name = "dock", 4478 - .acpi = &ibm_dock_acpidriver[1], 4479 - }, 4480 - }; 4481 - 4482 - #define dock_docked() (_sta(dock_handle) & 1) 4483 - 4484 - static int __init dock_init(struct ibm_init_struct *iibm) 4485 - { 4486 - vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n"); 4487 - 4488 - TPACPI_ACPIHANDLE_INIT(dock); 4489 - 4490 - vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n", 4491 - str_supported(dock_handle != NULL)); 4492 - 4493 - return (dock_handle)? 0 : 1; 4494 - } 4495 - 4496 - static int __init dock_init2(struct ibm_init_struct *iibm) 4497 - { 4498 - int dock2_needed; 4499 - 4500 - vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n"); 4501 - 4502 - if (dock_driver_data[0].flags.acpi_driver_registered && 4503 - dock_driver_data[0].flags.acpi_notify_installed) { 4504 - TPACPI_ACPIHANDLE_INIT(pci); 4505 - dock2_needed = (pci_handle != NULL); 4506 - vdbg_printk(TPACPI_DBG_INIT, 4507 - "dock PCI handler for the TP 570 is %s\n", 4508 - str_supported(dock2_needed)); 4509 - } else { 4510 - vdbg_printk(TPACPI_DBG_INIT, 4511 - "dock subdriver part 2 not required\n"); 4512 - dock2_needed = 0; 4513 - } 4514 - 4515 - return (dock2_needed)? 0 : 1; 4516 - } 4517 - 4518 - static void dock_notify(struct ibm_struct *ibm, u32 event) 4519 - { 4520 - int docked = dock_docked(); 4521 - int pci = ibm->acpi->hid && ibm->acpi->device && 4522 - acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids); 4523 - int data; 4524 - 4525 - if (event == 1 && !pci) /* 570 */ 4526 - data = 1; /* button */ 4527 - else if (event == 1 && pci) /* 570 */ 4528 - data = 3; /* dock */ 4529 - else if (event == 3 && docked) 4530 - data = 1; /* button */ 4531 - else if (event == 3 && !docked) 4532 - data = 2; /* undock */ 4533 - else if (event == 0 && docked) 4534 - data = 3; /* dock */ 4535 - else { 4536 - printk(TPACPI_ERR "unknown dock event %d, status %d\n", 4537 - event, _sta(dock_handle)); 4538 - data = 0; /* unknown */ 4539 - } 4540 - acpi_bus_generate_proc_event(ibm->acpi->device, event, data); 4541 - acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 4542 - dev_name(&ibm->acpi->device->dev), 4543 - event, data); 4544 - } 4545 - 4546 - static int dock_read(char *p) 4547 - { 4548 - int len = 0; 4549 - int docked = dock_docked(); 4550 - 4551 - if (!dock_handle) 4552 - len += sprintf(p + len, "status:\t\tnot supported\n"); 4553 - else if (!docked) 4554 - len += sprintf(p + len, "status:\t\tundocked\n"); 4555 - else { 4556 - len += sprintf(p + len, "status:\t\tdocked\n"); 4557 - len += sprintf(p + len, "commands:\tdock, undock\n"); 4558 - } 4559 - 4560 - return len; 4561 - } 4562 - 4563 - static int dock_write(char *buf) 4564 - { 4565 - char *cmd; 4566 - 4567 - if (!dock_docked()) 4568 - return -ENODEV; 4569 - 4570 - while ((cmd = next_cmd(&buf))) { 4571 - if (strlencmp(cmd, "undock") == 0) { 4572 - if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) || 4573 - !acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1)) 4574 - return -EIO; 4575 - } else if (strlencmp(cmd, "dock") == 0) { 4576 - if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1)) 4577 - return -EIO; 4578 - } else 4579 - return -EINVAL; 4580 - } 4581 - 4582 - return 0; 4583 - } 4584 - 4585 - #endif /* CONFIG_THINKPAD_ACPI_DOCK */ 4586 - 4587 - /************************************************************************* 4588 - * Bay subdriver 4589 - */ 4590 - 4591 - #ifdef CONFIG_THINKPAD_ACPI_BAY 4592 - 4593 - TPACPI_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ 4594 - "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ 4595 - "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */ 4596 - "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */ 4597 - ); /* A21e, R30, R31 */ 4598 - TPACPI_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */ 4599 - "_EJ0", /* all others */ 4600 - ); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */ 4601 - TPACPI_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */ 4602 - "\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */ 4603 - ); /* all others */ 4604 - TPACPI_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */ 4605 - "_EJ0", /* 770x */ 4606 - ); /* all others */ 4607 - 4608 - static int __init bay_init(struct ibm_init_struct *iibm) 4609 - { 4610 - vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n"); 4611 - 4612 - TPACPI_ACPIHANDLE_INIT(bay); 4613 - if (bay_handle) 4614 - TPACPI_ACPIHANDLE_INIT(bay_ej); 4615 - TPACPI_ACPIHANDLE_INIT(bay2); 4616 - if (bay2_handle) 4617 - TPACPI_ACPIHANDLE_INIT(bay2_ej); 4618 - 4619 - tp_features.bay_status = bay_handle && 4620 - acpi_evalf(bay_handle, NULL, "_STA", "qv"); 4621 - tp_features.bay_status2 = bay2_handle && 4622 - acpi_evalf(bay2_handle, NULL, "_STA", "qv"); 4623 - 4624 - tp_features.bay_eject = bay_handle && bay_ej_handle && 4625 - (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental); 4626 - tp_features.bay_eject2 = bay2_handle && bay2_ej_handle && 4627 - (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental); 4628 - 4629 - vdbg_printk(TPACPI_DBG_INIT, 4630 - "bay 1: status %s, eject %s; bay 2: status %s, eject %s\n", 4631 - str_supported(tp_features.bay_status), 4632 - str_supported(tp_features.bay_eject), 4633 - str_supported(tp_features.bay_status2), 4634 - str_supported(tp_features.bay_eject2)); 4635 - 4636 - return (tp_features.bay_status || tp_features.bay_eject || 4637 - tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1; 4638 - } 4639 - 4640 - static void bay_notify(struct ibm_struct *ibm, u32 event) 4641 - { 4642 - acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); 4643 - acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 4644 - dev_name(&ibm->acpi->device->dev), 4645 - event, 0); 4646 - } 4647 - 4648 - #define bay_occupied(b) (_sta(b##_handle) & 1) 4649 - 4650 - static int bay_read(char *p) 4651 - { 4652 - int len = 0; 4653 - int occupied = bay_occupied(bay); 4654 - int occupied2 = bay_occupied(bay2); 4655 - int eject, eject2; 4656 - 4657 - len += sprintf(p + len, "status:\t\t%s\n", 4658 - tp_features.bay_status ? 4659 - (occupied ? "occupied" : "unoccupied") : 4660 - "not supported"); 4661 - if (tp_features.bay_status2) 4662 - len += sprintf(p + len, "status2:\t%s\n", occupied2 ? 4663 - "occupied" : "unoccupied"); 4664 - 4665 - eject = tp_features.bay_eject && occupied; 4666 - eject2 = tp_features.bay_eject2 && occupied2; 4667 - 4668 - if (eject && eject2) 4669 - len += sprintf(p + len, "commands:\teject, eject2\n"); 4670 - else if (eject) 4671 - len += sprintf(p + len, "commands:\teject\n"); 4672 - else if (eject2) 4673 - len += sprintf(p + len, "commands:\teject2\n"); 4674 - 4675 - return len; 4676 - } 4677 - 4678 - static int bay_write(char *buf) 4679 - { 4680 - char *cmd; 4681 - 4682 - if (!tp_features.bay_eject && !tp_features.bay_eject2) 4683 - return -ENODEV; 4684 - 4685 - while ((cmd = next_cmd(&buf))) { 4686 - if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) { 4687 - if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1)) 4688 - return -EIO; 4689 - } else if (tp_features.bay_eject2 && 4690 - strlencmp(cmd, "eject2") == 0) { 4691 - if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1)) 4692 - return -EIO; 4693 - } else 4694 - return -EINVAL; 4695 - } 4696 - 4697 - return 0; 4698 - } 4699 - 4700 - static struct tp_acpi_drv_struct ibm_bay_acpidriver = { 4701 - .notify = bay_notify, 4702 - .handle = &bay_handle, 4703 - .type = ACPI_SYSTEM_NOTIFY, 4704 - }; 4705 - 4706 - static struct ibm_struct bay_driver_data = { 4707 - .name = "bay", 4708 - .read = bay_read, 4709 - .write = bay_write, 4710 - .acpi = &ibm_bay_acpidriver, 4711 - }; 4712 - 4713 - #endif /* CONFIG_THINKPAD_ACPI_BAY */ 4714 - 4715 - /************************************************************************* 4716 * CMOS subdriver 4717 */ 4718 ··· 5642 5643 /* --------------------------------------------------------------------- */ 5644 5645 static int __init brightness_init(struct ibm_init_struct *iibm) 5646 { 5647 int b; 5648 5649 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); 5650 5651 mutex_init(&brightness_mutex); 5652 5653 /* 5654 * We always attempt to detect acpi support, so as to switch ··· 5740 /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */ 5741 if (brightness_mode == TPACPI_BRGHT_MODE_AUTO || 5742 brightness_mode == TPACPI_BRGHT_MODE_MAX) { 5743 - if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) { 5744 - /* 5745 - * IBM models that define HBRV probably have 5746 - * EC-based backlight level control 5747 - */ 5748 - if (acpi_evalf(ec_handle, NULL, "HBRV", "qd")) 5749 - /* T40-T43, R50-R52, R50e, R51e, X31-X41 */ 5750 - brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM; 5751 - else 5752 - /* all other IBM ThinkPads */ 5753 - brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP; 5754 - } else 5755 - /* All Lenovo ThinkPads */ 5756 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP; 5757 5758 dbg_printk(TPACPI_DBG_BRGHT, 5759 - "selected brightness_mode=%d\n", 5760 brightness_mode); 5761 } 5762 ··· 5772 } 5773 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, 5774 "brightness is supported\n"); 5775 5776 ibm_backlight_device->props.max_brightness = 5777 (tp_features.bright_16levels)? 15 : 7; ··· 7584 .init = light_init, 7585 .data = &light_driver_data, 7586 }, 7587 - #ifdef CONFIG_THINKPAD_ACPI_DOCK 7588 - { 7589 - .init = dock_init, 7590 - .data = &dock_driver_data[0], 7591 - }, 7592 - { 7593 - .init = dock_init2, 7594 - .data = &dock_driver_data[1], 7595 - }, 7596 - #endif 7597 - #ifdef CONFIG_THINKPAD_ACPI_BAY 7598 - { 7599 - .init = bay_init, 7600 - .data = &bay_driver_data, 7601 - }, 7602 - #endif 7603 { 7604 .init = cmos_init, 7605 .data = &cmos_driver_data, ··· 7682 TPACPI_PARAM(bluetooth); 7683 TPACPI_PARAM(video); 7684 TPACPI_PARAM(light); 7685 - #ifdef CONFIG_THINKPAD_ACPI_DOCK 7686 - TPACPI_PARAM(dock); 7687 - #endif 7688 - #ifdef CONFIG_THINKPAD_ACPI_BAY 7689 - TPACPI_PARAM(bay); 7690 - #endif /* CONFIG_THINKPAD_ACPI_BAY */ 7691 TPACPI_PARAM(cmos); 7692 TPACPI_PARAM(led); 7693 TPACPI_PARAM(beep);
··· 239 }; 240 241 static struct { 242 u32 bluetooth:1; 243 u32 hotkey:1; 244 u32 hotkey_mask:1; ··· 589 return 1; 590 } 591 592 static int issue_thinkpad_cmos_command(int cmos_cmd) 593 { 594 if (!cmos_handle) ··· 783 int ret; 784 785 if (!ibm || !ibm->write) 786 + return -EINVAL; 787 + if (count > PAGE_SIZE - 2) 788 return -EINVAL; 789 790 kernbuf = kmalloc(count + 2, GFP_KERNEL); ··· 4442 }; 4443 4444 /************************************************************************* 4445 * CMOS subdriver 4446 */ 4447 ··· 5945 5946 /* --------------------------------------------------------------------- */ 5947 5948 + /* 5949 + * These are only useful for models that have only one possibility 5950 + * of GPU. If the BIOS model handles both ATI and Intel, don't use 5951 + * these quirks. 5952 + */ 5953 + #define TPACPI_BRGHT_Q_NOEC 0x0001 /* Must NOT use EC HBRV */ 5954 + #define TPACPI_BRGHT_Q_EC 0x0002 /* Should or must use EC HBRV */ 5955 + #define TPACPI_BRGHT_Q_ASK 0x8000 /* Ask for user report */ 5956 + 5957 + static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { 5958 + /* Models with ATI GPUs known to require ECNVRAM mode */ 5959 + TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ 5960 + 5961 + /* Models with ATI GPUs (waiting confirmation) */ 5962 + TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 5963 + TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 5964 + TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 5965 + TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 5966 + 5967 + /* Models with Intel Extreme Graphics 2 (waiting confirmation) */ 5968 + TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 5969 + TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 5970 + TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 5971 + 5972 + /* Models with Intel GMA900 */ 5973 + TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ 5974 + TPACPI_Q_IBM('7', '4', TPACPI_BRGHT_Q_NOEC), /* X41 */ 5975 + TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC), /* X41 Tablet */ 5976 + }; 5977 + 5978 static int __init brightness_init(struct ibm_init_struct *iibm) 5979 { 5980 int b; 5981 + unsigned long quirks; 5982 5983 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); 5984 5985 mutex_init(&brightness_mutex); 5986 + 5987 + quirks = tpacpi_check_quirks(brightness_quirk_table, 5988 + ARRAY_SIZE(brightness_quirk_table)); 5989 5990 /* 5991 * We always attempt to detect acpi support, so as to switch ··· 6009 /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */ 6010 if (brightness_mode == TPACPI_BRGHT_MODE_AUTO || 6011 brightness_mode == TPACPI_BRGHT_MODE_MAX) { 6012 + if (quirks & TPACPI_BRGHT_Q_EC) 6013 + brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM; 6014 + else 6015 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP; 6016 6017 dbg_printk(TPACPI_DBG_BRGHT, 6018 + "driver auto-selected brightness_mode=%d\n", 6019 brightness_mode); 6020 } 6021 ··· 6051 } 6052 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, 6053 "brightness is supported\n"); 6054 + 6055 + if (quirks & TPACPI_BRGHT_Q_ASK) { 6056 + printk(TPACPI_NOTICE 6057 + "brightness: will use unverified default: " 6058 + "brightness_mode=%d\n", brightness_mode); 6059 + printk(TPACPI_NOTICE 6060 + "brightness: please report to %s whether it works well " 6061 + "or not on your ThinkPad\n", TPACPI_MAIL); 6062 + } 6063 6064 ibm_backlight_device->props.max_brightness = 6065 (tp_features.bright_16levels)? 15 : 7; ··· 7854 .init = light_init, 7855 .data = &light_driver_data, 7856 }, 7857 { 7858 .init = cmos_init, 7859 .data = &cmos_driver_data, ··· 7968 TPACPI_PARAM(bluetooth); 7969 TPACPI_PARAM(video); 7970 TPACPI_PARAM(light); 7971 TPACPI_PARAM(cmos); 7972 TPACPI_PARAM(led); 7973 TPACPI_PARAM(beep);
+4
include/acpi/acpiosxf.h
··· 242 acpi_status acpi_os_validate_interface(char *interface); 243 acpi_status acpi_osi_invalidate(char* interface); 244 245 u64 acpi_os_get_timer(void); 246 247 acpi_status acpi_os_signal(u32 function, void *info);
··· 242 acpi_status acpi_os_validate_interface(char *interface); 243 acpi_status acpi_osi_invalidate(char* interface); 244 245 + acpi_status 246 + acpi_os_validate_address(u8 space_id, acpi_physical_address address, 247 + acpi_size length, char *name); 248 + 249 u64 acpi_os_get_timer(void); 250 251 acpi_status acpi_os_signal(u32 function, void *info);