diff options
27 files changed, 435 insertions, 360 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 01c6c3d8a7e3..64b3f146e4b0 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
@@ -503,7 +503,7 @@ generate input device EV_KEY events. | |||
503 | In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW | 503 | In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW |
504 | events for switches: | 504 | events for switches: |
505 | 505 | ||
506 | SW_RADIO T60 and later hardare rfkill rocker switch | 506 | SW_RFKILL_ALL T60 and later hardare rfkill rocker switch |
507 | SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A | 507 | SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A |
508 | 508 | ||
509 | Non hot-key ACPI HKEY event map: | 509 | Non hot-key ACPI HKEY event map: |
diff --git a/MAINTAINERS b/MAINTAINERS index e3560df4608e..9d4304266043 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -228,21 +228,21 @@ ACPI BATTERY DRIVERS | |||
228 | P: Alexey Starikovskiy | 228 | P: Alexey Starikovskiy |
229 | M: astarikovskiy@suse.de | 229 | M: astarikovskiy@suse.de |
230 | L: linux-acpi@vger.kernel.org | 230 | L: linux-acpi@vger.kernel.org |
231 | W: http://acpi.sourceforge.net/ | 231 | W: http://www.lesswatts.org/projects/acpi/ |
232 | S: Supported | 232 | S: Supported |
233 | 233 | ||
234 | ACPI EC DRIVER | 234 | ACPI EC DRIVER |
235 | P: Alexey Starikovskiy | 235 | P: Alexey Starikovskiy |
236 | M: astarikovskiy@suse.de | 236 | M: astarikovskiy@suse.de |
237 | L: linux-acpi@vger.kernel.org | 237 | L: linux-acpi@vger.kernel.org |
238 | W: http://acpi.sourceforge.net/ | 238 | W: http://www.lesswatts.org/projects/acpi/ |
239 | S: Supported | 239 | S: Supported |
240 | 240 | ||
241 | ACPI FAN DRIVER | 241 | ACPI FAN DRIVER |
242 | P: Len Brown | 242 | P: Len Brown |
243 | M: len.brown@intel.com | 243 | M: len.brown@intel.com |
244 | L: linux-acpi@vger.kernel.org | 244 | L: linux-acpi@vger.kernel.org |
245 | W: http://acpi.sourceforge.net/ | 245 | W: http://www.lesswatts.org/projects/acpi/ |
246 | S: Supported | 246 | S: Supported |
247 | 247 | ||
248 | ACPI PCI HOTPLUG DRIVER | 248 | ACPI PCI HOTPLUG DRIVER |
@@ -255,14 +255,14 @@ ACPI THERMAL DRIVER | |||
255 | P: Len Brown | 255 | P: Len Brown |
256 | M: len.brown@intel.com | 256 | M: len.brown@intel.com |
257 | L: linux-acpi@vger.kernel.org | 257 | L: linux-acpi@vger.kernel.org |
258 | W: http://acpi.sourceforge.net/ | 258 | W: http://www.lesswatts.org/projects/acpi/ |
259 | S: Supported | 259 | S: Supported |
260 | 260 | ||
261 | ACPI VIDEO DRIVER | 261 | ACPI VIDEO DRIVER |
262 | P: Rui Zhang | 262 | P: Rui Zhang |
263 | M: rui.zhang@intel.com | 263 | M: rui.zhang@intel.com |
264 | L: linux-acpi@vger.kernel.org | 264 | L: linux-acpi@vger.kernel.org |
265 | W: http://acpi.sourceforge.net/ | 265 | W: http://www.lesswatts.org/projects/acpi/ |
266 | S: Supported | 266 | S: Supported |
267 | 267 | ||
268 | ACPI WMI DRIVER | 268 | ACPI WMI DRIVER |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 853d1f11be00..43687cc60dfb 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -465,7 +465,6 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) | |||
465 | printk(KERN_ERR | 465 | printk(KERN_ERR |
466 | "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", | 466 | "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", |
467 | len, slit->header.length); | 467 | len, slit->header.length); |
468 | memset(numa_slit, 10, sizeof(numa_slit)); | ||
469 | return; | 468 | return; |
470 | } | 469 | } |
471 | slit_table = slit; | 470 | slit_table = slit; |
@@ -574,8 +573,14 @@ void __init acpi_numa_arch_fixup(void) | |||
574 | printk(KERN_INFO "Number of memory chunks in system = %d\n", | 573 | printk(KERN_INFO "Number of memory chunks in system = %d\n", |
575 | num_node_memblks); | 574 | num_node_memblks); |
576 | 575 | ||
577 | if (!slit_table) | 576 | if (!slit_table) { |
577 | for (i = 0; i < MAX_NUMNODES; i++) | ||
578 | for (j = 0; j < MAX_NUMNODES; j++) | ||
579 | node_distance(i, j) = i == j ? LOCAL_DISTANCE : | ||
580 | REMOTE_DISTANCE; | ||
578 | return; | 581 | return; |
582 | } | ||
583 | |||
579 | memset(numa_slit, -1, sizeof(numa_slit)); | 584 | memset(numa_slit, -1, sizeof(numa_slit)); |
580 | for (i = 0; i < slit_table->locality_count; i++) { | 585 | for (i = 0; i < slit_table->locality_count; i++) { |
581 | if (!pxm_bit_test(i)) | 586 | if (!pxm_bit_test(i)) |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 3890234e5b26..99649dccad28 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -97,36 +97,9 @@ static __init inline int srat_disabled(void) | |||
97 | return numa_off || acpi_numa < 0; | 97 | return numa_off || acpi_numa < 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | /* | ||
101 | * A lot of BIOS fill in 10 (= no distance) everywhere. This messes | ||
102 | * up the NUMA heuristics which wants the local node to have a smaller | ||
103 | * distance than the others. | ||
104 | * Do some quick checks here and only use the SLIT if it passes. | ||
105 | */ | ||
106 | static __init int slit_valid(struct acpi_table_slit *slit) | ||
107 | { | ||
108 | int i, j; | ||
109 | int d = slit->locality_count; | ||
110 | for (i = 0; i < d; i++) { | ||
111 | for (j = 0; j < d; j++) { | ||
112 | u8 val = slit->entry[d*i + j]; | ||
113 | if (i == j) { | ||
114 | if (val != LOCAL_DISTANCE) | ||
115 | return 0; | ||
116 | } else if (val <= LOCAL_DISTANCE) | ||
117 | return 0; | ||
118 | } | ||
119 | } | ||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | /* Callback for SLIT parsing */ | 100 | /* Callback for SLIT parsing */ |
124 | void __init acpi_numa_slit_init(struct acpi_table_slit *slit) | 101 | void __init acpi_numa_slit_init(struct acpi_table_slit *slit) |
125 | { | 102 | { |
126 | if (!slit_valid(slit)) { | ||
127 | printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); | ||
128 | return; | ||
129 | } | ||
130 | acpi_slit = slit; | 103 | acpi_slit = slit; |
131 | } | 104 | } |
132 | 105 | ||
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index d2fc94161848..26038c2a2a71 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c | |||
@@ -301,16 +301,20 @@ static int bay_add(acpi_handle handle, int id) | |||
301 | */ | 301 | */ |
302 | pdev->dev.uevent_suppress = 0; | 302 | pdev->dev.uevent_suppress = 0; |
303 | 303 | ||
304 | if (acpi_bay_add_fs(new_bay)) { | ||
305 | platform_device_unregister(new_bay->pdev); | ||
306 | goto bay_add_err; | ||
307 | } | ||
308 | |||
309 | /* register for events on this device */ | 304 | /* register for events on this device */ |
310 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | 305 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
311 | bay_notify, new_bay); | 306 | bay_notify, new_bay); |
312 | if (ACPI_FAILURE(status)) { | 307 | if (ACPI_FAILURE(status)) { |
313 | printk(KERN_ERR PREFIX "Error installing bay notify handler\n"); | 308 | printk(KERN_INFO PREFIX "Error installing bay notify handler\n"); |
309 | platform_device_unregister(new_bay->pdev); | ||
310 | goto bay_add_err; | ||
311 | } | ||
312 | |||
313 | if (acpi_bay_add_fs(new_bay)) { | ||
314 | acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
315 | bay_notify); | ||
316 | platform_device_unregister(new_bay->pdev); | ||
317 | goto bay_add_err; | ||
314 | } | 318 | } |
315 | 319 | ||
316 | /* if we are on a dock station, we should register for dock | 320 | /* if we are on a dock station, we should register for dock |
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index c78078315be9..f988a5e7d2b4 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c | |||
@@ -450,10 +450,6 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
450 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 450 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
451 | } | 451 | } |
452 | 452 | ||
453 | if (!arg) { | ||
454 | return_ACPI_STATUS(AE_AML_NO_OPERAND); | ||
455 | } | ||
456 | |||
457 | /* Creating new namespace node(s), should not already exist */ | 453 | /* Creating new namespace node(s), should not already exist */ |
458 | 454 | ||
459 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | 455 | 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 | 463 | ||
468 | /* | 464 | /* |
469 | * Walk the list of entries in the field_list | 465 | * Walk the list of entries in the field_list |
466 | * Note: field_list can be of zero length. In this case, Arg will be NULL. | ||
470 | */ | 467 | */ |
471 | while (arg) { | 468 | while (arg) { |
472 | /* | 469 | /* |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index fa44fb96fc34..96c542f7fded 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -834,7 +834,7 @@ static int dock_add(acpi_handle handle) | |||
834 | goto dock_add_err; | 834 | goto dock_add_err; |
835 | } | 835 | } |
836 | 836 | ||
837 | printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_DESCRIPTION); | 837 | printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION); |
838 | 838 | ||
839 | return 0; | 839 | return 0; |
840 | 840 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 0924992187e8..5622aee996b2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -194,7 +194,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | |||
194 | while (time_before(jiffies, delay)) { | 194 | while (time_before(jiffies, delay)) { |
195 | if (acpi_ec_check_status(ec, event)) | 195 | if (acpi_ec_check_status(ec, event)) |
196 | return 0; | 196 | return 0; |
197 | udelay(ACPI_EC_UDELAY); | 197 | msleep(1); |
198 | } | 198 | } |
199 | } | 199 | } |
200 | pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", | 200 | pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", |
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 24da921d13e3..39d742190584 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -375,9 +375,15 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
375 | goto cleanup; | 375 | goto cleanup; |
376 | } | 376 | } |
377 | 377 | ||
378 | /* | ||
379 | * Add the table to the namespace. | ||
380 | * | ||
381 | * Note: We load the table objects relative to the root of the namespace. | ||
382 | * This appears to go against the ACPI specification, but we do it for | ||
383 | * compatibility with other ACPI implementations. | ||
384 | */ | ||
378 | status = | 385 | status = |
379 | acpi_ex_add_table(table_index, walk_state->scope_info->scope.node, | 386 | acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); |
380 | &ddb_handle); | ||
381 | if (ACPI_FAILURE(status)) { | 387 | if (ACPI_FAILURE(status)) { |
382 | 388 | ||
383 | /* On error, table_ptr was deallocated above */ | 389 | /* On error, table_ptr was deallocated above */ |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 06f8634fe58b..2808dc60fd67 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -272,6 +272,12 @@ static u32 rtc_handler(void *context) | |||
272 | static inline void rtc_wake_setup(void) | 272 | static inline void rtc_wake_setup(void) |
273 | { | 273 | { |
274 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | 274 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); |
275 | /* | ||
276 | * After the RTC handler is installed, the Fixed_RTC event should | ||
277 | * be disabled. Only when the RTC alarm is set will it be enabled. | ||
278 | */ | ||
279 | acpi_clear_event(ACPI_EVENT_RTC); | ||
280 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
275 | } | 281 | } |
276 | 282 | ||
277 | static void rtc_wake_on(struct device *dev) | 283 | static void rtc_wake_on(struct device *dev) |
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index d9937e05ec6a..dba3cfbe8cba 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -223,15 +223,17 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | |||
223 | break; | 223 | break; |
224 | } | 224 | } |
225 | 225 | ||
226 | /* Set the system indicators to show the desired sleep state. */ | 226 | /* |
227 | 227 | * Set the system indicators to show the desired sleep state. | |
228 | * _SST is an optional method (return no error if not found) | ||
229 | */ | ||
228 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | 230 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); |
229 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 231 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
230 | ACPI_EXCEPTION((AE_INFO, status, | 232 | ACPI_EXCEPTION((AE_INFO, status, |
231 | "While executing method _SST")); | 233 | "While executing method _SST")); |
232 | } | 234 | } |
233 | 235 | ||
234 | return_ACPI_STATUS(status); | 236 | return_ACPI_STATUS(AE_OK); |
235 | } | 237 | } |
236 | 238 | ||
237 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | 239 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 5d59cb33b1a5..658e5f3abae0 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -140,19 +140,42 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) | |||
140 | } | 140 | } |
141 | } | 141 | } |
142 | 142 | ||
143 | /* | ||
144 | * A lot of BIOS fill in 10 (= no distance) everywhere. This messes | ||
145 | * up the NUMA heuristics which wants the local node to have a smaller | ||
146 | * distance than the others. | ||
147 | * Do some quick checks here and only use the SLIT if it passes. | ||
148 | */ | ||
149 | static __init int slit_valid(struct acpi_table_slit *slit) | ||
150 | { | ||
151 | int i, j; | ||
152 | int d = slit->locality_count; | ||
153 | for (i = 0; i < d; i++) { | ||
154 | for (j = 0; j < d; j++) { | ||
155 | u8 val = slit->entry[d*i + j]; | ||
156 | if (i == j) { | ||
157 | if (val != LOCAL_DISTANCE) | ||
158 | return 0; | ||
159 | } else if (val <= LOCAL_DISTANCE) | ||
160 | return 0; | ||
161 | } | ||
162 | } | ||
163 | return 1; | ||
164 | } | ||
165 | |||
143 | static int __init acpi_parse_slit(struct acpi_table_header *table) | 166 | static int __init acpi_parse_slit(struct acpi_table_header *table) |
144 | { | 167 | { |
145 | struct acpi_table_slit *slit; | 168 | struct acpi_table_slit *slit; |
146 | u32 localities; | ||
147 | 169 | ||
148 | if (!table) | 170 | if (!table) |
149 | return -EINVAL; | 171 | return -EINVAL; |
150 | 172 | ||
151 | slit = (struct acpi_table_slit *)table; | 173 | slit = (struct acpi_table_slit *)table; |
152 | 174 | ||
153 | /* downcast just for %llu vs %lu for i386/ia64 */ | 175 | if (!slit_valid(slit)) { |
154 | localities = (u32) slit->locality_count; | 176 | printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); |
155 | 177 | return -EINVAL; | |
178 | } | ||
156 | acpi_numa_slit_init(slit); | 179 | acpi_numa_slit_init(slit); |
157 | 180 | ||
158 | return 0; | 181 | return 0; |
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index f1e8bf65e24e..e94463778845 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c | |||
@@ -268,7 +268,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
268 | */ | 268 | */ |
269 | if (ACPI_SUCCESS(status) && | 269 | if (ACPI_SUCCESS(status) && |
270 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { | 270 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { |
271 | if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { | 271 | if (walk_state->opcode == AML_UNLOAD_OP) { |
272 | /* | 272 | /* |
273 | * acpi_ps_get_next_namestring has increased the AML pointer, | 273 | * acpi_ps_get_next_namestring has increased the AML pointer, |
274 | * so we need to restore the saved AML pointer for method call. | 274 | * 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 | 691 | ||
692 | /* To support super_name arg of Unload */ | 692 | /* To support super_name arg of Unload */ |
693 | 693 | ||
694 | if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { | 694 | if (walk_state->opcode == AML_UNLOAD_OP) { |
695 | status = | 695 | status = |
696 | acpi_ps_get_next_namepath(walk_state, | 696 | acpi_ps_get_next_namepath(walk_state, |
697 | parser_state, arg, | 697 | parser_state, arg, |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 386e5aa48834..9dd0fa93b9e1 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -86,7 +86,6 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | |||
86 | static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); | 86 | static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); |
87 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | 87 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); |
88 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 88 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
89 | extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr); | ||
90 | 89 | ||
91 | 90 | ||
92 | static const struct acpi_device_id processor_device_ids[] = { | 91 | static const struct acpi_device_id processor_device_ids[] = { |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 2dd2c1f3a01c..556ee1585192 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -1669,6 +1669,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1669 | return -EINVAL; | 1669 | return -EINVAL; |
1670 | } | 1670 | } |
1671 | 1671 | ||
1672 | dev->cpu = pr->id; | ||
1672 | for (i = 0; i < CPUIDLE_STATE_MAX; i++) { | 1673 | for (i = 0; i < CPUIDLE_STATE_MAX; i++) { |
1673 | dev->states[i].name[0] = '\0'; | 1674 | dev->states[i].name[0] = '\0'; |
1674 | dev->states[i].desc[0] = '\0'; | 1675 | dev->states[i].desc[0] = '\0'; |
@@ -1738,7 +1739,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1738 | 1739 | ||
1739 | int acpi_processor_cst_has_changed(struct acpi_processor *pr) | 1740 | int acpi_processor_cst_has_changed(struct acpi_processor *pr) |
1740 | { | 1741 | { |
1741 | int ret; | 1742 | int ret = 0; |
1742 | 1743 | ||
1743 | if (boot_option_idle_override) | 1744 | if (boot_option_idle_override) |
1744 | return 0; | 1745 | return 0; |
@@ -1756,8 +1757,10 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
1756 | cpuidle_pause_and_lock(); | 1757 | cpuidle_pause_and_lock(); |
1757 | cpuidle_disable_device(&pr->power.dev); | 1758 | cpuidle_disable_device(&pr->power.dev); |
1758 | acpi_processor_get_power_info(pr); | 1759 | acpi_processor_get_power_info(pr); |
1759 | acpi_processor_setup_cpuidle(pr); | 1760 | if (pr->flags.power) { |
1760 | ret = cpuidle_enable_device(&pr->power.dev); | 1761 | acpi_processor_setup_cpuidle(pr); |
1762 | ret = cpuidle_enable_device(&pr->power.dev); | ||
1763 | } | ||
1761 | cpuidle_resume_and_unlock(); | 1764 | cpuidle_resume_and_unlock(); |
1762 | 1765 | ||
1763 | return ret; | 1766 | return ret; |
@@ -1813,7 +1816,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1813 | if (pr->flags.power) { | 1816 | if (pr->flags.power) { |
1814 | #ifdef CONFIG_CPU_IDLE | 1817 | #ifdef CONFIG_CPU_IDLE |
1815 | acpi_processor_setup_cpuidle(pr); | 1818 | acpi_processor_setup_cpuidle(pr); |
1816 | pr->power.dev.cpu = pr->id; | ||
1817 | if (cpuidle_register_device(&pr->power.dev)) | 1819 | if (cpuidle_register_device(&pr->power.dev)) |
1818 | return -EIO; | 1820 | return -EIO; |
1819 | #endif | 1821 | #endif |
@@ -1850,8 +1852,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
1850 | return 0; | 1852 | return 0; |
1851 | 1853 | ||
1852 | #ifdef CONFIG_CPU_IDLE | 1854 | #ifdef CONFIG_CPU_IDLE |
1853 | if (pr->flags.power) | 1855 | cpuidle_unregister_device(&pr->power.dev); |
1854 | cpuidle_unregister_device(&pr->power.dev); | ||
1855 | #endif | 1856 | #endif |
1856 | pr->flags.power_setup_done = 0; | 1857 | pr->flags.power_setup_done = 0; |
1857 | 1858 | ||
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 8a5fe8710513..224c57c03381 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -495,6 +495,12 @@ static int __init acpi_sleep_proc_init(void) | |||
495 | acpi_root_dir, &acpi_system_alarm_fops); | 495 | acpi_root_dir, &acpi_system_alarm_fops); |
496 | 496 | ||
497 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | 497 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); |
498 | /* | ||
499 | * Disable the RTC event after installing RTC handler. | ||
500 | * Only when RTC alarm is set will it be enabled. | ||
501 | */ | ||
502 | acpi_clear_event(ACPI_EVENT_RTC); | ||
503 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
498 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | 504 | #endif /* HAVE_ACPI_LEGACY_ALARM */ |
499 | 505 | ||
500 | /* 'wakeup device' [R/W] */ | 506 | /* 'wakeup device' [R/W] */ |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 769f24855eb6..5bd2dec9a7ac 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -77,7 +77,6 @@ static ssize_t acpi_table_show(struct kobject *kobj, | |||
77 | container_of(bin_attr, struct acpi_table_attr, attr); | 77 | container_of(bin_attr, struct acpi_table_attr, attr); |
78 | struct acpi_table_header *table_header = NULL; | 78 | struct acpi_table_header *table_header = NULL; |
79 | acpi_status status; | 79 | acpi_status status; |
80 | ssize_t ret_count = count; | ||
81 | 80 | ||
82 | status = | 81 | status = |
83 | acpi_get_table(table_attr->name, table_attr->instance, | 82 | acpi_get_table(table_attr->name, table_attr->instance, |
@@ -85,18 +84,8 @@ static ssize_t acpi_table_show(struct kobject *kobj, | |||
85 | if (ACPI_FAILURE(status)) | 84 | if (ACPI_FAILURE(status)) |
86 | return -ENODEV; | 85 | return -ENODEV; |
87 | 86 | ||
88 | if (offset >= table_header->length) { | 87 | return memory_read_from_buffer(buf, count, &offset, |
89 | ret_count = 0; | 88 | table_header, table_header->length); |
90 | goto end; | ||
91 | } | ||
92 | |||
93 | if (offset + ret_count > table_header->length) | ||
94 | ret_count = table_header->length - offset; | ||
95 | |||
96 | memcpy(buf, ((char *)table_header) + offset, ret_count); | ||
97 | |||
98 | end: | ||
99 | return ret_count; | ||
100 | } | 89 | } |
101 | 90 | ||
102 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | 91 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, |
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 402f93e1ff20..5336ce88f89f 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -123,24 +123,13 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | /* The table must be either an SSDT or a PSDT or an OEMx */ | 126 | /* |
127 | 127 | * Originally, we checked the table signature for "SSDT" or "PSDT" here. | |
128 | if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&& | 128 | * Next, we added support for OEMx tables, signature "OEM". |
129 | !ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&& | 129 | * Valid tables were encountered with a null signature, so we've just |
130 | strncmp(table_desc->pointer->signature, "OEM", 3)) { | 130 | * given up on validating the signature, since it seems to be a waste |
131 | /* Check for a printable name */ | 131 | * of code. The original code was removed (05/2008). |
132 | if (acpi_ut_valid_acpi_name( | 132 | */ |
133 | *(u32 *) table_desc->pointer->signature)) { | ||
134 | ACPI_ERROR((AE_INFO, "Table has invalid signature " | ||
135 | "[%4.4s], must be SSDT or PSDT", | ||
136 | table_desc->pointer->signature)); | ||
137 | } else { | ||
138 | ACPI_ERROR((AE_INFO, "Table has invalid signature " | ||
139 | "(0x%8.8X), must be SSDT or PSDT", | ||
140 | *(u32 *) table_desc->pointer->signature)); | ||
141 | } | ||
142 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
143 | } | ||
144 | 133 | ||
145 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 134 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
146 | 135 | ||
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index fb57b93c2495..0e319604d3e7 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
540 | acpi_tb_print_table_header(0, table); | 540 | acpi_tb_print_table_header(0, table); |
541 | 541 | ||
542 | if (no_auto_ssdt == 0) { | 542 | if (no_auto_ssdt == 0) { |
543 | printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\""); | 543 | printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n"); |
544 | } | 544 | } |
545 | } | 545 | } |
546 | 546 | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 504385b1f211..84c795fb9b1e 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -364,10 +364,17 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
364 | if (flag & ACPI_TRIPS_CRITICAL) { | 364 | if (flag & ACPI_TRIPS_CRITICAL) { |
365 | status = acpi_evaluate_integer(tz->device->handle, | 365 | status = acpi_evaluate_integer(tz->device->handle, |
366 | "_CRT", NULL, &tz->trips.critical.temperature); | 366 | "_CRT", NULL, &tz->trips.critical.temperature); |
367 | if (ACPI_FAILURE(status)) { | 367 | /* |
368 | * Treat freezing temperatures as invalid as well; some | ||
369 | * BIOSes return really low values and cause reboots at startup. | ||
370 | * Below zero (Celcius) values clearly aren't right for sure.. | ||
371 | * ... so lets discard those as invalid. | ||
372 | */ | ||
373 | if (ACPI_FAILURE(status) || | ||
374 | tz->trips.critical.temperature <= 2732) { | ||
368 | tz->trips.critical.flags.valid = 0; | 375 | tz->trips.critical.flags.valid = 0; |
369 | ACPI_EXCEPTION((AE_INFO, status, | 376 | ACPI_EXCEPTION((AE_INFO, status, |
370 | "No critical threshold")); | 377 | "No or invalid critical threshold")); |
371 | return -ENODEV; | 378 | return -ENODEV; |
372 | } else { | 379 | } else { |
373 | tz->trips.critical.flags.valid = 1; | 380 | tz->trips.critical.flags.valid = 1; |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index e4ba7192cd15..1f057b71db1a 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -1048,6 +1048,7 @@ acpi_ut_exception(char *module_name, | |||
1048 | va_start(args, format); | 1048 | va_start(args, format); |
1049 | acpi_os_vprintf(format, args); | 1049 | acpi_os_vprintf(format, args); |
1050 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1050 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); |
1051 | va_end(args); | ||
1051 | } | 1052 | } |
1052 | 1053 | ||
1053 | EXPORT_SYMBOL(acpi_ut_exception); | 1054 | EXPORT_SYMBOL(acpi_ut_exception); |
@@ -1063,7 +1064,6 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) | |||
1063 | acpi_os_vprintf(format, args); | 1064 | acpi_os_vprintf(format, args); |
1064 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1065 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); |
1065 | va_end(args); | 1066 | va_end(args); |
1066 | va_end(args); | ||
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | void ACPI_INTERNAL_VAR_XFACE | 1069 | void ACPI_INTERNAL_VAR_XFACE |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index fc555a90bb21..23554b676d6e 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -38,6 +38,8 @@ static void cpuidle_kick_cpus(void) | |||
38 | static void cpuidle_kick_cpus(void) {} | 38 | static void cpuidle_kick_cpus(void) {} |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | static int __cpuidle_register_device(struct cpuidle_device *dev); | ||
42 | |||
41 | /** | 43 | /** |
42 | * cpuidle_idle_call - the main idle loop | 44 | * cpuidle_idle_call - the main idle loop |
43 | * | 45 | * |
@@ -138,6 +140,12 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
138 | if (!dev->state_count) | 140 | if (!dev->state_count) |
139 | return -EINVAL; | 141 | return -EINVAL; |
140 | 142 | ||
143 | if (dev->registered == 0) { | ||
144 | ret = __cpuidle_register_device(dev); | ||
145 | if (ret) | ||
146 | return ret; | ||
147 | } | ||
148 | |||
141 | if ((ret = cpuidle_add_state_sysfs(dev))) | 149 | if ((ret = cpuidle_add_state_sysfs(dev))) |
142 | return ret; | 150 | return ret; |
143 | 151 | ||
@@ -232,10 +240,13 @@ static void poll_idle_init(struct cpuidle_device *dev) {} | |||
232 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ | 240 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ |
233 | 241 | ||
234 | /** | 242 | /** |
235 | * cpuidle_register_device - registers a CPU's idle PM feature | 243 | * __cpuidle_register_device - internal register function called before register |
244 | * and enable routines | ||
236 | * @dev: the cpu | 245 | * @dev: the cpu |
246 | * | ||
247 | * cpuidle_lock mutex must be held before this is called | ||
237 | */ | 248 | */ |
238 | int cpuidle_register_device(struct cpuidle_device *dev) | 249 | static int __cpuidle_register_device(struct cpuidle_device *dev) |
239 | { | 250 | { |
240 | int ret; | 251 | int ret; |
241 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); | 252 | 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 | 258 | ||
248 | init_completion(&dev->kobj_unregister); | 259 | init_completion(&dev->kobj_unregister); |
249 | 260 | ||
250 | mutex_lock(&cpuidle_lock); | ||
251 | |||
252 | poll_idle_init(dev); | 261 | poll_idle_init(dev); |
253 | 262 | ||
254 | per_cpu(cpuidle_devices, dev->cpu) = dev; | 263 | per_cpu(cpuidle_devices, dev->cpu) = dev; |
255 | list_add(&dev->device_list, &cpuidle_detected_devices); | 264 | list_add(&dev->device_list, &cpuidle_detected_devices); |
256 | if ((ret = cpuidle_add_sysfs(sys_dev))) { | 265 | if ((ret = cpuidle_add_sysfs(sys_dev))) { |
257 | mutex_unlock(&cpuidle_lock); | ||
258 | module_put(cpuidle_curr_driver->owner); | 266 | module_put(cpuidle_curr_driver->owner); |
259 | return ret; | 267 | return ret; |
260 | } | 268 | } |
261 | 269 | ||
270 | dev->registered = 1; | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * cpuidle_register_device - registers a CPU's idle PM feature | ||
276 | * @dev: the cpu | ||
277 | */ | ||
278 | int cpuidle_register_device(struct cpuidle_device *dev) | ||
279 | { | ||
280 | int ret; | ||
281 | |||
282 | mutex_lock(&cpuidle_lock); | ||
283 | |||
284 | if ((ret = __cpuidle_register_device(dev))) { | ||
285 | mutex_unlock(&cpuidle_lock); | ||
286 | return ret; | ||
287 | } | ||
288 | |||
262 | cpuidle_enable_device(dev); | 289 | cpuidle_enable_device(dev); |
263 | cpuidle_install_idle_handler(); | 290 | cpuidle_install_idle_handler(); |
264 | 291 | ||
@@ -278,6 +305,9 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) | |||
278 | { | 305 | { |
279 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); | 306 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); |
280 | 307 | ||
308 | if (dev->registered == 0) | ||
309 | return; | ||
310 | |||
281 | cpuidle_pause_and_lock(); | 311 | cpuidle_pause_and_lock(); |
282 | 312 | ||
283 | cpuidle_disable_device(dev); | 313 | cpuidle_disable_device(dev); |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index a0ce0b2fa03e..b5969298f3d3 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -1293,7 +1293,7 @@ static void tpacpi_input_send_radiosw(void) | |||
1293 | mutex_lock(&tpacpi_inputdev_send_mutex); | 1293 | mutex_lock(&tpacpi_inputdev_send_mutex); |
1294 | 1294 | ||
1295 | input_report_switch(tpacpi_inputdev, | 1295 | input_report_switch(tpacpi_inputdev, |
1296 | SW_RADIO, !!wlsw); | 1296 | SW_RFKILL_ALL, !!wlsw); |
1297 | input_sync(tpacpi_inputdev); | 1297 | input_sync(tpacpi_inputdev); |
1298 | 1298 | ||
1299 | mutex_unlock(&tpacpi_inputdev_send_mutex); | 1299 | mutex_unlock(&tpacpi_inputdev_send_mutex); |
@@ -1921,6 +1921,29 @@ static struct attribute *hotkey_mask_attributes[] __initdata = { | |||
1921 | &dev_attr_hotkey_wakeup_hotunplug_complete.attr, | 1921 | &dev_attr_hotkey_wakeup_hotunplug_complete.attr, |
1922 | }; | 1922 | }; |
1923 | 1923 | ||
1924 | static void hotkey_exit(void) | ||
1925 | { | ||
1926 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | ||
1927 | hotkey_poll_stop_sync(); | ||
1928 | #endif | ||
1929 | |||
1930 | if (hotkey_dev_attributes) | ||
1931 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); | ||
1932 | |||
1933 | kfree(hotkey_keycode_map); | ||
1934 | |||
1935 | if (tp_features.hotkey) { | ||
1936 | dbg_printk(TPACPI_DBG_EXIT, | ||
1937 | "restoring original hot key mask\n"); | ||
1938 | /* no short-circuit boolean operator below! */ | ||
1939 | if ((hotkey_mask_set(hotkey_orig_mask) | | ||
1940 | hotkey_status_set(hotkey_orig_status)) != 0) | ||
1941 | printk(TPACPI_ERR | ||
1942 | "failed to restore hot key mask " | ||
1943 | "to BIOS defaults\n"); | ||
1944 | } | ||
1945 | } | ||
1946 | |||
1924 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 1947 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
1925 | { | 1948 | { |
1926 | /* Requirements for changing the default keymaps: | 1949 | /* Requirements for changing the default keymaps: |
@@ -2060,226 +2083,220 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2060 | vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", | 2083 | vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", |
2061 | str_supported(tp_features.hotkey)); | 2084 | str_supported(tp_features.hotkey)); |
2062 | 2085 | ||
2063 | if (tp_features.hotkey) { | 2086 | if (!tp_features.hotkey) |
2064 | hotkey_dev_attributes = create_attr_set(13, NULL); | 2087 | return 1; |
2065 | if (!hotkey_dev_attributes) | ||
2066 | return -ENOMEM; | ||
2067 | res = add_many_to_attr_set(hotkey_dev_attributes, | ||
2068 | hotkey_attributes, | ||
2069 | ARRAY_SIZE(hotkey_attributes)); | ||
2070 | if (res) | ||
2071 | return res; | ||
2072 | 2088 | ||
2073 | /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, | 2089 | hotkey_dev_attributes = create_attr_set(13, NULL); |
2074 | A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking | 2090 | if (!hotkey_dev_attributes) |
2075 | for HKEY interface version 0x100 */ | 2091 | return -ENOMEM; |
2076 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | 2092 | res = add_many_to_attr_set(hotkey_dev_attributes, |
2077 | if ((hkeyv >> 8) != 1) { | 2093 | hotkey_attributes, |
2078 | printk(TPACPI_ERR "unknown version of the " | 2094 | ARRAY_SIZE(hotkey_attributes)); |
2079 | "HKEY interface: 0x%x\n", hkeyv); | 2095 | if (res) |
2080 | printk(TPACPI_ERR "please report this to %s\n", | 2096 | goto err_exit; |
2081 | TPACPI_MAIL); | 2097 | |
2082 | } else { | 2098 | /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, |
2083 | /* | 2099 | A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking |
2084 | * MHKV 0x100 in A31, R40, R40e, | 2100 | for HKEY interface version 0x100 */ |
2085 | * T4x, X31, and later | 2101 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { |
2086 | */ | 2102 | if ((hkeyv >> 8) != 1) { |
2087 | tp_features.hotkey_mask = 1; | 2103 | printk(TPACPI_ERR "unknown version of the " |
2088 | } | 2104 | "HKEY interface: 0x%x\n", hkeyv); |
2105 | printk(TPACPI_ERR "please report this to %s\n", | ||
2106 | TPACPI_MAIL); | ||
2107 | } else { | ||
2108 | /* | ||
2109 | * MHKV 0x100 in A31, R40, R40e, | ||
2110 | * T4x, X31, and later | ||
2111 | */ | ||
2112 | tp_features.hotkey_mask = 1; | ||
2089 | } | 2113 | } |
2114 | } | ||
2090 | 2115 | ||
2091 | vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", | 2116 | vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", |
2092 | str_supported(tp_features.hotkey_mask)); | 2117 | str_supported(tp_features.hotkey_mask)); |
2093 | 2118 | ||
2094 | if (tp_features.hotkey_mask) { | 2119 | if (tp_features.hotkey_mask) { |
2095 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, | 2120 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, |
2096 | "MHKA", "qd")) { | 2121 | "MHKA", "qd")) { |
2097 | printk(TPACPI_ERR | 2122 | printk(TPACPI_ERR |
2098 | "missing MHKA handler, " | 2123 | "missing MHKA handler, " |
2099 | "please report this to %s\n", | 2124 | "please report this to %s\n", |
2100 | TPACPI_MAIL); | 2125 | TPACPI_MAIL); |
2101 | /* FN+F12, FN+F4, FN+F3 */ | 2126 | /* FN+F12, FN+F4, FN+F3 */ |
2102 | hotkey_all_mask = 0x080cU; | 2127 | hotkey_all_mask = 0x080cU; |
2103 | } | ||
2104 | } | 2128 | } |
2129 | } | ||
2105 | 2130 | ||
2106 | /* hotkey_source_mask *must* be zero for | 2131 | /* hotkey_source_mask *must* be zero for |
2107 | * the first hotkey_mask_get */ | 2132 | * the first hotkey_mask_get */ |
2108 | res = hotkey_status_get(&hotkey_orig_status); | 2133 | res = hotkey_status_get(&hotkey_orig_status); |
2109 | if (!res && tp_features.hotkey_mask) { | 2134 | if (res) |
2110 | res = hotkey_mask_get(); | 2135 | goto err_exit; |
2111 | hotkey_orig_mask = hotkey_mask; | 2136 | |
2112 | if (!res) { | 2137 | if (tp_features.hotkey_mask) { |
2113 | res = add_many_to_attr_set( | 2138 | res = hotkey_mask_get(); |
2114 | hotkey_dev_attributes, | 2139 | if (res) |
2115 | hotkey_mask_attributes, | 2140 | goto err_exit; |
2116 | ARRAY_SIZE(hotkey_mask_attributes)); | 2141 | |
2117 | } | 2142 | hotkey_orig_mask = hotkey_mask; |
2118 | } | 2143 | res = add_many_to_attr_set( |
2144 | hotkey_dev_attributes, | ||
2145 | hotkey_mask_attributes, | ||
2146 | ARRAY_SIZE(hotkey_mask_attributes)); | ||
2147 | if (res) | ||
2148 | goto err_exit; | ||
2149 | } | ||
2119 | 2150 | ||
2120 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | 2151 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL |
2121 | if (tp_features.hotkey_mask) { | 2152 | if (tp_features.hotkey_mask) { |
2122 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK | 2153 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK |
2123 | & ~hotkey_all_mask; | 2154 | & ~hotkey_all_mask; |
2124 | } else { | 2155 | } else { |
2125 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; | 2156 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; |
2126 | } | 2157 | } |
2127 | 2158 | ||
2128 | vdbg_printk(TPACPI_DBG_INIT, | 2159 | vdbg_printk(TPACPI_DBG_INIT, |
2129 | "hotkey source mask 0x%08x, polling freq %d\n", | 2160 | "hotkey source mask 0x%08x, polling freq %d\n", |
2130 | hotkey_source_mask, hotkey_poll_freq); | 2161 | hotkey_source_mask, hotkey_poll_freq); |
2131 | #endif | 2162 | #endif |
2132 | 2163 | ||
2133 | /* Not all thinkpads have a hardware radio switch */ | 2164 | /* Not all thinkpads have a hardware radio switch */ |
2134 | if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { | 2165 | if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { |
2135 | tp_features.hotkey_wlsw = 1; | 2166 | tp_features.hotkey_wlsw = 1; |
2136 | printk(TPACPI_INFO | 2167 | printk(TPACPI_INFO |
2137 | "radio switch found; radios are %s\n", | 2168 | "radio switch found; radios are %s\n", |
2138 | enabled(status, 0)); | 2169 | enabled(status, 0)); |
2139 | res = add_to_attr_set(hotkey_dev_attributes, | 2170 | res = add_to_attr_set(hotkey_dev_attributes, |
2140 | &dev_attr_hotkey_radio_sw.attr); | 2171 | &dev_attr_hotkey_radio_sw.attr); |
2141 | } | 2172 | } |
2142 | 2173 | ||
2143 | /* For X41t, X60t, X61t Tablets... */ | 2174 | /* For X41t, X60t, X61t Tablets... */ |
2144 | if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { | 2175 | if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { |
2145 | tp_features.hotkey_tablet = 1; | 2176 | tp_features.hotkey_tablet = 1; |
2146 | printk(TPACPI_INFO | 2177 | printk(TPACPI_INFO |
2147 | "possible tablet mode switch found; " | 2178 | "possible tablet mode switch found; " |
2148 | "ThinkPad in %s mode\n", | 2179 | "ThinkPad in %s mode\n", |
2149 | (status & TP_HOTKEY_TABLET_MASK)? | 2180 | (status & TP_HOTKEY_TABLET_MASK)? |
2150 | "tablet" : "laptop"); | 2181 | "tablet" : "laptop"); |
2151 | res = add_to_attr_set(hotkey_dev_attributes, | 2182 | res = add_to_attr_set(hotkey_dev_attributes, |
2152 | &dev_attr_hotkey_tablet_mode.attr); | 2183 | &dev_attr_hotkey_tablet_mode.attr); |
2153 | } | 2184 | } |
2154 | 2185 | ||
2155 | if (!res) | 2186 | if (!res) |
2156 | res = register_attr_set_with_sysfs( | 2187 | res = register_attr_set_with_sysfs( |
2157 | hotkey_dev_attributes, | 2188 | hotkey_dev_attributes, |
2158 | &tpacpi_pdev->dev.kobj); | 2189 | &tpacpi_pdev->dev.kobj); |
2159 | if (res) | 2190 | if (res) |
2160 | return res; | 2191 | goto err_exit; |
2161 | 2192 | ||
2162 | /* Set up key map */ | 2193 | /* Set up key map */ |
2163 | 2194 | ||
2164 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, | 2195 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, |
2165 | GFP_KERNEL); | 2196 | GFP_KERNEL); |
2166 | if (!hotkey_keycode_map) { | 2197 | if (!hotkey_keycode_map) { |
2167 | printk(TPACPI_ERR | 2198 | printk(TPACPI_ERR |
2168 | "failed to allocate memory for key map\n"); | 2199 | "failed to allocate memory for key map\n"); |
2169 | return -ENOMEM; | 2200 | res = -ENOMEM; |
2170 | } | 2201 | goto err_exit; |
2202 | } | ||
2171 | 2203 | ||
2172 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { | 2204 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { |
2173 | dbg_printk(TPACPI_DBG_INIT, | 2205 | dbg_printk(TPACPI_DBG_INIT, |
2174 | "using Lenovo default hot key map\n"); | 2206 | "using Lenovo default hot key map\n"); |
2175 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, | 2207 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, |
2176 | TPACPI_HOTKEY_MAP_SIZE); | 2208 | TPACPI_HOTKEY_MAP_SIZE); |
2209 | } else { | ||
2210 | dbg_printk(TPACPI_DBG_INIT, | ||
2211 | "using IBM default hot key map\n"); | ||
2212 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | ||
2213 | TPACPI_HOTKEY_MAP_SIZE); | ||
2214 | } | ||
2215 | |||
2216 | set_bit(EV_KEY, tpacpi_inputdev->evbit); | ||
2217 | set_bit(EV_MSC, tpacpi_inputdev->evbit); | ||
2218 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); | ||
2219 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; | ||
2220 | tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; | ||
2221 | tpacpi_inputdev->keycode = hotkey_keycode_map; | ||
2222 | for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { | ||
2223 | if (hotkey_keycode_map[i] != KEY_RESERVED) { | ||
2224 | set_bit(hotkey_keycode_map[i], | ||
2225 | tpacpi_inputdev->keybit); | ||
2177 | } else { | 2226 | } else { |
2178 | dbg_printk(TPACPI_DBG_INIT, | 2227 | if (i < sizeof(hotkey_reserved_mask)*8) |
2179 | "using IBM default hot key map\n"); | 2228 | hotkey_reserved_mask |= 1 << i; |
2180 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | ||
2181 | TPACPI_HOTKEY_MAP_SIZE); | ||
2182 | } | ||
2183 | |||
2184 | set_bit(EV_KEY, tpacpi_inputdev->evbit); | ||
2185 | set_bit(EV_MSC, tpacpi_inputdev->evbit); | ||
2186 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); | ||
2187 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; | ||
2188 | tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; | ||
2189 | tpacpi_inputdev->keycode = hotkey_keycode_map; | ||
2190 | for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { | ||
2191 | if (hotkey_keycode_map[i] != KEY_RESERVED) { | ||
2192 | set_bit(hotkey_keycode_map[i], | ||
2193 | tpacpi_inputdev->keybit); | ||
2194 | } else { | ||
2195 | if (i < sizeof(hotkey_reserved_mask)*8) | ||
2196 | hotkey_reserved_mask |= 1 << i; | ||
2197 | } | ||
2198 | } | ||
2199 | |||
2200 | if (tp_features.hotkey_wlsw) { | ||
2201 | set_bit(EV_SW, tpacpi_inputdev->evbit); | ||
2202 | set_bit(SW_RADIO, tpacpi_inputdev->swbit); | ||
2203 | } | ||
2204 | if (tp_features.hotkey_tablet) { | ||
2205 | set_bit(EV_SW, tpacpi_inputdev->evbit); | ||
2206 | set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); | ||
2207 | } | 2229 | } |
2230 | } | ||
2208 | 2231 | ||
2209 | /* Do not issue duplicate brightness change events to | 2232 | if (tp_features.hotkey_wlsw) { |
2210 | * userspace */ | 2233 | set_bit(EV_SW, tpacpi_inputdev->evbit); |
2211 | if (!tp_features.bright_acpimode) | 2234 | set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); |
2212 | /* update bright_acpimode... */ | 2235 | } |
2213 | tpacpi_check_std_acpi_brightness_support(); | 2236 | if (tp_features.hotkey_tablet) { |
2214 | 2237 | set_bit(EV_SW, tpacpi_inputdev->evbit); | |
2215 | if (tp_features.bright_acpimode) { | 2238 | set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); |
2216 | printk(TPACPI_INFO | 2239 | } |
2217 | "This ThinkPad has standard ACPI backlight " | ||
2218 | "brightness control, supported by the ACPI " | ||
2219 | "video driver\n"); | ||
2220 | printk(TPACPI_NOTICE | ||
2221 | "Disabling thinkpad-acpi brightness events " | ||
2222 | "by default...\n"); | ||
2223 | |||
2224 | /* The hotkey_reserved_mask change below is not | ||
2225 | * necessary while the keys are at KEY_RESERVED in the | ||
2226 | * default map, but better safe than sorry, leave it | ||
2227 | * here as a marker of what we have to do, especially | ||
2228 | * when we finally become able to set this at runtime | ||
2229 | * on response to X.org requests */ | ||
2230 | hotkey_reserved_mask |= | ||
2231 | (1 << TP_ACPI_HOTKEYSCAN_FNHOME) | ||
2232 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); | ||
2233 | } | ||
2234 | 2240 | ||
2235 | dbg_printk(TPACPI_DBG_INIT, | 2241 | /* Do not issue duplicate brightness change events to |
2236 | "enabling hot key handling\n"); | 2242 | * userspace */ |
2237 | res = hotkey_status_set(1); | 2243 | if (!tp_features.bright_acpimode) |
2238 | if (res) | 2244 | /* update bright_acpimode... */ |
2239 | return res; | 2245 | tpacpi_check_std_acpi_brightness_support(); |
2240 | res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) | ||
2241 | & ~hotkey_reserved_mask) | ||
2242 | | hotkey_orig_mask); | ||
2243 | if (res < 0 && res != -ENXIO) | ||
2244 | return res; | ||
2245 | 2246 | ||
2246 | dbg_printk(TPACPI_DBG_INIT, | 2247 | if (tp_features.bright_acpimode) { |
2247 | "legacy hot key reporting over procfs %s\n", | 2248 | printk(TPACPI_INFO |
2248 | (hotkey_report_mode < 2) ? | 2249 | "This ThinkPad has standard ACPI backlight " |
2249 | "enabled" : "disabled"); | 2250 | "brightness control, supported by the ACPI " |
2251 | "video driver\n"); | ||
2252 | printk(TPACPI_NOTICE | ||
2253 | "Disabling thinkpad-acpi brightness events " | ||
2254 | "by default...\n"); | ||
2255 | |||
2256 | /* The hotkey_reserved_mask change below is not | ||
2257 | * necessary while the keys are at KEY_RESERVED in the | ||
2258 | * default map, but better safe than sorry, leave it | ||
2259 | * here as a marker of what we have to do, especially | ||
2260 | * when we finally become able to set this at runtime | ||
2261 | * on response to X.org requests */ | ||
2262 | hotkey_reserved_mask |= | ||
2263 | (1 << TP_ACPI_HOTKEYSCAN_FNHOME) | ||
2264 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); | ||
2265 | } | ||
2266 | |||
2267 | dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); | ||
2268 | res = hotkey_status_set(1); | ||
2269 | if (res) { | ||
2270 | hotkey_exit(); | ||
2271 | return res; | ||
2272 | } | ||
2273 | res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) | ||
2274 | & ~hotkey_reserved_mask) | ||
2275 | | hotkey_orig_mask); | ||
2276 | if (res < 0 && res != -ENXIO) { | ||
2277 | hotkey_exit(); | ||
2278 | return res; | ||
2279 | } | ||
2250 | 2280 | ||
2251 | tpacpi_inputdev->open = &hotkey_inputdev_open; | 2281 | dbg_printk(TPACPI_DBG_INIT, |
2252 | tpacpi_inputdev->close = &hotkey_inputdev_close; | 2282 | "legacy hot key reporting over procfs %s\n", |
2283 | (hotkey_report_mode < 2) ? | ||
2284 | "enabled" : "disabled"); | ||
2253 | 2285 | ||
2254 | hotkey_poll_setup_safe(1); | 2286 | tpacpi_inputdev->open = &hotkey_inputdev_open; |
2255 | tpacpi_input_send_radiosw(); | 2287 | tpacpi_inputdev->close = &hotkey_inputdev_close; |
2256 | tpacpi_input_send_tabletsw(); | ||
2257 | } | ||
2258 | 2288 | ||
2259 | return (tp_features.hotkey)? 0 : 1; | 2289 | hotkey_poll_setup_safe(1); |
2260 | } | 2290 | tpacpi_input_send_radiosw(); |
2291 | tpacpi_input_send_tabletsw(); | ||
2261 | 2292 | ||
2262 | static void hotkey_exit(void) | 2293 | return 0; |
2263 | { | ||
2264 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | ||
2265 | hotkey_poll_stop_sync(); | ||
2266 | #endif | ||
2267 | 2294 | ||
2268 | if (tp_features.hotkey) { | 2295 | err_exit: |
2269 | dbg_printk(TPACPI_DBG_EXIT, | 2296 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); |
2270 | "restoring original hot key mask\n"); | 2297 | hotkey_dev_attributes = NULL; |
2271 | /* no short-circuit boolean operator below! */ | ||
2272 | if ((hotkey_mask_set(hotkey_orig_mask) | | ||
2273 | hotkey_status_set(hotkey_orig_status)) != 0) | ||
2274 | printk(TPACPI_ERR | ||
2275 | "failed to restore hot key mask " | ||
2276 | "to BIOS defaults\n"); | ||
2277 | } | ||
2278 | 2298 | ||
2279 | if (hotkey_dev_attributes) { | 2299 | return (res < 0)? res : 1; |
2280 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); | ||
2281 | hotkey_dev_attributes = NULL; | ||
2282 | } | ||
2283 | } | 2300 | } |
2284 | 2301 | ||
2285 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) | 2302 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) |
@@ -3319,7 +3336,7 @@ static struct tpacpi_led_classdev tpacpi_led_thinklight = { | |||
3319 | 3336 | ||
3320 | static int __init light_init(struct ibm_init_struct *iibm) | 3337 | static int __init light_init(struct ibm_init_struct *iibm) |
3321 | { | 3338 | { |
3322 | int rc = 0; | 3339 | int rc; |
3323 | 3340 | ||
3324 | vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); | 3341 | vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); |
3325 | 3342 | ||
@@ -3337,20 +3354,23 @@ static int __init light_init(struct ibm_init_struct *iibm) | |||
3337 | tp_features.light_status = | 3354 | tp_features.light_status = |
3338 | acpi_evalf(ec_handle, NULL, "KBLT", "qv"); | 3355 | acpi_evalf(ec_handle, NULL, "KBLT", "qv"); |
3339 | 3356 | ||
3340 | vdbg_printk(TPACPI_DBG_INIT, "light is %s\n", | 3357 | vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n", |
3341 | str_supported(tp_features.light)); | 3358 | str_supported(tp_features.light), |
3359 | str_supported(tp_features.light_status)); | ||
3342 | 3360 | ||
3343 | if (tp_features.light) { | 3361 | if (!tp_features.light) |
3344 | rc = led_classdev_register(&tpacpi_pdev->dev, | 3362 | return 1; |
3345 | &tpacpi_led_thinklight.led_classdev); | 3363 | |
3346 | } | 3364 | rc = led_classdev_register(&tpacpi_pdev->dev, |
3365 | &tpacpi_led_thinklight.led_classdev); | ||
3347 | 3366 | ||
3348 | if (rc < 0) { | 3367 | if (rc < 0) { |
3349 | tp_features.light = 0; | 3368 | tp_features.light = 0; |
3350 | tp_features.light_status = 0; | 3369 | tp_features.light_status = 0; |
3351 | } else { | 3370 | } else { |
3352 | rc = (tp_features.light)? 0 : 1; | 3371 | rc = 0; |
3353 | } | 3372 | } |
3373 | |||
3354 | return rc; | 3374 | return rc; |
3355 | } | 3375 | } |
3356 | 3376 | ||
@@ -3833,7 +3853,7 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { | |||
3833 | "tpacpi::standby", | 3853 | "tpacpi::standby", |
3834 | }; | 3854 | }; |
3835 | 3855 | ||
3836 | static int led_get_status(unsigned int led) | 3856 | static int led_get_status(const unsigned int led) |
3837 | { | 3857 | { |
3838 | int status; | 3858 | int status; |
3839 | enum led_status_t led_s; | 3859 | enum led_status_t led_s; |
@@ -3857,41 +3877,42 @@ static int led_get_status(unsigned int led) | |||
3857 | /* not reached */ | 3877 | /* not reached */ |
3858 | } | 3878 | } |
3859 | 3879 | ||
3860 | static int led_set_status(unsigned int led, enum led_status_t ledstatus) | 3880 | static int led_set_status(const unsigned int led, |
3881 | const enum led_status_t ledstatus) | ||
3861 | { | 3882 | { |
3862 | /* off, on, blink. Index is led_status_t */ | 3883 | /* off, on, blink. Index is led_status_t */ |
3863 | static const int led_sled_arg1[] = { 0, 1, 3 }; | 3884 | static const unsigned int led_sled_arg1[] = { 0, 1, 3 }; |
3864 | static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */ | 3885 | static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 }; |
3865 | static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */ | ||
3866 | static const int led_led_arg1[] = { 0, 0x80, 0xc0 }; | ||
3867 | 3886 | ||
3868 | int rc = 0; | 3887 | int rc = 0; |
3869 | 3888 | ||
3870 | switch (led_supported) { | 3889 | switch (led_supported) { |
3871 | case TPACPI_LED_570: | 3890 | case TPACPI_LED_570: |
3872 | /* 570 */ | 3891 | /* 570 */ |
3873 | led = 1 << led; | 3892 | if (led > 7) |
3874 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | 3893 | return -EINVAL; |
3875 | led, led_sled_arg1[ledstatus])) | 3894 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", |
3876 | rc = -EIO; | 3895 | (1 << led), led_sled_arg1[ledstatus])) |
3877 | break; | 3896 | rc = -EIO; |
3897 | break; | ||
3878 | case TPACPI_LED_OLD: | 3898 | case TPACPI_LED_OLD: |
3879 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ | 3899 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ |
3880 | led = 1 << led; | 3900 | if (led > 7) |
3881 | rc = ec_write(TPACPI_LED_EC_HLMS, led); | 3901 | return -EINVAL; |
3882 | if (rc >= 0) | 3902 | rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); |
3883 | rc = ec_write(TPACPI_LED_EC_HLBL, | 3903 | if (rc >= 0) |
3884 | led * led_exp_hlbl[ledstatus]); | 3904 | rc = ec_write(TPACPI_LED_EC_HLBL, |
3885 | if (rc >= 0) | 3905 | (ledstatus == TPACPI_LED_BLINK) << led); |
3886 | rc = ec_write(TPACPI_LED_EC_HLCL, | 3906 | if (rc >= 0) |
3887 | led * led_exp_hlcl[ledstatus]); | 3907 | rc = ec_write(TPACPI_LED_EC_HLCL, |
3888 | break; | 3908 | (ledstatus != TPACPI_LED_OFF) << led); |
3909 | break; | ||
3889 | case TPACPI_LED_NEW: | 3910 | case TPACPI_LED_NEW: |
3890 | /* all others */ | 3911 | /* all others */ |
3891 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | 3912 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", |
3892 | led, led_led_arg1[ledstatus])) | 3913 | led, led_led_arg1[ledstatus])) |
3893 | rc = -EIO; | 3914 | rc = -EIO; |
3894 | break; | 3915 | break; |
3895 | default: | 3916 | default: |
3896 | rc = -ENXIO; | 3917 | rc = -ENXIO; |
3897 | } | 3918 | } |
@@ -3978,7 +3999,6 @@ static void led_exit(void) | |||
3978 | } | 3999 | } |
3979 | 4000 | ||
3980 | kfree(tpacpi_leds); | 4001 | kfree(tpacpi_leds); |
3981 | tpacpi_leds = NULL; | ||
3982 | } | 4002 | } |
3983 | 4003 | ||
3984 | static int __init led_init(struct ibm_init_struct *iibm) | 4004 | static int __init led_init(struct ibm_init_struct *iibm) |
@@ -4802,7 +4822,6 @@ static void brightness_exit(void) | |||
4802 | vdbg_printk(TPACPI_DBG_EXIT, | 4822 | vdbg_printk(TPACPI_DBG_EXIT, |
4803 | "calling backlight_device_unregister()\n"); | 4823 | "calling backlight_device_unregister()\n"); |
4804 | backlight_device_unregister(ibm_backlight_device); | 4824 | backlight_device_unregister(ibm_backlight_device); |
4805 | ibm_backlight_device = NULL; | ||
4806 | } | 4825 | } |
4807 | } | 4826 | } |
4808 | 4827 | ||
@@ -5764,11 +5783,16 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
5764 | fan_control_access_mode != TPACPI_FAN_WR_NONE) { | 5783 | fan_control_access_mode != TPACPI_FAN_WR_NONE) { |
5765 | rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, | 5784 | rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, |
5766 | &fan_attr_group); | 5785 | &fan_attr_group); |
5767 | if (!(rc < 0)) | ||
5768 | rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, | ||
5769 | &driver_attr_fan_watchdog); | ||
5770 | if (rc < 0) | 5786 | if (rc < 0) |
5771 | return rc; | 5787 | return rc; |
5788 | |||
5789 | rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, | ||
5790 | &driver_attr_fan_watchdog); | ||
5791 | if (rc < 0) { | ||
5792 | sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, | ||
5793 | &fan_attr_group); | ||
5794 | return rc; | ||
5795 | } | ||
5772 | return 0; | 5796 | return 0; |
5773 | } else | 5797 | } else |
5774 | return 1; | 5798 | return 1; |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 0201c8adfda7..46c791adb894 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -50,15 +50,17 @@ static int irq_flags(int triggering, int polarity, int shareable) | |||
50 | flags = IORESOURCE_IRQ_HIGHEDGE; | 50 | flags = IORESOURCE_IRQ_HIGHEDGE; |
51 | } | 51 | } |
52 | 52 | ||
53 | if (shareable) | 53 | if (shareable == ACPI_SHARED) |
54 | flags |= IORESOURCE_IRQ_SHAREABLE; | 54 | flags |= IORESOURCE_IRQ_SHAREABLE; |
55 | 55 | ||
56 | return flags; | 56 | return flags; |
57 | } | 57 | } |
58 | 58 | ||
59 | static void decode_irq_flags(int flag, int *triggering, int *polarity) | 59 | static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, |
60 | int *polarity, int *shareable) | ||
60 | { | 61 | { |
61 | switch (flag) { | 62 | switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL | |
63 | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) { | ||
62 | case IORESOURCE_IRQ_LOWLEVEL: | 64 | case IORESOURCE_IRQ_LOWLEVEL: |
63 | *triggering = ACPI_LEVEL_SENSITIVE; | 65 | *triggering = ACPI_LEVEL_SENSITIVE; |
64 | *polarity = ACPI_ACTIVE_LOW; | 66 | *polarity = ACPI_ACTIVE_LOW; |
@@ -75,7 +77,18 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity) | |||
75 | *triggering = ACPI_EDGE_SENSITIVE; | 77 | *triggering = ACPI_EDGE_SENSITIVE; |
76 | *polarity = ACPI_ACTIVE_HIGH; | 78 | *polarity = ACPI_ACTIVE_HIGH; |
77 | break; | 79 | break; |
80 | default: | ||
81 | dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n", | ||
82 | flags); | ||
83 | *triggering = ACPI_EDGE_SENSITIVE; | ||
84 | *polarity = ACPI_ACTIVE_HIGH; | ||
85 | break; | ||
78 | } | 86 | } |
87 | |||
88 | if (flags & IORESOURCE_IRQ_SHAREABLE) | ||
89 | *shareable = ACPI_SHARED; | ||
90 | else | ||
91 | *shareable = ACPI_EXCLUSIVE; | ||
79 | } | 92 | } |
80 | 93 | ||
81 | static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, | 94 | 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 | if (pnpacpi_supported_resource(res)) { | 755 | if (pnpacpi_supported_resource(res)) { |
743 | (*resource)->type = res->type; | 756 | (*resource)->type = res->type; |
744 | (*resource)->length = sizeof(struct acpi_resource); | 757 | (*resource)->length = sizeof(struct acpi_resource); |
758 | if (res->type == ACPI_RESOURCE_TYPE_IRQ) | ||
759 | (*resource)->data.irq.descriptor_length = | ||
760 | res->data.irq.descriptor_length; | ||
745 | (*resource)++; | 761 | (*resource)++; |
746 | } | 762 | } |
747 | 763 | ||
@@ -788,22 +804,21 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, | |||
788 | struct resource *p) | 804 | struct resource *p) |
789 | { | 805 | { |
790 | struct acpi_resource_irq *irq = &resource->data.irq; | 806 | struct acpi_resource_irq *irq = &resource->data.irq; |
791 | int triggering, polarity; | 807 | int triggering, polarity, shareable; |
792 | 808 | ||
793 | decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); | 809 | decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); |
794 | irq->triggering = triggering; | 810 | irq->triggering = triggering; |
795 | irq->polarity = polarity; | 811 | irq->polarity = polarity; |
796 | if (triggering == ACPI_EDGE_SENSITIVE) | 812 | irq->sharable = shareable; |
797 | irq->sharable = ACPI_EXCLUSIVE; | ||
798 | else | ||
799 | irq->sharable = ACPI_SHARED; | ||
800 | irq->interrupt_count = 1; | 813 | irq->interrupt_count = 1; |
801 | irq->interrupts[0] = p->start; | 814 | irq->interrupts[0] = p->start; |
802 | 815 | ||
803 | dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, | 816 | dev_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", |
817 | (int) p->start, | ||
804 | triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", | 818 | triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", |
805 | polarity == ACPI_ACTIVE_LOW ? "low" : "high", | 819 | polarity == ACPI_ACTIVE_LOW ? "low" : "high", |
806 | irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); | 820 | irq->sharable == ACPI_SHARED ? "shared" : "exclusive", |
821 | irq->descriptor_length); | ||
807 | } | 822 | } |
808 | 823 | ||
809 | static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, | 824 | 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 | struct resource *p) | 826 | struct resource *p) |
812 | { | 827 | { |
813 | struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; | 828 | struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; |
814 | int triggering, polarity; | 829 | int triggering, polarity, shareable; |
815 | 830 | ||
816 | decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); | 831 | decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); |
817 | extended_irq->producer_consumer = ACPI_CONSUMER; | 832 | extended_irq->producer_consumer = ACPI_CONSUMER; |
818 | extended_irq->triggering = triggering; | 833 | extended_irq->triggering = triggering; |
819 | extended_irq->polarity = polarity; | 834 | extended_irq->polarity = polarity; |
820 | if (triggering == ACPI_EDGE_SENSITIVE) | 835 | extended_irq->sharable = shareable; |
821 | extended_irq->sharable = ACPI_EXCLUSIVE; | ||
822 | else | ||
823 | extended_irq->sharable = ACPI_SHARED; | ||
824 | extended_irq->interrupt_count = 1; | 836 | extended_irq->interrupt_count = 1; |
825 | extended_irq->interrupts[0] = p->start; | 837 | extended_irq->interrupts[0] = p->start; |
826 | 838 | ||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 06480bcabfdc..06ebb6ef72aa 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
@@ -319,6 +319,7 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) | |||
319 | #endif /* CONFIG_CPU_FREQ */ | 319 | #endif /* CONFIG_CPU_FREQ */ |
320 | 320 | ||
321 | /* in processor_throttling.c */ | 321 | /* in processor_throttling.c */ |
322 | int acpi_processor_tstate_has_changed(struct acpi_processor *pr); | ||
322 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); | 323 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); |
323 | extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state); | 324 | extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state); |
324 | extern struct file_operations acpi_processor_throttling_fops; | 325 | extern struct file_operations acpi_processor_throttling_fops; |
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 51e6b1e520e6..dcf77fa826b5 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
@@ -82,6 +82,7 @@ struct cpuidle_state_kobj { | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | struct cpuidle_device { | 84 | struct cpuidle_device { |
85 | unsigned int registered:1; | ||
85 | unsigned int enabled:1; | 86 | unsigned int enabled:1; |
86 | unsigned int cpu; | 87 | unsigned int cpu; |
87 | 88 | ||
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index d5d40a9f7929..c6801bffe76d 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -53,14 +53,14 @@ struct resource_list { | |||
53 | #define IORESOURCE_AUTO 0x40000000 | 53 | #define IORESOURCE_AUTO 0x40000000 |
54 | #define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ | 54 | #define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ |
55 | 55 | ||
56 | /* ISA PnP IRQ specific bits (IORESOURCE_BITS) */ | 56 | /* PnP IRQ specific bits (IORESOURCE_BITS) */ |
57 | #define IORESOURCE_IRQ_HIGHEDGE (1<<0) | 57 | #define IORESOURCE_IRQ_HIGHEDGE (1<<0) |
58 | #define IORESOURCE_IRQ_LOWEDGE (1<<1) | 58 | #define IORESOURCE_IRQ_LOWEDGE (1<<1) |
59 | #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) | 59 | #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) |
60 | #define IORESOURCE_IRQ_LOWLEVEL (1<<3) | 60 | #define IORESOURCE_IRQ_LOWLEVEL (1<<3) |
61 | #define IORESOURCE_IRQ_SHAREABLE (1<<4) | 61 | #define IORESOURCE_IRQ_SHAREABLE (1<<4) |
62 | 62 | ||
63 | /* ISA PnP DMA specific bits (IORESOURCE_BITS) */ | 63 | /* PnP DMA specific bits (IORESOURCE_BITS) */ |
64 | #define IORESOURCE_DMA_TYPE_MASK (3<<0) | 64 | #define IORESOURCE_DMA_TYPE_MASK (3<<0) |
65 | #define IORESOURCE_DMA_8BIT (0<<0) | 65 | #define IORESOURCE_DMA_8BIT (0<<0) |
66 | #define IORESOURCE_DMA_8AND16BIT (1<<0) | 66 | #define IORESOURCE_DMA_8AND16BIT (1<<0) |
@@ -76,7 +76,7 @@ struct resource_list { | |||
76 | #define IORESOURCE_DMA_TYPEB (2<<6) | 76 | #define IORESOURCE_DMA_TYPEB (2<<6) |
77 | #define IORESOURCE_DMA_TYPEF (3<<6) | 77 | #define IORESOURCE_DMA_TYPEF (3<<6) |
78 | 78 | ||
79 | /* ISA PnP memory I/O specific bits (IORESOURCE_BITS) */ | 79 | /* PnP memory I/O specific bits (IORESOURCE_BITS) */ |
80 | #define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */ | 80 | #define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */ |
81 | #define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */ | 81 | #define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */ |
82 | #define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */ | 82 | #define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */ |