depends on PCI
depends on PM
select PNP
++ +++++ select CPU_IDLE
default y
---help---
Advanced Configuration and Power Interface (ACPI) support for
support physical cpu/memory hot-plug.
If one selects "m", this driver can be loaded with
----- -- "modprobe acpi_container".
+++++ ++ "modprobe container".
config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug"
static ssize_t show_docked(struct device *dev,
struct device_attribute *attr, char *buf)
{
+++++ ++ struct acpi_device *tmp;
+++++ ++
struct dock_station *dock_station = *((struct dock_station **)
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);
ret = device_create_file(&dock_device->dev, &dev_attr_docked);
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);
kfree(dock_station);
dock_station = NULL;
}
ret = device_create_file(&dock_device->dev, &dev_attr_undock);
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);
platform_device_unregister(dock_device);
kfree(dock_station);
}
ret = device_create_file(&dock_device->dev, &dev_attr_uid);
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_undock);
platform_device_unregister(dock_device);
}
ret = device_create_file(&dock_device->dev, &dev_attr_flags);
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_undock);
device_remove_file(&dock_device->dev, &dev_attr_uid);
if (acpi_in_debugger) {
kdb_printf("%s", buffer);
} else {
------ - printk("%s", buffer);
++++++ + printk(KERN_CONT "%s", buffer);
}
#else
------ - printk("%s", buffer);
++++++ + printk(KERN_CONT "%s", buffer);
#endif
}
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
switch (space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
+++ ++++ if (!valid_aml_io_address(address, length))
+++ ++++ return AE_AML_ILLEGAL_ADDRESS;
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
/* Only interference checks against SystemIO and SytemMemory
are needed */
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.
*/
#endif /* CONFIG_ACPI_SLEEP */
#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);
static u32 acpi_suspend_states[] = {
#endif /* CONFIG_SUSPEND */
#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 struct acpi_table_facs *facs;
static bool nosigcheck;
static void acpi_power_off(void)
{
/* 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();
acpi_enable_wakeup_device(ACPI_STATE_S5);
acpi_enter_sleep_state(ACPI_STATE_S5);
}
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, "\ncurrent: %d\n", dev->brightness->curr);
return -EFAULT;
/* 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 (ACPI_SUCCESS
(acpi_video_device_lcd_set_level(dev, level)))
printk(KERN_WARNING PREFIX
"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>");
if (options & 2)
seq_printf(seq, " <PCI video>");
max = max_below = 0;
min = min_above = 255;
/* 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];
if (abs(l - level_current) < abs(delta)) {
delta = l - level_current;
}
/* Ajust level_current to closest available level */
level_current += delta;
- ------ for (i = 0; i < device->brightness->count; i++) {
+ ++++++ for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (l < min)
min = l;
device->pnp.bus_id[3] = '0' + 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;
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/rfkill.h>
+++++++#include <linux/pci.h>
#define EEEPC_LAPTOP_VERSION "0.1"
{KE_KEY, 0x13, KEY_MUTE },
{KE_KEY, 0x14, KEY_VOLUMEDOWN },
{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, 0x31, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
static void notify_brn(void)
{
struct backlight_device *bd = eeepc_backlight_device;
----- -- bd->props.brightness = read_brightness(bd);
+++++ ++ if (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 struct key_entry *key;
return;
if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
notify_brn();
------- acpi_bus_generate_proc_event(ehotk->device, event,
------- ehotk->event_count[event % 128]++);
+++++++ acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
+++++++ dev_name(&ehotk->device->dev), event,
+++++++ ehotk->event_count[event % 128]++);
if (ehotk->inputdev) {
key = eepc_get_entry_by_scancode(event);
if (key) {
}
}
+++++++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)
{
acpi_status status = AE_OK;
ehotk->device = device;
result = eeepc_hotk_check();
if (result)
------- goto end;
+++++++ goto ehotk_fail;
status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
eeepc_hotk_notify, ehotk);
if (ACPI_FAILURE(status))
RFKILL_TYPE_WLAN);
if (!ehotk->eeepc_wlan_rfkill)
------- goto end;
+++++++ goto wlan_fail;
ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
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 =
RFKILL_STATE_UNBLOCKED;
------- else
+++++++ rfkill_set_default(RFKILL_TYPE_WLAN,
+++++++ RFKILL_STATE_UNBLOCKED);
+++++++ } else {
ehotk->eeepc_wlan_rfkill->state =
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) {
rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
if (!ehotk->eeepc_bluetooth_rfkill)
------- goto end;
+++++++ goto bluetooth_fail;
ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
ehotk->eeepc_bluetooth_rfkill->toggle_radio =
eeepc_bluetooth_rfkill_set;
ehotk->eeepc_bluetooth_rfkill->get_state =
eeepc_bluetooth_rfkill_state;
------- if (get_acpi(CM_ASL_BLUETOOTH) == 1)
+++++++ if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
ehotk->eeepc_bluetooth_rfkill->state =
RFKILL_STATE_UNBLOCKED;
------- else
+++++++ rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
+++++++ RFKILL_STATE_UNBLOCKED);
+++++++ } else {
ehotk->eeepc_bluetooth_rfkill->state =
RFKILL_STATE_SOFT_BLOCKED;
------- rfkill_register(ehotk->eeepc_bluetooth_rfkill);
------- }
+++++++ rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
+++++++ RFKILL_STATE_SOFT_BLOCKED);
+++++++ }
------- end:
------- if (result) {
------- kfree(ehotk);
------- ehotk = NULL;
+++++++ result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
+++++++ 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);
+++++++ ehotk = NULL;
+++++++
return result;
}
eeepc_hotk_notify);
if (ACPI_FAILURE(status))
printk(EEEPC_ERR "Error removing notify handler\n");
+++++++
+++++++ eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
+++++++ eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
+++++++
kfree(ehotk);
return 0;
}
{
if (eeepc_backlight_device)
backlight_device_unregister(eeepc_backlight_device);
------- if (ehotk->inputdev)
------- input_unregister_device(ehotk->inputdev);
+++++++ eeepc_backlight_device = NULL;
+++++++}
+++++++
+++++++static void eeepc_rfkill_exit(void)
+++++++{
if (ehotk->eeepc_wlan_rfkill)
rfkill_unregister(ehotk->eeepc_wlan_rfkill);
if (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 __exit eeepc_laptop_exit(void)
{
eeepc_backlight_exit();
+++++++ eeepc_rfkill_exit();
+++++++ eeepc_input_exit();
eeepc_hwmon_exit();
acpi_bus_unregister_driver(&eeepc_hotk_driver);
sysfs_remove_group(&platform_device->dev.kobj,
fail_hwmon:
eeepc_backlight_exit();
fail_backlight:
+++++++ eeepc_input_exit();
+++++++ eeepc_rfkill_exit();
return result;
}