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"
This commit is contained in:
@@ -36,8 +36,6 @@ detailed description):
|
|||||||
- Bluetooth enable and disable
|
- Bluetooth enable and disable
|
||||||
- video output switching, expansion control
|
- video output switching, expansion control
|
||||||
- ThinkLight on and off
|
- ThinkLight on and off
|
||||||
- limited docking and undocking
|
|
||||||
- UltraBay eject
|
|
||||||
- CMOS/UCMS control
|
- CMOS/UCMS control
|
||||||
- LED control
|
- LED control
|
||||||
- ACPI sounds
|
- ACPI sounds
|
||||||
@@ -729,131 +727,6 @@ cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
|
|||||||
It is impossible to know if the status returned through sysfs is valid.
|
It is impossible to know if the status returned through sysfs is valid.
|
||||||
|
|
||||||
|
|
||||||
Docking / undocking -- /proc/acpi/ibm/dock
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
Docking and undocking (e.g. with the X4 UltraBase) requires some
|
|
||||||
actions to be taken by the operating system to safely make or break
|
|
||||||
the electrical connections with the dock.
|
|
||||||
|
|
||||||
The docking feature of this driver generates the following ACPI events:
|
|
||||||
|
|
||||||
ibm/dock GDCK 00000003 00000001 -- eject request
|
|
||||||
ibm/dock GDCK 00000003 00000002 -- undocked
|
|
||||||
ibm/dock GDCK 00000000 00000003 -- docked
|
|
||||||
|
|
||||||
NOTE: These events will only be generated if the laptop was docked
|
|
||||||
when originally booted. This is due to the current lack of support for
|
|
||||||
hot plugging of devices in the Linux ACPI framework. If the laptop was
|
|
||||||
booted while not in the dock, the following message is shown in the
|
|
||||||
logs:
|
|
||||||
|
|
||||||
Mar 17 01:42:34 aero kernel: thinkpad_acpi: dock device not present
|
|
||||||
|
|
||||||
In this case, no dock-related events are generated but the dock and
|
|
||||||
undock commands described below still work. They can be executed
|
|
||||||
manually or triggered by Fn key combinations (see the example acpid
|
|
||||||
configuration files included in the driver tarball package available
|
|
||||||
on the web site).
|
|
||||||
|
|
||||||
When the eject request button on the dock is pressed, the first event
|
|
||||||
above is generated. The handler for this event should issue the
|
|
||||||
following command:
|
|
||||||
|
|
||||||
echo undock > /proc/acpi/ibm/dock
|
|
||||||
|
|
||||||
After the LED on the dock goes off, it is safe to eject the laptop.
|
|
||||||
Note: if you pressed this key by mistake, go ahead and eject the
|
|
||||||
laptop, then dock it back in. Otherwise, the dock may not function as
|
|
||||||
expected.
|
|
||||||
|
|
||||||
When the laptop is docked, the third event above is generated. The
|
|
||||||
handler for this event should issue the following command to fully
|
|
||||||
enable the dock:
|
|
||||||
|
|
||||||
echo dock > /proc/acpi/ibm/dock
|
|
||||||
|
|
||||||
The contents of the /proc/acpi/ibm/dock file shows the current status
|
|
||||||
of the dock, as provided by the ACPI framework.
|
|
||||||
|
|
||||||
The docking support in this driver does not take care of enabling or
|
|
||||||
disabling any other devices you may have attached to the dock. For
|
|
||||||
example, a CD drive plugged into the UltraBase needs to be disabled or
|
|
||||||
enabled separately. See the provided example acpid configuration files
|
|
||||||
for how this can be accomplished.
|
|
||||||
|
|
||||||
There is no support yet for PCI devices that may be attached to a
|
|
||||||
docking station, e.g. in the ThinkPad Dock II. The driver currently
|
|
||||||
does not recognize, enable or disable such devices. This means that
|
|
||||||
the only docking stations currently supported are the X-series
|
|
||||||
UltraBase docks and "dumb" port replicators like the Mini Dock (the
|
|
||||||
latter don't need any ACPI support, actually).
|
|
||||||
|
|
||||||
|
|
||||||
UltraBay eject -- /proc/acpi/ibm/bay
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
Inserting or ejecting an UltraBay device requires some actions to be
|
|
||||||
taken by the operating system to safely make or break the electrical
|
|
||||||
connections with the device.
|
|
||||||
|
|
||||||
This feature generates the following ACPI events:
|
|
||||||
|
|
||||||
ibm/bay MSTR 00000003 00000000 -- eject request
|
|
||||||
ibm/bay MSTR 00000001 00000000 -- eject lever inserted
|
|
||||||
|
|
||||||
NOTE: These events will only be generated if the UltraBay was present
|
|
||||||
when the laptop was originally booted (on the X series, the UltraBay
|
|
||||||
is in the dock, so it may not be present if the laptop was undocked).
|
|
||||||
This is due to the current lack of support for hot plugging of devices
|
|
||||||
in the Linux ACPI framework. If the laptop was booted without the
|
|
||||||
UltraBay, the following message is shown in the logs:
|
|
||||||
|
|
||||||
Mar 17 01:42:34 aero kernel: thinkpad_acpi: bay device not present
|
|
||||||
|
|
||||||
In this case, no bay-related events are generated but the eject
|
|
||||||
command described below still works. It can be executed manually or
|
|
||||||
triggered by a hot key combination.
|
|
||||||
|
|
||||||
Sliding the eject lever generates the first event shown above. The
|
|
||||||
handler for this event should take whatever actions are necessary to
|
|
||||||
shut down the device in the UltraBay (e.g. call idectl), then issue
|
|
||||||
the following command:
|
|
||||||
|
|
||||||
echo eject > /proc/acpi/ibm/bay
|
|
||||||
|
|
||||||
After the LED on the UltraBay goes off, it is safe to pull out the
|
|
||||||
device.
|
|
||||||
|
|
||||||
When the eject lever is inserted, the second event above is
|
|
||||||
generated. The handler for this event should take whatever actions are
|
|
||||||
necessary to enable the UltraBay device (e.g. call idectl).
|
|
||||||
|
|
||||||
The contents of the /proc/acpi/ibm/bay file shows the current status
|
|
||||||
of the UltraBay, as provided by the ACPI framework.
|
|
||||||
|
|
||||||
EXPERIMENTAL warm eject support on the 600e/x, A22p and A3x (To use
|
|
||||||
this feature, you need to supply the experimental=1 parameter when
|
|
||||||
loading the module):
|
|
||||||
|
|
||||||
These models do not have a button near the UltraBay device to request
|
|
||||||
a hot eject but rather require the laptop to be put to sleep
|
|
||||||
(suspend-to-ram) before the bay device is ejected or inserted).
|
|
||||||
The sequence of steps to eject the device is as follows:
|
|
||||||
|
|
||||||
echo eject > /proc/acpi/ibm/bay
|
|
||||||
put the ThinkPad to sleep
|
|
||||||
remove the drive
|
|
||||||
resume from sleep
|
|
||||||
cat /proc/acpi/ibm/bay should show that the drive was removed
|
|
||||||
|
|
||||||
On the A3x, both the UltraBay 2000 and UltraBay Plus devices are
|
|
||||||
supported. Use "eject2" instead of "eject" for the second bay.
|
|
||||||
|
|
||||||
Note: the UltraBay eject support on the 600e/x, A22p and A3x is
|
|
||||||
EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
|
|
||||||
|
|
||||||
|
|
||||||
CMOS/UCMS control
|
CMOS/UCMS control
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
@@ -38,6 +38,9 @@
|
|||||||
|
|
||||||
#define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT
|
#define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT
|
||||||
|
|
||||||
|
#undef PREFIX
|
||||||
|
#define PREFIX "ACPI:memory_hp:"
|
||||||
|
|
||||||
ACPI_MODULE_NAME("acpi_memhotplug");
|
ACPI_MODULE_NAME("acpi_memhotplug");
|
||||||
MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
|
MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
|
||||||
MODULE_DESCRIPTION("Hotplug Mem Driver");
|
MODULE_DESCRIPTION("Hotplug Mem Driver");
|
||||||
@@ -153,6 +156,7 @@ acpi_memory_get_device(acpi_handle handle,
|
|||||||
acpi_handle phandle;
|
acpi_handle phandle;
|
||||||
struct acpi_device *device = NULL;
|
struct acpi_device *device = NULL;
|
||||||
struct acpi_device *pdevice = NULL;
|
struct acpi_device *pdevice = NULL;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
|
||||||
if (!acpi_bus_get_device(handle, &device) && device)
|
if (!acpi_bus_get_device(handle, &device) && device)
|
||||||
@@ -165,9 +169,9 @@ acpi_memory_get_device(acpi_handle handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the parent device */
|
/* Get the parent device */
|
||||||
status = acpi_bus_get_device(phandle, &pdevice);
|
result = acpi_bus_get_device(phandle, &pdevice);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (result) {
|
||||||
ACPI_EXCEPTION((AE_INFO, status, "Cannot get acpi bus device"));
|
printk(KERN_WARNING PREFIX "Cannot get acpi bus device");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,9 +179,9 @@ acpi_memory_get_device(acpi_handle handle,
|
|||||||
* Now add the notified device. This creates the acpi_device
|
* Now add the notified device. This creates the acpi_device
|
||||||
* and invokes .add function
|
* and invokes .add function
|
||||||
*/
|
*/
|
||||||
status = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
|
result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (result) {
|
||||||
ACPI_EXCEPTION((AE_INFO, status, "Cannot add acpi bus"));
|
printk(KERN_WARNING PREFIX "Cannot add acpi bus");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +242,12 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
|
|||||||
num_enabled++;
|
num_enabled++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* If the memory block size is zero, please ignore it.
|
||||||
|
* Don't try to do the following memory hotplug flowchart.
|
||||||
|
*/
|
||||||
|
if (!info->length)
|
||||||
|
continue;
|
||||||
if (node < 0)
|
if (node < 0)
|
||||||
node = memory_add_physaddr_to_nid(info->start_addr);
|
node = memory_add_physaddr_to_nid(info->start_addr);
|
||||||
|
|
||||||
@@ -253,8 +262,15 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
|
|||||||
mem_device->state = MEMORY_INVALID_STATE;
|
mem_device->state = MEMORY_INVALID_STATE;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
return result;
|
* Sometimes the memory device will contain several memory blocks.
|
||||||
|
* When one memory block is hot-added to the system memory, it will
|
||||||
|
* be regarded as a success.
|
||||||
|
* Otherwise if the last memory block can't be hot-added to the system
|
||||||
|
* memory, it will be failure and the memory device can't be bound with
|
||||||
|
* driver.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
|
static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
|
||||||
|
@@ -97,6 +97,7 @@
|
|||||||
#define AOPOBJ_OBJECT_INITIALIZED 0x08
|
#define AOPOBJ_OBJECT_INITIALIZED 0x08
|
||||||
#define AOPOBJ_SETUP_COMPLETE 0x10
|
#define AOPOBJ_SETUP_COMPLETE 0x10
|
||||||
#define AOPOBJ_SINGLE_DATUM 0x20
|
#define AOPOBJ_SINGLE_DATUM 0x20
|
||||||
|
#define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
|
@@ -397,6 +397,30 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
|
|||||||
status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
|
status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
|
||||||
extra_desc->extra.aml_length,
|
extra_desc->extra.aml_length,
|
||||||
extra_desc->extra.aml_start);
|
extra_desc->extra.aml_start);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate the region address/length via the host OS */
|
||||||
|
|
||||||
|
status = acpi_os_validate_address(obj_desc->region.space_id,
|
||||||
|
obj_desc->region.address,
|
||||||
|
(acpi_size) obj_desc->region.length,
|
||||||
|
acpi_ut_get_node_name(node));
|
||||||
|
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
/*
|
||||||
|
* Invalid address/length. We will emit an error message and mark
|
||||||
|
* the region as invalid, so that it will cause an additional error if
|
||||||
|
* it is ever used. Then return AE_OK.
|
||||||
|
*/
|
||||||
|
ACPI_EXCEPTION((AE_INFO, status,
|
||||||
|
"During address validation of OpRegion [%4.4s]",
|
||||||
|
node->name.ascii));
|
||||||
|
obj_desc->common.flags |= AOPOBJ_INVALID;
|
||||||
|
status = AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -113,6 +113,12 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Exit if Address/Length have been disallowed by the host OS */
|
||||||
|
|
||||||
|
if (rgn_desc->common.flags & AOPOBJ_INVALID) {
|
||||||
|
return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exit now for SMBus address space, it has a non-linear address space
|
* Exit now for SMBus address space, it has a non-linear address space
|
||||||
* and the request cannot be directly validated
|
* and the request cannot be directly validated
|
||||||
|
@@ -189,11 +189,36 @@ acpi_status __init acpi_os_initialize(void)
|
|||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bind_to_cpu0(struct work_struct *work)
|
||||||
|
{
|
||||||
|
set_cpus_allowed(current, cpumask_of_cpu(0));
|
||||||
|
kfree(work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bind_workqueue(struct workqueue_struct *wq)
|
||||||
|
{
|
||||||
|
struct work_struct *work;
|
||||||
|
|
||||||
|
work = kzalloc(sizeof(struct work_struct), GFP_KERNEL);
|
||||||
|
INIT_WORK(work, bind_to_cpu0);
|
||||||
|
queue_work(wq, work);
|
||||||
|
}
|
||||||
|
|
||||||
acpi_status acpi_os_initialize1(void)
|
acpi_status acpi_os_initialize1(void)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* On some machines, a software-initiated SMI causes corruption unless
|
||||||
|
* the SMI runs on CPU 0. An SMI can be initiated by any AML, but
|
||||||
|
* typically it's done in GPE-related methods that are run via
|
||||||
|
* workqueues, so we can avoid the known corruption cases by binding
|
||||||
|
* the workqueues to CPU 0.
|
||||||
|
*/
|
||||||
kacpid_wq = create_singlethread_workqueue("kacpid");
|
kacpid_wq = create_singlethread_workqueue("kacpid");
|
||||||
|
bind_workqueue(kacpid_wq);
|
||||||
kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
|
kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
|
||||||
|
bind_workqueue(kacpi_notify_wq);
|
||||||
kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug");
|
kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug");
|
||||||
|
bind_workqueue(kacpi_hotplug_wq);
|
||||||
BUG_ON(!kacpid_wq);
|
BUG_ON(!kacpid_wq);
|
||||||
BUG_ON(!kacpi_notify_wq);
|
BUG_ON(!kacpi_notify_wq);
|
||||||
BUG_ON(!kacpi_hotplug_wq);
|
BUG_ON(!kacpi_hotplug_wq);
|
||||||
|
@@ -121,7 +121,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
|
|||||||
table_attr->attr.size = 0;
|
table_attr->attr.size = 0;
|
||||||
table_attr->attr.read = acpi_table_show;
|
table_attr->attr.read = acpi_table_show;
|
||||||
table_attr->attr.attr.name = table_attr->name;
|
table_attr->attr.attr.name = table_attr->name;
|
||||||
table_attr->attr.attr.mode = 0444;
|
table_attr->attr.attr.mode = 0400;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -277,31 +277,6 @@ config THINKPAD_ACPI_UNSAFE_LEDS
|
|||||||
Say N here, unless you are building a kernel for your own
|
Say N here, unless you are building a kernel for your own
|
||||||
use, and need to control the important firmware LEDs.
|
use, and need to control the important firmware LEDs.
|
||||||
|
|
||||||
config THINKPAD_ACPI_DOCK
|
|
||||||
bool "Legacy Docking Station Support"
|
|
||||||
depends on THINKPAD_ACPI
|
|
||||||
depends on ACPI_DOCK=n
|
|
||||||
default n
|
|
||||||
---help---
|
|
||||||
Allows the thinkpad_acpi driver to handle docking station events.
|
|
||||||
This support was made obsolete by the generic ACPI docking station
|
|
||||||
support (CONFIG_ACPI_DOCK). It will allow locking and removing the
|
|
||||||
laptop from the docking station, but will not properly connect PCI
|
|
||||||
devices.
|
|
||||||
|
|
||||||
If you are not sure, say N here.
|
|
||||||
|
|
||||||
config THINKPAD_ACPI_BAY
|
|
||||||
bool "Legacy Removable Bay Support"
|
|
||||||
depends on THINKPAD_ACPI
|
|
||||||
default y
|
|
||||||
---help---
|
|
||||||
Allows the thinkpad_acpi driver to handle removable bays. It will
|
|
||||||
electrically disable the device in the bay, and also generate
|
|
||||||
notifications when the bay lever is ejected or inserted.
|
|
||||||
|
|
||||||
If you are not sure, say Y here.
|
|
||||||
|
|
||||||
config THINKPAD_ACPI_VIDEO
|
config THINKPAD_ACPI_VIDEO
|
||||||
bool "Video output control support"
|
bool "Video output control support"
|
||||||
depends on THINKPAD_ACPI
|
depends on THINKPAD_ACPI
|
||||||
|
@@ -143,6 +143,7 @@ struct eeepc_hotk {
|
|||||||
struct rfkill *bluetooth_rfkill;
|
struct rfkill *bluetooth_rfkill;
|
||||||
struct rfkill *wwan3g_rfkill;
|
struct rfkill *wwan3g_rfkill;
|
||||||
struct hotplug_slot *hotplug_slot;
|
struct hotplug_slot *hotplug_slot;
|
||||||
|
struct work_struct hotplug_work;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The actual device the driver binds to */
|
/* The actual device the driver binds to */
|
||||||
@@ -660,7 +661,7 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eeepc_rfkill_hotplug(void)
|
static void eeepc_hotplug_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
struct pci_bus *bus = pci_find_bus(0, 1);
|
struct pci_bus *bus = pci_find_bus(0, 1);
|
||||||
@@ -701,7 +702,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
|
|||||||
if (event != ACPI_NOTIFY_BUS_CHECK)
|
if (event != ACPI_NOTIFY_BUS_CHECK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
eeepc_rfkill_hotplug();
|
schedule_work(&ehotk->hotplug_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
|
static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
|
||||||
@@ -892,7 +893,7 @@ static int eeepc_hotk_resume(struct acpi_device *device)
|
|||||||
|
|
||||||
rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
|
rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
|
||||||
|
|
||||||
eeepc_rfkill_hotplug();
|
schedule_work(&ehotk->hotplug_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ehotk->bluetooth_rfkill)
|
if (ehotk->bluetooth_rfkill)
|
||||||
@@ -1093,6 +1094,8 @@ static int eeepc_rfkill_init(struct device *dev)
|
|||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
INIT_WORK(&ehotk->hotplug_work, eeepc_hotplug_work);
|
||||||
|
|
||||||
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
|
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
|
||||||
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
|
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
|
||||||
|
|
||||||
|
@@ -520,11 +520,13 @@ static int hp_wmi_resume_handler(struct platform_device *device)
|
|||||||
* the input layer will only actually pass it on if the state
|
* the input layer will only actually pass it on if the state
|
||||||
* changed.
|
* changed.
|
||||||
*/
|
*/
|
||||||
|
if (hp_wmi_input_dev) {
|
||||||
input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state());
|
input_report_switch(hp_wmi_input_dev, SW_DOCK,
|
||||||
input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
|
hp_wmi_dock_state());
|
||||||
hp_wmi_tablet_state());
|
input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
|
||||||
input_sync(hp_wmi_input_dev);
|
hp_wmi_tablet_state());
|
||||||
|
input_sync(hp_wmi_input_dev);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -239,12 +239,6 @@ struct ibm_init_struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
#ifdef CONFIG_THINKPAD_ACPI_BAY
|
|
||||||
u32 bay_status:1;
|
|
||||||
u32 bay_eject:1;
|
|
||||||
u32 bay_status2:1;
|
|
||||||
u32 bay_eject2:1;
|
|
||||||
#endif
|
|
||||||
u32 bluetooth:1;
|
u32 bluetooth:1;
|
||||||
u32 hotkey:1;
|
u32 hotkey:1;
|
||||||
u32 hotkey_mask:1;
|
u32 hotkey_mask:1;
|
||||||
@@ -589,18 +583,6 @@ static int acpi_ec_write(int i, u8 v)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_THINKPAD_ACPI_DOCK) || defined(CONFIG_THINKPAD_ACPI_BAY)
|
|
||||||
static int _sta(acpi_handle handle)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if (!handle || !acpi_evalf(handle, &status, "_STA", "d"))
|
|
||||||
status = 0;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int issue_thinkpad_cmos_command(int cmos_cmd)
|
static int issue_thinkpad_cmos_command(int cmos_cmd)
|
||||||
{
|
{
|
||||||
if (!cmos_handle)
|
if (!cmos_handle)
|
||||||
@@ -784,6 +766,8 @@ static int dispatch_procfs_write(struct file *file,
|
|||||||
|
|
||||||
if (!ibm || !ibm->write)
|
if (!ibm || !ibm->write)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (count > PAGE_SIZE - 2)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
kernbuf = kmalloc(count + 2, GFP_KERNEL);
|
kernbuf = kmalloc(count + 2, GFP_KERNEL);
|
||||||
if (!kernbuf)
|
if (!kernbuf)
|
||||||
@@ -4441,293 +4425,6 @@ static struct ibm_struct light_driver_data = {
|
|||||||
.exit = light_exit,
|
.exit = light_exit,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
* Dock subdriver
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CONFIG_THINKPAD_ACPI_DOCK
|
|
||||||
|
|
||||||
static void dock_notify(struct ibm_struct *ibm, u32 event);
|
|
||||||
static int dock_read(char *p);
|
|
||||||
static int dock_write(char *buf);
|
|
||||||
|
|
||||||
TPACPI_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
|
|
||||||
"\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
|
|
||||||
"\\_SB.PCI0.PCI1.DOCK", /* all others */
|
|
||||||
"\\_SB.PCI.ISA.SLCE", /* 570 */
|
|
||||||
); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
|
|
||||||
|
|
||||||
/* don't list other alternatives as we install a notify handler on the 570 */
|
|
||||||
TPACPI_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */
|
|
||||||
|
|
||||||
static const struct acpi_device_id ibm_pci_device_ids[] = {
|
|
||||||
{PCI_ROOT_HID_STRING, 0},
|
|
||||||
{"", 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
|
|
||||||
{
|
|
||||||
.notify = dock_notify,
|
|
||||||
.handle = &dock_handle,
|
|
||||||
.type = ACPI_SYSTEM_NOTIFY,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
/* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING.
|
|
||||||
* We just use it to get notifications of dock hotplug
|
|
||||||
* in very old thinkpads */
|
|
||||||
.hid = ibm_pci_device_ids,
|
|
||||||
.notify = dock_notify,
|
|
||||||
.handle = &pci_handle,
|
|
||||||
.type = ACPI_SYSTEM_NOTIFY,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct ibm_struct dock_driver_data[2] = {
|
|
||||||
{
|
|
||||||
.name = "dock",
|
|
||||||
.read = dock_read,
|
|
||||||
.write = dock_write,
|
|
||||||
.acpi = &ibm_dock_acpidriver[0],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "dock",
|
|
||||||
.acpi = &ibm_dock_acpidriver[1],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define dock_docked() (_sta(dock_handle) & 1)
|
|
||||||
|
|
||||||
static int __init dock_init(struct ibm_init_struct *iibm)
|
|
||||||
{
|
|
||||||
vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
|
|
||||||
|
|
||||||
TPACPI_ACPIHANDLE_INIT(dock);
|
|
||||||
|
|
||||||
vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
|
|
||||||
str_supported(dock_handle != NULL));
|
|
||||||
|
|
||||||
return (dock_handle)? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init dock_init2(struct ibm_init_struct *iibm)
|
|
||||||
{
|
|
||||||
int dock2_needed;
|
|
||||||
|
|
||||||
vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n");
|
|
||||||
|
|
||||||
if (dock_driver_data[0].flags.acpi_driver_registered &&
|
|
||||||
dock_driver_data[0].flags.acpi_notify_installed) {
|
|
||||||
TPACPI_ACPIHANDLE_INIT(pci);
|
|
||||||
dock2_needed = (pci_handle != NULL);
|
|
||||||
vdbg_printk(TPACPI_DBG_INIT,
|
|
||||||
"dock PCI handler for the TP 570 is %s\n",
|
|
||||||
str_supported(dock2_needed));
|
|
||||||
} else {
|
|
||||||
vdbg_printk(TPACPI_DBG_INIT,
|
|
||||||
"dock subdriver part 2 not required\n");
|
|
||||||
dock2_needed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (dock2_needed)? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dock_notify(struct ibm_struct *ibm, u32 event)
|
|
||||||
{
|
|
||||||
int docked = dock_docked();
|
|
||||||
int pci = ibm->acpi->hid && ibm->acpi->device &&
|
|
||||||
acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids);
|
|
||||||
int data;
|
|
||||||
|
|
||||||
if (event == 1 && !pci) /* 570 */
|
|
||||||
data = 1; /* button */
|
|
||||||
else if (event == 1 && pci) /* 570 */
|
|
||||||
data = 3; /* dock */
|
|
||||||
else if (event == 3 && docked)
|
|
||||||
data = 1; /* button */
|
|
||||||
else if (event == 3 && !docked)
|
|
||||||
data = 2; /* undock */
|
|
||||||
else if (event == 0 && docked)
|
|
||||||
data = 3; /* dock */
|
|
||||||
else {
|
|
||||||
printk(TPACPI_ERR "unknown dock event %d, status %d\n",
|
|
||||||
event, _sta(dock_handle));
|
|
||||||
data = 0; /* unknown */
|
|
||||||
}
|
|
||||||
acpi_bus_generate_proc_event(ibm->acpi->device, event, data);
|
|
||||||
acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
|
|
||||||
dev_name(&ibm->acpi->device->dev),
|
|
||||||
event, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dock_read(char *p)
|
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
int docked = dock_docked();
|
|
||||||
|
|
||||||
if (!dock_handle)
|
|
||||||
len += sprintf(p + len, "status:\t\tnot supported\n");
|
|
||||||
else if (!docked)
|
|
||||||
len += sprintf(p + len, "status:\t\tundocked\n");
|
|
||||||
else {
|
|
||||||
len += sprintf(p + len, "status:\t\tdocked\n");
|
|
||||||
len += sprintf(p + len, "commands:\tdock, undock\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dock_write(char *buf)
|
|
||||||
{
|
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
if (!dock_docked())
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
while ((cmd = next_cmd(&buf))) {
|
|
||||||
if (strlencmp(cmd, "undock") == 0) {
|
|
||||||
if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) ||
|
|
||||||
!acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1))
|
|
||||||
return -EIO;
|
|
||||||
} else if (strlencmp(cmd, "dock") == 0) {
|
|
||||||
if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1))
|
|
||||||
return -EIO;
|
|
||||||
} else
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_THINKPAD_ACPI_DOCK */
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
* Bay subdriver
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CONFIG_THINKPAD_ACPI_BAY
|
|
||||||
|
|
||||||
TPACPI_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
|
|
||||||
"\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
|
|
||||||
"\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */
|
|
||||||
"\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
|
|
||||||
); /* A21e, R30, R31 */
|
|
||||||
TPACPI_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */
|
|
||||||
"_EJ0", /* all others */
|
|
||||||
); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
|
|
||||||
TPACPI_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
|
|
||||||
"\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */
|
|
||||||
); /* all others */
|
|
||||||
TPACPI_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */
|
|
||||||
"_EJ0", /* 770x */
|
|
||||||
); /* all others */
|
|
||||||
|
|
||||||
static int __init bay_init(struct ibm_init_struct *iibm)
|
|
||||||
{
|
|
||||||
vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
|
|
||||||
|
|
||||||
TPACPI_ACPIHANDLE_INIT(bay);
|
|
||||||
if (bay_handle)
|
|
||||||
TPACPI_ACPIHANDLE_INIT(bay_ej);
|
|
||||||
TPACPI_ACPIHANDLE_INIT(bay2);
|
|
||||||
if (bay2_handle)
|
|
||||||
TPACPI_ACPIHANDLE_INIT(bay2_ej);
|
|
||||||
|
|
||||||
tp_features.bay_status = bay_handle &&
|
|
||||||
acpi_evalf(bay_handle, NULL, "_STA", "qv");
|
|
||||||
tp_features.bay_status2 = bay2_handle &&
|
|
||||||
acpi_evalf(bay2_handle, NULL, "_STA", "qv");
|
|
||||||
|
|
||||||
tp_features.bay_eject = bay_handle && bay_ej_handle &&
|
|
||||||
(strlencmp(bay_ej_path, "_EJ0") == 0 || experimental);
|
|
||||||
tp_features.bay_eject2 = bay2_handle && bay2_ej_handle &&
|
|
||||||
(strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
|
|
||||||
|
|
||||||
vdbg_printk(TPACPI_DBG_INIT,
|
|
||||||
"bay 1: status %s, eject %s; bay 2: status %s, eject %s\n",
|
|
||||||
str_supported(tp_features.bay_status),
|
|
||||||
str_supported(tp_features.bay_eject),
|
|
||||||
str_supported(tp_features.bay_status2),
|
|
||||||
str_supported(tp_features.bay_eject2));
|
|
||||||
|
|
||||||
return (tp_features.bay_status || tp_features.bay_eject ||
|
|
||||||
tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bay_notify(struct ibm_struct *ibm, u32 event)
|
|
||||||
{
|
|
||||||
acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
|
|
||||||
acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
|
|
||||||
dev_name(&ibm->acpi->device->dev),
|
|
||||||
event, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define bay_occupied(b) (_sta(b##_handle) & 1)
|
|
||||||
|
|
||||||
static int bay_read(char *p)
|
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
int occupied = bay_occupied(bay);
|
|
||||||
int occupied2 = bay_occupied(bay2);
|
|
||||||
int eject, eject2;
|
|
||||||
|
|
||||||
len += sprintf(p + len, "status:\t\t%s\n",
|
|
||||||
tp_features.bay_status ?
|
|
||||||
(occupied ? "occupied" : "unoccupied") :
|
|
||||||
"not supported");
|
|
||||||
if (tp_features.bay_status2)
|
|
||||||
len += sprintf(p + len, "status2:\t%s\n", occupied2 ?
|
|
||||||
"occupied" : "unoccupied");
|
|
||||||
|
|
||||||
eject = tp_features.bay_eject && occupied;
|
|
||||||
eject2 = tp_features.bay_eject2 && occupied2;
|
|
||||||
|
|
||||||
if (eject && eject2)
|
|
||||||
len += sprintf(p + len, "commands:\teject, eject2\n");
|
|
||||||
else if (eject)
|
|
||||||
len += sprintf(p + len, "commands:\teject\n");
|
|
||||||
else if (eject2)
|
|
||||||
len += sprintf(p + len, "commands:\teject2\n");
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bay_write(char *buf)
|
|
||||||
{
|
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
if (!tp_features.bay_eject && !tp_features.bay_eject2)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
while ((cmd = next_cmd(&buf))) {
|
|
||||||
if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) {
|
|
||||||
if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1))
|
|
||||||
return -EIO;
|
|
||||||
} else if (tp_features.bay_eject2 &&
|
|
||||||
strlencmp(cmd, "eject2") == 0) {
|
|
||||||
if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1))
|
|
||||||
return -EIO;
|
|
||||||
} else
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct tp_acpi_drv_struct ibm_bay_acpidriver = {
|
|
||||||
.notify = bay_notify,
|
|
||||||
.handle = &bay_handle,
|
|
||||||
.type = ACPI_SYSTEM_NOTIFY,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct ibm_struct bay_driver_data = {
|
|
||||||
.name = "bay",
|
|
||||||
.read = bay_read,
|
|
||||||
.write = bay_write,
|
|
||||||
.acpi = &ibm_bay_acpidriver,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* CONFIG_THINKPAD_ACPI_BAY */
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* CMOS subdriver
|
* CMOS subdriver
|
||||||
*/
|
*/
|
||||||
@@ -5945,14 +5642,48 @@ static struct backlight_ops ibm_backlight_data = {
|
|||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are only useful for models that have only one possibility
|
||||||
|
* of GPU. If the BIOS model handles both ATI and Intel, don't use
|
||||||
|
* these quirks.
|
||||||
|
*/
|
||||||
|
#define TPACPI_BRGHT_Q_NOEC 0x0001 /* Must NOT use EC HBRV */
|
||||||
|
#define TPACPI_BRGHT_Q_EC 0x0002 /* Should or must use EC HBRV */
|
||||||
|
#define TPACPI_BRGHT_Q_ASK 0x8000 /* Ask for user report */
|
||||||
|
|
||||||
|
static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
|
||||||
|
/* Models with ATI GPUs known to require ECNVRAM mode */
|
||||||
|
TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */
|
||||||
|
|
||||||
|
/* Models with ATI GPUs (waiting confirmation) */
|
||||||
|
TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
|
||||||
|
TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
|
||||||
|
TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
|
||||||
|
TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
|
||||||
|
|
||||||
|
/* Models with Intel Extreme Graphics 2 (waiting confirmation) */
|
||||||
|
TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
|
||||||
|
TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
|
||||||
|
TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
|
||||||
|
|
||||||
|
/* Models with Intel GMA900 */
|
||||||
|
TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */
|
||||||
|
TPACPI_Q_IBM('7', '4', TPACPI_BRGHT_Q_NOEC), /* X41 */
|
||||||
|
TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC), /* X41 Tablet */
|
||||||
|
};
|
||||||
|
|
||||||
static int __init brightness_init(struct ibm_init_struct *iibm)
|
static int __init brightness_init(struct ibm_init_struct *iibm)
|
||||||
{
|
{
|
||||||
int b;
|
int b;
|
||||||
|
unsigned long quirks;
|
||||||
|
|
||||||
vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
|
vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
|
||||||
|
|
||||||
mutex_init(&brightness_mutex);
|
mutex_init(&brightness_mutex);
|
||||||
|
|
||||||
|
quirks = tpacpi_check_quirks(brightness_quirk_table,
|
||||||
|
ARRAY_SIZE(brightness_quirk_table));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We always attempt to detect acpi support, so as to switch
|
* We always attempt to detect acpi support, so as to switch
|
||||||
* Lenovo Vista BIOS to ACPI brightness mode even if we are not
|
* 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)
|
|||||||
/* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
|
/* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
|
||||||
if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
|
if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
|
||||||
brightness_mode == TPACPI_BRGHT_MODE_MAX) {
|
brightness_mode == TPACPI_BRGHT_MODE_MAX) {
|
||||||
if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
|
if (quirks & TPACPI_BRGHT_Q_EC)
|
||||||
/*
|
brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
|
||||||
* IBM models that define HBRV probably have
|
else
|
||||||
* EC-based backlight level control
|
|
||||||
*/
|
|
||||||
if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
|
|
||||||
/* T40-T43, R50-R52, R50e, R51e, X31-X41 */
|
|
||||||
brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
|
|
||||||
else
|
|
||||||
/* all other IBM ThinkPads */
|
|
||||||
brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
|
|
||||||
} else
|
|
||||||
/* All Lenovo ThinkPads */
|
|
||||||
brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
|
brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
|
||||||
|
|
||||||
dbg_printk(TPACPI_DBG_BRGHT,
|
dbg_printk(TPACPI_DBG_BRGHT,
|
||||||
"selected brightness_mode=%d\n",
|
"driver auto-selected brightness_mode=%d\n",
|
||||||
brightness_mode);
|
brightness_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6052,6 +5773,15 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
|
|||||||
vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
|
vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
|
||||||
"brightness is supported\n");
|
"brightness is supported\n");
|
||||||
|
|
||||||
|
if (quirks & TPACPI_BRGHT_Q_ASK) {
|
||||||
|
printk(TPACPI_NOTICE
|
||||||
|
"brightness: will use unverified default: "
|
||||||
|
"brightness_mode=%d\n", brightness_mode);
|
||||||
|
printk(TPACPI_NOTICE
|
||||||
|
"brightness: please report to %s whether it works well "
|
||||||
|
"or not on your ThinkPad\n", TPACPI_MAIL);
|
||||||
|
}
|
||||||
|
|
||||||
ibm_backlight_device->props.max_brightness =
|
ibm_backlight_device->props.max_brightness =
|
||||||
(tp_features.bright_16levels)? 15 : 7;
|
(tp_features.bright_16levels)? 15 : 7;
|
||||||
ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
|
ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
|
||||||
@@ -7854,22 +7584,6 @@ static struct ibm_init_struct ibms_init[] __initdata = {
|
|||||||
.init = light_init,
|
.init = light_init,
|
||||||
.data = &light_driver_data,
|
.data = &light_driver_data,
|
||||||
},
|
},
|
||||||
#ifdef CONFIG_THINKPAD_ACPI_DOCK
|
|
||||||
{
|
|
||||||
.init = dock_init,
|
|
||||||
.data = &dock_driver_data[0],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.init = dock_init2,
|
|
||||||
.data = &dock_driver_data[1],
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_THINKPAD_ACPI_BAY
|
|
||||||
{
|
|
||||||
.init = bay_init,
|
|
||||||
.data = &bay_driver_data,
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
.init = cmos_init,
|
.init = cmos_init,
|
||||||
.data = &cmos_driver_data,
|
.data = &cmos_driver_data,
|
||||||
@@ -7968,12 +7682,6 @@ TPACPI_PARAM(hotkey);
|
|||||||
TPACPI_PARAM(bluetooth);
|
TPACPI_PARAM(bluetooth);
|
||||||
TPACPI_PARAM(video);
|
TPACPI_PARAM(video);
|
||||||
TPACPI_PARAM(light);
|
TPACPI_PARAM(light);
|
||||||
#ifdef CONFIG_THINKPAD_ACPI_DOCK
|
|
||||||
TPACPI_PARAM(dock);
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_THINKPAD_ACPI_BAY
|
|
||||||
TPACPI_PARAM(bay);
|
|
||||||
#endif /* CONFIG_THINKPAD_ACPI_BAY */
|
|
||||||
TPACPI_PARAM(cmos);
|
TPACPI_PARAM(cmos);
|
||||||
TPACPI_PARAM(led);
|
TPACPI_PARAM(led);
|
||||||
TPACPI_PARAM(beep);
|
TPACPI_PARAM(beep);
|
||||||
|
@@ -242,6 +242,10 @@ acpi_os_derive_pci_id(acpi_handle rhandle,
|
|||||||
acpi_status acpi_os_validate_interface(char *interface);
|
acpi_status acpi_os_validate_interface(char *interface);
|
||||||
acpi_status acpi_osi_invalidate(char* interface);
|
acpi_status acpi_osi_invalidate(char* interface);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_os_validate_address(u8 space_id, acpi_physical_address address,
|
||||||
|
acpi_size length, char *name);
|
||||||
|
|
||||||
u64 acpi_os_get_timer(void);
|
u64 acpi_os_get_timer(void);
|
||||||
|
|
||||||
acpi_status acpi_os_signal(u32 function, void *info);
|
acpi_status acpi_os_signal(u32 function, void *info);
|
||||||
|
Reference in New Issue
Block a user