mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 04:42:12 +00:00
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (28 commits) ACPI: delete stale reference in kernel-parameters.txt ACPI: add missing _OSI strings ACPI: remove NID_INVAL thermal: make THERMAL_HWMON implementation fully internal thermal: split hwmon lookup to a separate function thermal: hide CONFIG_THERMAL_HWMON ACPI print OSI(Linux) warning only once ACPI: DMI workaround for Asus A8N-SLI Premium and Asus A8N-SLI DELUX ACPI / Battery: propagate sysfs error in acpi_battery_add() ACPI / Battery: avoid acpi_battery_add() use-after-free ACPI: introduce "acpi_rsdp=" parameter for kdump ACPI: constify ops structs ACPI: fix CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS ACPI: fix 80 char overflow ACPI / Battery: Resolve the race condition in the sysfs_remove_battery() ACPI / Battery: Add the check before refresh sysfs in the battery_notify() ACPI / Battery: Add the hibernation process in the battery_notify() ACPI / Battery: Rename acpi_battery_quirks2 with acpi_battery_quirks ACPI / Battery: Change 16-bit signed negative battery current into correct value ACPI / Battery: Add the power unit macro ...
This commit is contained in:
commit
c299eba3c5
@ -296,15 +296,6 @@ Who: Ravikiran Thirumalai <kiran@scalex86.org>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: CONFIG_THERMAL_HWMON
|
||||
When: January 2009
|
||||
Why: This option was introduced just to allow older lm-sensors userspace
|
||||
to keep working over the upgrade to 2.6.26. At the scheduled time of
|
||||
removal fixed lm-sensors (2.x or 3.x) should be readily available.
|
||||
Who: Rene Herman <rene.herman@gmail.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS
|
||||
(in net/core/net-sysfs.c)
|
||||
When: After the only user (hal) has seen a release with the patches
|
||||
|
@ -163,6 +163,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
|
||||
See also Documentation/power/pm.txt, pci=noacpi
|
||||
|
||||
acpi_rsdp= [ACPI,EFI,KEXEC]
|
||||
Pass the RSDP address to the kernel, mostly used
|
||||
on machines running EFI runtime service to boot the
|
||||
second kernel for kdump.
|
||||
|
||||
acpi_apic_instance= [ACPI, IOAPIC]
|
||||
Format: <int>
|
||||
2: use 2nd APIC table, if available
|
||||
|
@ -126,6 +126,12 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE);
|
||||
*/
|
||||
u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE);
|
||||
|
||||
/*
|
||||
* Disable runtime checking and repair of values returned by control methods.
|
||||
* Use only if the repair is causing a problem on a particular machine.
|
||||
*/
|
||||
u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE);
|
||||
|
||||
/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
|
||||
|
||||
struct acpi_table_fadt acpi_gbl_FADT;
|
||||
|
@ -357,6 +357,7 @@ struct acpi_predefined_data {
|
||||
char *pathname;
|
||||
const union acpi_predefined_info *predefined;
|
||||
union acpi_operand_object *parent_package;
|
||||
struct acpi_namespace_node *node;
|
||||
u32 flags;
|
||||
u8 node_flags;
|
||||
};
|
||||
|
@ -468,6 +468,7 @@ static const union acpi_predefined_info predefined_names[] =
|
||||
{{"_SWS", 0, ACPI_RTYPE_INTEGER}},
|
||||
{{"_TC1", 0, ACPI_RTYPE_INTEGER}},
|
||||
{{"_TC2", 0, ACPI_RTYPE_INTEGER}},
|
||||
{{"_TDL", 0, ACPI_RTYPE_INTEGER}},
|
||||
{{"_TIP", 1, ACPI_RTYPE_INTEGER}},
|
||||
{{"_TIV", 1, ACPI_RTYPE_INTEGER}},
|
||||
{{"_TMP", 0, ACPI_RTYPE_INTEGER}},
|
||||
|
@ -193,14 +193,20 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) We have a return value, but if one wasn't expected, just exit, this is
|
||||
* not a problem. For example, if the "Implicit Return" feature is
|
||||
* enabled, methods will always return a value.
|
||||
* Return value validation and possible repair.
|
||||
*
|
||||
* 2) If the return value can be of any type, then we cannot perform any
|
||||
* validation, exit.
|
||||
* 1) Don't perform return value validation/repair if this feature
|
||||
* has been disabled via a global option.
|
||||
*
|
||||
* 2) We have a return value, but if one wasn't expected, just exit,
|
||||
* this is not a problem. For example, if the "Implicit Return"
|
||||
* feature is enabled, methods will always return a value.
|
||||
*
|
||||
* 3) If the return value can be of any type, then we cannot perform
|
||||
* any validation, just exit.
|
||||
*/
|
||||
if ((!predefined->info.expected_btypes) ||
|
||||
if (acpi_gbl_disable_auto_repair ||
|
||||
(!predefined->info.expected_btypes) ||
|
||||
(predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
|
||||
goto cleanup;
|
||||
}
|
||||
@ -212,6 +218,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
|
||||
goto cleanup;
|
||||
}
|
||||
data->predefined = predefined;
|
||||
data->node = node;
|
||||
data->node_flags = node->flags;
|
||||
data->pathname = pathname;
|
||||
|
||||
|
@ -503,6 +503,21 @@ acpi_ns_repair_TSS(struct acpi_predefined_data *data,
|
||||
{
|
||||
union acpi_operand_object *return_object = *return_object_ptr;
|
||||
acpi_status status;
|
||||
struct acpi_namespace_node *node;
|
||||
|
||||
/*
|
||||
* We can only sort the _TSS return package if there is no _PSS in the
|
||||
* same scope. This is because if _PSS is present, the ACPI specification
|
||||
* dictates that the _TSS Power Dissipation field is to be ignored, and
|
||||
* therefore some BIOSs leave garbage values in the _TSS Power field(s).
|
||||
* In this case, it is best to just return the _TSS package as-is.
|
||||
* (May, 2011)
|
||||
*/
|
||||
status =
|
||||
acpi_ns_get_node(data->node, "^_PSS", ACPI_NS_NO_UPSEARCH, &node);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
status = acpi_ns_check_sorted_list(data, return_object, 5, 1,
|
||||
ACPI_SORT_DESCENDING,
|
||||
|
@ -126,12 +126,29 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
|
||||
}
|
||||
|
||||
/*
|
||||
* Originally, we checked the table signature for "SSDT" or "PSDT" here.
|
||||
* Next, we added support for OEMx tables, signature "OEM".
|
||||
* Valid tables were encountered with a null signature, so we've just
|
||||
* given up on validating the signature, since it seems to be a waste
|
||||
* of code. The original code was removed (05/2008).
|
||||
* Validate the incoming table signature.
|
||||
*
|
||||
* 1) Originally, we checked the table signature for "SSDT" or "PSDT".
|
||||
* 2) We added support for OEMx tables, signature "OEM".
|
||||
* 3) Valid tables were encountered with a null signature, so we just
|
||||
* gave up on validating the signature, (05/2008).
|
||||
* 4) We encountered non-AML tables such as the MADT, which caused
|
||||
* interpreter errors and kernel faults. So now, we once again allow
|
||||
* only "SSDT", "OEMx", and now, also a null signature. (05/2011).
|
||||
*/
|
||||
if ((table_desc->pointer->signature[0] != 0x00) &&
|
||||
(!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))
|
||||
&& (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx",
|
||||
acpi_ut_valid_acpi_name(*(u32 *)table_desc->
|
||||
pointer->
|
||||
signature) ? table_desc->
|
||||
pointer->signature : "????",
|
||||
*(u32 *)table_desc->pointer->signature));
|
||||
|
||||
return_ACPI_STATUS(AE_BAD_SIGNATURE);
|
||||
}
|
||||
|
||||
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
|
||||
|
||||
|
@ -55,6 +55,9 @@
|
||||
#define ACPI_BATTERY_NOTIFY_INFO 0x81
|
||||
#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82
|
||||
|
||||
/* Battery power unit: 0 means mW, 1 means mA */
|
||||
#define ACPI_BATTERY_POWER_UNIT_MA 1
|
||||
|
||||
#define _COMPONENT ACPI_BATTERY_COMPONENT
|
||||
|
||||
ACPI_MODULE_NAME("battery");
|
||||
@ -91,11 +94,6 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids);
|
||||
enum {
|
||||
ACPI_BATTERY_ALARM_PRESENT,
|
||||
ACPI_BATTERY_XINFO_PRESENT,
|
||||
/* For buggy DSDTs that report negative 16-bit values for either
|
||||
* charging or discharging current and/or report 0 as 65536
|
||||
* due to bad math.
|
||||
*/
|
||||
ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
|
||||
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
|
||||
};
|
||||
|
||||
@ -301,7 +299,8 @@ static enum power_supply_property energy_battery_props[] = {
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
inline char *acpi_battery_units(struct acpi_battery *battery)
|
||||
{
|
||||
return (battery->power_unit)?"mA":"mW";
|
||||
return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
|
||||
"mA" : "mW";
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -461,9 +460,17 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
|
||||
battery->update_time = jiffies;
|
||||
kfree(buffer.pointer);
|
||||
|
||||
if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) &&
|
||||
battery->rate_now != -1)
|
||||
/* For buggy DSDTs that report negative 16-bit values for either
|
||||
* charging or discharging current and/or report 0 as 65536
|
||||
* due to bad math.
|
||||
*/
|
||||
if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
|
||||
battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
|
||||
(s16)(battery->rate_now) < 0) {
|
||||
battery->rate_now = abs((s16)battery->rate_now);
|
||||
printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate"
|
||||
" invalid.\n");
|
||||
}
|
||||
|
||||
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
|
||||
&& battery->capacity_now >= 0 && battery->capacity_now <= 100)
|
||||
@ -544,7 +551,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (battery->power_unit) {
|
||||
if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
|
||||
battery->bat.properties = charge_battery_props;
|
||||
battery->bat.num_properties =
|
||||
ARRAY_SIZE(charge_battery_props);
|
||||
@ -566,18 +573,16 @@ static int sysfs_add_battery(struct acpi_battery *battery)
|
||||
|
||||
static void sysfs_remove_battery(struct acpi_battery *battery)
|
||||
{
|
||||
if (!battery->bat.dev)
|
||||
mutex_lock(&battery->lock);
|
||||
if (!battery->bat.dev) {
|
||||
mutex_unlock(&battery->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
device_remove_file(battery->bat.dev, &alarm_attr);
|
||||
power_supply_unregister(&battery->bat);
|
||||
battery->bat.dev = NULL;
|
||||
}
|
||||
|
||||
static void acpi_battery_quirks(struct acpi_battery *battery)
|
||||
{
|
||||
if (dmi_name_in_vendors("Acer") && battery->power_unit) {
|
||||
set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags);
|
||||
}
|
||||
mutex_unlock(&battery->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -592,7 +597,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
|
||||
*
|
||||
* Handle this correctly so that they won't break userspace.
|
||||
*/
|
||||
static void acpi_battery_quirks2(struct acpi_battery *battery)
|
||||
static void acpi_battery_quirks(struct acpi_battery *battery)
|
||||
{
|
||||
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
||||
return ;
|
||||
@ -623,13 +628,15 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
||||
result = acpi_battery_get_info(battery);
|
||||
if (result)
|
||||
return result;
|
||||
acpi_battery_quirks(battery);
|
||||
acpi_battery_init_alarm(battery);
|
||||
}
|
||||
if (!battery->bat.dev)
|
||||
sysfs_add_battery(battery);
|
||||
if (!battery->bat.dev) {
|
||||
result = sysfs_add_battery(battery);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
result = acpi_battery_get_state(battery);
|
||||
acpi_battery_quirks2(battery);
|
||||
acpi_battery_quirks(battery);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -863,7 +870,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct battery_file {
|
||||
static const struct battery_file {
|
||||
struct file_operations ops;
|
||||
mode_t mode;
|
||||
const char *name;
|
||||
@ -948,9 +955,12 @@ static int battery_notify(struct notifier_block *nb,
|
||||
struct acpi_battery *battery = container_of(nb, struct acpi_battery,
|
||||
pm_nb);
|
||||
switch (mode) {
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_SUSPEND:
|
||||
sysfs_remove_battery(battery);
|
||||
sysfs_add_battery(battery);
|
||||
if (battery->bat.dev) {
|
||||
sysfs_remove_battery(battery);
|
||||
sysfs_add_battery(battery);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -975,25 +985,33 @@ static int acpi_battery_add(struct acpi_device *device)
|
||||
if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
|
||||
"_BIX", &handle)))
|
||||
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
|
||||
acpi_battery_update(battery);
|
||||
result = acpi_battery_update(battery);
|
||||
if (result)
|
||||
goto fail;
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
result = acpi_battery_add_fs(device);
|
||||
#endif
|
||||
if (!result) {
|
||||
printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
|
||||
ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
|
||||
device->status.battery_present ? "present" : "absent");
|
||||
} else {
|
||||
if (result) {
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
acpi_battery_remove_fs(device);
|
||||
#endif
|
||||
kfree(battery);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
|
||||
ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
|
||||
device->status.battery_present ? "present" : "absent");
|
||||
|
||||
battery->pm_nb.notifier_call = battery_notify;
|
||||
register_pm_notifier(&battery->pm_nb);
|
||||
|
||||
return result;
|
||||
|
||||
fail:
|
||||
sysfs_remove_battery(battery);
|
||||
mutex_destroy(&battery->lock);
|
||||
kfree(battery);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_battery_remove(struct acpi_device *device, int type)
|
||||
|
@ -77,7 +77,7 @@ struct dock_dependent_device {
|
||||
struct list_head list;
|
||||
struct list_head hotplug_list;
|
||||
acpi_handle handle;
|
||||
struct acpi_dock_ops *ops;
|
||||
const struct acpi_dock_ops *ops;
|
||||
void *context;
|
||||
};
|
||||
|
||||
@ -589,7 +589,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
|
||||
* the dock driver after _DCK is executed.
|
||||
*/
|
||||
int
|
||||
register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
|
||||
register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops,
|
||||
void *context)
|
||||
{
|
||||
struct dock_dependent_device *dd;
|
||||
|
@ -92,7 +92,7 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct file_operations acpi_ec_io_ops = {
|
||||
static const struct file_operations acpi_ec_io_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_ec_open_io,
|
||||
.read = acpi_ec_read_io,
|
||||
|
@ -110,7 +110,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct thermal_cooling_device_ops fan_cooling_ops = {
|
||||
static const struct thermal_cooling_device_ops fan_cooling_ops = {
|
||||
.get_max_state = fan_get_max_state,
|
||||
.get_cur_state = fan_get_cur_state,
|
||||
.set_cur_state = fan_set_cur_state,
|
||||
|
@ -155,7 +155,7 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)
|
||||
{
|
||||
if (!strcmp("Linux", interface)) {
|
||||
|
||||
printk(KERN_NOTICE FW_BUG PREFIX
|
||||
printk_once(KERN_NOTICE FW_BUG PREFIX
|
||||
"BIOS _OSI(Linux) query %s%s\n",
|
||||
osi_linux.enable ? "honored" : "ignored",
|
||||
osi_linux.cmdline ? " via cmdline" :
|
||||
@ -237,8 +237,23 @@ void acpi_os_vprintf(const char *fmt, va_list args)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
static unsigned long acpi_rsdp;
|
||||
static int __init setup_acpi_rsdp(char *arg)
|
||||
{
|
||||
acpi_rsdp = simple_strtoul(arg, NULL, 16);
|
||||
return 0;
|
||||
}
|
||||
early_param("acpi_rsdp", setup_acpi_rsdp);
|
||||
#endif
|
||||
|
||||
acpi_physical_address __init acpi_os_get_root_pointer(void)
|
||||
{
|
||||
#ifdef CONFIG_KEXEC
|
||||
if (acpi_rsdp)
|
||||
return acpi_rsdp;
|
||||
#endif
|
||||
|
||||
if (efi_enabled) {
|
||||
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
|
||||
return efi.acpi20;
|
||||
@ -1083,7 +1098,13 @@ struct osi_setup_entry {
|
||||
bool enable;
|
||||
};
|
||||
|
||||
static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
|
||||
static struct osi_setup_entry __initdata
|
||||
osi_setup_entries[OSI_STRING_ENTRIES_MAX] = {
|
||||
{"Module Device", true},
|
||||
{"Processor Device", true},
|
||||
{"3.0 _SCP Extensions", true},
|
||||
{"Processor Aggregator Device", true},
|
||||
};
|
||||
|
||||
void __init acpi_osi_setup(char *str)
|
||||
{
|
||||
|
@ -303,6 +303,61 @@ void acpi_pci_irq_del_prt(struct pci_bus *bus)
|
||||
/* --------------------------------------------------------------------------
|
||||
PCI Interrupt Routing Support
|
||||
-------------------------------------------------------------------------- */
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
extern int noioapicquirk;
|
||||
extern int noioapicreroute;
|
||||
|
||||
static int bridge_has_boot_interrupt_variant(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_bus *bus_it;
|
||||
|
||||
for (bus_it = bus ; bus_it ; bus_it = bus_it->parent) {
|
||||
if (!bus_it->self)
|
||||
return 0;
|
||||
if (bus_it->self->irq_reroute_variant)
|
||||
return bus_it->self->irq_reroute_variant;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some chipsets (e.g. Intel 6700PXH) generate a legacy INTx when the IRQ
|
||||
* entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel does
|
||||
* during interrupt handling). When this INTx generation cannot be disabled,
|
||||
* we reroute these interrupts to their legacy equivalent to get rid of
|
||||
* spurious interrupts.
|
||||
*/
|
||||
static int acpi_reroute_boot_interrupt(struct pci_dev *dev,
|
||||
struct acpi_prt_entry *entry)
|
||||
{
|
||||
if (noioapicquirk || noioapicreroute) {
|
||||
return 0;
|
||||
} else {
|
||||
switch (bridge_has_boot_interrupt_variant(dev->bus)) {
|
||||
case 0:
|
||||
/* no rerouting necessary */
|
||||
return 0;
|
||||
case INTEL_IRQ_REROUTE_VARIANT:
|
||||
/*
|
||||
* Remap according to INTx routing table in 6700PXH
|
||||
* specs, intel order number 302628-002, section
|
||||
* 2.15.2. Other chipsets (80332, ...) have the same
|
||||
* mapping and are handled here as well.
|
||||
*/
|
||||
dev_info(&dev->dev, "PCI IRQ %d -> rerouted to legacy "
|
||||
"IRQ %d\n", entry->index,
|
||||
(entry->index % 4) + 16);
|
||||
entry->index = (entry->index % 4) + 16;
|
||||
return 1;
|
||||
default:
|
||||
dev_warn(&dev->dev, "Cannot reroute IRQ %d to legacy "
|
||||
"IRQ: unknown mapping\n", entry->index);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_X86_IO_APIC */
|
||||
|
||||
static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
|
||||
{
|
||||
struct acpi_prt_entry *entry;
|
||||
@ -311,6 +366,9 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
|
||||
|
||||
entry = acpi_pci_irq_find_prt_entry(dev, pin);
|
||||
if (entry) {
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
acpi_reroute_boot_interrupt(dev, entry);
|
||||
#endif /* CONFIG_X86_IO_APIC */
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
|
||||
pci_name(dev), pin_name(pin)));
|
||||
return entry;
|
||||
|
@ -485,7 +485,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
root->secondary.end = 0xFF;
|
||||
printk(KERN_WARNING FW_BUG PREFIX
|
||||
"no secondary bus range in _CRS\n");
|
||||
status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus);
|
||||
status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,
|
||||
NULL, &bus);
|
||||
if (ACPI_SUCCESS(status))
|
||||
root->secondary.start = bus;
|
||||
else if (status == AE_NOT_FOUND)
|
||||
|
@ -244,7 +244,7 @@ processor_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
return result;
|
||||
}
|
||||
|
||||
struct thermal_cooling_device_ops processor_cooling_ops = {
|
||||
const struct thermal_cooling_device_ops processor_cooling_ops = {
|
||||
.get_max_state = processor_get_max_state,
|
||||
.get_cur_state = processor_get_cur_state,
|
||||
.set_cur_state = processor_set_cur_state,
|
||||
|
@ -130,6 +130,9 @@ struct acpi_sbs {
|
||||
|
||||
#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
|
||||
|
||||
static int acpi_sbs_remove(struct acpi_device *device, int type);
|
||||
static int acpi_battery_get_state(struct acpi_battery *battery);
|
||||
|
||||
static inline int battery_scale(int log)
|
||||
{
|
||||
int scale = 1;
|
||||
@ -195,6 +198,8 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
|
||||
|
||||
if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
|
||||
return -ENODEV;
|
||||
|
||||
acpi_battery_get_state(battery);
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
if (battery->rate_now < 0)
|
||||
@ -225,11 +230,17 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
|
||||
case POWER_SUPPLY_PROP_POWER_NOW:
|
||||
val->intval = abs(battery->rate_now) *
|
||||
acpi_battery_ipscale(battery) * 1000;
|
||||
val->intval *= (acpi_battery_mode(battery)) ?
|
||||
(battery->voltage_now *
|
||||
acpi_battery_vscale(battery) / 1000) : 1;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_AVG:
|
||||
case POWER_SUPPLY_PROP_POWER_AVG:
|
||||
val->intval = abs(battery->rate_avg) *
|
||||
acpi_battery_ipscale(battery) * 1000;
|
||||
val->intval *= (acpi_battery_mode(battery)) ?
|
||||
(battery->voltage_now *
|
||||
acpi_battery_vscale(battery) / 1000) : 1;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
val->intval = battery->state_of_charge;
|
||||
@ -903,8 +914,6 @@ static void acpi_sbs_callback(void *context)
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_sbs_remove(struct acpi_device *device, int type);
|
||||
|
||||
static int acpi_sbs_add(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_sbs *sbs;
|
||||
|
@ -428,6 +428,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = init_old_suspend_ordering,
|
||||
.ident = "Asus A8N-SLI DELUXE",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = init_old_suspend_ordering,
|
||||
.ident = "Asus A8N-SLI Premium",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),
|
||||
},
|
||||
},
|
||||
{},
|
||||
};
|
||||
#endif /* CONFIG_SUSPEND */
|
||||
|
@ -149,12 +149,12 @@ static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct kernel_param_ops param_ops_debug_layer = {
|
||||
static const struct kernel_param_ops param_ops_debug_layer = {
|
||||
.set = param_set_uint,
|
||||
.get = param_get_debug_layer,
|
||||
};
|
||||
|
||||
static struct kernel_param_ops param_ops_debug_level = {
|
||||
static const struct kernel_param_ops param_ops_debug_level = {
|
||||
.set = param_set_uint,
|
||||
.get = param_get_debug_level,
|
||||
};
|
||||
|
@ -812,7 +812,7 @@ acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
|
||||
thermal_zone_unbind_cooling_device);
|
||||
}
|
||||
|
||||
static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
|
||||
static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
|
||||
.bind = acpi_thermal_bind_cooling_device,
|
||||
.unbind = acpi_thermal_unbind_cooling_device,
|
||||
.get_temp = thermal_get_temp,
|
||||
|
@ -307,7 +307,7 @@ video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long st
|
||||
return acpi_video_device_lcd_set_level(video, level);
|
||||
}
|
||||
|
||||
static struct thermal_cooling_device_ops video_cooling_ops = {
|
||||
static const struct thermal_cooling_device_ops video_cooling_ops = {
|
||||
.get_max_state = video_get_max_state,
|
||||
.get_cur_state = video_get_cur_state,
|
||||
.set_cur_state = video_set_cur_state,
|
||||
|
@ -218,12 +218,12 @@ static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data)
|
||||
ata_acpi_uevent(dev->link->ap, dev, event);
|
||||
}
|
||||
|
||||
static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
|
||||
static const struct acpi_dock_ops ata_acpi_dev_dock_ops = {
|
||||
.handler = ata_acpi_dev_notify_dock,
|
||||
.uevent = ata_acpi_dev_uevent,
|
||||
};
|
||||
|
||||
static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
|
||||
static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
|
||||
.handler = ata_acpi_ap_notify_dock,
|
||||
.uevent = ata_acpi_ap_uevent,
|
||||
};
|
||||
|
@ -110,7 +110,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
|
||||
}
|
||||
|
||||
|
||||
static struct acpi_dock_ops acpiphp_dock_ops = {
|
||||
static const struct acpi_dock_ops acpiphp_dock_ops = {
|
||||
.handler = handle_hotplug_event_func,
|
||||
};
|
||||
|
||||
|
@ -14,11 +14,7 @@ menuconfig THERMAL
|
||||
If you want this support, you should say Y or M here.
|
||||
|
||||
config THERMAL_HWMON
|
||||
bool "Hardware monitoring support"
|
||||
bool
|
||||
depends on THERMAL
|
||||
depends on HWMON=y || HWMON=THERMAL
|
||||
help
|
||||
The generic thermal sysfs driver's hardware monitoring support
|
||||
requires a 2.10.7/3.0.2 or later lm-sensors userspace.
|
||||
|
||||
Say Y if your user-space is new enough.
|
||||
default y
|
||||
|
@ -420,6 +420,29 @@ thermal_cooling_device_trip_point_show(struct device *dev,
|
||||
|
||||
/* hwmon sys I/F */
|
||||
#include <linux/hwmon.h>
|
||||
|
||||
/* thermal zone devices with the same type share one hwmon device */
|
||||
struct thermal_hwmon_device {
|
||||
char type[THERMAL_NAME_LENGTH];
|
||||
struct device *device;
|
||||
int count;
|
||||
struct list_head tz_list;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct thermal_hwmon_attr {
|
||||
struct device_attribute attr;
|
||||
char name[16];
|
||||
};
|
||||
|
||||
/* one temperature input for each thermal zone */
|
||||
struct thermal_hwmon_temp {
|
||||
struct list_head hwmon_node;
|
||||
struct thermal_zone_device *tz;
|
||||
struct thermal_hwmon_attr temp_input; /* hwmon sys attr */
|
||||
struct thermal_hwmon_attr temp_crit; /* hwmon sys attr */
|
||||
};
|
||||
|
||||
static LIST_HEAD(thermal_hwmon_list);
|
||||
|
||||
static ssize_t
|
||||
@ -437,9 +460,10 @@ temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
int ret;
|
||||
struct thermal_hwmon_attr *hwmon_attr
|
||||
= container_of(attr, struct thermal_hwmon_attr, attr);
|
||||
struct thermal_zone_device *tz
|
||||
= container_of(hwmon_attr, struct thermal_zone_device,
|
||||
struct thermal_hwmon_temp *temp
|
||||
= container_of(hwmon_attr, struct thermal_hwmon_temp,
|
||||
temp_input);
|
||||
struct thermal_zone_device *tz = temp->tz;
|
||||
|
||||
ret = tz->ops->get_temp(tz, &temperature);
|
||||
|
||||
@ -455,9 +479,10 @@ temp_crit_show(struct device *dev, struct device_attribute *attr,
|
||||
{
|
||||
struct thermal_hwmon_attr *hwmon_attr
|
||||
= container_of(attr, struct thermal_hwmon_attr, attr);
|
||||
struct thermal_zone_device *tz
|
||||
= container_of(hwmon_attr, struct thermal_zone_device,
|
||||
struct thermal_hwmon_temp *temp
|
||||
= container_of(hwmon_attr, struct thermal_hwmon_temp,
|
||||
temp_crit);
|
||||
struct thermal_zone_device *tz = temp->tz;
|
||||
long temperature;
|
||||
int ret;
|
||||
|
||||
@ -469,22 +494,54 @@ temp_crit_show(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
||||
static struct thermal_hwmon_device *
|
||||
thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_hwmon_device *hwmon;
|
||||
int new_hwmon_device = 1;
|
||||
int result;
|
||||
|
||||
mutex_lock(&thermal_list_lock);
|
||||
list_for_each_entry(hwmon, &thermal_hwmon_list, node)
|
||||
if (!strcmp(hwmon->type, tz->type)) {
|
||||
new_hwmon_device = 0;
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
goto register_sys_interface;
|
||||
return hwmon;
|
||||
}
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the temperature input matching a given thermal zone */
|
||||
static struct thermal_hwmon_temp *
|
||||
thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon,
|
||||
const struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_hwmon_temp *temp;
|
||||
|
||||
mutex_lock(&thermal_list_lock);
|
||||
list_for_each_entry(temp, &hwmon->tz_list, hwmon_node)
|
||||
if (temp->tz == tz) {
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
return temp;
|
||||
}
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_hwmon_device *hwmon;
|
||||
struct thermal_hwmon_temp *temp;
|
||||
int new_hwmon_device = 1;
|
||||
int result;
|
||||
|
||||
hwmon = thermal_hwmon_lookup_by_type(tz);
|
||||
if (hwmon) {
|
||||
new_hwmon_device = 0;
|
||||
goto register_sys_interface;
|
||||
}
|
||||
|
||||
hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL);
|
||||
if (!hwmon)
|
||||
return -ENOMEM;
|
||||
@ -502,30 +559,36 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
||||
goto free_mem;
|
||||
|
||||
register_sys_interface:
|
||||
tz->hwmon = hwmon;
|
||||
temp = kzalloc(sizeof(struct thermal_hwmon_temp), GFP_KERNEL);
|
||||
if (!temp) {
|
||||
result = -ENOMEM;
|
||||
goto unregister_name;
|
||||
}
|
||||
|
||||
temp->tz = tz;
|
||||
hwmon->count++;
|
||||
|
||||
snprintf(tz->temp_input.name, THERMAL_NAME_LENGTH,
|
||||
snprintf(temp->temp_input.name, THERMAL_NAME_LENGTH,
|
||||
"temp%d_input", hwmon->count);
|
||||
tz->temp_input.attr.attr.name = tz->temp_input.name;
|
||||
tz->temp_input.attr.attr.mode = 0444;
|
||||
tz->temp_input.attr.show = temp_input_show;
|
||||
sysfs_attr_init(&tz->temp_input.attr.attr);
|
||||
result = device_create_file(hwmon->device, &tz->temp_input.attr);
|
||||
temp->temp_input.attr.attr.name = temp->temp_input.name;
|
||||
temp->temp_input.attr.attr.mode = 0444;
|
||||
temp->temp_input.attr.show = temp_input_show;
|
||||
sysfs_attr_init(&temp->temp_input.attr.attr);
|
||||
result = device_create_file(hwmon->device, &temp->temp_input.attr);
|
||||
if (result)
|
||||
goto unregister_name;
|
||||
goto free_temp_mem;
|
||||
|
||||
if (tz->ops->get_crit_temp) {
|
||||
unsigned long temperature;
|
||||
if (!tz->ops->get_crit_temp(tz, &temperature)) {
|
||||
snprintf(tz->temp_crit.name, THERMAL_NAME_LENGTH,
|
||||
snprintf(temp->temp_crit.name, THERMAL_NAME_LENGTH,
|
||||
"temp%d_crit", hwmon->count);
|
||||
tz->temp_crit.attr.attr.name = tz->temp_crit.name;
|
||||
tz->temp_crit.attr.attr.mode = 0444;
|
||||
tz->temp_crit.attr.show = temp_crit_show;
|
||||
sysfs_attr_init(&tz->temp_crit.attr.attr);
|
||||
temp->temp_crit.attr.attr.name = temp->temp_crit.name;
|
||||
temp->temp_crit.attr.attr.mode = 0444;
|
||||
temp->temp_crit.attr.show = temp_crit_show;
|
||||
sysfs_attr_init(&temp->temp_crit.attr.attr);
|
||||
result = device_create_file(hwmon->device,
|
||||
&tz->temp_crit.attr);
|
||||
&temp->temp_crit.attr);
|
||||
if (result)
|
||||
goto unregister_input;
|
||||
}
|
||||
@ -534,13 +597,15 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
||||
mutex_lock(&thermal_list_lock);
|
||||
if (new_hwmon_device)
|
||||
list_add_tail(&hwmon->node, &thermal_hwmon_list);
|
||||
list_add_tail(&tz->hwmon_node, &hwmon->tz_list);
|
||||
list_add_tail(&temp->hwmon_node, &hwmon->tz_list);
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_input:
|
||||
device_remove_file(hwmon->device, &tz->temp_input.attr);
|
||||
device_remove_file(hwmon->device, &temp->temp_input.attr);
|
||||
free_temp_mem:
|
||||
kfree(temp);
|
||||
unregister_name:
|
||||
if (new_hwmon_device) {
|
||||
device_remove_file(hwmon->device, &dev_attr_name);
|
||||
@ -556,15 +621,30 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
||||
static void
|
||||
thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_hwmon_device *hwmon = tz->hwmon;
|
||||
struct thermal_hwmon_device *hwmon;
|
||||
struct thermal_hwmon_temp *temp;
|
||||
|
||||
tz->hwmon = NULL;
|
||||
device_remove_file(hwmon->device, &tz->temp_input.attr);
|
||||
hwmon = thermal_hwmon_lookup_by_type(tz);
|
||||
if (unlikely(!hwmon)) {
|
||||
/* Should never happen... */
|
||||
dev_dbg(&tz->device, "hwmon device lookup failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
temp = thermal_hwmon_lookup_temp(hwmon, tz);
|
||||
if (unlikely(!temp)) {
|
||||
/* Should never happen... */
|
||||
dev_dbg(&tz->device, "temperature input lookup failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
device_remove_file(hwmon->device, &temp->temp_input.attr);
|
||||
if (tz->ops->get_crit_temp)
|
||||
device_remove_file(hwmon->device, &tz->temp_crit.attr);
|
||||
device_remove_file(hwmon->device, &temp->temp_crit.attr);
|
||||
|
||||
mutex_lock(&thermal_list_lock);
|
||||
list_del(&tz->hwmon_node);
|
||||
list_del(&temp->hwmon_node);
|
||||
kfree(temp);
|
||||
if (!list_empty(&hwmon->tz_list)) {
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
return;
|
||||
|
@ -128,7 +128,7 @@ extern int is_dock_device(acpi_handle handle);
|
||||
extern int register_dock_notifier(struct notifier_block *nb);
|
||||
extern void unregister_dock_notifier(struct notifier_block *nb);
|
||||
extern int register_hotplug_dock_device(acpi_handle handle,
|
||||
struct acpi_dock_ops *ops,
|
||||
const struct acpi_dock_ops *ops,
|
||||
void *context);
|
||||
extern void unregister_hotplug_dock_device(acpi_handle handle);
|
||||
#else
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||
|
||||
#define ACPI_CA_VERSION 0x20110413
|
||||
#define ACPI_CA_VERSION 0x20110623
|
||||
|
||||
#include "actypes.h"
|
||||
#include "actbl.h"
|
||||
@ -69,6 +69,7 @@ extern u32 acpi_gbl_trace_flags;
|
||||
extern u32 acpi_gbl_enable_aml_debug_object;
|
||||
extern u8 acpi_gbl_copy_dsdt_locally;
|
||||
extern u8 acpi_gbl_truncate_io_addresses;
|
||||
extern u8 acpi_gbl_disable_auto_repair;
|
||||
|
||||
extern u32 acpi_current_gpe_count;
|
||||
extern struct acpi_table_fadt acpi_gbl_FADT;
|
||||
|
@ -337,7 +337,7 @@ extern struct cpuidle_driver acpi_idle_driver;
|
||||
|
||||
/* in processor_thermal.c */
|
||||
int acpi_processor_get_limit_info(struct acpi_processor *pr);
|
||||
extern struct thermal_cooling_device_ops processor_cooling_ops;
|
||||
extern const struct thermal_cooling_device_ops processor_cooling_ops;
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
void acpi_thermal_cpufreq_init(void);
|
||||
void acpi_thermal_cpufreq_exit(void);
|
||||
|
@ -238,7 +238,6 @@ extern int acpi_paddr_to_node(u64 start_addr, u64 size);
|
||||
extern int pnpacpi_disabled;
|
||||
|
||||
#define PXM_INVAL (-1)
|
||||
#define NID_INVAL (-1)
|
||||
|
||||
int acpi_check_resource_conflict(const struct resource *res);
|
||||
|
||||
|
@ -85,22 +85,6 @@ struct thermal_cooling_device {
|
||||
((long)t-2732+5)/10 : ((long)t-2732-5)/10)
|
||||
#define CELSIUS_TO_KELVIN(t) ((t)*10+2732)
|
||||
|
||||
#if defined(CONFIG_THERMAL_HWMON)
|
||||
/* thermal zone devices with the same type share one hwmon device */
|
||||
struct thermal_hwmon_device {
|
||||
char type[THERMAL_NAME_LENGTH];
|
||||
struct device *device;
|
||||
int count;
|
||||
struct list_head tz_list;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct thermal_hwmon_attr {
|
||||
struct device_attribute attr;
|
||||
char name[16];
|
||||
};
|
||||
#endif
|
||||
|
||||
struct thermal_zone_device {
|
||||
int id;
|
||||
char type[THERMAL_NAME_LENGTH];
|
||||
@ -120,12 +104,6 @@ struct thermal_zone_device {
|
||||
struct mutex lock; /* protect cooling devices list */
|
||||
struct list_head node;
|
||||
struct delayed_work poll_queue;
|
||||
#if defined(CONFIG_THERMAL_HWMON)
|
||||
struct list_head hwmon_node;
|
||||
struct thermal_hwmon_device *hwmon;
|
||||
struct thermal_hwmon_attr temp_input; /* hwmon sys attr */
|
||||
struct thermal_hwmon_attr temp_crit; /* hwmon sys attr */
|
||||
#endif
|
||||
};
|
||||
/* Adding event notification support elements */
|
||||
#define THERMAL_GENL_FAMILY_NAME "thermal_event"
|
||||
|
Loading…
Reference in New Issue
Block a user