diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/Kconfig | 9 | ||||
-rw-r--r-- | drivers/acpi/Makefile | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/hwxface.c | 3 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbfadt.c | 8 | ||||
-rw-r--r-- | drivers/acpi/bgrt.c | 175 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 1 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 8 | ||||
-rw-r--r-- | drivers/acpi/nvs.c | 4 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 5 | ||||
-rw-r--r-- | drivers/acpi/processor_driver.c | 62 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 34 | ||||
-rw-r--r-- | drivers/acpi/processor_thermal.c | 45 | ||||
-rw-r--r-- | drivers/acpi/processor_throttling.c | 5 | ||||
-rw-r--r-- | drivers/acpi/reboot.c | 3 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 5 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 8 | ||||
-rw-r--r-- | drivers/acpi/video.c | 50 |
17 files changed, 356 insertions, 70 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 7556913aba4..47768ff8734 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -384,6 +384,15 @@ config ACPI_CUSTOM_METHOD load additional kernel modules after boot, this feature may be used to override that restriction). +config ACPI_BGRT + tristate "Boottime Graphics Resource Table support" + default n + help + This driver adds support for exposing the ACPI Boottime Graphics + Resource Table, which allows the operating system to obtain + data from the firmware boot splash. It will appear under + /sys/firmware/acpi/bgrt/ . + source "drivers/acpi/apei/Kconfig" endif # ACPI diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 1567028d203..47199e2a913 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_ACPI_SBS) += sbs.o obj-$(CONFIG_ACPI_HED) += hed.o obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o +obj-$(CONFIG_ACPI_BGRT) += bgrt.o # processor has its own "processor." module_param namespace processor-y := processor_driver.o processor_throttling.o diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index a716fede4f2..ab513a972c9 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -74,8 +74,7 @@ acpi_status acpi_reset(void) /* Check if the reset register is supported */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || - !reset_reg->address) { + if (!reset_reg->address) { return_ACPI_STATUS(AE_NOT_EXIST); } diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index c5d870406f4..4c9c760db4a 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -363,10 +363,6 @@ static void acpi_tb_convert_fadt(void) u32 address32; u32 i; - /* Update the local FADT table header length */ - - acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); - /* * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. * Later code will always use the X 64-bit field. Also, check for an @@ -408,6 +404,10 @@ static void acpi_tb_convert_fadt(void) acpi_gbl_FADT.boot_flags = 0; } + /* Update the local FADT table header length */ + + acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); + /* * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" * generic address structures as necessary. Later code will always use diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c new file mode 100644 index 00000000000..8cf6c46e99f --- /dev/null +++ b/drivers/acpi/bgrt.c @@ -0,0 +1,175 @@ +/* + * Copyright 2012 Red Hat, Inc <mjg@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/sysfs.h> +#include <acpi/acpi.h> +#include <acpi/acpi_bus.h> + +static struct acpi_table_bgrt *bgrt_tab; +static struct kobject *bgrt_kobj; + +struct bmp_header { + u16 id; + u32 size; +} __attribute ((packed)); + +static struct bmp_header bmp_header; + +static ssize_t show_version(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->version); +} +static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); + +static ssize_t show_status(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->status); +} +static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); + +static ssize_t show_type(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_type); +} +static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); + +static ssize_t show_xoffset(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_x); +} +static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL); + +static ssize_t show_yoffset(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_y); +} +static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL); + +static ssize_t show_image(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) +{ + int size = attr->size; + void __iomem *image = attr->private; + + if (off >= size) { + count = 0; + } else { + if (off + count > size) + count = size - off; + + memcpy_fromio(buf, image+off, count); + } + + return count; +} + +static struct bin_attribute image_attr = { + .attr = { + .name = "image", + .mode = S_IRUGO, + }, + .read = show_image, +}; + +static struct attribute *bgrt_attributes[] = { + &dev_attr_version.attr, + &dev_attr_status.attr, + &dev_attr_type.attr, + &dev_attr_xoffset.attr, + &dev_attr_yoffset.attr, + NULL, +}; + +static struct attribute_group bgrt_attribute_group = { + .attrs = bgrt_attributes, +}; + +static int __init bgrt_init(void) +{ + acpi_status status; + int ret; + void __iomem *bgrt; + + if (acpi_disabled) + return -ENODEV; + + status = acpi_get_table("BGRT", 0, + (struct acpi_table_header **)&bgrt_tab); + + if (ACPI_FAILURE(status)) + return -ENODEV; + + sysfs_bin_attr_init(&image_attr); + + bgrt = ioremap(bgrt_tab->image_address, sizeof(struct bmp_header)); + + if (!bgrt) { + ret = -EINVAL; + goto out_err; + } + + memcpy_fromio(&bmp_header, bgrt, sizeof(bmp_header)); + image_attr.size = bmp_header.size; + iounmap(bgrt); + + image_attr.private = ioremap(bgrt_tab->image_address, image_attr.size); + + if (!image_attr.private) { + ret = -EINVAL; + goto out_err; + } + + + bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj); + if (!bgrt_kobj) { + ret = -EINVAL; + goto out_iounmap; + } + + ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group); + if (ret) + goto out_kobject; + + ret = sysfs_create_bin_file(bgrt_kobj, &image_attr); + if (ret) + goto out_group; + + return 0; + +out_group: + sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group); +out_kobject: + kobject_put(bgrt_kobj); +out_iounmap: + iounmap(image_attr.private); +out_err: + return ret; +} + +static void __exit bgrt_exit(void) +{ + iounmap(image_attr.private); + sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group); + sysfs_remove_bin_file(bgrt_kobj, &image_attr); +} + +module_init(bgrt_init); +module_exit(bgrt_exit); + +MODULE_AUTHOR("Matthew Garrett"); +MODULE_DESCRIPTION("BGRT boot graphic support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9ecec98bc76..3263b68cdfa 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1010,6 +1010,7 @@ static int __init acpi_bus_init(void) } struct kobject *acpi_kobj; +EXPORT_SYMBOL_GPL(acpi_kobj); static int __init acpi_init(void) { diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index b19a18dd994..3268dcfbaa9 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -812,10 +812,10 @@ static int acpi_ec_add(struct acpi_device *device) first_ec = ec; device->driver_data = ec; - WARN(!request_region(ec->data_addr, 1, "EC data"), - "Could not request EC data io port 0x%lx", ec->data_addr); - WARN(!request_region(ec->command_addr, 1, "EC cmd"), - "Could not request EC cmd io port 0x%lx", ec->command_addr); + ret = !!request_region(ec->data_addr, 1, "EC data"); + WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr); + ret = !!request_region(ec->command_addr, 1, "EC cmd"); + WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", ec->gpe, ec->command_addr, ec->data_addr); diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c index 7a2035fa8c7..266bc58ce0c 100644 --- a/drivers/acpi/nvs.c +++ b/drivers/acpi/nvs.c @@ -95,8 +95,8 @@ static int suspend_nvs_register(unsigned long start, unsigned long size) { struct nvs_page *entry, *next; - pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n", - start, size); + pr_info("PM: Registering ACPI NVS region [mem %#010lx-%#010lx] (%ld bytes)\n", + start, start + size - 1, size); while (size > 0) { unsigned int nr_bytes; diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 07d426425b5..9fddb55764f 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -347,7 +347,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) unsigned long pfn; pfn = pg_off >> PAGE_SHIFT; - if (page_is_ram(pfn)) + if (should_use_kmap(pfn)) kunmap(pfn_to_page(pfn)); else iounmap(vaddr); @@ -604,7 +604,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, acpi_irq_handler = handler; acpi_irq_context = context; - if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { + if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi", + acpi_irq)) { printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); acpi_irq_handler = NULL; return AE_NOT_ACQUIRED; diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 8ae05ce1850..41de1355edc 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -68,6 +68,7 @@ #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 +#define ACPI_PROCESSOR_DEVICE_HID "ACPI0007" #define ACPI_PROCESSOR_LIMIT_USER 0 #define ACPI_PROCESSOR_LIMIT_THERMAL 1 @@ -88,7 +89,7 @@ static int acpi_processor_start(struct acpi_processor *pr); static const struct acpi_device_id processor_device_ids[] = { {ACPI_PROCESSOR_OBJECT_HID, 0}, - {"ACPI0007", 0}, + {ACPI_PROCESSOR_DEVICE_HID, 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, processor_device_ids); @@ -535,8 +536,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) return -ENOMEM; if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { - kfree(pr); - return -ENOMEM; + result = -ENOMEM; + goto err_free_pr; } pr->handle = device->handle; @@ -576,7 +577,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) dev = get_cpu_device(pr->id); if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) { result = -EFAULT; - goto err_free_cpumask; + goto err_clear_processor; } /* @@ -594,9 +595,15 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) err_remove_sysfs: sysfs_remove_link(&device->dev.kobj, "sysdev"); +err_clear_processor: + /* + * processor_device_array is not cleared to allow checks for buggy BIOS + */ + per_cpu(processors, pr->id) = NULL; err_free_cpumask: free_cpumask_var(pr->throttling.shared_cpu_map); - +err_free_pr: + kfree(pr); return result; } @@ -741,20 +748,46 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, return; } +static acpi_status is_processor_device(acpi_handle handle) +{ + struct acpi_device_info *info; + char *hid; + acpi_status status; + + status = acpi_get_object_info(handle, &info); + if (ACPI_FAILURE(status)) + return status; + + if (info->type == ACPI_TYPE_PROCESSOR) { + kfree(info); + return AE_OK; /* found a processor object */ + } + + if (!(info->valid & ACPI_VALID_HID)) { + kfree(info); + return AE_ERROR; + } + + hid = info->hardware_id.string; + if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) { + kfree(info); + return AE_ERROR; + } + + kfree(info); + return AE_OK; /* found a processor device object */ +} + static acpi_status processor_walk_namespace_cb(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; int *action = context; - acpi_object_type type = 0; - status = acpi_get_type(handle, &type); + status = is_processor_device(handle); if (ACPI_FAILURE(status)) - return (AE_OK); - - if (type != ACPI_TYPE_PROCESSOR) - return (AE_OK); + return AE_OK; /* not a processor; continue to walk */ switch (*action) { case INSTALL_NOTIFY_HANDLER: @@ -772,7 +805,8 @@ processor_walk_namespace_cb(acpi_handle handle, break; } - return (AE_OK); + /* found a processor; skip walking underneath */ + return AE_CTRL_DEPTH; } static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) @@ -830,7 +864,7 @@ void acpi_processor_install_hotplug_notify(void) { #ifdef CONFIG_ACPI_HOTPLUG_CPU int action = INSTALL_NOTIFY_HANDLER; - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, + acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, processor_walk_namespace_cb, NULL, &action, NULL); @@ -843,7 +877,7 @@ void acpi_processor_uninstall_hotplug_notify(void) { #ifdef CONFIG_ACPI_HOTPLUG_CPU int action = UNINSTALL_NOTIFY_HANDLER; - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, + acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, processor_walk_namespace_cb, NULL, &action, NULL); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0e8e2de2ed3..b3447f63e46 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -770,6 +770,35 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, return index; } + +/** + * acpi_idle_play_dead - enters an ACPI state for long-term idle (i.e. off-lining) + * @dev: the target CPU + * @index: the index of suggested state + */ +static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) +{ + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; + struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); + + ACPI_FLUSH_CPU_CACHE(); + + while (1) { + + if (cx->entry_method == ACPI_CSTATE_HALT) + halt(); + else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) { + inb(cx->address); + /* See comment in acpi_idle_do_entry() */ + inl(acpi_gbl_FADT.xpm_timer_block.address); + } else + return -ENODEV; + } + + /* Never reached */ + return 0; +} + /** * acpi_idle_enter_simple - enters an ACPI state without BM handling * @dev: the target CPU @@ -1077,12 +1106,14 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) state->flags |= CPUIDLE_FLAG_TIME_VALID; state->enter = acpi_idle_enter_c1; + state->enter_dead = acpi_idle_play_dead; drv->safe_state_index = count; break; case ACPI_STATE_C2: state->flags |= CPUIDLE_FLAG_TIME_VALID; state->enter = acpi_idle_enter_simple; + state->enter_dead = acpi_idle_play_dead; drv->safe_state_index = count; break; @@ -1159,8 +1190,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) * to make the code that updates C-States be called once. */ - if (smp_processor_id() == 0 && - cpuidle_get_driver() == &acpi_idle_driver) { + if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) { cpuidle_pause_and_lock(); /* Protect against cpu-hotplug */ diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 3b599abf2b4..641b5450a0d 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -57,6 +57,27 @@ ACPI_MODULE_NAME("processor_thermal"); static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); static unsigned int acpi_thermal_cpufreq_is_init = 0; +#define reduction_pctg(cpu) \ + per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu)) + +/* + * Emulate "per package data" using per cpu data (which should really be + * provided elsewhere) + * + * Note we can lose a CPU on cpu hotunplug, in this case we forget the state + * temporarily. Fortunately that's not a big issue here (I hope) + */ +static int phys_package_first_cpu(int cpu) +{ + int i; + int id = topology_physical_package_id(cpu); + + for_each_online_cpu(i) + if (topology_physical_package_id(i) == id) + return i; + return 0; +} + static int cpu_has_cpufreq(unsigned int cpu) { struct cpufreq_policy policy; @@ -76,7 +97,7 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, max_freq = ( policy->cpuinfo.max_freq * - (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20) + (100 - reduction_pctg(policy->cpu) * 20) ) / 100; cpufreq_verify_within_limits(policy, 0, max_freq); @@ -102,16 +123,28 @@ static int cpufreq_get_cur_state(unsigned int cpu) if (!cpu_has_cpufreq(cpu)) return 0; - return per_cpu(cpufreq_thermal_reduction_pctg, cpu); + return reduction_pctg(cpu); } static int cpufreq_set_cur_state(unsigned int cpu, int state) { + int i; + if (!cpu_has_cpufreq(cpu)) return 0; - per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state; - cpufreq_update_policy(cpu); + reduction_pctg(cpu) = state; + + /* + * Update all the CPUs in the same package because they all + * contribute to the temperature and often share the same + * frequency. + */ + for_each_online_cpu(i) { + if (topology_physical_package_id(i) == + topology_physical_package_id(cpu)) + cpufreq_update_policy(i); + } return 0; } @@ -119,10 +152,6 @@ void acpi_thermal_cpufreq_init(void) { int i; - for (i = 0; i < nr_cpu_ids; i++) - if (cpu_present(i)) - per_cpu(cpufreq_thermal_reduction_pctg, i) = 0; - i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); if (!i) diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 605a2954ef1..1d02b7b5ade 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -769,7 +769,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, u64 *value) { u32 bit_width, bit_offset; - u64 ptc_value; + u32 ptc_value; u64 ptc_mask; struct acpi_processor_throttling *throttling; int ret = -1; @@ -777,12 +777,11 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, throttling = &pr->throttling; 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, + address, &ptc_value, (u32) (bit_width + bit_offset)); ptc_mask = (1 << bit_width) - 1; *value = (u64) ((ptc_value >> bit_offset) & ptc_mask); diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index a6c77e8b37b..c1d61243593 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c @@ -23,8 +23,7 @@ void acpi_reboot(void) /* Is the reset register supported? The spec says we should be * checking the bit width and bit offset, but Windows ignores * these fields */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) - return; + /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */ reset_value = acpi_gbl_FADT.reset_value; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8ab80bafe3f..5d24a17aa85 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -880,7 +880,6 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) int j; device->power.flags.power_resources = 1; - ps->flags.valid = 1; for (j = 0; j < ps->resources.count; j++) acpi_bus_add_power_resource(ps->resources.handles[j]); } @@ -888,10 +887,8 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) /* Evaluate "_PSx" to see if we can do explicit sets */ object_name[2] = 'S'; status = acpi_get_handle(device->handle, object_name, &handle); - if (ACPI_SUCCESS(status)) { + if (ACPI_SUCCESS(status)) ps->flags.explicit_set = 1; - ps->flags.valid = 1; - } /* State is valid if we have some power control */ if (ps->resources.count || ps->flags.explicit_set) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 48fbc647b17..7dbebea1ec3 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -941,13 +941,13 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz) if (!tz) return -EINVAL; - /* Get temperature [_TMP] (required) */ - result = acpi_thermal_get_temperature(tz); + /* Get trip points [_CRT, _PSV, etc.] (required) */ + result = acpi_thermal_get_trip_points(tz); if (result) return result; - /* Get trip points [_CRT, _PSV, etc.] (required) */ - result = acpi_thermal_get_trip_points(tz); + /* Get temperature [_TMP] (required) */ + result = acpi_thermal_get_temperature(tz); if (result) return result; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index eaef02afc7c..9577b6fa265 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -548,27 +548,27 @@ acpi_video_device_EDID(struct acpi_video_device *device, * 1. The system BIOS should NOT automatically control the brightness * level of the LCD when the power changes from AC to DC. * Return Value: - * -1 wrong arg. + * -EINVAL wrong arg. */ static int acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) { - u64 status = 0; + acpi_status status; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; - if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) { - status = -1; - goto Failed; - } + if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) + return -EINVAL; arg0.integer.value = (lcd_flag << 2) | bios_flag; video->dos_setting = arg0.integer.value; - acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL); + status = acpi_evaluate_object(video->device->handle, "_DOS", + &args, NULL); + if (ACPI_FAILURE(status)) + return -EIO; - Failed: - return status; + return 0; } /* @@ -1343,15 +1343,17 @@ static int acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) { - int status = 0; + int status; struct acpi_device *dev; - acpi_video_device_enumerate(video); + status = acpi_video_device_enumerate(video); + if (status) + return status; list_for_each_entry(dev, &device->children, node) { status = acpi_video_bus_get_one_device(dev, video); - if (ACPI_FAILURE(status)) { + if (status) { printk(KERN_WARNING PREFIX "Can't attach device\n"); continue; @@ -1653,15 +1655,20 @@ static int acpi_video_bus_add(struct acpi_device *device) mutex_init(&video->device_list_lock); INIT_LIST_HEAD(&video->video_device_list); - acpi_video_bus_get_devices(video, device); - acpi_video_bus_start_devices(video); + error = acpi_video_bus_get_devices(video, device); + if (error) + goto err_free_video; video->input = input = input_allocate_device(); if (!input) { error = -ENOMEM; - goto err_stop_video; + goto err_put_video; } + error = acpi_video_bus_start_devices(video); + if (error) + goto err_free_input_dev; + snprintf(video->phys, sizeof(video->phys), "%s/video/input0", acpi_device_hid(video->device)); @@ -1682,7 +1689,7 @@ static int acpi_video_bus_add(struct acpi_device *device) error = input_register_device(input); if (error) - goto err_free_input_dev; + goto err_stop_video; printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), @@ -1692,14 +1699,19 @@ static int acpi_video_bus_add(struct acpi_device *device) video->pm_nb.notifier_call = acpi_video_resume; video->pm_nb.priority = 0; - register_pm_notifier(&video->pm_nb); + error = register_pm_notifier(&video->pm_nb); + if (error) + goto err_unregister_input_dev; return 0; - err_free_input_dev: - input_free_device(input); + err_unregister_input_dev: + input_unregister_device(input); err_stop_video: acpi_video_bus_stop_devices(video); + err_free_input_dev: + input_free_device(input); + err_put_video: acpi_video_bus_put_devices(video); kfree(video->attached_array); err_free_video: |