Commit da50ccc6 authored by Linus Torvalds's avatar Linus Torvalds

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: (23 commits)
  ACPICA: fix stray va_end() caused by mis-merge
  ACPI: Reject below-freezing temperatures as invalid critical temperatures
  ACPICA: Fix for access to deleted object <regression>
  ACPICA: Fix to make _SST method optional
  ACPICA: Fix for Load operator, load table at the namespace root
  ACPICA: Ignore ACPI table signature for Load() operator
  ACPICA: Fix to allow zero-length ASL field declarations
  ACPI: use memory_read_from_buffer()
  bay: exit if notify handler cannot be installed
  dock.c remove trailing printk whitespace
  proper prototype for acpi_processor_tstate_has_changed()
  ACPI: handle invalid ACPI SLIT table
  PNPACPI: use _CRS IRQ descriptor length for _SRS
  pnpacpi: fix shareable IRQ encode/decode
  pnpacpi: fix IRQ flag decoding
  MAINTAINERS: update ACPI homepage
  ACPI 2.6.26-rc2: Add missing newline to DSDT/SSDT warning message
  ACPI: EC: Use msleep instead of udelay while waiting for event.
  thinkpad-acpi: fix LED handling on older ThinkPads
  thinkpad-acpi: fix initialization error paths
  ...
