diff --git a/[refs] b/[refs] index 1b0cba77e070..3c2b81ae7dac 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e6532b8883760bdf9d251c669a3919fc9457aeca +refs/heads/master: 0af2f653c504d302d83d3a648c0408882ff62d4c diff --git a/trunk/Documentation/thinkpad-acpi.txt b/trunk/Documentation/thinkpad-acpi.txt index 10c041ca13c7..ec499265deca 100644 --- a/trunk/Documentation/thinkpad-acpi.txt +++ b/trunk/Documentation/thinkpad-acpi.txt @@ -1,7 +1,7 @@ ThinkPad ACPI Extras Driver - Version 0.17 - October 04th, 2007 + Version 0.16 + August 2nd, 2007 Borislav Deianov Henrique de Moraes Holschuh @@ -923,34 +923,19 @@ sysfs backlight device "thinkpad_screen" This feature allows software control of the LCD brightness on ThinkPad models which don't have a hardware brightness slider. -It has some limitations: the LCD backlight cannot be actually turned on or -off by this interface, and in many ThinkPad models, the "dim while on -battery" functionality will be enabled by the BIOS when this interface is -used, and cannot be controlled. - -On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control -has eight brightness levels, ranging from 0 to 7. Some of the levels -may not be distinct. Later Lenovo models that implement the ACPI -display backlight brightness control methods have 16 levels, ranging -from 0 to 15. - -There are two interfaces to the firmware for direct brightness control, -EC and CMOS. To select which one should be used, use the -brightness_mode module parameter: brightness_mode=1 selects EC mode, -brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC -and CMOS. The driver tries to autodetect which interface to use. - -When display backlight brightness controls are available through the -standard ACPI interface, it is best to use it instead of this direct -ThinkPad-specific interface. The driver will disable its native -backlight brightness control interface if it detects that the standard -ACPI interface is available in the ThinkPad. - -The brightness_enable module parameter can be used to control whether -the LCD brightness control feature will be enabled when available. -brightness_enable=0 forces it to be disabled. brightness_enable=1 -forces it to be enabled when available, even if the standard ACPI -interface is also available. +It has some limitations: the LCD backlight cannot be actually turned on or off +by this interface, and in many ThinkPad models, the "dim while on battery" +functionality will be enabled by the BIOS when this interface is used, and +cannot be controlled. + +The backlight control has eight levels, ranging from 0 to 7. Some of the +levels may not be distinct. + +There are two interfaces to the firmware for brightness control, EC and CMOS. +To select which one should be used, use the brightness_mode module parameter: +brightness_mode=1 selects EC mode, brightness_mode=2 selects CMOS mode, +brightness_mode=3 selects both EC and CMOS. The driver tries to autodetect +which interface to use. Procfs notes: @@ -962,11 +947,11 @@ Procfs notes: Sysfs notes: -The interface is implemented through the backlight sysfs class, which is -poorly documented at this time. +The interface is implemented through the backlight sysfs class, which is poorly +documented at this time. -Locate the thinkpad_screen device under /sys/class/backlight, and inside -it there will be the following attributes: +Locate the thinkpad_screen device under /sys/class/backlight, and inside it +there will be the following attributes: max_brightness: Reads the maximum brightness the hardware can be set to. @@ -976,19 +961,17 @@ it there will be the following attributes: Reads what brightness the screen is set to at this instant. brightness: - Writes request the driver to change brightness to the - given value. Reads will tell you what brightness the - driver is trying to set the display to when "power" is set - to zero and the display has not been dimmed by a kernel - power management event. + Writes request the driver to change brightness to the given + value. Reads will tell you what brightness the driver is trying + to set the display to when "power" is set to zero and the display + has not been dimmed by a kernel power management event. power: - power management mode, where 0 is "display on", and 1 to 3 - will dim the display backlight to brightness level 0 - because thinkpad-acpi cannot really turn the backlight - off. Kernel power management events can temporarily - increase the current power management level, i.e. they can - dim the display. + power management mode, where 0 is "display on", and 1 to 3 will + dim the display backlight to brightness level 0 because + thinkpad-acpi cannot really turn the backlight off. Kernel + power management events can temporarily increase the current + power management level, i.e. they can dim the display. Volume control -- /proc/acpi/ibm/volume diff --git a/trunk/arch/x86/kernel/acpi/processor.c b/trunk/arch/x86/kernel/acpi/processor.c index a25db514c719..f63e5ff0aca1 100644 --- a/trunk/arch/x86/kernel/acpi/processor.c +++ b/trunk/arch/x86/kernel/acpi/processor.c @@ -49,9 +49,6 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) if (cpu_has(c, X86_FEATURE_EST)) buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; - if (cpu_has(c, X86_FEATURE_ACPI)) - buf[2] |= ACPI_PDC_T_FFH; - obj->type = ACPI_TYPE_BUFFER; obj->buffer.length = 12; obj->buffer.pointer = (u8 *) buf; diff --git a/trunk/arch/x86/kernel/acpi/sleep_64.c b/trunk/arch/x86/kernel/acpi/sleep_64.c index da42de261ba8..79475d237071 100644 --- a/trunk/arch/x86/kernel/acpi/sleep_64.c +++ b/trunk/arch/x86/kernel/acpi/sleep_64.c @@ -115,3 +115,6 @@ static int __init acpi_sleep_setup(char *str) __setup("acpi_sleep=", acpi_sleep_setup); +void acpi_pci_link_exit(void) +{ +} diff --git a/trunk/arch/x86/kernel/io_apic_32.c b/trunk/arch/x86/kernel/io_apic_32.c index 6bb80ea5f4ee..f35c6eb33da9 100644 --- a/trunk/arch/x86/kernel/io_apic_32.c +++ b/trunk/arch/x86/kernel/io_apic_32.c @@ -962,7 +962,7 @@ static int EISA_ELCR(unsigned int irq) #define default_MCA_trigger(idx) (1) #define default_MCA_polarity(idx) (0) -static int MPBIOS_polarity(int idx) +static int __init MPBIOS_polarity(int idx) { int bus = mp_irqs[idx].mpc_srcbus; int polarity; @@ -2830,25 +2830,6 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a return 0; } -int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) -{ - int i; - - if (skip_ioapic_setup) - return -1; - - for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].mpc_irqtype == mp_INT && - mp_irqs[i].mpc_srcbusirq == bus_irq) - break; - if (i >= mp_irq_entries) - return -1; - - *trigger = irq_trigger(i); - *polarity = irq_polarity(i); - return 0; -} - #endif /* CONFIG_ACPI */ static int __init parse_disable_timer_pin_1(char *arg) diff --git a/trunk/arch/x86/kernel/io_apic_64.c b/trunk/arch/x86/kernel/io_apic_64.c index 435a8c9b55f8..953328b55a30 100644 --- a/trunk/arch/x86/kernel/io_apic_64.c +++ b/trunk/arch/x86/kernel/io_apic_64.c @@ -546,7 +546,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) #define default_PCI_trigger(idx) (1) #define default_PCI_polarity(idx) (1) -static int MPBIOS_polarity(int idx) +static int __init MPBIOS_polarity(int idx) { int bus = mp_irqs[idx].mpc_srcbus; int polarity; @@ -2222,28 +2222,9 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p return 0; } - -int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) -{ - int i; - - if (skip_ioapic_setup) - return -1; - - for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].mpc_irqtype == mp_INT && - mp_irqs[i].mpc_srcbusirq == bus_irq) - break; - if (i >= mp_irq_entries) - return -1; - - *trigger = irq_trigger(i); - *polarity = irq_polarity(i); - return 0; -} - #endif /* CONFIG_ACPI */ + /* * This function currently is only a helper for the i386 smp boot process where * we need to reprogram the ioredtbls to cater for the cpus which have come online @@ -2279,4 +2260,3 @@ void __init setup_ioapic_dest(void) } } #endif - diff --git a/trunk/arch/x86/pci/acpi.c b/trunk/arch/x86/pci/acpi.c index 0234f2831bf3..7e35078673a4 100644 --- a/trunk/arch/x86/pci/acpi.c +++ b/trunk/arch/x86/pci/acpi.c @@ -13,7 +13,7 @@ static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) return 0; } -static struct dmi_system_id acpi_pciprobe_dmi_table[] __devinitdata = { +static struct dmi_system_id acpi_pciprobe_dmi_table[] = { /* * Systems where PCI IO resource ISA alignment can be skipped * when the ISA enable bit in the bridge control is not set diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index b9f923ef173d..087a7028ae84 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -50,6 +50,7 @@ config ACPI_SLEEP config ACPI_PROCFS bool "Deprecated /proc/acpi files" depends on PROC_FS + default y ---help--- For backwards compatibility, this option allows deprecated /proc/acpi/ files to exist, even when @@ -60,6 +61,7 @@ config ACPI_PROCFS /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version) /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT) /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) + /proc/acpi/battery (/sys/class/power_supply) /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) @@ -67,21 +69,7 @@ config ACPI_PROCFS and functions which do not yet exist in /sys. Say N to delete /proc/acpi/ files that have moved to /sys/ -config ACPI_PROCFS_POWER - bool "Deprecated power /proc/acpi folders" - depends on PROC_FS - default y - ---help--- - For backwards compatibility, this option allows - deprecated power /proc/acpi/ folders to exist, even when - they have been replaced by functions in /sys. - The deprecated folders (and their replacements) include: - /proc/acpi/battery/* (/sys/class/power_supply/*) - /proc/acpi/ac_adapter/* (sys/class/power_supply/*) - This option has no effect on /proc/acpi/ folders - and functions, which do not yet exist in /sys - - Say N to delete power /proc/acpi/ folders that have moved to /sys/ + config ACPI_PROC_EVENT bool "Deprecated /proc/acpi/event support" depends on PROC_FS diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index 456446f90077..54e3ab0e5fc0 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -58,6 +58,6 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o -obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o +obj-y += cm_sbs.o obj-$(CONFIG_ACPI_SBS) += sbs.o obj-$(CONFIG_ACPI_SBS) += sbshc.o diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index 76ed4f52bebd..30238f6ff232 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -27,7 +27,7 @@ #include #include #include -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS #include #include #endif @@ -51,7 +51,7 @@ MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI AC Adapter Driver"); MODULE_LICENSE("GPL"); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS extern struct proc_dir_entry *acpi_lock_ac_dir(void); extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); static int acpi_ac_open_fs(struct inode *inode, struct file *file); @@ -86,7 +86,7 @@ struct acpi_ac { #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS static const struct file_operations acpi_ac_fops = { .open = acpi_ac_open_fs, .read = seq_read, @@ -136,7 +136,7 @@ static int acpi_ac_get_state(struct acpi_ac *ac) return 0; } -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ @@ -275,7 +275,7 @@ static int acpi_ac_add(struct acpi_device *device) if (result) goto end; -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS result = acpi_ac_add_fs(device); #endif if (result) @@ -300,7 +300,7 @@ static int acpi_ac_add(struct acpi_device *device) end: if (result) { -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_ac_remove_fs(device); #endif kfree(ac); @@ -339,7 +339,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type) ACPI_ALL_NOTIFY, acpi_ac_notify); if (ac->charger.dev) power_supply_unregister(&ac->charger); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_ac_remove_fs(device); #endif @@ -355,7 +355,7 @@ static int __init acpi_ac_init(void) if (acpi_disabled) return -ENODEV; -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_ac_dir = acpi_lock_ac_dir(); if (!acpi_ac_dir) return -ENODEV; @@ -363,7 +363,7 @@ static int __init acpi_ac_init(void) result = acpi_bus_register_driver(&acpi_ac_driver); if (result < 0) { -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_unlock_ac_dir(acpi_ac_dir); #endif return -ENODEV; @@ -377,7 +377,7 @@ static void __exit acpi_ac_exit(void) acpi_bus_unregister_driver(&acpi_ac_driver); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_unlock_ac_dir(acpi_ac_dir); #endif diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 7d6be23eff89..192c244f6190 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -31,7 +31,7 @@ #include #include -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS #include #include #include @@ -63,7 +63,7 @@ static unsigned int cache_time = 1000; module_param(cache_time, uint, 0644); MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS extern struct proc_dir_entry *acpi_lock_battery_dir(void); extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); @@ -153,8 +153,6 @@ static int acpi_battery_get_property(struct power_supply *psy, val->intval = POWER_SUPPLY_STATUS_CHARGING; else if (battery->state == 0) val->intval = POWER_SUPPLY_STATUS_FULL; - else - val->intval = POWER_SUPPLY_STATUS_UNKNOWN; break; case POWER_SUPPLY_PROP_PRESENT: val->intval = acpi_battery_present(battery); @@ -223,7 +221,7 @@ static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_MANUFACTURER, }; -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS inline char *acpi_battery_units(struct acpi_battery *battery) { return (battery->power_unit)?"mA":"mW"; @@ -481,7 +479,7 @@ static int acpi_battery_update(struct acpi_battery *battery) FS Interface (/proc) -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS static struct proc_dir_entry *acpi_battery_dir; static int acpi_battery_print_info(struct seq_file *seq, int result) @@ -788,7 +786,7 @@ static int acpi_battery_add(struct acpi_device *device) acpi_driver_data(device) = battery; mutex_init(&battery->lock); acpi_battery_update(battery); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS result = acpi_battery_add_fs(device); if (result) goto end; @@ -806,7 +804,7 @@ static int acpi_battery_add(struct acpi_device *device) device->status.battery_present ? "present" : "absent"); end: if (result) { -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_battery_remove_fs(device); #endif kfree(battery); @@ -825,7 +823,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_battery_notify); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_battery_remove_fs(device); #endif sysfs_remove_battery(battery); @@ -861,13 +859,13 @@ static int __init acpi_battery_init(void) { if (acpi_disabled) return -ENODEV; -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_battery_dir = acpi_lock_battery_dir(); if (!acpi_battery_dir) return -ENODEV; #endif if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_unlock_battery_dir(acpi_battery_dir); #endif return -ENODEV; @@ -878,7 +876,7 @@ static int __init acpi_battery_init(void) static void __exit acpi_battery_exit(void) { acpi_bus_unregister_driver(&acpi_battery_driver); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_unlock_battery_dir(acpi_battery_dir); #endif } diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index c5028568058b..06b78e5e33a1 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -75,8 +75,7 @@ enum { EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */ EC_FLAGS_QUERY_PENDING, /* Query is pending */ EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */ - EC_FLAGS_NO_ADDRESS_GPE, /* Expect GPE only for non-address event */ - EC_FLAGS_ADDRESS, /* Address is being written */ + EC_FLAGS_ONLY_IBF_GPE, /* Expect GPE only for IBF = 0 event */ }; static int acpi_ec_remove(struct acpi_device *device, int type); @@ -167,45 +166,38 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event) static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) { - int ret = 0; - if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && - test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) - force_poll = 1; if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) && likely(!force_poll)) { if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event), msecs_to_jiffies(ACPI_EC_DELAY))) - goto end; + return 0; clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); if (acpi_ec_check_status(ec, event)) { - if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) { - /* miss address GPE, don't expect it anymore */ - printk(KERN_INFO PREFIX "missing address confirmation, " - "don't expect it any longer.\n"); - set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags); + if (event == ACPI_EC_EVENT_OBF_1) { + /* miss OBF = 1 GPE, don't expect it anymore */ + printk(KERN_INFO PREFIX "missing OBF_1 confirmation," + "switching to degraded mode.\n"); + set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags); } else { /* missing GPEs, switch back to poll mode */ - printk(KERN_INFO PREFIX "missing confirmations, " + printk(KERN_INFO PREFIX "missing IBF_1 confirmations," "switch off interrupt mode.\n"); clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); } - goto end; + return 0; } } else { unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); while (time_before(jiffies, delay)) { if (acpi_ec_check_status(ec, event)) - goto end; + return 0; } } printk(KERN_ERR PREFIX "acpi_ec_wait timeout," " status = %d, expect_event = %d\n", acpi_ec_read_status(ec), event); - ret = -ETIME; - end: - clear_bit(EC_FLAGS_ADDRESS, &ec->flags); - return ret; + return -ETIME; } static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, @@ -224,9 +216,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, "write_cmd timeout, command = %d\n", command); goto end; } - /* mark the address byte written to EC */ - if (rdata_len + wdata_len > 1) - set_bit(EC_FLAGS_ADDRESS, &ec->flags); set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); acpi_ec_write_data(ec, *(wdata++)); } @@ -242,6 +231,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); for (; rdata_len > 0; --rdata_len) { + if (test_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags)) + force_poll = 1; result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll); if (result) { printk(KERN_ERR PREFIX "read timeout, command = %d\n", @@ -890,20 +881,12 @@ int __init acpi_ec_ecdt_probe(void) boot_ec->gpe = ecdt_ptr->gpe; boot_ec->handle = ACPI_ROOT_OBJECT; } else { - /* This workaround is needed only on some broken machines, - * which require early EC, but fail to provide ECDT */ - acpi_handle x; printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, boot_ec, NULL); /* Check that acpi_get_devices actually find something */ if (ACPI_FAILURE(status) || !boot_ec->handle) goto error; - /* We really need to limit this workaround, the only ASUS, - * which needs it, has fake EC._INI method, so use it as flag. - */ - if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) - goto error; } ret = ec_install_handlers(boot_ec); diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index e3a673a00845..aabc6ca4a81c 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -387,14 +387,17 @@ acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width) if (!value) value = &dummy; - *value = 0; - if (width <= 8) { + switch (width) { + case 8: *(u8 *) value = inb(port); - } else if (width <= 16) { + break; + case 16: *(u16 *) value = inw(port); - } else if (width <= 32) { + break; + case 32: *(u32 *) value = inl(port); - } else { + break; + default: BUG(); } @@ -405,13 +408,17 @@ EXPORT_SYMBOL(acpi_os_read_port); acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width) { - if (width <= 8) { + switch (width) { + case 8: outb(value, port); - } else if (width <= 16) { + break; + case 16: outw(value, port); - } else if (width <= 32) { + break; + case 32: outl(value, port); - } else { + break; + default: BUG(); } diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 949ba0395901..235a51e328c3 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -612,6 +612,12 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) request_region(pr->throttling.address, 6, "ACPI CPU throttle"); } +#ifdef CONFIG_CPU_FREQ + acpi_processor_ppc_has_changed(pr); +#endif + acpi_processor_get_throttling_info(pr); + acpi_processor_get_limit_info(pr); + return 0; } @@ -641,7 +647,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) */ if (processor_device_array[pr->id] != NULL && processor_device_array[pr->id] != device) { - printk(KERN_WARNING "BIOS reported wrong ACPI id " + printk(KERN_WARNING "BIOS reported wrong ACPI id" "for the processor\n"); return -ENODEV; } @@ -659,12 +665,6 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) /* _PDC call should be done before doing anything else (if reqd.). */ arch_acpi_processor_init_pdc(pr); acpi_processor_set_pdc(pr); -#ifdef CONFIG_CPU_FREQ - acpi_processor_ppc_has_changed(pr); -#endif - acpi_processor_get_throttling_info(pr); - acpi_processor_get_limit_info(pr); - acpi_processor_power_init(pr, device); diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 7b6c20eeeaff..f996d0e37689 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -197,19 +197,6 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2) return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); } -static void acpi_safe_halt(void) -{ - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we - * test NEED_RESCHED: - */ - smp_mb(); - if (!need_resched()) - safe_halt(); - current_thread_info()->status |= TS_POLLING; -} - #ifndef CONFIG_CPU_IDLE static void @@ -252,6 +239,19 @@ acpi_processor_power_activate(struct acpi_processor *pr, return; } +static void acpi_safe_halt(void) +{ + current_thread_info()->status &= ~TS_POLLING; + /* + * TS_POLLING-cleared state must be visible before we + * test NEED_RESCHED: + */ + smp_mb(); + if (!need_resched()) + safe_halt(); + current_thread_info()->status |= TS_POLLING; +} + static atomic_t c3_cpu_count; /* Common C-state entry for C2, C3, .. */ @@ -1373,7 +1373,15 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, if (pr->flags.bm_check) acpi_idle_update_bm_rld(pr, cx); - acpi_safe_halt(); + current_thread_info()->status &= ~TS_POLLING; + /* + * TS_POLLING-cleared state must be visible before we test + * NEED_RESCHED: + */ + smp_mb(); + if (!need_resched()) + safe_halt(); + current_thread_info()->status |= TS_POLLING; cx->usage++; @@ -1391,8 +1399,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); u32 t1, t2; - int sleep_ticks = 0; - pr = processors[smp_processor_id()]; if (unlikely(!pr)) @@ -1422,8 +1428,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, ACPI_FLUSH_CPU_CACHE(); t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); - /* Tell the scheduler that we are going deep-idle: */ - sched_clock_idle_sleep_event(); acpi_state_timer_broadcast(pr, cx, 1); acpi_idle_do_entry(cx); t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); @@ -1432,10 +1436,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, /* TSC could halt in idle, so notify users */ mark_tsc_unstable("TSC halts in idle");; #endif - sleep_ticks = ticks_elapsed(t1, t2); - - /* Tell the scheduler how much we idled: */ - sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); local_irq_enable(); current_thread_info()->status |= TS_POLLING; @@ -1443,7 +1443,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, cx->usage++; acpi_state_timer_broadcast(pr, cx, 0); - cx->time += sleep_ticks; + cx->time += ticks_elapsed(t1, t2); return ticks_elapsed_in_us(t1, t2); } @@ -1463,8 +1463,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); u32 t1, t2; - int sleep_ticks = 0; - pr = processors[smp_processor_id()]; if (unlikely(!pr)) @@ -1473,15 +1471,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, if (acpi_idle_suspend) return(acpi_idle_enter_c1(dev, state)); - if (acpi_idle_bm_check()) { - if (dev->safe_state) { - return dev->safe_state->enter(dev, dev->safe_state); - } else { - acpi_safe_halt(); - return 0; - } - } - local_irq_disable(); current_thread_info()->status &= ~TS_POLLING; /* @@ -1496,45 +1485,38 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, return 0; } - /* Tell the scheduler that we are going deep-idle: */ - sched_clock_idle_sleep_event(); /* * Must be done before busmaster disable as we might need to * access HPET ! */ acpi_state_timer_broadcast(pr, cx, 1); - acpi_idle_update_bm_rld(pr, cx); + if (acpi_idle_bm_check()) { + cx = pr->power.bm_state; + + acpi_idle_update_bm_rld(pr, cx); + + t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + acpi_idle_do_entry(cx); + t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + } else { + acpi_idle_update_bm_rld(pr, cx); - /* - * disable bus master - * bm_check implies we need ARB_DIS - * !bm_check implies we need cache flush - * bm_control implies whether we can do ARB_DIS - * - * That leaves a case where bm_check is set and bm_control is - * not set. In that case we cannot do much, we enter C3 - * without doing anything. - */ - if (pr->flags.bm_check && pr->flags.bm_control) { spin_lock(&c3_lock); c3_cpu_count++; /* Disable bus master arbitration when all CPUs are in C3 */ if (c3_cpu_count == num_online_cpus()) acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); spin_unlock(&c3_lock); - } else if (!pr->flags.bm_check) { - ACPI_FLUSH_CPU_CACHE(); - } - t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); - acpi_idle_do_entry(cx); - t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + acpi_idle_do_entry(cx); + t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); - /* Re-enable bus master arbitration */ - if (pr->flags.bm_check && pr->flags.bm_control) { spin_lock(&c3_lock); - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); + /* Re-enable bus master arbitration */ + if (c3_cpu_count == num_online_cpus()) + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); c3_cpu_count--; spin_unlock(&c3_lock); } @@ -1543,9 +1525,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, /* TSC could halt in idle, so notify users */ mark_tsc_unstable("TSC halts in idle"); #endif - sleep_ticks = ticks_elapsed(t1, t2); - /* Tell the scheduler how much we idled: */ - sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); local_irq_enable(); current_thread_info()->status |= TS_POLLING; @@ -1553,7 +1532,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, cx->usage++; acpi_state_timer_broadcast(pr, cx, 0); - cx->time += sleep_ticks; + cx->time += ticks_elapsed(t1, t2); return ticks_elapsed_in_us(t1, t2); } @@ -1605,14 +1584,12 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) case ACPI_STATE_C1: state->flags |= CPUIDLE_FLAG_SHALLOW; state->enter = acpi_idle_enter_c1; - dev->safe_state = state; break; case ACPI_STATE_C2: state->flags |= CPUIDLE_FLAG_BALANCED; state->flags |= CPUIDLE_FLAG_TIME_VALID; state->enter = acpi_idle_enter_simple; - dev->safe_state = state; break; case ACPI_STATE_C3: @@ -1633,6 +1610,14 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) if (!count) return -EINVAL; + /* find the deepest state that can handle active BM */ + if (pr->flags.bm_check) { + for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) + if (pr->power.states[i].type == ACPI_STATE_C3) + break; + pr->power.bm_state = &pr->power.states[i-1]; + } + return 0; } diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index c26c61fb36c3..0b8204e7082a 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -70,55 +70,7 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) int acpi_processor_tstate_has_changed(struct acpi_processor *pr) { - int result = 0; - int throttling_limit; - int current_state; - struct acpi_processor_limit *limit; - int target_state; - - result = acpi_processor_get_platform_limit(pr); - if (result) { - /* Throttling Limit is unsupported */ - return result; - } - - throttling_limit = pr->throttling_platform_limit; - if (throttling_limit >= pr->throttling.state_count) { - /* Uncorrect Throttling Limit */ - return -EINVAL; - } - - current_state = pr->throttling.state; - if (current_state > throttling_limit) { - /* - * The current state can meet the requirement of - * _TPC limit. But it is reasonable that OSPM changes - * t-states from high to low for better performance. - * Of course the limit condition of thermal - * and user should be considered. - */ - limit = &pr->limit; - target_state = throttling_limit; - if (limit->thermal.tx > target_state) - target_state = limit->thermal.tx; - if (limit->user.tx > target_state) - target_state = limit->user.tx; - } else if (current_state == throttling_limit) { - /* - * Unnecessary to change the throttling state - */ - return 0; - } else { - /* - * If the current state is lower than the limit of _TPC, it - * will be forced to switch to the throttling state defined - * by throttling_platfor_limit. - * Because the previous state meets with the limit condition - * of thermal and user, it is unnecessary to check it again. - */ - target_state = throttling_limit; - } - return acpi_processor_set_throttling(pr, target_state); + return acpi_processor_get_platform_limit(pr); } /* @@ -131,7 +83,6 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr) struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *ptc = NULL; union acpi_object obj = { 0 }; - struct acpi_processor_throttling *throttling; status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer); if (ACPI_FAILURE(status)) { @@ -183,22 +134,6 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr) memcpy(&pr->throttling.status_register, obj.buffer.pointer, sizeof(struct acpi_ptc_register)); - throttling = &pr->throttling; - - if ((throttling->control_register.bit_width + - throttling->control_register.bit_offset) > 32) { - printk(KERN_ERR PREFIX "Invalid _PTC control register\n"); - result = -EFAULT; - goto end; - } - - if ((throttling->status_register.bit_width + - throttling->status_register.bit_offset) > 32) { - printk(KERN_ERR PREFIX "Invalid _PTC status register\n"); - result = -EFAULT; - goto end; - } - end: kfree(buffer.pointer); @@ -393,132 +328,44 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr) return 0; } -#ifdef CONFIG_X86 -static int acpi_throttling_rdmsr(struct acpi_processor *pr, - acpi_integer * value) +static int acpi_read_throttling_status(struct acpi_processor_throttling + *throttling) { - struct cpuinfo_x86 *c; - u64 msr_high, msr_low; - unsigned int cpu; - u64 msr = 0; - int ret = -1; - - cpu = pr->id; - c = &cpu_data(cpu); - - if ((c->x86_vendor != X86_VENDOR_INTEL) || - !cpu_has(c, X86_FEATURE_ACPI)) { - printk(KERN_ERR PREFIX - "HARDWARE addr space,NOT supported yet\n"); - } else { - msr_low = 0; - msr_high = 0; - rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, - (u32 *)&msr_low , (u32 *) &msr_high); - msr = (msr_high << 32) | msr_low; - *value = (acpi_integer) msr; - ret = 0; - } - return ret; -} - -static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) -{ - struct cpuinfo_x86 *c; - unsigned int cpu; - int ret = -1; - u64 msr; - - cpu = pr->id; - c = &cpu_data(cpu); - - if ((c->x86_vendor != X86_VENDOR_INTEL) || - !cpu_has(c, X86_FEATURE_ACPI)) { - printk(KERN_ERR PREFIX - "HARDWARE addr space,NOT supported yet\n"); - } else { - msr = value; - wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, - msr & 0xffffffff, msr >> 32); - ret = 0; - } - return ret; -} -#else -static int acpi_throttling_rdmsr(struct acpi_processor *pr, - acpi_integer * value) -{ - printk(KERN_ERR PREFIX - "HARDWARE addr space,NOT supported yet\n"); - return -1; -} - -static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) -{ - printk(KERN_ERR PREFIX - "HARDWARE addr space,NOT supported yet\n"); - return -1; -} -#endif - -static int acpi_read_throttling_status(struct acpi_processor *pr, - acpi_integer *value) -{ - u32 bit_width, bit_offset; - u64 ptc_value; - u64 ptc_mask; - struct acpi_processor_throttling *throttling; - int ret = -1; - - throttling = &pr->throttling; + int value = -1; switch (throttling->status_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: - ptc_value = 0; - bit_width = throttling->status_register.bit_width; - bit_offset = throttling->status_register.bit_offset; - acpi_os_read_port((acpi_io_address) throttling->status_register. - address, (u32 *) &ptc_value, - (u32) (bit_width + bit_offset)); - ptc_mask = (1 << bit_width) - 1; - *value = (acpi_integer) ((ptc_value >> bit_offset) & ptc_mask); - ret = 0; + address, &value, + (u32) throttling->status_register.bit_width * + 8); break; case ACPI_ADR_SPACE_FIXED_HARDWARE: - ret = acpi_throttling_rdmsr(pr, value); + printk(KERN_ERR PREFIX + "HARDWARE addr space,NOT supported yet\n"); break; default: printk(KERN_ERR PREFIX "Unknown addr space %d\n", (u32) (throttling->status_register.space_id)); } - return ret; + return value; } -static int acpi_write_throttling_state(struct acpi_processor *pr, - acpi_integer value) +static int acpi_write_throttling_state(struct acpi_processor_throttling + *throttling, int value) { - u32 bit_width, bit_offset; - u64 ptc_value; - u64 ptc_mask; - struct acpi_processor_throttling *throttling; int ret = -1; - throttling = &pr->throttling; switch (throttling->control_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: - bit_width = throttling->control_register.bit_width; - bit_offset = throttling->control_register.bit_offset; - ptc_mask = (1 << bit_width) - 1; - ptc_value = value & ptc_mask; - acpi_os_write_port((acpi_io_address) throttling-> - control_register.address, - (u32) (ptc_value << bit_offset), - (u32) (bit_width + bit_offset)); + control_register.address, value, + (u32) throttling->control_register. + bit_width * 8); ret = 0; break; case ACPI_ADR_SPACE_FIXED_HARDWARE: - ret = acpi_throttling_wrmsr(pr, value); + printk(KERN_ERR PREFIX + "HARDWARE addr space,NOT supported yet\n"); break; default: printk(KERN_ERR PREFIX "Unknown addr space %d\n", @@ -527,8 +374,7 @@ static int acpi_write_throttling_state(struct acpi_processor *pr, return ret; } -static int acpi_get_throttling_state(struct acpi_processor *pr, - acpi_integer value) +static int acpi_get_throttling_state(struct acpi_processor *pr, int value) { int i; @@ -544,26 +390,22 @@ static int acpi_get_throttling_state(struct acpi_processor *pr, return i; } -static int acpi_get_throttling_value(struct acpi_processor *pr, - int state, acpi_integer *value) +static int acpi_get_throttling_value(struct acpi_processor *pr, int state) { - int ret = -1; - + int value = -1; if (state >= 0 && state <= pr->throttling.state_count) { struct acpi_processor_tx_tss *tx = (struct acpi_processor_tx_tss *)&(pr->throttling. states_tss[state]); - *value = tx->control; - ret = 0; + value = tx->control; } - return ret; + return value; } static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) { int state = 0; - int ret; - acpi_integer value; + u32 value = 0; if (!pr) return -EINVAL; @@ -573,9 +415,8 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) pr->throttling.state = 0; local_irq_disable(); - value = 0; - ret = acpi_read_throttling_status(pr, &value); - if (ret >= 0) { + value = acpi_read_throttling_status(&pr->throttling); + if (value >= 0) { state = acpi_get_throttling_state(pr, value); pr->throttling.state = state; } @@ -589,40 +430,6 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr) return pr->throttling.acpi_processor_get_throttling(pr); } -static int acpi_processor_get_fadt_info(struct acpi_processor *pr) -{ - int i, step; - - if (!pr->throttling.address) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); - return -EINVAL; - } else if (!pr->throttling.duty_width) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n")); - return -EINVAL; - } - /* TBD: Support duty_cycle values that span bit 4. */ - else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) { - printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n"); - return -EINVAL; - } - - pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width; - - /* - * Compute state values. Note that throttling displays a linear power - * performance relationship (at 50% performance the CPU will consume - * 50% power). Values are in 1/10th of a percent to preserve accuracy. - */ - - step = (1000 / pr->throttling.state_count); - - for (i = 0; i < pr->throttling.state_count; i++) { - pr->throttling.states[i].performance = 1000 - step * i; - pr->throttling.states[i].power = 1000 - step * i; - } - return 0; -} - static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, int state) { @@ -699,8 +506,7 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, int state) { - int ret; - acpi_integer value; + u32 value = 0; if (!pr) return -EINVAL; @@ -718,10 +524,10 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, return -EPERM; local_irq_disable(); - value = 0; - ret = acpi_get_throttling_value(pr, state, &value); - if (ret >= 0) { - acpi_write_throttling_state(pr, value); + + value = acpi_get_throttling_value(pr, state); + if (value >= 0) { + acpi_write_throttling_state(&pr->throttling, value); pr->throttling.state = state; } local_irq_enable(); @@ -737,6 +543,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) int acpi_processor_get_throttling_info(struct acpi_processor *pr) { int result = 0; + int step = 0; + int i = 0; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", @@ -755,8 +563,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) acpi_processor_get_throttling_states(pr) || acpi_processor_get_platform_limit(pr)) { - if (acpi_processor_get_fadt_info(pr)) - return 0; pr->throttling.acpi_processor_get_throttling = &acpi_processor_get_throttling_fadt; pr->throttling.acpi_processor_set_throttling = @@ -770,6 +576,19 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) acpi_processor_get_tsd(pr); + if (!pr->throttling.address) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); + return 0; + } else if (!pr->throttling.duty_width) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n")); + return 0; + } + /* TBD: Support duty_cycle values that span bit 4. */ + else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) { + printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n"); + return 0; + } + /* * PIIX4 Errata: We don't support throttling on the original PIIX4. * This shouldn't be an issue as few (if any) mobile systems ever @@ -781,6 +600,21 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) return 0; } + pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width; + + /* + * Compute state values. Note that throttling displays a linear power/ + * performance relationship (at 50% performance the CPU will consume + * 50% power). Values are in 1/10th of a percent to preserve accuracy. + */ + + step = (1000 / pr->throttling.state_count); + + for (i = 0; i < pr->throttling.state_count; i++) { + pr->throttling.states[i].performance = step * i; + pr->throttling.states[i].power = step * i; + } + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n", pr->throttling.state_count)); diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index 6045cdbe176b..90fd09c65f95 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -29,7 +29,7 @@ #include #include -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS #include #include #include @@ -88,7 +88,7 @@ MODULE_DEVICE_TABLE(acpi, sbs_device_ids); struct acpi_battery { struct power_supply bat; struct acpi_sbs *sbs; -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *proc_entry; #endif unsigned long update_time; @@ -113,7 +113,6 @@ struct acpi_battery { u16 spec; u8 id; u8 present:1; - u8 have_sysfs_alarm:1; }; #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); @@ -123,7 +122,7 @@ struct acpi_sbs { struct acpi_device *device; struct acpi_smb_hc *hc; struct mutex lock; -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *charger_entry; #endif struct acpi_battery battery[MAX_SBS_BAT]; @@ -469,7 +468,7 @@ static struct device_attribute alarm_attr = { FS Interface (/proc/acpi) -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS /* Generic Routines */ static int acpi_sbs_add_fs(struct proc_dir_entry **dir, @@ -790,7 +789,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) return result; sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir, battery->name, &acpi_battery_info_fops, &acpi_battery_state_fops, &acpi_battery_alarm_fops, @@ -809,13 +808,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) } battery->bat.get_property = acpi_sbs_battery_get_property; result = power_supply_register(&sbs->device->dev, &battery->bat); - if (result) - goto end; - result = device_create_file(battery->bat.dev, &alarm_attr); - if (result) - goto end; - battery->have_sysfs_alarm = 1; - end: + device_create_file(battery->bat.dev, &alarm_attr); printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), battery->name, sbs->battery->present ? "present" : "absent"); @@ -824,16 +817,14 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) static void acpi_battery_remove(struct acpi_sbs *sbs, int id) { - struct acpi_battery *battery = &sbs->battery[id]; - - if (battery->bat.dev) { - if (battery->have_sysfs_alarm) - device_remove_file(battery->bat.dev, &alarm_attr); - power_supply_unregister(&battery->bat); + if (sbs->battery[id].bat.dev) + device_remove_file(sbs->battery[id].bat.dev, &alarm_attr); + power_supply_unregister(&sbs->battery[id].bat); +#ifdef CONFIG_ACPI_PROCFS + if (sbs->battery[id].proc_entry) { + acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry), + acpi_battery_dir); } -#ifdef CONFIG_ACPI_PROCFS_POWER - if (battery->proc_entry) - acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); #endif } @@ -844,7 +835,7 @@ static int acpi_charger_add(struct acpi_sbs *sbs) result = acpi_ac_get_present(sbs); if (result) goto end; -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir, ACPI_AC_DIR_NAME, NULL, &acpi_ac_state_fops, NULL, sbs); @@ -868,7 +859,7 @@ static void acpi_charger_remove(struct acpi_sbs *sbs) { if (sbs->charger.dev) power_supply_unregister(&sbs->charger); -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS if (sbs->charger_entry) acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); #endif @@ -974,7 +965,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type) static void acpi_sbs_rmdirs(void) { -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS if (acpi_ac_dir) { acpi_unlock_ac_dir(acpi_ac_dir); acpi_ac_dir = NULL; @@ -1013,7 +1004,7 @@ static int __init acpi_sbs_init(void) if (acpi_disabled) return -ENODEV; -#ifdef CONFIG_ACPI_PROCFS_POWER +#ifdef CONFIG_ACPI_PROCFS acpi_ac_dir = acpi_lock_ac_dir(); if (!acpi_ac_dir) return -ENODEV; diff --git a/trunk/drivers/acpi/tables/tbutils.c b/trunk/drivers/acpi/tables/tbutils.c index 010f19652f80..5f1d85f2ffe4 100644 --- a/trunk/drivers/acpi/tables/tbutils.c +++ b/trunk/drivers/acpi/tables/tbutils.c @@ -449,7 +449,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) /* XSDT has NULL entry, RSDT is used */ address = rsdt_address; table_entry_size = sizeof(u32); - ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry, " + ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry," "using RSDT")); } } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 44a0d9ba9bd6..bac956b30c57 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -136,8 +135,8 @@ struct acpi_video_bus { u8 attached_count; struct acpi_video_bus_cap cap; struct acpi_video_bus_flags flags; + struct semaphore sem; struct list_head video_device_list; - struct mutex device_list_lock; /* protects video_device_list */ struct proc_dir_entry *dir; struct input_dev *input; char phys[32]; /* for input device */ @@ -897,7 +896,7 @@ acpi_video_device_write_brightness(struct file *file, { struct seq_file *m = file->private_data; struct acpi_video_device *dev = m->private; - char str[5] = { 0 }; + char str[4] = { 0 }; unsigned int level = 0; int i; @@ -1437,9 +1436,9 @@ acpi_video_bus_get_one_device(struct acpi_device *device, return -ENODEV; } - mutex_lock(&video->device_list_lock); + down(&video->sem); list_add_tail(&data->entry, &video->video_device_list); - mutex_unlock(&video->device_list_lock); + up(&video->sem); acpi_video_device_add_fs(device); @@ -1463,14 +1462,12 @@ acpi_video_bus_get_one_device(struct acpi_device *device, static void acpi_video_device_rebind(struct acpi_video_bus *video) { - struct acpi_video_device *dev; - - mutex_lock(&video->device_list_lock); - - list_for_each_entry(dev, &video->video_device_list, entry) + struct list_head *node, *next; + list_for_each_safe(node, next, &video->video_device_list) { + struct acpi_video_device *dev = + container_of(node, struct acpi_video_device, entry); acpi_video_device_bind(video, dev); - - mutex_unlock(&video->device_list_lock); + } } /* @@ -1595,33 +1592,30 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) static int acpi_video_switch_output(struct acpi_video_bus *video, int event) { - struct list_head *node; + struct list_head *node, *next; struct acpi_video_device *dev = NULL; struct acpi_video_device *dev_next = NULL; struct acpi_video_device *dev_prev = NULL; unsigned long state; int status = 0; - mutex_lock(&video->device_list_lock); - list_for_each(node, &video->video_device_list) { + list_for_each_safe(node, next, &video->video_device_list) { dev = container_of(node, struct acpi_video_device, entry); status = acpi_video_device_get_state(dev, &state); if (state & 0x2) { - dev_next = container_of(node->next, - struct acpi_video_device, entry); - dev_prev = container_of(node->prev, - struct acpi_video_device, entry); + dev_next = + container_of(node->next, struct acpi_video_device, + entry); + dev_prev = + container_of(node->prev, struct acpi_video_device, + entry); goto out; } } - dev_next = container_of(node->next, struct acpi_video_device, entry); dev_prev = container_of(node->prev, struct acpi_video_device, entry); - - out: - mutex_unlock(&video->device_list_lock); - + out: switch (event) { case ACPI_VIDEO_NOTIFY_CYCLE: case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: @@ -1697,17 +1691,24 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) { int status = 0; - struct acpi_device *dev; + struct list_head *node, *next; + acpi_video_device_enumerate(video); - list_for_each_entry(dev, &device->children, node) { + list_for_each_safe(node, next, &device->children) { + struct acpi_device *dev = + list_entry(node, struct acpi_device, node); + + if (!dev) + continue; status = acpi_video_bus_get_one_device(dev, video); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Cant attach device")); continue; } + } return status; } @@ -1723,6 +1724,9 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) video = device->video; + down(&video->sem); + list_del(&device->entry); + up(&video->sem); acpi_video_device_remove_fs(device->dev); status = acpi_remove_notify_handler(device->dev->handle, @@ -1730,34 +1734,32 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) acpi_video_device_notify); backlight_device_unregister(device->backlight); video_output_unregister(device->output_dev); - return 0; } static int acpi_video_bus_put_devices(struct acpi_video_bus *video) { int status; - struct acpi_video_device *dev, *next; + struct list_head *node, *next; - mutex_lock(&video->device_list_lock); - list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { + list_for_each_safe(node, next, &video->video_device_list) { + struct acpi_video_device *data = + list_entry(node, struct acpi_video_device, entry); + if (!data) + continue; - status = acpi_video_bus_put_one_device(dev); + status = acpi_video_bus_put_one_device(data); if (ACPI_FAILURE(status)) printk(KERN_WARNING PREFIX "hhuuhhuu bug in acpi video driver.\n"); - if (dev->brightness) { - kfree(dev->brightness->levels); - kfree(dev->brightness); - } - list_del(&dev->entry); - kfree(dev); + if (data->brightness) + kfree(data->brightness->levels); + kfree(data->brightness); + kfree(data); } - mutex_unlock(&video->device_list_lock); - return 0; } @@ -1780,6 +1782,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) struct input_dev *input; int keycode; + + printk("video bus notify\n"); + if (!video) return; @@ -1892,10 +1897,14 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) static int instance; static int acpi_video_bus_add(struct acpi_device *device) { - acpi_status status; - struct acpi_video_bus *video; + int result = 0; + acpi_status status = 0; + struct acpi_video_bus *video = NULL; struct input_dev *input; - int error; + + + if (!device) + return -EINVAL; video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); if (!video) @@ -1914,15 +1923,15 @@ static int acpi_video_bus_add(struct acpi_device *device) acpi_driver_data(device) = video; acpi_video_bus_find_cap(video); - error = acpi_video_bus_check(video); - if (error) - goto err_free_video; + result = acpi_video_bus_check(video); + if (result) + goto end; - error = acpi_video_bus_add_fs(device); - if (error) - goto err_free_video; + result = acpi_video_bus_add_fs(device); + if (result) + goto end; - mutex_init(&video->device_list_lock); + init_MUTEX(&video->sem); INIT_LIST_HEAD(&video->video_device_list); acpi_video_bus_get_devices(video, device); @@ -1934,15 +1943,16 @@ static int acpi_video_bus_add(struct acpi_device *device) if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing notify handler\n")); - error = -ENODEV; - goto err_stop_video; + acpi_video_bus_stop_devices(video); + acpi_video_bus_put_devices(video); + kfree(video->attached_array); + acpi_video_bus_remove_fs(device); + result = -ENODEV; + goto end; } + video->input = input = input_allocate_device(); - if (!input) { - error = -ENOMEM; - goto err_uninstall_notify; - } snprintf(video->phys, sizeof(video->phys), "%s/video/input0", acpi_device_hid(video->device)); @@ -1951,7 +1961,6 @@ static int acpi_video_bus_add(struct acpi_device *device) input->phys = video->phys; input->id.bustype = BUS_HOST; input->id.product = 0x06; - input->dev.parent = &device->dev; input->evbit[0] = BIT(EV_KEY); set_bit(KEY_SWITCHVIDEOMODE, input->keybit); set_bit(KEY_VIDEO_NEXT, input->keybit); @@ -1962,10 +1971,18 @@ static int acpi_video_bus_add(struct acpi_device *device) set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); set_bit(KEY_DISPLAY_OFF, input->keybit); set_bit(KEY_UNKNOWN, input->keybit); + result = input_register_device(input); + if (result) { + acpi_remove_notify_handler(video->device->handle, + ACPI_DEVICE_NOTIFY, + acpi_video_bus_notify); + acpi_video_bus_stop_devices(video); + acpi_video_bus_put_devices(video); + kfree(video->attached_array); + acpi_video_bus_remove_fs(device); + goto end; + } - error = input_register_device(input); - if (error) - goto err_free_input_dev; printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), @@ -1973,23 +1990,11 @@ static int acpi_video_bus_add(struct acpi_device *device) video->flags.rom ? "yes" : "no", video->flags.post ? "yes" : "no"); - return 0; - - err_free_input_dev: - input_free_device(input); - err_uninstall_notify: - acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, - acpi_video_bus_notify); - err_stop_video: - acpi_video_bus_stop_devices(video); - acpi_video_bus_put_devices(video); - kfree(video->attached_array); - acpi_video_bus_remove_fs(device); - err_free_video: - kfree(video); - acpi_driver_data(device) = NULL; + end: + if (result) + kfree(video); - return error; + return result; } static int acpi_video_bus_remove(struct acpi_device *device, int type) diff --git a/trunk/drivers/misc/thinkpad_acpi.c b/trunk/drivers/misc/thinkpad_acpi.c index ab23a3221585..e953276664a0 100644 --- a/trunk/drivers/misc/thinkpad_acpi.c +++ b/trunk/drivers/misc/thinkpad_acpi.c @@ -21,7 +21,7 @@ * 02110-1301, USA. */ -#define IBM_VERSION "0.17" +#define IBM_VERSION "0.16" #define TPACPI_SYSFS_VERSION 0x020000 /* @@ -964,15 +964,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ KEY_UNKNOWN, /* 0x0D: FN+INSERT */ KEY_UNKNOWN, /* 0x0E: FN+DELETE */ - KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ + KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */ /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ - KEY_RESERVED, /* 0x10: FN+END (brightness down) */ + KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */ KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ - KEY_RESERVED, /* 0x14: VOLUME UP */ - KEY_RESERVED, /* 0x15: VOLUME DOWN */ - KEY_RESERVED, /* 0x16: MUTE */ + KEY_VOLUMEUP, /* 0x14: VOLUME UP */ + KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */ + KEY_MUTE, /* 0x16: MUTE */ KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ /* (assignments unknown, please report if found) */ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, @@ -993,9 +993,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ - KEY_RESERVED, /* 0x14: VOLUME UP */ - KEY_RESERVED, /* 0x15: VOLUME DOWN */ - KEY_RESERVED, /* 0x16: MUTE */ + KEY_VOLUMEUP, /* 0x14: VOLUME UP */ + KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */ + KEY_MUTE, /* 0x16: MUTE */ KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ /* (assignments unknown, please report if found) */ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, @@ -1342,8 +1342,9 @@ static int hotkey_read(char *p) return len; } - if (mutex_lock_interruptible(&hotkey_mutex)) - return -ERESTARTSYS; + res = mutex_lock_interruptible(&hotkey_mutex); + if (res < 0) + return res; res = hotkey_get(&status, &mask); mutex_unlock(&hotkey_mutex); if (res) @@ -1372,8 +1373,9 @@ static int hotkey_write(char *buf) if (!tp_features.hotkey) return -ENODEV; - if (mutex_lock_interruptible(&hotkey_mutex)) - return -ERESTARTSYS; + res = mutex_lock_interruptible(&hotkey_mutex); + if (res < 0) + return res; res = hotkey_get(&status, &mask); if (res) @@ -3112,99 +3114,6 @@ static struct backlight_ops ibm_backlight_data = { static struct mutex brightness_mutex; -static int __init tpacpi_query_bcll_levels(acpi_handle handle) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - int rc; - - if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { - obj = (union acpi_object *)buffer.pointer; - if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { - printk(IBM_ERR "Unknown BCLL data, " - "please report this to %s\n", IBM_MAIL); - rc = 0; - } else { - rc = obj->package.count; - } - } else { - return 0; - } - - kfree(buffer.pointer); - return rc; -} - -static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl, - void *context, void **rv) -{ - char name[ACPI_PATH_SEGMENT_LENGTH]; - struct acpi_buffer buffer = { sizeof(name), &name }; - - if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && - !strncmp("BCLL", name, sizeof(name) - 1)) { - if (tpacpi_query_bcll_levels(handle) == 16) { - *rv = handle; - return AE_CTRL_TERMINATE; - } else { - return AE_OK; - } - } else { - return AE_OK; - } -} - -static int __init brightness_check_levels(void) -{ - int status; - void *found_node = NULL; - - if (!vid_handle) { - IBM_ACPIHANDLE_INIT(vid); - } - if (!vid_handle) - return 0; - - /* Search for a BCLL package with 16 levels */ - status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3, - brightness_find_bcll, NULL, &found_node); - - return (ACPI_SUCCESS(status) && found_node != NULL); -} - -static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl, - void *context, void **rv) -{ - char name[ACPI_PATH_SEGMENT_LENGTH]; - struct acpi_buffer buffer = { sizeof(name), &name }; - - if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && - !strncmp("_BCL", name, sizeof(name) - 1)) { - *rv = handle; - return AE_CTRL_TERMINATE; - } else { - return AE_OK; - } -} - -static int __init brightness_check_std_acpi_support(void) -{ - int status; - void *found_node = NULL; - - if (!vid_handle) { - IBM_ACPIHANDLE_INIT(vid); - } - if (!vid_handle) - return 0; - - /* Search for a _BCL method, but don't execute it */ - status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, - brightness_find_bcl, NULL, &found_node); - - return (ACPI_SUCCESS(status) && found_node != NULL); -} - static int __init brightness_init(struct ibm_init_struct *iibm) { int b; @@ -3213,18 +3122,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm) mutex_init(&brightness_mutex); - if (!brightness_enable) { - dbg_printk(TPACPI_DBG_INIT, - "brightness support disabled by module parameter\n"); - return 1; - } else if (brightness_enable > 1) { - if (brightness_check_std_acpi_support()) { - printk(IBM_NOTICE - "standard ACPI backlight interface available, not loading native one...\n"); - return 1; - } - } - if (!brightness_mode) { if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) brightness_mode = 2; @@ -3238,17 +3135,10 @@ static int __init brightness_init(struct ibm_init_struct *iibm) if (brightness_mode > 3) return -EINVAL; - tp_features.bright_16levels = - thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO && - brightness_check_levels(); - b = brightness_get(NULL); if (b < 0) return 1; - if (tp_features.bright_16levels) - printk(IBM_INFO "detected a 16-level brightness capable ThinkPad\n"); - ibm_backlight_device = backlight_device_register( TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, &ibm_backlight_data); @@ -3258,8 +3148,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm) } vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n"); - ibm_backlight_device->props.max_brightness = - (tp_features.bright_16levels)? 15 : 7; + ibm_backlight_device->props.max_brightness = 7; ibm_backlight_device->props.brightness = b; backlight_update_status(ibm_backlight_device); @@ -3278,8 +3167,6 @@ static void brightness_exit(void) static int brightness_update_status(struct backlight_device *bd) { - /* it is the backlight class's job (caller) to handle - * EINTR and other errors properly */ return brightness_set( (bd->props.fb_blank == FB_BLANK_UNBLANK && bd->props.power == FB_BLANK_UNBLANK) ? @@ -3297,14 +3184,13 @@ static int brightness_get(struct backlight_device *bd) if (brightness_mode & 1) { if (!acpi_ec_read(brightness_offset, &lec)) return -EIO; - lec &= (tp_features.bright_16levels)? 0x0f : 0x07; + lec &= 7; level = lec; }; if (brightness_mode & 2) { lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; - lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07; level = lcmos; } @@ -3320,13 +3206,12 @@ static int brightness_get(struct backlight_device *bd) return level; } -/* May return EINTR which can always be mapped to ERESTARTSYS */ static int brightness_set(int value) { int cmos_cmd, inc, i, res; int current_value; - if (value > ((tp_features.bright_16levels)? 15 : 7)) + if (value > 7) return -EINVAL; res = mutex_lock_interruptible(&brightness_mutex); @@ -3342,7 +3227,7 @@ static int brightness_set(int value) cmos_cmd = value > current_value ? TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN; - inc = (value > current_value)? 1 : -1; + inc = value > current_value ? 1 : -1; res = 0; for (i = current_value; i != value; i += inc) { @@ -3371,11 +3256,10 @@ static int brightness_read(char *p) if ((level = brightness_get(NULL)) < 0) { len += sprintf(p + len, "level:\t\tunreadable\n"); } else { - len += sprintf(p + len, "level:\t\t%d\n", level); + len += sprintf(p + len, "level:\t\t%d\n", level & 0x7); len += sprintf(p + len, "commands:\tup, down\n"); len += sprintf(p + len, "commands:\tlevel " - " ( is 0-%d)\n", - (tp_features.bright_16levels) ? 15 : 7); + " ( is 0-7)\n"); } return len; @@ -3384,34 +3268,28 @@ static int brightness_read(char *p) static int brightness_write(char *buf) { int level; - int rc; + int new_level; char *cmd; - int max_level = (tp_features.bright_16levels) ? 15 : 7; - - level = brightness_get(NULL); - if (level < 0) - return level; while ((cmd = next_cmd(&buf))) { + if ((level = brightness_get(NULL)) < 0) + return level; + level &= 7; + if (strlencmp(cmd, "up") == 0) { - if (level < max_level) - level++; + new_level = level == 7 ? 7 : level + 1; } else if (strlencmp(cmd, "down") == 0) { - if (level > 0) - level--; - } else if (sscanf(cmd, "level %d", &level) == 1 && - level >= 0 && level <= max_level) { - /* new level set */ + new_level = level == 0 ? 0 : level - 1; + } else if (sscanf(cmd, "level %d", &new_level) == 1 && + new_level >= 0 && new_level <= 7) { + /* new_level set */ } else return -EINVAL; + + brightness_set(new_level); } - /* - * Now we know what the final level should be, so we try to set it. - * Doing it this way makes the syscall restartable in case of EINTR - */ - rc = brightness_set(level); - return (rc == -EINTR)? ERESTARTSYS : rc; + return 0; } static struct ibm_struct brightness_driver_data = { @@ -3774,8 +3652,9 @@ static ssize_t fan_pwm1_store(struct device *dev, /* scale down from 0-255 to 0-7 */ newlevel = (s >> 5) & 0x07; - if (mutex_lock_interruptible(&fan_mutex)) - return -ERESTARTSYS; + rc = mutex_lock_interruptible(&fan_mutex); + if (rc < 0) + return rc; rc = fan_get_status(&status); if (!rc && (status & @@ -4025,8 +3904,9 @@ static int fan_get_status_safe(u8 *status) int rc; u8 s; - if (mutex_lock_interruptible(&fan_mutex)) - return -ERESTARTSYS; + rc = mutex_lock_interruptible(&fan_mutex); + if (rc < 0) + return rc; rc = fan_get_status(&s); if (!rc) fan_update_desired_level(s); @@ -4160,8 +4040,9 @@ static int fan_set_level_safe(int level) if (!fan_control_allowed) return -EPERM; - if (mutex_lock_interruptible(&fan_mutex)) - return -ERESTARTSYS; + rc = mutex_lock_interruptible(&fan_mutex); + if (rc < 0) + return rc; if (level == TPACPI_FAN_LAST_LEVEL) level = fan_control_desired_level; @@ -4182,8 +4063,9 @@ static int fan_set_enable(void) if (!fan_control_allowed) return -EPERM; - if (mutex_lock_interruptible(&fan_mutex)) - return -ERESTARTSYS; + rc = mutex_lock_interruptible(&fan_mutex); + if (rc < 0) + return rc; switch (fan_control_access_mode) { case TPACPI_FAN_WR_ACPI_FANS: @@ -4237,8 +4119,9 @@ static int fan_set_disable(void) if (!fan_control_allowed) return -EPERM; - if (mutex_lock_interruptible(&fan_mutex)) - return -ERESTARTSYS; + rc = mutex_lock_interruptible(&fan_mutex); + if (rc < 0) + return rc; rc = 0; switch (fan_control_access_mode) { @@ -4275,8 +4158,9 @@ static int fan_set_speed(int speed) if (!fan_control_allowed) return -EPERM; - if (mutex_lock_interruptible(&fan_mutex)) - return -ERESTARTSYS; + rc = mutex_lock_interruptible(&fan_mutex); + if (rc < 0) + return rc; rc = 0; switch (fan_control_access_mode) { @@ -4817,15 +4701,9 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp) unsigned int i; struct ibm_struct *ibm; - if (!kp || !kp->name || !val) - return -EINVAL; - for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { ibm = ibms_init[i].data; - WARN_ON(ibm == NULL); - - if (!ibm || !ibm->name) - continue; + BUG_ON(ibm == NULL); if (strcmp(ibm->name, kp->name) == 0 && ibm->write) { if (strlen(val) > sizeof(ibms_init[i].param) - 2) @@ -4854,9 +4732,6 @@ module_param_named(fan_control, fan_control_allowed, bool, 0); static int brightness_mode; module_param_named(brightness_mode, brightness_mode, int, 0); -static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ -module_param(brightness_enable, uint, 0); - static unsigned int hotkey_report_mode; module_param(hotkey_report_mode, uint, 0); diff --git a/trunk/drivers/misc/thinkpad_acpi.h b/trunk/drivers/misc/thinkpad_acpi.h index 8fba2bbe345e..3abcc8120634 100644 --- a/trunk/drivers/misc/thinkpad_acpi.h +++ b/trunk/drivers/misc/thinkpad_acpi.h @@ -84,7 +84,7 @@ /* ThinkPad CMOS NVRAM constants */ #define TP_NVRAM_ADDR_BRIGHTNESS 0x5e -#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x0f +#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x07 #define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0 #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") @@ -246,7 +246,6 @@ static struct { u32 hotkey_wlsw:1; u32 light:1; u32 light_status:1; - u32 bright_16levels:1; u32 wan:1; u32 fan_ctrl_status_undef:1; u32 input_device_registered:1; @@ -339,7 +338,6 @@ static int bluetooth_write(char *buf); static struct backlight_device *ibm_backlight_device; static int brightness_offset = 0x31; static int brightness_mode; -static unsigned int brightness_enable; /* 0 = no, 1 = yes, 2 = auto */ static int brightness_init(struct ibm_init_struct *iibm); static void brightness_exit(void); diff --git a/trunk/drivers/pnp/pnpacpi/rsparser.c b/trunk/drivers/pnp/pnpacpi/rsparser.c index 11adab13f2b7..cd0a204d96d1 100644 --- a/trunk/drivers/pnp/pnpacpi/rsparser.c +++ b/trunk/drivers/pnp/pnpacpi/rsparser.c @@ -75,7 +75,6 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, { int i = 0; int irq; - int p, t; if (!valid_IRQ(gsi)) return; @@ -86,22 +85,15 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, if (i >= PNP_MAX_IRQ) return; - /* - * in IO-APIC mode, use overrided attribute. Two reasons: - * 1. BIOS bug in DSDT - * 2. BIOS uses IO-APIC mode Interrupt Source Override - */ - if (!acpi_get_override_irq(gsi, &t, &p)) { - t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; - p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; - - if (triggering != t || polarity != p) { - pnp_warn("IRQ %d override to %s, %s", - gsi, t ? "edge":"level", p ? "low":"high"); - triggering = t; - polarity = p; - } +#ifdef CONFIG_X86 + if (gsi < 16 && (triggering != ACPI_EDGE_SENSITIVE || + polarity != ACPI_ACTIVE_HIGH)) { + pnp_warn("BIOS BUG: legacy PNP IRQ %d should be edge trigger, " + "active high", gsi); + triggering = ACPI_EDGE_SENSITIVE; + polarity = ACPI_ACTIVE_HIGH; } +#endif res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag res->irq_resource[i].flags |= irq_flags(triggering, polarity); diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 76411b1fc4fd..26d79f6db8a0 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -78,6 +78,7 @@ struct acpi_processor_cx { struct acpi_processor_power { struct cpuidle_device dev; struct acpi_processor_cx *state; + struct acpi_processor_cx *bm_state; unsigned long bm_check_timestamp; u32 default_state; u32 bm_activity; diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index e3c16c981e46..8ccedf7a0a5a 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -132,11 +132,6 @@ extern unsigned long acpi_realmode_flags; int acpi_register_gsi (u32 gsi, int triggering, int polarity); int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); -#ifdef CONFIG_X86_IO_APIC -extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity); -#else -#define acpi_get_override_irq(bus, trigger, polarity) (-1) -#endif /* * This function undoes the effect of one call to acpi_register_gsi(). * If this matches the last registration, any IRQ resources for gsi diff --git a/trunk/include/linux/cpuidle.h b/trunk/include/linux/cpuidle.h index c4e00161a247..16a51546db44 100644 --- a/trunk/include/linux/cpuidle.h +++ b/trunk/include/linux/cpuidle.h @@ -92,7 +92,6 @@ struct cpuidle_device { struct kobject kobj; struct completion kobj_unregister; void *governor_data; - struct cpuidle_state *safe_state; }; DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);