提交 f12b12a8 编写于 作者: L Linus Torvalds

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: (30 commits)
  ACPI: Kconfig text - Fix the ACPI_CONTAINER module name according to the real module name.
  eeepc-laptop: fix oops when changing backlight brightness during eeepc-laptop init
  ACPICA: Fix table entry truncation calculation
  ACPI: Enable bit 11 in _PDC to advertise hw coord
  ACPI: struct device - replace bus_id with dev_name(), dev_set_name()
  ACPI: add missing KERN_* constants to printks
  ACPI: dock: Don't eval _STA on every show_docked sysfs read
  ACPI: disable ACPI cleanly when bad RSDP found
  ACPI: delete CPU_IDLE=n code
  ACPI: cpufreq: Remove deprecated /proc/acpi/processor/../performance proc entries
  ACPI: make some IO ports off-limits to AML
  ACPICA: add debug dump of BIOS _OSI strings
  ACPI: proc_dir_entry 'video/VGA' already registered
  ACPI: Skip the first two elements in the _BCL package
  ACPI: remove BM_RLD access from idle entry path
  ACPI: remove locking from PM1x_STS register reads
  eeepc-laptop: use netlink interface
  eeepc-laptop: Implement rfkill hotplugging in eeepc-laptop
  eeepc-laptop: Check return values from rfkill_register
  eeepc-laptop: Add support for extended hotkeys
  ...