parents a4df1ac1 3549dba2
...@@ -503,7 +503,7 @@ generate input device EV_KEY events. ...@@ -503,7 +503,7 @@ generate input device EV_KEY events.
In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW
events for switches: events for switches:
SW_RADIO T60 and later hardare rfkill rocker switch SW_RFKILL_ALL T60 and later hardare rfkill rocker switch
SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A
Non hot-key ACPI HKEY event map: Non hot-key ACPI HKEY event map:
......
...@@ -228,21 +228,21 @@ ACPI BATTERY DRIVERS ...@@ -228,21 +228,21 @@ ACPI BATTERY DRIVERS
P: Alexey Starikovskiy P: Alexey Starikovskiy
M: astarikovskiy@suse.de M: astarikovskiy@suse.de
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://acpi.sourceforge.net/ W: http://www.lesswatts.org/projects/acpi/
S: Supported S: Supported
ACPI EC DRIVER ACPI EC DRIVER
P: Alexey Starikovskiy P: Alexey Starikovskiy
M: astarikovskiy@suse.de M: astarikovskiy@suse.de
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://acpi.sourceforge.net/ W: http://www.lesswatts.org/projects/acpi/
S: Supported S: Supported
ACPI FAN DRIVER ACPI FAN DRIVER
P: Len Brown P: Len Brown
M: len.brown@intel.com M: len.brown@intel.com
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://acpi.sourceforge.net/ W: http://www.lesswatts.org/projects/acpi/
S: Supported S: Supported
ACPI PCI HOTPLUG DRIVER ACPI PCI HOTPLUG DRIVER
...@@ -255,14 +255,14 @@ ACPI THERMAL DRIVER ...@@ -255,14 +255,14 @@ ACPI THERMAL DRIVER
P: Len Brown P: Len Brown
M: len.brown@intel.com M: len.brown@intel.com
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://acpi.sourceforge.net/ W: http://www.lesswatts.org/projects/acpi/
S: Supported S: Supported
ACPI VIDEO DRIVER ACPI VIDEO DRIVER
P: Rui Zhang P: Rui Zhang
M: rui.zhang@intel.com M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://acpi.sourceforge.net/ W: http://www.lesswatts.org/projects/acpi/
S: Supported S: Supported
ACPI WMI DRIVER ACPI WMI DRIVER
......
...@@ -465,7 +465,6 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) ...@@ -465,7 +465,6 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
printk(KERN_ERR printk(KERN_ERR
"ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
len, slit->header.length); len, slit->header.length);
memset(numa_slit, 10, sizeof(numa_slit));
return; return;
} }
slit_table = slit; slit_table = slit;
...@@ -574,8 +573,14 @@ void __init acpi_numa_arch_fixup(void) ...@@ -574,8 +573,14 @@ void __init acpi_numa_arch_fixup(void)
printk(KERN_INFO "Number of memory chunks in system = %d\n", printk(KERN_INFO "Number of memory chunks in system = %d\n",
num_node_memblks); num_node_memblks);
if (!slit_table) if (!slit_table) {
for (i = 0; i < MAX_NUMNODES; i++)
for (j = 0; j < MAX_NUMNODES; j++)
node_distance(i, j) = i == j ? LOCAL_DISTANCE :
REMOTE_DISTANCE;
return; return;
}
memset(numa_slit, -1, sizeof(numa_slit)); memset(numa_slit, -1, sizeof(numa_slit));
for (i = 0; i < slit_table->locality_count; i++) { for (i = 0; i < slit_table->locality_count; i++) {
if (!pxm_bit_test(i)) if (!pxm_bit_test(i))
......
...@@ -97,36 +97,9 @@ static __init inline int srat_disabled(void) ...@@ -97,36 +97,9 @@ static __init inline int srat_disabled(void)
return numa_off || acpi_numa < 0; return numa_off || acpi_numa < 0;
} }
/*
* A lot of BIOS fill in 10 (= no distance) everywhere. This messes
* up the NUMA heuristics which wants the local node to have a smaller
* distance than the others.
* Do some quick checks here and only use the SLIT if it passes.
*/
static __init int slit_valid(struct acpi_table_slit *slit)
{
int i, j;
int d = slit->locality_count;
for (i = 0; i < d; i++) {
for (j = 0; j < d; j++) {
u8 val = slit->entry[d*i + j];
if (i == j) {
if (val != LOCAL_DISTANCE)
return 0;
} else if (val <= LOCAL_DISTANCE)
return 0;
}
}
return 1;
}
/* Callback for SLIT parsing */ /* Callback for SLIT parsing */
void __init acpi_numa_slit_init(struct acpi_table_slit *slit) void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
{ {
if (!slit_valid(slit)) {
printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n");
return;
}
acpi_slit = slit; acpi_slit = slit;
} }
......
...@@ -301,16 +301,20 @@ static int bay_add(acpi_handle handle, int id) ...@@ -301,16 +301,20 @@ static int bay_add(acpi_handle handle, int id)
*/ */
pdev->dev.uevent_suppress = 0; pdev->dev.uevent_suppress = 0;
if (acpi_bay_add_fs(new_bay)) {
platform_device_unregister(new_bay->pdev);
goto bay_add_err;
}
/* register for events on this device */ /* register for events on this device */
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
bay_notify, new_bay); bay_notify, new_bay);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Error installing bay notify handler\n"); printk(KERN_INFO PREFIX "Error installing bay notify handler\n");
platform_device_unregister(new_bay->pdev);
goto bay_add_err;
}
if (acpi_bay_add_fs(new_bay)) {
acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
bay_notify);
platform_device_unregister(new_bay->pdev);
goto bay_add_err;
} }
/* if we are on a dock station, we should register for dock /* if we are on a dock station, we should register for dock
......
...@@ -450,10 +450,6 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, ...@@ -450,10 +450,6 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
return_ACPI_STATUS(AE_BAD_PARAMETER); return_ACPI_STATUS(AE_BAD_PARAMETER);
} }
if (!arg) {
return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
/* Creating new namespace node(s), should not already exist */ /* Creating new namespace node(s), should not already exist */
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
...@@ -467,6 +463,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, ...@@ -467,6 +463,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
/* /*
* Walk the list of entries in the field_list * Walk the list of entries in the field_list
* Note: field_list can be of zero length. In this case, Arg will be NULL.
*/ */
while (arg) { while (arg) {
/* /*
......
...@@ -834,7 +834,7 @@ static int dock_add(acpi_handle handle) ...@@ -834,7 +834,7 @@ static int dock_add(acpi_handle handle)
goto dock_add_err; goto dock_add_err;
} }
printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_DESCRIPTION); printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION);
return 0; return 0;
......
...@@ -194,7 +194,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) ...@@ -194,7 +194,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
while (time_before(jiffies, delay)) { while (time_before(jiffies, delay)) {
if (acpi_ec_check_status(ec, event)) if (acpi_ec_check_status(ec, event))
return 0; return 0;
udelay(ACPI_EC_UDELAY); msleep(1);
} }
} }
pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
......
...@@ -375,9 +375,15 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -375,9 +375,15 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
goto cleanup; goto cleanup;
} }
/*
* Add the table to the namespace.
*
* Note: We load the table objects relative to the root of the namespace.
* This appears to go against the ACPI specification, but we do it for
* compatibility with other ACPI implementations.
*/
status = status =
acpi_ex_add_table(table_index, walk_state->scope_info->scope.node, acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
&ddb_handle);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* On error, table_ptr was deallocated above */ /* On error, table_ptr was deallocated above */
......
...@@ -272,6 +272,12 @@ static u32 rtc_handler(void *context) ...@@ -272,6 +272,12 @@ static u32 rtc_handler(void *context)
static inline void rtc_wake_setup(void) static inline void rtc_wake_setup(void)
{ {
acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
/*
* After the RTC handler is installed, the Fixed_RTC event should
* be disabled. Only when the RTC alarm is set will it be enabled.
*/
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
} }
static void rtc_wake_on(struct device *dev) static void rtc_wake_on(struct device *dev)
......
...@@ -223,15 +223,17 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) ...@@ -223,15 +223,17 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
break; break;
} }
/* Set the system indicators to show the desired sleep state. */ /*
* Set the system indicators to show the desired sleep state.
* _SST is an optional method (return no error if not found)
*/
status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"While executing method _SST")); "While executing method _SST"));
} }
return_ACPI_STATUS(status); return_ACPI_STATUS(AE_OK);
} }
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
......
...@@ -140,19 +140,42 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) ...@@ -140,19 +140,42 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
} }
} }
/*
* A lot of BIOS fill in 10 (= no distance) everywhere. This messes
* up the NUMA heuristics which wants the local node to have a smaller
* distance than the others.
* Do some quick checks here and only use the SLIT if it passes.
*/
static __init int slit_valid(struct acpi_table_slit *slit)
{
int i, j;
int d = slit->locality_count;
for (i = 0; i < d; i++) {
for (j = 0; j < d; j++) {
u8 val = slit->entry[d*i + j];
if (i == j) {
if (val != LOCAL_DISTANCE)
return 0;
} else if (val <= LOCAL_DISTANCE)
return 0;
}
}
return 1;
}
static int __init acpi_parse_slit(struct acpi_table_header *table) static int __init acpi_parse_slit(struct acpi_table_header *table)
{ {
struct acpi_table_slit *slit; struct acpi_table_slit *slit;
u32 localities;
if (!table) if (!table)
return -EINVAL; return -EINVAL;
slit = (struct acpi_table_slit *)table; slit = (struct acpi_table_slit *)table;
/* downcast just for %llu vs %lu for i386/ia64 */ if (!slit_valid(slit)) {
localities = (u32) slit->locality_count; printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n");
return -EINVAL;
}
acpi_numa_slit_init(slit); acpi_numa_slit_init(slit);
return 0; return 0;
......
...@@ -268,7 +268,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, ...@@ -268,7 +268,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
*/ */
if (ACPI_SUCCESS(status) && if (ACPI_SUCCESS(status) &&
possible_method_call && (node->type == ACPI_TYPE_METHOD)) { possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { if (walk_state->opcode == AML_UNLOAD_OP) {
/* /*
* acpi_ps_get_next_namestring has increased the AML pointer, * acpi_ps_get_next_namestring has increased the AML pointer,
* so we need to restore the saved AML pointer for method call. * so we need to restore the saved AML pointer for method call.
...@@ -691,7 +691,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, ...@@ -691,7 +691,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
/* To support super_name arg of Unload */ /* To support super_name arg of Unload */
if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { if (walk_state->opcode == AML_UNLOAD_OP) {
status = status =
acpi_ps_get_next_namepath(walk_state, acpi_ps_get_next_namepath(walk_state,
parser_state, arg, parser_state, arg,
......
...@@ -86,7 +86,6 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); ...@@ -86,7 +86,6 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
static int acpi_processor_handle_eject(struct acpi_processor *pr); static int acpi_processor_handle_eject(struct acpi_processor *pr);
extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
static const struct acpi_device_id processor_device_ids[] = { static const struct acpi_device_id processor_device_ids[] = {
......
...@@ -1669,6 +1669,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) ...@@ -1669,6 +1669,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
return -EINVAL; return -EINVAL;
} }
dev->cpu = pr->id;
for (i = 0; i < CPUIDLE_STATE_MAX; i++) { for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
dev->states[i].name[0] = '\0'; dev->states[i].name[0] = '\0';
dev->states[i].desc[0] = '\0'; dev->states[i].desc[0] = '\0';
...@@ -1738,7 +1739,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) ...@@ -1738,7 +1739,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
int acpi_processor_cst_has_changed(struct acpi_processor *pr) int acpi_processor_cst_has_changed(struct acpi_processor *pr)
{ {
int ret; int ret = 0;
if (boot_option_idle_override) if (boot_option_idle_override)
return 0; return 0;
...@@ -1756,8 +1757,10 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) ...@@ -1756,8 +1757,10 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
cpuidle_pause_and_lock(); cpuidle_pause_and_lock();
cpuidle_disable_device(&pr->power.dev); cpuidle_disable_device(&pr->power.dev);
acpi_processor_get_power_info(pr); acpi_processor_get_power_info(pr);
if (pr->flags.power) {
acpi_processor_setup_cpuidle(pr); acpi_processor_setup_cpuidle(pr);
ret = cpuidle_enable_device(&pr->power.dev); ret = cpuidle_enable_device(&pr->power.dev);
}
cpuidle_resume_and_unlock(); cpuidle_resume_and_unlock();
return ret; return ret;
...@@ -1813,7 +1816,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, ...@@ -1813,7 +1816,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
if (pr->flags.power) { if (pr->flags.power) {
#ifdef CONFIG_CPU_IDLE #ifdef CONFIG_CPU_IDLE
acpi_processor_setup_cpuidle(pr); acpi_processor_setup_cpuidle(pr);
pr->power.dev.cpu = pr->id;
if (cpuidle_register_device(&pr->power.dev)) if (cpuidle_register_device(&pr->power.dev))
return -EIO; return -EIO;
#endif #endif
...@@ -1850,7 +1852,6 @@ int acpi_processor_power_exit(struct acpi_processor *pr, ...@@ -1850,7 +1852,6 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
return 0; return 0;
#ifdef CONFIG_CPU_IDLE #ifdef CONFIG_CPU_IDLE
if (pr->flags.power)
cpuidle_unregister_device(&pr->power.dev); cpuidle_unregister_device(&pr->power.dev);
#endif #endif
pr->flags.power_setup_done = 0; pr->flags.power_setup_done = 0;
......
...@@ -495,6 +495,12 @@ static int __init acpi_sleep_proc_init(void) ...@@ -495,6 +495,12 @@ static int __init acpi_sleep_proc_init(void)
acpi_root_dir, &acpi_system_alarm_fops); acpi_root_dir, &acpi_system_alarm_fops);
acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
/*
* Disable the RTC event after installing RTC handler.
* Only when RTC alarm is set will it be enabled.
*/
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
#endif /* HAVE_ACPI_LEGACY_ALARM */ #endif /* HAVE_ACPI_LEGACY_ALARM */
/* 'wakeup device' [R/W] */ /* 'wakeup device' [R/W] */
......
...@@ -77,7 +77,6 @@ static ssize_t acpi_table_show(struct kobject *kobj, ...@@ -77,7 +77,6 @@ static ssize_t acpi_table_show(struct kobject *kobj,
container_of(bin_attr, struct acpi_table_attr, attr); container_of(bin_attr, struct acpi_table_attr, attr);
struct acpi_table_header *table_header = NULL; struct acpi_table_header *table_header = NULL;
acpi_status status; acpi_status status;
ssize_t ret_count = count;
status = status =
acpi_get_table(table_attr->name, table_attr->instance, acpi_get_table(table_attr->name, table_attr->instance,
...@@ -85,18 +84,8 @@ static ssize_t acpi_table_show(struct kobject *kobj, ...@@ -85,18 +84,8 @@ static ssize_t acpi_table_show(struct kobject *kobj,
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
if (offset >= table_header->length) { return memory_read_from_buffer(buf, count, &offset,
ret_count = 0; table_header, table_header->length);
goto end;
}
if (offset + ret_count > table_header->length)
ret_count = table_header->length - offset;
memcpy(buf, ((char *)table_header) + offset, ret_count);
end:
return ret_count;
} }
static void acpi_table_attr_init(struct acpi_table_attr *table_attr, static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
......
...@@ -123,24 +123,13 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, ...@@ -123,24 +123,13 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
} }
} }
/* The table must be either an SSDT or a PSDT or an OEMx */ /*
* Originally, we checked the table signature for "SSDT" or "PSDT" here.
if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&& * Next, we added support for OEMx tables, signature "OEM".
!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&& * Valid tables were encountered with a null signature, so we've just
strncmp(table_desc->pointer->signature, "OEM", 3)) { * given up on validating the signature, since it seems to be a waste
/* Check for a printable name */ * of code. The original code was removed (05/2008).
if (acpi_ut_valid_acpi_name( */
*(u32 *) table_desc->pointer->signature)) {
ACPI_ERROR((AE_INFO, "Table has invalid signature "
"[%4.4s], must be SSDT or PSDT",
table_desc->pointer->signature));
} else {
ACPI_ERROR((AE_INFO, "Table has invalid signature "
"(0x%8.8X), must be SSDT or PSDT",
*(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);
......
...@@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespace(void) ...@@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespace(void)
acpi_tb_print_table_header(0, table); acpi_tb_print_table_header(0, table);
if (no_auto_ssdt == 0) { if (no_auto_ssdt == 0) {
printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\""); printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
} }
} }
......
...@@ -364,10 +364,17 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) ...@@ -364,10 +364,17 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
if (flag & ACPI_TRIPS_CRITICAL) { if (flag & ACPI_TRIPS_CRITICAL) {
status = acpi_evaluate_integer(tz->device->handle, status = acpi_evaluate_integer(tz->device->handle,
"_CRT", NULL, &tz->trips.critical.temperature); "_CRT", NULL, &tz->trips.critical.temperature);
if (ACPI_FAILURE(status)) { /*
* Treat freezing temperatures as invalid as well; some
* BIOSes return really low values and cause reboots at startup.
* Below zero (Celcius) values clearly aren't right for sure..
* ... so lets discard those as invalid.
*/
if (ACPI_FAILURE(status) ||
tz->trips.critical.temperature <= 2732) {
tz->trips.critical.flags.valid = 0; tz->trips.critical.flags.valid = 0;
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"No critical threshold")); "No or invalid critical threshold"));
return -ENODEV; return -ENODEV;
} else { } else {
tz->trips.critical.flags.valid = 1; tz->trips.critical.flags.valid = 1;
......
...@@ -1048,6 +1048,7 @@ acpi_ut_exception(char *module_name, ...@@ -1048,6 +1048,7 @@ acpi_ut_exception(char *module_name,
va_start(args, format); va_start(args, format);
acpi_os_vprintf(format, args); acpi_os_vprintf(format, args);
acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
va_end(args);
} }
EXPORT_SYMBOL(acpi_ut_exception); EXPORT_SYMBOL(acpi_ut_exception);
...@@ -1063,7 +1064,6 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) ...@@ -1063,7 +1064,6 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...)
acpi_os_vprintf(format, args); acpi_os_vprintf(format, args);
acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
va_end(args); va_end(args);
va_end(args);
} }
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
......
...@@ -38,6 +38,8 @@ static void cpuidle_kick_cpus(void) ...@@ -38,6 +38,8 @@ static void cpuidle_kick_cpus(void)
static void cpuidle_kick_cpus(void) {} static void cpuidle_kick_cpus(void) {}
#endif #endif
static int __cpuidle_register_device(struct cpuidle_device *dev);
/** /**
* cpuidle_idle_call - the main idle loop * cpuidle_idle_call - the main idle loop
* *
...@@ -138,6 +140,12 @@ int cpuidle_enable_device(struct cpuidle_device *dev) ...@@ -138,6 +140,12 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
if (!dev->state_count) if (!dev->state_count)
return -EINVAL; return -EINVAL;
if (dev->registered == 0) {
ret = __cpuidle_register_device(dev);
if (ret)
return ret;
}
if ((ret = cpuidle_add_state_sysfs(dev))) if ((ret = cpuidle_add_state_sysfs(dev)))
return ret; return ret;
...@@ -232,10 +240,13 @@ static void poll_idle_init(struct cpuidle_device *dev) {} ...@@ -232,10 +240,13 @@ static void poll_idle_init(struct cpuidle_device *dev) {}
#endif /* CONFIG_ARCH_HAS_CPU_RELAX */ #endif /* CONFIG_ARCH_HAS_CPU_RELAX */
/** /**
* cpuidle_register_device - registers a CPU's idle PM feature * __cpuidle_register_device - internal register function called before register
* and enable routines
* @dev: the cpu * @dev: the cpu
*
* cpuidle_lock mutex must be held before this is called
*/ */
int cpuidle_register_device(struct cpuidle_device *dev) static int __cpuidle_register_device(struct cpuidle_device *dev)
{ {
int ret; int ret;
struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
...@@ -247,18 +258,34 @@ int cpuidle_register_device(struct cpuidle_device *dev) ...@@ -247,18 +258,34 @@ int cpuidle_register_device(struct cpuidle_device *dev)
init_completion(&dev->kobj_unregister); init_completion(&dev->kobj_unregister);
mutex_lock(&cpuidle_lock);
poll_idle_init(dev); poll_idle_init(dev);
per_cpu(cpuidle_devices, dev->cpu) = dev; per_cpu(cpuidle_devices, dev->cpu) = dev;
list_add(&dev->device_list, &cpuidle_detected_devices); list_add(&dev->device_list, &cpuidle_detected_devices);
if ((ret = cpuidle_add_sysfs(sys_dev))) { if ((ret = cpuidle_add_sysfs(sys_dev))) {
mutex_unlock(&cpuidle_lock);
module_put(cpuidle_curr_driver->owner); module_put(cpuidle_curr_driver->owner);
return ret; return ret;
} }
dev->registered = 1;
return 0;
}
/**
* cpuidle_register_device - registers a CPU's idle PM feature
* @dev: the cpu
*/
int cpuidle_register_device(struct cpuidle_device *dev)
{
int ret;
mutex_lock(&cpuidle_lock);
if ((ret = __cpuidle_register_device(dev))) {
mutex_unlock(&cpuidle_lock);
return ret;
}
cpuidle_enable_device(dev); cpuidle_enable_device(dev);
cpuidle_install_idle_handler(); cpuidle_install_idle_handler();
...@@ -278,6 +305,9 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) ...@@ -278,6 +305,9 @@ void cpuidle_unregister_device(struct cpuidle_device *dev)
{ {
struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
if (dev->registered == 0)
return;
cpuidle_pause_and_lock(); cpuidle_pause_and_lock();
cpuidle_disable_device(dev); cpuidle_disable_device(dev);
......
...@@ -1293,7 +1293,7 @@ static void tpacpi_input_send_radiosw(void) ...@@ -1293,7 +1293,7 @@ static void tpacpi_input_send_radiosw(void)
mutex_lock(&tpacpi_inputdev_send_mutex); mutex_lock(&tpacpi_inputdev_send_mutex);
input_report_switch(tpacpi_inputdev, input_report_switch(tpacpi_inputdev,
SW_RADIO, !!wlsw); SW_RFKILL_ALL, !!wlsw);
input_sync(tpacpi_inputdev); input_sync(tpacpi_inputdev);
mutex_unlock(&tpacpi_inputdev_send_mutex); mutex_unlock(&tpacpi_inputdev_send_mutex);
...@@ -1921,6 +1921,29 @@ static struct attribute *hotkey_mask_attributes[] __initdata = { ...@@ -1921,6 +1921,29 @@ static struct attribute *hotkey_mask_attributes[] __initdata = {
&dev_attr_hotkey_wakeup_hotunplug_complete.attr, &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
}; };
static void hotkey_exit(void)
{
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
hotkey_poll_stop_sync();
#endif
if (hotkey_dev_attributes)
delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
kfree(hotkey_keycode_map);
if (tp_features.hotkey) {
dbg_printk(TPACPI_DBG_EXIT,
"restoring original hot key mask\n");
/* no short-circuit boolean operator below! */
if ((hotkey_mask_set(hotkey_orig_mask) |
hotkey_status_set(hotkey_orig_status)) != 0)
printk(TPACPI_ERR
"failed to restore hot key mask "
"to BIOS defaults\n");
}
}
static int __init hotkey_init(struct ibm_init_struct *iibm) static int __init hotkey_init(struct ibm_init_struct *iibm)
{ {
/* Requirements for changing the default keymaps: /* Requirements for changing the default keymaps:
...@@ -2060,7 +2083,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2060,7 +2083,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
str_supported(tp_features.hotkey)); str_supported(tp_features.hotkey));
if (tp_features.hotkey) { if (!tp_features.hotkey)
return 1;
hotkey_dev_attributes = create_attr_set(13, NULL); hotkey_dev_attributes = create_attr_set(13, NULL);
if (!hotkey_dev_attributes) if (!hotkey_dev_attributes)
return -ENOMEM; return -ENOMEM;
...@@ -2068,7 +2093,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2068,7 +2093,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
hotkey_attributes, hotkey_attributes,
ARRAY_SIZE(hotkey_attributes)); ARRAY_SIZE(hotkey_attributes));
if (res) if (res)
return res; goto err_exit;
/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking
...@@ -2106,15 +2131,21 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2106,15 +2131,21 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* hotkey_source_mask *must* be zero for /* hotkey_source_mask *must* be zero for
* the first hotkey_mask_get */ * the first hotkey_mask_get */
res = hotkey_status_get(&hotkey_orig_status); res = hotkey_status_get(&hotkey_orig_status);
if (!res && tp_features.hotkey_mask) { if (res)
goto err_exit;
if (tp_features.hotkey_mask) {
res = hotkey_mask_get(); res = hotkey_mask_get();
if (res)
goto err_exit;
hotkey_orig_mask = hotkey_mask; hotkey_orig_mask = hotkey_mask;
if (!res) {
res = add_many_to_attr_set( res = add_many_to_attr_set(
hotkey_dev_attributes, hotkey_dev_attributes,
hotkey_mask_attributes, hotkey_mask_attributes,
ARRAY_SIZE(hotkey_mask_attributes)); ARRAY_SIZE(hotkey_mask_attributes));
} if (res)
goto err_exit;
} }
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
...@@ -2131,7 +2162,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2131,7 +2162,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
#endif #endif
/* Not all thinkpads have a hardware radio switch */ /* Not all thinkpads have a hardware radio switch */
if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
tp_features.hotkey_wlsw = 1; tp_features.hotkey_wlsw = 1;
printk(TPACPI_INFO printk(TPACPI_INFO
"radio switch found; radios are %s\n", "radio switch found; radios are %s\n",
...@@ -2157,7 +2188,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2157,7 +2188,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
hotkey_dev_attributes, hotkey_dev_attributes,
&tpacpi_pdev->dev.kobj); &tpacpi_pdev->dev.kobj);
if (res) if (res)
return res; goto err_exit;
/* Set up key map */ /* Set up key map */
...@@ -2166,7 +2197,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2166,7 +2197,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
if (!hotkey_keycode_map) { if (!hotkey_keycode_map) {
printk(TPACPI_ERR printk(TPACPI_ERR
"failed to allocate memory for key map\n"); "failed to allocate memory for key map\n");
return -ENOMEM; res = -ENOMEM;
goto err_exit;
} }
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
...@@ -2199,7 +2231,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2199,7 +2231,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
if (tp_features.hotkey_wlsw) { if (tp_features.hotkey_wlsw) {
set_bit(EV_SW, tpacpi_inputdev->evbit); set_bit(EV_SW, tpacpi_inputdev->evbit);
set_bit(SW_RADIO, tpacpi_inputdev->swbit); set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit);
} }
if (tp_features.hotkey_tablet) { if (tp_features.hotkey_tablet) {
set_bit(EV_SW, tpacpi_inputdev->evbit); set_bit(EV_SW, tpacpi_inputdev->evbit);
...@@ -2232,16 +2264,19 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2232,16 +2264,19 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
| (1 << TP_ACPI_HOTKEYSCAN_FNEND); | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
} }
dbg_printk(TPACPI_DBG_INIT, dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
"enabling hot key handling\n");
res = hotkey_status_set(1); res = hotkey_status_set(1);
if (res) if (res) {
hotkey_exit();
return res; return res;
}
res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask)
& ~hotkey_reserved_mask) & ~hotkey_reserved_mask)
| hotkey_orig_mask); | hotkey_orig_mask);
if (res < 0 && res != -ENXIO) if (res < 0 && res != -ENXIO) {
hotkey_exit();
return res; return res;
}
dbg_printk(TPACPI_DBG_INIT, dbg_printk(TPACPI_DBG_INIT,
"legacy hot key reporting over procfs %s\n", "legacy hot key reporting over procfs %s\n",
...@@ -2254,32 +2289,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -2254,32 +2289,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
hotkey_poll_setup_safe(1); hotkey_poll_setup_safe(1);
tpacpi_input_send_radiosw(); tpacpi_input_send_radiosw();
tpacpi_input_send_tabletsw(); tpacpi_input_send_tabletsw();
}
return (tp_features.hotkey)? 0 : 1; return 0;
}
static void hotkey_exit(void)
{
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
hotkey_poll_stop_sync();
#endif
if (tp_features.hotkey) {
dbg_printk(TPACPI_DBG_EXIT,
"restoring original hot key mask\n");
/* no short-circuit boolean operator below! */
if ((hotkey_mask_set(hotkey_orig_mask) |
hotkey_status_set(hotkey_orig_status)) != 0)
printk(TPACPI_ERR
"failed to restore hot key mask "
"to BIOS defaults\n");
}
if (hotkey_dev_attributes) { err_exit:
delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
hotkey_dev_attributes = NULL; hotkey_dev_attributes = NULL;
}
return (res < 0)? res : 1;
} }
static void hotkey_notify(struct ibm_struct *ibm, u32 event) static void hotkey_notify(struct ibm_struct *ibm, u32 event)
...@@ -3319,7 +3336,7 @@ static struct tpacpi_led_classdev tpacpi_led_thinklight = { ...@@ -3319,7 +3336,7 @@ static struct tpacpi_led_classdev tpacpi_led_thinklight = {
static int __init light_init(struct ibm_init_struct *iibm) static int __init light_init(struct ibm_init_struct *iibm)
{ {
int rc = 0; int rc;
vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
...@@ -3337,20 +3354,23 @@ static int __init light_init(struct ibm_init_struct *iibm) ...@@ -3337,20 +3354,23 @@ static int __init light_init(struct ibm_init_struct *iibm)
tp_features.light_status = tp_features.light_status =
acpi_evalf(ec_handle, NULL, "KBLT", "qv"); acpi_evalf(ec_handle, NULL, "KBLT", "qv");
vdbg_printk(TPACPI_DBG_INIT, "light is %s\n", vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n",
str_supported(tp_features.light)); str_supported(tp_features.light),
str_supported(tp_features.light_status));
if (!tp_features.light)
return 1;
if (tp_features.light) {
rc = led_classdev_register(&tpacpi_pdev->dev, rc = led_classdev_register(&tpacpi_pdev->dev,
&tpacpi_led_thinklight.led_classdev); &tpacpi_led_thinklight.led_classdev);
}
if (rc < 0) { if (rc < 0) {
tp_features.light = 0; tp_features.light = 0;
tp_features.light_status = 0; tp_features.light_status = 0;
} else { } else {
rc = (tp_features.light)? 0 : 1; rc = 0;
} }
return rc; return rc;
} }
...@@ -3833,7 +3853,7 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { ...@@ -3833,7 +3853,7 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
"tpacpi::standby", "tpacpi::standby",
}; };
static int led_get_status(unsigned int led) static int led_get_status(const unsigned int led)
{ {
int status; int status;
enum led_status_t led_s; enum led_status_t led_s;
...@@ -3857,34 +3877,35 @@ static int led_get_status(unsigned int led) ...@@ -3857,34 +3877,35 @@ static int led_get_status(unsigned int led)
/* not reached */ /* not reached */
} }
static int led_set_status(unsigned int led, enum led_status_t ledstatus) static int led_set_status(const unsigned int led,
const enum led_status_t ledstatus)
{ {
/* off, on, blink. Index is led_status_t */ /* off, on, blink. Index is led_status_t */
static const int led_sled_arg1[] = { 0, 1, 3 }; static const unsigned int led_sled_arg1[] = { 0, 1, 3 };
static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */ static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 };
static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */
static const int led_led_arg1[] = { 0, 0x80, 0xc0 };
int rc = 0; int rc = 0;
switch (led_supported) { switch (led_supported) {
case TPACPI_LED_570: case TPACPI_LED_570:
/* 570 */ /* 570 */
led = 1 << led; if (led > 7)
return -EINVAL;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd", if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
led, led_sled_arg1[ledstatus])) (1 << led), led_sled_arg1[ledstatus]))
rc = -EIO; rc = -EIO;
break; break;
case TPACPI_LED_OLD: case TPACPI_LED_OLD:
/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
led = 1 << led; if (led > 7)
rc = ec_write(TPACPI_LED_EC_HLMS, led); return -EINVAL;
rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
if (rc >= 0) if (rc >= 0)
rc = ec_write(TPACPI_LED_EC_HLBL, rc = ec_write(TPACPI_LED_EC_HLBL,
led * led_exp_hlbl[ledstatus]); (ledstatus == TPACPI_LED_BLINK) << led);
if (rc >= 0) if (rc >= 0)
rc = ec_write(TPACPI_LED_EC_HLCL, rc = ec_write(TPACPI_LED_EC_HLCL,
led * led_exp_hlcl[ledstatus]); (ledstatus != TPACPI_LED_OFF) << led);
break; break;
case TPACPI_LED_NEW: case TPACPI_LED_NEW:
/* all others */ /* all others */
...@@ -3978,7 +3999,6 @@ static void led_exit(void) ...@@ -3978,7 +3999,6 @@ static void led_exit(void)
} }
kfree(tpacpi_leds); kfree(tpacpi_leds);
tpacpi_leds = NULL;
} }
static int __init led_init(struct ibm_init_struct *iibm) static int __init led_init(struct ibm_init_struct *iibm)
...@@ -4802,7 +4822,6 @@ static void brightness_exit(void) ...@@ -4802,7 +4822,6 @@ static void brightness_exit(void)
vdbg_printk(TPACPI_DBG_EXIT, vdbg_printk(TPACPI_DBG_EXIT,
"calling backlight_device_unregister()\n"); "calling backlight_device_unregister()\n");
backlight_device_unregister(ibm_backlight_device); backlight_device_unregister(ibm_backlight_device);
ibm_backlight_device = NULL;
} }
} }
...@@ -5764,11 +5783,16 @@ static int __init fan_init(struct ibm_init_struct *iibm) ...@@ -5764,11 +5783,16 @@ static int __init fan_init(struct ibm_init_struct *iibm)
fan_control_access_mode != TPACPI_FAN_WR_NONE) { fan_control_access_mode != TPACPI_FAN_WR_NONE) {
rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
&fan_attr_group); &fan_attr_group);
if (!(rc < 0)) if (rc < 0)
return rc;
rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
&driver_attr_fan_watchdog); &driver_attr_fan_watchdog);
if (rc < 0) if (rc < 0) {
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
&fan_attr_group);
return rc; return rc;
}
return 0; return 0;
} else } else
return 1; return 1;
......
...@@ -50,15 +50,17 @@ static int irq_flags(int triggering, int polarity, int shareable) ...@@ -50,15 +50,17 @@ static int irq_flags(int triggering, int polarity, int shareable)
flags = IORESOURCE_IRQ_HIGHEDGE; flags = IORESOURCE_IRQ_HIGHEDGE;
} }
if (shareable) if (shareable == ACPI_SHARED)
flags |= IORESOURCE_IRQ_SHAREABLE; flags |= IORESOURCE_IRQ_SHAREABLE;
return flags; return flags;
} }
static void decode_irq_flags(int flag, int *triggering, int *polarity) static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering,
int *polarity, int *shareable)
{ {
switch (flag) { switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL |
IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) {
case IORESOURCE_IRQ_LOWLEVEL: case IORESOURCE_IRQ_LOWLEVEL:
*triggering = ACPI_LEVEL_SENSITIVE; *triggering = ACPI_LEVEL_SENSITIVE;
*polarity = ACPI_ACTIVE_LOW; *polarity = ACPI_ACTIVE_LOW;
...@@ -75,7 +77,18 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity) ...@@ -75,7 +77,18 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity)
*triggering = ACPI_EDGE_SENSITIVE; *triggering = ACPI_EDGE_SENSITIVE;
*polarity = ACPI_ACTIVE_HIGH; *polarity = ACPI_ACTIVE_HIGH;
break; break;
default:
dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n",
flags);
*triggering = ACPI_EDGE_SENSITIVE;
*polarity = ACPI_ACTIVE_HIGH;
break;
} }
if (flags & IORESOURCE_IRQ_SHAREABLE)
*shareable = ACPI_SHARED;
else
*shareable = ACPI_EXCLUSIVE;
} }
static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
...@@ -742,6 +755,9 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) ...@@ -742,6 +755,9 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
if (pnpacpi_supported_resource(res)) { if (pnpacpi_supported_resource(res)) {
(*resource)->type = res->type; (*resource)->type = res->type;
(*resource)->length = sizeof(struct acpi_resource); (*resource)->length = sizeof(struct acpi_resource);
if (res->type == ACPI_RESOURCE_TYPE_IRQ)
(*resource)->data.irq.descriptor_length =
res->data.irq.descriptor_length;
(*resource)++; (*resource)++;
} }
...@@ -788,22 +804,21 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, ...@@ -788,22 +804,21 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
struct resource *p) struct resource *p)
{ {
struct acpi_resource_irq *irq = &resource->data.irq; struct acpi_resource_irq *irq = &resource->data.irq;
int triggering, polarity; int triggering, polarity, shareable;
decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
irq->triggering = triggering; irq->triggering = triggering;
irq->polarity = polarity; irq->polarity = polarity;
if (triggering == ACPI_EDGE_SENSITIVE) irq->sharable = shareable;
irq->sharable = ACPI_EXCLUSIVE;
else
irq->sharable = ACPI_SHARED;
irq->interrupt_count = 1; irq->interrupt_count = 1;
irq->interrupts[0] = p->start; irq->interrupts[0] = p->start;
dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, dev_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n",
(int) p->start,
triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
polarity == ACPI_ACTIVE_LOW ? "low" : "high", polarity == ACPI_ACTIVE_LOW ? "low" : "high",
irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); irq->sharable == ACPI_SHARED ? "shared" : "exclusive",
irq->descriptor_length);
} }
static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
...@@ -811,16 +826,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, ...@@ -811,16 +826,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
struct resource *p) struct resource *p)
{ {
struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
int triggering, polarity; int triggering, polarity, shareable;
decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
extended_irq->producer_consumer = ACPI_CONSUMER; extended_irq->producer_consumer = ACPI_CONSUMER;
extended_irq->triggering = triggering; extended_irq->triggering = triggering;
extended_irq->polarity = polarity; extended_irq->polarity = polarity;
if (triggering == ACPI_EDGE_SENSITIVE) extended_irq->sharable = shareable;
extended_irq->sharable = ACPI_EXCLUSIVE;
else
extended_irq->sharable = ACPI_SHARED;
extended_irq->interrupt_count = 1; extended_irq->interrupt_count = 1;
extended_irq->interrupts[0] = p->start; extended_irq->interrupts[0] = p->start;
......
...@@ -319,6 +319,7 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) ...@@ -319,6 +319,7 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
#endif /* CONFIG_CPU_FREQ */ #endif /* CONFIG_CPU_FREQ */
/* in processor_throttling.c */ /* in processor_throttling.c */
int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
int acpi_processor_get_throttling_info(struct acpi_processor *pr); int acpi_processor_get_throttling_info(struct acpi_processor *pr);
extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state); extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
extern struct file_operations acpi_processor_throttling_fops; extern struct file_operations acpi_processor_throttling_fops;
......
...@@ -82,6 +82,7 @@ struct cpuidle_state_kobj { ...@@ -82,6 +82,7 @@ struct cpuidle_state_kobj {
}; };
struct cpuidle_device { struct cpuidle_device {
unsigned int registered:1;
unsigned int enabled:1; unsigned int enabled:1;
unsigned int cpu; unsigned int cpu;
......
...@@ -53,14 +53,14 @@ struct resource_list { ...@@ -53,14 +53,14 @@ struct resource_list {
#define IORESOURCE_AUTO 0x40000000 #define IORESOURCE_AUTO 0x40000000
#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ #define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */
/* ISA PnP IRQ specific bits (IORESOURCE_BITS) */ /* PnP IRQ specific bits (IORESOURCE_BITS) */
#define IORESOURCE_IRQ_HIGHEDGE (1<<0) #define IORESOURCE_IRQ_HIGHEDGE (1<<0)
#define IORESOURCE_IRQ_LOWEDGE (1<<1) #define IORESOURCE_IRQ_LOWEDGE (1<<1)
#define IORESOURCE_IRQ_HIGHLEVEL (1<<2) #define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
#define IORESOURCE_IRQ_LOWLEVEL (1<<3) #define IORESOURCE_IRQ_LOWLEVEL (1<<3)
#define IORESOURCE_IRQ_SHAREABLE (1<<4) #define IORESOURCE_IRQ_SHAREABLE (1<<4)
/* ISA PnP DMA specific bits (IORESOURCE_BITS) */ /* PnP DMA specific bits (IORESOURCE_BITS) */
#define IORESOURCE_DMA_TYPE_MASK (3<<0) #define IORESOURCE_DMA_TYPE_MASK (3<<0)
#define IORESOURCE_DMA_8BIT (0<<0) #define IORESOURCE_DMA_8BIT (0<<0)
#define IORESOURCE_DMA_8AND16BIT (1<<0) #define IORESOURCE_DMA_8AND16BIT (1<<0)
...@@ -76,7 +76,7 @@ struct resource_list { ...@@ -76,7 +76,7 @@ struct resource_list {
#define IORESOURCE_DMA_TYPEB (2<<6) #define IORESOURCE_DMA_TYPEB (2<<6)
#define IORESOURCE_DMA_TYPEF (3<<6) #define IORESOURCE_DMA_TYPEF (3<<6)
/* ISA PnP memory I/O specific bits (IORESOURCE_BITS) */ /* PnP memory I/O specific bits (IORESOURCE_BITS) */
#define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */ #define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */
#define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */ #define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */
#define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */ #define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment