diff --git a/[refs] b/[refs] index 3ac328ac574d..c711ee39de77 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 255f0385c8e0d6b9005c0e09fffb5bd852f3b506 +refs/heads/master: 8903795a5275e0366acf961190c57074ad27f9bb diff --git a/trunk/Documentation/acpi-hotkey.txt b/trunk/Documentation/acpi-hotkey.txt new file mode 100644 index 000000000000..38040fa37649 --- /dev/null +++ b/trunk/Documentation/acpi-hotkey.txt @@ -0,0 +1,38 @@ +driver/acpi/hotkey.c implement: +1. /proc/acpi/hotkey/event_config +(event based hotkey or event config interface): +a. add a event based hotkey(event) : +echo "0:bus::action:method:num:num" > event_config + +b. delete a event based hotkey(event): +echo "1:::::num:num" > event_config + +c. modify a event based hotkey(event): +echo "2:bus::action:method:num:num" > event_config + +2. /proc/acpi/hotkey/poll_config +(polling based hotkey or event config interface): +a.add a polling based hotkey(event) : +echo "0:bus:method:action:method:num" > poll_config +this adding command will create a proc file +/proc/acpi/hotkey/method, which is used to get +result of polling. + +b.delete a polling based hotkey(event): +echo "1:::::num" > event_config + +c.modify a polling based hotkey(event): +echo "2:bus:method:action:method:num" > poll_config + +3./proc/acpi/hotkey/action +(interface to call aml method associated with a +specific hotkey(event)) +echo "event_num:event_type:event_argument" > + /proc/acpi/hotkey/action. +The result of the execution of this aml method is +attached to /proc/acpi/hotkey/poll_method, which is dynamically +created. Please use command "cat /proc/acpi/hotkey/polling_method" +to retrieve it. + +Note: Use cmdline "acpi_generic_hotkey" to over-ride +platform-specific with generic driver. diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 28f897fd3674..c585aa8d62b4 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -253,6 +253,29 @@ Who: Venkatesh Pallipadi --------------------------- +<<<<<<< test:Documentation/feature-removal-schedule.txt +What: ACPI hotkey driver (CONFIG_ACPI_HOTKEY) +When: 2.6.21 +Why: hotkey.c was an attempt to consolidate multiple drivers that use + ACPI to implement hotkeys. However, hotkeys are not documented + in the ACPI specification, so the drivers used undocumented + vendor-specific hooks and turned out to be more different than + the same. + + Further, the keys and the features supplied by each platform + are different, so there will always be a need for + platform-specific drivers. + + So the new plan is to delete hotkey.c and instead, work on the + platform specific drivers to try to make them look the same + to the user when they supply the same features. + + hotkey.c has always depended on CONFIG_EXPERIMENTAL + +Who: Len Brown + +--------------------------- + What: /sys/firmware/acpi/namespace When: 2.6.21 Why: The ACPI namespace is effectively the symbol list for diff --git a/trunk/Documentation/sony-laptop.txt b/trunk/Documentation/sony-laptop.txt deleted file mode 100644 index dfd26df056f4..000000000000 --- a/trunk/Documentation/sony-laptop.txt +++ /dev/null @@ -1,106 +0,0 @@ -Sony Notebook Control Driver (SNC) Readme ------------------------------------------ - Copyright (C) 2004- 2005 Stelian Pop - Copyright (C) 2007 Mattia Dongili - -This mini-driver drives the SNC device present in the ACPI BIOS of -the Sony Vaio laptops. - -It gives access to some extra laptop functionalities. In its current -form, this driver let the user set or query the screen brightness -through the backlight subsystem and remove/apply power to some devices. - -Backlight control: ------------------- -If your laptop model supports it, you will find sysfs files in the -/sys/class/backlight/sony/ -directory. You will be able to query and set the current screen -brightness: - brightness get/set screen brightness (an iteger - between 0 and 7) - actual_brightness reading from this file will query the HW - to get real brightness value - max_brightness the maximum brightness value - - -Platform specific: ------------------- -Loading the sony-laptop module will create a -/sys/devices/platform/sony-laptop/ -directory populated with some files. - -You then read/write integer values from/to those files by using -standard UNIX tools. - -The files are: - brightness_default screen brightness which will be set - when the laptop will be rebooted - cdpower power on/off the internal CD drive - audiopower power on/off the internal sound card - lanpower power on/off the internal ethernet card - (only in debug mode) - -Note that some files may be missing if they are not supported -by your particular laptop model. - -Example usage: - # echo "1" > /sys/devices/platform/sony-laptop/brightness_default -sets the lowest screen brightness for the next and later reboots, - # echo "8" > /sys/devices/platform/sony-laptop/brightness_default -sets the highest screen brightness for the next and later reboots, - # cat /sys/devices/platform/sony-laptop/brightness_default -retrieves the value. - - # echo "0" > /sys/devices/platform/sony-laptop/audiopower -powers off the sound card, - # echo "1" > /sys/devices/platform/sony-laptop/audiopower -powers on the sound card. - -Development: ------------- - -If you want to help with the development of this driver (and -you are not afraid of any side effects doing strange things with -your ACPI BIOS could have on your laptop), load the driver and -pass the option 'debug=1'. - -REPEAT: DON'T DO THIS IF YOU DON'T LIKE RISKY BUSINESS. - -In your kernel logs you will find the list of all ACPI methods -the SNC device has on your laptop. You can see the GCDP/GCDP methods -used to pwer on/off the CD drive, but there are others. - -I HAVE NO IDEA WHAT THOSE METHODS DO. - -The sony-laptop driver creates, for some of those methods (the most -current ones found on several Vaio models), an entry under -/sys/devices/platform/sony-laptop, just like the 'cdpower' one. -You can create other entries corresponding to your own laptop methods by -further editing the source (see the 'sony_acpi_values' table, and add a new -entry to this table with your get/set method names using the -HANDLE_NAMES macro). - -Your mission, should you accept it, is to try finding out what -those entries are for, by reading/writing random values from/to those -files and find out what is the impact on your laptop. - -Should you find anything interesting, please report it back to me, -I will not disavow all knowledge of your actions :) - -Bugs/Limitations: ------------------ - -* This driver is not based on official documentation from Sony - (because there is none), so there is no guarantee this driver - will work at all, or do the right thing. Although this hasn't - happened to me, this driver could do very bad things to your - laptop, including permanent damage. - -* The sony-laptop and sonypi drivers do not interact at all. In the - future, sonypi could use sony-laptop to do (part of) its business. - -* spicctrl, which is the userspace tool used to communicate with the - sonypi driver (through /dev/sonypi) does not try to use the - sony-laptop driver. In the future, spicctrl could try sonypi first, - and if it isn't present, try sony-laptop instead. - diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index a384551a5978..b0fd71b3f66f 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -247,13 +247,6 @@ L: linux-acpi@vger.kernel.org W: http://acpi.sourceforge.net/ S: Supported -ACPI VIDEO DRIVER -P: Luming Yu -M: luming.yu@intel.com -L: linux-acpi@vger.kernel.org -W: http://acpi.sourceforge.net/ -S: Supported - AD1816 SOUND DRIVER P: Thorsten Knabe M: Thorsten Knabe @@ -3068,8 +3061,6 @@ S: Maintained SONY VAIO CONTROL DEVICE DRIVER P: Stelian Pop M: stelian@popies.net -P: Mattia Dongili -M: malattia@linux.it W: http://popies.net/sonypi/ S: Maintained diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index e5eb97a910ed..fb3e72328a5a 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -850,9 +850,10 @@ static inline int acpi_parse_madt_ioapic_entries(void) static void __init acpi_process_madt(void) { #ifdef CONFIG_X86_LOCAL_APIC - int error; + int count, error; - if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { + count = acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt); + if (count >= 1) { /* * Parse MADT LAPIC entries diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 3549c94467b8..9197d7b361b3 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -651,7 +651,7 @@ int __init acpi_boot_init(void) * information -- the successor to MPS tables. */ - if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { + if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt) < 1) { printk(KERN_ERR PREFIX "Can't find MADT\n"); goto skip_madt; } @@ -702,7 +702,7 @@ int __init acpi_boot_init(void) * gets interrupts such as power and sleep buttons. If it's not * on a Legacy interrupt, it needs to be setup. */ - if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt)) + if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) < 1) printk(KERN_ERR PREFIX "Can't find FADT\n"); #ifdef CONFIG_SMP diff --git a/trunk/arch/x86_64/kernel/early-quirks.c b/trunk/arch/x86_64/kernel/early-quirks.c index 8047ea8c2ab2..bd30d138113f 100644 --- a/trunk/arch/x86_64/kernel/early-quirks.c +++ b/trunk/arch/x86_64/kernel/early-quirks.c @@ -53,9 +53,7 @@ static void nvidia_bugs(void) return; nvidia_hpet_detected = 0; - if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) - return; - + acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; printk(KERN_INFO "Nvidia board " diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index e942ffe8b57e..20eacc2c9e0e 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -13,7 +13,6 @@ config ACPI depends on IA64 || X86 depends on PCI depends on PM - select PNP default y ---help--- Advanced Configuration and Power Interface (ACPI) support for @@ -133,6 +132,15 @@ config ACPI_VIDEO Note that this is an ref. implementation only. It may or may not work for your integrated video device. +config ACPI_HOTKEY + tristate "Generic Hotkey (EXPERIMENTAL)" + depends on EXPERIMENTAL + depends on X86 + default n + help + Experimental consolidated hotkey driver. + If you are unsure, say N. + config ACPI_FAN tristate "Fan" default y diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index 5956e9f64a8b..856c32bccacb 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_ACPI_FAN) += fan.o obj-$(CONFIG_ACPI_DOCK) += dock.o obj-$(CONFIG_ACPI_BAY) += bay.o obj-$(CONFIG_ACPI_VIDEO) += video.o +obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o obj-$(CONFIG_ACPI_POWER) += power.o obj-$(CONFIG_ACPI_PROCESSOR) += processor.o diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index 37c7dc4f9fe5..6daeace796a8 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -35,6 +35,7 @@ #define ACPI_AC_COMPONENT 0x00020000 #define ACPI_AC_CLASS "ac_adapter" #define ACPI_AC_HID "ACPI0003" +#define ACPI_AC_DRIVER_NAME "ACPI AC Adapter Driver" #define ACPI_AC_DEVICE_NAME "AC Adapter" #define ACPI_AC_FILE_STATE "state" #define ACPI_AC_NOTIFY_STATUS 0x80 @@ -43,10 +44,10 @@ #define ACPI_AC_STATUS_UNKNOWN 0xFF #define _COMPONENT ACPI_AC_COMPONENT -ACPI_MODULE_NAME("ac"); +ACPI_MODULE_NAME("acpi_ac") -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION("ACPI AC Adapter Driver"); + MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME); MODULE_LICENSE("GPL"); extern struct proc_dir_entry *acpi_lock_ac_dir(void); @@ -57,7 +58,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type); static int acpi_ac_open_fs(struct inode *inode, struct file *file); static struct acpi_driver acpi_ac_driver = { - .name = "ac", + .name = ACPI_AC_DRIVER_NAME, .class = ACPI_AC_CLASS, .ids = ACPI_AC_HID, .ops = { diff --git a/trunk/drivers/acpi/acpi_memhotplug.c b/trunk/drivers/acpi/acpi_memhotplug.c index c26172671fd8..cd946ed192d3 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -35,13 +35,14 @@ #define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL #define ACPI_MEMORY_DEVICE_CLASS "memory" #define ACPI_MEMORY_DEVICE_HID "PNP0C80" +#define ACPI_MEMORY_DEVICE_DRIVER_NAME "Hotplug Mem Driver" #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" #define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT -ACPI_MODULE_NAME("acpi_memhotplug"); -MODULE_AUTHOR("Naveen B S "); -MODULE_DESCRIPTION("Hotplug Mem Driver"); +ACPI_MODULE_NAME("acpi_memory") + MODULE_AUTHOR("Naveen B S "); +MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME); MODULE_LICENSE("GPL"); /* ACPI _STA method values */ @@ -59,7 +60,7 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type); static int acpi_memory_device_start(struct acpi_device *device); static struct acpi_driver acpi_memory_device_driver = { - .name = "acpi_memhotplug", + .name = ACPI_MEMORY_DEVICE_DRIVER_NAME, .class = ACPI_MEMORY_DEVICE_CLASS, .ids = ACPI_MEMORY_DEVICE_HID, .ops = { diff --git a/trunk/drivers/acpi/asus_acpi.c b/trunk/drivers/acpi/asus_acpi.c index 772299fb5f9d..31ad70a6e22e 100644 --- a/trunk/drivers/acpi/asus_acpi.c +++ b/trunk/drivers/acpi/asus_acpi.c @@ -141,7 +141,6 @@ struct asus_hotk { W5A, //W5A W3V, //W3030V xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N - A4S, //Z81sp //(Centrino) END_MODEL } model; //Models currently supported @@ -398,16 +397,7 @@ static struct model_data model_conf[END_MODEL] = { .brightness_set = "SPLV", .brightness_get = "GPLV", .display_set = "SDSP", - .display_get = "\\ADVG"}, - - { - .name = "A4S", - .brightness_set = "SPLV", - .brightness_get = "GPLV", - .mt_bt_switch = "BLED", - .mt_wled = "WLED" - } - + .display_get = "\\ADVG"} }; /* procdir we use */ @@ -431,7 +421,7 @@ static struct asus_hotk *hotk; static int asus_hotk_add(struct acpi_device *device); static int asus_hotk_remove(struct acpi_device *device, int type); static struct acpi_driver asus_hotk_driver = { - .name = "asus_acpi", + .name = ACPI_HOTK_NAME, .class = ACPI_HOTK_CLASS, .ids = ACPI_HOTK_HID, .ops = { @@ -1127,8 +1117,6 @@ static int asus_model_match(char *model) return W3V; else if (strncmp(model, "W5A", 3) == 0) return W5A; - else if (strncmp(model, "A4S", 3) == 0) - return A4S; else return END_MODEL; } @@ -1377,6 +1365,10 @@ static int __init asus_acpi_init(void) if (acpi_disabled) return -ENODEV; + if (!acpi_specific_hotkey_enabled) { + printk(KERN_ERR "Using generic hotkey driver\n"); + return -ENODEV; + } asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); if (!asus_proc_dir) { printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n"); diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index e64c76c8b726..2f4521a48fe7 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -42,6 +42,7 @@ #define ACPI_BATTERY_COMPONENT 0x00040000 #define ACPI_BATTERY_CLASS "battery" #define ACPI_BATTERY_HID "PNP0C0A" +#define ACPI_BATTERY_DRIVER_NAME "ACPI Battery Driver" #define ACPI_BATTERY_DEVICE_NAME "Battery" #define ACPI_BATTERY_FILE_INFO "info" #define ACPI_BATTERY_FILE_STATUS "state" @@ -52,10 +53,10 @@ #define ACPI_BATTERY_UNITS_AMPS "mA" #define _COMPONENT ACPI_BATTERY_COMPONENT -ACPI_MODULE_NAME("battery"); +ACPI_MODULE_NAME("acpi_battery") -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION("ACPI Battery Driver"); + MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME); MODULE_LICENSE("GPL"); extern struct proc_dir_entry *acpi_lock_battery_dir(void); @@ -66,7 +67,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type); static int acpi_battery_resume(struct acpi_device *device); static struct acpi_driver acpi_battery_driver = { - .name = "battery", + .name = ACPI_BATTERY_DRIVER_NAME, .class = ACPI_BATTERY_CLASS, .ids = ACPI_BATTERY_HID, .ops = { @@ -323,13 +324,6 @@ static int acpi_battery_check(struct acpi_battery *battery) return result; } -static void acpi_battery_check_present(struct acpi_battery *battery) -{ - if (!battery->flags.present) { - acpi_battery_check(battery); - } -} - /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ @@ -346,8 +340,6 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) if (!battery) goto end; - acpi_battery_check_present(battery); - if (battery->flags.present) seq_printf(seq, "present: yes\n"); else { @@ -432,8 +424,6 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) if (!battery) goto end; - acpi_battery_check_present(battery); - if (battery->flags.present) seq_printf(seq, "present: yes\n"); else { @@ -509,8 +499,6 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) if (!battery) goto end; - acpi_battery_check_present(battery); - if (!battery->flags.present) { seq_printf(seq, "present: no\n"); goto end; @@ -548,8 +536,6 @@ acpi_battery_write_alarm(struct file *file, if (!battery || (count > sizeof(alarm_string) - 1)) return -EINVAL; - acpi_battery_check_present(battery); - if (!battery->flags.present) return -ENODEV; diff --git a/trunk/drivers/acpi/bay.c b/trunk/drivers/acpi/bay.c index fb3f31b5e69f..91082ce6f5d1 100644 --- a/trunk/drivers/acpi/bay.c +++ b/trunk/drivers/acpi/bay.c @@ -32,9 +32,11 @@ #include #include -ACPI_MODULE_NAME("bay"); +#define ACPI_BAY_DRIVER_NAME "ACPI Removable Drive Bay Driver" + +ACPI_MODULE_NAME("bay") MODULE_AUTHOR("Kristen Carlson Accardi"); -MODULE_DESCRIPTION("ACPI Removable Drive Bay Driver"); +MODULE_DESCRIPTION(ACPI_BAY_DRIVER_NAME); MODULE_LICENSE("GPL"); #define ACPI_BAY_CLASS "bay" #define ACPI_BAY_COMPONENT 0x10000000 @@ -45,6 +47,18 @@ MODULE_LICENSE("GPL"); acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\ printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } static void bay_notify(acpi_handle handle, u32 event, void *data); +static int acpi_bay_add(struct acpi_device *device); +static int acpi_bay_remove(struct acpi_device *device, int type); + +static struct acpi_driver acpi_bay_driver = { + .name = ACPI_BAY_DRIVER_NAME, + .class = ACPI_BAY_CLASS, + .ids = ACPI_BAY_HID, + .ops = { + .add = acpi_bay_add, + .remove = acpi_bay_remove, + }, +}; struct bay { acpi_handle handle; @@ -220,6 +234,14 @@ int eject_removable_drive(struct device *dev) } EXPORT_SYMBOL_GPL(eject_removable_drive); +static int acpi_bay_add(struct acpi_device *device) +{ + bay_dprintk(device->handle, "adding bay device"); + strcpy(acpi_device_name(device), "Dockable Bay"); + strcpy(acpi_device_class(device), "bay"); + return 0; +} + static int acpi_bay_add_fs(struct bay *bay) { int ret; @@ -281,7 +303,7 @@ static int bay_add(acpi_handle handle, int id) /* initialize platform device stuff */ pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0); - if (IS_ERR(pdev)) { + if (pdev == NULL) { printk(KERN_ERR PREFIX "Error registering bay device\n"); goto bay_add_err; } @@ -317,6 +339,52 @@ static int bay_add(acpi_handle handle, int id) return -ENODEV; } +static int acpi_bay_remove(struct acpi_device *device, int type) +{ + /*** FIXME: do something here */ + return 0; +} + +/** + * bay_create_acpi_device - add new devices to acpi + * @handle - handle of the device to add + * + * This function will create a new acpi_device for the given + * handle if one does not exist already. This should cause + * acpi to scan for drivers for the given devices, and call + * matching driver's add routine. + * + * Returns a pointer to the acpi_device corresponding to the handle. + */ +static struct acpi_device * bay_create_acpi_device(acpi_handle handle) +{ + struct acpi_device *device = NULL; + struct acpi_device *parent_device; + acpi_handle parent; + int ret; + + bay_dprintk(handle, "Trying to get device"); + if (acpi_bus_get_device(handle, &device)) { + /* + * no device created for this object, + * so we should create one. + */ + bay_dprintk(handle, "No device for handle"); + acpi_get_parent(handle, &parent); + if (acpi_bus_get_device(parent, &parent_device)) + parent_device = NULL; + + ret = acpi_bus_add(&device, parent_device, handle, + ACPI_BUS_TYPE_DEVICE); + if (ret) { + pr_debug("error adding bus, %x\n", + -ret); + return NULL; + } + } + return device; +} + /** * bay_notify - act upon an acpi bay notification * @handle: the bay handle @@ -326,19 +394,38 @@ static int bay_add(acpi_handle handle, int id) */ static void bay_notify(acpi_handle handle, u32 event, void *data) { - struct bay *bay_dev = (struct bay *)data; - struct device *dev = &bay_dev->pdev->dev; + struct acpi_device *dev; bay_dprintk(handle, "Bay event"); switch(event) { case ACPI_NOTIFY_BUS_CHECK: + printk("Bus Check\n"); case ACPI_NOTIFY_DEVICE_CHECK: + printk("Device Check\n"); + dev = bay_create_acpi_device(handle); + if (dev) + acpi_bus_generate_event(dev, event, 0); + else + printk("No device for generating event\n"); + /* wouldn't it be a good idea to just rescan SATA + * right here? + */ + break; case ACPI_NOTIFY_EJECT_REQUEST: - kobject_uevent(&dev->kobj, KOBJ_CHANGE); + printk("Eject request\n"); + dev = bay_create_acpi_device(handle); + if (dev) + acpi_bus_generate_event(dev, event, 0); + else + printk("No device for generating eventn"); + + /* wouldn't it be a good idea to just call the + * eject_device here if we were a SATA device? + */ break; default: - printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event); + printk("unknown event %d\n", event); } } @@ -370,6 +457,10 @@ static int __init bay_init(void) acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, find_bay, &bays, NULL); + if (bays) + if ((acpi_bus_register_driver(&acpi_bay_driver) < 0)) + printk(KERN_ERR "Unable to register bay driver\n"); + if (!bays) return -ENODEV; @@ -390,6 +481,8 @@ static void __exit bay_exit(void) kfree(bay->name); kfree(bay); } + + acpi_bus_unregister_driver(&acpi_bay_driver); } postcore_initcall(bay_init); diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index dd49ea0d0ed3..c26468da4295 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -39,7 +39,7 @@ #include #define _COMPONENT ACPI_BUS_COMPONENT -ACPI_MODULE_NAME("bus"); +ACPI_MODULE_NAME("acpi_bus") #ifdef CONFIG_X86 extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); #endif @@ -147,7 +147,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state) *state = ACPI_STATE_D0; } else { /* - * Get the device's power state either directly (via _PSC) or + * Get the device's power state either directly (via _PSC) or * indirectly (via power resources). */ if (device->power.flags.explicit_get) { @@ -199,14 +199,15 @@ int acpi_bus_set_power(acpi_handle handle, int state) * Get device's current power state if it's unknown * This means device power state isn't initialized or previous setting failed */ - if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state) - acpi_bus_get_power(device->handle, &device->power.state); - if ((state == device->power.state) && !device->flags.force_power_state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", - state)); - return 0; + if (!device->flags.force_power_state) { + if (device->power.state == ACPI_STATE_UNKNOWN) + acpi_bus_get_power(device->handle, &device->power.state); + if (state == device->power.state) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", + state)); + return 0; + } } - if (!device->power.states[state].flags.valid) { printk(KERN_WARNING PREFIX "Device does not support D%d\n", state); return -ENODEV; @@ -461,7 +462,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) "Received BUS CHECK notification for device [%s]\n", device->pnp.bus_id)); result = acpi_bus_check_scope(device); - /* + /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). */ @@ -472,7 +473,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) "Received DEVICE CHECK notification for device [%s]\n", device->pnp.bus_id)); result = acpi_bus_check_device(device, NULL); - /* + /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). */ @@ -542,7 +543,7 @@ static int __init acpi_bus_init_irq(void) char *message = NULL; - /* + /* * Let the system know what interrupt model we are using by * evaluating the \_PIC object, if exists. */ @@ -683,7 +684,7 @@ static int __init acpi_bus_init(void) * the EC device is found in the namespace (i.e. before acpi_initialize_objects() * is called). * - * This is accomplished by looking for the ECDT table, and getting + * This is accomplished by looking for the ECDT table, and getting * the EC parameters out of that. */ status = acpi_ec_ecdt_probe(); @@ -698,9 +699,6 @@ static int __init acpi_bus_init(void) printk(KERN_INFO PREFIX "Interpreter enabled\n"); - /* Initialize sleep structures */ - acpi_sleep_init(); - /* * Get the system interrupt model and evaluate \_PIC. */ diff --git a/trunk/drivers/acpi/button.c b/trunk/drivers/acpi/button.c index cb4110b50cd0..c726612fafb6 100644 --- a/trunk/drivers/acpi/button.c +++ b/trunk/drivers/acpi/button.c @@ -34,6 +34,7 @@ #include #define ACPI_BUTTON_COMPONENT 0x00080000 +#define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver" #define ACPI_BUTTON_CLASS "button" #define ACPI_BUTTON_FILE_INFO "info" #define ACPI_BUTTON_FILE_STATE "state" @@ -60,10 +61,10 @@ #define ACPI_BUTTON_TYPE_LID 0x05 #define _COMPONENT ACPI_BUTTON_COMPONENT -ACPI_MODULE_NAME("button"); +ACPI_MODULE_NAME("acpi_button") MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION("ACPI Button Driver"); +MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME); MODULE_LICENSE("GPL"); static int acpi_button_add(struct acpi_device *device); @@ -72,7 +73,7 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file); static int acpi_button_state_open_fs(struct inode *inode, struct file *file); static struct acpi_driver acpi_button_driver = { - .name = "button", + .name = ACPI_BUTTON_DRIVER_NAME, .class = ACPI_BUTTON_CLASS, .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E", .ops = { diff --git a/trunk/drivers/acpi/cm_sbs.c b/trunk/drivers/acpi/cm_sbs.c index f9db4f444bd0..4a9b7bf6f44e 100644 --- a/trunk/drivers/acpi/cm_sbs.c +++ b/trunk/drivers/acpi/cm_sbs.c @@ -31,7 +31,7 @@ #include #include -ACPI_MODULE_NAME("cm_sbs"); +ACPI_MODULE_NAME("cm_sbs") #define ACPI_AC_CLASS "ac_adapter" #define ACPI_BATTERY_CLASS "battery" #define ACPI_SBS_COMPONENT 0x00080000 diff --git a/trunk/drivers/acpi/container.c b/trunk/drivers/acpi/container.c index 0930d9413dfa..69a68fd394cf 100644 --- a/trunk/drivers/acpi/container.c +++ b/trunk/drivers/acpi/container.c @@ -35,6 +35,7 @@ #include #include +#define ACPI_CONTAINER_DRIVER_NAME "ACPI container driver" #define ACPI_CONTAINER_DEVICE_NAME "ACPI container device" #define ACPI_CONTAINER_CLASS "container" @@ -43,10 +44,10 @@ #define ACPI_CONTAINER_COMPONENT 0x01000000 #define _COMPONENT ACPI_CONTAINER_COMPONENT -ACPI_MODULE_NAME("container"); +ACPI_MODULE_NAME("acpi_container") -MODULE_AUTHOR("Anil S Keshavamurthy"); -MODULE_DESCRIPTION("ACPI container driver"); + MODULE_AUTHOR("Anil S Keshavamurthy"); +MODULE_DESCRIPTION(ACPI_CONTAINER_DRIVER_NAME); MODULE_LICENSE("GPL"); #define ACPI_STA_PRESENT (0x00000001) @@ -55,7 +56,7 @@ static int acpi_container_add(struct acpi_device *device); static int acpi_container_remove(struct acpi_device *device, int type); static struct acpi_driver acpi_container_driver = { - .name = "container", + .name = ACPI_CONTAINER_DRIVER_NAME, .class = ACPI_CONTAINER_CLASS, .ids = "ACPI0004,PNP0A05,PNP0A06", .ops = { diff --git a/trunk/drivers/acpi/debug.c b/trunk/drivers/acpi/debug.c index bf513e07b773..d48f65a8f658 100644 --- a/trunk/drivers/acpi/debug.c +++ b/trunk/drivers/acpi/debug.c @@ -12,7 +12,7 @@ #include #define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("debug"); +ACPI_MODULE_NAME("debug") #ifdef MODULE_PARAM_PREFIX #undef MODULE_PARAM_PREFIX diff --git a/trunk/drivers/acpi/dispatcher/dsmethod.c b/trunk/drivers/acpi/dispatcher/dsmethod.c index 1683e5c5b94c..1cbe61905824 100644 --- a/trunk/drivers/acpi/dispatcher/dsmethod.c +++ b/trunk/drivers/acpi/dispatcher/dsmethod.c @@ -231,8 +231,10 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, * Obtain the method mutex if necessary. Do not acquire mutex for a * recursive call. */ - if (acpi_os_get_thread_id() != - obj_desc->method.mutex->mutex.owner_thread_id) { + if (!walk_state || + !obj_desc->method.mutex->mutex.owner_thread || + (walk_state->thread != + obj_desc->method.mutex->mutex.owner_thread)) { /* * Acquire the method mutex. This releases the interpreter if we * block (and reacquires it before it returns) @@ -246,14 +248,14 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, } /* Update the mutex and walk info and save the original sync_level */ - obj_desc->method.mutex->mutex.owner_thread_id = - acpi_os_get_thread_id(); if (walk_state) { obj_desc->method.mutex->mutex. original_sync_level = walk_state->thread->current_sync_level; + obj_desc->method.mutex->mutex.owner_thread = + walk_state->thread; walk_state->thread->current_sync_level = obj_desc->method.sync_level; } else { @@ -567,7 +569,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, acpi_os_release_mutex(method_desc->method.mutex->mutex. os_mutex); - method_desc->method.mutex->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; + method_desc->method.mutex->mutex.owner_thread = NULL; } } diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 54a697f9aa18..688e83a16906 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -32,11 +32,11 @@ #include #include -#define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver" +#define ACPI_DOCK_DRIVER_NAME "ACPI Dock Station Driver" -ACPI_MODULE_NAME("dock"); +ACPI_MODULE_NAME("dock") MODULE_AUTHOR("Kristen Carlson Accardi"); -MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); +MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME); MODULE_LICENSE("GPL"); static struct atomic_notifier_head dock_notifier_list; @@ -741,7 +741,7 @@ static int dock_add(acpi_handle handle) goto dock_add_err; } - printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_DESCRIPTION); + printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_NAME); return 0; diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index ab6888373795..743ce27fa0bb 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -38,10 +38,11 @@ #include #define _COMPONENT ACPI_EC_COMPONENT -ACPI_MODULE_NAME("ec"); +ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_COMPONENT 0x00100000 #define ACPI_EC_CLASS "embedded_controller" #define ACPI_EC_HID "PNP0C09" +#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" #undef PREFIX @@ -79,7 +80,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type); static int acpi_ec_add(struct acpi_device *device); static struct acpi_driver acpi_ec_driver = { - .name = "ec", + .name = ACPI_EC_DRIVER_NAME, .class = ACPI_EC_CLASS, .ids = ACPI_EC_HID, .ops = { @@ -279,10 +280,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, mutex_lock(&ec->lock); if (ec->global_lock) { status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) { - mutex_unlock(&ec->lock); + if (ACPI_FAILURE(status)) return -ENODEV; - } } /* Make sure GPE is enabled before doing transaction */ diff --git a/trunk/drivers/acpi/event.c b/trunk/drivers/acpi/event.c index 3b23562e6f92..959a893c8d1f 100644 --- a/trunk/drivers/acpi/event.c +++ b/trunk/drivers/acpi/event.c @@ -13,7 +13,7 @@ #include #define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("event"); +ACPI_MODULE_NAME("event") /* Global vars for handling event proc entry */ static DEFINE_SPINLOCK(acpi_system_event_lock); diff --git a/trunk/drivers/acpi/events/evgpe.c b/trunk/drivers/acpi/events/evgpe.c index 635ba449ebc2..dfac3ecc596e 100644 --- a/trunk/drivers/acpi/events/evgpe.c +++ b/trunk/drivers/acpi/events/evgpe.c @@ -636,6 +636,17 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) } } + if (!acpi_gbl_system_awake_and_running) { + /* + * We just woke up because of a wake GPE. Disable any further GPEs + * until we are fully up and running (Only wake GPEs should be enabled + * at this time, but we just brute-force disable them all.) + * 1) We must disable this particular wake GPE so it won't fire again + * 2) We want to disable all wake GPEs, since we are now awake + */ + (void)acpi_hw_disable_all_gpes(); + } + /* * Dispatch the GPE to either an installed handler, or the control method * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke diff --git a/trunk/drivers/acpi/events/evmisc.c b/trunk/drivers/acpi/events/evmisc.c index d572700197f3..1b784ffe54c3 100644 --- a/trunk/drivers/acpi/events/evmisc.c +++ b/trunk/drivers/acpi/events/evmisc.c @@ -196,11 +196,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, notify_info->notify.value = (u16) notify_value; notify_info->notify.handler_obj = handler_obj; - acpi_ex_relinquish_interpreter(); - - acpi_ev_notify_dispatch(notify_info); - - acpi_ex_reacquire_interpreter(); + status = + acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, + notify_info); + if (ACPI_FAILURE(status)) { + acpi_ut_delete_generic_state(notify_info); + } } if (!handler_obj) { diff --git a/trunk/drivers/acpi/executer/exdump.c b/trunk/drivers/acpi/executer/exdump.c index 1a73c14df2c5..68d283fd60e7 100644 --- a/trunk/drivers/acpi/executer/exdump.c +++ b/trunk/drivers/acpi/executer/exdump.c @@ -134,7 +134,7 @@ static struct acpi_exdump_info acpi_ex_dump_method[8] = { static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread_id), "Owner Thread"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), "Acquire Depth"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"} diff --git a/trunk/drivers/acpi/executer/exmutex.c b/trunk/drivers/acpi/executer/exmutex.c index 4eb883bda6ae..5101bad5baf8 100644 --- a/trunk/drivers/acpi/executer/exmutex.c +++ b/trunk/drivers/acpi/executer/exmutex.c @@ -66,9 +66,10 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc, * ******************************************************************************/ -void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc, - struct acpi_thread_state *thread) +void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) { + struct acpi_thread_state *thread = obj_desc->mutex.owner_thread; + if (!thread) { return; } @@ -173,13 +174,16 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Support for multiple acquires by the owning thread */ - if (obj_desc->mutex.owner_thread_id == acpi_os_get_thread_id()) { - /* - * The mutex is already owned by this thread, just increment the - * acquisition depth - */ - obj_desc->mutex.acquisition_depth++; - return_ACPI_STATUS(AE_OK); + if (obj_desc->mutex.owner_thread) { + if (obj_desc->mutex.owner_thread->thread_id == + walk_state->thread->thread_id) { + /* + * The mutex is already owned by this thread, just increment the + * acquisition depth + */ + obj_desc->mutex.acquisition_depth++; + return_ACPI_STATUS(AE_OK); + } } /* Acquire the mutex, wait if necessary. Special case for Global Lock */ @@ -202,7 +206,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Have the mutex: update mutex and walk info and save the sync_level */ - obj_desc->mutex.owner_thread_id = acpi_os_get_thread_id(); + obj_desc->mutex.owner_thread = walk_state->thread; obj_desc->mutex.acquisition_depth = 1; obj_desc->mutex.original_sync_level = walk_state->thread->current_sync_level; @@ -242,7 +246,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, /* The mutex must have been previously acquired in order to release it */ - if (!obj_desc->mutex.owner_thread_id) { + if (!obj_desc->mutex.owner_thread) { ACPI_ERROR((AE_INFO, "Cannot release Mutex [%4.4s], not acquired", acpi_ut_get_node_name(obj_desc->mutex.node))); @@ -262,14 +266,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, * The Mutex is owned, but this thread must be the owner. * Special case for Global Lock, any thread can release */ - if ((obj_desc->mutex.owner_thread_id != + if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { ACPI_ERROR((AE_INFO, "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", (unsigned long)walk_state->thread->thread_id, acpi_ut_get_node_name(obj_desc->mutex.node), - (unsigned long)obj_desc->mutex.owner_thread_id)); + (unsigned long)obj_desc->mutex.owner_thread->thread_id)); return_ACPI_STATUS(AE_AML_NOT_OWNER); } @@ -296,7 +300,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, /* Unlink the mutex from the owner's list */ - acpi_ex_unlink_mutex(obj_desc, walk_state->thread); + acpi_ex_unlink_mutex(obj_desc); /* Release the mutex, special case for Global Lock */ @@ -308,7 +312,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, /* Update the mutex and restore sync_level */ - obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; + obj_desc->mutex.owner_thread = NULL; walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level; @@ -363,7 +367,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) /* Mark mutex unowned */ - obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; + obj_desc->mutex.owner_thread = NULL; /* Update Thread sync_level (Last mutex is the important one) */ diff --git a/trunk/drivers/acpi/fan.c b/trunk/drivers/acpi/fan.c index ec655c539492..af22fdf73413 100644 --- a/trunk/drivers/acpi/fan.c +++ b/trunk/drivers/acpi/fan.c @@ -36,13 +36,14 @@ #define ACPI_FAN_COMPONENT 0x00200000 #define ACPI_FAN_CLASS "fan" +#define ACPI_FAN_DRIVER_NAME "ACPI Fan Driver" #define ACPI_FAN_FILE_STATE "state" #define _COMPONENT ACPI_FAN_COMPONENT -ACPI_MODULE_NAME("fan"); +ACPI_MODULE_NAME("acpi_fan") -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION("ACPI Fan Driver"); + MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME); MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); @@ -51,7 +52,7 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state); static int acpi_fan_resume(struct acpi_device *device); static struct acpi_driver acpi_fan_driver = { - .name = "fan", + .name = ACPI_FAN_DRIVER_NAME, .class = ACPI_FAN_CLASS, .ids = "PNP0C0B", .ops = { diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 4334c208841a..7b6c9ff9bebe 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -241,65 +241,3 @@ static int __init init_acpi_device_notify(void) } arch_initcall(init_acpi_device_notify); - - -#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) - -/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find - * its device node and pass extra config data. This helps its driver use - * capabilities that the now-obsolete mc146818 didn't have, and informs it - * that this board's RTC is wakeup-capable (per ACPI spec). - */ -#include - -static struct cmos_rtc_board_info rtc_info; - - -/* PNP devices are registered in a subsys_initcall(); - * ACPI specifies the PNP IDs to use. - */ -#include - -static int __init pnp_match(struct device *dev, void *data) -{ - static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", }; - struct pnp_dev *pnp = to_pnp_dev(dev); - int i; - - for (i = 0; i < ARRAY_SIZE(ids); i++) { - if (compare_pnp_id(pnp->id, ids[i]) != 0) - return 1; - } - return 0; -} - -static struct device *__init get_rtc_dev(void) -{ - return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match); -} - -static int __init acpi_rtc_init(void) -{ - struct device *dev = get_rtc_dev(); - - if (dev) { - rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; - rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; - rtc_info.rtc_century = acpi_gbl_FADT.century; - - /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */ - - dev->platform_data = &rtc_info; - - /* RTC always wakes from S1/S2/S3, and often S4/STD */ - device_init_wakeup(dev, 1); - - put_device(dev); - } else - pr_debug("ACPI: RTC unavailable?\n"); - return 0; -} -/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ -fs_initcall(acpi_rtc_init); - -#endif diff --git a/trunk/drivers/acpi/hardware/hwsleep.c b/trunk/drivers/acpi/hardware/hwsleep.c index 8fa93125fd4c..57901ca3ade9 100644 --- a/trunk/drivers/acpi/hardware/hwsleep.c +++ b/trunk/drivers/acpi/hardware/hwsleep.c @@ -235,14 +235,6 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) "While executing method _SST")); } - /* - * 1) Disable/Clear all GPEs - */ - status = acpi_hw_disable_all_gpes(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - return_ACPI_STATUS(AE_OK); } @@ -298,8 +290,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) } /* + * 1) Disable/Clear all GPEs * 2) Enable all wakeup GPEs */ + status = acpi_hw_disable_all_gpes(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } acpi_gbl_system_awake_and_running = FALSE; status = acpi_hw_enable_all_wakeup_gpes(); diff --git a/trunk/drivers/acpi/hotkey.c b/trunk/drivers/acpi/hotkey.c new file mode 100644 index 000000000000..8edfb92f7ede --- /dev/null +++ b/trunk/drivers/acpi/hotkey.c @@ -0,0 +1,1042 @@ +/* + * hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $) + * + * Copyright (C) 2004 Luming Yu + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HOTKEY_ACPI_VERSION "0.1" + +#define HOTKEY_PROC "hotkey" +#define HOTKEY_EV_CONFIG "event_config" +#define HOTKEY_PL_CONFIG "poll_config" +#define HOTKEY_ACTION "action" +#define HOTKEY_INFO "info" + +#define ACPI_HOTK_NAME "Generic Hotkey Driver" +#define ACPI_HOTK_CLASS "Hotkey" +#define ACPI_HOTK_DEVICE_NAME "Hotkey" +#define ACPI_HOTK_HID "Unknown?" +#define ACPI_HOTKEY_COMPONENT 0x20000000 + +#define ACPI_HOTKEY_EVENT 0x1 +#define ACPI_HOTKEY_POLLING 0x2 +#define ACPI_UNDEFINED_EVENT 0xf + +#define RESULT_STR_LEN 80 + +#define ACTION_METHOD 0 +#define POLL_METHOD 1 + +#define IS_EVENT(e) ((e) <= 10000 && (e) >0) +#define IS_POLL(e) ((e) > 10000) +#define IS_OTHERS(e) ((e)<=0 || (e)>=20000) +#define _COMPONENT ACPI_HOTKEY_COMPONENT +ACPI_MODULE_NAME("acpi_hotkey") + + MODULE_AUTHOR("luming.yu@intel.com"); +MODULE_DESCRIPTION(ACPI_HOTK_NAME); +MODULE_LICENSE("GPL"); + +/* standardized internal hotkey number/event */ +enum { + /* Video Extension event */ + HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80, + HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE, + HK_EVENT_CYCLE_DISPLAY_OUTPUT, + HK_EVENT_NEXT_DISPLAY_OUTPUT, + HK_EVENT_PREVIOUS_DISPLAY_OUTPUT, + HK_EVENT_CYCLE_BRIGHTNESS, + HK_EVENT_INCREASE_BRIGHTNESS, + HK_EVENT_DECREASE_BRIGHTNESS, + HK_EVENT_ZERO_BRIGHTNESS, + HK_EVENT_DISPLAY_DEVICE_OFF, + + /* Snd Card event */ + HK_EVENT_VOLUME_MUTE, + HK_EVENT_VOLUME_INCLREASE, + HK_EVENT_VOLUME_DECREASE, + + /* running state control */ + HK_EVENT_ENTERRING_S3, + HK_EVENT_ENTERRING_S4, + HK_EVENT_ENTERRING_S5, +}; + +enum conf_entry_enum { + bus_handle = 0, + bus_method = 1, + action_handle = 2, + method = 3, + LAST_CONF_ENTRY +}; + +/* procdir we use */ +static struct proc_dir_entry *hotkey_proc_dir; +static struct proc_dir_entry *hotkey_config; +static struct proc_dir_entry *hotkey_poll_config; +static struct proc_dir_entry *hotkey_action; +static struct proc_dir_entry *hotkey_info; + +/* linkage for all type of hotkey */ +struct acpi_hotkey_link { + struct list_head entries; + int hotkey_type; /* event or polling based hotkey */ + int hotkey_standard_num; /* standardized hotkey(event) number */ +}; + +/* event based hotkey */ +struct acpi_event_hotkey { + struct acpi_hotkey_link hotkey_link; + int flag; + acpi_handle bus_handle; /* bus to install notify handler */ + int external_hotkey_num; /* external hotkey/event number */ + acpi_handle action_handle; /* acpi handle attached aml action method */ + char *action_method; /* action method */ +}; + +/* + * There are two ways to poll status + * 1. directy call read_xxx method, without any arguments passed in + * 2. call write_xxx method, with arguments passed in, you need + * the result is saved in acpi_polling_hotkey.poll_result. + * anthoer read command through polling interface. + * + */ + +/* polling based hotkey */ +struct acpi_polling_hotkey { + struct acpi_hotkey_link hotkey_link; + int flag; + acpi_handle poll_handle; /* acpi handle attached polling method */ + char *poll_method; /* poll method */ + acpi_handle action_handle; /* acpi handle attached action method */ + char *action_method; /* action method */ + union acpi_object *poll_result; /* polling_result */ + struct proc_dir_entry *proc; +}; + +/* hotkey object union */ +union acpi_hotkey { + struct list_head entries; + struct acpi_hotkey_link link; + struct acpi_event_hotkey event_hotkey; + struct acpi_polling_hotkey poll_hotkey; +}; + +/* hotkey object list */ +struct acpi_hotkey_list { + struct list_head *entries; + int count; +}; + +static int auto_hotkey_add(struct acpi_device *device); +static int auto_hotkey_remove(struct acpi_device *device, int type); + +static struct acpi_driver hotkey_driver = { + .name = ACPI_HOTK_NAME, + .class = ACPI_HOTK_CLASS, + .ids = ACPI_HOTK_HID, + .ops = { + .add = auto_hotkey_add, + .remove = auto_hotkey_remove, + }, +}; + +static void free_hotkey_device(union acpi_hotkey *key); +static void free_hotkey_buffer(union acpi_hotkey *key); +static void free_poll_hotkey_buffer(union acpi_hotkey *key); +static int hotkey_open_config(struct inode *inode, struct file *file); +static int hotkey_poll_open_config(struct inode *inode, struct file *file); +static ssize_t hotkey_write_config(struct file *file, + const char __user * buffer, + size_t count, loff_t * data); +static int hotkey_info_open_fs(struct inode *inode, struct file *file); +static int hotkey_action_open_fs(struct inode *inode, struct file *file); +static ssize_t hotkey_execute_aml_method(struct file *file, + const char __user * buffer, + size_t count, loff_t * data); +static int hotkey_config_seq_show(struct seq_file *seq, void *offset); +static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset); +static int hotkey_polling_open_fs(struct inode *inode, struct file *file); +static union acpi_hotkey *get_hotkey_by_event(struct + acpi_hotkey_list + *hotkey_list, int event); + +/* event based config */ +static const struct file_operations hotkey_config_fops = { + .open = hotkey_open_config, + .read = seq_read, + .write = hotkey_write_config, + .llseek = seq_lseek, + .release = single_release, +}; + +/* polling based config */ +static const struct file_operations hotkey_poll_config_fops = { + .open = hotkey_poll_open_config, + .read = seq_read, + .write = hotkey_write_config, + .llseek = seq_lseek, + .release = single_release, +}; + +/* hotkey driver info */ +static const struct file_operations hotkey_info_fops = { + .open = hotkey_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* action */ +static const struct file_operations hotkey_action_fops = { + .open = hotkey_action_open_fs, + .read = seq_read, + .write = hotkey_execute_aml_method, + .llseek = seq_lseek, + .release = single_release, +}; + +/* polling results */ +static const struct file_operations hotkey_polling_fops = { + .open = hotkey_polling_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +struct acpi_hotkey_list global_hotkey_list; /* link all ev or pl hotkey */ +struct list_head hotkey_entries; /* head of the list of hotkey_list */ + +static int hotkey_info_seq_show(struct seq_file *seq, void *offset) +{ + + seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION); + + return 0; +} + +static int hotkey_info_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, hotkey_info_seq_show, PDE(inode)->data); +} + +static char *format_result(union acpi_object *object) +{ + char *buf; + + buf = kzalloc(RESULT_STR_LEN, GFP_KERNEL); + if (!buf) + return NULL; + /* Now, just support integer type */ + if (object->type == ACPI_TYPE_INTEGER) + sprintf(buf, "%d\n", (u32) object->integer.value); + return buf; +} + +static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_polling_hotkey *poll_hotkey = seq->private; + char *buf; + + + if (poll_hotkey->poll_result) { + buf = format_result(poll_hotkey->poll_result); + if (buf) + seq_printf(seq, "%s", buf); + kfree(buf); + } + return 0; +} + +static int hotkey_polling_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, hotkey_polling_seq_show, PDE(inode)->data); +} + +static int hotkey_action_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, hotkey_info_seq_show, PDE(inode)->data); +} + +/* Mapping external hotkey number to standardized hotkey event num */ +static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list) +{ + struct list_head *entries; + int val = -1; + + + list_for_each(entries, list->entries) { + union acpi_hotkey *key = + container_of(entries, union acpi_hotkey, entries); + if (key->link.hotkey_type == ACPI_HOTKEY_EVENT + && key->event_hotkey.external_hotkey_num == event) { + val = key->link.hotkey_standard_num; + break; + } + } + + return val; +} + +static void +acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data) +{ + struct acpi_device *device = NULL; + u32 internal_event; + + + if (acpi_bus_get_device(handle, &device)) + return; + + internal_event = hotkey_get_internal_event(event, &global_hotkey_list); + acpi_bus_generate_event(device, internal_event, 0); + + return; +} + +/* Need to invent automatically hotkey add method */ +static int auto_hotkey_add(struct acpi_device *device) +{ + /* Implement me */ + return 0; +} + +/* Need to invent automatically hotkey remove method */ +static int auto_hotkey_remove(struct acpi_device *device, int type) +{ + /* Implement me */ + return 0; +} + +/* Create a proc file for each polling method */ +static int create_polling_proc(union acpi_hotkey *device) +{ + struct proc_dir_entry *proc; + char proc_name[80]; + mode_t mode; + + mode = S_IFREG | S_IRUGO | S_IWUGO; + + sprintf(proc_name, "%d", device->link.hotkey_standard_num); + /* + strcat(proc_name, device->poll_hotkey.poll_method); + */ + proc = create_proc_entry(proc_name, mode, hotkey_proc_dir); + + if (!proc) { + return -ENODEV; + } else { + proc->proc_fops = &hotkey_polling_fops; + proc->owner = THIS_MODULE; + proc->data = device; + proc->uid = 0; + proc->gid = 0; + device->poll_hotkey.proc = proc; + } + return 0; +} + +static int hotkey_add(union acpi_hotkey *device) +{ + int status = 0; + struct acpi_device *dev = NULL; + + + if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) { + acpi_bus_get_device(device->event_hotkey.bus_handle, &dev); + status = acpi_install_notify_handler(dev->handle, + ACPI_DEVICE_NOTIFY, + acpi_hotkey_notify_handler, + dev); + } else /* Add polling hotkey */ + create_polling_proc(device); + + global_hotkey_list.count++; + + list_add_tail(&device->link.entries, global_hotkey_list.entries); + + return status; +} + +static int hotkey_remove(union acpi_hotkey *device) +{ + struct list_head *entries, *next; + + + list_for_each_safe(entries, next, global_hotkey_list.entries) { + union acpi_hotkey *key = + container_of(entries, union acpi_hotkey, entries); + if (key->link.hotkey_standard_num == + device->link.hotkey_standard_num) { + list_del(&key->link.entries); + free_hotkey_device(key); + global_hotkey_list.count--; + break; + } + } + kfree(device); + return 0; +} + +static int hotkey_update(union acpi_hotkey *key) +{ + struct list_head *entries; + + + list_for_each(entries, global_hotkey_list.entries) { + union acpi_hotkey *tmp = + container_of(entries, union acpi_hotkey, entries); + if (tmp->link.hotkey_standard_num == + key->link.hotkey_standard_num) { + if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { + free_hotkey_buffer(tmp); + tmp->event_hotkey.bus_handle = + key->event_hotkey.bus_handle; + tmp->event_hotkey.external_hotkey_num = + key->event_hotkey.external_hotkey_num; + tmp->event_hotkey.action_handle = + key->event_hotkey.action_handle; + tmp->event_hotkey.action_method = + key->event_hotkey.action_method; + kfree(key); + } else { + /* + char proc_name[80]; + + sprintf(proc_name, "%d", tmp->link.hotkey_standard_num); + strcat(proc_name, tmp->poll_hotkey.poll_method); + remove_proc_entry(proc_name,hotkey_proc_dir); + */ + free_poll_hotkey_buffer(tmp); + tmp->poll_hotkey.poll_handle = + key->poll_hotkey.poll_handle; + tmp->poll_hotkey.poll_method = + key->poll_hotkey.poll_method; + tmp->poll_hotkey.action_handle = + key->poll_hotkey.action_handle; + tmp->poll_hotkey.action_method = + key->poll_hotkey.action_method; + tmp->poll_hotkey.poll_result = + key->poll_hotkey.poll_result; + /* + create_polling_proc(tmp); + */ + kfree(key); + } + return 0; + break; + } + } + + return -ENODEV; +} + +static void free_hotkey_device(union acpi_hotkey *key) +{ + struct acpi_device *dev; + + + if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { + acpi_bus_get_device(key->event_hotkey.bus_handle, &dev); + if (dev->handle) + acpi_remove_notify_handler(dev->handle, + ACPI_DEVICE_NOTIFY, + acpi_hotkey_notify_handler); + free_hotkey_buffer(key); + } else { + char proc_name[80]; + + sprintf(proc_name, "%d", key->link.hotkey_standard_num); + /* + strcat(proc_name, key->poll_hotkey.poll_method); + */ + remove_proc_entry(proc_name, hotkey_proc_dir); + free_poll_hotkey_buffer(key); + } + kfree(key); + return; +} + +static void free_hotkey_buffer(union acpi_hotkey *key) +{ + /* key would never be null, action method could be */ + kfree(key->event_hotkey.action_method); +} + +static void free_poll_hotkey_buffer(union acpi_hotkey *key) +{ + /* key would never be null, others could be*/ + kfree(key->poll_hotkey.action_method); + kfree(key->poll_hotkey.poll_method); + kfree(key->poll_hotkey.poll_result); +} +static int +init_hotkey_device(union acpi_hotkey *key, char **config_entry, + int std_num, int external_num) +{ + acpi_handle tmp_handle; + acpi_status status = AE_OK; + + if (std_num < 0 || IS_POLL(std_num) || !key) + goto do_fail; + + if (!config_entry[bus_handle] || !config_entry[action_handle] + || !config_entry[method]) + goto do_fail; + + key->link.hotkey_type = ACPI_HOTKEY_EVENT; + key->link.hotkey_standard_num = std_num; + key->event_hotkey.flag = 0; + key->event_hotkey.action_method = config_entry[method]; + + status = acpi_get_handle(NULL, config_entry[bus_handle], + &(key->event_hotkey.bus_handle)); + if (ACPI_FAILURE(status)) + goto do_fail_zero; + key->event_hotkey.external_hotkey_num = external_num; + status = acpi_get_handle(NULL, config_entry[action_handle], + &(key->event_hotkey.action_handle)); + if (ACPI_FAILURE(status)) + goto do_fail_zero; + status = acpi_get_handle(key->event_hotkey.action_handle, + config_entry[method], &tmp_handle); + if (ACPI_FAILURE(status)) + goto do_fail_zero; + return AE_OK; +do_fail_zero: + key->event_hotkey.action_method = NULL; +do_fail: + return -ENODEV; +} + +static int +init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry, + int std_num) +{ + acpi_status status = AE_OK; + acpi_handle tmp_handle; + + if (std_num < 0 || IS_EVENT(std_num) || !key) + goto do_fail; + if (!config_entry[bus_handle] ||!config_entry[bus_method] || + !config_entry[action_handle] || !config_entry[method]) + goto do_fail; + + key->link.hotkey_type = ACPI_HOTKEY_POLLING; + key->link.hotkey_standard_num = std_num; + key->poll_hotkey.flag = 0; + key->poll_hotkey.poll_method = config_entry[bus_method]; + key->poll_hotkey.action_method = config_entry[method]; + + status = acpi_get_handle(NULL, config_entry[bus_handle], + &(key->poll_hotkey.poll_handle)); + if (ACPI_FAILURE(status)) + goto do_fail_zero; + status = acpi_get_handle(key->poll_hotkey.poll_handle, + config_entry[bus_method], &tmp_handle); + if (ACPI_FAILURE(status)) + goto do_fail_zero; + status = + acpi_get_handle(NULL, config_entry[action_handle], + &(key->poll_hotkey.action_handle)); + if (ACPI_FAILURE(status)) + goto do_fail_zero; + status = acpi_get_handle(key->poll_hotkey.action_handle, + config_entry[method], &tmp_handle); + if (ACPI_FAILURE(status)) + goto do_fail_zero; + key->poll_hotkey.poll_result = + kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!key->poll_hotkey.poll_result) + goto do_fail_zero; + return AE_OK; + +do_fail_zero: + key->poll_hotkey.poll_method = NULL; + key->poll_hotkey.action_method = NULL; +do_fail: + return -ENODEV; +} + +static int hotkey_open_config(struct inode *inode, struct file *file) +{ + return (single_open + (file, hotkey_config_seq_show, PDE(inode)->data)); +} + +static int hotkey_poll_open_config(struct inode *inode, struct file *file) +{ + return (single_open + (file, hotkey_poll_config_seq_show, PDE(inode)->data)); +} + +static int hotkey_config_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; + struct list_head *entries; + char bus_name[ACPI_PATHNAME_MAX] = { 0 }; + char action_name[ACPI_PATHNAME_MAX] = { 0 }; + struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name }; + struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name }; + + + list_for_each(entries, hotkey_list->entries) { + union acpi_hotkey *key = + container_of(entries, union acpi_hotkey, entries); + if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { + acpi_get_name(key->event_hotkey.bus_handle, + ACPI_NAME_TYPE_MAX, &bus); + acpi_get_name(key->event_hotkey.action_handle, + ACPI_NAME_TYPE_MAX, &act); + seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name, + action_name, + key->event_hotkey.action_method, + key->link.hotkey_standard_num, + key->event_hotkey.external_hotkey_num); + } + } + seq_puts(seq, "\n"); + return 0; +} + +static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; + struct list_head *entries; + char bus_name[ACPI_PATHNAME_MAX] = { 0 }; + char action_name[ACPI_PATHNAME_MAX] = { 0 }; + struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name }; + struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name }; + + + list_for_each(entries, hotkey_list->entries) { + union acpi_hotkey *key = + container_of(entries, union acpi_hotkey, entries); + if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) { + acpi_get_name(key->poll_hotkey.poll_handle, + ACPI_NAME_TYPE_MAX, &bus); + acpi_get_name(key->poll_hotkey.action_handle, + ACPI_NAME_TYPE_MAX, &act); + seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name, + key->poll_hotkey.poll_method, + action_name, + key->poll_hotkey.action_method, + key->link.hotkey_standard_num); + } + } + seq_puts(seq, "\n"); + return 0; +} + +static int +get_parms(char *config_record, int *cmd, char **config_entry, + int *internal_event_num, int *external_event_num) +{ +/* the format of *config_record = + * "1:\d+:*" : "cmd:internal_event_num" + * "\d+:\w+:\w+:\w+:\w+:\d+:\d+" : + * "cmd:bus_handle:bus_method:action_handle:method:internal_event_num:external_event_num" + */ + char *tmp, *tmp1, count; + int i; + + sscanf(config_record, "%d", cmd); + if (*cmd == 1) { + if (sscanf(config_record, "%d:%d", cmd, internal_event_num) != + 2) + goto do_fail; + else + return (6); + } + tmp = strchr(config_record, ':'); + if (!tmp) + goto do_fail; + tmp++; + for (i = 0; i < LAST_CONF_ENTRY; i++) { + tmp1 = strchr(tmp, ':'); + if (!tmp1) { + goto do_fail; + } + count = tmp1 - tmp; + config_entry[i] = kzalloc(count + 1, GFP_KERNEL); + if (!config_entry[i]) + goto handle_failure; + strncpy(config_entry[i], tmp, count); + tmp = tmp1 + 1; + } + if (sscanf(tmp, "%d:%d", internal_event_num, external_event_num) <= 0) + goto handle_failure; + if (!IS_OTHERS(*internal_event_num)) { + return 6; + } +handle_failure: + while (i-- > 0) + kfree(config_entry[i]); +do_fail: + return -1; +} + +/* count is length for one input record */ +static ssize_t hotkey_write_config(struct file *file, + const char __user * buffer, + size_t count, loff_t * data) +{ + char *config_record = NULL; + char *config_entry[LAST_CONF_ENTRY]; + int cmd, internal_event_num, external_event_num; + int ret = 0; + union acpi_hotkey *key = kzalloc(sizeof(union acpi_hotkey), GFP_KERNEL); + + if (!key) + return -ENOMEM; + + config_record = kzalloc(count + 1, GFP_KERNEL); + if (!config_record) { + kfree(key); + return -ENOMEM; + } + + if (copy_from_user(config_record, buffer, count)) { + kfree(config_record); + kfree(key); + printk(KERN_ERR PREFIX "Invalid data\n"); + return -EINVAL; + } + ret = get_parms(config_record, &cmd, config_entry, + &internal_event_num, &external_event_num); + kfree(config_record); + if (ret != 6) { + printk(KERN_ERR PREFIX "Invalid data format ret=%d\n", ret); + return -EINVAL; + } + + if (cmd == 1) { + union acpi_hotkey *tmp = NULL; + tmp = get_hotkey_by_event(&global_hotkey_list, + internal_event_num); + if (!tmp) + printk(KERN_ERR PREFIX "Invalid key\n"); + else + memcpy(key, tmp, sizeof(union acpi_hotkey)); + goto cont_cmd; + } + if (IS_EVENT(internal_event_num)) { + if (init_hotkey_device(key, config_entry, + internal_event_num, external_event_num)) + goto init_hotkey_fail; + } else { + if (init_poll_hotkey_device(key, config_entry, + internal_event_num)) + goto init_poll_hotkey_fail; + } +cont_cmd: + switch (cmd) { + case 0: + if (get_hotkey_by_event(&global_hotkey_list, + key->link.hotkey_standard_num)) + goto fail_out; + else + hotkey_add(key); + break; + case 1: + hotkey_remove(key); + break; + case 2: + /* key is kfree()ed if matched*/ + if (hotkey_update(key)) + goto fail_out; + break; + default: + goto fail_out; + break; + } + return count; + +init_poll_hotkey_fail: /* failed init_poll_hotkey_device */ + kfree(config_entry[bus_method]); + config_entry[bus_method] = NULL; +init_hotkey_fail: /* failed init_hotkey_device */ + kfree(config_entry[method]); +fail_out: + kfree(config_entry[bus_handle]); + kfree(config_entry[action_handle]); + /* No double free since elements =NULL for error cases */ + if (IS_EVENT(internal_event_num)) { + if (config_entry[bus_method]) + kfree(config_entry[bus_method]); + free_hotkey_buffer(key); /* frees [method] */ + } else + free_poll_hotkey_buffer(key); /* frees [bus_method]+[method] */ + kfree(key); + printk(KERN_ERR PREFIX "invalid key\n"); + return -EINVAL; +} + +/* + * 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 + * of the method is written is output, which can also be NULL + * + * returns 1 if write is successful, 0 else. + */ +static int write_acpi_int(acpi_handle handle, const char *method, int val, + struct acpi_buffer *output) +{ + struct acpi_object_list params; /* list of input parameters (an int here) */ + union acpi_object in_obj; /* the only param we use */ + acpi_status status; + + params.count = 1; + params.pointer = &in_obj; + in_obj.type = ACPI_TYPE_INTEGER; + in_obj.integer.value = val; + + status = acpi_evaluate_object(handle, (char *)method, ¶ms, output); + + return (status == AE_OK); +} + +static int read_acpi_int(acpi_handle handle, const char *method, + union acpi_object *val) +{ + struct acpi_buffer output; + union acpi_object out_obj; + acpi_status status; + + output.length = sizeof(out_obj); + output.pointer = &out_obj; + + status = acpi_evaluate_object(handle, (char *)method, NULL, &output); + if (val) { + val->integer.value = out_obj.integer.value; + val->type = out_obj.type; + } else + printk(KERN_ERR PREFIX "null val pointer\n"); + return ((status == AE_OK) + && (out_obj.type == ACPI_TYPE_INTEGER)); +} + +static union acpi_hotkey *get_hotkey_by_event(struct + acpi_hotkey_list + *hotkey_list, int event) +{ + struct list_head *entries; + + list_for_each(entries, hotkey_list->entries) { + union acpi_hotkey *key = + container_of(entries, union acpi_hotkey, entries); + if (key->link.hotkey_standard_num == event) { + return (key); + } + } + return (NULL); +} + +/* + * user call AML method interface: + * Call convention: + * echo "event_num: arg type : value" + * example: echo "1:1:30" > /proc/acpi/action + * Just support 1 integer arg passing to AML method + */ + +static ssize_t hotkey_execute_aml_method(struct file *file, + const char __user * buffer, + size_t count, loff_t * data) +{ + struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; + char *arg; + int event, method_type, type, value; + union acpi_hotkey *key; + + + arg = kzalloc(count + 1, GFP_KERNEL); + if (!arg) + return -ENOMEM; + + if (copy_from_user(arg, buffer, count)) { + kfree(arg); + printk(KERN_ERR PREFIX "Invalid argument 2\n"); + return -EINVAL; + } + + if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) != + 4) { + kfree(arg); + printk(KERN_ERR PREFIX "Invalid argument 3\n"); + return -EINVAL; + } + kfree(arg); + if (type == ACPI_TYPE_INTEGER) { + key = get_hotkey_by_event(hotkey_list, event); + if (!key) + goto do_fail; + if (IS_EVENT(event)) + write_acpi_int(key->event_hotkey.action_handle, + key->event_hotkey.action_method, value, + NULL); + else if (IS_POLL(event)) { + if (method_type == POLL_METHOD) + read_acpi_int(key->poll_hotkey.poll_handle, + key->poll_hotkey.poll_method, + key->poll_hotkey.poll_result); + else if (method_type == ACTION_METHOD) + write_acpi_int(key->poll_hotkey.action_handle, + key->poll_hotkey.action_method, + value, NULL); + else + goto do_fail; + + } + } else { + printk(KERN_WARNING "Not supported\n"); + return -EINVAL; + } + return count; + do_fail: + return -EINVAL; + +} + +static int __init hotkey_init(void) +{ + int result; + mode_t mode = S_IFREG | S_IRUGO | S_IWUGO; + + + if (acpi_disabled) + return -ENODEV; + + if (acpi_specific_hotkey_enabled) { + printk("Using specific hotkey driver\n"); + return -ENODEV; + } + + hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir); + if (!hotkey_proc_dir) { + return (-ENODEV); + } + hotkey_proc_dir->owner = THIS_MODULE; + + hotkey_config = + create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir); + if (!hotkey_config) { + goto do_fail1; + } else { + hotkey_config->proc_fops = &hotkey_config_fops; + hotkey_config->data = &global_hotkey_list; + hotkey_config->owner = THIS_MODULE; + hotkey_config->uid = 0; + hotkey_config->gid = 0; + } + + hotkey_poll_config = + create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir); + if (!hotkey_poll_config) { + goto do_fail2; + } else { + hotkey_poll_config->proc_fops = &hotkey_poll_config_fops; + hotkey_poll_config->data = &global_hotkey_list; + hotkey_poll_config->owner = THIS_MODULE; + hotkey_poll_config->uid = 0; + hotkey_poll_config->gid = 0; + } + + hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir); + if (!hotkey_action) { + goto do_fail3; + } else { + hotkey_action->proc_fops = &hotkey_action_fops; + hotkey_action->owner = THIS_MODULE; + hotkey_action->uid = 0; + hotkey_action->gid = 0; + } + + hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir); + if (!hotkey_info) { + goto do_fail4; + } else { + hotkey_info->proc_fops = &hotkey_info_fops; + hotkey_info->owner = THIS_MODULE; + hotkey_info->uid = 0; + hotkey_info->gid = 0; + } + + result = acpi_bus_register_driver(&hotkey_driver); + if (result < 0) + goto do_fail5; + global_hotkey_list.count = 0; + global_hotkey_list.entries = &hotkey_entries; + + INIT_LIST_HEAD(&hotkey_entries); + + return (0); + + do_fail5: + remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir); + do_fail4: + remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir); + do_fail3: + remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir); + do_fail2: + remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir); + do_fail1: + remove_proc_entry(HOTKEY_PROC, acpi_root_dir); + return (-ENODEV); +} + +static void __exit hotkey_exit(void) +{ + struct list_head *entries, *next; + + + list_for_each_safe(entries, next, global_hotkey_list.entries) { + union acpi_hotkey *key = + container_of(entries, union acpi_hotkey, entries); + + acpi_os_wait_events_complete(NULL); + list_del(&key->link.entries); + global_hotkey_list.count--; + free_hotkey_device(key); + } + acpi_bus_unregister_driver(&hotkey_driver); + remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir); + remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir); + remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir); + remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir); + remove_proc_entry(HOTKEY_PROC, acpi_root_dir); + return; +} + +module_init(hotkey_init); +module_exit(hotkey_exit); diff --git a/trunk/drivers/acpi/i2c_ec.c b/trunk/drivers/acpi/i2c_ec.c index acab4a481897..76ec8b63e69f 100644 --- a/trunk/drivers/acpi/i2c_ec.c +++ b/trunk/drivers/acpi/i2c_ec.c @@ -27,17 +27,18 @@ #define ACPI_EC_HC_COMPONENT 0x00080000 #define ACPI_EC_HC_CLASS "ec_hc_smbus" #define ACPI_EC_HC_HID "ACPI0001" +#define ACPI_EC_HC_DRIVER_NAME "ACPI EC HC smbus driver" #define ACPI_EC_HC_DEVICE_NAME "EC HC smbus" #define _COMPONENT ACPI_EC_HC_COMPONENT -ACPI_MODULE_NAME("i2c_ec"); +ACPI_MODULE_NAME("acpi_smbus") static int acpi_ec_hc_add(struct acpi_device *device); static int acpi_ec_hc_remove(struct acpi_device *device, int type); static struct acpi_driver acpi_ec_hc_driver = { - .name = "i2c_ec", + .name = ACPI_EC_HC_DRIVER_NAME, .class = ACPI_EC_HC_CLASS, .ids = ACPI_EC_HC_HID, .ops = { diff --git a/trunk/drivers/acpi/ibm_acpi.c b/trunk/drivers/acpi/ibm_acpi.c index 1a0ed3dc409c..c6144ca66638 100644 --- a/trunk/drivers/acpi/ibm_acpi.c +++ b/trunk/drivers/acpi/ibm_acpi.c @@ -496,10 +496,6 @@ static int ibm_acpi_driver_init(void) printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); printk(IBM_INFO "%s\n", IBM_URL); - if (ibm_thinkpad_ec_found) - printk(IBM_INFO "ThinkPad EC firmware %s\n", - ibm_thinkpad_ec_found); - return 0; } @@ -2621,7 +2617,7 @@ static void __init ibm_handle_init(char *name, ibm_handle_init(#object, &object##_handle, *object##_parent, \ object##_paths, ARRAY_SIZE(object##_paths), &object##_path) -static int __init set_ibm_param(const char *val, struct kernel_param *kp) +static int set_ibm_param(const char *val, struct kernel_param *kp) { unsigned int i; @@ -2663,8 +2659,7 @@ static void acpi_ibm_exit(void) for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--) ibm_exit(&ibms[i]); - if (proc_dir) - remove_proc_entry(IBM_DIR, acpi_root_dir); + remove_proc_entry(IBM_DIR, acpi_root_dir); if (ibm_thinkpad_ec_found) kfree(ibm_thinkpad_ec_found); @@ -2701,6 +2696,11 @@ static int __init acpi_ibm_init(void) if (acpi_disabled) return -ENODEV; + if (!acpi_specific_hotkey_enabled) { + printk(IBM_ERR "using generic hotkey driver\n"); + return -ENODEV; + } + /* ec is required because many other handles are relative to it */ IBM_HANDLE_INIT(ec); if (!ec_handle) { @@ -2710,6 +2710,9 @@ static int __init acpi_ibm_init(void) /* Models with newer firmware report the EC in DMI */ ibm_thinkpad_ec_found = check_dmi_for_ec(); + if (ibm_thinkpad_ec_found) + printk(IBM_INFO "ThinkPad EC firmware %s\n", + ibm_thinkpad_ec_found); /* these handles are not required */ IBM_HANDLE_INIT(vid); @@ -2739,7 +2742,6 @@ static int __init acpi_ibm_init(void) proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir); if (!proc_dir) { printk(IBM_ERR "unable to create proc dir %s", IBM_DIR); - acpi_ibm_exit(); return -ENODEV; } proc_dir->owner = THIS_MODULE; diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index 8fcd6a15517f..4a9faff4c01d 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -33,7 +33,7 @@ #define ACPI_NUMA 0x80000000 #define _COMPONENT ACPI_NUMA -ACPI_MODULE_NAME("numa"); +ACPI_MODULE_NAME("numa") static nodemask_t nodes_found_map = NODE_MASK_NONE; #define PXM_INVAL -1 @@ -45,6 +45,12 @@ int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS] int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; +extern int __init acpi_table_parse_madt_family(char *id, + unsigned long madt_size, + int entry_id, + acpi_madt_entry_handler handler, + unsigned int max_entries); + int __cpuinit pxm_to_node(int pxm) { if (pxm < 0) @@ -202,9 +208,9 @@ static int __init acpi_parse_srat(struct acpi_table_header *table) int __init acpi_table_parse_srat(enum acpi_srat_type id, - acpi_table_entry_handler handler, unsigned int max_entries) + acpi_madt_entry_handler handler, unsigned int max_entries) { - return acpi_table_parse_entries(ACPI_SIG_SRAT, + return acpi_table_parse_madt_family(ACPI_SIG_SRAT, sizeof(struct acpi_table_srat), id, handler, max_entries); } @@ -214,7 +220,9 @@ int __init acpi_numa_init(void) int result; /* SRAT: Static Resource Affinity Table */ - if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { + result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat); + + if (result > 0) { result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, acpi_parse_processor_affinity, NR_CPUS); @@ -222,7 +230,7 @@ int __init acpi_numa_init(void) } /* SLIT: System Locality Information Table */ - acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); + result = acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); acpi_numa_arch_fixup(); return 0; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 971eca4864fa..0f6f3bcbc8eb 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -46,7 +46,7 @@ #include #define _COMPONENT ACPI_OS_SERVICES -ACPI_MODULE_NAME("osl"); +ACPI_MODULE_NAME("osl") #define PREFIX "ACPI: " struct acpi_os_dpc { acpi_osd_exec_callback function; @@ -68,6 +68,9 @@ EXPORT_SYMBOL(acpi_in_debugger); extern char line_buf[80]; #endif /*ENABLE_DEBUGGER */ +int acpi_specific_hotkey_enabled = TRUE; +EXPORT_SYMBOL(acpi_specific_hotkey_enabled); + static unsigned int acpi_irq_irq; static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; @@ -202,7 +205,7 @@ void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { if (phys > ULONG_MAX) { printk(KERN_ERR PREFIX "Cannot map memory that high\n"); - return NULL; + return 0; } if (acpi_gbl_permanent_mmap) /* @@ -887,6 +890,26 @@ u32 acpi_os_get_line(char *buffer) } #endif /* ACPI_FUTURE_USAGE */ +/* Assumes no unreadable holes inbetween */ +u8 acpi_os_readable(void *ptr, acpi_size len) +{ +#if defined(__i386__) || defined(__x86_64__) + char tmp; + return !__get_user(tmp, (char __user *)ptr) + && !__get_user(tmp, (char __user *)ptr + len - 1); +#endif + return 1; +} + +#ifdef ACPI_FUTURE_USAGE +u8 acpi_os_writable(void *ptr, acpi_size len) +{ + /* could do dummy write (racy) or a kernel page table lookup. + The later may be difficult at early boot when kmap doesn't work yet. */ + return 1; +} +#endif + acpi_status acpi_os_signal(u32 function, void *info) { switch (function) { @@ -989,6 +1012,14 @@ static int __init acpi_wake_gpes_always_on_setup(char *str) __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); +static int __init acpi_hotkey_setup(char *str) +{ + acpi_specific_hotkey_enabled = FALSE; + return 1; +} + +__setup("acpi_generic_hotkey", acpi_hotkey_setup); + /* * max_cstate is defined in the base kernel so modules can * change it w/o depending on the state of the processor module. diff --git a/trunk/drivers/acpi/pci_bind.c b/trunk/drivers/acpi/pci_bind.c index 028969370bbf..55f57a61c55e 100644 --- a/trunk/drivers/acpi/pci_bind.c +++ b/trunk/drivers/acpi/pci_bind.c @@ -36,7 +36,7 @@ #include #define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME("pci_bind"); +ACPI_MODULE_NAME("pci_bind") struct acpi_pci_data { struct acpi_pci_id id; diff --git a/trunk/drivers/acpi/pci_irq.c b/trunk/drivers/acpi/pci_irq.c index dd3186abe07a..fe7d007833ad 100644 --- a/trunk/drivers/acpi/pci_irq.c +++ b/trunk/drivers/acpi/pci_irq.c @@ -38,7 +38,7 @@ #include #define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME("pci_irq"); +ACPI_MODULE_NAME("pci_irq") static struct acpi_prt_list acpi_prt; static DEFINE_SPINLOCK(acpi_prt_lock); diff --git a/trunk/drivers/acpi/pci_link.c b/trunk/drivers/acpi/pci_link.c index acc594771379..0f683c8c6fbc 100644 --- a/trunk/drivers/acpi/pci_link.c +++ b/trunk/drivers/acpi/pci_link.c @@ -44,9 +44,10 @@ #include #define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME("pci_link"); +ACPI_MODULE_NAME("pci_link") #define ACPI_PCI_LINK_CLASS "pci_irq_routing" #define ACPI_PCI_LINK_HID "PNP0C0F" +#define ACPI_PCI_LINK_DRIVER_NAME "ACPI PCI Interrupt Link Driver" #define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link" #define ACPI_PCI_LINK_FILE_INFO "info" #define ACPI_PCI_LINK_FILE_STATUS "state" @@ -55,7 +56,7 @@ static int acpi_pci_link_add(struct acpi_device *device); static int acpi_pci_link_remove(struct acpi_device *device, int type); static struct acpi_driver acpi_pci_link_driver = { - .name = "pci_link", + .name = ACPI_PCI_LINK_DRIVER_NAME, .class = ACPI_PCI_LINK_CLASS, .ids = ACPI_PCI_LINK_HID, .ops = { diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index ad4145a37786..4ecf701687e8 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -36,16 +36,17 @@ #include #define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME("pci_root"); +ACPI_MODULE_NAME("pci_root") #define ACPI_PCI_ROOT_CLASS "pci_bridge" #define ACPI_PCI_ROOT_HID "PNP0A03" +#define ACPI_PCI_ROOT_DRIVER_NAME "ACPI PCI Root Bridge Driver" #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" static int acpi_pci_root_add(struct acpi_device *device); static int acpi_pci_root_remove(struct acpi_device *device, int type); static int acpi_pci_root_start(struct acpi_device *device); static struct acpi_driver acpi_pci_root_driver = { - .name = "pci_root", + .name = ACPI_PCI_ROOT_DRIVER_NAME, .class = ACPI_PCI_ROOT_CLASS, .ids = ACPI_PCI_ROOT_HID, .ops = { diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index 1ef338545dfe..0ba7dfbbb2ee 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -45,9 +45,10 @@ #include #define _COMPONENT ACPI_POWER_COMPONENT -ACPI_MODULE_NAME("power"); +ACPI_MODULE_NAME("acpi_power") #define ACPI_POWER_COMPONENT 0x00800000 #define ACPI_POWER_CLASS "power_resource" +#define ACPI_POWER_DRIVER_NAME "ACPI Power Resource Driver" #define ACPI_POWER_DEVICE_NAME "Power Resource" #define ACPI_POWER_FILE_INFO "info" #define ACPI_POWER_FILE_STATUS "state" @@ -56,33 +57,25 @@ ACPI_MODULE_NAME("power"); #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF static int acpi_power_add(struct acpi_device *device); static int acpi_power_remove(struct acpi_device *device, int type); -static int acpi_power_resume(struct acpi_device *device); static int acpi_power_open_fs(struct inode *inode, struct file *file); static struct acpi_driver acpi_power_driver = { - .name = "power", + .name = ACPI_POWER_DRIVER_NAME, .class = ACPI_POWER_CLASS, .ids = ACPI_POWER_HID, .ops = { .add = acpi_power_add, .remove = acpi_power_remove, - .resume = acpi_power_resume, }, }; -struct acpi_power_reference { - struct list_head node; - struct acpi_device *device; -}; - struct acpi_power_resource { struct acpi_device * device; acpi_bus_id name; u32 system_level; u32 order; int state; - struct mutex resource_lock; - struct list_head reference; + int references; }; static struct list_head acpi_power_resource_list; @@ -178,47 +171,22 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) return result; } -static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) +static int acpi_power_on(acpi_handle handle) { int result = 0; - int found = 0; acpi_status status = AE_OK; + struct acpi_device *device = NULL; struct acpi_power_resource *resource = NULL; - struct list_head *node, *next; - struct acpi_power_reference *ref; result = acpi_power_get_context(handle, &resource); if (result) return result; - mutex_lock(&resource->resource_lock); - list_for_each_safe(node, next, &resource->reference) { - ref = container_of(node, struct acpi_power_reference, node); - if (dev->handle == ref->device->handle) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already referenced by resource [%s]\n", - dev->pnp.bus_id, resource->name)); - found = 1; - break; - } - } - - if (!found) { - ref = kmalloc(sizeof (struct acpi_power_reference), - irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); - if (!ref) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "kmalloc() failed\n")); - mutex_unlock(&resource->resource_lock); - return -ENOMEM; - } - list_add_tail(&ref->node, &resource->reference); - ref->device = dev; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] added to resource [%s] references\n", - dev->pnp.bus_id, resource->name)); - } - mutex_unlock(&resource->resource_lock); + resource->references++; - if (resource->state == ACPI_POWER_RESOURCE_STATE_ON) { + if ((resource->references > 1) + || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n", resource->name)); return 0; @@ -235,49 +203,38 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) return -ENOEXEC; /* Update the power resource's _device_ power state */ + device = resource->device; resource->device->power.state = ACPI_STATE_D0; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n", resource->name)); + return 0; } -static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) +static int acpi_power_off_device(acpi_handle handle) { int result = 0; acpi_status status = AE_OK; struct acpi_power_resource *resource = NULL; - struct list_head *node, *next; - struct acpi_power_reference *ref; - result = acpi_power_get_context(handle, &resource); if (result) return result; - mutex_lock(&resource->resource_lock); - list_for_each_safe(node, next, &resource->reference) { - ref = container_of(node, struct acpi_power_reference, node); - if (dev->handle == ref->device->handle) { - list_del(&ref->node); - kfree(ref); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] removed from resource [%s] references\n", - dev->pnp.bus_id, resource->name)); - break; - } - } + if (resource->references) + resource->references--; - if (!list_empty(&resource->reference)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cannot turn resource [%s] off - resource is in use\n", - resource->name)); - mutex_unlock(&resource->resource_lock); + if (resource->references) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Resource [%s] is still in use, dereferencing\n", + resource->device->pnp.bus_id)); return 0; } - mutex_unlock(&resource->resource_lock); if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", - resource->name)); + resource->device->pnp.bus_id)); return 0; } @@ -319,7 +276,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev) arg.integer.value = 1; /* Open power resource */ for (i = 0; i < dev->wakeup.resources.count; i++) { - ret = acpi_power_on(dev->wakeup.resources.handles[i], dev); + ret = acpi_power_on(dev->wakeup.resources.handles[i]); if (ret) { printk(KERN_ERR PREFIX "Transition power state\n"); dev->wakeup.flags.valid = 0; @@ -366,7 +323,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) /* Close power resource */ for (i = 0; i < dev->wakeup.resources.count; i++) { - ret = acpi_power_off_device(dev->wakeup.resources.handles[i], dev); + ret = acpi_power_off_device(dev->wakeup.resources.handles[i]); if (ret) { printk(KERN_ERR PREFIX "Transition power state\n"); dev->wakeup.flags.valid = 0; @@ -450,20 +407,16 @@ int acpi_power_transition(struct acpi_device *device, int state) * (e.g. so the device doesn't lose power while transitioning). */ for (i = 0; i < tl->count; i++) { - result = acpi_power_on(tl->handles[i], device); + result = acpi_power_on(tl->handles[i]); if (result) goto end; } - if (device->power.state == state) { - goto end; - } - /* * Then we dereference all power resources used in the current list. */ for (i = 0; i < cl->count; i++) { - result = acpi_power_off_device(cl->handles[i], device); + result = acpi_power_off_device(cl->handles[i]); if (result) goto end; } @@ -486,11 +439,7 @@ static struct proc_dir_entry *acpi_power_dir; static int acpi_power_seq_show(struct seq_file *seq, void *offset) { - int count = 0; - int result = 0; struct acpi_power_resource *resource = NULL; - struct list_head *node, *next; - struct acpi_power_reference *ref; resource = seq->private; @@ -498,10 +447,6 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset) if (!resource) goto end; - result = acpi_power_get_state(resource); - if (result) - goto end; - seq_puts(seq, "state: "); switch (resource->state) { case ACPI_POWER_RESOURCE_STATE_ON: @@ -515,18 +460,11 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset) break; } - mutex_lock(&resource->resource_lock); - list_for_each_safe(node, next, &resource->reference) { - ref = container_of(node, struct acpi_power_reference, node); - count++; - } - mutex_unlock(&resource->resource_lock); - seq_printf(seq, "system level: S%d\n" "order: %d\n" "reference count: %d\n", resource->system_level, - resource->order, count); + resource->order, resource->references); end: return 0; @@ -599,8 +537,6 @@ static int acpi_power_add(struct acpi_device *device) return -ENOMEM; resource->device = device; - mutex_init(&resource->resource_lock); - INIT_LIST_HEAD(&resource->reference); strcpy(resource->name, device->pnp.bus_id); strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_POWER_CLASS); @@ -648,7 +584,6 @@ static int acpi_power_add(struct acpi_device *device) static int acpi_power_remove(struct acpi_device *device, int type) { struct acpi_power_resource *resource = NULL; - struct list_head *node, *next; if (!device || !acpi_driver_data(device)) @@ -658,54 +593,11 @@ static int acpi_power_remove(struct acpi_device *device, int type) acpi_power_remove_fs(device); - mutex_lock(&resource->resource_lock); - list_for_each_safe(node, next, &resource->reference) { - struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node); - list_del(&ref->node); - kfree(ref); - } - mutex_unlock(&resource->resource_lock); - kfree(resource); return 0; } -static int acpi_power_resume(struct acpi_device *device) -{ - int result = 0; - struct acpi_power_resource *resource = NULL; - struct acpi_power_reference *ref; - - if (!device || !acpi_driver_data(device)) - return -EINVAL; - - resource = (struct acpi_power_resource *)acpi_driver_data(device); - - result = acpi_power_get_state(resource); - if (result) - return result; - - mutex_lock(&resource->resource_lock); - if ((resource->state == ACPI_POWER_RESOURCE_STATE_ON) && - list_empty(&resource->reference)) { - mutex_unlock(&resource->resource_lock); - result = acpi_power_off_device(device->handle, NULL); - return result; - } - - if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) && - !list_empty(&resource->reference)) { - ref = container_of(resource->reference.next, struct acpi_power_reference, node); - mutex_unlock(&resource->resource_lock); - result = acpi_power_on(device->handle, ref->device); - return result; - } - - mutex_unlock(&resource->resource_lock); - return 0; -} - static int __init acpi_power_init(void) { int result = 0; diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 99d1516d1e70..0079bc51082c 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -60,6 +60,7 @@ #define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" +#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" #define ACPI_PROCESSOR_DEVICE_NAME "Processor" #define ACPI_PROCESSOR_FILE_INFO "info" #define ACPI_PROCESSOR_FILE_THROTTLING "throttling" @@ -73,10 +74,10 @@ #define ACPI_STA_PRESENT 0x00000001 #define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_core"); +ACPI_MODULE_NAME("acpi_processor") -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION("ACPI Processor Driver"); + MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME); MODULE_LICENSE("GPL"); static int acpi_processor_add(struct acpi_device *device); @@ -88,7 +89,7 @@ static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); static int acpi_processor_handle_eject(struct acpi_processor *pr); static struct acpi_driver acpi_processor_driver = { - .name = "processor", + .name = ACPI_PROCESSOR_DRIVER_NAME, .class = ACPI_PROCESSOR_CLASS, .ids = ACPI_PROCESSOR_HID, .ops = { @@ -403,7 +404,7 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { /* First check against id */ if (lsapic->processor_id == acpi_id) { - *apic_id = (lsapic->id << 8) | lsapic->eid; + *apic_id = lsapic->id; return 1; /* Check against optional uid */ } else if (entry->length >= 16 && @@ -1004,7 +1005,7 @@ static int __init acpi_processor_init(void) #ifdef CONFIG_SMP if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, (struct acpi_table_header **)&madt))) - madt = NULL; + madt = 0; #endif acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 60773005b8af..8206fc1ecc58 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -51,14 +51,6 @@ #include #endif -/* - * Include the apic definitions for x86 to have the APIC timer related defines - * available also for UP (on SMP it gets magically included via linux/smp.h). - */ -#ifdef CONFIG_X86 -#include -#endif - #include #include @@ -67,8 +59,9 @@ #define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" +#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" #define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_idle"); +ACPI_MODULE_NAME("acpi_processor") #define ACPI_PROCESSOR_FILE_POWER "power" #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index 2f2e7964226d..058f13cf3b79 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -44,9 +44,10 @@ #define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" +#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" #define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_perflib"); +ACPI_MODULE_NAME("acpi_processor") static DEFINE_MUTEX(performance_mutex); diff --git a/trunk/drivers/acpi/processor_thermal.c b/trunk/drivers/acpi/processor_thermal.c index 06e6f3fb8825..40fecd67ad83 100644 --- a/trunk/drivers/acpi/processor_thermal.c +++ b/trunk/drivers/acpi/processor_thermal.c @@ -41,8 +41,9 @@ #define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" +#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" #define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_thermal"); +ACPI_MODULE_NAME("acpi_processor") /* -------------------------------------------------------------------------- Limit Interface diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index b33486009f41..89dff3639abe 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -41,8 +41,9 @@ #define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" +#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" #define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_throttling"); +ACPI_MODULE_NAME("acpi_processor") /* -------------------------------------------------------------------------- Throttling Control diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index 59640d9a0acc..f58fc7447ab4 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -59,6 +59,7 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); #define ACPI_AC_CLASS "ac_adapter" #define ACPI_BATTERY_CLASS "battery" #define ACPI_SBS_HID "ACPI0002" +#define ACPI_SBS_DRIVER_NAME "ACPI Smart Battery System Driver" #define ACPI_SBS_DEVICE_NAME "Smart Battery System" #define ACPI_SBS_FILE_INFO "info" #define ACPI_SBS_FILE_STATE "state" @@ -77,7 +78,7 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); #define MAX_SBS_BAT 4 #define MAX_SMBUS_ERR 1 -ACPI_MODULE_NAME("sbs"); +ACPI_MODULE_NAME("acpi_sbs"); MODULE_AUTHOR("Rich Townsend"); MODULE_DESCRIPTION("Smart Battery System ACPI interface driver"); @@ -109,7 +110,7 @@ static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus); static void acpi_sbs_update_queue(void *data); static struct acpi_driver acpi_sbs_driver = { - .name = "sbs", + .name = ACPI_SBS_DRIVER_NAME, .class = ACPI_SBS_CLASS, .ids = ACPI_SBS_HID, .ops = { @@ -1033,19 +1034,21 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) } else { seq_printf(seq, "capacity state: ok\n"); } - - foo = (s16) battery->state.amperage * battery->info.ipscale; - if (battery->info.capacity_mode) { - foo = foo * battery->info.design_voltage / 1000; - } if (battery->state.amperage < 0) { seq_printf(seq, "charging state: discharging\n"); - seq_printf(seq, "present rate: %d %s\n", - -foo, battery->info.capacity_mode ? "mW" : "mA"); + foo = battery->state.remaining_capacity * cscale * 60 / + (battery->state.average_time_to_empty == 0 ? 1 : + battery->state.average_time_to_empty); + seq_printf(seq, "present rate: %i%s\n", + foo, battery->info.capacity_mode ? "0 mW" : " mA"); } else if (battery->state.amperage > 0) { seq_printf(seq, "charging state: charging\n"); - seq_printf(seq, "present rate: %d %s\n", - foo, battery->info.capacity_mode ? "mW" : "mA"); + foo = (battery->info.full_charge_capacity - + battery->state.remaining_capacity) * cscale * 60 / + (battery->state.average_time_to_full == 0 ? 1 : + battery->state.average_time_to_full); + seq_printf(seq, "present rate: %i%s\n", + foo, battery->info.capacity_mode ? "0 mW" : " mA"); } else { seq_printf(seq, "charging state: charged\n"); seq_printf(seq, "present rate: 0 %s\n", diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index bb0e0da39fb1..64f26db10c8e 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -11,12 +11,13 @@ #include /* for acpi_ex_eisa_id_to_string() */ #define _COMPONENT ACPI_BUS_COMPONENT -ACPI_MODULE_NAME("scan"); +ACPI_MODULE_NAME("scan") #define STRUCT_TO_INT(s) (*((int*)&s)) extern struct acpi_device *acpi_root; #define ACPI_BUS_CLASS "system_bus" #define ACPI_BUS_HID "ACPI_BUS" +#define ACPI_BUS_DRIVER_NAME "ACPI Bus Driver" #define ACPI_BUS_DEVICE_NAME "System Bus" static LIST_HEAD(acpi_device_list); diff --git a/trunk/drivers/acpi/sleep/main.c b/trunk/drivers/acpi/sleep/main.c index 37a0930fc0a6..62ce87d71651 100644 --- a/trunk/drivers/acpi/sleep/main.c +++ b/trunk/drivers/acpi/sleep/main.c @@ -200,7 +200,7 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { {}, }; -int __init acpi_sleep_init(void) +static int __init acpi_sleep_init(void) { int i = 0; @@ -229,3 +229,4 @@ int __init acpi_sleep_init(void) return 0; } +late_initcall(acpi_sleep_init); diff --git a/trunk/drivers/acpi/system.c b/trunk/drivers/acpi/system.c index 83a8d3097904..7147b0bdab0a 100644 --- a/trunk/drivers/acpi/system.c +++ b/trunk/drivers/acpi/system.c @@ -31,13 +31,14 @@ #include #define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("system"); +ACPI_MODULE_NAME("acpi_system") #ifdef MODULE_PARAM_PREFIX #undef MODULE_PARAM_PREFIX #endif #define MODULE_PARAM_PREFIX "acpi." #define ACPI_SYSTEM_CLASS "system" +#define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver" #define ACPI_SYSTEM_DEVICE_NAME "System" #define ACPI_SYSTEM_FILE_INFO "info" #define ACPI_SYSTEM_FILE_EVENT "event" diff --git a/trunk/drivers/acpi/tables.c b/trunk/drivers/acpi/tables.c index 849e2c361804..45bd17313c4a 100644 --- a/trunk/drivers/acpi/tables.c +++ b/trunk/drivers/acpi/tables.c @@ -169,40 +169,40 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header * header) int __init -acpi_table_parse_entries(char *id, - unsigned long table_size, +acpi_table_parse_madt_family(char *id, + unsigned long madt_size, int entry_id, - acpi_table_entry_handler handler, + acpi_madt_entry_handler handler, unsigned int max_entries) { - struct acpi_table_header *table_header = NULL; + struct acpi_table_header *madt = NULL; struct acpi_subtable_header *entry; unsigned int count = 0; - unsigned long table_end; + unsigned long madt_end; if (!handler) return -EINVAL; - /* Locate the table (if exists). There should only be one. */ - acpi_get_table(id, 0, &table_header); + /* Locate the MADT (if exists). There should only be one. */ + acpi_get_table(id, 0, &madt); - if (!table_header) { + if (!madt) { printk(KERN_WARNING PREFIX "%4.4s not present\n", id); return -ENODEV; } - table_end = (unsigned long)table_header + table_header->length; + madt_end = (unsigned long)madt + madt->length; /* Parse all entries looking for a match. */ entry = (struct acpi_subtable_header *) - ((unsigned long)table_header + table_size); + ((unsigned long)madt + madt_size); while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < - table_end) { + madt_end) { if (entry->type == entry_id && (!max_entries || count++ < max_entries)) - if (handler(entry, table_end)) + if (handler(entry, madt_end)) return -EINVAL; entry = (struct acpi_subtable_header *) @@ -218,22 +218,13 @@ acpi_table_parse_entries(char *id, int __init acpi_table_parse_madt(enum acpi_madt_type id, - acpi_table_entry_handler handler, unsigned int max_entries) + acpi_madt_entry_handler handler, unsigned int max_entries) { - return acpi_table_parse_entries(ACPI_SIG_MADT, + return acpi_table_parse_madt_family(ACPI_SIG_MADT, sizeof(struct acpi_table_madt), id, handler, max_entries); } -/** - * acpi_table_parse - find table with @id, run @handler on it - * - * @id: table id to find - * @handler: handler to run - * - * Scan the ACPI System Descriptor Table (STD) for a table matching @id, - * run @handler on it. Return 0 if table found, return on if not. - */ int __init acpi_table_parse(char *id, acpi_table_handler handler) { struct acpi_table_header *table = NULL; @@ -243,9 +234,9 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) acpi_get_table(id, 0, &table); if (table) { handler(table); - return 0; - } else return 1; + } else + return 0; } /* diff --git a/trunk/drivers/acpi/tables/tbxface.c b/trunk/drivers/acpi/tables/tbxface.c index 417ef5fa7666..807978d5381a 100644 --- a/trunk/drivers/acpi/tables/tbxface.c +++ b/trunk/drivers/acpi/tables/tbxface.c @@ -338,9 +338,9 @@ acpi_status acpi_unload_table_id(acpi_owner_id id) int i; acpi_status status = AE_NOT_EXIST; - ACPI_FUNCTION_TRACE(acpi_unload_table_id); + ACPI_FUNCTION_TRACE(acpi_unload_table); - /* Find table in the global table list */ + /* Find table from the requested type list */ for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { if (id != acpi_gbl_root_table_list.tables[i].owner_id) { continue; @@ -352,9 +352,8 @@ acpi_status acpi_unload_table_id(acpi_owner_id id) * simply a position within the hierarchy */ acpi_tb_delete_namespace_by_owner(i); - status = acpi_tb_release_owner_id(i); + acpi_tb_release_owner_id(i); acpi_tb_set_table_loaded_flag(i, FALSE); - break; } return_ACPI_STATUS(status); } @@ -409,7 +408,7 @@ acpi_get_table(char *signature, } if (!acpi_gbl_permanent_mmap) { - acpi_gbl_root_table_list.tables[i].pointer = NULL; + acpi_gbl_root_table_list.tables[i].pointer = 0; } return (status); diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index 0ae8b9310cbf..986afd470a14 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -47,6 +47,7 @@ #define ACPI_THERMAL_COMPONENT 0x04000000 #define ACPI_THERMAL_CLASS "thermal_zone" +#define ACPI_THERMAL_DRIVER_NAME "ACPI Thermal Zone Driver" #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" #define ACPI_THERMAL_FILE_STATE "state" #define ACPI_THERMAL_FILE_TEMPERATURE "temperature" @@ -70,10 +71,10 @@ #define CELSIUS_TO_KELVIN(t) ((t+273)*10) #define _COMPONENT ACPI_THERMAL_COMPONENT -ACPI_MODULE_NAME("thermal"); +ACPI_MODULE_NAME("acpi_thermal") MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); +MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME); MODULE_LICENSE("GPL"); static int tzp; @@ -98,7 +99,7 @@ static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, size_t, loff_t *); static struct acpi_driver acpi_thermal_driver = { - .name = "thermal", + .name = ACPI_THERMAL_DRIVER_NAME, .class = ACPI_THERMAL_CLASS, .ids = ACPI_THERMAL_HID, .ops = { @@ -269,7 +270,7 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency set to %lu seconds\n", - tz->polling_frequency/10)); + tz->polling_frequency)); return 0; } @@ -1356,32 +1357,28 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) static int acpi_thermal_resume(struct acpi_device *device) { struct acpi_thermal *tz = NULL; - int i, j, power_state, result; - + int i; if (!device || !acpi_driver_data(device)) return -EINVAL; tz = acpi_driver_data(device); + acpi_thermal_get_temperature(tz); + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - if (!(&tz->trips.active[i])) - break; - if (!tz->trips.active[i].flags.valid) - break; - tz->trips.active[i].flags.enabled = 1; - for (j = 0; j < tz->trips.active[i].devices.count; j++) { - result = acpi_bus_get_power(tz->trips.active[i].devices. - handles[j], &power_state); - if (result || (power_state != ACPI_STATE_D0)) { - tz->trips.active[i].flags.enabled = 0; - break; - } + if (tz->trips.active[i].flags.valid) { + tz->temperature = tz->trips.active[i].temperature; + tz->trips.active[i].flags.enabled = 0; + + acpi_thermal_active(tz); + + tz->state.active |= tz->trips.active[i].flags.enabled; + tz->state.active_index = i; } - tz->state.active |= tz->trips.active[i].flags.enabled; } - acpi_thermal_check(tz); + acpi_thermal_check(tz); return AE_OK; } diff --git a/trunk/drivers/acpi/toshiba_acpi.c b/trunk/drivers/acpi/toshiba_acpi.c index faf8a5232d8e..d9b651ffcdc0 100644 --- a/trunk/drivers/acpi/toshiba_acpi.c +++ b/trunk/drivers/acpi/toshiba_acpi.c @@ -125,7 +125,7 @@ static int write_acpi_int(const char *methodName, int val) union acpi_object in_objs[1]; acpi_status status; - params.count = ARRAY_SIZE(in_objs); + params.count = sizeof(in_objs) / sizeof(in_objs[0]); params.pointer = in_objs; in_objs[0].type = ACPI_TYPE_INTEGER; in_objs[0].integer.value = val; @@ -561,6 +561,10 @@ static int __init toshiba_acpi_init(void) if (acpi_disabled) return -ENODEV; + if (!acpi_specific_hotkey_enabled) { + printk(MY_INFO "Using generic hotkey driver\n"); + return -ENODEV; + } /* simple device detection: look for HCI method */ if (is_valid_acpi_path(METHOD_HCI_1)) method_hci = METHOD_HCI_1; diff --git a/trunk/drivers/acpi/utilities/utdelete.c b/trunk/drivers/acpi/utilities/utdelete.c index 673a0caa4073..f777cebdc46d 100644 --- a/trunk/drivers/acpi/utilities/utdelete.c +++ b/trunk/drivers/acpi/utilities/utdelete.c @@ -170,6 +170,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) acpi_os_delete_mutex(object->mutex.os_mutex); acpi_gbl_global_lock_mutex = NULL; } else { + acpi_ex_unlink_mutex(object); acpi_os_delete_mutex(object->mutex.os_mutex); } break; diff --git a/trunk/drivers/acpi/utils.c b/trunk/drivers/acpi/utils.c index 34f157571080..68a809fa7b19 100644 --- a/trunk/drivers/acpi/utils.c +++ b/trunk/drivers/acpi/utils.c @@ -31,7 +31,7 @@ #include #define _COMPONENT ACPI_BUS_COMPONENT -ACPI_MODULE_NAME("utils"); +ACPI_MODULE_NAME("acpi_utils") /* -------------------------------------------------------------------------- Object Evaluation Helpers diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index bf525cca3b63..e0b97add8c63 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -40,6 +40,7 @@ #define ACPI_VIDEO_COMPONENT 0x08000000 #define ACPI_VIDEO_CLASS "video" +#define ACPI_VIDEO_DRIVER_NAME "ACPI Video Driver" #define ACPI_VIDEO_BUS_NAME "Video Bus" #define ACPI_VIDEO_DEVICE_NAME "Video Device" #define ACPI_VIDEO_NOTIFY_SWITCH 0x80 @@ -64,17 +65,17 @@ #define ACPI_VIDEO_DISPLAY_LCD 4 #define _COMPONENT ACPI_VIDEO_COMPONENT -ACPI_MODULE_NAME("video"); +ACPI_MODULE_NAME("acpi_video") -MODULE_AUTHOR("Bruno Ducrot"); -MODULE_DESCRIPTION("ACPI Video Driver"); + MODULE_AUTHOR("Bruno Ducrot"); +MODULE_DESCRIPTION(ACPI_VIDEO_DRIVER_NAME); MODULE_LICENSE("GPL"); static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_remove(struct acpi_device *device, int type); static struct acpi_driver acpi_video_bus = { - .name = "video", + .name = ACPI_VIDEO_DRIVER_NAME, .class = ACPI_VIDEO_CLASS, .ids = ACPI_VIDEO_HID, .ops = { diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index 80b199fa0aa9..bedae4ad3f74 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -107,19 +107,4 @@ config MSI_LAPTOP If you have an MSI S270 laptop, say Y or M here. -config SONY_LAPTOP - tristate "Sony Laptop Extras" - depends on X86 && ACPI - select BACKLIGHT_CLASS_DEVICE - ---help--- - This mini-driver drives the SNC device present in the ACPI BIOS of - the Sony Vaio laptops. - - It gives access to some extra laptop functionalities. In its current - form, this driver let the user set or query the screen brightness - through the backlight subsystem and remove/apply power to some - devices. - - Read for more information. - endmenu diff --git a/trunk/drivers/misc/Makefile b/trunk/drivers/misc/Makefile index 7793ccd79049..35da53c409c0 100644 --- a/trunk/drivers/misc/Makefile +++ b/trunk/drivers/misc/Makefile @@ -11,4 +11,3 @@ obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_SGI_IOC4) += ioc4.o -obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o diff --git a/trunk/drivers/misc/asus-laptop.c b/trunk/drivers/misc/asus-laptop.c index e4e2b707a353..861c39935f99 100644 --- a/trunk/drivers/misc/asus-laptop.c +++ b/trunk/drivers/misc/asus-laptop.c @@ -1088,6 +1088,11 @@ static int __init asus_laptop_init(void) if (acpi_disabled) return -ENODEV; + if (!acpi_specific_hotkey_enabled) { + printk(ASUS_ERR "Using generic hotkey driver\n"); + return -ENODEV; + } + result = acpi_bus_register_driver(&asus_hotk_driver); if (result < 0) return result; diff --git a/trunk/drivers/misc/sony-laptop.c b/trunk/drivers/misc/sony-laptop.c deleted file mode 100644 index cabbed0015e4..000000000000 --- a/trunk/drivers/misc/sony-laptop.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * ACPI Sony Notebook Control Driver (SNC) - * - * Copyright (C) 2004-2005 Stelian Pop - * Copyright (C) 2007 Mattia Dongili - * - * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c - * which are copyrighted by their respective authors. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ACPI_SNC_CLASS "sony" -#define ACPI_SNC_HID "SNY5001" -#define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.4" - -/* the device uses 1-based values, while the backlight subsystem uses - 0-based values */ -#define SONY_MAX_BRIGHTNESS 8 - -#define LOG_PFX KERN_WARNING "sony-laptop: " - -MODULE_AUTHOR("Stelian Pop, Mattia Dongili"); -MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " - "the development of this driver"); - -static ssize_t sony_acpi_show(struct device *, struct device_attribute *, - char *); -static ssize_t sony_acpi_store(struct device *, struct device_attribute *, - const char *, size_t); -static int boolean_validate(const int, const int); -static int brightness_default_validate(const int, const int); - -#define SNC_VALIDATE_IN 0 -#define SNC_VALIDATE_OUT 1 - -struct sony_acpi_value { - char *name; /* name of the entry */ - char **acpiget; /* names of the ACPI get function */ - char **acpiset; /* names of the ACPI set function */ - int (*validate)(const int, const int); /* input/output validation */ - int value; /* current setting */ - int valid; /* Has ever been set */ - int debug; /* active only in debug mode ? */ - struct device_attribute devattr; /* sysfs atribute */ -}; - -#define HANDLE_NAMES(_name, _values...) \ - static char *snc_##_name[] = { _values, NULL } - -#define SONY_ACPI_VALUE(_name, _getters, _setters, _validate, _debug) \ - { \ - .name = __stringify(_name), \ - .acpiget = _getters, \ - .acpiset = _setters, \ - .validate = _validate, \ - .debug = _debug, \ - .devattr = __ATTR(_name, 0, sony_acpi_show, sony_acpi_store), \ - } - -#define SONY_ACPI_VALUE_NULL { .name = NULL } - -HANDLE_NAMES(fnkey_get, "GHKE"); - -HANDLE_NAMES(brightness_def_get, "GPBR"); -HANDLE_NAMES(brightness_def_set, "SPBR"); - -HANDLE_NAMES(cdpower_get, "GCDP"); -HANDLE_NAMES(cdpower_set, "SCDP", "CDPW"); - -HANDLE_NAMES(audiopower_get, "GAZP"); -HANDLE_NAMES(audiopower_set, "AZPW"); - -HANDLE_NAMES(lanpower_get, "GLNP"); -HANDLE_NAMES(lanpower_set, "LNPW"); - -HANDLE_NAMES(PID_get, "GPID"); - -HANDLE_NAMES(CTR_get, "GCTR"); -HANDLE_NAMES(CTR_set, "SCTR"); - -HANDLE_NAMES(PCR_get, "GPCR"); -HANDLE_NAMES(PCR_set, "SPCR"); - -HANDLE_NAMES(CMI_get, "GCMI"); -HANDLE_NAMES(CMI_set, "SCMI"); - -static struct sony_acpi_value sony_acpi_values[] = { - SONY_ACPI_VALUE(brightness_default, snc_brightness_def_get, - snc_brightness_def_set, brightness_default_validate, 0), - SONY_ACPI_VALUE(fnkey, snc_fnkey_get, NULL, NULL, 0), - SONY_ACPI_VALUE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0), - SONY_ACPI_VALUE(audiopower, snc_audiopower_get, snc_audiopower_set, - boolean_validate, 0), - SONY_ACPI_VALUE(lanpower, snc_lanpower_get, snc_lanpower_set, - boolean_validate, 1), - /* unknown methods */ - SONY_ACPI_VALUE(PID, snc_PID_get, NULL, NULL, 1), - SONY_ACPI_VALUE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), - SONY_ACPI_VALUE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1), - SONY_ACPI_VALUE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1), - SONY_ACPI_VALUE_NULL -}; - -static acpi_handle sony_acpi_handle; -static struct acpi_device *sony_acpi_acpi_device = NULL; - -/* - * acpi_evaluate_object wrappers - */ -static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) -{ - struct acpi_buffer output; - union acpi_object out_obj; - acpi_status status; - - output.length = sizeof(out_obj); - output.pointer = &out_obj; - - status = acpi_evaluate_object(handle, name, NULL, &output); - if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) { - *result = out_obj.integer.value; - return 0; - } - - printk(LOG_PFX "acpi_callreadfunc failed\n"); - - return -1; -} - -static int acpi_callsetfunc(acpi_handle handle, char *name, int value, - int *result) -{ - struct acpi_object_list params; - union acpi_object in_obj; - struct acpi_buffer output; - union acpi_object out_obj; - acpi_status status; - - params.count = 1; - params.pointer = &in_obj; - in_obj.type = ACPI_TYPE_INTEGER; - in_obj.integer.value = value; - - output.length = sizeof(out_obj); - output.pointer = &out_obj; - - status = acpi_evaluate_object(handle, name, ¶ms, &output); - if (status == AE_OK) { - if (result != NULL) { - if (out_obj.type != ACPI_TYPE_INTEGER) { - printk(LOG_PFX "acpi_evaluate_object bad " - "return type\n"); - return -1; - } - *result = out_obj.integer.value; - } - return 0; - } - - printk(LOG_PFX "acpi_evaluate_object failed\n"); - - return -1; -} - -/* - * sony_acpi_values input/output validate functions - */ - -/* brightness_default_validate: - * - * manipulate input output values to keep consistency with the - * backlight framework for which brightness values are 0-based. - */ -static int brightness_default_validate(const int direction, const int value) -{ - switch (direction) { - case SNC_VALIDATE_OUT: - return value - 1; - case SNC_VALIDATE_IN: - if (value >= 0 && value < SONY_MAX_BRIGHTNESS) - return value + 1; - } - return -EINVAL; -} - -/* boolean_validate: - * - * on input validate boolean values 0/1, on output just pass the - * received value. - */ -static int boolean_validate(const int direction, const int value) -{ - if (direction == SNC_VALIDATE_IN) { - if (value != 0 && value != 1) - return -EINVAL; - } - return value; -} - -/* - * Sysfs show/store common to all sony_acpi_values - */ -static ssize_t sony_acpi_show(struct device *dev, struct device_attribute *attr, - char *buffer) -{ - int value; - struct sony_acpi_value *item = - container_of(attr, struct sony_acpi_value, devattr); - - if (!*item->acpiget) - return -EIO; - - if (acpi_callgetfunc(sony_acpi_handle, *item->acpiget, &value) < 0) - return -EIO; - - if (item->validate) - value = item->validate(SNC_VALIDATE_OUT, value); - - return snprintf(buffer, PAGE_SIZE, "%d\n", value); -} - -static ssize_t sony_acpi_store(struct device *dev, - struct device_attribute *attr, - const char *buffer, size_t count) -{ - int value; - struct sony_acpi_value *item = - container_of(attr, struct sony_acpi_value, devattr); - - if (!item->acpiset) - return -EIO; - - if (count > 31) - return -EINVAL; - - value = simple_strtoul(buffer, NULL, 10); - - if (item->validate) - value = item->validate(SNC_VALIDATE_IN, value); - - if (value < 0) - return value; - - if (acpi_callsetfunc(sony_acpi_handle, *item->acpiset, value, NULL) < 0) - return -EIO; - item->value = value; - item->valid = 1; - return count; -} - -/* - * Platform device - */ -static struct platform_driver sncpf_driver = { - .driver = { - .name = "sony-laptop", - .owner = THIS_MODULE, - } -}; -static struct platform_device *sncpf_device; - -static int sony_snc_pf_add(void) -{ - acpi_handle handle; - struct sony_acpi_value *item; - int ret = 0; - - ret = platform_driver_register(&sncpf_driver); - if (ret) - goto out; - - sncpf_device = platform_device_alloc("sony-laptop", -1); - if (!sncpf_device) { - ret = -ENOMEM; - goto out_platform_registered; - } - - ret = platform_device_add(sncpf_device); - if (ret) - goto out_platform_alloced; - - for (item = sony_acpi_values; item->name; ++item) { - - if (!debug && item->debug) - continue; - - /* find the available acpiget as described in the DSDT */ - for (; item->acpiget && *item->acpiget; ++item->acpiget) { - if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, - *item->acpiget, - &handle))) { - if (debug) - printk(LOG_PFX "Found %s getter: %s\n", - item->name, *item->acpiget); - item->devattr.attr.mode |= S_IRUGO; - break; - } - } - - /* find the available acpiset as described in the DSDT */ - for (; item->acpiset && *item->acpiset; ++item->acpiset) { - if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, - *item->acpiset, - &handle))) { - if (debug) - printk(LOG_PFX "Found %s setter: %s\n", - item->name, *item->acpiset); - item->devattr.attr.mode |= S_IWUSR; - break; - } - } - - if (item->devattr.attr.mode != 0) { - ret = - device_create_file(&sncpf_device->dev, - &item->devattr); - if (ret) - goto out_sysfs; - } - } - - return 0; - - out_sysfs: - for (item = sony_acpi_values; item->name; ++item) { - device_remove_file(&sncpf_device->dev, &item->devattr); - } - platform_device_del(sncpf_device); - out_platform_alloced: - platform_device_put(sncpf_device); - out_platform_registered: - platform_driver_unregister(&sncpf_driver); - out: - return ret; -} - -static void sony_snc_pf_remove(void) -{ - struct sony_acpi_value *item; - - for (item = sony_acpi_values; item->name; ++item) { - device_remove_file(&sncpf_device->dev, &item->devattr); - } - - platform_device_del(sncpf_device); - platform_device_put(sncpf_device); - platform_driver_unregister(&sncpf_driver); -} - -/* - * Backlight device - */ -static int sony_backlight_update_status(struct backlight_device *bd) -{ - return acpi_callsetfunc(sony_acpi_handle, "SBRT", - bd->props->brightness + 1, NULL); -} - -static int sony_backlight_get_brightness(struct backlight_device *bd) -{ - int value; - - if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value)) - return 0; - /* brightness levels are 1-based, while backlight ones are 0-based */ - return value - 1; -} - -static struct backlight_device *sony_backlight_device; -static struct backlight_properties sony_backlight_properties = { - .owner = THIS_MODULE, - .update_status = sony_backlight_update_status, - .get_brightness = sony_backlight_get_brightness, - .max_brightness = SONY_MAX_BRIGHTNESS - 1, -}; - -/* - * ACPI callbacks - */ -static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) -{ - if (debug) - printk(LOG_PFX "sony_acpi_notify, event: %d\n", event); - acpi_bus_generate_event(sony_acpi_acpi_device, 1, event); -} - -static acpi_status sony_walk_callback(acpi_handle handle, u32 level, - void *context, void **return_value) -{ - struct acpi_namespace_node *node; - union acpi_operand_object *operand; - - node = (struct acpi_namespace_node *)handle; - operand = (union acpi_operand_object *)node->object; - - printk(LOG_PFX "method: name: %4.4s, args %X\n", node->name.ascii, - (u32) operand->method.param_count); - - return AE_OK; -} - -/* - * ACPI device - */ -static int sony_acpi_resume(struct acpi_device *device) -{ - struct sony_acpi_value *item; - - for (item = sony_acpi_values; item->name; item++) { - int ret; - - if (!item->valid) - continue; - ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset, - item->value, NULL); - if (ret < 0) { - printk("%s: %d\n", __FUNCTION__, ret); - break; - } - } - return 0; -} - -static int sony_acpi_add(struct acpi_device *device) -{ - acpi_status status; - int result; - acpi_handle handle; - - sony_acpi_acpi_device = device; - - sony_acpi_handle = device->handle; - - if (debug) { - status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle, - 1, sony_walk_callback, NULL, NULL); - if (ACPI_FAILURE(status)) { - printk(LOG_PFX "unable to walk acpi resources\n"); - result = -ENODEV; - goto outwalk; - } - } - - status = acpi_install_notify_handler(sony_acpi_handle, - ACPI_DEVICE_NOTIFY, - sony_acpi_notify, NULL); - if (ACPI_FAILURE(status)) { - printk(LOG_PFX "unable to install notify handler\n"); - result = -ENODEV; - goto outwalk; - } - - if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) { - sony_backlight_device = backlight_device_register("sony", NULL, - NULL, - &sony_backlight_properties); - - if (IS_ERR(sony_backlight_device)) { - printk(LOG_PFX "unable to register backlight device\n"); - sony_backlight_device = NULL; - } else - sony_backlight_properties.brightness = - sony_backlight_get_brightness - (sony_backlight_device); - } - - if (sony_snc_pf_add()) - goto outbacklight; - - printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n"); - - return 0; - - outbacklight: - if (sony_backlight_device) - backlight_device_unregister(sony_backlight_device); - - status = acpi_remove_notify_handler(sony_acpi_handle, - ACPI_DEVICE_NOTIFY, - sony_acpi_notify); - if (ACPI_FAILURE(status)) - printk(LOG_PFX "unable to remove notify handler\n"); - outwalk: - return result; -} - -static int sony_acpi_remove(struct acpi_device *device, int type) -{ - acpi_status status; - - if (sony_backlight_device) - backlight_device_unregister(sony_backlight_device); - - sony_acpi_acpi_device = NULL; - - status = acpi_remove_notify_handler(sony_acpi_handle, - ACPI_DEVICE_NOTIFY, - sony_acpi_notify); - if (ACPI_FAILURE(status)) - printk(LOG_PFX "unable to remove notify handler\n"); - - sony_snc_pf_remove(); - - printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n"); - - return 0; -} - -static struct acpi_driver sony_acpi_driver = { - .name = ACPI_SNC_DRIVER_NAME, - .class = ACPI_SNC_CLASS, - .ids = ACPI_SNC_HID, - .ops = { - .add = sony_acpi_add, - .remove = sony_acpi_remove, - .resume = sony_acpi_resume, - }, -}; - -static int __init sony_acpi_init(void) -{ - return acpi_bus_register_driver(&sony_acpi_driver); -} - -static void __exit sony_acpi_exit(void) -{ - acpi_bus_unregister_driver(&sony_acpi_driver); -} - -module_init(sony_acpi_init); -module_exit(sony_acpi_exit); diff --git a/trunk/drivers/pnp/pnpacpi/Kconfig b/trunk/drivers/pnp/pnpacpi/Kconfig index b04767ce273e..ad27e5e0101f 100644 --- a/trunk/drivers/pnp/pnpacpi/Kconfig +++ b/trunk/drivers/pnp/pnpacpi/Kconfig @@ -2,5 +2,17 @@ # Plug and Play ACPI configuration # config PNPACPI - bool - default (PNP && ACPI) + bool "Plug and Play ACPI support" + depends on PNP && ACPI + default y + ---help--- + Linux uses the PNPACPI to autodetect built-in + mainboard resources (e.g. parallel port resources). + + Some features (e.g. real hotplug) are not currently + implemented. + + If you would like the kernel to detect and allocate resources to + your mainboard devices (on some systems they are disabled by the + BIOS) say Y here. Also the PNPACPI can help prevent resource + conflicts between mainboard devices and other bus devices. diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 185721dba42b..6bf909e1adf0 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -299,6 +299,19 @@ static void ehci_watchdog (unsigned long param) spin_unlock_irqrestore (&ehci->lock, flags); } +/* On some systems, leaving remote wakeup enabled prevents system shutdown. + * The firmware seems to think that powering off is a wakeup event! + * This routine turns off remote wakeup and everything else, on all ports. + */ +static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) +{ + int port = HCS_N_PORTS(ehci->hcs_params); + + while (port--) + ehci_writel(ehci, PORT_RWC_BITS, + &ehci->regs->port_status[port]); +} + /* ehci_shutdown kick in for silicon on any bus (not just pci, etc). * This forcibly disables dma and IRQs, helping kexec and other cases * where the next system software may expect clean state. @@ -310,9 +323,13 @@ ehci_shutdown (struct usb_hcd *hcd) ehci = hcd_to_ehci (hcd); (void) ehci_halt (ehci); + ehci_turn_off_all_ports(ehci); /* make BIOS/etc use companion controller during reboot */ ehci_writel(ehci, 0, &ehci->regs->configured_flag); + + /* unblock posted writes */ + ehci_readl(ehci, &ehci->regs->configured_flag); } static void ehci_port_power (struct ehci_hcd *ehci, int is_on) diff --git a/trunk/drivers/usb/misc/appledisplay.c b/trunk/drivers/usb/misc/appledisplay.c index e573c8ba9785..32f0e3a5b022 100644 --- a/trunk/drivers/usb/misc/appledisplay.c +++ b/trunk/drivers/usb/misc/appledisplay.c @@ -281,8 +281,8 @@ static int appledisplay_probe(struct usb_interface *iface, /* Register backlight device */ snprintf(bl_name, sizeof(bl_name), "appledisplay%d", atomic_inc_return(&count_displays) - 1); - pdata->bd = backlight_device_register(bl_name, NULL, pdata, - &appledisplay_bl_data); + pdata->bd = backlight_device_register(bl_name, NULL, + pdata, &appledisplay_bl_data); if (IS_ERR(pdata->bd)) { err("appledisplay: Backlight registration failed"); goto error; diff --git a/trunk/include/acpi/acinterp.h b/trunk/include/acpi/acinterp.h index 73967c8152d3..ce7c9d653910 100644 --- a/trunk/include/acpi/acinterp.h +++ b/trunk/include/acpi/acinterp.h @@ -253,8 +253,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread); -void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc, - struct acpi_thread_state *thread); +void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc); /* * exprep - ACPI AML execution - prep utilities diff --git a/trunk/include/acpi/acobject.h b/trunk/include/acpi/acobject.h index 5206d61d74a6..04e9735a6742 100644 --- a/trunk/include/acpi/acobject.h +++ b/trunk/include/acpi/acobject.h @@ -155,7 +155,7 @@ struct acpi_object_event { struct acpi_object_mutex { ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */ u16 acquisition_depth; /* Allow multiple Acquires, same thread */ - acpi_thread_id owner_thread_id; /* Current owner of the mutex */ + struct acpi_thread_state *owner_thread; /* Current owner of the mutex */ acpi_mutex os_mutex; /* Actual OS synchronization object */ union acpi_operand_object *prev; /* Link for list of acquired mutexes */ union acpi_operand_object *next; /* Link for list of acquired mutexes */ diff --git a/trunk/include/acpi/acpi_drivers.h b/trunk/include/acpi/acpi_drivers.h index f6275b0e66dd..4dc8a5043ef0 100644 --- a/trunk/include/acpi/acpi_drivers.h +++ b/trunk/include/acpi/acpi_drivers.h @@ -105,6 +105,12 @@ int acpi_ec_ecdt_probe(void); int acpi_processor_set_thermal_limit(acpi_handle handle, int type); +/* -------------------------------------------------------------------------- + Hot Keys + -------------------------------------------------------------------------- */ + +extern int acpi_specific_hotkey_enabled; + /*-------------------------------------------------------------------------- Dock Station -------------------------------------------------------------------------- */ @@ -116,34 +122,10 @@ extern int register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler, void *context); extern void unregister_hotplug_dock_device(acpi_handle handle); #else -static inline int is_dock_device(acpi_handle handle) -{ - return 0; -} -static inline int register_dock_notifier(struct notifier_block *nb) -{ - return -ENODEV; -} -static inline void unregister_dock_notifier(struct notifier_block *nb) -{ -} -static inline int register_hotplug_dock_device(acpi_handle handle, - acpi_notify_handler handler, void *context) -{ - return -ENODEV; -} -static inline void unregister_hotplug_dock_device(acpi_handle handle) -{ -} -#endif - -/*-------------------------------------------------------------------------- - Suspend/Resume - -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_SLEEP -extern int acpi_sleep_init(void); -#else -#define acpi_sleep_init() do {} while (0) +#define is_dock_device(h) (0) +#define register_dock_notifier(nb) (-ENODEV) +#define unregister_dock_notifier(nb) do { } while(0) +#define register_hotplug_dock_device(h1, h2, c) (-ENODEV) +#define unregister_hotplug_dock_device(h) do { } while(0) #endif - #endif /*__ACPI_DRIVERS_H__*/ diff --git a/trunk/include/acpi/acpiosxf.h b/trunk/include/acpi/acpiosxf.h index 2785058c82ab..781394b9efe0 100644 --- a/trunk/include/acpi/acpiosxf.h +++ b/trunk/include/acpi/acpiosxf.h @@ -240,6 +240,12 @@ acpi_status acpi_os_validate_address(u8 space_id, acpi_physical_address address, acpi_size length); +u8 acpi_os_readable(void *pointer, acpi_size length); + +#ifdef ACPI_FUTURE_USAGE +u8 acpi_os_writable(void *pointer, acpi_size length); +#endif + u64 acpi_os_get_timer(void); acpi_status acpi_os_signal(u32 function, void *info); diff --git a/trunk/include/asm-i386/acpi.h b/trunk/include/asm-i386/acpi.h index 449f3f272e07..5e657eb8946c 100644 --- a/trunk/include/asm-i386/acpi.h +++ b/trunk/include/asm-i386/acpi.h @@ -127,7 +127,6 @@ extern int acpi_irq_balance_set(char *str); #define acpi_ioapic 0 static inline void acpi_noirq_set(void) { } static inline void acpi_disable_pci(void) { } -static inline void disable_acpi(void) { } #endif /* !CONFIG_ACPI */ diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 8bcfaa4c66ae..815f1fb4ce21 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -75,7 +75,7 @@ enum acpi_address_range_id { typedef int (*acpi_table_handler) (struct acpi_table_header *table); -typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); +typedef int (*acpi_madt_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); char * __acpi_map_table (unsigned long phys_addr, unsigned long size); unsigned long acpi_find_rsdp (void); @@ -85,10 +85,8 @@ int acpi_numa_init (void); int acpi_table_init (void); int acpi_table_parse (char *id, acpi_table_handler handler); -int __init acpi_table_parse_entries(char *id, unsigned long table_size, - int entry_id, acpi_table_entry_handler handler, unsigned int max_entries); -int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries); -int acpi_table_parse_srat (enum acpi_srat_type id, acpi_table_entry_handler handler, unsigned int max_entries); +int acpi_table_parse_madt (enum acpi_madt_type id, acpi_madt_entry_handler handler, unsigned int max_entries); +int acpi_table_parse_srat (enum acpi_srat_type id, acpi_madt_entry_handler handler, unsigned int max_entries); int acpi_parse_mcfg (struct acpi_table_header *header); void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); void acpi_table_print_srat_entry (struct acpi_subtable_header *srat);