...@@ -195,19 +195,3 @@ scaling_setspeed. By "echoing" a new frequency into this ...@@ -195,19 +195,3 @@ scaling_setspeed. By "echoing" a new frequency into this
you can change the speed of the CPU, you can change the speed of the CPU,
but only within the limits of but only within the limits of
scaling_min_freq and scaling_max_freq. scaling_min_freq and scaling_max_freq.
3.2 Deprecated Interfaces
-------------------------
Depending on your kernel configuration, you might find the following
cpufreq-related files:
/proc/cpufreq
/proc/sys/cpu/*/speed
/proc/sys/cpu/*/speed-min
/proc/sys/cpu/*/speed-max
These are files for deprecated interfaces to cpufreq, which offer far
less functionality. Because of this, these interfaces aren't described
here.
...@@ -156,11 +156,11 @@ static int __init acpi_sleep_setup(char *str) ...@@ -156,11 +156,11 @@ static int __init acpi_sleep_setup(char *str)
#ifdef CONFIG_HIBERNATION #ifdef CONFIG_HIBERNATION
if (strncmp(str, "s4_nohwsig", 10) == 0) if (strncmp(str, "s4_nohwsig", 10) == 0)
acpi_no_s4_hw_signature(); acpi_no_s4_hw_signature();
if (strncmp(str, "s4_nonvs", 8) == 0)
acpi_s4_no_nvs();
#endif #endif
if (strncmp(str, "old_ordering", 12) == 0) if (strncmp(str, "old_ordering", 12) == 0)
acpi_old_suspend_ordering(); acpi_old_suspend_ordering();
if (strncmp(str, "s4_nonvs", 8) == 0)
acpi_s4_no_nvs();
str = strchr(str, ','); str = strchr(str, ',');
if (str != NULL) if (str != NULL)
str += strspn(str, ", \t"); str += strspn(str, ", \t");
......
...@@ -245,17 +245,6 @@ config X86_E_POWERSAVER ...@@ -245,17 +245,6 @@ config X86_E_POWERSAVER
comment "shared options" comment "shared options"
config X86_ACPI_CPUFREQ_PROC_INTF
bool "/proc/acpi/processor/../performance interface (deprecated)"
depends on PROC_FS
depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI
help
This enables the deprecated /proc/acpi/processor/../performance
interface. While it is helpful for debugging, the generic,
cross-architecture cpufreq interfaces should be used.
If in doubt, say N.
config X86_SPEEDSTEP_LIB config X86_SPEEDSTEP_LIB
tristate tristate
default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD)
......
...@@ -9,6 +9,7 @@ menuconfig ACPI ...@@ -9,6 +9,7 @@ menuconfig ACPI
depends on PCI depends on PCI
depends on PM depends on PM
select PNP select PNP
select CPU_IDLE
default y default y
---help--- ---help---
Advanced Configuration and Power Interface (ACPI) support for Advanced Configuration and Power Interface (ACPI) support for
...@@ -287,7 +288,7 @@ config ACPI_CONTAINER ...@@ -287,7 +288,7 @@ config ACPI_CONTAINER
support physical cpu/memory hot-plug. support physical cpu/memory hot-plug.
If one selects "m", this driver can be loaded with If one selects "m", this driver can be loaded with
"modprobe acpi_container". "modprobe container".
config ACPI_HOTPLUG_MEMORY config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug" tristate "Memory Hotplug"
......
...@@ -538,10 +538,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) ...@@ -538,10 +538,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_WARNING((AE_INFO, ACPI_WARNING((AE_INFO,
"Truncating %u table entries!", "Truncating %u table entries!",
(unsigned) (unsigned) (table_count -
(acpi_gbl_root_table_list.size - (acpi_gbl_root_table_list.
acpi_gbl_root_table_list. count - 2))));
count)));
break; break;
} }
} }
......
...@@ -116,9 +116,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) ...@@ -116,9 +116,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
/* Default return value is SUPPORTED */ /* Default return value is 0, NOT-SUPPORTED */
return_desc->integer.value = ACPI_UINT32_MAX; return_desc->integer.value = 0;
walk_state->return_desc = return_desc; walk_state->return_desc = return_desc;
/* Compare input string to static table of supported interfaces */ /* Compare input string to static table of supported interfaces */
...@@ -127,10 +127,8 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) ...@@ -127,10 +127,8 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
if (!ACPI_STRCMP if (!ACPI_STRCMP
(string_desc->string.pointer, (string_desc->string.pointer,
acpi_interfaces_supported[i])) { acpi_interfaces_supported[i])) {
return_desc->integer.value = ACPI_UINT32_MAX;
/* The interface is supported */ goto done;
return_ACPI_STATUS(AE_OK);
} }
} }
...@@ -141,15 +139,14 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) ...@@ -141,15 +139,14 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
*/ */
status = acpi_os_validate_interface(string_desc->string.pointer); status = acpi_os_validate_interface(string_desc->string.pointer);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
return_desc->integer.value = ACPI_UINT32_MAX;
/* The interface is supported */
return_ACPI_STATUS(AE_OK);
} }
/* The interface is not supported */ done:
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
string_desc->string.pointer,
return_desc->integer.value == 0 ? "not-" : ""));
return_desc->integer.value = 0;
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
......
...@@ -163,7 +163,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) ...@@ -163,7 +163,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_BUS_CHECK:
/* Fall through */ /* Fall through */
case ACPI_NOTIFY_DEVICE_CHECK: case ACPI_NOTIFY_DEVICE_CHECK:
printk("Container driver received %s event\n", printk(KERN_WARNING "Container driver received %s event\n",
(type == ACPI_NOTIFY_BUS_CHECK) ? (type == ACPI_NOTIFY_BUS_CHECK) ?
"ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
status = acpi_bus_get_device(handle, &device); status = acpi_bus_get_device(handle, &device);
...@@ -174,7 +174,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) ...@@ -174,7 +174,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
kobject_uevent(&device->dev.kobj, kobject_uevent(&device->dev.kobj,
KOBJ_ONLINE); KOBJ_ONLINE);
else else
printk("Failed to add container\n"); printk(KERN_WARNING
"Failed to add container\n");
} }
} else { } else {
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
......
...@@ -855,10 +855,14 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) ...@@ -855,10 +855,14 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
static ssize_t show_docked(struct device *dev, static ssize_t show_docked(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct acpi_device *tmp;
struct dock_station *dock_station = *((struct dock_station **) struct dock_station *dock_station = *((struct dock_station **)
dev->platform_data); dev->platform_data);
return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp)))
return snprintf(buf, PAGE_SIZE, "1\n");
return snprintf(buf, PAGE_SIZE, "0\n");
} }
static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
...@@ -984,7 +988,7 @@ static int dock_add(acpi_handle handle) ...@@ -984,7 +988,7 @@ static int dock_add(acpi_handle handle)
ret = device_create_file(&dock_device->dev, &dev_attr_docked); ret = device_create_file(&dock_device->dev, &dev_attr_docked);
if (ret) { if (ret) {
printk("Error %d adding sysfs file\n", ret); printk(KERN_ERR "Error %d adding sysfs file\n", ret);
platform_device_unregister(dock_device); platform_device_unregister(dock_device);
kfree(dock_station); kfree(dock_station);
dock_station = NULL; dock_station = NULL;
...@@ -992,7 +996,7 @@ static int dock_add(acpi_handle handle) ...@@ -992,7 +996,7 @@ static int dock_add(acpi_handle handle)
} }
ret = device_create_file(&dock_device->dev, &dev_attr_undock); ret = device_create_file(&dock_device->dev, &dev_attr_undock);
if (ret) { if (ret) {
printk("Error %d adding sysfs file\n", ret); printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked); device_remove_file(&dock_device->dev, &dev_attr_docked);
platform_device_unregister(dock_device); platform_device_unregister(dock_device);
kfree(dock_station); kfree(dock_station);
...@@ -1001,7 +1005,7 @@ static int dock_add(acpi_handle handle) ...@@ -1001,7 +1005,7 @@ static int dock_add(acpi_handle handle)
} }
ret = device_create_file(&dock_device->dev, &dev_attr_uid); ret = device_create_file(&dock_device->dev, &dev_attr_uid);
if (ret) { if (ret) {
printk("Error %d adding sysfs file\n", ret); printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked); device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock); device_remove_file(&dock_device->dev, &dev_attr_undock);
platform_device_unregister(dock_device); platform_device_unregister(dock_device);
...@@ -1011,7 +1015,7 @@ static int dock_add(acpi_handle handle) ...@@ -1011,7 +1015,7 @@ static int dock_add(acpi_handle handle)
} }
ret = device_create_file(&dock_device->dev, &dev_attr_flags); ret = device_create_file(&dock_device->dev, &dev_attr_flags);
if (ret) { if (ret) {
printk("Error %d adding sysfs file\n", ret); printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked); device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock); device_remove_file(&dock_device->dev, &dev_attr_undock);
device_remove_file(&dock_device->dev, &dev_attr_uid); device_remove_file(&dock_device->dev, &dev_attr_uid);
......
...@@ -982,7 +982,7 @@ int __init acpi_ec_ecdt_probe(void) ...@@ -982,7 +982,7 @@ int __init acpi_ec_ecdt_probe(void)
saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!saved_ec) if (!saved_ec)
return -ENOMEM; return -ENOMEM;
memcpy(&saved_ec, boot_ec, sizeof(saved_ec)); memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
/* fall through */ /* fall through */
} }
/* This workaround is needed only on some broken machines, /* This workaround is needed only on some broken machines,
......
...@@ -255,12 +255,12 @@ static int acpi_platform_notify(struct device *dev) ...@@ -255,12 +255,12 @@ static int acpi_platform_notify(struct device *dev)
} }
type = acpi_get_bus_type(dev->bus); type = acpi_get_bus_type(dev->bus);
if (!type) { if (!type) {
DBG("No ACPI bus support for %s\n", dev->bus_id); DBG("No ACPI bus support for %s\n", dev_name(dev));
ret = -EINVAL; ret = -EINVAL;
goto end; goto end;
} }
if ((ret = type->find_device(dev, &handle)) != 0) if ((ret = type->find_device(dev, &handle)) != 0)
DBG("Can't get handler for %s\n", dev->bus_id); DBG("Can't get handler for %s\n", dev_name(dev));
end: end:
if (!ret) if (!ret)
acpi_bind_one(dev, handle); acpi_bind_one(dev, handle);
...@@ -271,10 +271,10 @@ static int acpi_platform_notify(struct device *dev) ...@@ -271,10 +271,10 @@ static int acpi_platform_notify(struct device *dev)
acpi_get_name(dev->archdata.acpi_handle, acpi_get_name(dev->archdata.acpi_handle,
ACPI_FULL_PATHNAME, &buffer); ACPI_FULL_PATHNAME, &buffer);
DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
kfree(buffer.pointer); kfree(buffer.pointer);
} else } else
DBG("Device %s -> No ACPI support\n", dev->bus_id); DBG("Device %s -> No ACPI support\n", dev_name(dev));
#endif #endif
return ret; return ret;
......
...@@ -228,10 +228,10 @@ void acpi_os_vprintf(const char *fmt, va_list args) ...@@ -228,10 +228,10 @@ void acpi_os_vprintf(const char *fmt, va_list args)
if (acpi_in_debugger) { if (acpi_in_debugger) {
kdb_printf("%s", buffer); kdb_printf("%s", buffer);
} else { } else {
printk("%s", buffer); printk(KERN_CONT "%s", buffer);
} }
#else #else
printk("%s", buffer); printk(KERN_CONT "%s", buffer);
#endif #endif
} }
...@@ -1317,6 +1317,54 @@ acpi_os_validate_interface (char *interface) ...@@ -1317,6 +1317,54 @@ acpi_os_validate_interface (char *interface)
return AE_SUPPORT; return AE_SUPPORT;
} }
#ifdef CONFIG_X86
struct aml_port_desc {
uint start;
uint end;
char* name;
char warned;
};
static struct aml_port_desc aml_invalid_port_list[] = {
{0x20, 0x21, "PIC0", 0},
{0xA0, 0xA1, "PIC1", 0},
{0x4D0, 0x4D1, "ELCR", 0}
};
/*
* valid_aml_io_address()
*
* if valid, return true
* else invalid, warn once, return false
*/
static bool valid_aml_io_address(uint address, uint length)
{
int i;
int entries = sizeof(aml_invalid_port_list) / sizeof(struct aml_port_desc);
for (i = 0; i < entries; ++i) {
if ((address >= aml_invalid_port_list[i].start &&
address <= aml_invalid_port_list[i].end) ||
(address + length >= aml_invalid_port_list[i].start &&
address + length <= aml_invalid_port_list[i].end))
{
if (!aml_invalid_port_list[i].warned)
{
printk(KERN_ERR "ACPI: Denied BIOS AML access"
" to invalid port 0x%x+0x%x (%s)\n",
address, length,
aml_invalid_port_list[i].name);
aml_invalid_port_list[i].warned = 1;
}
return false; /* invalid */
}
}
return true; /* valid */
}
#else
static inline bool valid_aml_io_address(uint address, uint length) { return true; }
#endif
/****************************************************************************** /******************************************************************************
* *
* FUNCTION: acpi_os_validate_address * FUNCTION: acpi_os_validate_address
...@@ -1346,6 +1394,8 @@ acpi_os_validate_address ( ...@@ -1346,6 +1394,8 @@ acpi_os_validate_address (
switch (space_id) { switch (space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO: case ACPI_ADR_SPACE_SYSTEM_IO:
if (!valid_aml_io_address(address, length))
return AE_AML_ILLEGAL_ADDRESS;
case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_MEMORY:
/* Only interference checks against SystemIO and SytemMemory /* Only interference checks against SystemIO and SytemMemory
are needed */ are needed */
......
...@@ -593,7 +593,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) ...@@ -593,7 +593,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
return -ENODEV; return -ENODEV;
} else { } else {
acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
printk(PREFIX "%s [%s] enabled at IRQ %d\n", printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
acpi_device_name(link->device), acpi_device_name(link->device),
acpi_device_bid(link->device), link->irq.active); acpi_device_bid(link->device), link->irq.active);
} }
......
此差异已折叠。
...@@ -31,14 +31,6 @@ ...@@ -31,14 +31,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#endif
#ifdef CONFIG_X86 #ifdef CONFIG_X86
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#endif #endif
...@@ -434,96 +426,6 @@ int acpi_processor_notify_smm(struct module *calling_module) ...@@ -434,96 +426,6 @@ int acpi_processor_notify_smm(struct module *calling_module)
EXPORT_SYMBOL(acpi_processor_notify_smm); EXPORT_SYMBOL(acpi_processor_notify_smm);
#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
/* /proc/acpi/processor/../performance interface (DEPRECATED) */
static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
static struct file_operations acpi_processor_perf_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_perf_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_processor *pr = seq->private;
int i;
if (!pr)
goto end;
if (!pr->performance) {
seq_puts(seq, "<not supported>\n");
goto end;
}
seq_printf(seq, "state count: %d\n"
"active state: P%d\n",
pr->performance->state_count, pr->performance->state);
seq_puts(seq, "states:\n");
for (i = 0; i < pr->performance->state_count; i++)
seq_printf(seq,
" %cP%d: %d MHz, %d mW, %d uS\n",
(i == pr->performance->state ? '*' : ' '), i,
(u32) pr->performance->states[i].core_frequency,
(u32) pr->performance->states[i].power,
(u32) pr->performance->states[i].transition_latency);
end:
return 0;
}
static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_perf_seq_show,
PDE(inode)->data);
}
static void acpi_cpufreq_add_file(struct acpi_processor *pr)
{
struct acpi_device *device = NULL;
if (acpi_bus_get_device(pr->handle, &device))
return;
/* add file 'performance' [R/W] */
proc_create_data(ACPI_PROCESSOR_FILE_PERFORMANCE, S_IFREG | S_IRUGO,
acpi_device_dir(device),
&acpi_processor_perf_fops, acpi_driver_data(device));
return;
}
static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
{
struct acpi_device *device = NULL;
if (acpi_bus_get_device(pr->handle, &device))
return;
/* remove file 'performance' */
remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
acpi_device_dir(device));
return;
}
#else
static void acpi_cpufreq_add_file(struct acpi_processor *pr)
{
return;
}
static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
{
return;
}
#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
static int acpi_processor_get_psd(struct acpi_processor *pr) static int acpi_processor_get_psd(struct acpi_processor *pr)
{ {
int result = 0; int result = 0;
...@@ -747,14 +649,12 @@ int acpi_processor_preregister_performance( ...@@ -747,14 +649,12 @@ int acpi_processor_preregister_performance(
} }
EXPORT_SYMBOL(acpi_processor_preregister_performance); EXPORT_SYMBOL(acpi_processor_preregister_performance);
int int
acpi_processor_register_performance(struct acpi_processor_performance acpi_processor_register_performance(struct acpi_processor_performance
*performance, unsigned int cpu) *performance, unsigned int cpu)
{ {
struct acpi_processor *pr; struct acpi_processor *pr;
if (!(acpi_processor_ppc_status & PPC_REGISTERED)) if (!(acpi_processor_ppc_status & PPC_REGISTERED))
return -EINVAL; return -EINVAL;
...@@ -781,8 +681,6 @@ acpi_processor_register_performance(struct acpi_processor_performance ...@@ -781,8 +681,6 @@ acpi_processor_register_performance(struct acpi_processor_performance
return -EIO; return -EIO;
} }
acpi_cpufreq_add_file(pr);
mutex_unlock(&performance_mutex); mutex_unlock(&performance_mutex);
return 0; return 0;
} }
...@@ -795,7 +693,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance ...@@ -795,7 +693,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
{ {
struct acpi_processor *pr; struct acpi_processor *pr;
mutex_lock(&performance_mutex); mutex_lock(&performance_mutex);
pr = per_cpu(processors, cpu); pr = per_cpu(processors, cpu);
...@@ -808,8 +705,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance ...@@ -808,8 +705,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
kfree(pr->performance->states); kfree(pr->performance->states);
pr->performance = NULL; pr->performance = NULL;
acpi_cpufreq_remove_file(pr);
mutex_unlock(&performance_mutex); mutex_unlock(&performance_mutex);
return; return;
......
...@@ -90,31 +90,6 @@ void __init acpi_old_suspend_ordering(void) ...@@ -90,31 +90,6 @@ void __init acpi_old_suspend_ordering(void)
old_suspend_ordering = true; old_suspend_ordering = true;
} }
/*
* According to the ACPI specification the BIOS should make sure that ACPI is
* enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
* some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
* on such systems during resume. Unfortunately that doesn't help in
* particularly pathological cases in which SCI_EN has to be set directly on
* resume, although the specification states very clearly that this flag is
* owned by the hardware. The set_sci_en_on_resume variable will be set in such
* cases.
*/
static bool set_sci_en_on_resume;
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. However, it is not certain
* if this mechanism is going to work on all machines, so we allow the user to
* disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
* option.
*/
static bool s4_no_nvs;
void __init acpi_s4_no_nvs(void)
{
s4_no_nvs = true;
}
/** /**
* acpi_pm_disable_gpes - Disable the GPEs. * acpi_pm_disable_gpes - Disable the GPEs.
*/ */
...@@ -193,6 +168,18 @@ static void acpi_pm_end(void) ...@@ -193,6 +168,18 @@ static void acpi_pm_end(void)
#endif /* CONFIG_ACPI_SLEEP */ #endif /* CONFIG_ACPI_SLEEP */
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
/*
* According to the ACPI specification the BIOS should make sure that ACPI is
* enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
* some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
* on such systems during resume. Unfortunately that doesn't help in
* particularly pathological cases in which SCI_EN has to be set directly on
* resume, although the specification states very clearly that this flag is
* owned by the hardware. The set_sci_en_on_resume variable will be set in such
* cases.
*/
static bool set_sci_en_on_resume;
extern void do_suspend_lowlevel(void); extern void do_suspend_lowlevel(void);
static u32 acpi_suspend_states[] = { static u32 acpi_suspend_states[] = {
...@@ -396,6 +383,20 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { ...@@ -396,6 +383,20 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
#endif /* CONFIG_SUSPEND */ #endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION #ifdef CONFIG_HIBERNATION
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. However, it is not certain
* if this mechanism is going to work on all machines, so we allow the user to
* disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
* option.
*/
static bool s4_no_nvs;
void __init acpi_s4_no_nvs(void)
{
s4_no_nvs = true;
}
static unsigned long s4_hardware_signature; static unsigned long s4_hardware_signature;
static struct acpi_table_facs *facs; static struct acpi_table_facs *facs;
static bool nosigcheck; static bool nosigcheck;
...@@ -679,7 +680,7 @@ static void acpi_power_off_prepare(void) ...@@ -679,7 +680,7 @@ static void acpi_power_off_prepare(void)
static void acpi_power_off(void) static void acpi_power_off(void)
{ {
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
printk("%s called\n", __func__); printk(KERN_DEBUG "%s called\n", __func__);
local_irq_disable(); local_irq_disable();
acpi_enable_wakeup_device(ACPI_STATE_S5); acpi_enable_wakeup_device(ACPI_STATE_S5);
acpi_enter_sleep_state(ACPI_STATE_S5); acpi_enter_sleep_state(ACPI_STATE_S5);
......
...@@ -293,7 +293,12 @@ static void __init check_multiple_madt(void) ...@@ -293,7 +293,12 @@ static void __init check_multiple_madt(void)
int __init acpi_table_init(void) int __init acpi_table_init(void)
{ {
acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); acpi_status status;
status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
if (ACPI_FAILURE(status))
return 1;
check_multiple_madt(); check_multiple_madt();
return 0; return 0;
} }
......
...@@ -1020,7 +1020,7 @@ acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) ...@@ -1020,7 +1020,7 @@ acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
} }
seq_printf(seq, "levels: "); seq_printf(seq, "levels: ");
for (i = 0; i < dev->brightness->count; i++) for (i = 2; i < dev->brightness->count; i++)
seq_printf(seq, " %d", dev->brightness->levels[i]); seq_printf(seq, " %d", dev->brightness->levels[i]);
seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
...@@ -1059,7 +1059,7 @@ acpi_video_device_write_brightness(struct file *file, ...@@ -1059,7 +1059,7 @@ acpi_video_device_write_brightness(struct file *file,
return -EFAULT; return -EFAULT;
/* validate through the list of available levels */ /* validate through the list of available levels */
for (i = 0; i < dev->brightness->count; i++) for (i = 2; i < dev->brightness->count; i++)
if (level == dev->brightness->levels[i]) { if (level == dev->brightness->levels[i]) {
if (ACPI_SUCCESS if (ACPI_SUCCESS
(acpi_video_device_lcd_set_level(dev, level))) (acpi_video_device_lcd_set_level(dev, level)))
...@@ -1260,7 +1260,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) ...@@ -1260,7 +1260,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
printk(KERN_WARNING PREFIX printk(KERN_WARNING PREFIX
"This indicates a BIOS bug. Please contact the manufacturer.\n"); "This indicates a BIOS bug. Please contact the manufacturer.\n");
} }
printk("%llx\n", options); printk(KERN_WARNING "%llx\n", options);
seq_printf(seq, "can POST: <integrated video>"); seq_printf(seq, "can POST: <integrated video>");
if (options & 2) if (options & 2)
seq_printf(seq, " <PCI video>"); seq_printf(seq, " <PCI video>");
...@@ -1712,7 +1712,7 @@ acpi_video_get_next_level(struct acpi_video_device *device, ...@@ -1712,7 +1712,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
max = max_below = 0; max = max_below = 0;
min = min_above = 255; min = min_above = 255;
/* Find closest level to level_current */ /* Find closest level to level_current */
for (i = 0; i < device->brightness->count; i++) { for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i]; l = device->brightness->levels[i];
if (abs(l - level_current) < abs(delta)) { if (abs(l - level_current) < abs(delta)) {
delta = l - level_current; delta = l - level_current;
...@@ -1722,7 +1722,7 @@ acpi_video_get_next_level(struct acpi_video_device *device, ...@@ -1722,7 +1722,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
} }
/* Ajust level_current to closest available level */ /* Ajust level_current to closest available level */
level_current += delta; level_current += delta;
for (i = 0; i < device->brightness->count; i++) { for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i]; l = device->brightness->levels[i];
if (l < min) if (l < min)
min = l; min = l;
...@@ -2006,6 +2006,12 @@ static int acpi_video_bus_add(struct acpi_device *device) ...@@ -2006,6 +2006,12 @@ static int acpi_video_bus_add(struct acpi_device *device)
device->pnp.bus_id[3] = '0' + instance; device->pnp.bus_id[3] = '0' + instance;
instance ++; instance ++;
} }
/* a hack to fix the duplicate name "VGA" problem on Pa 3553 */
if (!strcmp(device->pnp.bus_id, "VGA")) {
if (instance)
device->pnp.bus_id[3] = '0' + instance;
instance++;
}
video->device = device; video->device = device;
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
......
...@@ -42,6 +42,7 @@ config ASUS_LAPTOP ...@@ -42,6 +42,7 @@ config ASUS_LAPTOP
depends on LEDS_CLASS depends on LEDS_CLASS
depends on NEW_LEDS depends on NEW_LEDS
depends on BACKLIGHT_CLASS_DEVICE depends on BACKLIGHT_CLASS_DEVICE
depends on INPUT
---help--- ---help---
This is the new Linux driver for Asus laptops. It may also support some This is the new Linux driver for Asus laptops. It may also support some
MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/input.h>
#define ASUS_LAPTOP_VERSION "0.42" #define ASUS_LAPTOP_VERSION "0.42"
...@@ -181,6 +182,8 @@ struct asus_hotk { ...@@ -181,6 +182,8 @@ struct asus_hotk {
u8 light_level; //light sensor level u8 light_level; //light sensor level
u8 light_switch; //light sensor switch value u8 light_switch; //light sensor switch value
u16 event_count[128]; //count for each event TODO make this better u16 event_count[128]; //count for each event TODO make this better
struct input_dev *inputdev;
u16 *keycode_map;
}; };
/* /*
...@@ -250,6 +253,37 @@ ASUS_LED(rled, "record"); ...@@ -250,6 +253,37 @@ ASUS_LED(rled, "record");
ASUS_LED(pled, "phone"); ASUS_LED(pled, "phone");
ASUS_LED(gled, "gaming"); ASUS_LED(gled, "gaming");
struct key_entry {
char type;
u8 code;
u16 keycode;
};
enum { KE_KEY, KE_END };
static struct key_entry asus_keymap[] = {
{KE_KEY, 0x30, KEY_VOLUMEUP},
{KE_KEY, 0x31, KEY_VOLUMEDOWN},
{KE_KEY, 0x32, KEY_MUTE},
{KE_KEY, 0x33, KEY_SWITCHVIDEOMODE},
{KE_KEY, 0x34, KEY_SWITCHVIDEOMODE},
{KE_KEY, 0x40, KEY_PREVIOUSSONG},
{KE_KEY, 0x41, KEY_NEXTSONG},
{KE_KEY, 0x43, KEY_STOP},
{KE_KEY, 0x45, KEY_PLAYPAUSE},
{KE_KEY, 0x50, KEY_EMAIL},
{KE_KEY, 0x51, KEY_WWW},
{KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */
{KE_KEY, 0x5D, KEY_WLAN},
{KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
{KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */
{KE_KEY, 0x82, KEY_CAMERA},
{KE_KEY, 0x8A, KEY_TV},
{KE_KEY, 0x95, KEY_MEDIA},
{KE_KEY, 0x99, KEY_PHONE},
{KE_END, 0},
};
/* /*
* This function evaluates an ACPI method, given an int as parameter, the * This function evaluates an ACPI method, given an int as parameter, the
* method is searched within the scope of the handle, can be NULL. The output * method is searched within the scope of the handle, can be NULL. The output
...@@ -720,8 +754,68 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr, ...@@ -720,8 +754,68 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr,
return store_status(buf, count, NULL, GPS_ON); return store_status(buf, count, NULL, GPS_ON);
} }
/*
* Hotkey functions
*/
static struct key_entry *asus_get_entry_by_scancode(int code)
{
struct key_entry *key;
for (key = asus_keymap; key->type != KE_END; key++)
if (code == key->code)
return key;
return NULL;
}
static struct key_entry *asus_get_entry_by_keycode(int code)
{
struct key_entry *key;
for (key = asus_keymap; key->type != KE_END; key++)
if (code == key->keycode && key->type == KE_KEY)
return key;
return NULL;
}
static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode)
{
struct key_entry *key = asus_get_entry_by_scancode(scancode);
if (key && key->type == KE_KEY) {
*keycode = key->keycode;
return 0;
}
return -EINVAL;
}
static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
{
struct key_entry *key;
int old_keycode;
if (keycode < 0 || keycode > KEY_MAX)
return -EINVAL;
key = asus_get_entry_by_scancode(scancode);
if (key && key->type == KE_KEY) {
old_keycode = key->keycode;
key->keycode = keycode;
set_bit(keycode, dev->keybit);
if (!asus_get_entry_by_keycode(old_keycode))
clear_bit(old_keycode, dev->keybit);
return 0;
}
return -EINVAL;
}
static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
{ {
static struct key_entry *key;
/* TODO Find a better way to handle events count. */ /* TODO Find a better way to handle events count. */
if (!hotk) if (!hotk)
return; return;
...@@ -738,10 +832,24 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) ...@@ -738,10 +832,24 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
lcd_blank(FB_BLANK_POWERDOWN); lcd_blank(FB_BLANK_POWERDOWN);
} }
acpi_bus_generate_proc_event(hotk->device, event, acpi_bus_generate_netlink_event(hotk->device->pnp.device_class,
dev_name(&hotk->device->dev), event,
hotk->event_count[event % 128]++); hotk->event_count[event % 128]++);
return; if (hotk->inputdev) {
key = asus_get_entry_by_scancode(event);
if (!key)
return ;
switch (key->type) {
case KE_KEY:
input_report_key(hotk->inputdev, key->keycode, 1);
input_sync(hotk->inputdev);
input_report_key(hotk->inputdev, key->keycode, 0);
input_sync(hotk->inputdev);
break;
}
}
} }
#define ASUS_CREATE_DEVICE_ATTR(_name) \ #define ASUS_CREATE_DEVICE_ATTR(_name) \
...@@ -959,6 +1067,38 @@ static int asus_hotk_get_info(void) ...@@ -959,6 +1067,38 @@ static int asus_hotk_get_info(void)
return AE_OK; return AE_OK;
} }
static int asus_input_init(void)
{
const struct key_entry *key;
int result;
hotk->inputdev = input_allocate_device();
if (!hotk->inputdev) {
printk(ASUS_INFO "Unable to allocate input device\n");
return 0;
}
hotk->inputdev->name = "Asus Laptop extra buttons";
hotk->inputdev->phys = ASUS_HOTK_FILE "/input0";
hotk->inputdev->id.bustype = BUS_HOST;
hotk->inputdev->getkeycode = asus_getkeycode;
hotk->inputdev->setkeycode = asus_setkeycode;
for (key = asus_keymap; key->type != KE_END; key++) {
switch (key->type) {
case KE_KEY:
set_bit(EV_KEY, hotk->inputdev->evbit);
set_bit(key->keycode, hotk->inputdev->keybit);
break;
}
}
result = input_register_device(hotk->inputdev);
if (result) {
printk(ASUS_INFO "Unable to register input device\n");
input_free_device(hotk->inputdev);
}
return result;
}
static int asus_hotk_check(void) static int asus_hotk_check(void)
{ {
int result = 0; int result = 0;
...@@ -1044,7 +1184,7 @@ static int asus_hotk_add(struct acpi_device *device) ...@@ -1044,7 +1184,7 @@ static int asus_hotk_add(struct acpi_device *device)
/* GPS is on by default */ /* GPS is on by default */
write_status(NULL, 1, GPS_ON); write_status(NULL, 1, GPS_ON);
end: end:
if (result) { if (result) {
kfree(hotk->name); kfree(hotk->name);
kfree(hotk); kfree(hotk);
...@@ -1091,10 +1231,17 @@ static void asus_led_exit(void) ...@@ -1091,10 +1231,17 @@ static void asus_led_exit(void)
ASUS_LED_UNREGISTER(gled); ASUS_LED_UNREGISTER(gled);
} }
static void asus_input_exit(void)
{
if (hotk->inputdev)
input_unregister_device(hotk->inputdev);
}
static void __exit asus_laptop_exit(void) static void __exit asus_laptop_exit(void)
{ {
asus_backlight_exit(); asus_backlight_exit();
asus_led_exit(); asus_led_exit();
asus_input_exit();
acpi_bus_unregister_driver(&asus_hotk_driver); acpi_bus_unregister_driver(&asus_hotk_driver);
sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group);
...@@ -1216,6 +1363,10 @@ static int __init asus_laptop_init(void) ...@@ -1216,6 +1363,10 @@ static int __init asus_laptop_init(void)
printk(ASUS_INFO "Brightness ignored, must be controlled by " printk(ASUS_INFO "Brightness ignored, must be controlled by "
"ACPI video driver\n"); "ACPI video driver\n");
result = asus_input_init();
if (result)
goto fail_input;
result = asus_led_init(dev); result = asus_led_init(dev);
if (result) if (result)
goto fail_led; goto fail_led;
...@@ -1242,22 +1393,25 @@ static int __init asus_laptop_init(void) ...@@ -1242,22 +1393,25 @@ static int __init asus_laptop_init(void)
return 0; return 0;
fail_sysfs: fail_sysfs:
platform_device_del(asuspf_device); platform_device_del(asuspf_device);
fail_platform_device2: fail_platform_device2:
platform_device_put(asuspf_device); platform_device_put(asuspf_device);
fail_platform_device1: fail_platform_device1:
platform_driver_unregister(&asuspf_driver); platform_driver_unregister(&asuspf_driver);
fail_platform_driver: fail_platform_driver:
asus_led_exit(); asus_led_exit();
fail_led: fail_led:
asus_input_exit();
fail_input:
asus_backlight_exit(); asus_backlight_exit();
fail_backlight: fail_backlight:
return result; return result;
} }
......
...@@ -143,6 +143,7 @@ struct asus_hotk { ...@@ -143,6 +143,7 @@ struct asus_hotk {
S1300N, S5200N*/ S1300N, S5200N*/
A4S, /* Z81sp */ A4S, /* Z81sp */
F3Sa, /* (Centrino) */ F3Sa, /* (Centrino) */
R1F,
END_MODEL END_MODEL
} model; /* Models currently supported */ } model; /* Models currently supported */
u16 event_count[128]; /* Count for each event TODO make this better */ u16 event_count[128]; /* Count for each event TODO make this better */
...@@ -420,7 +421,18 @@ static struct model_data model_conf[END_MODEL] = { ...@@ -420,7 +421,18 @@ static struct model_data model_conf[END_MODEL] = {
.display_get = "\\ADVG", .display_get = "\\ADVG",
.display_set = "SDSP", .display_set = "SDSP",
}, },
{
.name = "R1F",
.mt_bt_switch = "BLED",
.mt_mled = "MLED",
.mt_wled = "WLED",
.mt_lcd_switch = "\\Q10",
.lcd_status = "\\GP06",
.brightness_set = "SPLV",
.brightness_get = "GPLV",
.display_set = "SDSP",
.display_get = "\\INFB"
}
}; };
/* procdir we use */ /* procdir we use */
...@@ -1165,6 +1177,8 @@ static int asus_model_match(char *model) ...@@ -1165,6 +1177,8 @@ static int asus_model_match(char *model)
return W3V; return W3V;
else if (strncmp(model, "W5A", 3) == 0) else if (strncmp(model, "W5A", 3) == 0)
return W5A; return W5A;
else if (strncmp(model, "R1F", 3) == 0)
return R1F;
else if (strncmp(model, "A4S", 3) == 0) else if (strncmp(model, "A4S", 3) == 0)
return A4S; return A4S;
else if (strncmp(model, "F3Sa", 4) == 0) else if (strncmp(model, "F3Sa", 4) == 0)
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/rfkill.h> #include <linux/rfkill.h>
#include <linux/pci.h>
#define EEEPC_LAPTOP_VERSION "0.1" #define EEEPC_LAPTOP_VERSION "0.1"
...@@ -161,6 +162,10 @@ static struct key_entry eeepc_keymap[] = { ...@@ -161,6 +162,10 @@ static struct key_entry eeepc_keymap[] = {
{KE_KEY, 0x13, KEY_MUTE }, {KE_KEY, 0x13, KEY_MUTE },
{KE_KEY, 0x14, KEY_VOLUMEDOWN }, {KE_KEY, 0x14, KEY_VOLUMEDOWN },
{KE_KEY, 0x15, KEY_VOLUMEUP }, {KE_KEY, 0x15, KEY_VOLUMEUP },
{KE_KEY, 0x1a, KEY_COFFEE },
{KE_KEY, 0x1b, KEY_ZOOM },
{KE_KEY, 0x1c, KEY_PROG2 },
{KE_KEY, 0x1d, KEY_PROG3 },
{KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
...@@ -510,9 +515,45 @@ static int eeepc_hotk_check(void) ...@@ -510,9 +515,45 @@ static int eeepc_hotk_check(void)
static void notify_brn(void) static void notify_brn(void)
{ {
struct backlight_device *bd = eeepc_backlight_device; struct backlight_device *bd = eeepc_backlight_device;
if (bd)
bd->props.brightness = read_brightness(bd); bd->props.brightness = read_brightness(bd);
} }
static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
{
struct pci_dev *dev;
struct pci_bus *bus = pci_find_bus(0, 1);
if (event != ACPI_NOTIFY_BUS_CHECK)
return;
if (!bus) {
printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
return;
}
if (get_acpi(CM_ASL_WLAN) == 1) {
dev = pci_get_slot(bus, 0);
if (dev) {
/* Device already present */
pci_dev_put(dev);
return;
}
dev = pci_scan_single_device(bus, 0);
if (dev) {
pci_bus_assign_resources(bus);
if (pci_bus_add_device(dev))
printk(EEEPC_ERR "Unable to hotplug wifi\n");
}
} else {
dev = pci_get_slot(bus, 0);
if (dev) {
pci_remove_bus_device(dev);
pci_dev_put(dev);
}
}
}
static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
{ {
static struct key_entry *key; static struct key_entry *key;
...@@ -520,7 +561,8 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) ...@@ -520,7 +561,8 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
return; return;
if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
notify_brn(); notify_brn();
acpi_bus_generate_proc_event(ehotk->device, event, acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
dev_name(&ehotk->device->dev), event,
ehotk->event_count[event % 128]++); ehotk->event_count[event % 128]++);
if (ehotk->inputdev) { if (ehotk->inputdev) {
key = eepc_get_entry_by_scancode(event); key = eepc_get_entry_by_scancode(event);
...@@ -539,6 +581,45 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) ...@@ -539,6 +581,45 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
} }
} }
static int eeepc_register_rfkill_notifier(char *node)
{
acpi_status status = AE_OK;
acpi_handle handle;
status = acpi_get_handle(NULL, node, &handle);
if (ACPI_SUCCESS(status)) {
status = acpi_install_notify_handler(handle,
ACPI_SYSTEM_NOTIFY,
eeepc_rfkill_notify,
NULL);
if (ACPI_FAILURE(status))
printk(EEEPC_WARNING
"Failed to register notify on %s\n", node);
} else
return -ENODEV;
return 0;
}
static void eeepc_unregister_rfkill_notifier(char *node)
{
acpi_status status = AE_OK;
acpi_handle handle;
status = acpi_get_handle(NULL, node, &handle);
if (ACPI_SUCCESS(status)) {
status = acpi_remove_notify_handler(handle,
ACPI_SYSTEM_NOTIFY,
eeepc_rfkill_notify);
if (ACPI_FAILURE(status))
printk(EEEPC_ERR
"Error removing rfkill notify handler %s\n",
node);
}
}
static int eeepc_hotk_add(struct acpi_device *device) static int eeepc_hotk_add(struct acpi_device *device)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
...@@ -558,7 +639,7 @@ static int eeepc_hotk_add(struct acpi_device *device) ...@@ -558,7 +639,7 @@ static int eeepc_hotk_add(struct acpi_device *device)
ehotk->device = device; ehotk->device = device;
result = eeepc_hotk_check(); result = eeepc_hotk_check();
if (result) if (result)
goto end; goto ehotk_fail;
status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
eeepc_hotk_notify, ehotk); eeepc_hotk_notify, ehotk);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
...@@ -569,18 +650,25 @@ static int eeepc_hotk_add(struct acpi_device *device) ...@@ -569,18 +650,25 @@ static int eeepc_hotk_add(struct acpi_device *device)
RFKILL_TYPE_WLAN); RFKILL_TYPE_WLAN);
if (!ehotk->eeepc_wlan_rfkill) if (!ehotk->eeepc_wlan_rfkill)
goto end; goto wlan_fail;
ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
if (get_acpi(CM_ASL_WLAN) == 1) if (get_acpi(CM_ASL_WLAN) == 1) {
ehotk->eeepc_wlan_rfkill->state = ehotk->eeepc_wlan_rfkill->state =
RFKILL_STATE_UNBLOCKED; RFKILL_STATE_UNBLOCKED;
else rfkill_set_default(RFKILL_TYPE_WLAN,
RFKILL_STATE_UNBLOCKED);
} else {
ehotk->eeepc_wlan_rfkill->state = ehotk->eeepc_wlan_rfkill->state =
RFKILL_STATE_SOFT_BLOCKED; RFKILL_STATE_SOFT_BLOCKED;
rfkill_register(ehotk->eeepc_wlan_rfkill); rfkill_set_default(RFKILL_TYPE_WLAN,
RFKILL_STATE_SOFT_BLOCKED);
}
result = rfkill_register(ehotk->eeepc_wlan_rfkill);
if (result)
goto wlan_fail;
} }
if (get_acpi(CM_ASL_BLUETOOTH) != -1) { if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
...@@ -588,27 +676,47 @@ static int eeepc_hotk_add(struct acpi_device *device) ...@@ -588,27 +676,47 @@ static int eeepc_hotk_add(struct acpi_device *device)
rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
if (!ehotk->eeepc_bluetooth_rfkill) if (!ehotk->eeepc_bluetooth_rfkill)
goto end; goto bluetooth_fail;
ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
ehotk->eeepc_bluetooth_rfkill->toggle_radio = ehotk->eeepc_bluetooth_rfkill->toggle_radio =
eeepc_bluetooth_rfkill_set; eeepc_bluetooth_rfkill_set;
ehotk->eeepc_bluetooth_rfkill->get_state = ehotk->eeepc_bluetooth_rfkill->get_state =
eeepc_bluetooth_rfkill_state; eeepc_bluetooth_rfkill_state;
if (get_acpi(CM_ASL_BLUETOOTH) == 1) if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
ehotk->eeepc_bluetooth_rfkill->state = ehotk->eeepc_bluetooth_rfkill->state =
RFKILL_STATE_UNBLOCKED; RFKILL_STATE_UNBLOCKED;
else rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
RFKILL_STATE_UNBLOCKED);
} else {
ehotk->eeepc_bluetooth_rfkill->state = ehotk->eeepc_bluetooth_rfkill->state =
RFKILL_STATE_SOFT_BLOCKED; RFKILL_STATE_SOFT_BLOCKED;
rfkill_register(ehotk->eeepc_bluetooth_rfkill); rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
RFKILL_STATE_SOFT_BLOCKED);
} }
end: result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
if (result) { if (result)
goto bluetooth_fail;
}
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
return 0;
bluetooth_fail:
if (ehotk->eeepc_bluetooth_rfkill)
rfkill_free(ehotk->eeepc_bluetooth_rfkill);
rfkill_unregister(ehotk->eeepc_wlan_rfkill);
ehotk->eeepc_wlan_rfkill = NULL;
wlan_fail:
if (ehotk->eeepc_wlan_rfkill)
rfkill_free(ehotk->eeepc_wlan_rfkill);
ehotk_fail:
kfree(ehotk); kfree(ehotk);
ehotk = NULL; ehotk = NULL;
}
return result; return result;
} }
...@@ -622,6 +730,10 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) ...@@ -622,6 +730,10 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
eeepc_hotk_notify); eeepc_hotk_notify);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
printk(EEEPC_ERR "Error removing notify handler\n"); printk(EEEPC_ERR "Error removing notify handler\n");
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
kfree(ehotk); kfree(ehotk);
return 0; return 0;
} }
...@@ -737,13 +849,21 @@ static void eeepc_backlight_exit(void) ...@@ -737,13 +849,21 @@ static void eeepc_backlight_exit(void)
{ {
if (eeepc_backlight_device) if (eeepc_backlight_device)
backlight_device_unregister(eeepc_backlight_device); backlight_device_unregister(eeepc_backlight_device);
if (ehotk->inputdev) eeepc_backlight_device = NULL;
input_unregister_device(ehotk->inputdev); }
static void eeepc_rfkill_exit(void)
{
if (ehotk->eeepc_wlan_rfkill) if (ehotk->eeepc_wlan_rfkill)
rfkill_unregister(ehotk->eeepc_wlan_rfkill); rfkill_unregister(ehotk->eeepc_wlan_rfkill);
if (ehotk->eeepc_bluetooth_rfkill) if (ehotk->eeepc_bluetooth_rfkill)
rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
eeepc_backlight_device = NULL; }
static void eeepc_input_exit(void)
{
if (ehotk->inputdev)
input_unregister_device(ehotk->inputdev);
} }
static void eeepc_hwmon_exit(void) static void eeepc_hwmon_exit(void)
...@@ -762,6 +882,8 @@ static void eeepc_hwmon_exit(void) ...@@ -762,6 +882,8 @@ static void eeepc_hwmon_exit(void)
static void __exit eeepc_laptop_exit(void) static void __exit eeepc_laptop_exit(void)
{ {
eeepc_backlight_exit(); eeepc_backlight_exit();
eeepc_rfkill_exit();
eeepc_input_exit();
eeepc_hwmon_exit(); eeepc_hwmon_exit();
acpi_bus_unregister_driver(&eeepc_hotk_driver); acpi_bus_unregister_driver(&eeepc_hotk_driver);
sysfs_remove_group(&platform_device->dev.kobj, sysfs_remove_group(&platform_device->dev.kobj,
...@@ -865,6 +987,8 @@ static int __init eeepc_laptop_init(void) ...@@ -865,6 +987,8 @@ static int __init eeepc_laptop_init(void)
fail_hwmon: fail_hwmon:
eeepc_backlight_exit(); eeepc_backlight_exit();
fail_backlight: fail_backlight:
eeepc_input_exit();
eeepc_rfkill_exit();
return result; return result;
} }
......
...@@ -507,7 +507,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) ...@@ -507,7 +507,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
hkey_num = result & 0xf; hkey_num = result & 0xf;
if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) { if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"hotkey number out of range: %d\n", "hotkey number out of range: %d\n",
hkey_num)); hkey_num));
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#define ACPI_PDC_SMP_T_SWCOORD (0x0080) #define ACPI_PDC_SMP_T_SWCOORD (0x0080)
#define ACPI_PDC_C_C1_FFH (0x0100) #define ACPI_PDC_C_C1_FFH (0x0100)
#define ACPI_PDC_C_C2C3_FFH (0x0200) #define ACPI_PDC_C_C2C3_FFH (0x0200)
#define ACPI_PDC_SMP_P_HWCOORD (0x0800)
#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT | \ ACPI_PDC_C_C1_HALT | \
...@@ -22,6 +23,7 @@ ...@@ -22,6 +23,7 @@
#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ #define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT | \ ACPI_PDC_C_C1_HALT | \
ACPI_PDC_SMP_P_SWCOORD | \ ACPI_PDC_SMP_P_SWCOORD | \
ACPI_PDC_SMP_P_HWCOORD | \
ACPI_PDC_P_FFH) ACPI_PDC_P_FFH)
#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \
......
...@@ -57,16 +57,6 @@ int pm_notifier_call_chain(unsigned long val) ...@@ -57,16 +57,6 @@ int pm_notifier_call_chain(unsigned long val)
#ifdef CONFIG_PM_DEBUG #ifdef CONFIG_PM_DEBUG
int pm_test_level = TEST_NONE; int pm_test_level = TEST_NONE;
static int suspend_test(int level)
{
if (pm_test_level == level) {
printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n");
mdelay(5000);
return 1;
}
return 0;
}
static const char * const pm_tests[__TEST_AFTER_LAST] = { static const char * const pm_tests[__TEST_AFTER_LAST] = {
[TEST_NONE] = "none", [TEST_NONE] = "none",
[TEST_CORE] = "core", [TEST_CORE] = "core",
...@@ -125,14 +115,24 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, ...@@ -125,14 +115,24 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
} }
power_attr(pm_test); power_attr(pm_test);
#else /* !CONFIG_PM_DEBUG */ #endif /* CONFIG_PM_DEBUG */
static inline int suspend_test(int level) { return 0; }
#endif /* !CONFIG_PM_DEBUG */
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
static int suspend_test(int level)
{
#ifdef CONFIG_PM_DEBUG
if (pm_test_level == level) {
printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n");
mdelay(5000);
return 1;
}
#endif /* !CONFIG_PM_DEBUG */
return 0;
}
#ifdef CONFIG_PM_TEST_SUSPEND #ifdef CONFIG_PM_TEST_SUSPEND
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册