mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 12:52:30 +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
|
What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS
|
||||||
(in net/core/net-sysfs.c)
|
(in net/core/net-sysfs.c)
|
||||||
When: After the only user (hal) has seen a release with the patches
|
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
|
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]
|
acpi_apic_instance= [ACPI, IOAPIC]
|
||||||
Format: <int>
|
Format: <int>
|
||||||
2: use 2nd APIC table, if available
|
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);
|
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. */
|
/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
|
||||||
|
|
||||||
struct acpi_table_fadt acpi_gbl_FADT;
|
struct acpi_table_fadt acpi_gbl_FADT;
|
||||||
|
@ -357,6 +357,7 @@ struct acpi_predefined_data {
|
|||||||
char *pathname;
|
char *pathname;
|
||||||
const union acpi_predefined_info *predefined;
|
const union acpi_predefined_info *predefined;
|
||||||
union acpi_operand_object *parent_package;
|
union acpi_operand_object *parent_package;
|
||||||
|
struct acpi_namespace_node *node;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
u8 node_flags;
|
u8 node_flags;
|
||||||
};
|
};
|
||||||
|
@ -468,6 +468,7 @@ static const union acpi_predefined_info predefined_names[] =
|
|||||||
{{"_SWS", 0, ACPI_RTYPE_INTEGER}},
|
{{"_SWS", 0, ACPI_RTYPE_INTEGER}},
|
||||||
{{"_TC1", 0, ACPI_RTYPE_INTEGER}},
|
{{"_TC1", 0, ACPI_RTYPE_INTEGER}},
|
||||||
{{"_TC2", 0, ACPI_RTYPE_INTEGER}},
|
{{"_TC2", 0, ACPI_RTYPE_INTEGER}},
|
||||||
|
{{"_TDL", 0, ACPI_RTYPE_INTEGER}},
|
||||||
{{"_TIP", 1, ACPI_RTYPE_INTEGER}},
|
{{"_TIP", 1, ACPI_RTYPE_INTEGER}},
|
||||||
{{"_TIV", 1, ACPI_RTYPE_INTEGER}},
|
{{"_TIV", 1, ACPI_RTYPE_INTEGER}},
|
||||||
{{"_TMP", 0, 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
|
* Return value validation and possible repair.
|
||||||
* not a problem. For example, if the "Implicit Return" feature is
|
|
||||||
* enabled, methods will always return a value.
|
|
||||||
*
|
*
|
||||||
* 2) If the return value can be of any type, then we cannot perform any
|
* 1) Don't perform return value validation/repair if this feature
|
||||||
* validation, exit.
|
* 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)) {
|
(predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -212,6 +218,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
data->predefined = predefined;
|
data->predefined = predefined;
|
||||||
|
data->node = node;
|
||||||
data->node_flags = node->flags;
|
data->node_flags = node->flags;
|
||||||
data->pathname = pathname;
|
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;
|
union acpi_operand_object *return_object = *return_object_ptr;
|
||||||
acpi_status status;
|
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,
|
status = acpi_ns_check_sorted_list(data, return_object, 5, 1,
|
||||||
ACPI_SORT_DESCENDING,
|
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.
|
* Validate the incoming table signature.
|
||||||
* Next, we added support for OEMx tables, signature "OEM".
|
*
|
||||||
* Valid tables were encountered with a null signature, so we've just
|
* 1) Originally, we checked the table signature for "SSDT" or "PSDT".
|
||||||
* given up on validating the signature, since it seems to be a waste
|
* 2) We added support for OEMx tables, signature "OEM".
|
||||||
* of code. The original code was removed (05/2008).
|
* 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);
|
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
|
||||||
|
|
||||||
|
@ -55,6 +55,9 @@
|
|||||||
#define ACPI_BATTERY_NOTIFY_INFO 0x81
|
#define ACPI_BATTERY_NOTIFY_INFO 0x81
|
||||||
#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82
|
#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
|
#define _COMPONENT ACPI_BATTERY_COMPONENT
|
||||||
|
|
||||||
ACPI_MODULE_NAME("battery");
|
ACPI_MODULE_NAME("battery");
|
||||||
@ -91,11 +94,6 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids);
|
|||||||
enum {
|
enum {
|
||||||
ACPI_BATTERY_ALARM_PRESENT,
|
ACPI_BATTERY_ALARM_PRESENT,
|
||||||
ACPI_BATTERY_XINFO_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,
|
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -301,7 +299,8 @@ static enum power_supply_property energy_battery_props[] = {
|
|||||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||||
inline char *acpi_battery_units(struct acpi_battery *battery)
|
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
|
#endif
|
||||||
|
|
||||||
@ -461,9 +460,17 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
|
|||||||
battery->update_time = jiffies;
|
battery->update_time = jiffies;
|
||||||
kfree(buffer.pointer);
|
kfree(buffer.pointer);
|
||||||
|
|
||||||
if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) &&
|
/* For buggy DSDTs that report negative 16-bit values for either
|
||||||
battery->rate_now != -1)
|
* 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);
|
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)
|
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
|
||||||
&& battery->capacity_now >= 0 && battery->capacity_now <= 100)
|
&& battery->capacity_now >= 0 && battery->capacity_now <= 100)
|
||||||
@ -544,7 +551,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (battery->power_unit) {
|
if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
|
||||||
battery->bat.properties = charge_battery_props;
|
battery->bat.properties = charge_battery_props;
|
||||||
battery->bat.num_properties =
|
battery->bat.num_properties =
|
||||||
ARRAY_SIZE(charge_battery_props);
|
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)
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
device_remove_file(battery->bat.dev, &alarm_attr);
|
device_remove_file(battery->bat.dev, &alarm_attr);
|
||||||
power_supply_unregister(&battery->bat);
|
power_supply_unregister(&battery->bat);
|
||||||
battery->bat.dev = NULL;
|
battery->bat.dev = NULL;
|
||||||
}
|
mutex_unlock(&battery->lock);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -592,7 +597,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
|
|||||||
*
|
*
|
||||||
* Handle this correctly so that they won't break userspace.
|
* 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))
|
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
||||||
return ;
|
return ;
|
||||||
@ -623,13 +628,15 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
|||||||
result = acpi_battery_get_info(battery);
|
result = acpi_battery_get_info(battery);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
acpi_battery_quirks(battery);
|
|
||||||
acpi_battery_init_alarm(battery);
|
acpi_battery_init_alarm(battery);
|
||||||
}
|
}
|
||||||
if (!battery->bat.dev)
|
if (!battery->bat.dev) {
|
||||||
sysfs_add_battery(battery);
|
result = sysfs_add_battery(battery);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
result = acpi_battery_get_state(battery);
|
result = acpi_battery_get_state(battery);
|
||||||
acpi_battery_quirks2(battery);
|
acpi_battery_quirks(battery);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -863,7 +870,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
|
|||||||
}, \
|
}, \
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct battery_file {
|
static const struct battery_file {
|
||||||
struct file_operations ops;
|
struct file_operations ops;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
const char *name;
|
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,
|
struct acpi_battery *battery = container_of(nb, struct acpi_battery,
|
||||||
pm_nb);
|
pm_nb);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
case PM_POST_HIBERNATION:
|
||||||
case PM_POST_SUSPEND:
|
case PM_POST_SUSPEND:
|
||||||
sysfs_remove_battery(battery);
|
if (battery->bat.dev) {
|
||||||
sysfs_add_battery(battery);
|
sysfs_remove_battery(battery);
|
||||||
|
sysfs_add_battery(battery);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -975,25 +985,33 @@ static int acpi_battery_add(struct acpi_device *device)
|
|||||||
if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
|
if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
|
||||||
"_BIX", &handle)))
|
"_BIX", &handle)))
|
||||||
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
|
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
|
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||||
result = acpi_battery_add_fs(device);
|
result = acpi_battery_add_fs(device);
|
||||||
#endif
|
#endif
|
||||||
if (!result) {
|
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 {
|
|
||||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||||
acpi_battery_remove_fs(device);
|
acpi_battery_remove_fs(device);
|
||||||
#endif
|
#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;
|
battery->pm_nb.notifier_call = battery_notify;
|
||||||
register_pm_notifier(&battery->pm_nb);
|
register_pm_notifier(&battery->pm_nb);
|
||||||
|
|
||||||
return result;
|
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)
|
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 list;
|
||||||
struct list_head hotplug_list;
|
struct list_head hotplug_list;
|
||||||
acpi_handle handle;
|
acpi_handle handle;
|
||||||
struct acpi_dock_ops *ops;
|
const struct acpi_dock_ops *ops;
|
||||||
void *context;
|
void *context;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -589,7 +589,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
|
|||||||
* the dock driver after _DCK is executed.
|
* the dock driver after _DCK is executed.
|
||||||
*/
|
*/
|
||||||
int
|
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)
|
void *context)
|
||||||
{
|
{
|
||||||
struct dock_dependent_device *dd;
|
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;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct file_operations acpi_ec_io_ops = {
|
static const struct file_operations acpi_ec_io_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = acpi_ec_open_io,
|
.open = acpi_ec_open_io,
|
||||||
.read = acpi_ec_read_io,
|
.read = acpi_ec_read_io,
|
||||||
|
@ -110,7 +110,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
|
|||||||
return result;
|
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_max_state = fan_get_max_state,
|
||||||
.get_cur_state = fan_get_cur_state,
|
.get_cur_state = fan_get_cur_state,
|
||||||
.set_cur_state = fan_set_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)) {
|
if (!strcmp("Linux", interface)) {
|
||||||
|
|
||||||
printk(KERN_NOTICE FW_BUG PREFIX
|
printk_once(KERN_NOTICE FW_BUG PREFIX
|
||||||
"BIOS _OSI(Linux) query %s%s\n",
|
"BIOS _OSI(Linux) query %s%s\n",
|
||||||
osi_linux.enable ? "honored" : "ignored",
|
osi_linux.enable ? "honored" : "ignored",
|
||||||
osi_linux.cmdline ? " via cmdline" :
|
osi_linux.cmdline ? " via cmdline" :
|
||||||
@ -237,8 +237,23 @@ void acpi_os_vprintf(const char *fmt, va_list args)
|
|||||||
#endif
|
#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)
|
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_enabled) {
|
||||||
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
|
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
|
||||||
return efi.acpi20;
|
return efi.acpi20;
|
||||||
@ -1083,7 +1098,13 @@ struct osi_setup_entry {
|
|||||||
bool enable;
|
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)
|
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
|
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)
|
static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
|
||||||
{
|
{
|
||||||
struct acpi_prt_entry *entry;
|
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);
|
entry = acpi_pci_irq_find_prt_entry(dev, pin);
|
||||||
if (entry) {
|
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",
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
|
||||||
pci_name(dev), pin_name(pin)));
|
pci_name(dev), pin_name(pin)));
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -485,7 +485,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
|||||||
root->secondary.end = 0xFF;
|
root->secondary.end = 0xFF;
|
||||||
printk(KERN_WARNING FW_BUG PREFIX
|
printk(KERN_WARNING FW_BUG PREFIX
|
||||||
"no secondary bus range in _CRS\n");
|
"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))
|
if (ACPI_SUCCESS(status))
|
||||||
root->secondary.start = bus;
|
root->secondary.start = bus;
|
||||||
else if (status == AE_NOT_FOUND)
|
else if (status == AE_NOT_FOUND)
|
||||||
|
@ -244,7 +244,7 @@ processor_set_cur_state(struct thermal_cooling_device *cdev,
|
|||||||
return result;
|
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_max_state = processor_get_max_state,
|
||||||
.get_cur_state = processor_get_cur_state,
|
.get_cur_state = processor_get_cur_state,
|
||||||
.set_cur_state = processor_set_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)
|
#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)
|
static inline int battery_scale(int log)
|
||||||
{
|
{
|
||||||
int scale = 1;
|
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)
|
if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
acpi_battery_get_state(battery);
|
||||||
switch (psp) {
|
switch (psp) {
|
||||||
case POWER_SUPPLY_PROP_STATUS:
|
case POWER_SUPPLY_PROP_STATUS:
|
||||||
if (battery->rate_now < 0)
|
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:
|
case POWER_SUPPLY_PROP_POWER_NOW:
|
||||||
val->intval = abs(battery->rate_now) *
|
val->intval = abs(battery->rate_now) *
|
||||||
acpi_battery_ipscale(battery) * 1000;
|
acpi_battery_ipscale(battery) * 1000;
|
||||||
|
val->intval *= (acpi_battery_mode(battery)) ?
|
||||||
|
(battery->voltage_now *
|
||||||
|
acpi_battery_vscale(battery) / 1000) : 1;
|
||||||
break;
|
break;
|
||||||
case POWER_SUPPLY_PROP_CURRENT_AVG:
|
case POWER_SUPPLY_PROP_CURRENT_AVG:
|
||||||
case POWER_SUPPLY_PROP_POWER_AVG:
|
case POWER_SUPPLY_PROP_POWER_AVG:
|
||||||
val->intval = abs(battery->rate_avg) *
|
val->intval = abs(battery->rate_avg) *
|
||||||
acpi_battery_ipscale(battery) * 1000;
|
acpi_battery_ipscale(battery) * 1000;
|
||||||
|
val->intval *= (acpi_battery_mode(battery)) ?
|
||||||
|
(battery->voltage_now *
|
||||||
|
acpi_battery_vscale(battery) / 1000) : 1;
|
||||||
break;
|
break;
|
||||||
case POWER_SUPPLY_PROP_CAPACITY:
|
case POWER_SUPPLY_PROP_CAPACITY:
|
||||||
val->intval = battery->state_of_charge;
|
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)
|
static int acpi_sbs_add(struct acpi_device *device)
|
||||||
{
|
{
|
||||||
struct acpi_sbs *sbs;
|
struct acpi_sbs *sbs;
|
||||||
|
@ -428,6 +428,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
|
|||||||
DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
|
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 */
|
#endif /* CONFIG_SUSPEND */
|
||||||
|
@ -149,12 +149,12 @@ static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
|
|||||||
return result;
|
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,
|
.set = param_set_uint,
|
||||||
.get = param_get_debug_layer,
|
.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,
|
.set = param_set_uint,
|
||||||
.get = param_get_debug_level,
|
.get = param_get_debug_level,
|
||||||
};
|
};
|
||||||
|
@ -812,7 +812,7 @@ acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
|
|||||||
thermal_zone_unbind_cooling_device);
|
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,
|
.bind = acpi_thermal_bind_cooling_device,
|
||||||
.unbind = acpi_thermal_unbind_cooling_device,
|
.unbind = acpi_thermal_unbind_cooling_device,
|
||||||
.get_temp = thermal_get_temp,
|
.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);
|
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_max_state = video_get_max_state,
|
||||||
.get_cur_state = video_get_cur_state,
|
.get_cur_state = video_get_cur_state,
|
||||||
.set_cur_state = video_set_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);
|
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,
|
.handler = ata_acpi_dev_notify_dock,
|
||||||
.uevent = ata_acpi_dev_uevent,
|
.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,
|
.handler = ata_acpi_ap_notify_dock,
|
||||||
.uevent = ata_acpi_ap_uevent,
|
.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,
|
.handler = handle_hotplug_event_func,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,11 +14,7 @@ menuconfig THERMAL
|
|||||||
If you want this support, you should say Y or M here.
|
If you want this support, you should say Y or M here.
|
||||||
|
|
||||||
config THERMAL_HWMON
|
config THERMAL_HWMON
|
||||||
bool "Hardware monitoring support"
|
bool
|
||||||
depends on THERMAL
|
depends on THERMAL
|
||||||
depends on HWMON=y || HWMON=THERMAL
|
depends on HWMON=y || HWMON=THERMAL
|
||||||
help
|
default y
|
||||||
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.
|
|
||||||
|
@ -420,6 +420,29 @@ thermal_cooling_device_trip_point_show(struct device *dev,
|
|||||||
|
|
||||||
/* hwmon sys I/F */
|
/* hwmon sys I/F */
|
||||||
#include <linux/hwmon.h>
|
#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 LIST_HEAD(thermal_hwmon_list);
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
@ -437,9 +460,10 @@ temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
|
|||||||
int ret;
|
int ret;
|
||||||
struct thermal_hwmon_attr *hwmon_attr
|
struct thermal_hwmon_attr *hwmon_attr
|
||||||
= container_of(attr, struct thermal_hwmon_attr, attr);
|
= container_of(attr, struct thermal_hwmon_attr, attr);
|
||||||
struct thermal_zone_device *tz
|
struct thermal_hwmon_temp *temp
|
||||||
= container_of(hwmon_attr, struct thermal_zone_device,
|
= container_of(hwmon_attr, struct thermal_hwmon_temp,
|
||||||
temp_input);
|
temp_input);
|
||||||
|
struct thermal_zone_device *tz = temp->tz;
|
||||||
|
|
||||||
ret = tz->ops->get_temp(tz, &temperature);
|
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
|
struct thermal_hwmon_attr *hwmon_attr
|
||||||
= container_of(attr, struct thermal_hwmon_attr, attr);
|
= container_of(attr, struct thermal_hwmon_attr, attr);
|
||||||
struct thermal_zone_device *tz
|
struct thermal_hwmon_temp *temp
|
||||||
= container_of(hwmon_attr, struct thermal_zone_device,
|
= container_of(hwmon_attr, struct thermal_hwmon_temp,
|
||||||
temp_crit);
|
temp_crit);
|
||||||
|
struct thermal_zone_device *tz = temp->tz;
|
||||||
long temperature;
|
long temperature;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -469,22 +494,54 @@ temp_crit_show(struct device *dev, struct device_attribute *attr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static struct thermal_hwmon_device *
|
||||||
thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
|
||||||
{
|
{
|
||||||
struct thermal_hwmon_device *hwmon;
|
struct thermal_hwmon_device *hwmon;
|
||||||
int new_hwmon_device = 1;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
mutex_lock(&thermal_list_lock);
|
mutex_lock(&thermal_list_lock);
|
||||||
list_for_each_entry(hwmon, &thermal_hwmon_list, node)
|
list_for_each_entry(hwmon, &thermal_hwmon_list, node)
|
||||||
if (!strcmp(hwmon->type, tz->type)) {
|
if (!strcmp(hwmon->type, tz->type)) {
|
||||||
new_hwmon_device = 0;
|
|
||||||
mutex_unlock(&thermal_list_lock);
|
mutex_unlock(&thermal_list_lock);
|
||||||
goto register_sys_interface;
|
return hwmon;
|
||||||
}
|
}
|
||||||
mutex_unlock(&thermal_list_lock);
|
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);
|
hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL);
|
||||||
if (!hwmon)
|
if (!hwmon)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -502,30 +559,36 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
|||||||
goto free_mem;
|
goto free_mem;
|
||||||
|
|
||||||
register_sys_interface:
|
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++;
|
hwmon->count++;
|
||||||
|
|
||||||
snprintf(tz->temp_input.name, THERMAL_NAME_LENGTH,
|
snprintf(temp->temp_input.name, THERMAL_NAME_LENGTH,
|
||||||
"temp%d_input", hwmon->count);
|
"temp%d_input", hwmon->count);
|
||||||
tz->temp_input.attr.attr.name = tz->temp_input.name;
|
temp->temp_input.attr.attr.name = temp->temp_input.name;
|
||||||
tz->temp_input.attr.attr.mode = 0444;
|
temp->temp_input.attr.attr.mode = 0444;
|
||||||
tz->temp_input.attr.show = temp_input_show;
|
temp->temp_input.attr.show = temp_input_show;
|
||||||
sysfs_attr_init(&tz->temp_input.attr.attr);
|
sysfs_attr_init(&temp->temp_input.attr.attr);
|
||||||
result = device_create_file(hwmon->device, &tz->temp_input.attr);
|
result = device_create_file(hwmon->device, &temp->temp_input.attr);
|
||||||
if (result)
|
if (result)
|
||||||
goto unregister_name;
|
goto free_temp_mem;
|
||||||
|
|
||||||
if (tz->ops->get_crit_temp) {
|
if (tz->ops->get_crit_temp) {
|
||||||
unsigned long temperature;
|
unsigned long temperature;
|
||||||
if (!tz->ops->get_crit_temp(tz, &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);
|
"temp%d_crit", hwmon->count);
|
||||||
tz->temp_crit.attr.attr.name = tz->temp_crit.name;
|
temp->temp_crit.attr.attr.name = temp->temp_crit.name;
|
||||||
tz->temp_crit.attr.attr.mode = 0444;
|
temp->temp_crit.attr.attr.mode = 0444;
|
||||||
tz->temp_crit.attr.show = temp_crit_show;
|
temp->temp_crit.attr.show = temp_crit_show;
|
||||||
sysfs_attr_init(&tz->temp_crit.attr.attr);
|
sysfs_attr_init(&temp->temp_crit.attr.attr);
|
||||||
result = device_create_file(hwmon->device,
|
result = device_create_file(hwmon->device,
|
||||||
&tz->temp_crit.attr);
|
&temp->temp_crit.attr);
|
||||||
if (result)
|
if (result)
|
||||||
goto unregister_input;
|
goto unregister_input;
|
||||||
}
|
}
|
||||||
@ -534,13 +597,15 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
|||||||
mutex_lock(&thermal_list_lock);
|
mutex_lock(&thermal_list_lock);
|
||||||
if (new_hwmon_device)
|
if (new_hwmon_device)
|
||||||
list_add_tail(&hwmon->node, &thermal_hwmon_list);
|
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);
|
mutex_unlock(&thermal_list_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unregister_input:
|
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:
|
unregister_name:
|
||||||
if (new_hwmon_device) {
|
if (new_hwmon_device) {
|
||||||
device_remove_file(hwmon->device, &dev_attr_name);
|
device_remove_file(hwmon->device, &dev_attr_name);
|
||||||
@ -556,15 +621,30 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
|||||||
static void
|
static void
|
||||||
thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
|
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;
|
hwmon = thermal_hwmon_lookup_by_type(tz);
|
||||||
device_remove_file(hwmon->device, &tz->temp_input.attr);
|
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)
|
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);
|
mutex_lock(&thermal_list_lock);
|
||||||
list_del(&tz->hwmon_node);
|
list_del(&temp->hwmon_node);
|
||||||
|
kfree(temp);
|
||||||
if (!list_empty(&hwmon->tz_list)) {
|
if (!list_empty(&hwmon->tz_list)) {
|
||||||
mutex_unlock(&thermal_list_lock);
|
mutex_unlock(&thermal_list_lock);
|
||||||
return;
|
return;
|
||||||
|
@ -128,7 +128,7 @@ extern int is_dock_device(acpi_handle handle);
|
|||||||
extern int register_dock_notifier(struct notifier_block *nb);
|
extern int register_dock_notifier(struct notifier_block *nb);
|
||||||
extern void unregister_dock_notifier(struct notifier_block *nb);
|
extern void unregister_dock_notifier(struct notifier_block *nb);
|
||||||
extern int register_hotplug_dock_device(acpi_handle handle,
|
extern int register_hotplug_dock_device(acpi_handle handle,
|
||||||
struct acpi_dock_ops *ops,
|
const struct acpi_dock_ops *ops,
|
||||||
void *context);
|
void *context);
|
||||||
extern void unregister_hotplug_dock_device(acpi_handle handle);
|
extern void unregister_hotplug_dock_device(acpi_handle handle);
|
||||||
#else
|
#else
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||||
|
|
||||||
#define ACPI_CA_VERSION 0x20110413
|
#define ACPI_CA_VERSION 0x20110623
|
||||||
|
|
||||||
#include "actypes.h"
|
#include "actypes.h"
|
||||||
#include "actbl.h"
|
#include "actbl.h"
|
||||||
@ -69,6 +69,7 @@ extern u32 acpi_gbl_trace_flags;
|
|||||||
extern u32 acpi_gbl_enable_aml_debug_object;
|
extern u32 acpi_gbl_enable_aml_debug_object;
|
||||||
extern u8 acpi_gbl_copy_dsdt_locally;
|
extern u8 acpi_gbl_copy_dsdt_locally;
|
||||||
extern u8 acpi_gbl_truncate_io_addresses;
|
extern u8 acpi_gbl_truncate_io_addresses;
|
||||||
|
extern u8 acpi_gbl_disable_auto_repair;
|
||||||
|
|
||||||
extern u32 acpi_current_gpe_count;
|
extern u32 acpi_current_gpe_count;
|
||||||
extern struct acpi_table_fadt acpi_gbl_FADT;
|
extern struct acpi_table_fadt acpi_gbl_FADT;
|
||||||
|
@ -337,7 +337,7 @@ extern struct cpuidle_driver acpi_idle_driver;
|
|||||||
|
|
||||||
/* in processor_thermal.c */
|
/* in processor_thermal.c */
|
||||||
int acpi_processor_get_limit_info(struct acpi_processor *pr);
|
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
|
#ifdef CONFIG_CPU_FREQ
|
||||||
void acpi_thermal_cpufreq_init(void);
|
void acpi_thermal_cpufreq_init(void);
|
||||||
void acpi_thermal_cpufreq_exit(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;
|
extern int pnpacpi_disabled;
|
||||||
|
|
||||||
#define PXM_INVAL (-1)
|
#define PXM_INVAL (-1)
|
||||||
#define NID_INVAL (-1)
|
|
||||||
|
|
||||||
int acpi_check_resource_conflict(const struct resource *res);
|
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)
|
((long)t-2732+5)/10 : ((long)t-2732-5)/10)
|
||||||
#define CELSIUS_TO_KELVIN(t) ((t)*10+2732)
|
#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 {
|
struct thermal_zone_device {
|
||||||
int id;
|
int id;
|
||||||
char type[THERMAL_NAME_LENGTH];
|
char type[THERMAL_NAME_LENGTH];
|
||||||
@ -120,12 +104,6 @@ struct thermal_zone_device {
|
|||||||
struct mutex lock; /* protect cooling devices list */
|
struct mutex lock; /* protect cooling devices list */
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
struct delayed_work poll_queue;
|
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 */
|
/* Adding event notification support elements */
|
||||||
#define THERMAL_GENL_FAMILY_NAME "thermal_event"
|
#define THERMAL_GENL_FAMILY_NAME "thermal_event"
|
||||||
|
Loading…
Reference in New Issue
Block a user