diff options
Diffstat (limited to 'drivers')
150 files changed, 2643 insertions, 2966 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 100bd724f648..3278a210c435 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -91,24 +91,6 @@ config ACPI_EC_DEBUGFS | |||
91 | Thus this option is a debug option that helps to write ACPI drivers | 91 | Thus this option is a debug option that helps to write ACPI drivers |
92 | and can be used to identify ACPI code or EC firmware bugs. | 92 | and can be used to identify ACPI code or EC firmware bugs. |
93 | 93 | ||
94 | config ACPI_PROC_EVENT | ||
95 | bool "Deprecated /proc/acpi/event support" | ||
96 | depends on PROC_FS | ||
97 | default y | ||
98 | help | ||
99 | A user-space daemon, acpid, typically reads /proc/acpi/event | ||
100 | and handles all ACPI-generated events. | ||
101 | |||
102 | These events are now delivered to user-space either | ||
103 | via the input layer or as netlink events. | ||
104 | |||
105 | This build option enables the old code for legacy | ||
106 | user-space implementation. After some time, this will | ||
107 | be moved under CONFIG_ACPI_PROCFS, and then deleted. | ||
108 | |||
109 | Say Y here to retain the old behaviour. Say N if your | ||
110 | user-space is newer than kernel 2.6.23 (September 2007). | ||
111 | |||
112 | config ACPI_AC | 94 | config ACPI_AC |
113 | tristate "AC Adapter" | 95 | tristate "AC Adapter" |
114 | depends on X86 | 96 | depends on X86 |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 4f4e741d34b2..f37beaa32750 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -267,7 +267,6 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) | |||
267 | msleep(ac_sleep_before_get_state_ms); | 267 | msleep(ac_sleep_before_get_state_ms); |
268 | 268 | ||
269 | acpi_ac_get_state(ac); | 269 | acpi_ac_get_state(ac); |
270 | acpi_bus_generate_proc_event(device, event, (u32) ac->state); | ||
271 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 270 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
272 | dev_name(&device->dev), event, | 271 | dev_name(&device->dev), event, |
273 | (u32) ac->state); | 272 | (u32) ac->state); |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 27bb6a91de5f..6230637054c6 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -452,7 +452,6 @@ static void acpi_pad_notify(acpi_handle handle, u32 event, | |||
452 | switch (event) { | 452 | switch (event) { |
453 | case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: | 453 | case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: |
454 | acpi_pad_handle_notify(handle); | 454 | acpi_pad_handle_notify(handle); |
455 | acpi_bus_generate_proc_event(device, event, 0); | ||
456 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 455 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
457 | dev_name(&device->dev), event, 0); | 456 | dev_name(&device->dev), event, 0); |
458 | break; | 457 | break; |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index fafec5ddf17f..1bde12708f9e 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -52,7 +52,7 @@ int acpi_create_platform_device(struct acpi_device *adev, | |||
52 | struct platform_device_info pdevinfo; | 52 | struct platform_device_info pdevinfo; |
53 | struct resource_list_entry *rentry; | 53 | struct resource_list_entry *rentry; |
54 | struct list_head resource_list; | 54 | struct list_head resource_list; |
55 | struct resource *resources; | 55 | struct resource *resources = NULL; |
56 | int count; | 56 | int count; |
57 | 57 | ||
58 | /* If the ACPI node already has a physical device attached, skip it. */ | 58 | /* If the ACPI node already has a physical device attached, skip it. */ |
@@ -61,20 +61,22 @@ int acpi_create_platform_device(struct acpi_device *adev, | |||
61 | 61 | ||
62 | INIT_LIST_HEAD(&resource_list); | 62 | INIT_LIST_HEAD(&resource_list); |
63 | count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); | 63 | count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); |
64 | if (count <= 0) | 64 | if (count < 0) { |
65 | return 0; | 65 | return 0; |
66 | } else if (count > 0) { | ||
67 | resources = kmalloc(count * sizeof(struct resource), | ||
68 | GFP_KERNEL); | ||
69 | if (!resources) { | ||
70 | dev_err(&adev->dev, "No memory for resources\n"); | ||
71 | acpi_dev_free_resource_list(&resource_list); | ||
72 | return -ENOMEM; | ||
73 | } | ||
74 | count = 0; | ||
75 | list_for_each_entry(rentry, &resource_list, node) | ||
76 | resources[count++] = rentry->res; | ||
66 | 77 | ||
67 | resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); | ||
68 | if (!resources) { | ||
69 | dev_err(&adev->dev, "No memory for resources\n"); | ||
70 | acpi_dev_free_resource_list(&resource_list); | 78 | acpi_dev_free_resource_list(&resource_list); |
71 | return -ENOMEM; | ||
72 | } | 79 | } |
73 | count = 0; | ||
74 | list_for_each_entry(rentry, &resource_list, node) | ||
75 | resources[count++] = rentry->res; | ||
76 | |||
77 | acpi_dev_free_resource_list(&resource_list); | ||
78 | 80 | ||
79 | memset(&pdevinfo, 0, sizeof(pdevinfo)); | 81 | memset(&pdevinfo, 0, sizeof(pdevinfo)); |
80 | /* | 82 | /* |
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 5a74a9c1e42c..f29e06efa479 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -178,14 +178,17 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) | |||
178 | if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) | 178 | if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) |
179 | return -ENODEV; | 179 | return -ENODEV; |
180 | 180 | ||
181 | cpu_maps_update_begin(); | ||
182 | cpu_hotplug_begin(); | ||
183 | |||
181 | ret = acpi_map_lsapic(pr->handle, &pr->id); | 184 | ret = acpi_map_lsapic(pr->handle, &pr->id); |
182 | if (ret) | 185 | if (ret) |
183 | return ret; | 186 | goto out; |
184 | 187 | ||
185 | ret = arch_register_cpu(pr->id); | 188 | ret = arch_register_cpu(pr->id); |
186 | if (ret) { | 189 | if (ret) { |
187 | acpi_unmap_lsapic(pr->id); | 190 | acpi_unmap_lsapic(pr->id); |
188 | return ret; | 191 | goto out; |
189 | } | 192 | } |
190 | 193 | ||
191 | /* | 194 | /* |
@@ -195,7 +198,11 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) | |||
195 | */ | 198 | */ |
196 | pr_info("CPU%d has been hot-added\n", pr->id); | 199 | pr_info("CPU%d has been hot-added\n", pr->id); |
197 | pr->flags.need_hotplug_init = 1; | 200 | pr->flags.need_hotplug_init = 1; |
198 | return 0; | 201 | |
202 | out: | ||
203 | cpu_hotplug_done(); | ||
204 | cpu_maps_update_done(); | ||
205 | return ret; | ||
199 | } | 206 | } |
200 | #else | 207 | #else |
201 | static inline int acpi_processor_hotadd_init(struct acpi_processor *pr) | 208 | static inline int acpi_processor_hotadd_init(struct acpi_processor *pr) |
@@ -452,11 +459,15 @@ static void acpi_processor_remove(struct acpi_device *device) | |||
452 | per_cpu(processor_device_array, pr->id) = NULL; | 459 | per_cpu(processor_device_array, pr->id) = NULL; |
453 | per_cpu(processors, pr->id) = NULL; | 460 | per_cpu(processors, pr->id) = NULL; |
454 | 461 | ||
462 | cpu_maps_update_begin(); | ||
463 | cpu_hotplug_begin(); | ||
464 | |||
455 | /* Remove the CPU. */ | 465 | /* Remove the CPU. */ |
456 | get_online_cpus(); | ||
457 | arch_unregister_cpu(pr->id); | 466 | arch_unregister_cpu(pr->id); |
458 | acpi_unmap_lsapic(pr->id); | 467 | acpi_unmap_lsapic(pr->id); |
459 | put_online_cpus(); | 468 | |
469 | cpu_hotplug_done(); | ||
470 | cpu_maps_update_done(); | ||
460 | 471 | ||
461 | try_offline_node(cpu_to_node(pr->id)); | 472 | try_offline_node(cpu_to_node(pr->id)); |
462 | 473 | ||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index b8d38117a20c..90e846f985fa 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -138,6 +138,12 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE); | |||
138 | */ | 138 | */ |
139 | u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_ssdt_table_load, FALSE); | 139 | u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_ssdt_table_load, FALSE); |
140 | 140 | ||
141 | /* | ||
142 | * We keep track of the latest version of Windows that has been requested by | ||
143 | * the BIOS. | ||
144 | */ | ||
145 | u8 ACPI_INIT_GLOBAL(acpi_gbl_osi_data, 0); | ||
146 | |||
141 | /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ | 147 | /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ |
142 | 148 | ||
143 | struct acpi_table_fadt acpi_gbl_FADT; | 149 | struct acpi_table_fadt acpi_gbl_FADT; |
@@ -285,7 +291,6 @@ ACPI_EXTERN u8 acpi_gbl_debugger_configuration; | |||
285 | ACPI_EXTERN u8 acpi_gbl_step_to_next_call; | 291 | ACPI_EXTERN u8 acpi_gbl_step_to_next_call; |
286 | ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; | 292 | ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; |
287 | ACPI_EXTERN u8 acpi_gbl_events_initialized; | 293 | ACPI_EXTERN u8 acpi_gbl_events_initialized; |
288 | ACPI_EXTERN u8 acpi_gbl_osi_data; | ||
289 | ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces; | 294 | ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces; |
290 | ACPI_EXTERN struct acpi_address_range | 295 | ACPI_EXTERN struct acpi_address_range |
291 | *acpi_gbl_address_range_list[ACPI_ADDRESS_RANGE_MAX]; | 296 | *acpi_gbl_address_range_list[ACPI_ADDRESS_RANGE_MAX]; |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index d4a4901637cd..0ed00669cd21 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -942,6 +942,9 @@ struct acpi_interface_info { | |||
942 | 942 | ||
943 | #define ACPI_OSI_INVALID 0x01 | 943 | #define ACPI_OSI_INVALID 0x01 |
944 | #define ACPI_OSI_DYNAMIC 0x02 | 944 | #define ACPI_OSI_DYNAMIC 0x02 |
945 | #define ACPI_OSI_FEATURE 0x04 | ||
946 | #define ACPI_OSI_DEFAULT_INVALID 0x08 | ||
947 | #define ACPI_OSI_OPTIONAL_FEATURE (ACPI_OSI_FEATURE | ACPI_OSI_DEFAULT_INVALID | ACPI_OSI_INVALID) | ||
945 | 948 | ||
946 | struct acpi_port_info { | 949 | struct acpi_port_info { |
947 | char *name; | 950 | char *name; |
@@ -1030,6 +1033,7 @@ struct acpi_external_list { | |||
1030 | u8 type; | 1033 | u8 type; |
1031 | u8 flags; | 1034 | u8 flags; |
1032 | u8 resolved; | 1035 | u8 resolved; |
1036 | u8 emitted; | ||
1033 | }; | 1037 | }; |
1034 | 1038 | ||
1035 | /* Values for Flags field above */ | 1039 | /* Values for Flags field above */ |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index b83dc32a5ae0..40b04bd5579e 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -104,8 +104,8 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
104 | acpi_handle start_object, | 104 | acpi_handle start_object, |
105 | u32 max_depth, | 105 | u32 max_depth, |
106 | u32 flags, | 106 | u32 flags, |
107 | acpi_walk_callback pre_order_visit, | 107 | acpi_walk_callback descending_callback, |
108 | acpi_walk_callback post_order_visit, | 108 | acpi_walk_callback ascending_callback, |
109 | void *context, void **return_value); | 109 | void *context, void **return_value); |
110 | 110 | ||
111 | struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node | 111 | struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node |
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 7755e915a007..c54f42c64fe2 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -47,6 +47,13 @@ | |||
47 | acpi_status acpi_allocate_root_table(u32 initial_table_count); | 47 | acpi_status acpi_allocate_root_table(u32 initial_table_count); |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * tbxfroot - Root pointer utilities | ||
51 | */ | ||
52 | acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | ||
53 | |||
54 | u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); | ||
55 | |||
56 | /* | ||
50 | * tbfadt - FADT parse/convert/validate | 57 | * tbfadt - FADT parse/convert/validate |
51 | */ | 58 | */ |
52 | void acpi_tb_parse_fadt(u32 table_index); | 59 | void acpi_tb_parse_fadt(u32 table_index); |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 3c76edea6803..d5a62a6182bb 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -470,6 +470,8 @@ acpi_status acpi_ut_install_interface(acpi_string interface_name); | |||
470 | 470 | ||
471 | acpi_status acpi_ut_remove_interface(acpi_string interface_name); | 471 | acpi_status acpi_ut_remove_interface(acpi_string interface_name); |
472 | 472 | ||
473 | acpi_status acpi_ut_update_interfaces(u8 action); | ||
474 | |||
473 | struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name); | 475 | struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name); |
474 | 476 | ||
475 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); | 477 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); |
@@ -616,7 +618,7 @@ int acpi_ut_stricmp(char *string1, char *string2); | |||
616 | 618 | ||
617 | acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer); | 619 | acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer); |
618 | 620 | ||
619 | void acpi_ut_print_string(char *string, u8 max_length); | 621 | void acpi_ut_print_string(char *string, u16 max_length); |
620 | 622 | ||
621 | void ut_convert_backslashes(char *pathname); | 623 | void ut_convert_backslashes(char *pathname); |
622 | 624 | ||
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 9037f17c9608..7842700346a4 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -125,7 +125,6 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
125 | /* GPE block 0 exists (has both length and address > 0) */ | 125 | /* GPE block 0 exists (has both length and address > 0) */ |
126 | 126 | ||
127 | register_count0 = (u16)(acpi_gbl_FADT.gpe0_block_length / 2); | 127 | register_count0 = (u16)(acpi_gbl_FADT.gpe0_block_length / 2); |
128 | |||
129 | gpe_number_max = | 128 | gpe_number_max = |
130 | (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; | 129 | (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; |
131 | 130 | ||
@@ -204,16 +203,6 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
204 | goto cleanup; | 203 | goto cleanup; |
205 | } | 204 | } |
206 | 205 | ||
207 | /* Check for Max GPE number out-of-range */ | ||
208 | |||
209 | if (gpe_number_max > ACPI_GPE_MAX) { | ||
210 | ACPI_ERROR((AE_INFO, | ||
211 | "Maximum GPE number from FADT is too large: 0x%X", | ||
212 | gpe_number_max)); | ||
213 | status = AE_BAD_VALUE; | ||
214 | goto cleanup; | ||
215 | } | ||
216 | |||
217 | cleanup: | 206 | cleanup: |
218 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 207 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
219 | return_ACPI_STATUS(AE_OK); | 208 | return_ACPI_STATUS(AE_OK); |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index c740f24e3101..4d046faac48c 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -338,6 +338,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
338 | { | 338 | { |
339 | u8 *target; | 339 | u8 *target; |
340 | char *name; | 340 | char *name; |
341 | const char *reference_name; | ||
341 | u8 count; | 342 | u8 count; |
342 | 343 | ||
343 | if (!info) { | 344 | if (!info) { |
@@ -426,10 +427,9 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
426 | 427 | ||
427 | case ACPI_EXD_REFERENCE: | 428 | case ACPI_EXD_REFERENCE: |
428 | 429 | ||
430 | reference_name = acpi_ut_get_reference_name(obj_desc); | ||
429 | acpi_ex_out_string("Class Name", | 431 | acpi_ex_out_string("Class Name", |
430 | ACPI_CAST_PTR(char, | 432 | ACPI_CAST_PTR(char, reference_name)); |
431 | acpi_ut_get_reference_name | ||
432 | (obj_desc))); | ||
433 | acpi_ex_dump_reference_obj(obj_desc); | 433 | acpi_ex_dump_reference_obj(obj_desc); |
434 | break; | 434 | break; |
435 | 435 | ||
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 814b4a3d656a..2cdd41d8ade6 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c | |||
@@ -962,10 +962,17 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
962 | */ | 962 | */ |
963 | return_desc = | 963 | return_desc = |
964 | *(operand[0]->reference.where); | 964 | *(operand[0]->reference.where); |
965 | if (return_desc) { | 965 | if (!return_desc) { |
966 | acpi_ut_add_reference | 966 | /* |
967 | (return_desc); | 967 | * Element is NULL, do not allow the dereference. |
968 | * This provides compatibility with other ACPI | ||
969 | * implementations. | ||
970 | */ | ||
971 | return_ACPI_STATUS | ||
972 | (AE_AML_UNINITIALIZED_ELEMENT); | ||
968 | } | 973 | } |
974 | |||
975 | acpi_ut_add_reference(return_desc); | ||
969 | break; | 976 | break; |
970 | 977 | ||
971 | default: | 978 | default: |
@@ -990,11 +997,40 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
990 | acpi_namespace_node | 997 | acpi_namespace_node |
991 | *) | 998 | *) |
992 | return_desc); | 999 | return_desc); |
993 | } | 1000 | if (!return_desc) { |
1001 | break; | ||
1002 | } | ||
994 | 1003 | ||
995 | /* Add another reference to the object! */ | 1004 | /* |
1005 | * June 2013: | ||
1006 | * buffer_fields/field_units require additional resolution | ||
1007 | */ | ||
1008 | switch (return_desc->common.type) { | ||
1009 | case ACPI_TYPE_BUFFER_FIELD: | ||
1010 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
1011 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
1012 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
996 | 1013 | ||
997 | acpi_ut_add_reference(return_desc); | 1014 | status = |
1015 | acpi_ex_read_data_from_field | ||
1016 | (walk_state, return_desc, | ||
1017 | &temp_desc); | ||
1018 | if (ACPI_FAILURE(status)) { | ||
1019 | goto cleanup; | ||
1020 | } | ||
1021 | |||
1022 | return_desc = temp_desc; | ||
1023 | break; | ||
1024 | |||
1025 | default: | ||
1026 | |||
1027 | /* Add another reference to the object */ | ||
1028 | |||
1029 | acpi_ut_add_reference | ||
1030 | (return_desc); | ||
1031 | break; | ||
1032 | } | ||
1033 | } | ||
998 | break; | 1034 | break; |
999 | 1035 | ||
1000 | default: | 1036 | default: |
diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index 5e5f76230f5e..414076818d40 100644 --- a/drivers/acpi/acpica/hwesleep.c +++ b/drivers/acpi/acpica/hwesleep.c | |||
@@ -43,6 +43,7 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include <linux/acpi.h> | ||
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | 48 | ||
48 | #define _COMPONENT ACPI_HARDWARE | 49 | #define _COMPONENT ACPI_HARDWARE |
@@ -128,6 +129,14 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state) | |||
128 | 129 | ||
129 | ACPI_FLUSH_CPU_CACHE(); | 130 | ACPI_FLUSH_CPU_CACHE(); |
130 | 131 | ||
132 | status = acpi_os_prepare_extended_sleep(sleep_state, | ||
133 | acpi_gbl_sleep_type_a, | ||
134 | acpi_gbl_sleep_type_b); | ||
135 | if (ACPI_SKIP(status)) | ||
136 | return_ACPI_STATUS(AE_OK); | ||
137 | if (ACPI_FAILURE(status)) | ||
138 | return_ACPI_STATUS(status); | ||
139 | |||
131 | /* | 140 | /* |
132 | * Set the SLP_TYP and SLP_EN bits. | 141 | * Set the SLP_TYP and SLP_EN bits. |
133 | * | 142 | * |
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 0c1a8bbd05d6..2d7d22ebc782 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c | |||
@@ -100,8 +100,13 @@ acpi_status acpi_get_timer(u32 * ticks) | |||
100 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 100 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
101 | } | 101 | } |
102 | 102 | ||
103 | status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); | 103 | /* ACPI 5.0A: PM Timer is optional */ |
104 | |||
105 | if (!acpi_gbl_FADT.xpm_timer_block.address) { | ||
106 | return_ACPI_STATUS(AE_SUPPORT); | ||
107 | } | ||
104 | 108 | ||
109 | status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); | ||
105 | return_ACPI_STATUS(status); | 110 | return_ACPI_STATUS(status); |
106 | } | 111 | } |
107 | 112 | ||
@@ -148,6 +153,12 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) | |||
148 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 153 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
149 | } | 154 | } |
150 | 155 | ||
156 | /* ACPI 5.0A: PM Timer is optional */ | ||
157 | |||
158 | if (!acpi_gbl_FADT.xpm_timer_block.address) { | ||
159 | return_ACPI_STATUS(AE_SUPPORT); | ||
160 | } | ||
161 | |||
151 | /* | 162 | /* |
152 | * Compute Tick Delta: | 163 | * Compute Tick Delta: |
153 | * Handle (max one) timer rollovers on 24-bit versus 32-bit timers. | 164 | * Handle (max one) timer rollovers on 24-bit versus 32-bit timers. |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 24b71a01bf93..098e7666cbc9 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -151,6 +151,15 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node, | |||
151 | } | 151 | } |
152 | 152 | ||
153 | /* | 153 | /* |
154 | * | ||
155 | * 4) If there is no return value and it is optional, just return | ||
156 | * AE_OK (_WAK). | ||
157 | */ | ||
158 | if (!(*return_object_ptr)) { | ||
159 | goto exit; | ||
160 | } | ||
161 | |||
162 | /* | ||
154 | * For returned Package objects, check the type of all sub-objects. | 163 | * For returned Package objects, check the type of all sub-objects. |
155 | * Note: Package may have been newly created by call above. | 164 | * Note: Package may have been newly created by call above. |
156 | */ | 165 | */ |
@@ -268,7 +277,12 @@ acpi_ns_check_object_type(struct acpi_evaluate_info *info, | |||
268 | 277 | ||
269 | acpi_ut_get_expected_return_types(type_buffer, expected_btypes); | 278 | acpi_ut_get_expected_return_types(type_buffer, expected_btypes); |
270 | 279 | ||
271 | if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { | 280 | if (!return_object) { |
281 | ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, | ||
282 | info->node_flags, | ||
283 | "Expected return object of type %s", | ||
284 | type_buffer)); | ||
285 | } else if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { | ||
272 | ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, | 286 | ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, |
273 | info->node_flags, | 287 | info->node_flags, |
274 | "Return type mismatch - found %s, expected %s", | 288 | "Return type mismatch - found %s, expected %s", |
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index e70911a9e441..e81f15ef659a 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c | |||
@@ -156,9 +156,9 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, | |||
156 | * max_depth - Depth to which search is to reach | 156 | * max_depth - Depth to which search is to reach |
157 | * flags - Whether to unlock the NS before invoking | 157 | * flags - Whether to unlock the NS before invoking |
158 | * the callback routine | 158 | * the callback routine |
159 | * pre_order_visit - Called during tree pre-order visit | 159 | * descending_callback - Called during tree descent |
160 | * when an object of "Type" is found | 160 | * when an object of "Type" is found |
161 | * post_order_visit - Called during tree post-order visit | 161 | * ascending_callback - Called during tree ascent |
162 | * when an object of "Type" is found | 162 | * when an object of "Type" is found |
163 | * context - Passed to user function(s) above | 163 | * context - Passed to user function(s) above |
164 | * return_value - from the user_function if terminated | 164 | * return_value - from the user_function if terminated |
@@ -185,8 +185,8 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
185 | acpi_handle start_node, | 185 | acpi_handle start_node, |
186 | u32 max_depth, | 186 | u32 max_depth, |
187 | u32 flags, | 187 | u32 flags, |
188 | acpi_walk_callback pre_order_visit, | 188 | acpi_walk_callback descending_callback, |
189 | acpi_walk_callback post_order_visit, | 189 | acpi_walk_callback ascending_callback, |
190 | void *context, void **return_value) | 190 | void *context, void **return_value) |
191 | { | 191 | { |
192 | acpi_status status; | 192 | acpi_status status; |
@@ -255,22 +255,22 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
255 | } | 255 | } |
256 | 256 | ||
257 | /* | 257 | /* |
258 | * Invoke the user function, either pre-order or post-order | 258 | * Invoke the user function, either descending, ascending, |
259 | * or both. | 259 | * or both. |
260 | */ | 260 | */ |
261 | if (!node_previously_visited) { | 261 | if (!node_previously_visited) { |
262 | if (pre_order_visit) { | 262 | if (descending_callback) { |
263 | status = | 263 | status = |
264 | pre_order_visit(child_node, level, | 264 | descending_callback(child_node, |
265 | context, | 265 | level, context, |
266 | return_value); | 266 | return_value); |
267 | } | 267 | } |
268 | } else { | 268 | } else { |
269 | if (post_order_visit) { | 269 | if (ascending_callback) { |
270 | status = | 270 | status = |
271 | post_order_visit(child_node, level, | 271 | ascending_callback(child_node, |
272 | context, | 272 | level, context, |
273 | return_value); | 273 | return_value); |
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index f553cfdb71dd..b38b4b07f86e 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -533,9 +533,9 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) | |||
533 | * PARAMETERS: type - acpi_object_type to search for | 533 | * PARAMETERS: type - acpi_object_type to search for |
534 | * start_object - Handle in namespace where search begins | 534 | * start_object - Handle in namespace where search begins |
535 | * max_depth - Depth to which search is to reach | 535 | * max_depth - Depth to which search is to reach |
536 | * pre_order_visit - Called during tree pre-order visit | 536 | * descending_callback - Called during tree descent |
537 | * when an object of "Type" is found | 537 | * when an object of "Type" is found |
538 | * post_order_visit - Called during tree post-order visit | 538 | * ascending_callback - Called during tree ascent |
539 | * when an object of "Type" is found | 539 | * when an object of "Type" is found |
540 | * context - Passed to user function(s) above | 540 | * context - Passed to user function(s) above |
541 | * return_value - Location where return value of | 541 | * return_value - Location where return value of |
@@ -563,8 +563,8 @@ acpi_status | |||
563 | acpi_walk_namespace(acpi_object_type type, | 563 | acpi_walk_namespace(acpi_object_type type, |
564 | acpi_handle start_object, | 564 | acpi_handle start_object, |
565 | u32 max_depth, | 565 | u32 max_depth, |
566 | acpi_walk_callback pre_order_visit, | 566 | acpi_walk_callback descending_callback, |
567 | acpi_walk_callback post_order_visit, | 567 | acpi_walk_callback ascending_callback, |
568 | void *context, void **return_value) | 568 | void *context, void **return_value) |
569 | { | 569 | { |
570 | acpi_status status; | 570 | acpi_status status; |
@@ -574,7 +574,7 @@ acpi_walk_namespace(acpi_object_type type, | |||
574 | /* Parameter validation */ | 574 | /* Parameter validation */ |
575 | 575 | ||
576 | if ((type > ACPI_TYPE_LOCAL_MAX) || | 576 | if ((type > ACPI_TYPE_LOCAL_MAX) || |
577 | (!max_depth) || (!pre_order_visit && !post_order_visit)) { | 577 | (!max_depth) || (!descending_callback && !ascending_callback)) { |
578 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 578 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
579 | } | 579 | } |
580 | 580 | ||
@@ -606,9 +606,9 @@ acpi_walk_namespace(acpi_object_type type, | |||
606 | } | 606 | } |
607 | 607 | ||
608 | status = acpi_ns_walk_namespace(type, start_object, max_depth, | 608 | status = acpi_ns_walk_namespace(type, start_object, max_depth, |
609 | ACPI_NS_WALK_UNLOCK, pre_order_visit, | 609 | ACPI_NS_WALK_UNLOCK, |
610 | post_order_visit, context, | 610 | descending_callback, ascending_callback, |
611 | return_value); | 611 | context, return_value); |
612 | 612 | ||
613 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 613 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
614 | 614 | ||
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index f3a4d95899f7..83c164434580 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -158,6 +158,7 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) | |||
158 | { | 158 | { |
159 | acpi_status status; | 159 | acpi_status status; |
160 | struct acpi_namespace_node *node; | 160 | struct acpi_namespace_node *node; |
161 | char *node_name; | ||
161 | 162 | ||
162 | /* Parameter validation */ | 163 | /* Parameter validation */ |
163 | 164 | ||
@@ -202,7 +203,8 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) | |||
202 | 203 | ||
203 | /* Just copy the ACPI name from the Node and zero terminate it */ | 204 | /* Just copy the ACPI name from the Node and zero terminate it */ |
204 | 205 | ||
205 | ACPI_MOVE_NAME(buffer->pointer, acpi_ut_get_node_name(node)); | 206 | node_name = acpi_ut_get_node_name(node); |
207 | ACPI_MOVE_NAME(buffer->pointer, node_name); | ||
206 | ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; | 208 | ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; |
207 | status = AE_OK; | 209 | status = AE_OK; |
208 | 210 | ||
@@ -379,9 +381,14 @@ acpi_get_object_info(acpi_handle handle, | |||
379 | * Get extra info for ACPI Device/Processor objects only: | 381 | * Get extra info for ACPI Device/Processor objects only: |
380 | * Run the _STA, _ADR and, sx_w, and _sx_d methods. | 382 | * Run the _STA, _ADR and, sx_w, and _sx_d methods. |
381 | * | 383 | * |
382 | * Note: none of these methods are required, so they may or may | 384 | * Notes: none of these methods are required, so they may or may |
383 | * not be present for this device. The Info->Valid bitfield is used | 385 | * not be present for this device. The Info->Valid bitfield is used |
384 | * to indicate which methods were found and run successfully. | 386 | * to indicate which methods were found and run successfully. |
387 | * | ||
388 | * For _STA, if the method does not exist, then (as per the ACPI | ||
389 | * specification), the returned current_status flags will indicate | ||
390 | * that the device is present/functional/enabled. Otherwise, the | ||
391 | * current_status flags reflect the value returned from _STA. | ||
385 | */ | 392 | */ |
386 | 393 | ||
387 | /* Execute the Device._STA method */ | 394 | /* Execute the Device._STA method */ |
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 33b00d22300a..9d99f2189693 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -117,7 +117,7 @@ static struct acpi_fadt_info fadt_info_table[] = { | |||
117 | ACPI_FADT_OFFSET(pm_timer_block), | 117 | ACPI_FADT_OFFSET(pm_timer_block), |
118 | ACPI_FADT_OFFSET(pm_timer_length), | 118 | ACPI_FADT_OFFSET(pm_timer_length), |
119 | ACPI_PM_TIMER_WIDTH, | 119 | ACPI_PM_TIMER_WIDTH, |
120 | ACPI_FADT_REQUIRED}, | 120 | ACPI_FADT_SEPARATE_LENGTH}, /* ACPI 5.0A: Timer is optional */ |
121 | 121 | ||
122 | {"Gpe0Block", | 122 | {"Gpe0Block", |
123 | ACPI_FADT_OFFSET(xgpe0_block), | 123 | ACPI_FADT_OFFSET(xgpe0_block), |
@@ -574,7 +574,7 @@ static void acpi_tb_validate_fadt(void) | |||
574 | 574 | ||
575 | if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { | 575 | if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { |
576 | /* | 576 | /* |
577 | * Field is required (Pm1a_event, Pm1a_control, pm_timer). | 577 | * Field is required (Pm1a_event, Pm1a_control). |
578 | * Both the address and length must be non-zero. | 578 | * Both the address and length must be non-zero. |
579 | */ | 579 | */ |
580 | if (!address64->address || !length) { | 580 | if (!address64->address || !length) { |
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index 7c2ecfb7c2c3..948c95e80d44 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c | |||
@@ -48,11 +48,6 @@ | |||
48 | #define _COMPONENT ACPI_TABLES | 48 | #define _COMPONENT ACPI_TABLES |
49 | ACPI_MODULE_NAME("tbxfroot") | 49 | ACPI_MODULE_NAME("tbxfroot") |
50 | 50 | ||
51 | /* Local prototypes */ | ||
52 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); | ||
53 | |||
54 | static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | ||
55 | |||
56 | /******************************************************************************* | 51 | /******************************************************************************* |
57 | * | 52 | * |
58 | * FUNCTION: acpi_tb_validate_rsdp | 53 | * FUNCTION: acpi_tb_validate_rsdp |
@@ -64,8 +59,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | |||
64 | * DESCRIPTION: Validate the RSDP (ptr) | 59 | * DESCRIPTION: Validate the RSDP (ptr) |
65 | * | 60 | * |
66 | ******************************************************************************/ | 61 | ******************************************************************************/ |
67 | 62 | acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) | |
68 | static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) | ||
69 | { | 63 | { |
70 | 64 | ||
71 | /* | 65 | /* |
@@ -74,7 +68,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) | |||
74 | * Note: Sometimes there exists more than one RSDP in memory; the valid | 68 | * Note: Sometimes there exists more than one RSDP in memory; the valid |
75 | * RSDP has a valid checksum, all others have an invalid checksum. | 69 | * RSDP has a valid checksum, all others have an invalid checksum. |
76 | */ | 70 | */ |
77 | if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, | 71 | if (ACPI_STRNCMP((char *)rsdp->signature, ACPI_SIG_RSDP, |
78 | sizeof(ACPI_SIG_RSDP) - 1) != 0) { | 72 | sizeof(ACPI_SIG_RSDP) - 1) != 0) { |
79 | 73 | ||
80 | /* Nope, BAD Signature */ | 74 | /* Nope, BAD Signature */ |
@@ -231,7 +225,7 @@ acpi_status acpi_find_root_pointer(acpi_size *table_address) | |||
231 | * DESCRIPTION: Search a block of memory for the RSDP signature | 225 | * DESCRIPTION: Search a block of memory for the RSDP signature |
232 | * | 226 | * |
233 | ******************************************************************************/ | 227 | ******************************************************************************/ |
234 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) | 228 | u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length) |
235 | { | 229 | { |
236 | acpi_status status; | 230 | acpi_status status; |
237 | u8 *mem_rover; | 231 | u8 *mem_rover; |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index ee83adb97b1e..4fd68971019b 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -239,7 +239,8 @@ acpi_ut_evaluate_numeric_object(char *object_name, | |||
239 | * RETURN: Status | 239 | * RETURN: Status |
240 | * | 240 | * |
241 | * DESCRIPTION: Executes _STA for selected device and stores results in | 241 | * DESCRIPTION: Executes _STA for selected device and stores results in |
242 | * *Flags. | 242 | * *Flags. If _STA does not exist, then the device is assumed |
243 | * to be present/functional/enabled (as per the ACPI spec). | ||
243 | * | 244 | * |
244 | * NOTE: Internal function, no parameter validation | 245 | * NOTE: Internal function, no parameter validation |
245 | * | 246 | * |
@@ -257,6 +258,11 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) | |||
257 | ACPI_BTYPE_INTEGER, &obj_desc); | 258 | ACPI_BTYPE_INTEGER, &obj_desc); |
258 | if (ACPI_FAILURE(status)) { | 259 | if (ACPI_FAILURE(status)) { |
259 | if (AE_NOT_FOUND == status) { | 260 | if (AE_NOT_FOUND == status) { |
261 | /* | ||
262 | * if _STA does not exist, then (as per the ACPI specification), | ||
263 | * the returned flags will indicate that the device is present, | ||
264 | * functional, and enabled. | ||
265 | */ | ||
260 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 266 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
261 | "_STA on %4.4s was not found, assuming device is present\n", | 267 | "_STA on %4.4s was not found, assuming device is present\n", |
262 | acpi_ut_get_node_name(device_node))); | 268 | acpi_ut_get_node_name(device_node))); |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index f736448a8606..d6f26bf8a062 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -336,7 +336,6 @@ acpi_status acpi_ut_init_globals(void) | |||
336 | acpi_gbl_trace_dbg_layer = 0; | 336 | acpi_gbl_trace_dbg_layer = 0; |
337 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; | 337 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; |
338 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; | 338 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; |
339 | acpi_gbl_osi_data = 0; | ||
340 | acpi_gbl_osi_mutex = NULL; | 339 | acpi_gbl_osi_mutex = NULL; |
341 | acpi_gbl_reg_methods_executed = FALSE; | 340 | acpi_gbl_reg_methods_executed = FALSE; |
342 | 341 | ||
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 7e807725c636..8856bd37bc76 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c | |||
@@ -77,21 +77,20 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = { | |||
77 | 77 | ||
78 | /* Feature Group Strings */ | 78 | /* Feature Group Strings */ |
79 | 79 | ||
80 | {"Extended Address Space Descriptor", NULL, 0, 0} | 80 | {"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0}, |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * All "optional" feature group strings (features that are implemented | 83 | * All "optional" feature group strings (features that are implemented |
84 | * by the host) should be dynamically added by the host via | 84 | * by the host) should be dynamically modified to VALID by the host via |
85 | * acpi_install_interface and should not be manually added here. | 85 | * acpi_install_interface or acpi_update_interfaces. Such optional feature |
86 | * | 86 | * group strings are set as INVALID by default here. |
87 | * Examples of optional feature group strings: | ||
88 | * | ||
89 | * "Module Device" | ||
90 | * "Processor Device" | ||
91 | * "3.0 Thermal Model" | ||
92 | * "3.0 _SCP Extensions" | ||
93 | * "Processor Aggregator Device" | ||
94 | */ | 87 | */ |
88 | |||
89 | {"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, | ||
90 | {"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, | ||
91 | {"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, | ||
92 | {"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, | ||
93 | {"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0} | ||
95 | }; | 94 | }; |
96 | 95 | ||
97 | /******************************************************************************* | 96 | /******************************************************************************* |
@@ -158,11 +157,20 @@ acpi_status acpi_ut_interface_terminate(void) | |||
158 | while (next_interface) { | 157 | while (next_interface) { |
159 | acpi_gbl_supported_interfaces = next_interface->next; | 158 | acpi_gbl_supported_interfaces = next_interface->next; |
160 | 159 | ||
161 | /* Only interfaces added at runtime can be freed */ | ||
162 | |||
163 | if (next_interface->flags & ACPI_OSI_DYNAMIC) { | 160 | if (next_interface->flags & ACPI_OSI_DYNAMIC) { |
161 | |||
162 | /* Only interfaces added at runtime can be freed */ | ||
163 | |||
164 | ACPI_FREE(next_interface->name); | 164 | ACPI_FREE(next_interface->name); |
165 | ACPI_FREE(next_interface); | 165 | ACPI_FREE(next_interface); |
166 | } else { | ||
167 | /* Interface is in static list. Reset it to invalid or valid. */ | ||
168 | |||
169 | if (next_interface->flags & ACPI_OSI_DEFAULT_INVALID) { | ||
170 | next_interface->flags |= ACPI_OSI_INVALID; | ||
171 | } else { | ||
172 | next_interface->flags &= ~ACPI_OSI_INVALID; | ||
173 | } | ||
166 | } | 174 | } |
167 | 175 | ||
168 | next_interface = acpi_gbl_supported_interfaces; | 176 | next_interface = acpi_gbl_supported_interfaces; |
@@ -278,6 +286,49 @@ acpi_status acpi_ut_remove_interface(acpi_string interface_name) | |||
278 | 286 | ||
279 | /******************************************************************************* | 287 | /******************************************************************************* |
280 | * | 288 | * |
289 | * FUNCTION: acpi_ut_update_interfaces | ||
290 | * | ||
291 | * PARAMETERS: action - Actions to be performed during the | ||
292 | * update | ||
293 | * | ||
294 | * RETURN: Status | ||
295 | * | ||
296 | * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor | ||
297 | * strings or/and feature group strings. | ||
298 | * Caller MUST hold acpi_gbl_osi_mutex | ||
299 | * | ||
300 | ******************************************************************************/ | ||
301 | |||
302 | acpi_status acpi_ut_update_interfaces(u8 action) | ||
303 | { | ||
304 | struct acpi_interface_info *next_interface; | ||
305 | |||
306 | next_interface = acpi_gbl_supported_interfaces; | ||
307 | while (next_interface) { | ||
308 | if (((next_interface->flags & ACPI_OSI_FEATURE) && | ||
309 | (action & ACPI_FEATURE_STRINGS)) || | ||
310 | (!(next_interface->flags & ACPI_OSI_FEATURE) && | ||
311 | (action & ACPI_VENDOR_STRINGS))) { | ||
312 | if (action & ACPI_DISABLE_INTERFACES) { | ||
313 | |||
314 | /* Mark the interfaces as invalid */ | ||
315 | |||
316 | next_interface->flags |= ACPI_OSI_INVALID; | ||
317 | } else { | ||
318 | /* Mark the interfaces as valid */ | ||
319 | |||
320 | next_interface->flags &= ~ACPI_OSI_INVALID; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | next_interface = next_interface->next; | ||
325 | } | ||
326 | |||
327 | return (AE_OK); | ||
328 | } | ||
329 | |||
330 | /******************************************************************************* | ||
331 | * | ||
281 | * FUNCTION: acpi_ut_get_interface | 332 | * FUNCTION: acpi_ut_get_interface |
282 | * | 333 | * |
283 | * PARAMETERS: interface_name - The interface to find | 334 | * PARAMETERS: interface_name - The interface to find |
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index c53759b76a3f..cb1e9cc32d5f 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c | |||
@@ -333,7 +333,8 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) | |||
333 | * FUNCTION: acpi_ut_print_string | 333 | * FUNCTION: acpi_ut_print_string |
334 | * | 334 | * |
335 | * PARAMETERS: string - Null terminated ASCII string | 335 | * PARAMETERS: string - Null terminated ASCII string |
336 | * max_length - Maximum output length | 336 | * max_length - Maximum output length. Used to constrain the |
337 | * length of strings during debug output only. | ||
337 | * | 338 | * |
338 | * RETURN: None | 339 | * RETURN: None |
339 | * | 340 | * |
@@ -342,7 +343,7 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) | |||
342 | * | 343 | * |
343 | ******************************************************************************/ | 344 | ******************************************************************************/ |
344 | 345 | ||
345 | void acpi_ut_print_string(char *string, u8 max_length) | 346 | void acpi_ut_print_string(char *string, u16 max_length) |
346 | { | 347 | { |
347 | u32 i; | 348 | u32 i; |
348 | 349 | ||
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 6505774f223e..03a211e6e26a 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -389,6 +389,34 @@ ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) | |||
389 | 389 | ||
390 | /***************************************************************************** | 390 | /***************************************************************************** |
391 | * | 391 | * |
392 | * FUNCTION: acpi_update_interfaces | ||
393 | * | ||
394 | * PARAMETERS: action - Actions to be performed during the | ||
395 | * update | ||
396 | * | ||
397 | * RETURN: Status | ||
398 | * | ||
399 | * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor | ||
400 | * string or/and feature group strings. | ||
401 | * | ||
402 | ****************************************************************************/ | ||
403 | acpi_status acpi_update_interfaces(u8 action) | ||
404 | { | ||
405 | acpi_status status; | ||
406 | |||
407 | status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); | ||
408 | if (ACPI_FAILURE(status)) { | ||
409 | return (status); | ||
410 | } | ||
411 | |||
412 | status = acpi_ut_update_interfaces(action); | ||
413 | |||
414 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | ||
415 | return (status); | ||
416 | } | ||
417 | |||
418 | /***************************************************************************** | ||
419 | * | ||
392 | * FUNCTION: acpi_check_address_range | 420 | * FUNCTION: acpi_check_address_range |
393 | * | 421 | * |
394 | * PARAMETERS: space_id - Address space ID | 422 | * PARAMETERS: space_id - Address space ID |
@@ -402,6 +430,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) | |||
402 | * ASL operation region address ranges. | 430 | * ASL operation region address ranges. |
403 | * | 431 | * |
404 | ****************************************************************************/ | 432 | ****************************************************************************/ |
433 | |||
405 | u32 | 434 | u32 |
406 | acpi_check_address_range(acpi_adr_space_type space_id, | 435 | acpi_check_address_range(acpi_adr_space_type space_id, |
407 | acpi_physical_address address, | 436 | acpi_physical_address address, |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index d405fbad406a..2c9958cd7a43 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -527,18 +527,14 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
527 | static int acpi_battery_set_alarm(struct acpi_battery *battery) | 527 | static int acpi_battery_set_alarm(struct acpi_battery *battery) |
528 | { | 528 | { |
529 | acpi_status status = 0; | 529 | acpi_status status = 0; |
530 | union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; | ||
531 | struct acpi_object_list arg_list = { 1, &arg0 }; | ||
532 | 530 | ||
533 | if (!acpi_battery_present(battery) || | 531 | if (!acpi_battery_present(battery) || |
534 | !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) | 532 | !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) |
535 | return -ENODEV; | 533 | return -ENODEV; |
536 | 534 | ||
537 | arg0.integer.value = battery->alarm; | ||
538 | |||
539 | mutex_lock(&battery->lock); | 535 | mutex_lock(&battery->lock); |
540 | status = acpi_evaluate_object(battery->device->handle, "_BTP", | 536 | status = acpi_execute_simple_method(battery->device->handle, "_BTP", |
541 | &arg_list, NULL); | 537 | battery->alarm); |
542 | mutex_unlock(&battery->lock); | 538 | mutex_unlock(&battery->lock); |
543 | 539 | ||
544 | if (ACPI_FAILURE(status)) | 540 | if (ACPI_FAILURE(status)) |
@@ -550,12 +546,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) | |||
550 | 546 | ||
551 | static int acpi_battery_init_alarm(struct acpi_battery *battery) | 547 | static int acpi_battery_init_alarm(struct acpi_battery *battery) |
552 | { | 548 | { |
553 | acpi_status status = AE_OK; | ||
554 | acpi_handle handle = NULL; | ||
555 | |||
556 | /* See if alarms are supported, and if so, set default */ | 549 | /* See if alarms are supported, and if so, set default */ |
557 | status = acpi_get_handle(battery->device->handle, "_BTP", &handle); | 550 | if (!acpi_has_method(battery->device->handle, "_BTP")) { |
558 | if (ACPI_FAILURE(status)) { | ||
559 | clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); | 551 | clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); |
560 | return 0; | 552 | return 0; |
561 | } | 553 | } |
@@ -1036,8 +1028,6 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) | |||
1036 | if (event == ACPI_BATTERY_NOTIFY_INFO) | 1028 | if (event == ACPI_BATTERY_NOTIFY_INFO) |
1037 | acpi_battery_refresh(battery); | 1029 | acpi_battery_refresh(battery); |
1038 | acpi_battery_update(battery); | 1030 | acpi_battery_update(battery); |
1039 | acpi_bus_generate_proc_event(device, event, | ||
1040 | acpi_battery_present(battery)); | ||
1041 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 1031 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
1042 | dev_name(&device->dev), event, | 1032 | dev_name(&device->dev), event, |
1043 | acpi_battery_present(battery)); | 1033 | acpi_battery_present(battery)); |
@@ -1068,7 +1058,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
1068 | { | 1058 | { |
1069 | int result = 0; | 1059 | int result = 0; |
1070 | struct acpi_battery *battery = NULL; | 1060 | struct acpi_battery *battery = NULL; |
1071 | acpi_handle handle; | 1061 | |
1072 | if (!device) | 1062 | if (!device) |
1073 | return -EINVAL; | 1063 | return -EINVAL; |
1074 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); | 1064 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); |
@@ -1080,8 +1070,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
1080 | device->driver_data = battery; | 1070 | device->driver_data = battery; |
1081 | mutex_init(&battery->lock); | 1071 | mutex_init(&battery->lock); |
1082 | mutex_init(&battery->sysfs_lock); | 1072 | mutex_init(&battery->sysfs_lock); |
1083 | if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, | 1073 | if (acpi_has_method(battery->device->handle, "_BIX")) |
1084 | "_BIX", &handle))) | ||
1085 | set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); | 1074 | set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); |
1086 | result = acpi_battery_update(battery); | 1075 | result = acpi_battery_update(battery); |
1087 | if (result) | 1076 | if (result) |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index cb9629638def..9515f18898b2 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -192,6 +192,12 @@ static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) | |||
192 | acpi_osi_setup("!Windows 2009"); | 192 | acpi_osi_setup("!Windows 2009"); |
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) | ||
196 | { | ||
197 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | ||
198 | acpi_osi_setup("!Windows 2012"); | ||
199 | return 0; | ||
200 | } | ||
195 | 201 | ||
196 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | 202 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { |
197 | { | 203 | { |
@@ -267,6 +273,30 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
267 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), | 273 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), |
268 | }, | 274 | }, |
269 | }, | 275 | }, |
276 | { | ||
277 | .callback = dmi_disable_osi_win8, | ||
278 | .ident = "ASUS Zenbook Prime UX31A", | ||
279 | .matches = { | ||
280 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
281 | DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"), | ||
282 | }, | ||
283 | }, | ||
284 | { | ||
285 | .callback = dmi_disable_osi_win8, | ||
286 | .ident = "Dell Inspiron 15R SE", | ||
287 | .matches = { | ||
288 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
289 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), | ||
290 | }, | ||
291 | }, | ||
292 | { | ||
293 | .callback = dmi_disable_osi_win8, | ||
294 | .ident = "Lenovo ThinkPad Edge E530", | ||
295 | .matches = { | ||
296 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
297 | DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"), | ||
298 | }, | ||
299 | }, | ||
270 | 300 | ||
271 | /* | 301 | /* |
272 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 302 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a5bb33bab448..b587ec8257b2 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -89,27 +89,6 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = { | |||
89 | Device Management | 89 | Device Management |
90 | -------------------------------------------------------------------------- */ | 90 | -------------------------------------------------------------------------- */ |
91 | 91 | ||
92 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | ||
93 | { | ||
94 | acpi_status status; | ||
95 | |||
96 | if (!device) | ||
97 | return -EINVAL; | ||
98 | |||
99 | /* TBD: Support fixed-feature devices */ | ||
100 | |||
101 | status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device); | ||
102 | if (ACPI_FAILURE(status) || !*device) { | ||
103 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", | ||
104 | handle)); | ||
105 | return -ENODEV; | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | EXPORT_SYMBOL(acpi_bus_get_device); | ||
112 | |||
113 | acpi_status acpi_bus_get_status_handle(acpi_handle handle, | 92 | acpi_status acpi_bus_get_status_handle(acpi_handle handle, |
114 | unsigned long long *sta) | 93 | unsigned long long *sta) |
115 | { | 94 | { |
@@ -346,104 +325,6 @@ static void acpi_bus_osc_support(void) | |||
346 | } | 325 | } |
347 | 326 | ||
348 | /* -------------------------------------------------------------------------- | 327 | /* -------------------------------------------------------------------------- |
349 | Event Management | ||
350 | -------------------------------------------------------------------------- */ | ||
351 | |||
352 | #ifdef CONFIG_ACPI_PROC_EVENT | ||
353 | static DEFINE_SPINLOCK(acpi_bus_event_lock); | ||
354 | |||
355 | LIST_HEAD(acpi_bus_event_list); | ||
356 | DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); | ||
357 | |||
358 | extern int event_is_open; | ||
359 | |||
360 | int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data) | ||
361 | { | ||
362 | struct acpi_bus_event *event; | ||
363 | unsigned long flags; | ||
364 | |||
365 | /* drop event on the floor if no one's listening */ | ||
366 | if (!event_is_open) | ||
367 | return 0; | ||
368 | |||
369 | event = kzalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC); | ||
370 | if (!event) | ||
371 | return -ENOMEM; | ||
372 | |||
373 | strcpy(event->device_class, device_class); | ||
374 | strcpy(event->bus_id, bus_id); | ||
375 | event->type = type; | ||
376 | event->data = data; | ||
377 | |||
378 | spin_lock_irqsave(&acpi_bus_event_lock, flags); | ||
379 | list_add_tail(&event->node, &acpi_bus_event_list); | ||
380 | spin_unlock_irqrestore(&acpi_bus_event_lock, flags); | ||
381 | |||
382 | wake_up_interruptible(&acpi_bus_event_queue); | ||
383 | |||
384 | return 0; | ||
385 | |||
386 | } | ||
387 | |||
388 | EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4); | ||
389 | |||
390 | int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) | ||
391 | { | ||
392 | if (!device) | ||
393 | return -EINVAL; | ||
394 | return acpi_bus_generate_proc_event4(device->pnp.device_class, | ||
395 | device->pnp.bus_id, type, data); | ||
396 | } | ||
397 | |||
398 | EXPORT_SYMBOL(acpi_bus_generate_proc_event); | ||
399 | |||
400 | int acpi_bus_receive_event(struct acpi_bus_event *event) | ||
401 | { | ||
402 | unsigned long flags; | ||
403 | struct acpi_bus_event *entry = NULL; | ||
404 | |||
405 | DECLARE_WAITQUEUE(wait, current); | ||
406 | |||
407 | |||
408 | if (!event) | ||
409 | return -EINVAL; | ||
410 | |||
411 | if (list_empty(&acpi_bus_event_list)) { | ||
412 | |||
413 | set_current_state(TASK_INTERRUPTIBLE); | ||
414 | add_wait_queue(&acpi_bus_event_queue, &wait); | ||
415 | |||
416 | if (list_empty(&acpi_bus_event_list)) | ||
417 | schedule(); | ||
418 | |||
419 | remove_wait_queue(&acpi_bus_event_queue, &wait); | ||
420 | set_current_state(TASK_RUNNING); | ||
421 | |||
422 | if (signal_pending(current)) | ||
423 | return -ERESTARTSYS; | ||
424 | } | ||
425 | |||
426 | spin_lock_irqsave(&acpi_bus_event_lock, flags); | ||
427 | if (!list_empty(&acpi_bus_event_list)) { | ||
428 | entry = list_entry(acpi_bus_event_list.next, | ||
429 | struct acpi_bus_event, node); | ||
430 | list_del(&entry->node); | ||
431 | } | ||
432 | spin_unlock_irqrestore(&acpi_bus_event_lock, flags); | ||
433 | |||
434 | if (!entry) | ||
435 | return -ENODEV; | ||
436 | |||
437 | memcpy(event, entry, sizeof(struct acpi_bus_event)); | ||
438 | |||
439 | kfree(entry); | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | #endif /* CONFIG_ACPI_PROC_EVENT */ | ||
445 | |||
446 | /* -------------------------------------------------------------------------- | ||
447 | Notification Handling | 328 | Notification Handling |
448 | -------------------------------------------------------------------------- */ | 329 | -------------------------------------------------------------------------- */ |
449 | 330 | ||
@@ -499,19 +380,6 @@ static void acpi_bus_check_scope(acpi_handle handle) | |||
499 | */ | 380 | */ |
500 | } | 381 | } |
501 | 382 | ||
502 | static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list); | ||
503 | int register_acpi_bus_notifier(struct notifier_block *nb) | ||
504 | { | ||
505 | return blocking_notifier_chain_register(&acpi_bus_notify_list, nb); | ||
506 | } | ||
507 | EXPORT_SYMBOL_GPL(register_acpi_bus_notifier); | ||
508 | |||
509 | void unregister_acpi_bus_notifier(struct notifier_block *nb) | ||
510 | { | ||
511 | blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb); | ||
512 | } | ||
513 | EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier); | ||
514 | |||
515 | /** | 383 | /** |
516 | * acpi_bus_notify | 384 | * acpi_bus_notify |
517 | * --------------- | 385 | * --------------- |
@@ -525,9 +393,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
525 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", | 393 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", |
526 | type, handle)); | 394 | type, handle)); |
527 | 395 | ||
528 | blocking_notifier_call_chain(&acpi_bus_notify_list, | ||
529 | type, (void *)handle); | ||
530 | |||
531 | switch (type) { | 396 | switch (type) { |
532 | 397 | ||
533 | case ACPI_NOTIFY_BUS_CHECK: | 398 | case ACPI_NOTIFY_BUS_CHECK: |
@@ -593,8 +458,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
593 | static int __init acpi_bus_init_irq(void) | 458 | static int __init acpi_bus_init_irq(void) |
594 | { | 459 | { |
595 | acpi_status status; | 460 | acpi_status status; |
596 | union acpi_object arg = { ACPI_TYPE_INTEGER }; | ||
597 | struct acpi_object_list arg_list = { 1, &arg }; | ||
598 | char *message = NULL; | 461 | char *message = NULL; |
599 | 462 | ||
600 | 463 | ||
@@ -623,9 +486,7 @@ static int __init acpi_bus_init_irq(void) | |||
623 | 486 | ||
624 | printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message); | 487 | printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message); |
625 | 488 | ||
626 | arg.integer.value = acpi_irq_model; | 489 | status = acpi_execute_simple_method(NULL, "\\_PIC", acpi_irq_model); |
627 | |||
628 | status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL); | ||
629 | if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { | 490 | if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { |
630 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC")); | 491 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC")); |
631 | return -ENODEV; | 492 | return -ENODEV; |
@@ -715,7 +576,6 @@ static int __init acpi_bus_init(void) | |||
715 | { | 576 | { |
716 | int result; | 577 | int result; |
717 | acpi_status status; | 578 | acpi_status status; |
718 | extern acpi_status acpi_os_initialize1(void); | ||
719 | 579 | ||
720 | acpi_os_initialize1(); | 580 | acpi_os_initialize1(); |
721 | 581 | ||
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index d2e617b5b3f6..a55773801c5f 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -303,8 +303,6 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
303 | 303 | ||
304 | pm_wakeup_event(&device->dev, 0); | 304 | pm_wakeup_event(&device->dev, 0); |
305 | } | 305 | } |
306 | |||
307 | acpi_bus_generate_proc_event(device, event, ++button->pushed); | ||
308 | break; | 306 | break; |
309 | default: | 307 | default: |
310 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 308 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 4ab807dc8518..59d3202f6b36 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -159,26 +159,29 @@ int acpi_device_set_power(struct acpi_device *device, int state) | |||
159 | int result = 0; | 159 | int result = 0; |
160 | bool cut_power = false; | 160 | bool cut_power = false; |
161 | 161 | ||
162 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) | 162 | if (!device || !device->flags.power_manageable |
163 | || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) | ||
163 | return -EINVAL; | 164 | return -EINVAL; |
164 | 165 | ||
165 | /* Make sure this is a valid target state */ | 166 | /* Make sure this is a valid target state */ |
166 | 167 | ||
167 | if (state == device->power.state) { | 168 | if (state == device->power.state) { |
168 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at %s\n", | 169 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already in %s\n", |
170 | device->pnp.bus_id, | ||
169 | acpi_power_state_string(state))); | 171 | acpi_power_state_string(state))); |
170 | return 0; | 172 | return 0; |
171 | } | 173 | } |
172 | 174 | ||
173 | if (!device->power.states[state].flags.valid) { | 175 | if (!device->power.states[state].flags.valid) { |
174 | printk(KERN_WARNING PREFIX "Device does not support %s\n", | 176 | dev_warn(&device->dev, "Power state %s not supported\n", |
175 | acpi_power_state_string(state)); | 177 | acpi_power_state_string(state)); |
176 | return -ENODEV; | 178 | return -ENODEV; |
177 | } | 179 | } |
178 | if (device->parent && (state < device->parent->power.state)) { | 180 | if (device->parent && (state < device->parent->power.state)) { |
179 | printk(KERN_WARNING PREFIX | 181 | dev_warn(&device->dev, |
180 | "Cannot set device to a higher-powered" | 182 | "Cannot transition to power state %s for parent in %s\n", |
181 | " state than parent\n"); | 183 | acpi_power_state_string(state), |
184 | acpi_power_state_string(device->parent->power.state)); | ||
182 | return -ENODEV; | 185 | return -ENODEV; |
183 | } | 186 | } |
184 | 187 | ||
@@ -191,8 +194,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) | |||
191 | 194 | ||
192 | if (state < device->power.state && state != ACPI_STATE_D0 | 195 | if (state < device->power.state && state != ACPI_STATE_D0 |
193 | && device->power.state >= ACPI_STATE_D3_HOT) { | 196 | && device->power.state >= ACPI_STATE_D3_HOT) { |
194 | printk(KERN_WARNING PREFIX | 197 | dev_warn(&device->dev, |
195 | "Cannot transition to non-D0 state from D3\n"); | 198 | "Cannot transition to non-D0 state from D3\n"); |
196 | return -ENODEV; | 199 | return -ENODEV; |
197 | } | 200 | } |
198 | 201 | ||
@@ -219,10 +222,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) | |||
219 | 222 | ||
220 | end: | 223 | end: |
221 | if (result) { | 224 | if (result) { |
222 | printk(KERN_WARNING PREFIX | 225 | dev_warn(&device->dev, "Failed to change power state to %s\n", |
223 | "Device [%s] failed to transition to %s\n", | 226 | acpi_power_state_string(state)); |
224 | device->pnp.bus_id, | ||
225 | acpi_power_state_string(state)); | ||
226 | } else { | 227 | } else { |
227 | device->power.state = state; | 228 | device->power.state = state; |
228 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 229 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -244,13 +245,6 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
244 | if (result) | 245 | if (result) |
245 | return result; | 246 | return result; |
246 | 247 | ||
247 | if (!device->flags.power_manageable) { | ||
248 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
249 | "Device [%s] is not power manageable\n", | ||
250 | dev_name(&device->dev))); | ||
251 | return -ENODEV; | ||
252 | } | ||
253 | |||
254 | return acpi_device_set_power(device, state); | 248 | return acpi_device_set_power(device, state); |
255 | } | 249 | } |
256 | EXPORT_SYMBOL(acpi_bus_set_power); | 250 | EXPORT_SYMBOL(acpi_bus_set_power); |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 826560753389..05ea4be01a83 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -51,8 +51,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " | |||
51 | " the driver to wait for userspace to write the undock sysfs file " | 51 | " the driver to wait for userspace to write the undock sysfs file " |
52 | " before undocking"); | 52 | " before undocking"); |
53 | 53 | ||
54 | static struct atomic_notifier_head dock_notifier_list; | ||
55 | |||
56 | static const struct acpi_device_id dock_device_ids[] = { | 54 | static const struct acpi_device_id dock_device_ids[] = { |
57 | {"LNXDOCK", 0}, | 55 | {"LNXDOCK", 0}, |
58 | {"", 0}, | 56 | {"", 0}, |
@@ -63,8 +61,6 @@ struct dock_station { | |||
63 | acpi_handle handle; | 61 | acpi_handle handle; |
64 | unsigned long last_dock_time; | 62 | unsigned long last_dock_time; |
65 | u32 flags; | 63 | u32 flags; |
66 | spinlock_t dd_lock; | ||
67 | struct mutex hp_lock; | ||
68 | struct list_head dependent_devices; | 64 | struct list_head dependent_devices; |
69 | 65 | ||
70 | struct list_head sibling; | 66 | struct list_head sibling; |
@@ -91,6 +87,12 @@ struct dock_dependent_device { | |||
91 | #define DOCK_EVENT 3 | 87 | #define DOCK_EVENT 3 |
92 | #define UNDOCK_EVENT 2 | 88 | #define UNDOCK_EVENT 2 |
93 | 89 | ||
90 | enum dock_callback_type { | ||
91 | DOCK_CALL_HANDLER, | ||
92 | DOCK_CALL_FIXUP, | ||
93 | DOCK_CALL_UEVENT, | ||
94 | }; | ||
95 | |||
94 | /***************************************************************************** | 96 | /***************************************************************************** |
95 | * Dock Dependent device functions * | 97 | * Dock Dependent device functions * |
96 | *****************************************************************************/ | 98 | *****************************************************************************/ |
@@ -101,7 +103,7 @@ struct dock_dependent_device { | |||
101 | * | 103 | * |
102 | * Add the dependent device to the dock's dependent device list. | 104 | * Add the dependent device to the dock's dependent device list. |
103 | */ | 105 | */ |
104 | static int | 106 | static int __init |
105 | add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | 107 | add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) |
106 | { | 108 | { |
107 | struct dock_dependent_device *dd; | 109 | struct dock_dependent_device *dd; |
@@ -112,14 +114,21 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | |||
112 | 114 | ||
113 | dd->handle = handle; | 115 | dd->handle = handle; |
114 | INIT_LIST_HEAD(&dd->list); | 116 | INIT_LIST_HEAD(&dd->list); |
115 | |||
116 | spin_lock(&ds->dd_lock); | ||
117 | list_add_tail(&dd->list, &ds->dependent_devices); | 117 | list_add_tail(&dd->list, &ds->dependent_devices); |
118 | spin_unlock(&ds->dd_lock); | ||
119 | 118 | ||
120 | return 0; | 119 | return 0; |
121 | } | 120 | } |
122 | 121 | ||
122 | static void remove_dock_dependent_devices(struct dock_station *ds) | ||
123 | { | ||
124 | struct dock_dependent_device *dd, *aux; | ||
125 | |||
126 | list_for_each_entry_safe(dd, aux, &ds->dependent_devices, list) { | ||
127 | list_del(&dd->list); | ||
128 | kfree(dd); | ||
129 | } | ||
130 | } | ||
131 | |||
123 | /** | 132 | /** |
124 | * dock_init_hotplug - Initialize a hotplug device on a docking station. | 133 | * dock_init_hotplug - Initialize a hotplug device on a docking station. |
125 | * @dd: Dock-dependent device. | 134 | * @dd: Dock-dependent device. |
@@ -135,19 +144,16 @@ static int dock_init_hotplug(struct dock_dependent_device *dd, | |||
135 | int ret = 0; | 144 | int ret = 0; |
136 | 145 | ||
137 | mutex_lock(&hotplug_lock); | 146 | mutex_lock(&hotplug_lock); |
138 | 147 | if (WARN_ON(dd->hp_context)) { | |
139 | if (dd->hp_context) { | ||
140 | ret = -EEXIST; | 148 | ret = -EEXIST; |
141 | } else { | 149 | } else { |
142 | dd->hp_refcount = 1; | 150 | dd->hp_refcount = 1; |
143 | dd->hp_ops = ops; | 151 | dd->hp_ops = ops; |
144 | dd->hp_context = context; | 152 | dd->hp_context = context; |
145 | dd->hp_release = release; | 153 | dd->hp_release = release; |
154 | if (init) | ||
155 | init(context); | ||
146 | } | 156 | } |
147 | |||
148 | if (!WARN_ON(ret) && init) | ||
149 | init(context); | ||
150 | |||
151 | mutex_unlock(&hotplug_lock); | 157 | mutex_unlock(&hotplug_lock); |
152 | return ret; | 158 | return ret; |
153 | } | 159 | } |
@@ -162,27 +168,22 @@ static int dock_init_hotplug(struct dock_dependent_device *dd, | |||
162 | */ | 168 | */ |
163 | static void dock_release_hotplug(struct dock_dependent_device *dd) | 169 | static void dock_release_hotplug(struct dock_dependent_device *dd) |
164 | { | 170 | { |
165 | void (*release)(void *) = NULL; | ||
166 | void *context = NULL; | ||
167 | |||
168 | mutex_lock(&hotplug_lock); | 171 | mutex_lock(&hotplug_lock); |
169 | |||
170 | if (dd->hp_context && !--dd->hp_refcount) { | 172 | if (dd->hp_context && !--dd->hp_refcount) { |
173 | void (*release)(void *) = dd->hp_release; | ||
174 | void *context = dd->hp_context; | ||
175 | |||
171 | dd->hp_ops = NULL; | 176 | dd->hp_ops = NULL; |
172 | context = dd->hp_context; | ||
173 | dd->hp_context = NULL; | 177 | dd->hp_context = NULL; |
174 | release = dd->hp_release; | ||
175 | dd->hp_release = NULL; | 178 | dd->hp_release = NULL; |
179 | if (release) | ||
180 | release(context); | ||
176 | } | 181 | } |
177 | |||
178 | if (release && context) | ||
179 | release(context); | ||
180 | |||
181 | mutex_unlock(&hotplug_lock); | 182 | mutex_unlock(&hotplug_lock); |
182 | } | 183 | } |
183 | 184 | ||
184 | static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, | 185 | static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, |
185 | bool uevent) | 186 | enum dock_callback_type cb_type) |
186 | { | 187 | { |
187 | acpi_notify_handler cb = NULL; | 188 | acpi_notify_handler cb = NULL; |
188 | bool run = false; | 189 | bool run = false; |
@@ -192,8 +193,18 @@ static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, | |||
192 | if (dd->hp_context) { | 193 | if (dd->hp_context) { |
193 | run = true; | 194 | run = true; |
194 | dd->hp_refcount++; | 195 | dd->hp_refcount++; |
195 | if (dd->hp_ops) | 196 | if (dd->hp_ops) { |
196 | cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler; | 197 | switch (cb_type) { |
198 | case DOCK_CALL_FIXUP: | ||
199 | cb = dd->hp_ops->fixup; | ||
200 | break; | ||
201 | case DOCK_CALL_UEVENT: | ||
202 | cb = dd->hp_ops->uevent; | ||
203 | break; | ||
204 | default: | ||
205 | cb = dd->hp_ops->handler; | ||
206 | } | ||
207 | } | ||
197 | } | 208 | } |
198 | 209 | ||
199 | mutex_unlock(&hotplug_lock); | 210 | mutex_unlock(&hotplug_lock); |
@@ -220,63 +231,17 @@ find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | |||
220 | { | 231 | { |
221 | struct dock_dependent_device *dd; | 232 | struct dock_dependent_device *dd; |
222 | 233 | ||
223 | spin_lock(&ds->dd_lock); | 234 | list_for_each_entry(dd, &ds->dependent_devices, list) |
224 | list_for_each_entry(dd, &ds->dependent_devices, list) { | 235 | if (handle == dd->handle) |
225 | if (handle == dd->handle) { | ||
226 | spin_unlock(&ds->dd_lock); | ||
227 | return dd; | 236 | return dd; |
228 | } | 237 | |
229 | } | ||
230 | spin_unlock(&ds->dd_lock); | ||
231 | return NULL; | 238 | return NULL; |
232 | } | 239 | } |
233 | 240 | ||
234 | /***************************************************************************** | 241 | /***************************************************************************** |
235 | * Dock functions * | 242 | * Dock functions * |
236 | *****************************************************************************/ | 243 | *****************************************************************************/ |
237 | /** | 244 | static int __init is_battery(acpi_handle handle) |
238 | * is_dock - see if a device is a dock station | ||
239 | * @handle: acpi handle of the device | ||
240 | * | ||
241 | * If an acpi object has a _DCK method, then it is by definition a dock | ||
242 | * station, so return true. | ||
243 | */ | ||
244 | static int is_dock(acpi_handle handle) | ||
245 | { | ||
246 | acpi_status status; | ||
247 | acpi_handle tmp; | ||
248 | |||
249 | status = acpi_get_handle(handle, "_DCK", &tmp); | ||
250 | if (ACPI_FAILURE(status)) | ||
251 | return 0; | ||
252 | return 1; | ||
253 | } | ||
254 | |||
255 | static int is_ejectable(acpi_handle handle) | ||
256 | { | ||
257 | acpi_status status; | ||
258 | acpi_handle tmp; | ||
259 | |||
260 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
261 | if (ACPI_FAILURE(status)) | ||
262 | return 0; | ||
263 | return 1; | ||
264 | } | ||
265 | |||
266 | static int is_ata(acpi_handle handle) | ||
267 | { | ||
268 | acpi_handle tmp; | ||
269 | |||
270 | if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || | ||
271 | (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || | ||
272 | (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || | ||
273 | (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) | ||
274 | return 1; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int is_battery(acpi_handle handle) | ||
280 | { | 245 | { |
281 | struct acpi_device_info *info; | 246 | struct acpi_device_info *info; |
282 | int ret = 1; | 247 | int ret = 1; |
@@ -292,17 +257,13 @@ static int is_battery(acpi_handle handle) | |||
292 | return ret; | 257 | return ret; |
293 | } | 258 | } |
294 | 259 | ||
295 | static int is_ejectable_bay(acpi_handle handle) | 260 | /* Check whether ACPI object is an ejectable battery or disk bay */ |
261 | static bool __init is_ejectable_bay(acpi_handle handle) | ||
296 | { | 262 | { |
297 | acpi_handle phandle; | 263 | if (acpi_has_method(handle, "_EJ0") && is_battery(handle)) |
264 | return true; | ||
298 | 265 | ||
299 | if (!is_ejectable(handle)) | 266 | return acpi_bay_match(handle); |
300 | return 0; | ||
301 | if (is_battery(handle) || is_ata(handle)) | ||
302 | return 1; | ||
303 | if (!acpi_get_parent(handle, &phandle) && is_ata(phandle)) | ||
304 | return 1; | ||
305 | return 0; | ||
306 | } | 267 | } |
307 | 268 | ||
308 | /** | 269 | /** |
@@ -320,7 +281,7 @@ int is_dock_device(acpi_handle handle) | |||
320 | if (!dock_station_count) | 281 | if (!dock_station_count) |
321 | return 0; | 282 | return 0; |
322 | 283 | ||
323 | if (is_dock(handle)) | 284 | if (acpi_dock_match(handle)) |
324 | return 1; | 285 | return 1; |
325 | 286 | ||
326 | list_for_each_entry(dock_station, &dock_stations, sibling) | 287 | list_for_each_entry(dock_station, &dock_stations, sibling) |
@@ -359,10 +320,8 @@ static int dock_present(struct dock_station *ds) | |||
359 | * handle if one does not exist already. This should cause | 320 | * handle if one does not exist already. This should cause |
360 | * acpi to scan for drivers for the given devices, and call | 321 | * acpi to scan for drivers for the given devices, and call |
361 | * matching driver's add routine. | 322 | * matching driver's add routine. |
362 | * | ||
363 | * Returns a pointer to the acpi_device corresponding to the handle. | ||
364 | */ | 323 | */ |
365 | static struct acpi_device * dock_create_acpi_device(acpi_handle handle) | 324 | static void dock_create_acpi_device(acpi_handle handle) |
366 | { | 325 | { |
367 | struct acpi_device *device; | 326 | struct acpi_device *device; |
368 | int ret; | 327 | int ret; |
@@ -375,10 +334,7 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle) | |||
375 | ret = acpi_bus_scan(handle); | 334 | ret = acpi_bus_scan(handle); |
376 | if (ret) | 335 | if (ret) |
377 | pr_debug("error adding bus, %x\n", -ret); | 336 | pr_debug("error adding bus, %x\n", -ret); |
378 | |||
379 | acpi_bus_get_device(handle, &device); | ||
380 | } | 337 | } |
381 | return device; | ||
382 | } | 338 | } |
383 | 339 | ||
384 | /** | 340 | /** |
@@ -397,9 +353,29 @@ static void dock_remove_acpi_device(acpi_handle handle) | |||
397 | } | 353 | } |
398 | 354 | ||
399 | /** | 355 | /** |
400 | * hotplug_dock_devices - insert or remove devices on the dock station | 356 | * hot_remove_dock_devices - Remove dock station devices. |
357 | * @ds: Dock station. | ||
358 | */ | ||
359 | static void hot_remove_dock_devices(struct dock_station *ds) | ||
360 | { | ||
361 | struct dock_dependent_device *dd; | ||
362 | |||
363 | /* | ||
364 | * Walk the list in reverse order so that devices that have been added | ||
365 | * last are removed first (in case there are some indirect dependencies | ||
366 | * between them). | ||
367 | */ | ||
368 | list_for_each_entry_reverse(dd, &ds->dependent_devices, list) | ||
369 | dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); | ||
370 | |||
371 | list_for_each_entry_reverse(dd, &ds->dependent_devices, list) | ||
372 | dock_remove_acpi_device(dd->handle); | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * hotplug_dock_devices - Insert devices on a dock station. | ||
401 | * @ds: the dock station | 377 | * @ds: the dock station |
402 | * @event: either bus check or eject request | 378 | * @event: either bus check or device check request |
403 | * | 379 | * |
404 | * Some devices on the dock station need to have drivers called | 380 | * Some devices on the dock station need to have drivers called |
405 | * to perform hotplug operations after a dock event has occurred. | 381 | * to perform hotplug operations after a dock event has occurred. |
@@ -410,27 +386,21 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
410 | { | 386 | { |
411 | struct dock_dependent_device *dd; | 387 | struct dock_dependent_device *dd; |
412 | 388 | ||
413 | mutex_lock(&ds->hp_lock); | 389 | /* Call driver specific post-dock fixups. */ |
390 | list_for_each_entry(dd, &ds->dependent_devices, list) | ||
391 | dock_hotplug_event(dd, event, DOCK_CALL_FIXUP); | ||
414 | 392 | ||
415 | /* | 393 | /* Call driver specific hotplug functions. */ |
416 | * First call driver specific hotplug functions | ||
417 | */ | ||
418 | list_for_each_entry(dd, &ds->dependent_devices, list) | 394 | list_for_each_entry(dd, &ds->dependent_devices, list) |
419 | dock_hotplug_event(dd, event, false); | 395 | dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); |
420 | 396 | ||
421 | /* | 397 | /* |
422 | * Now make sure that an acpi_device is created for each | 398 | * Now make sure that an acpi_device is created for each dependent |
423 | * dependent device, or removed if this is an eject request. | 399 | * device. That will cause scan handlers to be attached to device |
424 | * This will cause acpi_drivers to be stopped/started if they | 400 | * objects or acpi_drivers to be stopped/started if they are present. |
425 | * exist | ||
426 | */ | 401 | */ |
427 | list_for_each_entry(dd, &ds->dependent_devices, list) { | 402 | list_for_each_entry(dd, &ds->dependent_devices, list) |
428 | if (event == ACPI_NOTIFY_EJECT_REQUEST) | 403 | dock_create_acpi_device(dd->handle); |
429 | dock_remove_acpi_device(dd->handle); | ||
430 | else | ||
431 | dock_create_acpi_device(dd->handle); | ||
432 | } | ||
433 | mutex_unlock(&ds->hp_lock); | ||
434 | } | 404 | } |
435 | 405 | ||
436 | static void dock_event(struct dock_station *ds, u32 event, int num) | 406 | static void dock_event(struct dock_station *ds, u32 event, int num) |
@@ -453,44 +423,13 @@ static void dock_event(struct dock_station *ds, u32 event, int num) | |||
453 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | 423 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
454 | 424 | ||
455 | list_for_each_entry(dd, &ds->dependent_devices, list) | 425 | list_for_each_entry(dd, &ds->dependent_devices, list) |
456 | dock_hotplug_event(dd, event, true); | 426 | dock_hotplug_event(dd, event, DOCK_CALL_UEVENT); |
457 | 427 | ||
458 | if (num != DOCK_EVENT) | 428 | if (num != DOCK_EVENT) |
459 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | 429 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
460 | } | 430 | } |
461 | 431 | ||
462 | /** | 432 | /** |
463 | * eject_dock - respond to a dock eject request | ||
464 | * @ds: the dock station | ||
465 | * | ||
466 | * This is called after _DCK is called, to execute the dock station's | ||
467 | * _EJ0 method. | ||
468 | */ | ||
469 | static void eject_dock(struct dock_station *ds) | ||
470 | { | ||
471 | struct acpi_object_list arg_list; | ||
472 | union acpi_object arg; | ||
473 | acpi_status status; | ||
474 | acpi_handle tmp; | ||
475 | |||
476 | /* all dock devices should have _EJ0, but check anyway */ | ||
477 | status = acpi_get_handle(ds->handle, "_EJ0", &tmp); | ||
478 | if (ACPI_FAILURE(status)) { | ||
479 | pr_debug("No _EJ0 support for dock device\n"); | ||
480 | return; | ||
481 | } | ||
482 | |||
483 | arg_list.count = 1; | ||
484 | arg_list.pointer = &arg; | ||
485 | arg.type = ACPI_TYPE_INTEGER; | ||
486 | arg.integer.value = 1; | ||
487 | |||
488 | status = acpi_evaluate_object(ds->handle, "_EJ0", &arg_list, NULL); | ||
489 | if (ACPI_FAILURE(status)) | ||
490 | pr_debug("Failed to evaluate _EJ0!\n"); | ||
491 | } | ||
492 | |||
493 | /** | ||
494 | * handle_dock - handle a dock event | 433 | * handle_dock - handle a dock event |
495 | * @ds: the dock station | 434 | * @ds: the dock station |
496 | * @dock: to dock, or undock - that is the question | 435 | * @dock: to dock, or undock - that is the question |
@@ -550,27 +489,6 @@ static inline void complete_undock(struct dock_station *ds) | |||
550 | ds->flags &= ~(DOCK_UNDOCKING); | 489 | ds->flags &= ~(DOCK_UNDOCKING); |
551 | } | 490 | } |
552 | 491 | ||
553 | static void dock_lock(struct dock_station *ds, int lock) | ||
554 | { | ||
555 | struct acpi_object_list arg_list; | ||
556 | union acpi_object arg; | ||
557 | acpi_status status; | ||
558 | |||
559 | arg_list.count = 1; | ||
560 | arg_list.pointer = &arg; | ||
561 | arg.type = ACPI_TYPE_INTEGER; | ||
562 | arg.integer.value = !!lock; | ||
563 | status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL); | ||
564 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
565 | if (lock) | ||
566 | acpi_handle_warn(ds->handle, | ||
567 | "Locking device failed (0x%x)\n", status); | ||
568 | else | ||
569 | acpi_handle_warn(ds->handle, | ||
570 | "Unlocking device failed (0x%x)\n", status); | ||
571 | } | ||
572 | } | ||
573 | |||
574 | /** | 492 | /** |
575 | * dock_in_progress - see if we are in the middle of handling a dock event | 493 | * dock_in_progress - see if we are in the middle of handling a dock event |
576 | * @ds: the dock station | 494 | * @ds: the dock station |
@@ -588,37 +506,6 @@ static int dock_in_progress(struct dock_station *ds) | |||
588 | } | 506 | } |
589 | 507 | ||
590 | /** | 508 | /** |
591 | * register_dock_notifier - add yourself to the dock notifier list | ||
592 | * @nb: the callers notifier block | ||
593 | * | ||
594 | * If a driver wishes to be notified about dock events, they can | ||
595 | * use this function to put a notifier block on the dock notifier list. | ||
596 | * this notifier call chain will be called after a dock event, but | ||
597 | * before hotplugging any new devices. | ||
598 | */ | ||
599 | int register_dock_notifier(struct notifier_block *nb) | ||
600 | { | ||
601 | if (!dock_station_count) | ||
602 | return -ENODEV; | ||
603 | |||
604 | return atomic_notifier_chain_register(&dock_notifier_list, nb); | ||
605 | } | ||
606 | EXPORT_SYMBOL_GPL(register_dock_notifier); | ||
607 | |||
608 | /** | ||
609 | * unregister_dock_notifier - remove yourself from the dock notifier list | ||
610 | * @nb: the callers notifier block | ||
611 | */ | ||
612 | void unregister_dock_notifier(struct notifier_block *nb) | ||
613 | { | ||
614 | if (!dock_station_count) | ||
615 | return; | ||
616 | |||
617 | atomic_notifier_chain_unregister(&dock_notifier_list, nb); | ||
618 | } | ||
619 | EXPORT_SYMBOL_GPL(unregister_dock_notifier); | ||
620 | |||
621 | /** | ||
622 | * register_hotplug_dock_device - register a hotplug function | 509 | * register_hotplug_dock_device - register a hotplug function |
623 | * @handle: the handle of the device | 510 | * @handle: the handle of the device |
624 | * @ops: handlers to call after docking | 511 | * @ops: handlers to call after docking |
@@ -703,10 +590,10 @@ static int handle_eject_request(struct dock_station *ds, u32 event) | |||
703 | */ | 590 | */ |
704 | dock_event(ds, event, UNDOCK_EVENT); | 591 | dock_event(ds, event, UNDOCK_EVENT); |
705 | 592 | ||
706 | hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); | 593 | hot_remove_dock_devices(ds); |
707 | undock(ds); | 594 | undock(ds); |
708 | dock_lock(ds, 0); | 595 | acpi_evaluate_lck(ds->handle, 0); |
709 | eject_dock(ds); | 596 | acpi_evaluate_ej0(ds->handle); |
710 | if (dock_present(ds)) { | 597 | if (dock_present(ds)) { |
711 | acpi_handle_err(ds->handle, "Unable to undock!\n"); | 598 | acpi_handle_err(ds->handle, "Unable to undock!\n"); |
712 | return -EBUSY; | 599 | return -EBUSY; |
@@ -717,18 +604,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event) | |||
717 | 604 | ||
718 | /** | 605 | /** |
719 | * dock_notify - act upon an acpi dock notification | 606 | * dock_notify - act upon an acpi dock notification |
720 | * @handle: the dock station handle | 607 | * @ds: dock station |
721 | * @event: the acpi event | 608 | * @event: the acpi event |
722 | * @data: our driver data struct | ||
723 | * | 609 | * |
724 | * If we are notified to dock, then check to see if the dock is | 610 | * If we are notified to dock, then check to see if the dock is |
725 | * present and then dock. Notify all drivers of the dock event, | 611 | * present and then dock. Notify all drivers of the dock event, |
726 | * and then hotplug and devices that may need hotplugging. | 612 | * and then hotplug and devices that may need hotplugging. |
727 | */ | 613 | */ |
728 | static void dock_notify(acpi_handle handle, u32 event, void *data) | 614 | static void dock_notify(struct dock_station *ds, u32 event) |
729 | { | 615 | { |
730 | struct dock_station *ds = data; | 616 | acpi_handle handle = ds->handle; |
731 | struct acpi_device *tmp; | 617 | struct acpi_device *ad; |
732 | int surprise_removal = 0; | 618 | int surprise_removal = 0; |
733 | 619 | ||
734 | /* | 620 | /* |
@@ -751,8 +637,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
751 | switch (event) { | 637 | switch (event) { |
752 | case ACPI_NOTIFY_BUS_CHECK: | 638 | case ACPI_NOTIFY_BUS_CHECK: |
753 | case ACPI_NOTIFY_DEVICE_CHECK: | 639 | case ACPI_NOTIFY_DEVICE_CHECK: |
754 | if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle, | 640 | if (!dock_in_progress(ds) && acpi_bus_get_device(handle, &ad)) { |
755 | &tmp)) { | ||
756 | begin_dock(ds); | 641 | begin_dock(ds); |
757 | dock(ds); | 642 | dock(ds); |
758 | if (!dock_present(ds)) { | 643 | if (!dock_present(ds)) { |
@@ -760,12 +645,10 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
760 | complete_dock(ds); | 645 | complete_dock(ds); |
761 | break; | 646 | break; |
762 | } | 647 | } |
763 | atomic_notifier_call_chain(&dock_notifier_list, | ||
764 | event, NULL); | ||
765 | hotplug_dock_devices(ds, event); | 648 | hotplug_dock_devices(ds, event); |
766 | complete_dock(ds); | 649 | complete_dock(ds); |
767 | dock_event(ds, event, DOCK_EVENT); | 650 | dock_event(ds, event, DOCK_EVENT); |
768 | dock_lock(ds, 1); | 651 | acpi_evaluate_lck(ds->handle, 1); |
769 | acpi_update_all_gpes(); | 652 | acpi_update_all_gpes(); |
770 | break; | 653 | break; |
771 | } | 654 | } |
@@ -789,9 +672,8 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
789 | } | 672 | } |
790 | 673 | ||
791 | struct dock_data { | 674 | struct dock_data { |
792 | acpi_handle handle; | ||
793 | unsigned long event; | ||
794 | struct dock_station *ds; | 675 | struct dock_station *ds; |
676 | u32 event; | ||
795 | }; | 677 | }; |
796 | 678 | ||
797 | static void acpi_dock_deferred_cb(void *context) | 679 | static void acpi_dock_deferred_cb(void *context) |
@@ -799,52 +681,31 @@ static void acpi_dock_deferred_cb(void *context) | |||
799 | struct dock_data *data = context; | 681 | struct dock_data *data = context; |
800 | 682 | ||
801 | acpi_scan_lock_acquire(); | 683 | acpi_scan_lock_acquire(); |
802 | dock_notify(data->handle, data->event, data->ds); | 684 | dock_notify(data->ds, data->event); |
803 | acpi_scan_lock_release(); | 685 | acpi_scan_lock_release(); |
804 | kfree(data); | 686 | kfree(data); |
805 | } | 687 | } |
806 | 688 | ||
807 | static int acpi_dock_notifier_call(struct notifier_block *this, | 689 | static void dock_notify_handler(acpi_handle handle, u32 event, void *data) |
808 | unsigned long event, void *data) | ||
809 | { | 690 | { |
810 | struct dock_station *dock_station; | 691 | struct dock_data *dd; |
811 | acpi_handle handle = data; | ||
812 | 692 | ||
813 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK | 693 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK |
814 | && event != ACPI_NOTIFY_EJECT_REQUEST) | 694 | && event != ACPI_NOTIFY_EJECT_REQUEST) |
815 | return 0; | 695 | return; |
816 | |||
817 | acpi_scan_lock_acquire(); | ||
818 | |||
819 | list_for_each_entry(dock_station, &dock_stations, sibling) { | ||
820 | if (dock_station->handle == handle) { | ||
821 | struct dock_data *dd; | ||
822 | acpi_status status; | ||
823 | |||
824 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); | ||
825 | if (!dd) | ||
826 | break; | ||
827 | 696 | ||
828 | dd->handle = handle; | 697 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); |
829 | dd->event = event; | 698 | if (dd) { |
830 | dd->ds = dock_station; | 699 | acpi_status status; |
831 | status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, | ||
832 | dd); | ||
833 | if (ACPI_FAILURE(status)) | ||
834 | kfree(dd); | ||
835 | 700 | ||
836 | break; | 701 | dd->ds = data; |
837 | } | 702 | dd->event = event; |
703 | status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); | ||
704 | if (ACPI_FAILURE(status)) | ||
705 | kfree(dd); | ||
838 | } | 706 | } |
839 | |||
840 | acpi_scan_lock_release(); | ||
841 | return 0; | ||
842 | } | 707 | } |
843 | 708 | ||
844 | static struct notifier_block dock_acpi_notifier = { | ||
845 | .notifier_call = acpi_dock_notifier_call, | ||
846 | }; | ||
847 | |||
848 | /** | 709 | /** |
849 | * find_dock_devices - find devices on the dock station | 710 | * find_dock_devices - find devices on the dock station |
850 | * @handle: the handle of the device we are examining | 711 | * @handle: the handle of the device we are examining |
@@ -856,29 +717,16 @@ static struct notifier_block dock_acpi_notifier = { | |||
856 | * check to see if an object has an _EJD method. If it does, then it | 717 | * check to see if an object has an _EJD method. If it does, then it |
857 | * will see if it is dependent on the dock station. | 718 | * will see if it is dependent on the dock station. |
858 | */ | 719 | */ |
859 | static acpi_status | 720 | static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl, |
860 | find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) | 721 | void *context, void **rv) |
861 | { | 722 | { |
862 | acpi_status status; | ||
863 | acpi_handle tmp, parent; | ||
864 | struct dock_station *ds = context; | 723 | struct dock_station *ds = context; |
724 | acpi_handle ejd = NULL; | ||
865 | 725 | ||
866 | status = acpi_bus_get_ejd(handle, &tmp); | 726 | acpi_bus_get_ejd(handle, &ejd); |
867 | if (ACPI_FAILURE(status)) { | 727 | if (ejd == ds->handle) |
868 | /* try the parent device as well */ | ||
869 | status = acpi_get_parent(handle, &parent); | ||
870 | if (ACPI_FAILURE(status)) | ||
871 | goto fdd_out; | ||
872 | /* see if parent is dependent on dock */ | ||
873 | status = acpi_bus_get_ejd(parent, &tmp); | ||
874 | if (ACPI_FAILURE(status)) | ||
875 | goto fdd_out; | ||
876 | } | ||
877 | |||
878 | if (tmp == ds->handle) | ||
879 | add_dock_dependent_device(ds, handle); | 728 | add_dock_dependent_device(ds, handle); |
880 | 729 | ||
881 | fdd_out: | ||
882 | return AE_OK; | 730 | return AE_OK; |
883 | } | 731 | } |
884 | 732 | ||
@@ -988,13 +836,13 @@ static struct attribute_group dock_attribute_group = { | |||
988 | */ | 836 | */ |
989 | static int __init dock_add(acpi_handle handle) | 837 | static int __init dock_add(acpi_handle handle) |
990 | { | 838 | { |
991 | int ret, id; | 839 | struct dock_station *dock_station, ds = { NULL, }; |
992 | struct dock_station ds, *dock_station; | ||
993 | struct platform_device *dd; | 840 | struct platform_device *dd; |
841 | acpi_status status; | ||
842 | int ret; | ||
994 | 843 | ||
995 | id = dock_station_count; | 844 | dd = platform_device_register_data(NULL, "dock", dock_station_count, |
996 | memset(&ds, 0, sizeof(ds)); | 845 | &ds, sizeof(ds)); |
997 | dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds)); | ||
998 | if (IS_ERR(dd)) | 846 | if (IS_ERR(dd)) |
999 | return PTR_ERR(dd); | 847 | return PTR_ERR(dd); |
1000 | 848 | ||
@@ -1004,18 +852,15 @@ static int __init dock_add(acpi_handle handle) | |||
1004 | dock_station->dock_device = dd; | 852 | dock_station->dock_device = dd; |
1005 | dock_station->last_dock_time = jiffies - HZ; | 853 | dock_station->last_dock_time = jiffies - HZ; |
1006 | 854 | ||
1007 | mutex_init(&dock_station->hp_lock); | ||
1008 | spin_lock_init(&dock_station->dd_lock); | ||
1009 | INIT_LIST_HEAD(&dock_station->sibling); | 855 | INIT_LIST_HEAD(&dock_station->sibling); |
1010 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | ||
1011 | INIT_LIST_HEAD(&dock_station->dependent_devices); | 856 | INIT_LIST_HEAD(&dock_station->dependent_devices); |
1012 | 857 | ||
1013 | /* we want the dock device to send uevents */ | 858 | /* we want the dock device to send uevents */ |
1014 | dev_set_uevent_suppress(&dd->dev, 0); | 859 | dev_set_uevent_suppress(&dd->dev, 0); |
1015 | 860 | ||
1016 | if (is_dock(handle)) | 861 | if (acpi_dock_match(handle)) |
1017 | dock_station->flags |= DOCK_IS_DOCK; | 862 | dock_station->flags |= DOCK_IS_DOCK; |
1018 | if (is_ata(handle)) | 863 | if (acpi_ata_match(handle)) |
1019 | dock_station->flags |= DOCK_IS_ATA; | 864 | dock_station->flags |= DOCK_IS_ATA; |
1020 | if (is_battery(handle)) | 865 | if (is_battery(handle)) |
1021 | dock_station->flags |= DOCK_IS_BAT; | 866 | dock_station->flags |= DOCK_IS_BAT; |
@@ -1034,11 +879,19 @@ static int __init dock_add(acpi_handle handle) | |||
1034 | if (ret) | 879 | if (ret) |
1035 | goto err_rmgroup; | 880 | goto err_rmgroup; |
1036 | 881 | ||
882 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
883 | dock_notify_handler, dock_station); | ||
884 | if (ACPI_FAILURE(status)) { | ||
885 | ret = -ENODEV; | ||
886 | goto err_rmgroup; | ||
887 | } | ||
888 | |||
1037 | dock_station_count++; | 889 | dock_station_count++; |
1038 | list_add(&dock_station->sibling, &dock_stations); | 890 | list_add(&dock_station->sibling, &dock_stations); |
1039 | return 0; | 891 | return 0; |
1040 | 892 | ||
1041 | err_rmgroup: | 893 | err_rmgroup: |
894 | remove_dock_dependent_devices(dock_station); | ||
1042 | sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); | 895 | sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); |
1043 | err_unregister: | 896 | err_unregister: |
1044 | platform_device_unregister(dd); | 897 | platform_device_unregister(dd); |
@@ -1055,10 +908,10 @@ err_unregister: | |||
1055 | * | 908 | * |
1056 | * This is called by acpi_walk_namespace to look for dock stations and bays. | 909 | * This is called by acpi_walk_namespace to look for dock stations and bays. |
1057 | */ | 910 | */ |
1058 | static __init acpi_status | 911 | static acpi_status __init |
1059 | find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) | 912 | find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) |
1060 | { | 913 | { |
1061 | if (is_dock(handle) || is_ejectable_bay(handle)) | 914 | if (acpi_dock_match(handle) || is_ejectable_bay(handle)) |
1062 | dock_add(handle); | 915 | dock_add(handle); |
1063 | 916 | ||
1064 | return AE_OK; | 917 | return AE_OK; |
@@ -1078,7 +931,6 @@ void __init acpi_dock_init(void) | |||
1078 | return; | 931 | return; |
1079 | } | 932 | } |
1080 | 933 | ||
1081 | register_acpi_bus_notifier(&dock_acpi_notifier); | ||
1082 | pr_info(PREFIX "%s: %d docks/bays found\n", | 934 | pr_info(PREFIX "%s: %d docks/bays found\n", |
1083 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); | 935 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); |
1084 | } | 936 | } |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 80403c1a89f8..a06d98374705 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -948,7 +948,7 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) | |||
948 | return 0; | 948 | return 0; |
949 | } | 949 | } |
950 | 950 | ||
951 | static struct dmi_system_id __initdata ec_dmi_table[] = { | 951 | static struct dmi_system_id ec_dmi_table[] __initdata = { |
952 | { | 952 | { |
953 | ec_skip_dsdt_scan, "Compal JFL92", { | 953 | ec_skip_dsdt_scan, "Compal JFL92", { |
954 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | 954 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), |
@@ -987,6 +987,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { | |||
987 | ec_skip_dsdt_scan, "HP Folio 13", { | 987 | ec_skip_dsdt_scan, "HP Folio 13", { |
988 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 988 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
989 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, | 989 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, |
990 | { | ||
991 | ec_validate_ecdt, "ASUS hardware", { | ||
992 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), | ||
993 | DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, | ||
990 | {}, | 994 | {}, |
991 | }; | 995 | }; |
992 | 996 | ||
@@ -1049,10 +1053,8 @@ int __init acpi_ec_ecdt_probe(void) | |||
1049 | * which needs it, has fake EC._INI method, so use it as flag. | 1053 | * which needs it, has fake EC._INI method, so use it as flag. |
1050 | * Keep boot_ec struct as it will be needed soon. | 1054 | * Keep boot_ec struct as it will be needed soon. |
1051 | */ | 1055 | */ |
1052 | acpi_handle dummy; | ||
1053 | if (!dmi_name_in_vendors("ASUS") || | 1056 | if (!dmi_name_in_vendors("ASUS") || |
1054 | ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", | 1057 | !acpi_has_method(boot_ec->handle, "_INI")) |
1055 | &dummy))) | ||
1056 | return -ENODEV; | 1058 | return -ENODEV; |
1057 | } | 1059 | } |
1058 | install: | 1060 | install: |
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index 1442737cedec..8247fcdde079 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c | |||
@@ -21,100 +21,6 @@ | |||
21 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 21 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
22 | ACPI_MODULE_NAME("event"); | 22 | ACPI_MODULE_NAME("event"); |
23 | 23 | ||
24 | #ifdef CONFIG_ACPI_PROC_EVENT | ||
25 | /* Global vars for handling event proc entry */ | ||
26 | static DEFINE_SPINLOCK(acpi_system_event_lock); | ||
27 | int event_is_open = 0; | ||
28 | extern struct list_head acpi_bus_event_list; | ||
29 | extern wait_queue_head_t acpi_bus_event_queue; | ||
30 | |||
31 | static int acpi_system_open_event(struct inode *inode, struct file *file) | ||
32 | { | ||
33 | spin_lock_irq(&acpi_system_event_lock); | ||
34 | |||
35 | if (event_is_open) | ||
36 | goto out_busy; | ||
37 | |||
38 | event_is_open = 1; | ||
39 | |||
40 | spin_unlock_irq(&acpi_system_event_lock); | ||
41 | return 0; | ||
42 | |||
43 | out_busy: | ||
44 | spin_unlock_irq(&acpi_system_event_lock); | ||
45 | return -EBUSY; | ||
46 | } | ||
47 | |||
48 | static ssize_t | ||
49 | acpi_system_read_event(struct file *file, char __user * buffer, size_t count, | ||
50 | loff_t * ppos) | ||
51 | { | ||
52 | int result = 0; | ||
53 | struct acpi_bus_event event; | ||
54 | static char str[ACPI_MAX_STRING]; | ||
55 | static int chars_remaining = 0; | ||
56 | static char *ptr; | ||
57 | |||
58 | if (!chars_remaining) { | ||
59 | memset(&event, 0, sizeof(struct acpi_bus_event)); | ||
60 | |||
61 | if ((file->f_flags & O_NONBLOCK) | ||
62 | && (list_empty(&acpi_bus_event_list))) | ||
63 | return -EAGAIN; | ||
64 | |||
65 | result = acpi_bus_receive_event(&event); | ||
66 | if (result) | ||
67 | return result; | ||
68 | |||
69 | chars_remaining = sprintf(str, "%s %s %08x %08x\n", | ||
70 | event.device_class ? event. | ||
71 | device_class : "<unknown>", | ||
72 | event.bus_id ? event. | ||
73 | bus_id : "<unknown>", event.type, | ||
74 | event.data); | ||
75 | ptr = str; | ||
76 | } | ||
77 | |||
78 | if (chars_remaining < count) { | ||
79 | count = chars_remaining; | ||
80 | } | ||
81 | |||
82 | if (copy_to_user(buffer, ptr, count)) | ||
83 | return -EFAULT; | ||
84 | |||
85 | *ppos += count; | ||
86 | chars_remaining -= count; | ||
87 | ptr += count; | ||
88 | |||
89 | return count; | ||
90 | } | ||
91 | |||
92 | static int acpi_system_close_event(struct inode *inode, struct file *file) | ||
93 | { | ||
94 | spin_lock_irq(&acpi_system_event_lock); | ||
95 | event_is_open = 0; | ||
96 | spin_unlock_irq(&acpi_system_event_lock); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static unsigned int acpi_system_poll_event(struct file *file, poll_table * wait) | ||
101 | { | ||
102 | poll_wait(file, &acpi_bus_event_queue, wait); | ||
103 | if (!list_empty(&acpi_bus_event_list)) | ||
104 | return POLLIN | POLLRDNORM; | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static const struct file_operations acpi_system_event_ops = { | ||
109 | .owner = THIS_MODULE, | ||
110 | .open = acpi_system_open_event, | ||
111 | .read = acpi_system_read_event, | ||
112 | .release = acpi_system_close_event, | ||
113 | .poll = acpi_system_poll_event, | ||
114 | .llseek = default_llseek, | ||
115 | }; | ||
116 | #endif /* CONFIG_ACPI_PROC_EVENT */ | ||
117 | |||
118 | /* ACPI notifier chain */ | 24 | /* ACPI notifier chain */ |
119 | static BLOCKING_NOTIFIER_HEAD(acpi_chain_head); | 25 | static BLOCKING_NOTIFIER_HEAD(acpi_chain_head); |
120 | 26 | ||
@@ -280,9 +186,6 @@ static int acpi_event_genetlink_init(void) | |||
280 | 186 | ||
281 | static int __init acpi_event_init(void) | 187 | static int __init acpi_event_init(void) |
282 | { | 188 | { |
283 | #ifdef CONFIG_ACPI_PROC_EVENT | ||
284 | struct proc_dir_entry *entry; | ||
285 | #endif | ||
286 | int error = 0; | 189 | int error = 0; |
287 | 190 | ||
288 | if (acpi_disabled) | 191 | if (acpi_disabled) |
@@ -293,15 +196,6 @@ static int __init acpi_event_init(void) | |||
293 | if (error) | 196 | if (error) |
294 | printk(KERN_WARNING PREFIX | 197 | printk(KERN_WARNING PREFIX |
295 | "Failed to create genetlink family for ACPI event\n"); | 198 | "Failed to create genetlink family for ACPI event\n"); |
296 | |||
297 | #ifdef CONFIG_ACPI_PROC_EVENT | ||
298 | /* 'event' [R] */ | ||
299 | entry = proc_create("event", S_IRUSR, acpi_root_dir, | ||
300 | &acpi_system_event_ops); | ||
301 | if (!entry) | ||
302 | return -ENODEV; | ||
303 | #endif | ||
304 | |||
305 | return 0; | 199 | return 0; |
306 | } | 200 | } |
307 | 201 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 5b02a0aa540c..41ade6570bc0 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -93,7 +93,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long | |||
93 | if (result) | 93 | if (result) |
94 | return result; | 94 | return result; |
95 | 95 | ||
96 | *state = (acpi_state == ACPI_STATE_D3 ? 0 : | 96 | *state = (acpi_state == ACPI_STATE_D3_COLD ? 0 : |
97 | (acpi_state == ACPI_STATE_D0 ? 1 : -1)); | 97 | (acpi_state == ACPI_STATE_D0 ? 1 : -1)); |
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
@@ -108,7 +108,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) | |||
108 | return -EINVAL; | 108 | return -EINVAL; |
109 | 109 | ||
110 | result = acpi_bus_set_power(device->handle, | 110 | result = acpi_bus_set_power(device->handle, |
111 | state ? ACPI_STATE_D0 : ACPI_STATE_D3); | 111 | state ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD); |
112 | 112 | ||
113 | return result; | 113 | return result; |
114 | } | 114 | } |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 408f6b2a5fa8..94672297e1b1 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -173,6 +173,15 @@ acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge) | |||
173 | } | 173 | } |
174 | EXPORT_SYMBOL_GPL(acpi_find_child); | 174 | EXPORT_SYMBOL_GPL(acpi_find_child); |
175 | 175 | ||
176 | static void acpi_physnode_link_name(char *buf, unsigned int node_id) | ||
177 | { | ||
178 | if (node_id > 0) | ||
179 | snprintf(buf, PHYSICAL_NODE_NAME_SIZE, | ||
180 | PHYSICAL_NODE_STRING "%u", node_id); | ||
181 | else | ||
182 | strcpy(buf, PHYSICAL_NODE_STRING); | ||
183 | } | ||
184 | |||
176 | int acpi_bind_one(struct device *dev, acpi_handle handle) | 185 | int acpi_bind_one(struct device *dev, acpi_handle handle) |
177 | { | 186 | { |
178 | struct acpi_device *acpi_dev; | 187 | struct acpi_device *acpi_dev; |
@@ -216,8 +225,15 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
216 | list_for_each_entry(pn, &acpi_dev->physical_node_list, node) { | 225 | list_for_each_entry(pn, &acpi_dev->physical_node_list, node) { |
217 | /* Sanity check. */ | 226 | /* Sanity check. */ |
218 | if (pn->dev == dev) { | 227 | if (pn->dev == dev) { |
228 | mutex_unlock(&acpi_dev->physical_node_lock); | ||
229 | |||
219 | dev_warn(dev, "Already associated with ACPI node\n"); | 230 | dev_warn(dev, "Already associated with ACPI node\n"); |
220 | goto err_free; | 231 | kfree(physical_node); |
232 | if (ACPI_HANDLE(dev) != handle) | ||
233 | goto err; | ||
234 | |||
235 | put_device(dev); | ||
236 | return 0; | ||
221 | } | 237 | } |
222 | if (pn->node_id == node_id) { | 238 | if (pn->node_id == node_id) { |
223 | physnode_list = &pn->node; | 239 | physnode_list = &pn->node; |
@@ -230,20 +246,23 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
230 | list_add(&physical_node->node, physnode_list); | 246 | list_add(&physical_node->node, physnode_list); |
231 | acpi_dev->physical_node_count++; | 247 | acpi_dev->physical_node_count++; |
232 | 248 | ||
233 | mutex_unlock(&acpi_dev->physical_node_lock); | ||
234 | |||
235 | if (!ACPI_HANDLE(dev)) | 249 | if (!ACPI_HANDLE(dev)) |
236 | ACPI_HANDLE_SET(dev, acpi_dev->handle); | 250 | ACPI_HANDLE_SET(dev, acpi_dev->handle); |
237 | 251 | ||
238 | if (!physical_node->node_id) | 252 | acpi_physnode_link_name(physical_node_name, node_id); |
239 | strcpy(physical_node_name, PHYSICAL_NODE_STRING); | ||
240 | else | ||
241 | sprintf(physical_node_name, | ||
242 | "physical_node%d", physical_node->node_id); | ||
243 | retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | 253 | retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, |
244 | physical_node_name); | 254 | physical_node_name); |
255 | if (retval) | ||
256 | dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n", | ||
257 | physical_node_name, retval); | ||
258 | |||
245 | retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, | 259 | retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, |
246 | "firmware_node"); | 260 | "firmware_node"); |
261 | if (retval) | ||
262 | dev_err(dev, "Failed to create link firmware_node (%d)\n", | ||
263 | retval); | ||
264 | |||
265 | mutex_unlock(&acpi_dev->physical_node_lock); | ||
247 | 266 | ||
248 | if (acpi_dev->wakeup.flags.valid) | 267 | if (acpi_dev->wakeup.flags.valid) |
249 | device_set_wakeup_capable(dev, true); | 268 | device_set_wakeup_capable(dev, true); |
@@ -254,11 +273,6 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
254 | ACPI_HANDLE_SET(dev, NULL); | 273 | ACPI_HANDLE_SET(dev, NULL); |
255 | put_device(dev); | 274 | put_device(dev); |
256 | return retval; | 275 | return retval; |
257 | |||
258 | err_free: | ||
259 | mutex_unlock(&acpi_dev->physical_node_lock); | ||
260 | kfree(physical_node); | ||
261 | goto err; | ||
262 | } | 276 | } |
263 | EXPORT_SYMBOL_GPL(acpi_bind_one); | 277 | EXPORT_SYMBOL_GPL(acpi_bind_one); |
264 | 278 | ||
@@ -267,48 +281,37 @@ int acpi_unbind_one(struct device *dev) | |||
267 | struct acpi_device_physical_node *entry; | 281 | struct acpi_device_physical_node *entry; |
268 | struct acpi_device *acpi_dev; | 282 | struct acpi_device *acpi_dev; |
269 | acpi_status status; | 283 | acpi_status status; |
270 | struct list_head *node, *next; | ||
271 | 284 | ||
272 | if (!ACPI_HANDLE(dev)) | 285 | if (!ACPI_HANDLE(dev)) |
273 | return 0; | 286 | return 0; |
274 | 287 | ||
275 | status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev); | 288 | status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev); |
276 | if (ACPI_FAILURE(status)) | 289 | if (ACPI_FAILURE(status)) { |
277 | goto err; | 290 | dev_err(dev, "Oops, ACPI handle corrupt in %s()\n", __func__); |
291 | return -EINVAL; | ||
292 | } | ||
278 | 293 | ||
279 | mutex_lock(&acpi_dev->physical_node_lock); | 294 | mutex_lock(&acpi_dev->physical_node_lock); |
280 | list_for_each_safe(node, next, &acpi_dev->physical_node_list) { | ||
281 | char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; | ||
282 | 295 | ||
283 | entry = list_entry(node, struct acpi_device_physical_node, | 296 | list_for_each_entry(entry, &acpi_dev->physical_node_list, node) |
284 | node); | 297 | if (entry->dev == dev) { |
285 | if (entry->dev != dev) | 298 | char physnode_name[PHYSICAL_NODE_NAME_SIZE]; |
286 | continue; | ||
287 | 299 | ||
288 | list_del(node); | 300 | list_del(&entry->node); |
301 | acpi_dev->physical_node_count--; | ||
289 | 302 | ||
290 | acpi_dev->physical_node_count--; | 303 | acpi_physnode_link_name(physnode_name, entry->node_id); |
304 | sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name); | ||
305 | sysfs_remove_link(&dev->kobj, "firmware_node"); | ||
306 | ACPI_HANDLE_SET(dev, NULL); | ||
307 | /* acpi_bind_one() increase refcnt by one. */ | ||
308 | put_device(dev); | ||
309 | kfree(entry); | ||
310 | break; | ||
311 | } | ||
291 | 312 | ||
292 | if (!entry->node_id) | ||
293 | strcpy(physical_node_name, PHYSICAL_NODE_STRING); | ||
294 | else | ||
295 | sprintf(physical_node_name, | ||
296 | "physical_node%d", entry->node_id); | ||
297 | |||
298 | sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); | ||
299 | sysfs_remove_link(&dev->kobj, "firmware_node"); | ||
300 | ACPI_HANDLE_SET(dev, NULL); | ||
301 | /* acpi_bind_one increase refcnt by one */ | ||
302 | put_device(dev); | ||
303 | kfree(entry); | ||
304 | } | ||
305 | mutex_unlock(&acpi_dev->physical_node_lock); | 313 | mutex_unlock(&acpi_dev->physical_node_lock); |
306 | |||
307 | return 0; | 314 | return 0; |
308 | |||
309 | err: | ||
310 | dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); | ||
311 | return -EINVAL; | ||
312 | } | 315 | } |
313 | EXPORT_SYMBOL_GPL(acpi_unbind_one); | 316 | EXPORT_SYMBOL_GPL(acpi_unbind_one); |
314 | 317 | ||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 5da44e81dd4d..20f423337e1f 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #define PREFIX "ACPI: " | 24 | #define PREFIX "ACPI: " |
25 | 25 | ||
26 | acpi_status acpi_os_initialize1(void); | ||
26 | int init_acpi_device_notify(void); | 27 | int init_acpi_device_notify(void); |
27 | int acpi_scan_init(void); | 28 | int acpi_scan_init(void); |
28 | #ifdef CONFIG_ACPI_PCI_SLOT | 29 | #ifdef CONFIG_ACPI_PCI_SLOT |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 33e609f63585..2e82e5d76930 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -159,7 +159,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) | |||
159 | * distance than the others. | 159 | * distance than the others. |
160 | * Do some quick checks here and only use the SLIT if it passes. | 160 | * Do some quick checks here and only use the SLIT if it passes. |
161 | */ | 161 | */ |
162 | static __init int slit_valid(struct acpi_table_slit *slit) | 162 | static int __init slit_valid(struct acpi_table_slit *slit) |
163 | { | 163 | { |
164 | int i, j; | 164 | int i, j; |
165 | int d = slit->locality_count; | 165 | int d = slit->locality_count; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6ab2c3505520..e5f416c7f66e 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <acpi/acpi.h> | 52 | #include <acpi/acpi.h> |
53 | #include <acpi/acpi_bus.h> | 53 | #include <acpi/acpi_bus.h> |
54 | #include <acpi/processor.h> | 54 | #include <acpi/processor.h> |
55 | #include "internal.h" | ||
55 | 56 | ||
56 | #define _COMPONENT ACPI_OS_SERVICES | 57 | #define _COMPONENT ACPI_OS_SERVICES |
57 | ACPI_MODULE_NAME("osl"); | 58 | ACPI_MODULE_NAME("osl"); |
@@ -79,6 +80,8 @@ extern char line_buf[80]; | |||
79 | 80 | ||
80 | static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl, | 81 | static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl, |
81 | u32 pm1b_ctrl); | 82 | u32 pm1b_ctrl); |
83 | static int (*__acpi_os_prepare_extended_sleep)(u8 sleep_state, u32 val_a, | ||
84 | u32 val_b); | ||
82 | 85 | ||
83 | static acpi_osd_handler acpi_irq_handler; | 86 | static acpi_osd_handler acpi_irq_handler; |
84 | static void *acpi_irq_context; | 87 | static void *acpi_irq_context; |
@@ -140,7 +143,8 @@ static struct osi_linux { | |||
140 | unsigned int enable:1; | 143 | unsigned int enable:1; |
141 | unsigned int dmi:1; | 144 | unsigned int dmi:1; |
142 | unsigned int cmdline:1; | 145 | unsigned int cmdline:1; |
143 | } osi_linux = {0, 0, 0}; | 146 | unsigned int default_disabling:1; |
147 | } osi_linux = {0, 0, 0, 0}; | ||
144 | 148 | ||
145 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | 149 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) |
146 | { | 150 | { |
@@ -563,10 +567,6 @@ static const char * const table_sigs[] = { | |||
563 | ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT, | 567 | ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT, |
564 | ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL }; | 568 | ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL }; |
565 | 569 | ||
566 | /* Non-fatal errors: Affected tables/files are ignored */ | ||
567 | #define INVALID_TABLE(x, path, name) \ | ||
568 | { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); continue; } | ||
569 | |||
570 | #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) | 570 | #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) |
571 | 571 | ||
572 | /* Must not increase 10 or needs code modification below */ | 572 | /* Must not increase 10 or needs code modification below */ |
@@ -593,9 +593,11 @@ void __init acpi_initrd_override(void *data, size_t size) | |||
593 | data += offset; | 593 | data += offset; |
594 | size -= offset; | 594 | size -= offset; |
595 | 595 | ||
596 | if (file.size < sizeof(struct acpi_table_header)) | 596 | if (file.size < sizeof(struct acpi_table_header)) { |
597 | INVALID_TABLE("Table smaller than ACPI header", | 597 | pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n", |
598 | cpio_path, file.name); | 598 | cpio_path, file.name); |
599 | continue; | ||
600 | } | ||
599 | 601 | ||
600 | table = file.data; | 602 | table = file.data; |
601 | 603 | ||
@@ -603,15 +605,21 @@ void __init acpi_initrd_override(void *data, size_t size) | |||
603 | if (!memcmp(table->signature, table_sigs[sig], 4)) | 605 | if (!memcmp(table->signature, table_sigs[sig], 4)) |
604 | break; | 606 | break; |
605 | 607 | ||
606 | if (!table_sigs[sig]) | 608 | if (!table_sigs[sig]) { |
607 | INVALID_TABLE("Unknown signature", | 609 | pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n", |
608 | cpio_path, file.name); | 610 | cpio_path, file.name); |
609 | if (file.size != table->length) | 611 | continue; |
610 | INVALID_TABLE("File length does not match table length", | 612 | } |
611 | cpio_path, file.name); | 613 | if (file.size != table->length) { |
612 | if (acpi_table_checksum(file.data, table->length)) | 614 | pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n", |
613 | INVALID_TABLE("Bad table checksum", | 615 | cpio_path, file.name); |
614 | cpio_path, file.name); | 616 | continue; |
617 | } | ||
618 | if (acpi_table_checksum(file.data, table->length)) { | ||
619 | pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n", | ||
620 | cpio_path, file.name); | ||
621 | continue; | ||
622 | } | ||
615 | 623 | ||
616 | pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n", | 624 | pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n", |
617 | table->signature, cpio_path, file.name, table->length); | 625 | table->signature, cpio_path, file.name, table->length); |
@@ -1351,8 +1359,8 @@ struct osi_setup_entry { | |||
1351 | bool enable; | 1359 | bool enable; |
1352 | }; | 1360 | }; |
1353 | 1361 | ||
1354 | static struct osi_setup_entry __initdata | 1362 | static struct osi_setup_entry |
1355 | osi_setup_entries[OSI_STRING_ENTRIES_MAX] = { | 1363 | osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { |
1356 | {"Module Device", true}, | 1364 | {"Module Device", true}, |
1357 | {"Processor Device", true}, | 1365 | {"Processor Device", true}, |
1358 | {"3.0 _SCP Extensions", true}, | 1366 | {"3.0 _SCP Extensions", true}, |
@@ -1376,6 +1384,17 @@ void __init acpi_osi_setup(char *str) | |||
1376 | 1384 | ||
1377 | if (*str == '!') { | 1385 | if (*str == '!') { |
1378 | str++; | 1386 | str++; |
1387 | if (*str == '\0') { | ||
1388 | osi_linux.default_disabling = 1; | ||
1389 | return; | ||
1390 | } else if (*str == '*') { | ||
1391 | acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS); | ||
1392 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1393 | osi = &osi_setup_entries[i]; | ||
1394 | osi->enable = false; | ||
1395 | } | ||
1396 | return; | ||
1397 | } | ||
1379 | enable = false; | 1398 | enable = false; |
1380 | } | 1399 | } |
1381 | 1400 | ||
@@ -1441,6 +1460,13 @@ static void __init acpi_osi_setup_late(void) | |||
1441 | int i; | 1460 | int i; |
1442 | acpi_status status; | 1461 | acpi_status status; |
1443 | 1462 | ||
1463 | if (osi_linux.default_disabling) { | ||
1464 | status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS); | ||
1465 | |||
1466 | if (ACPI_SUCCESS(status)) | ||
1467 | printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n"); | ||
1468 | } | ||
1469 | |||
1444 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | 1470 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { |
1445 | osi = &osi_setup_entries[i]; | 1471 | osi = &osi_setup_entries[i]; |
1446 | str = osi->string; | 1472 | str = osi->string; |
@@ -1779,6 +1805,28 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, | |||
1779 | __acpi_os_prepare_sleep = func; | 1805 | __acpi_os_prepare_sleep = func; |
1780 | } | 1806 | } |
1781 | 1807 | ||
1808 | acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a, | ||
1809 | u32 val_b) | ||
1810 | { | ||
1811 | int rc = 0; | ||
1812 | if (__acpi_os_prepare_extended_sleep) | ||
1813 | rc = __acpi_os_prepare_extended_sleep(sleep_state, | ||
1814 | val_a, val_b); | ||
1815 | if (rc < 0) | ||
1816 | return AE_ERROR; | ||
1817 | else if (rc > 0) | ||
1818 | return AE_CTRL_SKIP; | ||
1819 | |||
1820 | return AE_OK; | ||
1821 | } | ||
1822 | |||
1823 | void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state, | ||
1824 | u32 val_a, u32 val_b)) | ||
1825 | { | ||
1826 | __acpi_os_prepare_extended_sleep = func; | ||
1827 | } | ||
1828 | |||
1829 | |||
1782 | void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, | 1830 | void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, |
1783 | void (*func)(struct work_struct *work)) | 1831 | void (*func)(struct work_struct *work)) |
1784 | { | 1832 | { |
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 033d1179bdb5..d678a180ca2a 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c | |||
@@ -159,12 +159,16 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
159 | return AE_OK; | 159 | return AE_OK; |
160 | } | 160 | } |
161 | 161 | ||
162 | void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle) | 162 | void acpi_pci_slot_enumerate(struct pci_bus *bus) |
163 | { | 163 | { |
164 | mutex_lock(&slot_list_lock); | 164 | acpi_handle handle = ACPI_HANDLE(bus->bridge); |
165 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, | 165 | |
166 | register_slot, NULL, bus, NULL); | 166 | if (handle) { |
167 | mutex_unlock(&slot_list_lock); | 167 | mutex_lock(&slot_list_lock); |
168 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, | ||
169 | register_slot, NULL, bus, NULL); | ||
170 | mutex_unlock(&slot_list_lock); | ||
171 | } | ||
168 | } | 172 | } |
169 | 173 | ||
170 | void acpi_pci_slot_remove(struct pci_bus *bus) | 174 | void acpi_pci_slot_remove(struct pci_bus *bus) |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 5c28c894c0fc..0dbe5cdf3396 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -637,9 +637,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev, | |||
637 | } | 637 | } |
638 | 638 | ||
639 | /* Execute _PSW */ | 639 | /* Execute _PSW */ |
640 | arg_list.count = 1; | 640 | status = acpi_execute_simple_method(dev->handle, "_PSW", enable); |
641 | in_arg[0].integer.value = enable; | ||
642 | status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); | ||
643 | if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { | 641 | if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { |
644 | printk(KERN_ERR PREFIX "_PSW execution failed\n"); | 642 | printk(KERN_ERR PREFIX "_PSW execution failed\n"); |
645 | dev->wakeup.flags.valid = 0; | 643 | dev->wakeup.flags.valid = 0; |
@@ -786,7 +784,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) | |||
786 | } | 784 | } |
787 | } | 785 | } |
788 | 786 | ||
789 | *state = ACPI_STATE_D3; | 787 | *state = ACPI_STATE_D3_COLD; |
790 | return 0; | 788 | return 0; |
791 | } | 789 | } |
792 | 790 | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index a5e9f4a5b281..cf34d903f4fb 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -28,7 +28,7 @@ static int __init set_no_mwait(const struct dmi_system_id *id) | |||
28 | return 0; | 28 | return 0; |
29 | } | 29 | } |
30 | 30 | ||
31 | static struct dmi_system_id __initdata processor_idle_dmi_table[] = { | 31 | static struct dmi_system_id processor_idle_dmi_table[] __initdata = { |
32 | { | 32 | { |
33 | set_no_mwait, "Extensa 5220", { | 33 | set_no_mwait, "Extensa 5220", { |
34 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | 34 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 870eaf5fa547..e534ba66d5b8 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -91,21 +91,17 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) | |||
91 | acpi_processor_ppc_has_changed(pr, 1); | 91 | acpi_processor_ppc_has_changed(pr, 1); |
92 | if (saved == pr->performance_platform_limit) | 92 | if (saved == pr->performance_platform_limit) |
93 | break; | 93 | break; |
94 | acpi_bus_generate_proc_event(device, event, | ||
95 | pr->performance_platform_limit); | ||
96 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 94 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
97 | dev_name(&device->dev), event, | 95 | dev_name(&device->dev), event, |
98 | pr->performance_platform_limit); | 96 | pr->performance_platform_limit); |
99 | break; | 97 | break; |
100 | case ACPI_PROCESSOR_NOTIFY_POWER: | 98 | case ACPI_PROCESSOR_NOTIFY_POWER: |
101 | acpi_processor_cst_has_changed(pr); | 99 | acpi_processor_cst_has_changed(pr); |
102 | acpi_bus_generate_proc_event(device, event, 0); | ||
103 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 100 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
104 | dev_name(&device->dev), event, 0); | 101 | dev_name(&device->dev), event, 0); |
105 | break; | 102 | break; |
106 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: | 103 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: |
107 | acpi_processor_tstate_has_changed(pr); | 104 | acpi_processor_tstate_has_changed(pr); |
108 | acpi_bus_generate_proc_event(device, event, 0); | ||
109 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 105 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
110 | dev_name(&device->dev), event, 0); | 106 | dev_name(&device->dev), event, 0); |
111 | break; | 107 | break; |
@@ -179,7 +175,9 @@ static int __acpi_processor_start(struct acpi_device *device) | |||
179 | acpi_processor_load_module(pr); | 175 | acpi_processor_load_module(pr); |
180 | #endif | 176 | #endif |
181 | acpi_processor_get_throttling_info(pr); | 177 | acpi_processor_get_throttling_info(pr); |
182 | acpi_processor_get_limit_info(pr); | 178 | |
179 | if (pr->flags.throttling) | ||
180 | pr->flags.limit = 1; | ||
183 | 181 | ||
184 | if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) | 182 | if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) |
185 | acpi_processor_power_init(pr); | 183 | acpi_processor_power_init(pr); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 1e9732d809bf..51d7948611da 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -164,17 +164,12 @@ static void acpi_processor_ppc_ost(acpi_handle handle, int status) | |||
164 | {.type = ACPI_TYPE_INTEGER,}, | 164 | {.type = ACPI_TYPE_INTEGER,}, |
165 | }; | 165 | }; |
166 | struct acpi_object_list arg_list = {2, params}; | 166 | struct acpi_object_list arg_list = {2, params}; |
167 | acpi_handle temp; | ||
168 | 167 | ||
169 | params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; | 168 | if (acpi_has_method(handle, "_OST")) { |
170 | params[1].integer.value = status; | 169 | params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; |
171 | 170 | params[1].integer.value = status; | |
172 | /* when there is no _OST , skip it */ | 171 | acpi_evaluate_object(handle, "_OST", &arg_list, NULL); |
173 | if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp))) | 172 | } |
174 | return; | ||
175 | |||
176 | acpi_evaluate_object(handle, "_OST", &arg_list, NULL); | ||
177 | return; | ||
178 | } | 173 | } |
179 | 174 | ||
180 | int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) | 175 | int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) |
@@ -468,14 +463,11 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) | |||
468 | int acpi_processor_get_performance_info(struct acpi_processor *pr) | 463 | int acpi_processor_get_performance_info(struct acpi_processor *pr) |
469 | { | 464 | { |
470 | int result = 0; | 465 | int result = 0; |
471 | acpi_status status = AE_OK; | ||
472 | acpi_handle handle = NULL; | ||
473 | 466 | ||
474 | if (!pr || !pr->performance || !pr->handle) | 467 | if (!pr || !pr->performance || !pr->handle) |
475 | return -EINVAL; | 468 | return -EINVAL; |
476 | 469 | ||
477 | status = acpi_get_handle(pr->handle, "_PCT", &handle); | 470 | if (!acpi_has_method(pr->handle, "_PCT")) { |
478 | if (ACPI_FAILURE(status)) { | ||
479 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 471 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
480 | "ACPI-based processor performance control unavailable\n")); | 472 | "ACPI-based processor performance control unavailable\n")); |
481 | return -ENODEV; | 473 | return -ENODEV; |
@@ -501,7 +493,7 @@ int acpi_processor_get_performance_info(struct acpi_processor *pr) | |||
501 | */ | 493 | */ |
502 | update_bios: | 494 | update_bios: |
503 | #ifdef CONFIG_X86 | 495 | #ifdef CONFIG_X86 |
504 | if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){ | 496 | if (acpi_has_method(pr->handle, "_PPC")) { |
505 | if(boot_cpu_has(X86_FEATURE_EST)) | 497 | if(boot_cpu_has(X86_FEATURE_EST)) |
506 | printk(KERN_WARNING FW_BUG "BIOS needs update for CPU " | 498 | printk(KERN_WARNING FW_BUG "BIOS needs update for CPU " |
507 | "frequency support\n"); | 499 | "frequency support\n"); |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index e8e652710e65..d1d2e7fb5b30 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -186,18 +186,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) | |||
186 | 186 | ||
187 | #endif | 187 | #endif |
188 | 188 | ||
189 | int acpi_processor_get_limit_info(struct acpi_processor *pr) | ||
190 | { | ||
191 | |||
192 | if (!pr) | ||
193 | return -EINVAL; | ||
194 | |||
195 | if (pr->flags.throttling) | ||
196 | pr->flags.limit = 1; | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* thermal coolign device callbacks */ | 189 | /* thermal coolign device callbacks */ |
202 | static int acpi_processor_max_state(struct acpi_processor *pr) | 190 | static int acpi_processor_max_state(struct acpi_processor *pr) |
203 | { | 191 | { |
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 3322b47ab7ca..b7201fc6f1e1 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
@@ -505,14 +505,12 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, | |||
505 | void *preproc_data) | 505 | void *preproc_data) |
506 | { | 506 | { |
507 | struct res_proc_context c; | 507 | struct res_proc_context c; |
508 | acpi_handle not_used; | ||
509 | acpi_status status; | 508 | acpi_status status; |
510 | 509 | ||
511 | if (!adev || !adev->handle || !list_empty(list)) | 510 | if (!adev || !adev->handle || !list_empty(list)) |
512 | return -EINVAL; | 511 | return -EINVAL; |
513 | 512 | ||
514 | status = acpi_get_handle(adev->handle, METHOD_NAME__CRS, ¬_used); | 513 | if (!acpi_has_method(adev->handle, METHOD_NAME__CRS)) |
515 | if (ACPI_FAILURE(status)) | ||
516 | return 0; | 514 | return 0; |
517 | 515 | ||
518 | c.list = list; | 516 | c.list = list; |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index b6241eeb1132..aef7e1cd1e5d 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -873,14 +873,9 @@ static void acpi_sbs_callback(void *context) | |||
873 | u8 saved_charger_state = sbs->charger_present; | 873 | u8 saved_charger_state = sbs->charger_present; |
874 | u8 saved_battery_state; | 874 | u8 saved_battery_state; |
875 | acpi_ac_get_present(sbs); | 875 | acpi_ac_get_present(sbs); |
876 | if (sbs->charger_present != saved_charger_state) { | 876 | if (sbs->charger_present != saved_charger_state) |
877 | #ifdef CONFIG_ACPI_PROC_EVENT | ||
878 | acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME, | ||
879 | ACPI_SBS_NOTIFY_STATUS, | ||
880 | sbs->charger_present); | ||
881 | #endif | ||
882 | kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); | 877 | kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); |
883 | } | 878 | |
884 | if (sbs->manager_present) { | 879 | if (sbs->manager_present) { |
885 | for (id = 0; id < MAX_SBS_BAT; ++id) { | 880 | for (id = 0; id < MAX_SBS_BAT; ++id) { |
886 | if (!(sbs->batteries_supported & (1 << id))) | 881 | if (!(sbs->batteries_supported & (1 << id))) |
@@ -890,12 +885,6 @@ static void acpi_sbs_callback(void *context) | |||
890 | acpi_battery_read(bat); | 885 | acpi_battery_read(bat); |
891 | if (saved_battery_state == bat->present) | 886 | if (saved_battery_state == bat->present) |
892 | continue; | 887 | continue; |
893 | #ifdef CONFIG_ACPI_PROC_EVENT | ||
894 | acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS, | ||
895 | bat->name, | ||
896 | ACPI_SBS_NOTIFY_STATUS, | ||
897 | bat->present); | ||
898 | #endif | ||
899 | kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); | 888 | kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); |
900 | } | 889 | } |
901 | } | 890 | } |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8a46c924effd..61d090b6ce25 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -193,9 +193,6 @@ static acpi_status acpi_bus_online_companions(acpi_handle handle, u32 lvl, | |||
193 | static int acpi_scan_hot_remove(struct acpi_device *device) | 193 | static int acpi_scan_hot_remove(struct acpi_device *device) |
194 | { | 194 | { |
195 | acpi_handle handle = device->handle; | 195 | acpi_handle handle = device->handle; |
196 | acpi_handle not_used; | ||
197 | struct acpi_object_list arg_list; | ||
198 | union acpi_object arg; | ||
199 | struct device *errdev; | 196 | struct device *errdev; |
200 | acpi_status status; | 197 | acpi_status status; |
201 | unsigned long long sta; | 198 | unsigned long long sta; |
@@ -258,32 +255,15 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
258 | put_device(&device->dev); | 255 | put_device(&device->dev); |
259 | device = NULL; | 256 | device = NULL; |
260 | 257 | ||
261 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", ¬_used))) { | 258 | acpi_evaluate_lck(handle, 0); |
262 | arg_list.count = 1; | ||
263 | arg_list.pointer = &arg; | ||
264 | arg.type = ACPI_TYPE_INTEGER; | ||
265 | arg.integer.value = 0; | ||
266 | acpi_evaluate_object(handle, "_LCK", &arg_list, NULL); | ||
267 | } | ||
268 | |||
269 | arg_list.count = 1; | ||
270 | arg_list.pointer = &arg; | ||
271 | arg.type = ACPI_TYPE_INTEGER; | ||
272 | arg.integer.value = 1; | ||
273 | |||
274 | /* | 259 | /* |
275 | * TBD: _EJD support. | 260 | * TBD: _EJD support. |
276 | */ | 261 | */ |
277 | status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); | 262 | status = acpi_evaluate_ej0(handle); |
278 | if (ACPI_FAILURE(status)) { | 263 | if (status == AE_NOT_FOUND) |
279 | if (status == AE_NOT_FOUND) { | 264 | return -ENODEV; |
280 | return -ENODEV; | 265 | else if (ACPI_FAILURE(status)) |
281 | } else { | 266 | return -EIO; |
282 | acpi_handle_warn(handle, "Eject failed (0x%x)\n", | ||
283 | status); | ||
284 | return -EIO; | ||
285 | } | ||
286 | } | ||
287 | 267 | ||
288 | /* | 268 | /* |
289 | * Verify if eject was indeed successful. If not, log an error | 269 | * Verify if eject was indeed successful. If not, log an error |
@@ -307,6 +287,7 @@ static void acpi_bus_device_eject(void *context) | |||
307 | struct acpi_device *device = NULL; | 287 | struct acpi_device *device = NULL; |
308 | struct acpi_scan_handler *handler; | 288 | struct acpi_scan_handler *handler; |
309 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 289 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
290 | int error; | ||
310 | 291 | ||
311 | mutex_lock(&acpi_scan_lock); | 292 | mutex_lock(&acpi_scan_lock); |
312 | 293 | ||
@@ -321,17 +302,13 @@ static void acpi_bus_device_eject(void *context) | |||
321 | } | 302 | } |
322 | acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, | 303 | acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, |
323 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 304 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
324 | if (handler->hotplug.mode == AHM_CONTAINER) { | 305 | if (handler->hotplug.mode == AHM_CONTAINER) |
325 | device->flags.eject_pending = true; | ||
326 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | 306 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); |
327 | } else { | ||
328 | int error; | ||
329 | 307 | ||
330 | get_device(&device->dev); | 308 | get_device(&device->dev); |
331 | error = acpi_scan_hot_remove(device); | 309 | error = acpi_scan_hot_remove(device); |
332 | if (error) | 310 | if (error) |
333 | goto err_out; | 311 | goto err_out; |
334 | } | ||
335 | 312 | ||
336 | out: | 313 | out: |
337 | mutex_unlock(&acpi_scan_lock); | 314 | mutex_unlock(&acpi_scan_lock); |
@@ -516,7 +493,6 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
516 | struct acpi_eject_event *ej_event; | 493 | struct acpi_eject_event *ej_event; |
517 | acpi_object_type not_used; | 494 | acpi_object_type not_used; |
518 | acpi_status status; | 495 | acpi_status status; |
519 | u32 ost_source; | ||
520 | int ret; | 496 | int ret; |
521 | 497 | ||
522 | if (!count || buf[0] != '1') | 498 | if (!count || buf[0] != '1') |
@@ -530,43 +506,28 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
530 | if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) | 506 | if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) |
531 | return -ENODEV; | 507 | return -ENODEV; |
532 | 508 | ||
533 | mutex_lock(&acpi_scan_lock); | ||
534 | |||
535 | if (acpi_device->flags.eject_pending) { | ||
536 | /* ACPI eject notification event. */ | ||
537 | ost_source = ACPI_NOTIFY_EJECT_REQUEST; | ||
538 | acpi_device->flags.eject_pending = 0; | ||
539 | } else { | ||
540 | /* Eject initiated by user space. */ | ||
541 | ost_source = ACPI_OST_EC_OSPM_EJECT; | ||
542 | } | ||
543 | ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); | 509 | ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); |
544 | if (!ej_event) { | 510 | if (!ej_event) { |
545 | ret = -ENOMEM; | 511 | ret = -ENOMEM; |
546 | goto err_out; | 512 | goto err_out; |
547 | } | 513 | } |
548 | acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source, | 514 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, |
549 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 515 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
550 | ej_event->device = acpi_device; | 516 | ej_event->device = acpi_device; |
551 | ej_event->event = ost_source; | 517 | ej_event->event = ACPI_OST_EC_OSPM_EJECT; |
552 | get_device(&acpi_device->dev); | 518 | get_device(&acpi_device->dev); |
553 | status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); | 519 | status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); |
554 | if (ACPI_FAILURE(status)) { | 520 | if (ACPI_SUCCESS(status)) |
555 | put_device(&acpi_device->dev); | 521 | return count; |
556 | kfree(ej_event); | ||
557 | ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; | ||
558 | goto err_out; | ||
559 | } | ||
560 | ret = count; | ||
561 | 522 | ||
562 | out: | 523 | put_device(&acpi_device->dev); |
563 | mutex_unlock(&acpi_scan_lock); | 524 | kfree(ej_event); |
564 | return ret; | 525 | ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; |
565 | 526 | ||
566 | err_out: | 527 | err_out: |
567 | acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source, | 528 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, |
568 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); | 529 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); |
569 | goto out; | 530 | return ret; |
570 | } | 531 | } |
571 | 532 | ||
572 | static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); | 533 | static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); |
@@ -654,7 +615,6 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
654 | { | 615 | { |
655 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 616 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
656 | acpi_status status; | 617 | acpi_status status; |
657 | acpi_handle temp; | ||
658 | unsigned long long sun; | 618 | unsigned long long sun; |
659 | int result = 0; | 619 | int result = 0; |
660 | 620 | ||
@@ -680,8 +640,7 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
680 | /* | 640 | /* |
681 | * If device has _STR, 'description' file is created | 641 | * If device has _STR, 'description' file is created |
682 | */ | 642 | */ |
683 | status = acpi_get_handle(dev->handle, "_STR", &temp); | 643 | if (acpi_has_method(dev->handle, "_STR")) { |
684 | if (ACPI_SUCCESS(status)) { | ||
685 | status = acpi_evaluate_object(dev->handle, "_STR", | 644 | status = acpi_evaluate_object(dev->handle, "_STR", |
686 | NULL, &buffer); | 645 | NULL, &buffer); |
687 | if (ACPI_FAILURE(status)) | 646 | if (ACPI_FAILURE(status)) |
@@ -711,8 +670,7 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
711 | * If device has _EJ0, 'eject' file is created that is used to trigger | 670 | * If device has _EJ0, 'eject' file is created that is used to trigger |
712 | * hot-removal function from userland. | 671 | * hot-removal function from userland. |
713 | */ | 672 | */ |
714 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); | 673 | if (acpi_has_method(dev->handle, "_EJ0")) { |
715 | if (ACPI_SUCCESS(status)) { | ||
716 | result = device_create_file(&dev->dev, &dev_attr_eject); | 674 | result = device_create_file(&dev->dev, &dev_attr_eject); |
717 | if (result) | 675 | if (result) |
718 | return result; | 676 | return result; |
@@ -734,9 +692,6 @@ end: | |||
734 | 692 | ||
735 | static void acpi_device_remove_files(struct acpi_device *dev) | 693 | static void acpi_device_remove_files(struct acpi_device *dev) |
736 | { | 694 | { |
737 | acpi_status status; | ||
738 | acpi_handle temp; | ||
739 | |||
740 | if (dev->flags.power_manageable) { | 695 | if (dev->flags.power_manageable) { |
741 | device_remove_file(&dev->dev, &dev_attr_power_state); | 696 | device_remove_file(&dev->dev, &dev_attr_power_state); |
742 | if (dev->power.flags.power_resources) | 697 | if (dev->power.flags.power_resources) |
@@ -747,20 +702,17 @@ static void acpi_device_remove_files(struct acpi_device *dev) | |||
747 | /* | 702 | /* |
748 | * If device has _STR, remove 'description' file | 703 | * If device has _STR, remove 'description' file |
749 | */ | 704 | */ |
750 | status = acpi_get_handle(dev->handle, "_STR", &temp); | 705 | if (acpi_has_method(dev->handle, "_STR")) { |
751 | if (ACPI_SUCCESS(status)) { | ||
752 | kfree(dev->pnp.str_obj); | 706 | kfree(dev->pnp.str_obj); |
753 | device_remove_file(&dev->dev, &dev_attr_description); | 707 | device_remove_file(&dev->dev, &dev_attr_description); |
754 | } | 708 | } |
755 | /* | 709 | /* |
756 | * If device has _EJ0, remove 'eject' file. | 710 | * If device has _EJ0, remove 'eject' file. |
757 | */ | 711 | */ |
758 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); | 712 | if (acpi_has_method(dev->handle, "_EJ0")) |
759 | if (ACPI_SUCCESS(status)) | ||
760 | device_remove_file(&dev->dev, &dev_attr_eject); | 713 | device_remove_file(&dev->dev, &dev_attr_eject); |
761 | 714 | ||
762 | status = acpi_get_handle(dev->handle, "_SUN", &temp); | 715 | if (acpi_has_method(dev->handle, "_SUN")) |
763 | if (ACPI_SUCCESS(status)) | ||
764 | device_remove_file(&dev->dev, &dev_attr_sun); | 716 | device_remove_file(&dev->dev, &dev_attr_sun); |
765 | 717 | ||
766 | if (dev->pnp.unique_id) | 718 | if (dev->pnp.unique_id) |
@@ -999,6 +951,28 @@ struct bus_type acpi_bus_type = { | |||
999 | .uevent = acpi_device_uevent, | 951 | .uevent = acpi_device_uevent, |
1000 | }; | 952 | }; |
1001 | 953 | ||
954 | static void acpi_bus_data_handler(acpi_handle handle, void *context) | ||
955 | { | ||
956 | /* Intentionally empty. */ | ||
957 | } | ||
958 | |||
959 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | ||
960 | { | ||
961 | acpi_status status; | ||
962 | |||
963 | if (!device) | ||
964 | return -EINVAL; | ||
965 | |||
966 | status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device); | ||
967 | if (ACPI_FAILURE(status) || !*device) { | ||
968 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", | ||
969 | handle)); | ||
970 | return -ENODEV; | ||
971 | } | ||
972 | return 0; | ||
973 | } | ||
974 | EXPORT_SYMBOL_GPL(acpi_bus_get_device); | ||
975 | |||
1002 | int acpi_device_add(struct acpi_device *device, | 976 | int acpi_device_add(struct acpi_device *device, |
1003 | void (*release)(struct device *)) | 977 | void (*release)(struct device *)) |
1004 | { | 978 | { |
@@ -1210,14 +1184,6 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) | |||
1210 | } | 1184 | } |
1211 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); | 1185 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); |
1212 | 1186 | ||
1213 | void acpi_bus_data_handler(acpi_handle handle, void *context) | ||
1214 | { | ||
1215 | |||
1216 | /* TBD */ | ||
1217 | |||
1218 | return; | ||
1219 | } | ||
1220 | |||
1221 | static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, | 1187 | static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, |
1222 | struct acpi_device_wakeup *wakeup) | 1188 | struct acpi_device_wakeup *wakeup) |
1223 | { | 1189 | { |
@@ -1336,13 +1302,10 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
1336 | 1302 | ||
1337 | static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | 1303 | static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) |
1338 | { | 1304 | { |
1339 | acpi_handle temp; | ||
1340 | acpi_status status = 0; | ||
1341 | int err; | 1305 | int err; |
1342 | 1306 | ||
1343 | /* Presence of _PRW indicates wake capable */ | 1307 | /* Presence of _PRW indicates wake capable */ |
1344 | status = acpi_get_handle(device->handle, "_PRW", &temp); | 1308 | if (!acpi_has_method(device->handle, "_PRW")) |
1345 | if (ACPI_FAILURE(status)) | ||
1346 | return; | 1309 | return; |
1347 | 1310 | ||
1348 | err = acpi_bus_extract_wakeup_device_power_package(device->handle, | 1311 | err = acpi_bus_extract_wakeup_device_power_package(device->handle, |
@@ -1372,7 +1335,6 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) | |||
1372 | struct acpi_device_power_state *ps = &device->power.states[state]; | 1335 | struct acpi_device_power_state *ps = &device->power.states[state]; |
1373 | char pathname[5] = { '_', 'P', 'R', '0' + state, '\0' }; | 1336 | char pathname[5] = { '_', 'P', 'R', '0' + state, '\0' }; |
1374 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 1337 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1375 | acpi_handle handle; | ||
1376 | acpi_status status; | 1338 | acpi_status status; |
1377 | 1339 | ||
1378 | INIT_LIST_HEAD(&ps->resources); | 1340 | INIT_LIST_HEAD(&ps->resources); |
@@ -1395,8 +1357,7 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) | |||
1395 | 1357 | ||
1396 | /* Evaluate "_PSx" to see if we can do explicit sets */ | 1358 | /* Evaluate "_PSx" to see if we can do explicit sets */ |
1397 | pathname[2] = 'S'; | 1359 | pathname[2] = 'S'; |
1398 | status = acpi_get_handle(device->handle, pathname, &handle); | 1360 | if (acpi_has_method(device->handle, pathname)) |
1399 | if (ACPI_SUCCESS(status)) | ||
1400 | ps->flags.explicit_set = 1; | 1361 | ps->flags.explicit_set = 1; |
1401 | 1362 | ||
1402 | /* | 1363 | /* |
@@ -1415,28 +1376,21 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) | |||
1415 | 1376 | ||
1416 | static void acpi_bus_get_power_flags(struct acpi_device *device) | 1377 | static void acpi_bus_get_power_flags(struct acpi_device *device) |
1417 | { | 1378 | { |
1418 | acpi_status status; | ||
1419 | acpi_handle handle; | ||
1420 | u32 i; | 1379 | u32 i; |
1421 | 1380 | ||
1422 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ | 1381 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ |
1423 | status = acpi_get_handle(device->handle, "_PS0", &handle); | 1382 | if (!acpi_has_method(device->handle, "_PS0") && |
1424 | if (ACPI_FAILURE(status)) { | 1383 | !acpi_has_method(device->handle, "_PR0")) |
1425 | status = acpi_get_handle(device->handle, "_PR0", &handle); | 1384 | return; |
1426 | if (ACPI_FAILURE(status)) | ||
1427 | return; | ||
1428 | } | ||
1429 | 1385 | ||
1430 | device->flags.power_manageable = 1; | 1386 | device->flags.power_manageable = 1; |
1431 | 1387 | ||
1432 | /* | 1388 | /* |
1433 | * Power Management Flags | 1389 | * Power Management Flags |
1434 | */ | 1390 | */ |
1435 | status = acpi_get_handle(device->handle, "_PSC", &handle); | 1391 | if (acpi_has_method(device->handle, "_PSC")) |
1436 | if (ACPI_SUCCESS(status)) | ||
1437 | device->power.flags.explicit_get = 1; | 1392 | device->power.flags.explicit_get = 1; |
1438 | status = acpi_get_handle(device->handle, "_IRC", &handle); | 1393 | if (acpi_has_method(device->handle, "_IRC")) |
1439 | if (ACPI_SUCCESS(status)) | ||
1440 | device->power.flags.inrush_current = 1; | 1394 | device->power.flags.inrush_current = 1; |
1441 | 1395 | ||
1442 | /* | 1396 | /* |
@@ -1450,8 +1404,8 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) | |||
1450 | /* Set defaults for D0 and D3 states (always valid) */ | 1404 | /* Set defaults for D0 and D3 states (always valid) */ |
1451 | device->power.states[ACPI_STATE_D0].flags.valid = 1; | 1405 | device->power.states[ACPI_STATE_D0].flags.valid = 1; |
1452 | device->power.states[ACPI_STATE_D0].power = 100; | 1406 | device->power.states[ACPI_STATE_D0].power = 100; |
1453 | device->power.states[ACPI_STATE_D3].flags.valid = 1; | 1407 | device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; |
1454 | device->power.states[ACPI_STATE_D3].power = 0; | 1408 | device->power.states[ACPI_STATE_D3_COLD].power = 0; |
1455 | 1409 | ||
1456 | /* Set D3cold's explicit_set flag if _PS3 exists. */ | 1410 | /* Set D3cold's explicit_set flag if _PS3 exists. */ |
1457 | if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set) | 1411 | if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set) |
@@ -1470,28 +1424,18 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) | |||
1470 | 1424 | ||
1471 | static void acpi_bus_get_flags(struct acpi_device *device) | 1425 | static void acpi_bus_get_flags(struct acpi_device *device) |
1472 | { | 1426 | { |
1473 | acpi_status status = AE_OK; | ||
1474 | acpi_handle temp = NULL; | ||
1475 | |||
1476 | /* Presence of _STA indicates 'dynamic_status' */ | 1427 | /* Presence of _STA indicates 'dynamic_status' */ |
1477 | status = acpi_get_handle(device->handle, "_STA", &temp); | 1428 | if (acpi_has_method(device->handle, "_STA")) |
1478 | if (ACPI_SUCCESS(status)) | ||
1479 | device->flags.dynamic_status = 1; | 1429 | device->flags.dynamic_status = 1; |
1480 | 1430 | ||
1481 | /* Presence of _RMV indicates 'removable' */ | 1431 | /* Presence of _RMV indicates 'removable' */ |
1482 | status = acpi_get_handle(device->handle, "_RMV", &temp); | 1432 | if (acpi_has_method(device->handle, "_RMV")) |
1483 | if (ACPI_SUCCESS(status)) | ||
1484 | device->flags.removable = 1; | 1433 | device->flags.removable = 1; |
1485 | 1434 | ||
1486 | /* Presence of _EJD|_EJ0 indicates 'ejectable' */ | 1435 | /* Presence of _EJD|_EJ0 indicates 'ejectable' */ |
1487 | status = acpi_get_handle(device->handle, "_EJD", &temp); | 1436 | if (acpi_has_method(device->handle, "_EJD") || |
1488 | if (ACPI_SUCCESS(status)) | 1437 | acpi_has_method(device->handle, "_EJ0")) |
1489 | device->flags.ejectable = 1; | 1438 | device->flags.ejectable = 1; |
1490 | else { | ||
1491 | status = acpi_get_handle(device->handle, "_EJ0", &temp); | ||
1492 | if (ACPI_SUCCESS(status)) | ||
1493 | device->flags.ejectable = 1; | ||
1494 | } | ||
1495 | } | 1439 | } |
1496 | 1440 | ||
1497 | static void acpi_device_get_busid(struct acpi_device *device) | 1441 | static void acpi_device_get_busid(struct acpi_device *device) |
@@ -1533,46 +1477,45 @@ static void acpi_device_get_busid(struct acpi_device *device) | |||
1533 | } | 1477 | } |
1534 | 1478 | ||
1535 | /* | 1479 | /* |
1480 | * acpi_ata_match - see if an acpi object is an ATA device | ||
1481 | * | ||
1482 | * If an acpi object has one of the ACPI ATA methods defined, | ||
1483 | * then we can safely call it an ATA device. | ||
1484 | */ | ||
1485 | bool acpi_ata_match(acpi_handle handle) | ||
1486 | { | ||
1487 | return acpi_has_method(handle, "_GTF") || | ||
1488 | acpi_has_method(handle, "_GTM") || | ||
1489 | acpi_has_method(handle, "_STM") || | ||
1490 | acpi_has_method(handle, "_SDD"); | ||
1491 | } | ||
1492 | |||
1493 | /* | ||
1536 | * acpi_bay_match - see if an acpi object is an ejectable driver bay | 1494 | * acpi_bay_match - see if an acpi object is an ejectable driver bay |
1537 | * | 1495 | * |
1538 | * If an acpi object is ejectable and has one of the ACPI ATA methods defined, | 1496 | * If an acpi object is ejectable and has one of the ACPI ATA methods defined, |
1539 | * then we can safely call it an ejectable drive bay | 1497 | * then we can safely call it an ejectable drive bay |
1540 | */ | 1498 | */ |
1541 | static int acpi_bay_match(acpi_handle handle) | 1499 | bool acpi_bay_match(acpi_handle handle) |
1542 | { | 1500 | { |
1543 | acpi_status status; | ||
1544 | acpi_handle tmp; | ||
1545 | acpi_handle phandle; | 1501 | acpi_handle phandle; |
1546 | 1502 | ||
1547 | status = acpi_get_handle(handle, "_EJ0", &tmp); | 1503 | if (!acpi_has_method(handle, "_EJ0")) |
1548 | if (ACPI_FAILURE(status)) | 1504 | return false; |
1549 | return -ENODEV; | 1505 | if (acpi_ata_match(handle)) |
1550 | 1506 | return true; | |
1551 | if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || | 1507 | if (ACPI_FAILURE(acpi_get_parent(handle, &phandle))) |
1552 | (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || | 1508 | return false; |
1553 | (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || | ||
1554 | (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) | ||
1555 | return 0; | ||
1556 | 1509 | ||
1557 | if (acpi_get_parent(handle, &phandle)) | 1510 | return acpi_ata_match(phandle); |
1558 | return -ENODEV; | ||
1559 | |||
1560 | if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) || | ||
1561 | (ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) || | ||
1562 | (ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) || | ||
1563 | (ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp)))) | ||
1564 | return 0; | ||
1565 | |||
1566 | return -ENODEV; | ||
1567 | } | 1511 | } |
1568 | 1512 | ||
1569 | /* | 1513 | /* |
1570 | * acpi_dock_match - see if an acpi object has a _DCK method | 1514 | * acpi_dock_match - see if an acpi object has a _DCK method |
1571 | */ | 1515 | */ |
1572 | static int acpi_dock_match(acpi_handle handle) | 1516 | bool acpi_dock_match(acpi_handle handle) |
1573 | { | 1517 | { |
1574 | acpi_handle tmp; | 1518 | return acpi_has_method(handle, "_DCK"); |
1575 | return acpi_get_handle(handle, "_DCK", &tmp); | ||
1576 | } | 1519 | } |
1577 | 1520 | ||
1578 | const char *acpi_device_hid(struct acpi_device *device) | 1521 | const char *acpi_device_hid(struct acpi_device *device) |
@@ -1610,34 +1553,26 @@ static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id) | |||
1610 | * lacks the SMBUS01 HID and the methods do not have the necessary "_" | 1553 | * lacks the SMBUS01 HID and the methods do not have the necessary "_" |
1611 | * prefix. Work around this. | 1554 | * prefix. Work around this. |
1612 | */ | 1555 | */ |
1613 | static int acpi_ibm_smbus_match(acpi_handle handle) | 1556 | static bool acpi_ibm_smbus_match(acpi_handle handle) |
1614 | { | 1557 | { |
1615 | acpi_handle h_dummy; | 1558 | char node_name[ACPI_PATH_SEGMENT_LENGTH]; |
1616 | struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; | 1559 | struct acpi_buffer path = { sizeof(node_name), node_name }; |
1617 | int result; | ||
1618 | 1560 | ||
1619 | if (!dmi_name_in_vendors("IBM")) | 1561 | if (!dmi_name_in_vendors("IBM")) |
1620 | return -ENODEV; | 1562 | return false; |
1621 | 1563 | ||
1622 | /* Look for SMBS object */ | 1564 | /* Look for SMBS object */ |
1623 | result = acpi_get_name(handle, ACPI_SINGLE_NAME, &path); | 1565 | if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &path)) || |
1624 | if (result) | 1566 | strcmp("SMBS", path.pointer)) |
1625 | return result; | 1567 | return false; |
1626 | |||
1627 | if (strcmp("SMBS", path.pointer)) { | ||
1628 | result = -ENODEV; | ||
1629 | goto out; | ||
1630 | } | ||
1631 | 1568 | ||
1632 | /* Does it have the necessary (but misnamed) methods? */ | 1569 | /* Does it have the necessary (but misnamed) methods? */ |
1633 | result = -ENODEV; | 1570 | if (acpi_has_method(handle, "SBI") && |
1634 | if (ACPI_SUCCESS(acpi_get_handle(handle, "SBI", &h_dummy)) && | 1571 | acpi_has_method(handle, "SBR") && |
1635 | ACPI_SUCCESS(acpi_get_handle(handle, "SBR", &h_dummy)) && | 1572 | acpi_has_method(handle, "SBW")) |
1636 | ACPI_SUCCESS(acpi_get_handle(handle, "SBW", &h_dummy))) | 1573 | return true; |
1637 | result = 0; | 1574 | |
1638 | out: | 1575 | return false; |
1639 | kfree(path.pointer); | ||
1640 | return result; | ||
1641 | } | 1576 | } |
1642 | 1577 | ||
1643 | static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, | 1578 | static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, |
@@ -1685,11 +1620,11 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, | |||
1685 | */ | 1620 | */ |
1686 | if (acpi_is_video_device(handle)) | 1621 | if (acpi_is_video_device(handle)) |
1687 | acpi_add_id(pnp, ACPI_VIDEO_HID); | 1622 | acpi_add_id(pnp, ACPI_VIDEO_HID); |
1688 | else if (ACPI_SUCCESS(acpi_bay_match(handle))) | 1623 | else if (acpi_bay_match(handle)) |
1689 | acpi_add_id(pnp, ACPI_BAY_HID); | 1624 | acpi_add_id(pnp, ACPI_BAY_HID); |
1690 | else if (ACPI_SUCCESS(acpi_dock_match(handle))) | 1625 | else if (acpi_dock_match(handle)) |
1691 | acpi_add_id(pnp, ACPI_DOCK_HID); | 1626 | acpi_add_id(pnp, ACPI_DOCK_HID); |
1692 | else if (!acpi_ibm_smbus_match(handle)) | 1627 | else if (acpi_ibm_smbus_match(handle)) |
1693 | acpi_add_id(pnp, ACPI_SMBUS_IBM_HID); | 1628 | acpi_add_id(pnp, ACPI_SMBUS_IBM_HID); |
1694 | else if (list_empty(&pnp->ids) && handle == ACPI_ROOT_OBJECT) { | 1629 | else if (list_empty(&pnp->ids) && handle == ACPI_ROOT_OBJECT) { |
1695 | acpi_add_id(pnp, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ | 1630 | acpi_add_id(pnp, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ |
@@ -1900,7 +1835,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | |||
1900 | struct acpi_device *device = NULL; | 1835 | struct acpi_device *device = NULL; |
1901 | int type; | 1836 | int type; |
1902 | unsigned long long sta; | 1837 | unsigned long long sta; |
1903 | acpi_status status; | ||
1904 | int result; | 1838 | int result; |
1905 | 1839 | ||
1906 | acpi_bus_get_device(handle, &device); | 1840 | acpi_bus_get_device(handle, &device); |
@@ -1921,10 +1855,8 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | |||
1921 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && | 1855 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && |
1922 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { | 1856 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { |
1923 | struct acpi_device_wakeup wakeup; | 1857 | struct acpi_device_wakeup wakeup; |
1924 | acpi_handle temp; | ||
1925 | 1858 | ||
1926 | status = acpi_get_handle(handle, "_PRW", &temp); | 1859 | if (acpi_has_method(handle, "_PRW")) { |
1927 | if (ACPI_SUCCESS(status)) { | ||
1928 | acpi_bus_extract_wakeup_device_power_package(handle, | 1860 | acpi_bus_extract_wakeup_device_power_package(handle, |
1929 | &wakeup); | 1861 | &wakeup); |
1930 | acpi_power_resources_list_free(&wakeup.resources); | 1862 | acpi_power_resources_list_free(&wakeup.resources); |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 187ab61889e6..14df30580e15 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -31,12 +31,9 @@ static u8 sleep_states[ACPI_S_STATE_COUNT]; | |||
31 | 31 | ||
32 | static void acpi_sleep_tts_switch(u32 acpi_state) | 32 | static void acpi_sleep_tts_switch(u32 acpi_state) |
33 | { | 33 | { |
34 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; | 34 | acpi_status status; |
35 | struct acpi_object_list arg_list = { 1, &in_arg }; | ||
36 | acpi_status status = AE_OK; | ||
37 | 35 | ||
38 | in_arg.integer.value = acpi_state; | 36 | status = acpi_execute_simple_method(NULL, "\\_TTS", acpi_state); |
39 | status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL); | ||
40 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 37 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
41 | /* | 38 | /* |
42 | * OS can't evaluate the _TTS object correctly. Some warning | 39 | * OS can't evaluate the _TTS object correctly. Some warning |
@@ -141,7 +138,7 @@ static int __init init_nvs_nosave(const struct dmi_system_id *d) | |||
141 | return 0; | 138 | return 0; |
142 | } | 139 | } |
143 | 140 | ||
144 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 141 | static struct dmi_system_id acpisleep_dmi_table[] __initdata = { |
145 | { | 142 | { |
146 | .callback = init_old_suspend_ordering, | 143 | .callback = init_old_suspend_ordering, |
147 | .ident = "Abit KN9 (nForce4 variant)", | 144 | .ident = "Abit KN9 (nForce4 variant)", |
@@ -423,10 +420,21 @@ static void acpi_pm_finish(void) | |||
423 | } | 420 | } |
424 | 421 | ||
425 | /** | 422 | /** |
426 | * acpi_pm_end - Finish up suspend sequence. | 423 | * acpi_pm_start - Start system PM transition. |
424 | */ | ||
425 | static void acpi_pm_start(u32 acpi_state) | ||
426 | { | ||
427 | acpi_target_sleep_state = acpi_state; | ||
428 | acpi_sleep_tts_switch(acpi_target_sleep_state); | ||
429 | acpi_scan_lock_acquire(); | ||
430 | } | ||
431 | |||
432 | /** | ||
433 | * acpi_pm_end - Finish up system PM transition. | ||
427 | */ | 434 | */ |
428 | static void acpi_pm_end(void) | 435 | static void acpi_pm_end(void) |
429 | { | 436 | { |
437 | acpi_scan_lock_release(); | ||
430 | /* | 438 | /* |
431 | * This is necessary in case acpi_pm_finish() is not called during a | 439 | * This is necessary in case acpi_pm_finish() is not called during a |
432 | * failing transition to a sleep state. | 440 | * failing transition to a sleep state. |
@@ -454,21 +462,19 @@ static u32 acpi_suspend_states[] = { | |||
454 | static int acpi_suspend_begin(suspend_state_t pm_state) | 462 | static int acpi_suspend_begin(suspend_state_t pm_state) |
455 | { | 463 | { |
456 | u32 acpi_state = acpi_suspend_states[pm_state]; | 464 | u32 acpi_state = acpi_suspend_states[pm_state]; |
457 | int error = 0; | 465 | int error; |
458 | 466 | ||
459 | error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc(); | 467 | error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc(); |
460 | if (error) | 468 | if (error) |
461 | return error; | 469 | return error; |
462 | 470 | ||
463 | if (sleep_states[acpi_state]) { | 471 | if (!sleep_states[acpi_state]) { |
464 | acpi_target_sleep_state = acpi_state; | 472 | pr_err("ACPI does not support sleep state S%u\n", acpi_state); |
465 | acpi_sleep_tts_switch(acpi_target_sleep_state); | 473 | return -ENOSYS; |
466 | } else { | ||
467 | printk(KERN_ERR "ACPI does not support this state: %d\n", | ||
468 | pm_state); | ||
469 | error = -ENOSYS; | ||
470 | } | 474 | } |
471 | return error; | 475 | |
476 | acpi_pm_start(acpi_state); | ||
477 | return 0; | ||
472 | } | 478 | } |
473 | 479 | ||
474 | /** | 480 | /** |
@@ -634,10 +640,8 @@ static int acpi_hibernation_begin(void) | |||
634 | int error; | 640 | int error; |
635 | 641 | ||
636 | error = nvs_nosave ? 0 : suspend_nvs_alloc(); | 642 | error = nvs_nosave ? 0 : suspend_nvs_alloc(); |
637 | if (!error) { | 643 | if (!error) |
638 | acpi_target_sleep_state = ACPI_STATE_S4; | 644 | acpi_pm_start(ACPI_STATE_S4); |
639 | acpi_sleep_tts_switch(acpi_target_sleep_state); | ||
640 | } | ||
641 | 645 | ||
642 | return error; | 646 | return error; |
643 | } | 647 | } |
@@ -716,8 +720,10 @@ static int acpi_hibernation_begin_old(void) | |||
716 | if (!error) { | 720 | if (!error) { |
717 | if (!nvs_nosave) | 721 | if (!nvs_nosave) |
718 | error = suspend_nvs_alloc(); | 722 | error = suspend_nvs_alloc(); |
719 | if (!error) | 723 | if (!error) { |
720 | acpi_target_sleep_state = ACPI_STATE_S4; | 724 | acpi_target_sleep_state = ACPI_STATE_S4; |
725 | acpi_scan_lock_acquire(); | ||
726 | } | ||
721 | } | 727 | } |
722 | return error; | 728 | return error; |
723 | } | 729 | } |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index a33821ca3895..6a0329340b42 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -50,11 +50,6 @@ | |||
50 | 50 | ||
51 | #define ACPI_THERMAL_CLASS "thermal_zone" | 51 | #define ACPI_THERMAL_CLASS "thermal_zone" |
52 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" | 52 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" |
53 | #define ACPI_THERMAL_FILE_STATE "state" | ||
54 | #define ACPI_THERMAL_FILE_TEMPERATURE "temperature" | ||
55 | #define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" | ||
56 | #define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" | ||
57 | #define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" | ||
58 | #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 | 53 | #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 |
59 | #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 | 54 | #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 |
60 | #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 | 55 | #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 |
@@ -190,7 +185,6 @@ struct acpi_thermal { | |||
190 | struct thermal_zone_device *thermal_zone; | 185 | struct thermal_zone_device *thermal_zone; |
191 | int tz_enabled; | 186 | int tz_enabled; |
192 | int kelvin_offset; | 187 | int kelvin_offset; |
193 | struct mutex lock; | ||
194 | }; | 188 | }; |
195 | 189 | ||
196 | /* -------------------------------------------------------------------------- | 190 | /* -------------------------------------------------------------------------- |
@@ -239,26 +233,16 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) | |||
239 | 233 | ||
240 | static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) | 234 | static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) |
241 | { | 235 | { |
242 | acpi_status status = AE_OK; | ||
243 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
244 | struct acpi_object_list arg_list = { 1, &arg0 }; | ||
245 | acpi_handle handle = NULL; | ||
246 | |||
247 | |||
248 | if (!tz) | 236 | if (!tz) |
249 | return -EINVAL; | 237 | return -EINVAL; |
250 | 238 | ||
251 | status = acpi_get_handle(tz->device->handle, "_SCP", &handle); | 239 | if (!acpi_has_method(tz->device->handle, "_SCP")) { |
252 | if (ACPI_FAILURE(status)) { | ||
253 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); | 240 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); |
254 | return -ENODEV; | 241 | return -ENODEV; |
255 | } | 242 | } else if (ACPI_FAILURE(acpi_execute_simple_method(tz->device->handle, |
256 | 243 | "_SCP", mode))) { | |
257 | arg0.integer.value = mode; | ||
258 | |||
259 | status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); | ||
260 | if (ACPI_FAILURE(status)) | ||
261 | return -ENODEV; | 244 | return -ENODEV; |
245 | } | ||
262 | 246 | ||
263 | return 0; | 247 | return 0; |
264 | } | 248 | } |
@@ -491,14 +475,14 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
491 | break; | 475 | break; |
492 | } | 476 | } |
493 | 477 | ||
494 | if (flag & ACPI_TRIPS_DEVICES) { | 478 | if ((flag & ACPI_TRIPS_DEVICES) |
495 | memset(&devices, 0, sizeof(struct acpi_handle_list)); | 479 | && acpi_has_method(tz->device->handle, "_TZD")) { |
480 | memset(&devices, 0, sizeof(devices)); | ||
496 | status = acpi_evaluate_reference(tz->device->handle, "_TZD", | 481 | status = acpi_evaluate_reference(tz->device->handle, "_TZD", |
497 | NULL, &devices); | 482 | NULL, &devices); |
498 | if (memcmp(&tz->devices, &devices, | 483 | if (ACPI_SUCCESS(status) |
499 | sizeof(struct acpi_handle_list))) { | 484 | && memcmp(&tz->devices, &devices, sizeof(devices))) { |
500 | memcpy(&tz->devices, &devices, | 485 | tz->devices = devices; |
501 | sizeof(struct acpi_handle_list)); | ||
502 | ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); | 486 | ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); |
503 | } | 487 | } |
504 | } | 488 | } |
@@ -769,7 +753,6 @@ static int thermal_notify(struct thermal_zone_device *thermal, int trip, | |||
769 | else | 753 | else |
770 | return 0; | 754 | return 0; |
771 | 755 | ||
772 | acpi_bus_generate_proc_event(tz->device, type, 1); | ||
773 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, | 756 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, |
774 | dev_name(&tz->device->dev), type, 1); | 757 | dev_name(&tz->device->dev), type, 1); |
775 | 758 | ||
@@ -850,12 +833,13 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, | |||
850 | if (ACPI_SUCCESS(status) && (dev == device)) { | 833 | if (ACPI_SUCCESS(status) && (dev == device)) { |
851 | if (bind) | 834 | if (bind) |
852 | result = thermal_zone_bind_cooling_device | 835 | result = thermal_zone_bind_cooling_device |
853 | (thermal, -1, cdev, | 836 | (thermal, THERMAL_TRIPS_NONE, |
854 | THERMAL_NO_LIMIT, | 837 | cdev, THERMAL_NO_LIMIT, |
855 | THERMAL_NO_LIMIT); | 838 | THERMAL_NO_LIMIT); |
856 | else | 839 | else |
857 | result = thermal_zone_unbind_cooling_device | 840 | result = thermal_zone_unbind_cooling_device |
858 | (thermal, -1, cdev); | 841 | (thermal, THERMAL_TRIPS_NONE, |
842 | cdev); | ||
859 | if (result) | 843 | if (result) |
860 | goto failed; | 844 | goto failed; |
861 | } | 845 | } |
@@ -980,14 +964,12 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event) | |||
980 | case ACPI_THERMAL_NOTIFY_THRESHOLDS: | 964 | case ACPI_THERMAL_NOTIFY_THRESHOLDS: |
981 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); | 965 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); |
982 | acpi_thermal_check(tz); | 966 | acpi_thermal_check(tz); |
983 | acpi_bus_generate_proc_event(device, event, 0); | ||
984 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 967 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
985 | dev_name(&device->dev), event, 0); | 968 | dev_name(&device->dev), event, 0); |
986 | break; | 969 | break; |
987 | case ACPI_THERMAL_NOTIFY_DEVICES: | 970 | case ACPI_THERMAL_NOTIFY_DEVICES: |
988 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); | 971 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); |
989 | acpi_thermal_check(tz); | 972 | acpi_thermal_check(tz); |
990 | acpi_bus_generate_proc_event(device, event, 0); | ||
991 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 973 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
992 | dev_name(&device->dev), event, 0); | 974 | dev_name(&device->dev), event, 0); |
993 | break; | 975 | break; |
@@ -1101,8 +1083,6 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1101 | strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); | 1083 | strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); |
1102 | strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); | 1084 | strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); |
1103 | device->driver_data = tz; | 1085 | device->driver_data = tz; |
1104 | mutex_init(&tz->lock); | ||
1105 | |||
1106 | 1086 | ||
1107 | result = acpi_thermal_get_info(tz); | 1087 | result = acpi_thermal_get_info(tz); |
1108 | if (result) | 1088 | if (result) |
@@ -1135,7 +1115,6 @@ static int acpi_thermal_remove(struct acpi_device *device) | |||
1135 | tz = acpi_driver_data(device); | 1115 | tz = acpi_driver_data(device); |
1136 | 1116 | ||
1137 | acpi_thermal_unregister_thermal_zone(tz); | 1117 | acpi_thermal_unregister_thermal_zone(tz); |
1138 | mutex_destroy(&tz->lock); | ||
1139 | kfree(tz); | 1118 | kfree(tz); |
1140 | return 0; | 1119 | return 0; |
1141 | } | 1120 | } |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 744371304313..552248b0005b 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -495,3 +495,73 @@ acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) | |||
495 | kfree(buffer.pointer); | 495 | kfree(buffer.pointer); |
496 | } | 496 | } |
497 | EXPORT_SYMBOL(acpi_handle_printk); | 497 | EXPORT_SYMBOL(acpi_handle_printk); |
498 | |||
499 | /** | ||
500 | * acpi_has_method: Check whether @handle has a method named @name | ||
501 | * @handle: ACPI device handle | ||
502 | * @name: name of object or method | ||
503 | * | ||
504 | * Check whether @handle has a method named @name. | ||
505 | */ | ||
506 | bool acpi_has_method(acpi_handle handle, char *name) | ||
507 | { | ||
508 | acpi_handle tmp; | ||
509 | |||
510 | return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp)); | ||
511 | } | ||
512 | EXPORT_SYMBOL(acpi_has_method); | ||
513 | |||
514 | acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, | ||
515 | u64 arg) | ||
516 | { | ||
517 | union acpi_object obj = { .type = ACPI_TYPE_INTEGER }; | ||
518 | struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, }; | ||
519 | |||
520 | obj.integer.value = arg; | ||
521 | |||
522 | return acpi_evaluate_object(handle, method, &arg_list, NULL); | ||
523 | } | ||
524 | EXPORT_SYMBOL(acpi_execute_simple_method); | ||
525 | |||
526 | /** | ||
527 | * acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations | ||
528 | * @handle: ACPI device handle | ||
529 | * | ||
530 | * Evaluate device's _EJ0 method for hotplug operations. | ||
531 | */ | ||
532 | acpi_status acpi_evaluate_ej0(acpi_handle handle) | ||
533 | { | ||
534 | acpi_status status; | ||
535 | |||
536 | status = acpi_execute_simple_method(handle, "_EJ0", 1); | ||
537 | if (status == AE_NOT_FOUND) | ||
538 | acpi_handle_warn(handle, "No _EJ0 support for device\n"); | ||
539 | else if (ACPI_FAILURE(status)) | ||
540 | acpi_handle_warn(handle, "Eject failed (0x%x)\n", status); | ||
541 | |||
542 | return status; | ||
543 | } | ||
544 | |||
545 | /** | ||
546 | * acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device | ||
547 | * @handle: ACPI device handle | ||
548 | * @lock: lock device if non-zero, otherwise unlock device | ||
549 | * | ||
550 | * Evaluate device's _LCK method if present to lock/unlock device | ||
551 | */ | ||
552 | acpi_status acpi_evaluate_lck(acpi_handle handle, int lock) | ||
553 | { | ||
554 | acpi_status status; | ||
555 | |||
556 | status = acpi_execute_simple_method(handle, "_LCK", !!lock); | ||
557 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
558 | if (lock) | ||
559 | acpi_handle_warn(handle, | ||
560 | "Locking device failed (0x%x)\n", status); | ||
561 | else | ||
562 | acpi_handle_warn(handle, | ||
563 | "Unlocking device failed (0x%x)\n", status); | ||
564 | } | ||
565 | |||
566 | return status; | ||
567 | } | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 3270d3c8ba4e..aebcf6355df4 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * video.c - ACPI Video Driver ($Revision:$) | 2 | * video.c - ACPI Video Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> | 4 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> |
5 | * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> | 5 | * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> |
@@ -88,7 +88,7 @@ module_param(allow_duplicates, bool, 0644); | |||
88 | static bool use_bios_initial_backlight = 1; | 88 | static bool use_bios_initial_backlight = 1; |
89 | module_param(use_bios_initial_backlight, bool, 0644); | 89 | module_param(use_bios_initial_backlight, bool, 0644); |
90 | 90 | ||
91 | static int register_count = 0; | 91 | static int register_count; |
92 | static int acpi_video_bus_add(struct acpi_device *device); | 92 | static int acpi_video_bus_add(struct acpi_device *device); |
93 | static int acpi_video_bus_remove(struct acpi_device *device); | 93 | static int acpi_video_bus_remove(struct acpi_device *device); |
94 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event); | 94 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event); |
@@ -118,26 +118,26 @@ struct acpi_video_bus_flags { | |||
118 | }; | 118 | }; |
119 | 119 | ||
120 | struct acpi_video_bus_cap { | 120 | struct acpi_video_bus_cap { |
121 | u8 _DOS:1; /*Enable/Disable output switching */ | 121 | u8 _DOS:1; /* Enable/Disable output switching */ |
122 | u8 _DOD:1; /*Enumerate all devices attached to display adapter */ | 122 | u8 _DOD:1; /* Enumerate all devices attached to display adapter */ |
123 | u8 _ROM:1; /*Get ROM Data */ | 123 | u8 _ROM:1; /* Get ROM Data */ |
124 | u8 _GPD:1; /*Get POST Device */ | 124 | u8 _GPD:1; /* Get POST Device */ |
125 | u8 _SPD:1; /*Set POST Device */ | 125 | u8 _SPD:1; /* Set POST Device */ |
126 | u8 _VPO:1; /*Video POST Options */ | 126 | u8 _VPO:1; /* Video POST Options */ |
127 | u8 reserved:2; | 127 | u8 reserved:2; |
128 | }; | 128 | }; |
129 | 129 | ||
130 | struct acpi_video_device_attrib { | 130 | struct acpi_video_device_attrib { |
131 | u32 display_index:4; /* A zero-based instance of the Display */ | 131 | u32 display_index:4; /* A zero-based instance of the Display */ |
132 | u32 display_port_attachment:4; /*This field differentiates the display type */ | 132 | u32 display_port_attachment:4; /* This field differentiates the display type */ |
133 | u32 display_type:4; /*Describe the specific type in use */ | 133 | u32 display_type:4; /* Describe the specific type in use */ |
134 | u32 vendor_specific:4; /*Chipset Vendor Specific */ | 134 | u32 vendor_specific:4; /* Chipset Vendor Specific */ |
135 | u32 bios_can_detect:1; /*BIOS can detect the device */ | 135 | u32 bios_can_detect:1; /* BIOS can detect the device */ |
136 | u32 depend_on_vga:1; /*Non-VGA output device whose power is related to | 136 | u32 depend_on_vga:1; /* Non-VGA output device whose power is related to |
137 | the VGA device. */ | 137 | the VGA device. */ |
138 | u32 pipe_id:3; /*For VGA multiple-head devices. */ | 138 | u32 pipe_id:3; /* For VGA multiple-head devices. */ |
139 | u32 reserved:10; /*Must be 0 */ | 139 | u32 reserved:10; /* Must be 0 */ |
140 | u32 device_id_scheme:1; /*Device ID Scheme */ | 140 | u32 device_id_scheme:1; /* Device ID Scheme */ |
141 | }; | 141 | }; |
142 | 142 | ||
143 | struct acpi_video_enumerated_device { | 143 | struct acpi_video_enumerated_device { |
@@ -174,19 +174,17 @@ struct acpi_video_device_flags { | |||
174 | }; | 174 | }; |
175 | 175 | ||
176 | struct acpi_video_device_cap { | 176 | struct acpi_video_device_cap { |
177 | u8 _ADR:1; /*Return the unique ID */ | 177 | u8 _ADR:1; /* Return the unique ID */ |
178 | u8 _BCL:1; /*Query list of brightness control levels supported */ | 178 | u8 _BCL:1; /* Query list of brightness control levels supported */ |
179 | u8 _BCM:1; /*Set the brightness level */ | 179 | u8 _BCM:1; /* Set the brightness level */ |
180 | u8 _BQC:1; /* Get current brightness level */ | 180 | u8 _BQC:1; /* Get current brightness level */ |
181 | u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ | 181 | u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ |
182 | u8 _DDC:1; /*Return the EDID for this device */ | 182 | u8 _DDC:1; /* Return the EDID for this device */ |
183 | }; | 183 | }; |
184 | 184 | ||
185 | struct acpi_video_brightness_flags { | 185 | struct acpi_video_brightness_flags { |
186 | u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */ | 186 | u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */ |
187 | u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/ | 187 | u8 _BCL_reversed:1; /* _BCL package is in a reversed order */ |
188 | u8 _BCL_use_index:1; /* levels in _BCL are index values */ | ||
189 | u8 _BCM_use_index:1; /* input of _BCM is an index value */ | ||
190 | u8 _BQC_use_index:1; /* _BQC returns an index value */ | 188 | u8 _BQC_use_index:1; /* _BQC returns an index value */ |
191 | }; | 189 | }; |
192 | 190 | ||
@@ -231,21 +229,22 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, | |||
231 | static int acpi_video_switch_brightness(struct acpi_video_device *device, | 229 | static int acpi_video_switch_brightness(struct acpi_video_device *device, |
232 | int event); | 230 | int event); |
233 | 231 | ||
234 | /*backlight device sysfs support*/ | 232 | /* backlight device sysfs support */ |
235 | static int acpi_video_get_brightness(struct backlight_device *bd) | 233 | static int acpi_video_get_brightness(struct backlight_device *bd) |
236 | { | 234 | { |
237 | unsigned long long cur_level; | 235 | unsigned long long cur_level; |
238 | int i; | 236 | int i; |
239 | struct acpi_video_device *vd = | 237 | struct acpi_video_device *vd = bl_get_data(bd); |
240 | (struct acpi_video_device *)bl_get_data(bd); | ||
241 | 238 | ||
242 | if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false)) | 239 | if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false)) |
243 | return -EINVAL; | 240 | return -EINVAL; |
244 | for (i = 2; i < vd->brightness->count; i++) { | 241 | for (i = 2; i < vd->brightness->count; i++) { |
245 | if (vd->brightness->levels[i] == cur_level) | 242 | if (vd->brightness->levels[i] == cur_level) |
246 | /* The first two entries are special - see page 575 | 243 | /* |
247 | of the ACPI spec 3.0 */ | 244 | * The first two entries are special - see page 575 |
248 | return i-2; | 245 | * of the ACPI spec 3.0 |
246 | */ | ||
247 | return i - 2; | ||
249 | } | 248 | } |
250 | return 0; | 249 | return 0; |
251 | } | 250 | } |
@@ -253,8 +252,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd) | |||
253 | static int acpi_video_set_brightness(struct backlight_device *bd) | 252 | static int acpi_video_set_brightness(struct backlight_device *bd) |
254 | { | 253 | { |
255 | int request_level = bd->props.brightness + 2; | 254 | int request_level = bd->props.brightness + 2; |
256 | struct acpi_video_device *vd = | 255 | struct acpi_video_device *vd = bl_get_data(bd); |
257 | (struct acpi_video_device *)bl_get_data(bd); | ||
258 | 256 | ||
259 | return acpi_video_device_lcd_set_level(vd, | 257 | return acpi_video_device_lcd_set_level(vd, |
260 | vd->brightness->levels[request_level]); | 258 | vd->brightness->levels[request_level]); |
@@ -302,11 +300,11 @@ video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long st | |||
302 | struct acpi_video_device *video = acpi_driver_data(device); | 300 | struct acpi_video_device *video = acpi_driver_data(device); |
303 | int level; | 301 | int level; |
304 | 302 | ||
305 | if ( state >= video->brightness->count - 2) | 303 | if (state >= video->brightness->count - 2) |
306 | return -EINVAL; | 304 | return -EINVAL; |
307 | 305 | ||
308 | state = video->brightness->count - state; | 306 | state = video->brightness->count - state; |
309 | level = video->brightness->levels[state -1]; | 307 | level = video->brightness->levels[state - 1]; |
310 | return acpi_video_device_lcd_set_level(video, level); | 308 | return acpi_video_device_lcd_set_level(video, level); |
311 | } | 309 | } |
312 | 310 | ||
@@ -316,9 +314,11 @@ static const struct thermal_cooling_device_ops video_cooling_ops = { | |||
316 | .set_cur_state = video_set_cur_state, | 314 | .set_cur_state = video_set_cur_state, |
317 | }; | 315 | }; |
318 | 316 | ||
319 | /* -------------------------------------------------------------------------- | 317 | /* |
320 | Video Management | 318 | * -------------------------------------------------------------------------- |
321 | -------------------------------------------------------------------------- */ | 319 | * Video Management |
320 | * -------------------------------------------------------------------------- | ||
321 | */ | ||
322 | 322 | ||
323 | static int | 323 | static int |
324 | acpi_video_device_lcd_query_levels(struct acpi_video_device *device, | 324 | acpi_video_device_lcd_query_levels(struct acpi_video_device *device, |
@@ -345,7 +345,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device, | |||
345 | 345 | ||
346 | return 0; | 346 | return 0; |
347 | 347 | ||
348 | err: | 348 | err: |
349 | kfree(buffer.pointer); | 349 | kfree(buffer.pointer); |
350 | 350 | ||
351 | return status; | 351 | return status; |
@@ -355,14 +355,10 @@ static int | |||
355 | acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) | 355 | acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) |
356 | { | 356 | { |
357 | int status; | 357 | int status; |
358 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
359 | struct acpi_object_list args = { 1, &arg0 }; | ||
360 | int state; | 358 | int state; |
361 | 359 | ||
362 | arg0.integer.value = level; | 360 | status = acpi_execute_simple_method(device->dev->handle, |
363 | 361 | "_BCM", level); | |
364 | status = acpi_evaluate_object(device->dev->handle, "_BCM", | ||
365 | &args, NULL); | ||
366 | if (ACPI_FAILURE(status)) { | 362 | if (ACPI_FAILURE(status)) { |
367 | ACPI_ERROR((AE_INFO, "Evaluating _BCM failed")); | 363 | ACPI_ERROR((AE_INFO, "Evaluating _BCM failed")); |
368 | return -EIO; | 364 | return -EIO; |
@@ -546,7 +542,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
546 | if (device->brightness->levels[i] == *level) { | 542 | if (device->brightness->levels[i] == *level) { |
547 | device->brightness->curr = *level; | 543 | device->brightness->curr = *level; |
548 | return 0; | 544 | return 0; |
549 | } | 545 | } |
550 | /* | 546 | /* |
551 | * BQC returned an invalid level. | 547 | * BQC returned an invalid level. |
552 | * Stop using it. | 548 | * Stop using it. |
@@ -556,7 +552,8 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
556 | buf)); | 552 | buf)); |
557 | device->cap._BQC = device->cap._BCQ = 0; | 553 | device->cap._BQC = device->cap._BCQ = 0; |
558 | } else { | 554 | } else { |
559 | /* Fixme: | 555 | /* |
556 | * Fixme: | ||
560 | * should we return an error or ignore this failure? | 557 | * should we return an error or ignore this failure? |
561 | * dev->brightness->curr is a cached value which stores | 558 | * dev->brightness->curr is a cached value which stores |
562 | * the correct current backlight level in most cases. | 559 | * the correct current backlight level in most cases. |
@@ -615,8 +612,8 @@ acpi_video_device_EDID(struct acpi_video_device *device, | |||
615 | 612 | ||
616 | /* | 613 | /* |
617 | * Arg: | 614 | * Arg: |
618 | * video : video bus device pointer | 615 | * video : video bus device pointer |
619 | * bios_flag : | 616 | * bios_flag : |
620 | * 0. The system BIOS should NOT automatically switch(toggle) | 617 | * 0. The system BIOS should NOT automatically switch(toggle) |
621 | * the active display output. | 618 | * the active display output. |
622 | * 1. The system BIOS should automatically switch (toggle) the | 619 | * 1. The system BIOS should automatically switch (toggle) the |
@@ -628,9 +625,9 @@ acpi_video_device_EDID(struct acpi_video_device *device, | |||
628 | * lcd_flag : | 625 | * lcd_flag : |
629 | * 0. The system BIOS should automatically control the brightness level | 626 | * 0. The system BIOS should automatically control the brightness level |
630 | * of the LCD when the power changes from AC to DC | 627 | * of the LCD when the power changes from AC to DC |
631 | * 1. The system BIOS should NOT automatically control the brightness | 628 | * 1. The system BIOS should NOT automatically control the brightness |
632 | * level of the LCD when the power changes from AC to DC. | 629 | * level of the LCD when the power changes from AC to DC. |
633 | * Return Value: | 630 | * Return Value: |
634 | * -EINVAL wrong arg. | 631 | * -EINVAL wrong arg. |
635 | */ | 632 | */ |
636 | 633 | ||
@@ -638,18 +635,15 @@ static int | |||
638 | acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) | 635 | acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) |
639 | { | 636 | { |
640 | acpi_status status; | 637 | acpi_status status; |
641 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
642 | struct acpi_object_list args = { 1, &arg0 }; | ||
643 | 638 | ||
644 | if (!video->cap._DOS) | 639 | if (!video->cap._DOS) |
645 | return 0; | 640 | return 0; |
646 | 641 | ||
647 | if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) | 642 | if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) |
648 | return -EINVAL; | 643 | return -EINVAL; |
649 | arg0.integer.value = (lcd_flag << 2) | bios_flag; | 644 | video->dos_setting = (lcd_flag << 2) | bios_flag; |
650 | video->dos_setting = arg0.integer.value; | 645 | status = acpi_execute_simple_method(video->device->handle, "_DOS", |
651 | status = acpi_evaluate_object(video->device->handle, "_DOS", | 646 | (lcd_flag << 2) | bios_flag); |
652 | &args, NULL); | ||
653 | if (ACPI_FAILURE(status)) | 647 | if (ACPI_FAILURE(status)) |
654 | return -EIO; | 648 | return -EIO; |
655 | 649 | ||
@@ -717,8 +711,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device, | |||
717 | 711 | ||
718 | 712 | ||
719 | /* | 713 | /* |
720 | * Arg: | 714 | * Arg: |
721 | * device : video output device (LCD, CRT, ..) | 715 | * device : video output device (LCD, CRT, ..) |
722 | * | 716 | * |
723 | * Return Value: | 717 | * Return Value: |
724 | * Maximum brightness level | 718 | * Maximum brightness level |
@@ -806,16 +800,6 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
806 | br->count = count; | 800 | br->count = count; |
807 | device->brightness = br; | 801 | device->brightness = br; |
808 | 802 | ||
809 | /* Check the input/output of _BQC/_BCL/_BCM */ | ||
810 | if ((max_level < 100) && (max_level <= (count - 2))) | ||
811 | br->flags._BCL_use_index = 1; | ||
812 | |||
813 | /* | ||
814 | * _BCM is always consistent with _BCL, | ||
815 | * at least for all the laptops we have ever seen. | ||
816 | */ | ||
817 | br->flags._BCM_use_index = br->flags._BCL_use_index; | ||
818 | |||
819 | /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ | 803 | /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ |
820 | br->curr = level = max_level; | 804 | br->curr = level = max_level; |
821 | 805 | ||
@@ -877,7 +861,7 @@ out: | |||
877 | * device : video output device (LCD, CRT, ..) | 861 | * device : video output device (LCD, CRT, ..) |
878 | * | 862 | * |
879 | * Return Value: | 863 | * Return Value: |
880 | * None | 864 | * None |
881 | * | 865 | * |
882 | * Find out all required AML methods defined under the output | 866 | * Find out all required AML methods defined under the output |
883 | * device. | 867 | * device. |
@@ -885,28 +869,21 @@ out: | |||
885 | 869 | ||
886 | static void acpi_video_device_find_cap(struct acpi_video_device *device) | 870 | static void acpi_video_device_find_cap(struct acpi_video_device *device) |
887 | { | 871 | { |
888 | acpi_handle h_dummy1; | 872 | if (acpi_has_method(device->dev->handle, "_ADR")) |
889 | |||
890 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { | ||
891 | device->cap._ADR = 1; | 873 | device->cap._ADR = 1; |
892 | } | 874 | if (acpi_has_method(device->dev->handle, "_BCL")) |
893 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) { | ||
894 | device->cap._BCL = 1; | 875 | device->cap._BCL = 1; |
895 | } | 876 | if (acpi_has_method(device->dev->handle, "_BCM")) |
896 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { | ||
897 | device->cap._BCM = 1; | 877 | device->cap._BCM = 1; |
898 | } | 878 | if (acpi_has_method(device->dev->handle, "_BQC")) { |
899 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) | ||
900 | device->cap._BQC = 1; | 879 | device->cap._BQC = 1; |
901 | else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ", | 880 | } else if (acpi_has_method(device->dev->handle, "_BCQ")) { |
902 | &h_dummy1))) { | ||
903 | printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n"); | 881 | printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n"); |
904 | device->cap._BCQ = 1; | 882 | device->cap._BCQ = 1; |
905 | } | 883 | } |
906 | 884 | ||
907 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { | 885 | if (acpi_has_method(device->dev->handle, "_DDC")) |
908 | device->cap._DDC = 1; | 886 | device->cap._DDC = 1; |
909 | } | ||
910 | 887 | ||
911 | if (acpi_video_backlight_support()) { | 888 | if (acpi_video_backlight_support()) { |
912 | struct backlight_properties props; | 889 | struct backlight_properties props; |
@@ -914,7 +891,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
914 | acpi_handle acpi_parent; | 891 | acpi_handle acpi_parent; |
915 | struct device *parent = NULL; | 892 | struct device *parent = NULL; |
916 | int result; | 893 | int result; |
917 | static int count = 0; | 894 | static int count; |
918 | char *name; | 895 | char *name; |
919 | 896 | ||
920 | result = acpi_video_init_brightness(device); | 897 | result = acpi_video_init_brightness(device); |
@@ -983,37 +960,29 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
983 | } | 960 | } |
984 | 961 | ||
985 | /* | 962 | /* |
986 | * Arg: | 963 | * Arg: |
987 | * device : video output device (VGA) | 964 | * device : video output device (VGA) |
988 | * | 965 | * |
989 | * Return Value: | 966 | * Return Value: |
990 | * None | 967 | * None |
991 | * | 968 | * |
992 | * Find out all required AML methods defined under the video bus device. | 969 | * Find out all required AML methods defined under the video bus device. |
993 | */ | 970 | */ |
994 | 971 | ||
995 | static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | 972 | static void acpi_video_bus_find_cap(struct acpi_video_bus *video) |
996 | { | 973 | { |
997 | acpi_handle h_dummy1; | 974 | if (acpi_has_method(video->device->handle, "_DOS")) |
998 | |||
999 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { | ||
1000 | video->cap._DOS = 1; | 975 | video->cap._DOS = 1; |
1001 | } | 976 | if (acpi_has_method(video->device->handle, "_DOD")) |
1002 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) { | ||
1003 | video->cap._DOD = 1; | 977 | video->cap._DOD = 1; |
1004 | } | 978 | if (acpi_has_method(video->device->handle, "_ROM")) |
1005 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) { | ||
1006 | video->cap._ROM = 1; | 979 | video->cap._ROM = 1; |
1007 | } | 980 | if (acpi_has_method(video->device->handle, "_GPD")) |
1008 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) { | ||
1009 | video->cap._GPD = 1; | 981 | video->cap._GPD = 1; |
1010 | } | 982 | if (acpi_has_method(video->device->handle, "_SPD")) |
1011 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) { | ||
1012 | video->cap._SPD = 1; | 983 | video->cap._SPD = 1; |
1013 | } | 984 | if (acpi_has_method(video->device->handle, "_VPO")) |
1014 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) { | ||
1015 | video->cap._VPO = 1; | 985 | video->cap._VPO = 1; |
1016 | } | ||
1017 | } | 986 | } |
1018 | 987 | ||
1019 | /* | 988 | /* |
@@ -1034,7 +1003,8 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) | |||
1034 | return -ENODEV; | 1003 | return -ENODEV; |
1035 | pci_dev_put(dev); | 1004 | pci_dev_put(dev); |
1036 | 1005 | ||
1037 | /* Since there is no HID, CID and so on for VGA driver, we have | 1006 | /* |
1007 | * Since there is no HID, CID and so on for VGA driver, we have | ||
1038 | * to check well known required nodes. | 1008 | * to check well known required nodes. |
1039 | */ | 1009 | */ |
1040 | 1010 | ||
@@ -1064,12 +1034,14 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) | |||
1064 | return status; | 1034 | return status; |
1065 | } | 1035 | } |
1066 | 1036 | ||
1067 | /* -------------------------------------------------------------------------- | 1037 | /* |
1068 | Driver Interface | 1038 | * -------------------------------------------------------------------------- |
1069 | -------------------------------------------------------------------------- */ | 1039 | * Driver Interface |
1040 | * -------------------------------------------------------------------------- | ||
1041 | */ | ||
1070 | 1042 | ||
1071 | /* device interface */ | 1043 | /* device interface */ |
1072 | static struct acpi_video_device_attrib* | 1044 | static struct acpi_video_device_attrib * |
1073 | acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) | 1045 | acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) |
1074 | { | 1046 | { |
1075 | struct acpi_video_enumerated_device *ids; | 1047 | struct acpi_video_enumerated_device *ids; |
@@ -1107,7 +1079,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1107 | unsigned long long device_id; | 1079 | unsigned long long device_id; |
1108 | int status, device_type; | 1080 | int status, device_type; |
1109 | struct acpi_video_device *data; | 1081 | struct acpi_video_device *data; |
1110 | struct acpi_video_device_attrib* attribute; | 1082 | struct acpi_video_device_attrib *attribute; |
1111 | 1083 | ||
1112 | status = | 1084 | status = |
1113 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); | 1085 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); |
@@ -1129,7 +1101,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1129 | 1101 | ||
1130 | attribute = acpi_video_get_device_attr(video, device_id); | 1102 | attribute = acpi_video_get_device_attr(video, device_id); |
1131 | 1103 | ||
1132 | if((attribute != NULL) && attribute->device_id_scheme) { | 1104 | if (attribute && attribute->device_id_scheme) { |
1133 | switch (attribute->display_type) { | 1105 | switch (attribute->display_type) { |
1134 | case ACPI_VIDEO_DISPLAY_CRT: | 1106 | case ACPI_VIDEO_DISPLAY_CRT: |
1135 | data->flags.crt = 1; | 1107 | data->flags.crt = 1; |
@@ -1147,24 +1119,24 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1147 | data->flags.unknown = 1; | 1119 | data->flags.unknown = 1; |
1148 | break; | 1120 | break; |
1149 | } | 1121 | } |
1150 | if(attribute->bios_can_detect) | 1122 | if (attribute->bios_can_detect) |
1151 | data->flags.bios = 1; | 1123 | data->flags.bios = 1; |
1152 | } else { | 1124 | } else { |
1153 | /* Check for legacy IDs */ | 1125 | /* Check for legacy IDs */ |
1154 | device_type = acpi_video_get_device_type(video, device_id); | 1126 | device_type = acpi_video_get_device_type(video, device_id); |
1155 | /* Ignore bits 16 and 18-20 */ | 1127 | /* Ignore bits 16 and 18-20 */ |
1156 | switch (device_type & 0xffe2ffff) { | 1128 | switch (device_type & 0xffe2ffff) { |
1157 | case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: | 1129 | case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: |
1158 | data->flags.crt = 1; | 1130 | data->flags.crt = 1; |
1159 | break; | 1131 | break; |
1160 | case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: | 1132 | case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: |
1161 | data->flags.lcd = 1; | 1133 | data->flags.lcd = 1; |
1162 | break; | 1134 | break; |
1163 | case ACPI_VIDEO_DISPLAY_LEGACY_TV: | 1135 | case ACPI_VIDEO_DISPLAY_LEGACY_TV: |
1164 | data->flags.tvout = 1; | 1136 | data->flags.tvout = 1; |
1165 | break; | 1137 | break; |
1166 | default: | 1138 | default: |
1167 | data->flags.unknown = 1; | 1139 | data->flags.unknown = 1; |
1168 | } | 1140 | } |
1169 | } | 1141 | } |
1170 | 1142 | ||
@@ -1187,12 +1159,12 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1187 | 1159 | ||
1188 | /* | 1160 | /* |
1189 | * Arg: | 1161 | * Arg: |
1190 | * video : video bus device | 1162 | * video : video bus device |
1191 | * | 1163 | * |
1192 | * Return: | 1164 | * Return: |
1193 | * none | 1165 | * none |
1194 | * | 1166 | * |
1195 | * Enumerate the video device list of the video bus, | 1167 | * Enumerate the video device list of the video bus, |
1196 | * bind the ids with the corresponding video devices | 1168 | * bind the ids with the corresponding video devices |
1197 | * under the video bus. | 1169 | * under the video bus. |
1198 | */ | 1170 | */ |
@@ -1211,13 +1183,13 @@ static void acpi_video_device_rebind(struct acpi_video_bus *video) | |||
1211 | 1183 | ||
1212 | /* | 1184 | /* |
1213 | * Arg: | 1185 | * Arg: |
1214 | * video : video bus device | 1186 | * video : video bus device |
1215 | * device : video output device under the video | 1187 | * device : video output device under the video |
1216 | * bus | 1188 | * bus |
1217 | * | 1189 | * |
1218 | * Return: | 1190 | * Return: |
1219 | * none | 1191 | * none |
1220 | * | 1192 | * |
1221 | * Bind the ids with the corresponding video devices | 1193 | * Bind the ids with the corresponding video devices |
1222 | * under the video bus. | 1194 | * under the video bus. |
1223 | */ | 1195 | */ |
@@ -1240,11 +1212,11 @@ acpi_video_device_bind(struct acpi_video_bus *video, | |||
1240 | 1212 | ||
1241 | /* | 1213 | /* |
1242 | * Arg: | 1214 | * Arg: |
1243 | * video : video bus device | 1215 | * video : video bus device |
1244 | * | 1216 | * |
1245 | * Return: | 1217 | * Return: |
1246 | * < 0 : error | 1218 | * < 0 : error |
1247 | * | 1219 | * |
1248 | * Call _DOD to enumerate all devices attached to display adapter | 1220 | * Call _DOD to enumerate all devices attached to display adapter |
1249 | * | 1221 | * |
1250 | */ | 1222 | */ |
@@ -1305,7 +1277,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1305 | video->attached_array = active_list; | 1277 | video->attached_array = active_list; |
1306 | video->attached_count = count; | 1278 | video->attached_count = count; |
1307 | 1279 | ||
1308 | out: | 1280 | out: |
1309 | kfree(buffer.pointer); | 1281 | kfree(buffer.pointer); |
1310 | return status; | 1282 | return status; |
1311 | } | 1283 | } |
@@ -1572,7 +1544,6 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
1572 | switch (event) { | 1544 | switch (event) { |
1573 | case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, | 1545 | case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, |
1574 | * most likely via hotkey. */ | 1546 | * most likely via hotkey. */ |
1575 | acpi_bus_generate_proc_event(device, event, 0); | ||
1576 | keycode = KEY_SWITCHVIDEOMODE; | 1547 | keycode = KEY_SWITCHVIDEOMODE; |
1577 | break; | 1548 | break; |
1578 | 1549 | ||
@@ -1580,20 +1551,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
1580 | * connector. */ | 1551 | * connector. */ |
1581 | acpi_video_device_enumerate(video); | 1552 | acpi_video_device_enumerate(video); |
1582 | acpi_video_device_rebind(video); | 1553 | acpi_video_device_rebind(video); |
1583 | acpi_bus_generate_proc_event(device, event, 0); | ||
1584 | keycode = KEY_SWITCHVIDEOMODE; | 1554 | keycode = KEY_SWITCHVIDEOMODE; |
1585 | break; | 1555 | break; |
1586 | 1556 | ||
1587 | case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ | 1557 | case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ |
1588 | acpi_bus_generate_proc_event(device, event, 0); | ||
1589 | keycode = KEY_SWITCHVIDEOMODE; | 1558 | keycode = KEY_SWITCHVIDEOMODE; |
1590 | break; | 1559 | break; |
1591 | case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ | 1560 | case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ |
1592 | acpi_bus_generate_proc_event(device, event, 0); | ||
1593 | keycode = KEY_VIDEO_NEXT; | 1561 | keycode = KEY_VIDEO_NEXT; |
1594 | break; | 1562 | break; |
1595 | case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ | 1563 | case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ |
1596 | acpi_bus_generate_proc_event(device, event, 0); | ||
1597 | keycode = KEY_VIDEO_PREV; | 1564 | keycode = KEY_VIDEO_PREV; |
1598 | break; | 1565 | break; |
1599 | 1566 | ||
@@ -1636,31 +1603,26 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
1636 | case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ | 1603 | case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ |
1637 | if (brightness_switch_enabled) | 1604 | if (brightness_switch_enabled) |
1638 | acpi_video_switch_brightness(video_device, event); | 1605 | acpi_video_switch_brightness(video_device, event); |
1639 | acpi_bus_generate_proc_event(device, event, 0); | ||
1640 | keycode = KEY_BRIGHTNESS_CYCLE; | 1606 | keycode = KEY_BRIGHTNESS_CYCLE; |
1641 | break; | 1607 | break; |
1642 | case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ | 1608 | case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ |
1643 | if (brightness_switch_enabled) | 1609 | if (brightness_switch_enabled) |
1644 | acpi_video_switch_brightness(video_device, event); | 1610 | acpi_video_switch_brightness(video_device, event); |
1645 | acpi_bus_generate_proc_event(device, event, 0); | ||
1646 | keycode = KEY_BRIGHTNESSUP; | 1611 | keycode = KEY_BRIGHTNESSUP; |
1647 | break; | 1612 | break; |
1648 | case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ | 1613 | case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ |
1649 | if (brightness_switch_enabled) | 1614 | if (brightness_switch_enabled) |
1650 | acpi_video_switch_brightness(video_device, event); | 1615 | acpi_video_switch_brightness(video_device, event); |
1651 | acpi_bus_generate_proc_event(device, event, 0); | ||
1652 | keycode = KEY_BRIGHTNESSDOWN; | 1616 | keycode = KEY_BRIGHTNESSDOWN; |
1653 | break; | 1617 | break; |
1654 | case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ | 1618 | case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ |
1655 | if (brightness_switch_enabled) | 1619 | if (brightness_switch_enabled) |
1656 | acpi_video_switch_brightness(video_device, event); | 1620 | acpi_video_switch_brightness(video_device, event); |
1657 | acpi_bus_generate_proc_event(device, event, 0); | ||
1658 | keycode = KEY_BRIGHTNESS_ZERO; | 1621 | keycode = KEY_BRIGHTNESS_ZERO; |
1659 | break; | 1622 | break; |
1660 | case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ | 1623 | case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ |
1661 | if (brightness_switch_enabled) | 1624 | if (brightness_switch_enabled) |
1662 | acpi_video_switch_brightness(video_device, event); | 1625 | acpi_video_switch_brightness(video_device, event); |
1663 | acpi_bus_generate_proc_event(device, event, 0); | ||
1664 | keycode = KEY_DISPLAY_OFF; | 1626 | keycode = KEY_DISPLAY_OFF; |
1665 | break; | 1627 | break; |
1666 | default: | 1628 | default: |
@@ -1760,7 +1722,7 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1760 | if (!strcmp(device->pnp.bus_id, "VID")) { | 1722 | if (!strcmp(device->pnp.bus_id, "VID")) { |
1761 | if (instance) | 1723 | if (instance) |
1762 | device->pnp.bus_id[3] = '0' + instance; | 1724 | device->pnp.bus_id[3] = '0' + instance; |
1763 | instance ++; | 1725 | instance++; |
1764 | } | 1726 | } |
1765 | /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ | 1727 | /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ |
1766 | if (!strcmp(device->pnp.bus_id, "VGA")) { | 1728 | if (!strcmp(device->pnp.bus_id, "VGA")) { |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index c3397748ba46..940edbf2fe8f 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -53,14 +53,13 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | |||
53 | void **retyurn_value) | 53 | void **retyurn_value) |
54 | { | 54 | { |
55 | long *cap = context; | 55 | long *cap = context; |
56 | acpi_handle h_dummy; | ||
57 | 56 | ||
58 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) && | 57 | if (acpi_has_method(handle, "_BCM") && |
59 | ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) { | 58 | acpi_has_method(handle, "_BCL")) { |
60 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " | 59 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " |
61 | "support\n")); | 60 | "support\n")); |
62 | *cap |= ACPI_VIDEO_BACKLIGHT; | 61 | *cap |= ACPI_VIDEO_BACKLIGHT; |
63 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) | 62 | if (!acpi_has_method(handle, "_BQC")) |
64 | printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, " | 63 | printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, " |
65 | "cannot determine initial brightness\n"); | 64 | "cannot determine initial brightness\n"); |
66 | /* We have backlight support, no need to scan further */ | 65 | /* We have backlight support, no need to scan further */ |
@@ -79,22 +78,20 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | |||
79 | */ | 78 | */ |
80 | long acpi_is_video_device(acpi_handle handle) | 79 | long acpi_is_video_device(acpi_handle handle) |
81 | { | 80 | { |
82 | acpi_handle h_dummy; | ||
83 | long video_caps = 0; | 81 | long video_caps = 0; |
84 | 82 | ||
85 | /* Is this device able to support video switching ? */ | 83 | /* Is this device able to support video switching ? */ |
86 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_DOD", &h_dummy)) || | 84 | if (acpi_has_method(handle, "_DOD") || acpi_has_method(handle, "_DOS")) |
87 | ACPI_SUCCESS(acpi_get_handle(handle, "_DOS", &h_dummy))) | ||
88 | video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; | 85 | video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; |
89 | 86 | ||
90 | /* Is this device able to retrieve a video ROM ? */ | 87 | /* Is this device able to retrieve a video ROM ? */ |
91 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_ROM", &h_dummy))) | 88 | if (acpi_has_method(handle, "_ROM")) |
92 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; | 89 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; |
93 | 90 | ||
94 | /* Is this device able to configure which video head to be POSTed ? */ | 91 | /* Is this device able to configure which video head to be POSTed ? */ |
95 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_VPO", &h_dummy)) && | 92 | if (acpi_has_method(handle, "_VPO") && |
96 | ACPI_SUCCESS(acpi_get_handle(handle, "_GPD", &h_dummy)) && | 93 | acpi_has_method(handle, "_GPD") && |
97 | ACPI_SUCCESS(acpi_get_handle(handle, "_SPD", &h_dummy))) | 94 | acpi_has_method(handle, "_SPD")) |
98 | video_caps |= ACPI_VIDEO_DEVICE_POSTING; | 95 | video_caps |= ACPI_VIDEO_DEVICE_POSTING; |
99 | 96 | ||
100 | /* Only check for backlight functionality if one of the above hit. */ | 97 | /* Only check for backlight functionality if one of the above hit. */ |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index cf4e7020adac..da8170dfc90f 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -947,11 +947,11 @@ static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state) | |||
947 | continue; | 947 | continue; |
948 | 948 | ||
949 | acpi_bus_set_power(dev_handle, state.event & PM_EVENT_RESUME ? | 949 | acpi_bus_set_power(dev_handle, state.event & PM_EVENT_RESUME ? |
950 | ACPI_STATE_D0 : ACPI_STATE_D3); | 950 | ACPI_STATE_D0 : ACPI_STATE_D3_COLD); |
951 | } | 951 | } |
952 | 952 | ||
953 | if (!(state.event & PM_EVENT_RESUME)) | 953 | if (!(state.event & PM_EVENT_RESUME)) |
954 | acpi_bus_set_power(port_handle, ACPI_STATE_D3); | 954 | acpi_bus_set_power(port_handle, ACPI_STATE_D3_COLD); |
955 | } | 955 | } |
956 | 956 | ||
957 | /** | 957 | /** |
diff --git a/drivers/base/core.c b/drivers/base/core.c index c7b0925f627a..c7cfadcf6752 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -50,6 +50,28 @@ static struct kobject *dev_kobj; | |||
50 | struct kobject *sysfs_dev_char_kobj; | 50 | struct kobject *sysfs_dev_char_kobj; |
51 | struct kobject *sysfs_dev_block_kobj; | 51 | struct kobject *sysfs_dev_block_kobj; |
52 | 52 | ||
53 | static DEFINE_MUTEX(device_hotplug_lock); | ||
54 | |||
55 | void lock_device_hotplug(void) | ||
56 | { | ||
57 | mutex_lock(&device_hotplug_lock); | ||
58 | } | ||
59 | |||
60 | void unlock_device_hotplug(void) | ||
61 | { | ||
62 | mutex_unlock(&device_hotplug_lock); | ||
63 | } | ||
64 | |||
65 | int lock_device_hotplug_sysfs(void) | ||
66 | { | ||
67 | if (mutex_trylock(&device_hotplug_lock)) | ||
68 | return 0; | ||
69 | |||
70 | /* Avoid busy looping (5 ms of sleep should do). */ | ||
71 | msleep(5); | ||
72 | return restart_syscall(); | ||
73 | } | ||
74 | |||
53 | #ifdef CONFIG_BLOCK | 75 | #ifdef CONFIG_BLOCK |
54 | static inline int device_is_not_partition(struct device *dev) | 76 | static inline int device_is_not_partition(struct device *dev) |
55 | { | 77 | { |
@@ -407,9 +429,9 @@ static ssize_t online_show(struct device *dev, struct device_attribute *attr, | |||
407 | { | 429 | { |
408 | bool val; | 430 | bool val; |
409 | 431 | ||
410 | lock_device_hotplug(); | 432 | device_lock(dev); |
411 | val = !dev->offline; | 433 | val = !dev->offline; |
412 | unlock_device_hotplug(); | 434 | device_unlock(dev); |
413 | return sprintf(buf, "%u\n", val); | 435 | return sprintf(buf, "%u\n", val); |
414 | } | 436 | } |
415 | 437 | ||
@@ -423,7 +445,10 @@ static ssize_t online_store(struct device *dev, struct device_attribute *attr, | |||
423 | if (ret < 0) | 445 | if (ret < 0) |
424 | return ret; | 446 | return ret; |
425 | 447 | ||
426 | lock_device_hotplug(); | 448 | ret = lock_device_hotplug_sysfs(); |
449 | if (ret) | ||
450 | return ret; | ||
451 | |||
427 | ret = val ? device_online(dev) : device_offline(dev); | 452 | ret = val ? device_online(dev) : device_offline(dev); |
428 | unlock_device_hotplug(); | 453 | unlock_device_hotplug(); |
429 | return ret < 0 ? ret : count; | 454 | return ret < 0 ? ret : count; |
@@ -1450,18 +1475,6 @@ int __init devices_init(void) | |||
1450 | return -ENOMEM; | 1475 | return -ENOMEM; |
1451 | } | 1476 | } |
1452 | 1477 | ||
1453 | static DEFINE_MUTEX(device_hotplug_lock); | ||
1454 | |||
1455 | void lock_device_hotplug(void) | ||
1456 | { | ||
1457 | mutex_lock(&device_hotplug_lock); | ||
1458 | } | ||
1459 | |||
1460 | void unlock_device_hotplug(void) | ||
1461 | { | ||
1462 | mutex_unlock(&device_hotplug_lock); | ||
1463 | } | ||
1464 | |||
1465 | static int device_check_offline(struct device *dev, void *not_used) | 1478 | static int device_check_offline(struct device *dev, void *not_used) |
1466 | { | 1479 | { |
1467 | int ret; | 1480 | int ret; |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 6bfaaca6955e..848ebbd25717 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/percpu.h> | 15 | #include <linux/percpu.h> |
16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
17 | #include <linux/of.h> | ||
17 | 18 | ||
18 | #include "base.h" | 19 | #include "base.h" |
19 | 20 | ||
@@ -293,6 +294,7 @@ int register_cpu(struct cpu *cpu, int num) | |||
293 | cpu->dev.release = cpu_device_release; | 294 | cpu->dev.release = cpu_device_release; |
294 | cpu->dev.offline_disabled = !cpu->hotpluggable; | 295 | cpu->dev.offline_disabled = !cpu->hotpluggable; |
295 | cpu->dev.offline = !cpu_online(num); | 296 | cpu->dev.offline = !cpu_online(num); |
297 | cpu->dev.of_node = of_get_cpu_node(num, NULL); | ||
296 | #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE | 298 | #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE |
297 | cpu->dev.bus->uevent = arch_cpu_uevent; | 299 | cpu->dev.bus->uevent = arch_cpu_uevent; |
298 | #endif | 300 | #endif |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 1c617623c8ae..9e59f6535c44 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -321,7 +321,9 @@ store_mem_state(struct device *dev, | |||
321 | struct memory_block *mem = to_memory_block(dev); | 321 | struct memory_block *mem = to_memory_block(dev); |
322 | int ret, online_type; | 322 | int ret, online_type; |
323 | 323 | ||
324 | lock_device_hotplug(); | 324 | ret = lock_device_hotplug_sysfs(); |
325 | if (ret) | ||
326 | return ret; | ||
325 | 327 | ||
326 | if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) | 328 | if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) |
327 | online_type = ONLINE_KERNEL; | 329 | online_type = ONLINE_KERNEL; |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 5a9b6569dd74..9f098a82cf04 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
29 | #include <linux/async.h> | 29 | #include <linux/async.h> |
30 | #include <linux/suspend.h> | 30 | #include <linux/suspend.h> |
31 | #include <trace/events/power.h> | ||
31 | #include <linux/cpuidle.h> | 32 | #include <linux/cpuidle.h> |
32 | #include "../base.h" | 33 | #include "../base.h" |
33 | #include "power.h" | 34 | #include "power.h" |
@@ -56,6 +57,30 @@ static pm_message_t pm_transition; | |||
56 | 57 | ||
57 | static int async_error; | 58 | static int async_error; |
58 | 59 | ||
60 | static char *pm_verb(int event) | ||
61 | { | ||
62 | switch (event) { | ||
63 | case PM_EVENT_SUSPEND: | ||
64 | return "suspend"; | ||
65 | case PM_EVENT_RESUME: | ||
66 | return "resume"; | ||
67 | case PM_EVENT_FREEZE: | ||
68 | return "freeze"; | ||
69 | case PM_EVENT_QUIESCE: | ||
70 | return "quiesce"; | ||
71 | case PM_EVENT_HIBERNATE: | ||
72 | return "hibernate"; | ||
73 | case PM_EVENT_THAW: | ||
74 | return "thaw"; | ||
75 | case PM_EVENT_RESTORE: | ||
76 | return "restore"; | ||
77 | case PM_EVENT_RECOVER: | ||
78 | return "recover"; | ||
79 | default: | ||
80 | return "(unknown PM event)"; | ||
81 | } | ||
82 | } | ||
83 | |||
59 | /** | 84 | /** |
60 | * device_pm_sleep_init - Initialize system suspend-related device fields. | 85 | * device_pm_sleep_init - Initialize system suspend-related device fields. |
61 | * @dev: Device object being initialized. | 86 | * @dev: Device object being initialized. |
@@ -172,16 +197,21 @@ static ktime_t initcall_debug_start(struct device *dev) | |||
172 | } | 197 | } |
173 | 198 | ||
174 | static void initcall_debug_report(struct device *dev, ktime_t calltime, | 199 | static void initcall_debug_report(struct device *dev, ktime_t calltime, |
175 | int error) | 200 | int error, pm_message_t state, char *info) |
176 | { | 201 | { |
177 | ktime_t delta, rettime; | 202 | ktime_t rettime; |
203 | s64 nsecs; | ||
204 | |||
205 | rettime = ktime_get(); | ||
206 | nsecs = (s64) ktime_to_ns(ktime_sub(rettime, calltime)); | ||
178 | 207 | ||
179 | if (pm_print_times_enabled) { | 208 | if (pm_print_times_enabled) { |
180 | rettime = ktime_get(); | ||
181 | delta = ktime_sub(rettime, calltime); | ||
182 | pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), | 209 | pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), |
183 | error, (unsigned long long)ktime_to_ns(delta) >> 10); | 210 | error, (unsigned long long)nsecs >> 10); |
184 | } | 211 | } |
212 | |||
213 | trace_device_pm_report_time(dev, info, nsecs, pm_verb(state.event), | ||
214 | error); | ||
185 | } | 215 | } |
186 | 216 | ||
187 | /** | 217 | /** |
@@ -309,30 +339,6 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t stat | |||
309 | return NULL; | 339 | return NULL; |
310 | } | 340 | } |
311 | 341 | ||
312 | static char *pm_verb(int event) | ||
313 | { | ||
314 | switch (event) { | ||
315 | case PM_EVENT_SUSPEND: | ||
316 | return "suspend"; | ||
317 | case PM_EVENT_RESUME: | ||
318 | return "resume"; | ||
319 | case PM_EVENT_FREEZE: | ||
320 | return "freeze"; | ||
321 | case PM_EVENT_QUIESCE: | ||
322 | return "quiesce"; | ||
323 | case PM_EVENT_HIBERNATE: | ||
324 | return "hibernate"; | ||
325 | case PM_EVENT_THAW: | ||
326 | return "thaw"; | ||
327 | case PM_EVENT_RESTORE: | ||
328 | return "restore"; | ||
329 | case PM_EVENT_RECOVER: | ||
330 | return "recover"; | ||
331 | default: | ||
332 | return "(unknown PM event)"; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info) | 342 | static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info) |
337 | { | 343 | { |
338 | dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event), | 344 | dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event), |
@@ -379,7 +385,7 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev, | |||
379 | error = cb(dev); | 385 | error = cb(dev); |
380 | suspend_report_result(cb, error); | 386 | suspend_report_result(cb, error); |
381 | 387 | ||
382 | initcall_debug_report(dev, calltime, error); | 388 | initcall_debug_report(dev, calltime, error, state, info); |
383 | 389 | ||
384 | return error; | 390 | return error; |
385 | } | 391 | } |
@@ -1027,7 +1033,8 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end); | |||
1027 | * @cb: Suspend callback to execute. | 1033 | * @cb: Suspend callback to execute. |
1028 | */ | 1034 | */ |
1029 | static int legacy_suspend(struct device *dev, pm_message_t state, | 1035 | static int legacy_suspend(struct device *dev, pm_message_t state, |
1030 | int (*cb)(struct device *dev, pm_message_t state)) | 1036 | int (*cb)(struct device *dev, pm_message_t state), |
1037 | char *info) | ||
1031 | { | 1038 | { |
1032 | int error; | 1039 | int error; |
1033 | ktime_t calltime; | 1040 | ktime_t calltime; |
@@ -1037,7 +1044,7 @@ static int legacy_suspend(struct device *dev, pm_message_t state, | |||
1037 | error = cb(dev, state); | 1044 | error = cb(dev, state); |
1038 | suspend_report_result(cb, error); | 1045 | suspend_report_result(cb, error); |
1039 | 1046 | ||
1040 | initcall_debug_report(dev, calltime, error); | 1047 | initcall_debug_report(dev, calltime, error, state, info); |
1041 | 1048 | ||
1042 | return error; | 1049 | return error; |
1043 | } | 1050 | } |
@@ -1097,7 +1104,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
1097 | goto Run; | 1104 | goto Run; |
1098 | } else if (dev->class->suspend) { | 1105 | } else if (dev->class->suspend) { |
1099 | pm_dev_dbg(dev, state, "legacy class "); | 1106 | pm_dev_dbg(dev, state, "legacy class "); |
1100 | error = legacy_suspend(dev, state, dev->class->suspend); | 1107 | error = legacy_suspend(dev, state, dev->class->suspend, |
1108 | "legacy class "); | ||
1101 | goto End; | 1109 | goto End; |
1102 | } | 1110 | } |
1103 | } | 1111 | } |
@@ -1108,7 +1116,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
1108 | callback = pm_op(dev->bus->pm, state); | 1116 | callback = pm_op(dev->bus->pm, state); |
1109 | } else if (dev->bus->suspend) { | 1117 | } else if (dev->bus->suspend) { |
1110 | pm_dev_dbg(dev, state, "legacy bus "); | 1118 | pm_dev_dbg(dev, state, "legacy bus "); |
1111 | error = legacy_suspend(dev, state, dev->bus->suspend); | 1119 | error = legacy_suspend(dev, state, dev->bus->suspend, |
1120 | "legacy bus "); | ||
1112 | goto End; | 1121 | goto End; |
1113 | } | 1122 | } |
1114 | } | 1123 | } |
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index c8ec186303db..ef89897c6043 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
@@ -460,6 +460,7 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) | |||
460 | srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp); | 460 | srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp); |
461 | return 0; | 461 | return 0; |
462 | } | 462 | } |
463 | EXPORT_SYMBOL_GPL(opp_add); | ||
463 | 464 | ||
464 | /** | 465 | /** |
465 | * opp_set_availability() - helper to set the availability of an opp | 466 | * opp_set_availability() - helper to set the availability of an opp |
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 733288967d4d..200926699778 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c | |||
@@ -122,17 +122,8 @@ EXPORT_SYMBOL_GPL(cci_ace_get_port); | |||
122 | 122 | ||
123 | static void __init cci_ace_init_ports(void) | 123 | static void __init cci_ace_init_ports(void) |
124 | { | 124 | { |
125 | int port, ac, cpu; | 125 | int port, cpu; |
126 | u64 hwid; | 126 | struct device_node *cpun; |
127 | const u32 *cell; | ||
128 | struct device_node *cpun, *cpus; | ||
129 | |||
130 | cpus = of_find_node_by_path("/cpus"); | ||
131 | if (WARN(!cpus, "Missing cpus node, bailing out\n")) | ||
132 | return; | ||
133 | |||
134 | if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac))) | ||
135 | ac = of_n_addr_cells(cpus); | ||
136 | 127 | ||
137 | /* | 128 | /* |
138 | * Port index look-up speeds up the function disabling ports by CPU, | 129 | * Port index look-up speeds up the function disabling ports by CPU, |
@@ -141,18 +132,13 @@ static void __init cci_ace_init_ports(void) | |||
141 | * The stashed index array is initialized for all possible CPUs | 132 | * The stashed index array is initialized for all possible CPUs |
142 | * at probe time. | 133 | * at probe time. |
143 | */ | 134 | */ |
144 | for_each_child_of_node(cpus, cpun) { | 135 | for_each_possible_cpu(cpu) { |
145 | if (of_node_cmp(cpun->type, "cpu")) | 136 | /* too early to use cpu->of_node */ |
146 | continue; | 137 | cpun = of_get_cpu_node(cpu, NULL); |
147 | cell = of_get_property(cpun, "reg", NULL); | ||
148 | if (WARN(!cell, "%s: missing reg property\n", cpun->full_name)) | ||
149 | continue; | ||
150 | |||
151 | hwid = of_read_number(cell, ac); | ||
152 | cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK); | ||
153 | 138 | ||
154 | if (cpu < 0 || !cpu_possible(cpu)) | 139 | if (WARN(!cpun, "Missing cpu device node\n")) |
155 | continue; | 140 | continue; |
141 | |||
156 | port = __cci_ace_get_port(cpun, ACE_PORT); | 142 | port = __cci_ace_get_port(cpun, ACE_PORT); |
157 | if (port < 0) | 143 | if (port < 0) |
158 | continue; | 144 | continue; |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index bf2349dbbf7f..7cc1fe2241fd 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -876,11 +876,6 @@ found: | |||
876 | if (useinput) | 876 | if (useinput) |
877 | sonypi_report_input_event(event); | 877 | sonypi_report_input_event(event); |
878 | 878 | ||
879 | #ifdef CONFIG_ACPI | ||
880 | if (sonypi_acpi_device) | ||
881 | acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); | ||
882 | #endif | ||
883 | |||
884 | kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event, | 879 | kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event, |
885 | sizeof(event), &sonypi_device.fifo_lock); | 880 | sizeof(event), &sonypi_device.fifo_lock); |
886 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); | 881 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); |
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index de4d5d93c3fd..0fa204b244bd 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
@@ -17,37 +17,47 @@ config ARM_DT_BL_CPUFREQ | |||
17 | big.LITTLE platform. This gets frequency tables from DT. | 17 | big.LITTLE platform. This gets frequency tables from DT. |
18 | 18 | ||
19 | config ARM_EXYNOS_CPUFREQ | 19 | config ARM_EXYNOS_CPUFREQ |
20 | bool "SAMSUNG EXYNOS SoCs" | 20 | bool |
21 | depends on ARCH_EXYNOS | ||
22 | select CPU_FREQ_TABLE | 21 | select CPU_FREQ_TABLE |
23 | default y | ||
24 | help | ||
25 | This adds the CPUFreq driver common part for Samsung | ||
26 | EXYNOS SoCs. | ||
27 | |||
28 | If in doubt, say N. | ||
29 | 22 | ||
30 | config ARM_EXYNOS4210_CPUFREQ | 23 | config ARM_EXYNOS4210_CPUFREQ |
31 | def_bool CPU_EXYNOS4210 | 24 | bool "SAMSUNG EXYNOS4210" |
25 | depends on CPU_EXYNOS4210 | ||
26 | default y | ||
27 | select ARM_EXYNOS_CPUFREQ | ||
32 | help | 28 | help |
33 | This adds the CPUFreq driver for Samsung EXYNOS4210 | 29 | This adds the CPUFreq driver for Samsung EXYNOS4210 |
34 | SoC (S5PV310 or S5PC210). | 30 | SoC (S5PV310 or S5PC210). |
35 | 31 | ||
32 | If in doubt, say N. | ||
33 | |||
36 | config ARM_EXYNOS4X12_CPUFREQ | 34 | config ARM_EXYNOS4X12_CPUFREQ |
37 | def_bool (SOC_EXYNOS4212 || SOC_EXYNOS4412) | 35 | bool "SAMSUNG EXYNOS4x12" |
36 | depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) | ||
37 | default y | ||
38 | select ARM_EXYNOS_CPUFREQ | ||
38 | help | 39 | help |
39 | This adds the CPUFreq driver for Samsung EXYNOS4X12 | 40 | This adds the CPUFreq driver for Samsung EXYNOS4X12 |
40 | SoC (EXYNOS4212 or EXYNOS4412). | 41 | SoC (EXYNOS4212 or EXYNOS4412). |
41 | 42 | ||
43 | If in doubt, say N. | ||
44 | |||
42 | config ARM_EXYNOS5250_CPUFREQ | 45 | config ARM_EXYNOS5250_CPUFREQ |
43 | def_bool SOC_EXYNOS5250 | 46 | bool "SAMSUNG EXYNOS5250" |
47 | depends on SOC_EXYNOS5250 | ||
48 | default y | ||
49 | select ARM_EXYNOS_CPUFREQ | ||
44 | help | 50 | help |
45 | This adds the CPUFreq driver for Samsung EXYNOS5250 | 51 | This adds the CPUFreq driver for Samsung EXYNOS5250 |
46 | SoC. | 52 | SoC. |
47 | 53 | ||
54 | If in doubt, say N. | ||
55 | |||
48 | config ARM_EXYNOS5440_CPUFREQ | 56 | config ARM_EXYNOS5440_CPUFREQ |
49 | def_bool SOC_EXYNOS5440 | 57 | bool "SAMSUNG EXYNOS5440" |
58 | depends on SOC_EXYNOS5440 | ||
50 | depends on HAVE_CLK && PM_OPP && OF | 59 | depends on HAVE_CLK && PM_OPP && OF |
60 | default y | ||
51 | select CPU_FREQ_TABLE | 61 | select CPU_FREQ_TABLE |
52 | help | 62 | help |
53 | This adds the CPUFreq driver for Samsung EXYNOS5440 | 63 | This adds the CPUFreq driver for Samsung EXYNOS5440 |
@@ -55,6 +65,8 @@ config ARM_EXYNOS5440_CPUFREQ | |||
55 | different than previous exynos controllers so not using | 65 | different than previous exynos controllers so not using |
56 | the common exynos framework. | 66 | the common exynos framework. |
57 | 67 | ||
68 | If in doubt, say N. | ||
69 | |||
58 | config ARM_HIGHBANK_CPUFREQ | 70 | config ARM_HIGHBANK_CPUFREQ |
59 | tristate "Calxeda Highbank-based" | 71 | tristate "Calxeda Highbank-based" |
60 | depends on ARCH_HIGHBANK | 72 | depends on ARCH_HIGHBANK |
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index d345b5a7aa71..ad5866c2ada0 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -23,7 +23,7 @@ obj-$(CONFIG_GENERIC_CPUFREQ_CPU0) += cpufreq-cpu0.o | |||
23 | # powernow-k8 can load then. ACPI is preferred to all other hardware-specific drivers. | 23 | # powernow-k8 can load then. ACPI is preferred to all other hardware-specific drivers. |
24 | # speedstep-* is preferred over p4-clockmod. | 24 | # speedstep-* is preferred over p4-clockmod. |
25 | 25 | ||
26 | obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o mperf.o | 26 | obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o |
27 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o | 27 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o |
28 | obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o | 28 | obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o |
29 | obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o | 29 | obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 39264020b88a..a1260b4549db 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <asm/msr.h> | 45 | #include <asm/msr.h> |
46 | #include <asm/processor.h> | 46 | #include <asm/processor.h> |
47 | #include <asm/cpufeature.h> | 47 | #include <asm/cpufeature.h> |
48 | #include "mperf.h" | ||
49 | 48 | ||
50 | MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); | 49 | MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); |
51 | MODULE_DESCRIPTION("ACPI Processor P-States Driver"); | 50 | MODULE_DESCRIPTION("ACPI Processor P-States Driver"); |
@@ -198,7 +197,7 @@ static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) | |||
198 | return sprintf(buf, "%u\n", boost_enabled); | 197 | return sprintf(buf, "%u\n", boost_enabled); |
199 | } | 198 | } |
200 | 199 | ||
201 | static struct freq_attr cpb = __ATTR(cpb, 0644, show_cpb, store_cpb); | 200 | cpufreq_freq_attr_rw(cpb); |
202 | #endif | 201 | #endif |
203 | 202 | ||
204 | static int check_est_cpu(unsigned int cpuid) | 203 | static int check_est_cpu(unsigned int cpuid) |
@@ -710,7 +709,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
710 | return blacklisted; | 709 | return blacklisted; |
711 | #endif | 710 | #endif |
712 | 711 | ||
713 | data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); | 712 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
714 | if (!data) | 713 | if (!data) |
715 | return -ENOMEM; | 714 | return -ENOMEM; |
716 | 715 | ||
@@ -800,7 +799,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
800 | goto err_unreg; | 799 | goto err_unreg; |
801 | } | 800 | } |
802 | 801 | ||
803 | data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * | 802 | data->freq_table = kmalloc(sizeof(*data->freq_table) * |
804 | (perf->state_count+1), GFP_KERNEL); | 803 | (perf->state_count+1), GFP_KERNEL); |
805 | if (!data->freq_table) { | 804 | if (!data->freq_table) { |
806 | result = -ENOMEM; | 805 | result = -ENOMEM; |
@@ -861,10 +860,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
861 | /* notify BIOS that we exist */ | 860 | /* notify BIOS that we exist */ |
862 | acpi_processor_notify_smm(THIS_MODULE); | 861 | acpi_processor_notify_smm(THIS_MODULE); |
863 | 862 | ||
864 | /* Check for APERF/MPERF support in hardware */ | ||
865 | if (boot_cpu_has(X86_FEATURE_APERFMPERF)) | ||
866 | acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf; | ||
867 | |||
868 | pr_debug("CPU%u - ACPI performance management activated.\n", cpu); | 863 | pr_debug("CPU%u - ACPI performance management activated.\n", cpu); |
869 | for (i = 0; i < perf->state_count; i++) | 864 | for (i = 0; i < perf->state_count; i++) |
870 | pr_debug(" %cP%d: %d MHz, %d mW, %d uS\n", | 865 | pr_debug(" %cP%d: %d MHz, %d mW, %d uS\n", |
@@ -941,7 +936,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = { | |||
941 | .exit = acpi_cpufreq_cpu_exit, | 936 | .exit = acpi_cpufreq_cpu_exit, |
942 | .resume = acpi_cpufreq_resume, | 937 | .resume = acpi_cpufreq_resume, |
943 | .name = "acpi-cpufreq", | 938 | .name = "acpi-cpufreq", |
944 | .owner = THIS_MODULE, | ||
945 | .attr = acpi_cpufreq_attr, | 939 | .attr = acpi_cpufreq_attr, |
946 | }; | 940 | }; |
947 | 941 | ||
diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index fd9e3ea6a480..480c0bd0468d 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c | |||
@@ -19,12 +19,11 @@ | |||
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
21 | 21 | ||
22 | #include <linux/cpu.h> | ||
23 | #include <linux/cpufreq.h> | 22 | #include <linux/cpufreq.h> |
24 | #include <linux/device.h> | 23 | #include <linux/device.h> |
25 | #include <linux/export.h> | 24 | #include <linux/export.h> |
26 | #include <linux/module.h> | 25 | #include <linux/module.h> |
27 | #include <linux/of.h> | 26 | #include <linux/of_device.h> |
28 | #include <linux/opp.h> | 27 | #include <linux/opp.h> |
29 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
@@ -34,27 +33,13 @@ | |||
34 | /* get cpu node with valid operating-points */ | 33 | /* get cpu node with valid operating-points */ |
35 | static struct device_node *get_cpu_node_with_valid_op(int cpu) | 34 | static struct device_node *get_cpu_node_with_valid_op(int cpu) |
36 | { | 35 | { |
37 | struct device_node *np = NULL, *parent; | 36 | struct device_node *np = of_cpu_device_node_get(cpu); |
38 | int count = 0; | ||
39 | 37 | ||
40 | parent = of_find_node_by_path("/cpus"); | 38 | if (!of_get_property(np, "operating-points", NULL)) { |
41 | if (!parent) { | 39 | of_node_put(np); |
42 | pr_err("failed to find OF /cpus\n"); | 40 | np = NULL; |
43 | return NULL; | ||
44 | } | 41 | } |
45 | 42 | ||
46 | for_each_child_of_node(parent, np) { | ||
47 | if (count++ != cpu) | ||
48 | continue; | ||
49 | if (!of_get_property(np, "operating-points", NULL)) { | ||
50 | of_node_put(np); | ||
51 | np = NULL; | ||
52 | } | ||
53 | |||
54 | break; | ||
55 | } | ||
56 | |||
57 | of_node_put(parent); | ||
58 | return np; | 43 | return np; |
59 | } | 44 | } |
60 | 45 | ||
@@ -63,11 +48,12 @@ static int dt_init_opp_table(struct device *cpu_dev) | |||
63 | struct device_node *np; | 48 | struct device_node *np; |
64 | int ret; | 49 | int ret; |
65 | 50 | ||
66 | np = get_cpu_node_with_valid_op(cpu_dev->id); | 51 | np = of_node_get(cpu_dev->of_node); |
67 | if (!np) | 52 | if (!np) { |
68 | return -ENODATA; | 53 | pr_err("failed to find cpu%d node\n", cpu_dev->id); |
54 | return -ENOENT; | ||
55 | } | ||
69 | 56 | ||
70 | cpu_dev->of_node = np; | ||
71 | ret = of_init_opp_table(cpu_dev); | 57 | ret = of_init_opp_table(cpu_dev); |
72 | of_node_put(np); | 58 | of_node_put(np); |
73 | 59 | ||
@@ -79,9 +65,11 @@ static int dt_get_transition_latency(struct device *cpu_dev) | |||
79 | struct device_node *np; | 65 | struct device_node *np; |
80 | u32 transition_latency = CPUFREQ_ETERNAL; | 66 | u32 transition_latency = CPUFREQ_ETERNAL; |
81 | 67 | ||
82 | np = get_cpu_node_with_valid_op(cpu_dev->id); | 68 | np = of_node_get(cpu_dev->of_node); |
83 | if (!np) | 69 | if (!np) { |
70 | pr_info("Failed to find cpu node. Use CPUFREQ_ETERNAL transition latency\n"); | ||
84 | return CPUFREQ_ETERNAL; | 71 | return CPUFREQ_ETERNAL; |
72 | } | ||
85 | 73 | ||
86 | of_property_read_u32(np, "clock-latency", &transition_latency); | 74 | of_property_read_u32(np, "clock-latency", &transition_latency); |
87 | of_node_put(np); | 75 | of_node_put(np); |
diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c index 654488723cb5..e0c38d938997 100644 --- a/drivers/cpufreq/at32ap-cpufreq.c +++ b/drivers/cpufreq/at32ap-cpufreq.c | |||
@@ -108,7 +108,6 @@ static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
108 | 108 | ||
109 | static struct cpufreq_driver at32_driver = { | 109 | static struct cpufreq_driver at32_driver = { |
110 | .name = "at32ap", | 110 | .name = "at32ap", |
111 | .owner = THIS_MODULE, | ||
112 | .init = at32_cpufreq_driver_init, | 111 | .init = at32_cpufreq_driver_init, |
113 | .verify = at32_verify_speed, | 112 | .verify = at32_verify_speed, |
114 | .target = at32_set_target, | 113 | .target = at32_set_target, |
diff --git a/drivers/cpufreq/blackfin-cpufreq.c b/drivers/cpufreq/blackfin-cpufreq.c index 9cdbbd278a80..ef05978a7237 100644 --- a/drivers/cpufreq/blackfin-cpufreq.c +++ b/drivers/cpufreq/blackfin-cpufreq.c | |||
@@ -225,7 +225,6 @@ static struct cpufreq_driver bfin_driver = { | |||
225 | .get = bfin_getfreq_khz, | 225 | .get = bfin_getfreq_khz, |
226 | .init = __bfin_cpu_init, | 226 | .init = __bfin_cpu_init, |
227 | .name = "bfin cpufreq", | 227 | .name = "bfin cpufreq", |
228 | .owner = THIS_MODULE, | ||
229 | .attr = bfin_freq_attr, | 228 | .attr = bfin_freq_attr, |
230 | }; | 229 | }; |
231 | 230 | ||
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index e9dedb27deca..cbfffa91ebdd 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c | |||
@@ -69,7 +69,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, | |||
69 | 69 | ||
70 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 70 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
71 | 71 | ||
72 | if (cpu_reg) { | 72 | if (!IS_ERR(cpu_reg)) { |
73 | rcu_read_lock(); | 73 | rcu_read_lock(); |
74 | opp = opp_find_freq_ceil(cpu_dev, &freq_Hz); | 74 | opp = opp_find_freq_ceil(cpu_dev, &freq_Hz); |
75 | if (IS_ERR(opp)) { | 75 | if (IS_ERR(opp)) { |
@@ -90,7 +90,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, | |||
90 | freqs.new / 1000, volt ? volt / 1000 : -1); | 90 | freqs.new / 1000, volt ? volt / 1000 : -1); |
91 | 91 | ||
92 | /* scaling up? scale voltage before frequency */ | 92 | /* scaling up? scale voltage before frequency */ |
93 | if (cpu_reg && freqs.new > freqs.old) { | 93 | if (!IS_ERR(cpu_reg) && freqs.new > freqs.old) { |
94 | ret = regulator_set_voltage_tol(cpu_reg, volt, tol); | 94 | ret = regulator_set_voltage_tol(cpu_reg, volt, tol); |
95 | if (ret) { | 95 | if (ret) { |
96 | pr_err("failed to scale voltage up: %d\n", ret); | 96 | pr_err("failed to scale voltage up: %d\n", ret); |
@@ -102,14 +102,14 @@ static int cpu0_set_target(struct cpufreq_policy *policy, | |||
102 | ret = clk_set_rate(cpu_clk, freq_exact); | 102 | ret = clk_set_rate(cpu_clk, freq_exact); |
103 | if (ret) { | 103 | if (ret) { |
104 | pr_err("failed to set clock rate: %d\n", ret); | 104 | pr_err("failed to set clock rate: %d\n", ret); |
105 | if (cpu_reg) | 105 | if (!IS_ERR(cpu_reg)) |
106 | regulator_set_voltage_tol(cpu_reg, volt_old, tol); | 106 | regulator_set_voltage_tol(cpu_reg, volt_old, tol); |
107 | freqs.new = freqs.old; | 107 | freqs.new = freqs.old; |
108 | goto post_notify; | 108 | goto post_notify; |
109 | } | 109 | } |
110 | 110 | ||
111 | /* scaling down? scale voltage after frequency */ | 111 | /* scaling down? scale voltage after frequency */ |
112 | if (cpu_reg && freqs.new < freqs.old) { | 112 | if (!IS_ERR(cpu_reg) && freqs.new < freqs.old) { |
113 | ret = regulator_set_voltage_tol(cpu_reg, volt, tol); | 113 | ret = regulator_set_voltage_tol(cpu_reg, volt, tol); |
114 | if (ret) { | 114 | if (ret) { |
115 | pr_err("failed to scale voltage down: %d\n", ret); | 115 | pr_err("failed to scale voltage down: %d\n", ret); |
@@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { | |||
174 | 174 | ||
175 | static int cpu0_cpufreq_probe(struct platform_device *pdev) | 175 | static int cpu0_cpufreq_probe(struct platform_device *pdev) |
176 | { | 176 | { |
177 | struct device_node *np, *parent; | 177 | struct device_node *np; |
178 | int ret; | 178 | int ret; |
179 | 179 | ||
180 | parent = of_find_node_by_path("/cpus"); | 180 | cpu_dev = &pdev->dev; |
181 | if (!parent) { | ||
182 | pr_err("failed to find OF /cpus\n"); | ||
183 | return -ENOENT; | ||
184 | } | ||
185 | |||
186 | for_each_child_of_node(parent, np) { | ||
187 | if (of_get_property(np, "operating-points", NULL)) | ||
188 | break; | ||
189 | } | ||
190 | 181 | ||
182 | np = of_node_get(cpu_dev->of_node); | ||
191 | if (!np) { | 183 | if (!np) { |
192 | pr_err("failed to find cpu0 node\n"); | 184 | pr_err("failed to find cpu0 node\n"); |
193 | ret = -ENOENT; | 185 | return -ENOENT; |
194 | goto out_put_parent; | ||
195 | } | 186 | } |
196 | 187 | ||
197 | cpu_dev = &pdev->dev; | ||
198 | cpu_dev->of_node = np; | ||
199 | |||
200 | cpu_reg = devm_regulator_get_optional(cpu_dev, "cpu0"); | 188 | cpu_reg = devm_regulator_get_optional(cpu_dev, "cpu0"); |
201 | if (IS_ERR(cpu_reg)) { | 189 | if (IS_ERR(cpu_reg)) { |
202 | /* | 190 | /* |
@@ -210,7 +198,6 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) | |||
210 | } | 198 | } |
211 | pr_warn("failed to get cpu0 regulator: %ld\n", | 199 | pr_warn("failed to get cpu0 regulator: %ld\n", |
212 | PTR_ERR(cpu_reg)); | 200 | PTR_ERR(cpu_reg)); |
213 | cpu_reg = NULL; | ||
214 | } | 201 | } |
215 | 202 | ||
216 | cpu_clk = devm_clk_get(cpu_dev, NULL); | 203 | cpu_clk = devm_clk_get(cpu_dev, NULL); |
@@ -269,15 +256,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) | |||
269 | } | 256 | } |
270 | 257 | ||
271 | of_node_put(np); | 258 | of_node_put(np); |
272 | of_node_put(parent); | ||
273 | return 0; | 259 | return 0; |
274 | 260 | ||
275 | out_free_table: | 261 | out_free_table: |
276 | opp_free_cpufreq_table(cpu_dev, &freq_table); | 262 | opp_free_cpufreq_table(cpu_dev, &freq_table); |
277 | out_put_node: | 263 | out_put_node: |
278 | of_node_put(np); | 264 | of_node_put(np); |
279 | out_put_parent: | ||
280 | of_node_put(parent); | ||
281 | return ret; | 265 | return ret; |
282 | } | 266 | } |
283 | 267 | ||
diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c index af1542d41440..b83d45f68574 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c | |||
@@ -379,7 +379,6 @@ static struct cpufreq_driver nforce2_driver = { | |||
379 | .get = nforce2_get, | 379 | .get = nforce2_get, |
380 | .init = nforce2_cpu_init, | 380 | .init = nforce2_cpu_init, |
381 | .exit = nforce2_cpu_exit, | 381 | .exit = nforce2_cpu_exit, |
382 | .owner = THIS_MODULE, | ||
383 | }; | 382 | }; |
384 | 383 | ||
385 | #ifdef MODULE | 384 | #ifdef MODULE |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f0a5e2b0eb8a..5c75e3147a60 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -17,24 +17,17 @@ | |||
17 | 17 | ||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
19 | 19 | ||
20 | #include <asm/cputime.h> | 20 | #include <linux/cpu.h> |
21 | #include <linux/kernel.h> | ||
22 | #include <linux/kernel_stat.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/notifier.h> | ||
26 | #include <linux/cpufreq.h> | 21 | #include <linux/cpufreq.h> |
27 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/tick.h> | ||
31 | #include <linux/device.h> | 23 | #include <linux/device.h> |
32 | #include <linux/slab.h> | 24 | #include <linux/init.h> |
33 | #include <linux/cpu.h> | 25 | #include <linux/kernel_stat.h> |
34 | #include <linux/completion.h> | 26 | #include <linux/module.h> |
35 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/slab.h> | ||
36 | #include <linux/syscore_ops.h> | 29 | #include <linux/syscore_ops.h> |
37 | 30 | #include <linux/tick.h> | |
38 | #include <trace/events/power.h> | 31 | #include <trace/events/power.h> |
39 | 32 | ||
40 | /** | 33 | /** |
@@ -44,8 +37,10 @@ | |||
44 | */ | 37 | */ |
45 | static struct cpufreq_driver *cpufreq_driver; | 38 | static struct cpufreq_driver *cpufreq_driver; |
46 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); | 39 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); |
40 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); | ||
47 | static DEFINE_RWLOCK(cpufreq_driver_lock); | 41 | static DEFINE_RWLOCK(cpufreq_driver_lock); |
48 | static DEFINE_MUTEX(cpufreq_governor_lock); | 42 | static DEFINE_MUTEX(cpufreq_governor_lock); |
43 | static LIST_HEAD(cpufreq_policy_list); | ||
49 | 44 | ||
50 | #ifdef CONFIG_HOTPLUG_CPU | 45 | #ifdef CONFIG_HOTPLUG_CPU |
51 | /* This one keeps track of the previously set governor of a removed CPU */ | 46 | /* This one keeps track of the previously set governor of a removed CPU */ |
@@ -69,15 +64,14 @@ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); | |||
69 | * - Lock should not be held across | 64 | * - Lock should not be held across |
70 | * __cpufreq_governor(data, CPUFREQ_GOV_STOP); | 65 | * __cpufreq_governor(data, CPUFREQ_GOV_STOP); |
71 | */ | 66 | */ |
72 | static DEFINE_PER_CPU(int, cpufreq_policy_cpu); | ||
73 | static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); | 67 | static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); |
74 | 68 | ||
75 | #define lock_policy_rwsem(mode, cpu) \ | 69 | #define lock_policy_rwsem(mode, cpu) \ |
76 | static int lock_policy_rwsem_##mode(int cpu) \ | 70 | static int lock_policy_rwsem_##mode(int cpu) \ |
77 | { \ | 71 | { \ |
78 | int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \ | 72 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \ |
79 | BUG_ON(policy_cpu == -1); \ | 73 | BUG_ON(!policy); \ |
80 | down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \ | 74 | down_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \ |
81 | \ | 75 | \ |
82 | return 0; \ | 76 | return 0; \ |
83 | } | 77 | } |
@@ -88,14 +82,20 @@ lock_policy_rwsem(write, cpu); | |||
88 | #define unlock_policy_rwsem(mode, cpu) \ | 82 | #define unlock_policy_rwsem(mode, cpu) \ |
89 | static void unlock_policy_rwsem_##mode(int cpu) \ | 83 | static void unlock_policy_rwsem_##mode(int cpu) \ |
90 | { \ | 84 | { \ |
91 | int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \ | 85 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \ |
92 | BUG_ON(policy_cpu == -1); \ | 86 | BUG_ON(!policy); \ |
93 | up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \ | 87 | up_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \ |
94 | } | 88 | } |
95 | 89 | ||
96 | unlock_policy_rwsem(read, cpu); | 90 | unlock_policy_rwsem(read, cpu); |
97 | unlock_policy_rwsem(write, cpu); | 91 | unlock_policy_rwsem(write, cpu); |
98 | 92 | ||
93 | /* | ||
94 | * rwsem to guarantee that cpufreq driver module doesn't unload during critical | ||
95 | * sections | ||
96 | */ | ||
97 | static DECLARE_RWSEM(cpufreq_rwsem); | ||
98 | |||
99 | /* internal prototypes */ | 99 | /* internal prototypes */ |
100 | static int __cpufreq_governor(struct cpufreq_policy *policy, | 100 | static int __cpufreq_governor(struct cpufreq_policy *policy, |
101 | unsigned int event); | 101 | unsigned int event); |
@@ -183,78 +183,46 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy) | |||
183 | } | 183 | } |
184 | EXPORT_SYMBOL_GPL(get_cpu_idle_time); | 184 | EXPORT_SYMBOL_GPL(get_cpu_idle_time); |
185 | 185 | ||
186 | static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) | 186 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) |
187 | { | 187 | { |
188 | struct cpufreq_policy *data; | 188 | struct cpufreq_policy *policy = NULL; |
189 | unsigned long flags; | 189 | unsigned long flags; |
190 | 190 | ||
191 | if (cpu >= nr_cpu_ids) | 191 | if (cpufreq_disabled() || (cpu >= nr_cpu_ids)) |
192 | goto err_out; | 192 | return NULL; |
193 | |||
194 | if (!down_read_trylock(&cpufreq_rwsem)) | ||
195 | return NULL; | ||
193 | 196 | ||
194 | /* get the cpufreq driver */ | 197 | /* get the cpufreq driver */ |
195 | read_lock_irqsave(&cpufreq_driver_lock, flags); | 198 | read_lock_irqsave(&cpufreq_driver_lock, flags); |
196 | 199 | ||
197 | if (!cpufreq_driver) | 200 | if (cpufreq_driver) { |
198 | goto err_out_unlock; | 201 | /* get the CPU */ |
199 | 202 | policy = per_cpu(cpufreq_cpu_data, cpu); | |
200 | if (!try_module_get(cpufreq_driver->owner)) | 203 | if (policy) |
201 | goto err_out_unlock; | 204 | kobject_get(&policy->kobj); |
202 | 205 | } | |
203 | /* get the CPU */ | ||
204 | data = per_cpu(cpufreq_cpu_data, cpu); | ||
205 | |||
206 | if (!data) | ||
207 | goto err_out_put_module; | ||
208 | |||
209 | if (!sysfs && !kobject_get(&data->kobj)) | ||
210 | goto err_out_put_module; | ||
211 | 206 | ||
212 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | 207 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); |
213 | return data; | ||
214 | 208 | ||
215 | err_out_put_module: | 209 | if (!policy) |
216 | module_put(cpufreq_driver->owner); | 210 | up_read(&cpufreq_rwsem); |
217 | err_out_unlock: | ||
218 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
219 | err_out: | ||
220 | return NULL; | ||
221 | } | ||
222 | |||
223 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | ||
224 | { | ||
225 | if (cpufreq_disabled()) | ||
226 | return NULL; | ||
227 | 211 | ||
228 | return __cpufreq_cpu_get(cpu, false); | 212 | return policy; |
229 | } | 213 | } |
230 | EXPORT_SYMBOL_GPL(cpufreq_cpu_get); | 214 | EXPORT_SYMBOL_GPL(cpufreq_cpu_get); |
231 | 215 | ||
232 | static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu) | 216 | void cpufreq_cpu_put(struct cpufreq_policy *policy) |
233 | { | ||
234 | return __cpufreq_cpu_get(cpu, true); | ||
235 | } | ||
236 | |||
237 | static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs) | ||
238 | { | ||
239 | if (!sysfs) | ||
240 | kobject_put(&data->kobj); | ||
241 | module_put(cpufreq_driver->owner); | ||
242 | } | ||
243 | |||
244 | void cpufreq_cpu_put(struct cpufreq_policy *data) | ||
245 | { | 217 | { |
246 | if (cpufreq_disabled()) | 218 | if (cpufreq_disabled()) |
247 | return; | 219 | return; |
248 | 220 | ||
249 | __cpufreq_cpu_put(data, false); | 221 | kobject_put(&policy->kobj); |
222 | up_read(&cpufreq_rwsem); | ||
250 | } | 223 | } |
251 | EXPORT_SYMBOL_GPL(cpufreq_cpu_put); | 224 | EXPORT_SYMBOL_GPL(cpufreq_cpu_put); |
252 | 225 | ||
253 | static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data) | ||
254 | { | ||
255 | __cpufreq_cpu_put(data, true); | ||
256 | } | ||
257 | |||
258 | /********************************************************************* | 226 | /********************************************************************* |
259 | * EXTERNALLY AFFECTING FREQUENCY CHANGES * | 227 | * EXTERNALLY AFFECTING FREQUENCY CHANGES * |
260 | *********************************************************************/ | 228 | *********************************************************************/ |
@@ -459,8 +427,8 @@ show_one(scaling_min_freq, min); | |||
459 | show_one(scaling_max_freq, max); | 427 | show_one(scaling_max_freq, max); |
460 | show_one(scaling_cur_freq, cur); | 428 | show_one(scaling_cur_freq, cur); |
461 | 429 | ||
462 | static int __cpufreq_set_policy(struct cpufreq_policy *data, | 430 | static int __cpufreq_set_policy(struct cpufreq_policy *policy, |
463 | struct cpufreq_policy *policy); | 431 | struct cpufreq_policy *new_policy); |
464 | 432 | ||
465 | /** | 433 | /** |
466 | * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access | 434 | * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access |
@@ -699,12 +667,12 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) | |||
699 | struct cpufreq_policy *policy = to_policy(kobj); | 667 | struct cpufreq_policy *policy = to_policy(kobj); |
700 | struct freq_attr *fattr = to_attr(attr); | 668 | struct freq_attr *fattr = to_attr(attr); |
701 | ssize_t ret = -EINVAL; | 669 | ssize_t ret = -EINVAL; |
702 | policy = cpufreq_cpu_get_sysfs(policy->cpu); | 670 | |
703 | if (!policy) | 671 | if (!down_read_trylock(&cpufreq_rwsem)) |
704 | goto no_policy; | 672 | goto exit; |
705 | 673 | ||
706 | if (lock_policy_rwsem_read(policy->cpu) < 0) | 674 | if (lock_policy_rwsem_read(policy->cpu) < 0) |
707 | goto fail; | 675 | goto up_read; |
708 | 676 | ||
709 | if (fattr->show) | 677 | if (fattr->show) |
710 | ret = fattr->show(policy, buf); | 678 | ret = fattr->show(policy, buf); |
@@ -712,9 +680,10 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) | |||
712 | ret = -EIO; | 680 | ret = -EIO; |
713 | 681 | ||
714 | unlock_policy_rwsem_read(policy->cpu); | 682 | unlock_policy_rwsem_read(policy->cpu); |
715 | fail: | 683 | |
716 | cpufreq_cpu_put_sysfs(policy); | 684 | up_read: |
717 | no_policy: | 685 | up_read(&cpufreq_rwsem); |
686 | exit: | ||
718 | return ret; | 687 | return ret; |
719 | } | 688 | } |
720 | 689 | ||
@@ -724,12 +693,12 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, | |||
724 | struct cpufreq_policy *policy = to_policy(kobj); | 693 | struct cpufreq_policy *policy = to_policy(kobj); |
725 | struct freq_attr *fattr = to_attr(attr); | 694 | struct freq_attr *fattr = to_attr(attr); |
726 | ssize_t ret = -EINVAL; | 695 | ssize_t ret = -EINVAL; |
727 | policy = cpufreq_cpu_get_sysfs(policy->cpu); | 696 | |
728 | if (!policy) | 697 | if (!down_read_trylock(&cpufreq_rwsem)) |
729 | goto no_policy; | 698 | goto exit; |
730 | 699 | ||
731 | if (lock_policy_rwsem_write(policy->cpu) < 0) | 700 | if (lock_policy_rwsem_write(policy->cpu) < 0) |
732 | goto fail; | 701 | goto up_read; |
733 | 702 | ||
734 | if (fattr->store) | 703 | if (fattr->store) |
735 | ret = fattr->store(policy, buf, count); | 704 | ret = fattr->store(policy, buf, count); |
@@ -737,9 +706,10 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, | |||
737 | ret = -EIO; | 706 | ret = -EIO; |
738 | 707 | ||
739 | unlock_policy_rwsem_write(policy->cpu); | 708 | unlock_policy_rwsem_write(policy->cpu); |
740 | fail: | 709 | |
741 | cpufreq_cpu_put_sysfs(policy); | 710 | up_read: |
742 | no_policy: | 711 | up_read(&cpufreq_rwsem); |
712 | exit: | ||
743 | return ret; | 713 | return ret; |
744 | } | 714 | } |
745 | 715 | ||
@@ -805,41 +775,32 @@ void cpufreq_sysfs_remove_file(const struct attribute *attr) | |||
805 | EXPORT_SYMBOL(cpufreq_sysfs_remove_file); | 775 | EXPORT_SYMBOL(cpufreq_sysfs_remove_file); |
806 | 776 | ||
807 | /* symlink affected CPUs */ | 777 | /* symlink affected CPUs */ |
808 | static int cpufreq_add_dev_symlink(unsigned int cpu, | 778 | static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy) |
809 | struct cpufreq_policy *policy) | ||
810 | { | 779 | { |
811 | unsigned int j; | 780 | unsigned int j; |
812 | int ret = 0; | 781 | int ret = 0; |
813 | 782 | ||
814 | for_each_cpu(j, policy->cpus) { | 783 | for_each_cpu(j, policy->cpus) { |
815 | struct cpufreq_policy *managed_policy; | ||
816 | struct device *cpu_dev; | 784 | struct device *cpu_dev; |
817 | 785 | ||
818 | if (j == cpu) | 786 | if (j == policy->cpu) |
819 | continue; | 787 | continue; |
820 | 788 | ||
821 | pr_debug("CPU %u already managed, adding link\n", j); | 789 | pr_debug("Adding link for CPU: %u\n", j); |
822 | managed_policy = cpufreq_cpu_get(cpu); | ||
823 | cpu_dev = get_cpu_device(j); | 790 | cpu_dev = get_cpu_device(j); |
824 | ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, | 791 | ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, |
825 | "cpufreq"); | 792 | "cpufreq"); |
826 | if (ret) { | 793 | if (ret) |
827 | cpufreq_cpu_put(managed_policy); | 794 | break; |
828 | return ret; | ||
829 | } | ||
830 | } | 795 | } |
831 | return ret; | 796 | return ret; |
832 | } | 797 | } |
833 | 798 | ||
834 | static int cpufreq_add_dev_interface(unsigned int cpu, | 799 | static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, |
835 | struct cpufreq_policy *policy, | ||
836 | struct device *dev) | 800 | struct device *dev) |
837 | { | 801 | { |
838 | struct cpufreq_policy new_policy; | ||
839 | struct freq_attr **drv_attr; | 802 | struct freq_attr **drv_attr; |
840 | unsigned long flags; | ||
841 | int ret = 0; | 803 | int ret = 0; |
842 | unsigned int j; | ||
843 | 804 | ||
844 | /* prepare interface data */ | 805 | /* prepare interface data */ |
845 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, | 806 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, |
@@ -871,18 +832,24 @@ static int cpufreq_add_dev_interface(unsigned int cpu, | |||
871 | goto err_out_kobj_put; | 832 | goto err_out_kobj_put; |
872 | } | 833 | } |
873 | 834 | ||
874 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 835 | ret = cpufreq_add_dev_symlink(policy); |
875 | for_each_cpu(j, policy->cpus) { | ||
876 | per_cpu(cpufreq_cpu_data, j) = policy; | ||
877 | per_cpu(cpufreq_policy_cpu, j) = policy->cpu; | ||
878 | } | ||
879 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
880 | |||
881 | ret = cpufreq_add_dev_symlink(cpu, policy); | ||
882 | if (ret) | 836 | if (ret) |
883 | goto err_out_kobj_put; | 837 | goto err_out_kobj_put; |
884 | 838 | ||
885 | memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); | 839 | return ret; |
840 | |||
841 | err_out_kobj_put: | ||
842 | kobject_put(&policy->kobj); | ||
843 | wait_for_completion(&policy->kobj_unregister); | ||
844 | return ret; | ||
845 | } | ||
846 | |||
847 | static void cpufreq_init_policy(struct cpufreq_policy *policy) | ||
848 | { | ||
849 | struct cpufreq_policy new_policy; | ||
850 | int ret = 0; | ||
851 | |||
852 | memcpy(&new_policy, policy, sizeof(*policy)); | ||
886 | /* assure that the starting sequence is run in __cpufreq_set_policy */ | 853 | /* assure that the starting sequence is run in __cpufreq_set_policy */ |
887 | policy->governor = NULL; | 854 | policy->governor = NULL; |
888 | 855 | ||
@@ -896,72 +863,106 @@ static int cpufreq_add_dev_interface(unsigned int cpu, | |||
896 | if (cpufreq_driver->exit) | 863 | if (cpufreq_driver->exit) |
897 | cpufreq_driver->exit(policy); | 864 | cpufreq_driver->exit(policy); |
898 | } | 865 | } |
899 | return ret; | ||
900 | |||
901 | err_out_kobj_put: | ||
902 | kobject_put(&policy->kobj); | ||
903 | wait_for_completion(&policy->kobj_unregister); | ||
904 | return ret; | ||
905 | } | 866 | } |
906 | 867 | ||
907 | #ifdef CONFIG_HOTPLUG_CPU | 868 | #ifdef CONFIG_HOTPLUG_CPU |
908 | static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, | 869 | static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, |
909 | struct device *dev) | 870 | unsigned int cpu, struct device *dev, |
871 | bool frozen) | ||
910 | { | 872 | { |
911 | struct cpufreq_policy *policy; | ||
912 | int ret = 0, has_target = !!cpufreq_driver->target; | 873 | int ret = 0, has_target = !!cpufreq_driver->target; |
913 | unsigned long flags; | 874 | unsigned long flags; |
914 | 875 | ||
915 | policy = cpufreq_cpu_get(sibling); | 876 | if (has_target) { |
916 | WARN_ON(!policy); | 877 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
917 | 878 | if (ret) { | |
918 | if (has_target) | 879 | pr_err("%s: Failed to stop governor\n", __func__); |
919 | __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 880 | return ret; |
881 | } | ||
882 | } | ||
920 | 883 | ||
921 | lock_policy_rwsem_write(sibling); | 884 | lock_policy_rwsem_write(policy->cpu); |
922 | 885 | ||
923 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 886 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
924 | 887 | ||
925 | cpumask_set_cpu(cpu, policy->cpus); | 888 | cpumask_set_cpu(cpu, policy->cpus); |
926 | per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu; | ||
927 | per_cpu(cpufreq_cpu_data, cpu) = policy; | 889 | per_cpu(cpufreq_cpu_data, cpu) = policy; |
928 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 890 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
929 | 891 | ||
930 | unlock_policy_rwsem_write(sibling); | 892 | unlock_policy_rwsem_write(policy->cpu); |
931 | 893 | ||
932 | if (has_target) { | 894 | if (has_target) { |
933 | __cpufreq_governor(policy, CPUFREQ_GOV_START); | 895 | if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || |
934 | __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 896 | (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { |
897 | pr_err("%s: Failed to start governor\n", __func__); | ||
898 | return ret; | ||
899 | } | ||
935 | } | 900 | } |
936 | 901 | ||
937 | ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); | 902 | /* Don't touch sysfs links during light-weight init */ |
938 | if (ret) { | 903 | if (!frozen) |
939 | cpufreq_cpu_put(policy); | 904 | ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); |
940 | return ret; | ||
941 | } | ||
942 | 905 | ||
943 | return 0; | 906 | return ret; |
944 | } | 907 | } |
945 | #endif | 908 | #endif |
946 | 909 | ||
947 | /** | 910 | static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu) |
948 | * cpufreq_add_dev - add a CPU device | 911 | { |
949 | * | 912 | struct cpufreq_policy *policy; |
950 | * Adds the cpufreq interface for a CPU device. | 913 | unsigned long flags; |
951 | * | 914 | |
952 | * The Oracle says: try running cpufreq registration/unregistration concurrently | 915 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
953 | * with with cpu hotplugging and all hell will break loose. Tried to clean this | 916 | |
954 | * mess up, but more thorough testing is needed. - Mathieu | 917 | policy = per_cpu(cpufreq_cpu_data_fallback, cpu); |
955 | */ | 918 | |
956 | static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | 919 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
920 | |||
921 | return policy; | ||
922 | } | ||
923 | |||
924 | static struct cpufreq_policy *cpufreq_policy_alloc(void) | ||
925 | { | ||
926 | struct cpufreq_policy *policy; | ||
927 | |||
928 | policy = kzalloc(sizeof(*policy), GFP_KERNEL); | ||
929 | if (!policy) | ||
930 | return NULL; | ||
931 | |||
932 | if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) | ||
933 | goto err_free_policy; | ||
934 | |||
935 | if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) | ||
936 | goto err_free_cpumask; | ||
937 | |||
938 | INIT_LIST_HEAD(&policy->policy_list); | ||
939 | return policy; | ||
940 | |||
941 | err_free_cpumask: | ||
942 | free_cpumask_var(policy->cpus); | ||
943 | err_free_policy: | ||
944 | kfree(policy); | ||
945 | |||
946 | return NULL; | ||
947 | } | ||
948 | |||
949 | static void cpufreq_policy_free(struct cpufreq_policy *policy) | ||
950 | { | ||
951 | free_cpumask_var(policy->related_cpus); | ||
952 | free_cpumask_var(policy->cpus); | ||
953 | kfree(policy); | ||
954 | } | ||
955 | |||
956 | static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | ||
957 | bool frozen) | ||
957 | { | 958 | { |
958 | unsigned int j, cpu = dev->id; | 959 | unsigned int j, cpu = dev->id; |
959 | int ret = -ENOMEM; | 960 | int ret = -ENOMEM; |
960 | struct cpufreq_policy *policy; | 961 | struct cpufreq_policy *policy; |
961 | unsigned long flags; | 962 | unsigned long flags; |
962 | #ifdef CONFIG_HOTPLUG_CPU | 963 | #ifdef CONFIG_HOTPLUG_CPU |
964 | struct cpufreq_policy *tpolicy; | ||
963 | struct cpufreq_governor *gov; | 965 | struct cpufreq_governor *gov; |
964 | int sibling; | ||
965 | #endif | 966 | #endif |
966 | 967 | ||
967 | if (cpu_is_offline(cpu)) | 968 | if (cpu_is_offline(cpu)) |
@@ -977,43 +978,38 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
977 | cpufreq_cpu_put(policy); | 978 | cpufreq_cpu_put(policy); |
978 | return 0; | 979 | return 0; |
979 | } | 980 | } |
981 | #endif | ||
982 | |||
983 | if (!down_read_trylock(&cpufreq_rwsem)) | ||
984 | return 0; | ||
980 | 985 | ||
981 | #ifdef CONFIG_HOTPLUG_CPU | 986 | #ifdef CONFIG_HOTPLUG_CPU |
982 | /* Check if this cpu was hot-unplugged earlier and has siblings */ | 987 | /* Check if this cpu was hot-unplugged earlier and has siblings */ |
983 | read_lock_irqsave(&cpufreq_driver_lock, flags); | 988 | read_lock_irqsave(&cpufreq_driver_lock, flags); |
984 | for_each_online_cpu(sibling) { | 989 | list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) { |
985 | struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); | 990 | if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { |
986 | if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) { | ||
987 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | 991 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); |
988 | return cpufreq_add_policy_cpu(cpu, sibling, dev); | 992 | ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen); |
993 | up_read(&cpufreq_rwsem); | ||
994 | return ret; | ||
989 | } | 995 | } |
990 | } | 996 | } |
991 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | 997 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); |
992 | #endif | 998 | #endif |
993 | #endif | ||
994 | 999 | ||
995 | if (!try_module_get(cpufreq_driver->owner)) { | 1000 | if (frozen) |
996 | ret = -EINVAL; | 1001 | /* Restore the saved policy when doing light-weight init */ |
997 | goto module_out; | 1002 | policy = cpufreq_policy_restore(cpu); |
998 | } | 1003 | else |
1004 | policy = cpufreq_policy_alloc(); | ||
999 | 1005 | ||
1000 | policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL); | ||
1001 | if (!policy) | 1006 | if (!policy) |
1002 | goto nomem_out; | 1007 | goto nomem_out; |
1003 | 1008 | ||
1004 | if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) | ||
1005 | goto err_free_policy; | ||
1006 | |||
1007 | if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) | ||
1008 | goto err_free_cpumask; | ||
1009 | |||
1010 | policy->cpu = cpu; | 1009 | policy->cpu = cpu; |
1011 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1010 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; |
1012 | cpumask_copy(policy->cpus, cpumask_of(cpu)); | 1011 | cpumask_copy(policy->cpus, cpumask_of(cpu)); |
1013 | 1012 | ||
1014 | /* Initially set CPU itself as the policy_cpu */ | ||
1015 | per_cpu(cpufreq_policy_cpu, cpu) = cpu; | ||
1016 | |||
1017 | init_completion(&policy->kobj_unregister); | 1013 | init_completion(&policy->kobj_unregister); |
1018 | INIT_WORK(&policy->update, handle_update); | 1014 | INIT_WORK(&policy->update, handle_update); |
1019 | 1015 | ||
@@ -1050,12 +1046,26 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1050 | } | 1046 | } |
1051 | #endif | 1047 | #endif |
1052 | 1048 | ||
1053 | ret = cpufreq_add_dev_interface(cpu, policy, dev); | 1049 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1054 | if (ret) | 1050 | for_each_cpu(j, policy->cpus) |
1055 | goto err_out_unregister; | 1051 | per_cpu(cpufreq_cpu_data, j) = policy; |
1052 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1053 | |||
1054 | if (!frozen) { | ||
1055 | ret = cpufreq_add_dev_interface(policy, dev); | ||
1056 | if (ret) | ||
1057 | goto err_out_unregister; | ||
1058 | } | ||
1059 | |||
1060 | write_lock_irqsave(&cpufreq_driver_lock, flags); | ||
1061 | list_add(&policy->policy_list, &cpufreq_policy_list); | ||
1062 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1063 | |||
1064 | cpufreq_init_policy(policy); | ||
1056 | 1065 | ||
1057 | kobject_uevent(&policy->kobj, KOBJ_ADD); | 1066 | kobject_uevent(&policy->kobj, KOBJ_ADD); |
1058 | module_put(cpufreq_driver->owner); | 1067 | up_read(&cpufreq_rwsem); |
1068 | |||
1059 | pr_debug("initialization complete\n"); | 1069 | pr_debug("initialization complete\n"); |
1060 | 1070 | ||
1061 | return 0; | 1071 | return 0; |
@@ -1066,32 +1076,33 @@ err_out_unregister: | |||
1066 | per_cpu(cpufreq_cpu_data, j) = NULL; | 1076 | per_cpu(cpufreq_cpu_data, j) = NULL; |
1067 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1077 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1068 | 1078 | ||
1069 | kobject_put(&policy->kobj); | ||
1070 | wait_for_completion(&policy->kobj_unregister); | ||
1071 | |||
1072 | err_set_policy_cpu: | 1079 | err_set_policy_cpu: |
1073 | per_cpu(cpufreq_policy_cpu, cpu) = -1; | 1080 | cpufreq_policy_free(policy); |
1074 | free_cpumask_var(policy->related_cpus); | ||
1075 | err_free_cpumask: | ||
1076 | free_cpumask_var(policy->cpus); | ||
1077 | err_free_policy: | ||
1078 | kfree(policy); | ||
1079 | nomem_out: | 1081 | nomem_out: |
1080 | module_put(cpufreq_driver->owner); | 1082 | up_read(&cpufreq_rwsem); |
1081 | module_out: | 1083 | |
1082 | return ret; | 1084 | return ret; |
1083 | } | 1085 | } |
1084 | 1086 | ||
1085 | static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) | 1087 | /** |
1088 | * cpufreq_add_dev - add a CPU device | ||
1089 | * | ||
1090 | * Adds the cpufreq interface for a CPU device. | ||
1091 | * | ||
1092 | * The Oracle says: try running cpufreq registration/unregistration concurrently | ||
1093 | * with with cpu hotplugging and all hell will break loose. Tried to clean this | ||
1094 | * mess up, but more thorough testing is needed. - Mathieu | ||
1095 | */ | ||
1096 | static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | ||
1086 | { | 1097 | { |
1087 | int j; | 1098 | return __cpufreq_add_dev(dev, sif, false); |
1099 | } | ||
1088 | 1100 | ||
1101 | static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) | ||
1102 | { | ||
1089 | policy->last_cpu = policy->cpu; | 1103 | policy->last_cpu = policy->cpu; |
1090 | policy->cpu = cpu; | 1104 | policy->cpu = cpu; |
1091 | 1105 | ||
1092 | for_each_cpu(j, policy->cpus) | ||
1093 | per_cpu(cpufreq_policy_cpu, j) = cpu; | ||
1094 | |||
1095 | #ifdef CONFIG_CPU_FREQ_TABLE | 1106 | #ifdef CONFIG_CPU_FREQ_TABLE |
1096 | cpufreq_frequency_table_update_policy_cpu(policy); | 1107 | cpufreq_frequency_table_update_policy_cpu(policy); |
1097 | #endif | 1108 | #endif |
@@ -1099,6 +1110,37 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) | |||
1099 | CPUFREQ_UPDATE_POLICY_CPU, policy); | 1110 | CPUFREQ_UPDATE_POLICY_CPU, policy); |
1100 | } | 1111 | } |
1101 | 1112 | ||
1113 | static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, | ||
1114 | unsigned int old_cpu, bool frozen) | ||
1115 | { | ||
1116 | struct device *cpu_dev; | ||
1117 | int ret; | ||
1118 | |||
1119 | /* first sibling now owns the new sysfs dir */ | ||
1120 | cpu_dev = get_cpu_device(cpumask_first(policy->cpus)); | ||
1121 | |||
1122 | /* Don't touch sysfs files during light-weight tear-down */ | ||
1123 | if (frozen) | ||
1124 | return cpu_dev->id; | ||
1125 | |||
1126 | sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); | ||
1127 | ret = kobject_move(&policy->kobj, &cpu_dev->kobj); | ||
1128 | if (ret) { | ||
1129 | pr_err("%s: Failed to move kobj: %d", __func__, ret); | ||
1130 | |||
1131 | WARN_ON(lock_policy_rwsem_write(old_cpu)); | ||
1132 | cpumask_set_cpu(old_cpu, policy->cpus); | ||
1133 | unlock_policy_rwsem_write(old_cpu); | ||
1134 | |||
1135 | ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, | ||
1136 | "cpufreq"); | ||
1137 | |||
1138 | return -EINVAL; | ||
1139 | } | ||
1140 | |||
1141 | return cpu_dev->id; | ||
1142 | } | ||
1143 | |||
1102 | /** | 1144 | /** |
1103 | * __cpufreq_remove_dev - remove a CPU device | 1145 | * __cpufreq_remove_dev - remove a CPU device |
1104 | * | 1146 | * |
@@ -1107,111 +1149,126 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) | |||
1107 | * This routine frees the rwsem before returning. | 1149 | * This routine frees the rwsem before returning. |
1108 | */ | 1150 | */ |
1109 | static int __cpufreq_remove_dev(struct device *dev, | 1151 | static int __cpufreq_remove_dev(struct device *dev, |
1110 | struct subsys_interface *sif) | 1152 | struct subsys_interface *sif, bool frozen) |
1111 | { | 1153 | { |
1112 | unsigned int cpu = dev->id, ret, cpus; | 1154 | unsigned int cpu = dev->id, cpus; |
1155 | int new_cpu, ret; | ||
1113 | unsigned long flags; | 1156 | unsigned long flags; |
1114 | struct cpufreq_policy *data; | 1157 | struct cpufreq_policy *policy; |
1115 | struct kobject *kobj; | 1158 | struct kobject *kobj; |
1116 | struct completion *cmp; | 1159 | struct completion *cmp; |
1117 | struct device *cpu_dev; | ||
1118 | 1160 | ||
1119 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); | 1161 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); |
1120 | 1162 | ||
1121 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 1163 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1122 | 1164 | ||
1123 | data = per_cpu(cpufreq_cpu_data, cpu); | 1165 | policy = per_cpu(cpufreq_cpu_data, cpu); |
1124 | per_cpu(cpufreq_cpu_data, cpu) = NULL; | 1166 | |
1167 | /* Save the policy somewhere when doing a light-weight tear-down */ | ||
1168 | if (frozen) | ||
1169 | per_cpu(cpufreq_cpu_data_fallback, cpu) = policy; | ||
1125 | 1170 | ||
1126 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1171 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1127 | 1172 | ||
1128 | if (!data) { | 1173 | if (!policy) { |
1129 | pr_debug("%s: No cpu_data found\n", __func__); | 1174 | pr_debug("%s: No cpu_data found\n", __func__); |
1130 | return -EINVAL; | 1175 | return -EINVAL; |
1131 | } | 1176 | } |
1132 | 1177 | ||
1133 | if (cpufreq_driver->target) | 1178 | if (cpufreq_driver->target) { |
1134 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); | 1179 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
1180 | if (ret) { | ||
1181 | pr_err("%s: Failed to stop governor\n", __func__); | ||
1182 | return ret; | ||
1183 | } | ||
1184 | } | ||
1135 | 1185 | ||
1136 | #ifdef CONFIG_HOTPLUG_CPU | 1186 | #ifdef CONFIG_HOTPLUG_CPU |
1137 | if (!cpufreq_driver->setpolicy) | 1187 | if (!cpufreq_driver->setpolicy) |
1138 | strncpy(per_cpu(cpufreq_cpu_governor, cpu), | 1188 | strncpy(per_cpu(cpufreq_cpu_governor, cpu), |
1139 | data->governor->name, CPUFREQ_NAME_LEN); | 1189 | policy->governor->name, CPUFREQ_NAME_LEN); |
1140 | #endif | 1190 | #endif |
1141 | 1191 | ||
1142 | WARN_ON(lock_policy_rwsem_write(cpu)); | 1192 | WARN_ON(lock_policy_rwsem_write(cpu)); |
1143 | cpus = cpumask_weight(data->cpus); | 1193 | cpus = cpumask_weight(policy->cpus); |
1144 | 1194 | ||
1145 | if (cpus > 1) | 1195 | if (cpus > 1) |
1146 | cpumask_clear_cpu(cpu, data->cpus); | 1196 | cpumask_clear_cpu(cpu, policy->cpus); |
1147 | unlock_policy_rwsem_write(cpu); | 1197 | unlock_policy_rwsem_write(cpu); |
1148 | 1198 | ||
1149 | if (cpu != data->cpu) { | 1199 | if (cpu != policy->cpu && !frozen) { |
1150 | sysfs_remove_link(&dev->kobj, "cpufreq"); | 1200 | sysfs_remove_link(&dev->kobj, "cpufreq"); |
1151 | } else if (cpus > 1) { | 1201 | } else if (cpus > 1) { |
1152 | /* first sibling now owns the new sysfs dir */ | ||
1153 | cpu_dev = get_cpu_device(cpumask_first(data->cpus)); | ||
1154 | sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); | ||
1155 | ret = kobject_move(&data->kobj, &cpu_dev->kobj); | ||
1156 | if (ret) { | ||
1157 | pr_err("%s: Failed to move kobj: %d", __func__, ret); | ||
1158 | 1202 | ||
1203 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen); | ||
1204 | if (new_cpu >= 0) { | ||
1159 | WARN_ON(lock_policy_rwsem_write(cpu)); | 1205 | WARN_ON(lock_policy_rwsem_write(cpu)); |
1160 | cpumask_set_cpu(cpu, data->cpus); | 1206 | update_policy_cpu(policy, new_cpu); |
1161 | |||
1162 | write_lock_irqsave(&cpufreq_driver_lock, flags); | ||
1163 | per_cpu(cpufreq_cpu_data, cpu) = data; | ||
1164 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1165 | |||
1166 | unlock_policy_rwsem_write(cpu); | 1207 | unlock_policy_rwsem_write(cpu); |
1167 | 1208 | ||
1168 | ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj, | 1209 | if (!frozen) { |
1169 | "cpufreq"); | 1210 | pr_debug("%s: policy Kobject moved to cpu: %d " |
1170 | return -EINVAL; | 1211 | "from: %d\n",__func__, new_cpu, cpu); |
1212 | } | ||
1171 | } | 1213 | } |
1172 | |||
1173 | WARN_ON(lock_policy_rwsem_write(cpu)); | ||
1174 | update_policy_cpu(data, cpu_dev->id); | ||
1175 | unlock_policy_rwsem_write(cpu); | ||
1176 | pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n", | ||
1177 | __func__, cpu_dev->id, cpu); | ||
1178 | } | 1214 | } |
1179 | 1215 | ||
1180 | /* If cpu is last user of policy, free policy */ | 1216 | /* If cpu is last user of policy, free policy */ |
1181 | if (cpus == 1) { | 1217 | if (cpus == 1) { |
1182 | if (cpufreq_driver->target) | 1218 | if (cpufreq_driver->target) { |
1183 | __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); | 1219 | ret = __cpufreq_governor(policy, |
1184 | 1220 | CPUFREQ_GOV_POLICY_EXIT); | |
1185 | lock_policy_rwsem_read(cpu); | 1221 | if (ret) { |
1186 | kobj = &data->kobj; | 1222 | pr_err("%s: Failed to exit governor\n", |
1187 | cmp = &data->kobj_unregister; | 1223 | __func__); |
1188 | unlock_policy_rwsem_read(cpu); | 1224 | return ret; |
1189 | kobject_put(kobj); | 1225 | } |
1190 | 1226 | } | |
1191 | /* we need to make sure that the underlying kobj is actually | 1227 | |
1192 | * not referenced anymore by anybody before we proceed with | 1228 | if (!frozen) { |
1193 | * unloading. | 1229 | lock_policy_rwsem_read(cpu); |
1194 | */ | 1230 | kobj = &policy->kobj; |
1195 | pr_debug("waiting for dropping of refcount\n"); | 1231 | cmp = &policy->kobj_unregister; |
1196 | wait_for_completion(cmp); | 1232 | unlock_policy_rwsem_read(cpu); |
1197 | pr_debug("wait complete\n"); | 1233 | kobject_put(kobj); |
1234 | |||
1235 | /* | ||
1236 | * We need to make sure that the underlying kobj is | ||
1237 | * actually not referenced anymore by anybody before we | ||
1238 | * proceed with unloading. | ||
1239 | */ | ||
1240 | pr_debug("waiting for dropping of refcount\n"); | ||
1241 | wait_for_completion(cmp); | ||
1242 | pr_debug("wait complete\n"); | ||
1243 | } | ||
1198 | 1244 | ||
1245 | /* | ||
1246 | * Perform the ->exit() even during light-weight tear-down, | ||
1247 | * since this is a core component, and is essential for the | ||
1248 | * subsequent light-weight ->init() to succeed. | ||
1249 | */ | ||
1199 | if (cpufreq_driver->exit) | 1250 | if (cpufreq_driver->exit) |
1200 | cpufreq_driver->exit(data); | 1251 | cpufreq_driver->exit(policy); |
1201 | 1252 | ||
1202 | free_cpumask_var(data->related_cpus); | 1253 | /* Remove policy from list of active policies */ |
1203 | free_cpumask_var(data->cpus); | 1254 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1204 | kfree(data); | 1255 | list_del(&policy->policy_list); |
1256 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1257 | |||
1258 | if (!frozen) | ||
1259 | cpufreq_policy_free(policy); | ||
1205 | } else { | 1260 | } else { |
1206 | pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); | ||
1207 | cpufreq_cpu_put(data); | ||
1208 | if (cpufreq_driver->target) { | 1261 | if (cpufreq_driver->target) { |
1209 | __cpufreq_governor(data, CPUFREQ_GOV_START); | 1262 | if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || |
1210 | __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); | 1263 | (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { |
1264 | pr_err("%s: Failed to start governor\n", | ||
1265 | __func__); | ||
1266 | return ret; | ||
1267 | } | ||
1211 | } | 1268 | } |
1212 | } | 1269 | } |
1213 | 1270 | ||
1214 | per_cpu(cpufreq_policy_cpu, cpu) = -1; | 1271 | per_cpu(cpufreq_cpu_data, cpu) = NULL; |
1215 | return 0; | 1272 | return 0; |
1216 | } | 1273 | } |
1217 | 1274 | ||
@@ -1223,7 +1280,7 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) | |||
1223 | if (cpu_is_offline(cpu)) | 1280 | if (cpu_is_offline(cpu)) |
1224 | return 0; | 1281 | return 0; |
1225 | 1282 | ||
1226 | retval = __cpufreq_remove_dev(dev, sif); | 1283 | retval = __cpufreq_remove_dev(dev, sif, false); |
1227 | return retval; | 1284 | return retval; |
1228 | } | 1285 | } |
1229 | 1286 | ||
@@ -1344,10 +1401,9 @@ static unsigned int __cpufreq_get(unsigned int cpu) | |||
1344 | unsigned int cpufreq_get(unsigned int cpu) | 1401 | unsigned int cpufreq_get(unsigned int cpu) |
1345 | { | 1402 | { |
1346 | unsigned int ret_freq = 0; | 1403 | unsigned int ret_freq = 0; |
1347 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | ||
1348 | 1404 | ||
1349 | if (!policy) | 1405 | if (!down_read_trylock(&cpufreq_rwsem)) |
1350 | goto out; | 1406 | return 0; |
1351 | 1407 | ||
1352 | if (unlikely(lock_policy_rwsem_read(cpu))) | 1408 | if (unlikely(lock_policy_rwsem_read(cpu))) |
1353 | goto out_policy; | 1409 | goto out_policy; |
@@ -1357,8 +1413,8 @@ unsigned int cpufreq_get(unsigned int cpu) | |||
1357 | unlock_policy_rwsem_read(cpu); | 1413 | unlock_policy_rwsem_read(cpu); |
1358 | 1414 | ||
1359 | out_policy: | 1415 | out_policy: |
1360 | cpufreq_cpu_put(policy); | 1416 | up_read(&cpufreq_rwsem); |
1361 | out: | 1417 | |
1362 | return ret_freq; | 1418 | return ret_freq; |
1363 | } | 1419 | } |
1364 | EXPORT_SYMBOL(cpufreq_get); | 1420 | EXPORT_SYMBOL(cpufreq_get); |
@@ -1381,23 +1437,23 @@ static int cpufreq_bp_suspend(void) | |||
1381 | int ret = 0; | 1437 | int ret = 0; |
1382 | 1438 | ||
1383 | int cpu = smp_processor_id(); | 1439 | int cpu = smp_processor_id(); |
1384 | struct cpufreq_policy *cpu_policy; | 1440 | struct cpufreq_policy *policy; |
1385 | 1441 | ||
1386 | pr_debug("suspending cpu %u\n", cpu); | 1442 | pr_debug("suspending cpu %u\n", cpu); |
1387 | 1443 | ||
1388 | /* If there's no policy for the boot CPU, we have nothing to do. */ | 1444 | /* If there's no policy for the boot CPU, we have nothing to do. */ |
1389 | cpu_policy = cpufreq_cpu_get(cpu); | 1445 | policy = cpufreq_cpu_get(cpu); |
1390 | if (!cpu_policy) | 1446 | if (!policy) |
1391 | return 0; | 1447 | return 0; |
1392 | 1448 | ||
1393 | if (cpufreq_driver->suspend) { | 1449 | if (cpufreq_driver->suspend) { |
1394 | ret = cpufreq_driver->suspend(cpu_policy); | 1450 | ret = cpufreq_driver->suspend(policy); |
1395 | if (ret) | 1451 | if (ret) |
1396 | printk(KERN_ERR "cpufreq: suspend failed in ->suspend " | 1452 | printk(KERN_ERR "cpufreq: suspend failed in ->suspend " |
1397 | "step on CPU %u\n", cpu_policy->cpu); | 1453 | "step on CPU %u\n", policy->cpu); |
1398 | } | 1454 | } |
1399 | 1455 | ||
1400 | cpufreq_cpu_put(cpu_policy); | 1456 | cpufreq_cpu_put(policy); |
1401 | return ret; | 1457 | return ret; |
1402 | } | 1458 | } |
1403 | 1459 | ||
@@ -1419,28 +1475,28 @@ static void cpufreq_bp_resume(void) | |||
1419 | int ret = 0; | 1475 | int ret = 0; |
1420 | 1476 | ||
1421 | int cpu = smp_processor_id(); | 1477 | int cpu = smp_processor_id(); |
1422 | struct cpufreq_policy *cpu_policy; | 1478 | struct cpufreq_policy *policy; |
1423 | 1479 | ||
1424 | pr_debug("resuming cpu %u\n", cpu); | 1480 | pr_debug("resuming cpu %u\n", cpu); |
1425 | 1481 | ||
1426 | /* If there's no policy for the boot CPU, we have nothing to do. */ | 1482 | /* If there's no policy for the boot CPU, we have nothing to do. */ |
1427 | cpu_policy = cpufreq_cpu_get(cpu); | 1483 | policy = cpufreq_cpu_get(cpu); |
1428 | if (!cpu_policy) | 1484 | if (!policy) |
1429 | return; | 1485 | return; |
1430 | 1486 | ||
1431 | if (cpufreq_driver->resume) { | 1487 | if (cpufreq_driver->resume) { |
1432 | ret = cpufreq_driver->resume(cpu_policy); | 1488 | ret = cpufreq_driver->resume(policy); |
1433 | if (ret) { | 1489 | if (ret) { |
1434 | printk(KERN_ERR "cpufreq: resume failed in ->resume " | 1490 | printk(KERN_ERR "cpufreq: resume failed in ->resume " |
1435 | "step on CPU %u\n", cpu_policy->cpu); | 1491 | "step on CPU %u\n", policy->cpu); |
1436 | goto fail; | 1492 | goto fail; |
1437 | } | 1493 | } |
1438 | } | 1494 | } |
1439 | 1495 | ||
1440 | schedule_work(&cpu_policy->update); | 1496 | schedule_work(&policy->update); |
1441 | 1497 | ||
1442 | fail: | 1498 | fail: |
1443 | cpufreq_cpu_put(cpu_policy); | 1499 | cpufreq_cpu_put(policy); |
1444 | } | 1500 | } |
1445 | 1501 | ||
1446 | static struct syscore_ops cpufreq_syscore_ops = { | 1502 | static struct syscore_ops cpufreq_syscore_ops = { |
@@ -1594,18 +1650,6 @@ fail: | |||
1594 | } | 1650 | } |
1595 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); | 1651 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); |
1596 | 1652 | ||
1597 | int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu) | ||
1598 | { | ||
1599 | if (cpufreq_disabled()) | ||
1600 | return 0; | ||
1601 | |||
1602 | if (!cpufreq_driver->getavg) | ||
1603 | return 0; | ||
1604 | |||
1605 | return cpufreq_driver->getavg(policy, cpu); | ||
1606 | } | ||
1607 | EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg); | ||
1608 | |||
1609 | /* | 1653 | /* |
1610 | * when "event" is CPUFREQ_GOV_LIMITS | 1654 | * when "event" is CPUFREQ_GOV_LIMITS |
1611 | */ | 1655 | */ |
@@ -1640,8 +1684,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
1640 | } | 1684 | } |
1641 | } | 1685 | } |
1642 | 1686 | ||
1643 | if (!try_module_get(policy->governor->owner)) | 1687 | if (event == CPUFREQ_GOV_POLICY_INIT) |
1644 | return -EINVAL; | 1688 | if (!try_module_get(policy->governor->owner)) |
1689 | return -EINVAL; | ||
1645 | 1690 | ||
1646 | pr_debug("__cpufreq_governor for CPU %u, event %u\n", | 1691 | pr_debug("__cpufreq_governor for CPU %u, event %u\n", |
1647 | policy->cpu, event); | 1692 | policy->cpu, event); |
@@ -1677,11 +1722,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
1677 | mutex_unlock(&cpufreq_governor_lock); | 1722 | mutex_unlock(&cpufreq_governor_lock); |
1678 | } | 1723 | } |
1679 | 1724 | ||
1680 | /* we keep one module reference alive for | 1725 | if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) || |
1681 | each CPU governed by this CPU */ | 1726 | ((event == CPUFREQ_GOV_POLICY_EXIT) && !ret)) |
1682 | if ((event != CPUFREQ_GOV_START) || ret) | ||
1683 | module_put(policy->governor->owner); | ||
1684 | if ((event == CPUFREQ_GOV_STOP) && !ret) | ||
1685 | module_put(policy->governor->owner); | 1727 | module_put(policy->governor->owner); |
1686 | 1728 | ||
1687 | return ret; | 1729 | return ret; |
@@ -1761,7 +1803,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) | |||
1761 | if (!cpu_policy) | 1803 | if (!cpu_policy) |
1762 | return -EINVAL; | 1804 | return -EINVAL; |
1763 | 1805 | ||
1764 | memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy)); | 1806 | memcpy(policy, cpu_policy, sizeof(*policy)); |
1765 | 1807 | ||
1766 | cpufreq_cpu_put(cpu_policy); | 1808 | cpufreq_cpu_put(cpu_policy); |
1767 | return 0; | 1809 | return 0; |
@@ -1772,95 +1814,94 @@ EXPORT_SYMBOL(cpufreq_get_policy); | |||
1772 | * data : current policy. | 1814 | * data : current policy. |
1773 | * policy : policy to be set. | 1815 | * policy : policy to be set. |
1774 | */ | 1816 | */ |
1775 | static int __cpufreq_set_policy(struct cpufreq_policy *data, | 1817 | static int __cpufreq_set_policy(struct cpufreq_policy *policy, |
1776 | struct cpufreq_policy *policy) | 1818 | struct cpufreq_policy *new_policy) |
1777 | { | 1819 | { |
1778 | int ret = 0, failed = 1; | 1820 | int ret = 0, failed = 1; |
1779 | 1821 | ||
1780 | pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, | 1822 | pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu, |
1781 | policy->min, policy->max); | 1823 | new_policy->min, new_policy->max); |
1782 | 1824 | ||
1783 | memcpy(&policy->cpuinfo, &data->cpuinfo, | 1825 | memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); |
1784 | sizeof(struct cpufreq_cpuinfo)); | ||
1785 | 1826 | ||
1786 | if (policy->min > data->max || policy->max < data->min) { | 1827 | if (new_policy->min > policy->max || new_policy->max < policy->min) { |
1787 | ret = -EINVAL; | 1828 | ret = -EINVAL; |
1788 | goto error_out; | 1829 | goto error_out; |
1789 | } | 1830 | } |
1790 | 1831 | ||
1791 | /* verify the cpu speed can be set within this limit */ | 1832 | /* verify the cpu speed can be set within this limit */ |
1792 | ret = cpufreq_driver->verify(policy); | 1833 | ret = cpufreq_driver->verify(new_policy); |
1793 | if (ret) | 1834 | if (ret) |
1794 | goto error_out; | 1835 | goto error_out; |
1795 | 1836 | ||
1796 | /* adjust if necessary - all reasons */ | 1837 | /* adjust if necessary - all reasons */ |
1797 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1838 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1798 | CPUFREQ_ADJUST, policy); | 1839 | CPUFREQ_ADJUST, new_policy); |
1799 | 1840 | ||
1800 | /* adjust if necessary - hardware incompatibility*/ | 1841 | /* adjust if necessary - hardware incompatibility*/ |
1801 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1842 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1802 | CPUFREQ_INCOMPATIBLE, policy); | 1843 | CPUFREQ_INCOMPATIBLE, new_policy); |
1803 | 1844 | ||
1804 | /* | 1845 | /* |
1805 | * verify the cpu speed can be set within this limit, which might be | 1846 | * verify the cpu speed can be set within this limit, which might be |
1806 | * different to the first one | 1847 | * different to the first one |
1807 | */ | 1848 | */ |
1808 | ret = cpufreq_driver->verify(policy); | 1849 | ret = cpufreq_driver->verify(new_policy); |
1809 | if (ret) | 1850 | if (ret) |
1810 | goto error_out; | 1851 | goto error_out; |
1811 | 1852 | ||
1812 | /* notification of the new policy */ | 1853 | /* notification of the new policy */ |
1813 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1854 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1814 | CPUFREQ_NOTIFY, policy); | 1855 | CPUFREQ_NOTIFY, new_policy); |
1815 | 1856 | ||
1816 | data->min = policy->min; | 1857 | policy->min = new_policy->min; |
1817 | data->max = policy->max; | 1858 | policy->max = new_policy->max; |
1818 | 1859 | ||
1819 | pr_debug("new min and max freqs are %u - %u kHz\n", | 1860 | pr_debug("new min and max freqs are %u - %u kHz\n", |
1820 | data->min, data->max); | 1861 | policy->min, policy->max); |
1821 | 1862 | ||
1822 | if (cpufreq_driver->setpolicy) { | 1863 | if (cpufreq_driver->setpolicy) { |
1823 | data->policy = policy->policy; | 1864 | policy->policy = new_policy->policy; |
1824 | pr_debug("setting range\n"); | 1865 | pr_debug("setting range\n"); |
1825 | ret = cpufreq_driver->setpolicy(policy); | 1866 | ret = cpufreq_driver->setpolicy(new_policy); |
1826 | } else { | 1867 | } else { |
1827 | if (policy->governor != data->governor) { | 1868 | if (new_policy->governor != policy->governor) { |
1828 | /* save old, working values */ | 1869 | /* save old, working values */ |
1829 | struct cpufreq_governor *old_gov = data->governor; | 1870 | struct cpufreq_governor *old_gov = policy->governor; |
1830 | 1871 | ||
1831 | pr_debug("governor switch\n"); | 1872 | pr_debug("governor switch\n"); |
1832 | 1873 | ||
1833 | /* end old governor */ | 1874 | /* end old governor */ |
1834 | if (data->governor) { | 1875 | if (policy->governor) { |
1835 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); | 1876 | __cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
1836 | unlock_policy_rwsem_write(policy->cpu); | 1877 | unlock_policy_rwsem_write(new_policy->cpu); |
1837 | __cpufreq_governor(data, | 1878 | __cpufreq_governor(policy, |
1838 | CPUFREQ_GOV_POLICY_EXIT); | 1879 | CPUFREQ_GOV_POLICY_EXIT); |
1839 | lock_policy_rwsem_write(policy->cpu); | 1880 | lock_policy_rwsem_write(new_policy->cpu); |
1840 | } | 1881 | } |
1841 | 1882 | ||
1842 | /* start new governor */ | 1883 | /* start new governor */ |
1843 | data->governor = policy->governor; | 1884 | policy->governor = new_policy->governor; |
1844 | if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) { | 1885 | if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) { |
1845 | if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) { | 1886 | if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) { |
1846 | failed = 0; | 1887 | failed = 0; |
1847 | } else { | 1888 | } else { |
1848 | unlock_policy_rwsem_write(policy->cpu); | 1889 | unlock_policy_rwsem_write(new_policy->cpu); |
1849 | __cpufreq_governor(data, | 1890 | __cpufreq_governor(policy, |
1850 | CPUFREQ_GOV_POLICY_EXIT); | 1891 | CPUFREQ_GOV_POLICY_EXIT); |
1851 | lock_policy_rwsem_write(policy->cpu); | 1892 | lock_policy_rwsem_write(new_policy->cpu); |
1852 | } | 1893 | } |
1853 | } | 1894 | } |
1854 | 1895 | ||
1855 | if (failed) { | 1896 | if (failed) { |
1856 | /* new governor failed, so re-start old one */ | 1897 | /* new governor failed, so re-start old one */ |
1857 | pr_debug("starting governor %s failed\n", | 1898 | pr_debug("starting governor %s failed\n", |
1858 | data->governor->name); | 1899 | policy->governor->name); |
1859 | if (old_gov) { | 1900 | if (old_gov) { |
1860 | data->governor = old_gov; | 1901 | policy->governor = old_gov; |
1861 | __cpufreq_governor(data, | 1902 | __cpufreq_governor(policy, |
1862 | CPUFREQ_GOV_POLICY_INIT); | 1903 | CPUFREQ_GOV_POLICY_INIT); |
1863 | __cpufreq_governor(data, | 1904 | __cpufreq_governor(policy, |
1864 | CPUFREQ_GOV_START); | 1905 | CPUFREQ_GOV_START); |
1865 | } | 1906 | } |
1866 | ret = -EINVAL; | 1907 | ret = -EINVAL; |
@@ -1869,7 +1910,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, | |||
1869 | /* might be a policy change, too, so fall through */ | 1910 | /* might be a policy change, too, so fall through */ |
1870 | } | 1911 | } |
1871 | pr_debug("governor: change or update limits\n"); | 1912 | pr_debug("governor: change or update limits\n"); |
1872 | __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); | 1913 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); |
1873 | } | 1914 | } |
1874 | 1915 | ||
1875 | error_out: | 1916 | error_out: |
@@ -1885,11 +1926,11 @@ error_out: | |||
1885 | */ | 1926 | */ |
1886 | int cpufreq_update_policy(unsigned int cpu) | 1927 | int cpufreq_update_policy(unsigned int cpu) |
1887 | { | 1928 | { |
1888 | struct cpufreq_policy *data = cpufreq_cpu_get(cpu); | 1929 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); |
1889 | struct cpufreq_policy policy; | 1930 | struct cpufreq_policy new_policy; |
1890 | int ret; | 1931 | int ret; |
1891 | 1932 | ||
1892 | if (!data) { | 1933 | if (!policy) { |
1893 | ret = -ENODEV; | 1934 | ret = -ENODEV; |
1894 | goto no_policy; | 1935 | goto no_policy; |
1895 | } | 1936 | } |
@@ -1900,34 +1941,34 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1900 | } | 1941 | } |
1901 | 1942 | ||
1902 | pr_debug("updating policy for CPU %u\n", cpu); | 1943 | pr_debug("updating policy for CPU %u\n", cpu); |
1903 | memcpy(&policy, data, sizeof(struct cpufreq_policy)); | 1944 | memcpy(&new_policy, policy, sizeof(*policy)); |
1904 | policy.min = data->user_policy.min; | 1945 | new_policy.min = policy->user_policy.min; |
1905 | policy.max = data->user_policy.max; | 1946 | new_policy.max = policy->user_policy.max; |
1906 | policy.policy = data->user_policy.policy; | 1947 | new_policy.policy = policy->user_policy.policy; |
1907 | policy.governor = data->user_policy.governor; | 1948 | new_policy.governor = policy->user_policy.governor; |
1908 | 1949 | ||
1909 | /* | 1950 | /* |
1910 | * BIOS might change freq behind our back | 1951 | * BIOS might change freq behind our back |
1911 | * -> ask driver for current freq and notify governors about a change | 1952 | * -> ask driver for current freq and notify governors about a change |
1912 | */ | 1953 | */ |
1913 | if (cpufreq_driver->get) { | 1954 | if (cpufreq_driver->get) { |
1914 | policy.cur = cpufreq_driver->get(cpu); | 1955 | new_policy.cur = cpufreq_driver->get(cpu); |
1915 | if (!data->cur) { | 1956 | if (!policy->cur) { |
1916 | pr_debug("Driver did not initialize current freq"); | 1957 | pr_debug("Driver did not initialize current freq"); |
1917 | data->cur = policy.cur; | 1958 | policy->cur = new_policy.cur; |
1918 | } else { | 1959 | } else { |
1919 | if (data->cur != policy.cur && cpufreq_driver->target) | 1960 | if (policy->cur != new_policy.cur && cpufreq_driver->target) |
1920 | cpufreq_out_of_sync(cpu, data->cur, | 1961 | cpufreq_out_of_sync(cpu, policy->cur, |
1921 | policy.cur); | 1962 | new_policy.cur); |
1922 | } | 1963 | } |
1923 | } | 1964 | } |
1924 | 1965 | ||
1925 | ret = __cpufreq_set_policy(data, &policy); | 1966 | ret = __cpufreq_set_policy(policy, &new_policy); |
1926 | 1967 | ||
1927 | unlock_policy_rwsem_write(cpu); | 1968 | unlock_policy_rwsem_write(cpu); |
1928 | 1969 | ||
1929 | fail: | 1970 | fail: |
1930 | cpufreq_cpu_put(data); | 1971 | cpufreq_cpu_put(policy); |
1931 | no_policy: | 1972 | no_policy: |
1932 | return ret; | 1973 | return ret; |
1933 | } | 1974 | } |
@@ -1938,21 +1979,26 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
1938 | { | 1979 | { |
1939 | unsigned int cpu = (unsigned long)hcpu; | 1980 | unsigned int cpu = (unsigned long)hcpu; |
1940 | struct device *dev; | 1981 | struct device *dev; |
1982 | bool frozen = false; | ||
1941 | 1983 | ||
1942 | dev = get_cpu_device(cpu); | 1984 | dev = get_cpu_device(cpu); |
1943 | if (dev) { | 1985 | if (dev) { |
1944 | switch (action) { | 1986 | |
1987 | if (action & CPU_TASKS_FROZEN) | ||
1988 | frozen = true; | ||
1989 | |||
1990 | switch (action & ~CPU_TASKS_FROZEN) { | ||
1945 | case CPU_ONLINE: | 1991 | case CPU_ONLINE: |
1946 | case CPU_ONLINE_FROZEN: | 1992 | __cpufreq_add_dev(dev, NULL, frozen); |
1947 | cpufreq_add_dev(dev, NULL); | 1993 | cpufreq_update_policy(cpu); |
1948 | break; | 1994 | break; |
1995 | |||
1949 | case CPU_DOWN_PREPARE: | 1996 | case CPU_DOWN_PREPARE: |
1950 | case CPU_DOWN_PREPARE_FROZEN: | 1997 | __cpufreq_remove_dev(dev, NULL, frozen); |
1951 | __cpufreq_remove_dev(dev, NULL); | ||
1952 | break; | 1998 | break; |
1999 | |||
1953 | case CPU_DOWN_FAILED: | 2000 | case CPU_DOWN_FAILED: |
1954 | case CPU_DOWN_FAILED_FROZEN: | 2001 | __cpufreq_add_dev(dev, NULL, frozen); |
1955 | cpufreq_add_dev(dev, NULL); | ||
1956 | break; | 2002 | break; |
1957 | } | 2003 | } |
1958 | } | 2004 | } |
@@ -2059,9 +2105,13 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) | |||
2059 | subsys_interface_unregister(&cpufreq_interface); | 2105 | subsys_interface_unregister(&cpufreq_interface); |
2060 | unregister_hotcpu_notifier(&cpufreq_cpu_notifier); | 2106 | unregister_hotcpu_notifier(&cpufreq_cpu_notifier); |
2061 | 2107 | ||
2108 | down_write(&cpufreq_rwsem); | ||
2062 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 2109 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
2110 | |||
2063 | cpufreq_driver = NULL; | 2111 | cpufreq_driver = NULL; |
2112 | |||
2064 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2113 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
2114 | up_write(&cpufreq_rwsem); | ||
2065 | 2115 | ||
2066 | return 0; | 2116 | return 0; |
2067 | } | 2117 | } |
@@ -2074,10 +2124,8 @@ static int __init cpufreq_core_init(void) | |||
2074 | if (cpufreq_disabled()) | 2124 | if (cpufreq_disabled()) |
2075 | return -ENODEV; | 2125 | return -ENODEV; |
2076 | 2126 | ||
2077 | for_each_possible_cpu(cpu) { | 2127 | for_each_possible_cpu(cpu) |
2078 | per_cpu(cpufreq_policy_cpu, cpu) = -1; | ||
2079 | init_rwsem(&per_cpu(cpu_policy_rwsem, cpu)); | 2128 | init_rwsem(&per_cpu(cpu_policy_rwsem, cpu)); |
2080 | } | ||
2081 | 2129 | ||
2082 | cpufreq_global_kobject = kobject_create(); | 2130 | cpufreq_global_kobject = kobject_create(); |
2083 | BUG_ON(!cpufreq_global_kobject); | 2131 | BUG_ON(!cpufreq_global_kobject); |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index f97cb3d8c5a2..f62d822048e6 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -11,19 +11,7 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/cpufreq.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/kernel_stat.h> | ||
18 | #include <linux/kobject.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/mutex.h> | ||
21 | #include <linux/notifier.h> | ||
22 | #include <linux/percpu-defs.h> | ||
23 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
24 | #include <linux/sysfs.h> | ||
25 | #include <linux/types.h> | ||
26 | |||
27 | #include "cpufreq_governor.h" | 15 | #include "cpufreq_governor.h" |
28 | 16 | ||
29 | /* Conservative governor macros */ | 17 | /* Conservative governor macros */ |
@@ -79,8 +67,6 @@ static void cs_check_cpu(int cpu, unsigned int load) | |||
79 | return; | 67 | return; |
80 | 68 | ||
81 | dbs_info->requested_freq += get_freq_target(cs_tuners, policy); | 69 | dbs_info->requested_freq += get_freq_target(cs_tuners, policy); |
82 | if (dbs_info->requested_freq > policy->max) | ||
83 | dbs_info->requested_freq = policy->max; | ||
84 | 70 | ||
85 | __cpufreq_driver_target(policy, dbs_info->requested_freq, | 71 | __cpufreq_driver_target(policy, dbs_info->requested_freq, |
86 | CPUFREQ_RELATION_H); | 72 | CPUFREQ_RELATION_H); |
@@ -101,8 +87,6 @@ static void cs_check_cpu(int cpu, unsigned int load) | |||
101 | return; | 87 | return; |
102 | 88 | ||
103 | dbs_info->requested_freq -= get_freq_target(cs_tuners, policy); | 89 | dbs_info->requested_freq -= get_freq_target(cs_tuners, policy); |
104 | if (dbs_info->requested_freq < policy->min) | ||
105 | dbs_info->requested_freq = policy->min; | ||
106 | 90 | ||
107 | __cpufreq_driver_target(policy, dbs_info->requested_freq, | 91 | __cpufreq_driver_target(policy, dbs_info->requested_freq, |
108 | CPUFREQ_RELATION_L); | 92 | CPUFREQ_RELATION_L); |
@@ -329,7 +313,7 @@ static int cs_init(struct dbs_data *dbs_data) | |||
329 | { | 313 | { |
330 | struct cs_dbs_tuners *tuners; | 314 | struct cs_dbs_tuners *tuners; |
331 | 315 | ||
332 | tuners = kzalloc(sizeof(struct cs_dbs_tuners), GFP_KERNEL); | 316 | tuners = kzalloc(sizeof(*tuners), GFP_KERNEL); |
333 | if (!tuners) { | 317 | if (!tuners) { |
334 | pr_err("%s: kzalloc failed\n", __func__); | 318 | pr_err("%s: kzalloc failed\n", __func__); |
335 | return -ENOMEM; | 319 | return -ENOMEM; |
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index e59afaa9da23..0806c31e5764 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c | |||
@@ -16,15 +16,9 @@ | |||
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
18 | 18 | ||
19 | #include <asm/cputime.h> | ||
20 | #include <linux/cpufreq.h> | ||
21 | #include <linux/cpumask.h> | ||
22 | #include <linux/export.h> | 19 | #include <linux/export.h> |
23 | #include <linux/kernel_stat.h> | 20 | #include <linux/kernel_stat.h> |
24 | #include <linux/mutex.h> | ||
25 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
26 | #include <linux/types.h> | ||
27 | #include <linux/workqueue.h> | ||
28 | 22 | ||
29 | #include "cpufreq_governor.h" | 23 | #include "cpufreq_governor.h" |
30 | 24 | ||
@@ -53,7 +47,7 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) | |||
53 | 47 | ||
54 | policy = cdbs->cur_policy; | 48 | policy = cdbs->cur_policy; |
55 | 49 | ||
56 | /* Get Absolute Load (in terms of freq for ondemand gov) */ | 50 | /* Get Absolute Load */ |
57 | for_each_cpu(j, policy->cpus) { | 51 | for_each_cpu(j, policy->cpus) { |
58 | struct cpu_dbs_common_info *j_cdbs; | 52 | struct cpu_dbs_common_info *j_cdbs; |
59 | u64 cur_wall_time, cur_idle_time; | 53 | u64 cur_wall_time, cur_idle_time; |
@@ -104,14 +98,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) | |||
104 | 98 | ||
105 | load = 100 * (wall_time - idle_time) / wall_time; | 99 | load = 100 * (wall_time - idle_time) / wall_time; |
106 | 100 | ||
107 | if (dbs_data->cdata->governor == GOV_ONDEMAND) { | ||
108 | int freq_avg = __cpufreq_driver_getavg(policy, j); | ||
109 | if (freq_avg <= 0) | ||
110 | freq_avg = policy->cur; | ||
111 | |||
112 | load *= freq_avg; | ||
113 | } | ||
114 | |||
115 | if (load > max_load) | 101 | if (load > max_load) |
116 | max_load = load; | 102 | max_load = load; |
117 | } | 103 | } |
@@ -133,8 +119,18 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, | |||
133 | { | 119 | { |
134 | int i; | 120 | int i; |
135 | 121 | ||
122 | if (!policy->governor_enabled) | ||
123 | return; | ||
124 | |||
136 | if (!all_cpus) { | 125 | if (!all_cpus) { |
137 | __gov_queue_work(smp_processor_id(), dbs_data, delay); | 126 | /* |
127 | * Use raw_smp_processor_id() to avoid preemptible warnings. | ||
128 | * We know that this is only called with all_cpus == false from | ||
129 | * works that have been queued with *_work_on() functions and | ||
130 | * those works are canceled during CPU_DOWN_PREPARE so they | ||
131 | * can't possibly run on any other CPU. | ||
132 | */ | ||
133 | __gov_queue_work(raw_smp_processor_id(), dbs_data, delay); | ||
138 | } else { | 134 | } else { |
139 | for_each_cpu(i, policy->cpus) | 135 | for_each_cpu(i, policy->cpus) |
140 | __gov_queue_work(i, dbs_data, delay); | 136 | __gov_queue_work(i, dbs_data, delay); |
@@ -244,7 +240,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
244 | 240 | ||
245 | policy->governor_data = dbs_data; | 241 | policy->governor_data = dbs_data; |
246 | 242 | ||
247 | /* policy latency is in nS. Convert it to uS first */ | 243 | /* policy latency is in ns. Convert it to us first */ |
248 | latency = policy->cpuinfo.transition_latency / 1000; | 244 | latency = policy->cpuinfo.transition_latency / 1000; |
249 | if (latency == 0) | 245 | if (latency == 0) |
250 | latency = 1; | 246 | latency = 1; |
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index d5f12b4b11b8..88cd39f7b0e9 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h | |||
@@ -18,19 +18,18 @@ | |||
18 | #define _CPUFREQ_GOVERNOR_H | 18 | #define _CPUFREQ_GOVERNOR_H |
19 | 19 | ||
20 | #include <linux/cpufreq.h> | 20 | #include <linux/cpufreq.h> |
21 | #include <linux/kobject.h> | 21 | #include <linux/kernel_stat.h> |
22 | #include <linux/module.h> | ||
22 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
23 | #include <linux/workqueue.h> | ||
24 | #include <linux/sysfs.h> | ||
25 | 24 | ||
26 | /* | 25 | /* |
27 | * The polling frequency depends on the capability of the processor. Default | 26 | * The polling frequency depends on the capability of the processor. Default |
28 | * polling frequency is 1000 times the transition latency of the processor. The | 27 | * polling frequency is 1000 times the transition latency of the processor. The |
29 | * governor will work on any processor with transition latency <= 10mS, using | 28 | * governor will work on any processor with transition latency <= 10ms, using |
30 | * appropriate sampling rate. | 29 | * appropriate sampling rate. |
31 | * | 30 | * |
32 | * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) | 31 | * For CPUs with transition latency > 10ms (mostly drivers with CPUFREQ_ETERNAL) |
33 | * this governor will not work. All times here are in uS. | 32 | * this governor will not work. All times here are in us (micro seconds). |
34 | */ | 33 | */ |
35 | #define MIN_SAMPLING_RATE_RATIO (2) | 34 | #define MIN_SAMPLING_RATE_RATIO (2) |
36 | #define LATENCY_MULTIPLIER (1000) | 35 | #define LATENCY_MULTIPLIER (1000) |
@@ -163,13 +162,12 @@ struct cs_cpu_dbs_info_s { | |||
163 | unsigned int enable:1; | 162 | unsigned int enable:1; |
164 | }; | 163 | }; |
165 | 164 | ||
166 | /* Per policy Governers sysfs tunables */ | 165 | /* Per policy Governors sysfs tunables */ |
167 | struct od_dbs_tuners { | 166 | struct od_dbs_tuners { |
168 | unsigned int ignore_nice_load; | 167 | unsigned int ignore_nice_load; |
169 | unsigned int sampling_rate; | 168 | unsigned int sampling_rate; |
170 | unsigned int sampling_down_factor; | 169 | unsigned int sampling_down_factor; |
171 | unsigned int up_threshold; | 170 | unsigned int up_threshold; |
172 | unsigned int adj_up_threshold; | ||
173 | unsigned int powersave_bias; | 171 | unsigned int powersave_bias; |
174 | unsigned int io_is_busy; | 172 | unsigned int io_is_busy; |
175 | }; | 173 | }; |
@@ -183,7 +181,7 @@ struct cs_dbs_tuners { | |||
183 | unsigned int freq_step; | 181 | unsigned int freq_step; |
184 | }; | 182 | }; |
185 | 183 | ||
186 | /* Common Governer data across policies */ | 184 | /* Common Governor data across policies */ |
187 | struct dbs_data; | 185 | struct dbs_data; |
188 | struct common_dbs_data { | 186 | struct common_dbs_data { |
189 | /* Common across governors */ | 187 | /* Common across governors */ |
@@ -207,7 +205,7 @@ struct common_dbs_data { | |||
207 | void *gov_ops; | 205 | void *gov_ops; |
208 | }; | 206 | }; |
209 | 207 | ||
210 | /* Governer Per policy data */ | 208 | /* Governor Per policy data */ |
211 | struct dbs_data { | 209 | struct dbs_data { |
212 | struct common_dbs_data *cdata; | 210 | struct common_dbs_data *cdata; |
213 | unsigned int min_sampling_rate; | 211 | unsigned int min_sampling_rate; |
@@ -223,7 +221,7 @@ struct od_ops { | |||
223 | void (*powersave_bias_init_cpu)(int cpu); | 221 | void (*powersave_bias_init_cpu)(int cpu); |
224 | unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy, | 222 | unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy, |
225 | unsigned int freq_next, unsigned int relation); | 223 | unsigned int freq_next, unsigned int relation); |
226 | void (*freq_increase)(struct cpufreq_policy *p, unsigned int freq); | 224 | void (*freq_increase)(struct cpufreq_policy *policy, unsigned int freq); |
227 | }; | 225 | }; |
228 | 226 | ||
229 | struct cs_ops { | 227 | struct cs_ops { |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index c087347d6688..32f26f6e17c5 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -12,28 +12,16 @@ | |||
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
14 | 14 | ||
15 | #include <linux/cpufreq.h> | 15 | #include <linux/cpu.h> |
16 | #include <linux/init.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/kernel_stat.h> | ||
19 | #include <linux/kobject.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/percpu-defs.h> | 16 | #include <linux/percpu-defs.h> |
23 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
24 | #include <linux/sysfs.h> | ||
25 | #include <linux/tick.h> | 18 | #include <linux/tick.h> |
26 | #include <linux/types.h> | ||
27 | #include <linux/cpu.h> | ||
28 | |||
29 | #include "cpufreq_governor.h" | 19 | #include "cpufreq_governor.h" |
30 | 20 | ||
31 | /* On-demand governor macros */ | 21 | /* On-demand governor macros */ |
32 | #define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10) | ||
33 | #define DEF_FREQUENCY_UP_THRESHOLD (80) | 22 | #define DEF_FREQUENCY_UP_THRESHOLD (80) |
34 | #define DEF_SAMPLING_DOWN_FACTOR (1) | 23 | #define DEF_SAMPLING_DOWN_FACTOR (1) |
35 | #define MAX_SAMPLING_DOWN_FACTOR (100000) | 24 | #define MAX_SAMPLING_DOWN_FACTOR (100000) |
36 | #define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3) | ||
37 | #define MICRO_FREQUENCY_UP_THRESHOLD (95) | 25 | #define MICRO_FREQUENCY_UP_THRESHOLD (95) |
38 | #define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000) | 26 | #define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000) |
39 | #define MIN_FREQUENCY_UP_THRESHOLD (11) | 27 | #define MIN_FREQUENCY_UP_THRESHOLD (11) |
@@ -144,31 +132,27 @@ static void ondemand_powersave_bias_init(void) | |||
144 | } | 132 | } |
145 | } | 133 | } |
146 | 134 | ||
147 | static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq) | 135 | static void dbs_freq_increase(struct cpufreq_policy *policy, unsigned int freq) |
148 | { | 136 | { |
149 | struct dbs_data *dbs_data = p->governor_data; | 137 | struct dbs_data *dbs_data = policy->governor_data; |
150 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; | 138 | struct od_dbs_tuners *od_tuners = dbs_data->tuners; |
151 | 139 | ||
152 | if (od_tuners->powersave_bias) | 140 | if (od_tuners->powersave_bias) |
153 | freq = od_ops.powersave_bias_target(p, freq, | 141 | freq = od_ops.powersave_bias_target(policy, freq, |
154 | CPUFREQ_RELATION_H); | 142 | CPUFREQ_RELATION_H); |
155 | else if (p->cur == p->max) | 143 | else if (policy->cur == policy->max) |
156 | return; | 144 | return; |
157 | 145 | ||
158 | __cpufreq_driver_target(p, freq, od_tuners->powersave_bias ? | 146 | __cpufreq_driver_target(policy, freq, od_tuners->powersave_bias ? |
159 | CPUFREQ_RELATION_L : CPUFREQ_RELATION_H); | 147 | CPUFREQ_RELATION_L : CPUFREQ_RELATION_H); |
160 | } | 148 | } |
161 | 149 | ||
162 | /* | 150 | /* |
163 | * Every sampling_rate, we check, if current idle time is less than 20% | 151 | * Every sampling_rate, we check, if current idle time is less than 20% |
164 | * (default), then we try to increase frequency. Every sampling_rate, we look | 152 | * (default), then we try to increase frequency. Else, we adjust the frequency |
165 | * for the lowest frequency which can sustain the load while keeping idle time | 153 | * proportional to load. |
166 | * over 30%. If such a frequency exist, we try to decrease to this frequency. | ||
167 | * | ||
168 | * Any frequency increase takes it to the maximum frequency. Frequency reduction | ||
169 | * happens at minimum steps of 5% (default) of current frequency | ||
170 | */ | 154 | */ |
171 | static void od_check_cpu(int cpu, unsigned int load_freq) | 155 | static void od_check_cpu(int cpu, unsigned int load) |
172 | { | 156 | { |
173 | struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); | 157 | struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); |
174 | struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; | 158 | struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; |
@@ -178,36 +162,21 @@ static void od_check_cpu(int cpu, unsigned int load_freq) | |||
178 | dbs_info->freq_lo = 0; | 162 | dbs_info->freq_lo = 0; |
179 | 163 | ||
180 | /* Check for frequency increase */ | 164 | /* Check for frequency increase */ |
181 | if (load_freq > od_tuners->up_threshold * policy->cur) { | 165 | if (load > od_tuners->up_threshold) { |
182 | /* If switching to max speed, apply sampling_down_factor */ | 166 | /* If switching to max speed, apply sampling_down_factor */ |
183 | if (policy->cur < policy->max) | 167 | if (policy->cur < policy->max) |
184 | dbs_info->rate_mult = | 168 | dbs_info->rate_mult = |
185 | od_tuners->sampling_down_factor; | 169 | od_tuners->sampling_down_factor; |
186 | dbs_freq_increase(policy, policy->max); | 170 | dbs_freq_increase(policy, policy->max); |
187 | return; | 171 | return; |
188 | } | 172 | } else { |
189 | 173 | /* Calculate the next frequency proportional to load */ | |
190 | /* Check for frequency decrease */ | ||
191 | /* if we cannot reduce the frequency anymore, break out early */ | ||
192 | if (policy->cur == policy->min) | ||
193 | return; | ||
194 | |||
195 | /* | ||
196 | * The optimal frequency is the frequency that is the lowest that can | ||
197 | * support the current CPU usage without triggering the up policy. To be | ||
198 | * safe, we focus 10 points under the threshold. | ||
199 | */ | ||
200 | if (load_freq < od_tuners->adj_up_threshold | ||
201 | * policy->cur) { | ||
202 | unsigned int freq_next; | 174 | unsigned int freq_next; |
203 | freq_next = load_freq / od_tuners->adj_up_threshold; | 175 | freq_next = load * policy->cpuinfo.max_freq / 100; |
204 | 176 | ||
205 | /* No longer fully busy, reset rate_mult */ | 177 | /* No longer fully busy, reset rate_mult */ |
206 | dbs_info->rate_mult = 1; | 178 | dbs_info->rate_mult = 1; |
207 | 179 | ||
208 | if (freq_next < policy->min) | ||
209 | freq_next = policy->min; | ||
210 | |||
211 | if (!od_tuners->powersave_bias) { | 180 | if (!od_tuners->powersave_bias) { |
212 | __cpufreq_driver_target(policy, freq_next, | 181 | __cpufreq_driver_target(policy, freq_next, |
213 | CPUFREQ_RELATION_L); | 182 | CPUFREQ_RELATION_L); |
@@ -374,9 +343,6 @@ static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf, | |||
374 | input < MIN_FREQUENCY_UP_THRESHOLD) { | 343 | input < MIN_FREQUENCY_UP_THRESHOLD) { |
375 | return -EINVAL; | 344 | return -EINVAL; |
376 | } | 345 | } |
377 | /* Calculate the new adj_up_threshold */ | ||
378 | od_tuners->adj_up_threshold += input; | ||
379 | od_tuners->adj_up_threshold -= od_tuners->up_threshold; | ||
380 | 346 | ||
381 | od_tuners->up_threshold = input; | 347 | od_tuners->up_threshold = input; |
382 | return count; | 348 | return count; |
@@ -513,7 +479,7 @@ static int od_init(struct dbs_data *dbs_data) | |||
513 | u64 idle_time; | 479 | u64 idle_time; |
514 | int cpu; | 480 | int cpu; |
515 | 481 | ||
516 | tuners = kzalloc(sizeof(struct od_dbs_tuners), GFP_KERNEL); | 482 | tuners = kzalloc(sizeof(*tuners), GFP_KERNEL); |
517 | if (!tuners) { | 483 | if (!tuners) { |
518 | pr_err("%s: kzalloc failed\n", __func__); | 484 | pr_err("%s: kzalloc failed\n", __func__); |
519 | return -ENOMEM; | 485 | return -ENOMEM; |
@@ -525,8 +491,6 @@ static int od_init(struct dbs_data *dbs_data) | |||
525 | if (idle_time != -1ULL) { | 491 | if (idle_time != -1ULL) { |
526 | /* Idle micro accounting is supported. Use finer thresholds */ | 492 | /* Idle micro accounting is supported. Use finer thresholds */ |
527 | tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD; | 493 | tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD; |
528 | tuners->adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD - | ||
529 | MICRO_FREQUENCY_DOWN_DIFFERENTIAL; | ||
530 | /* | 494 | /* |
531 | * In nohz/micro accounting case we set the minimum frequency | 495 | * In nohz/micro accounting case we set the minimum frequency |
532 | * not depending on HZ, but fixed (very low). The deferred | 496 | * not depending on HZ, but fixed (very low). The deferred |
@@ -535,8 +499,6 @@ static int od_init(struct dbs_data *dbs_data) | |||
535 | dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE; | 499 | dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE; |
536 | } else { | 500 | } else { |
537 | tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; | 501 | tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; |
538 | tuners->adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD - | ||
539 | DEF_FREQUENCY_DOWN_DIFFERENTIAL; | ||
540 | 502 | ||
541 | /* For correct statistics, we need 10 ticks for each measure */ | 503 | /* For correct statistics, we need 10 ticks for each measure */ |
542 | dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * | 504 | dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * |
diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c index 9fef7d6e4e6a..cf117deb39b1 100644 --- a/drivers/cpufreq/cpufreq_performance.c +++ b/drivers/cpufreq/cpufreq_performance.c | |||
@@ -12,10 +12,9 @@ | |||
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
14 | 14 | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/cpufreq.h> | 15 | #include <linux/cpufreq.h> |
18 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/module.h> | ||
19 | 18 | ||
20 | static int cpufreq_governor_performance(struct cpufreq_policy *policy, | 19 | static int cpufreq_governor_performance(struct cpufreq_policy *policy, |
21 | unsigned int event) | 20 | unsigned int event) |
diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c index 32109a14f5dc..e3b874c235ea 100644 --- a/drivers/cpufreq/cpufreq_powersave.c +++ b/drivers/cpufreq/cpufreq_powersave.c | |||
@@ -12,10 +12,9 @@ | |||
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
14 | 14 | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/cpufreq.h> | 15 | #include <linux/cpufreq.h> |
18 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/module.h> | ||
19 | 18 | ||
20 | static int cpufreq_governor_powersave(struct cpufreq_policy *policy, | 19 | static int cpufreq_governor_powersave(struct cpufreq_policy *policy, |
21 | unsigned int event) | 20 | unsigned int event) |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index d37568c5ca9c..04452f026ed0 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -9,17 +9,10 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/cpu.h> | 12 | #include <linux/cpu.h> |
15 | #include <linux/sysfs.h> | ||
16 | #include <linux/cpufreq.h> | 13 | #include <linux/cpufreq.h> |
17 | #include <linux/module.h> | 14 | #include <linux/module.h> |
18 | #include <linux/jiffies.h> | 15 | #include <linux/slab.h> |
19 | #include <linux/percpu.h> | ||
20 | #include <linux/kobject.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/notifier.h> | ||
23 | #include <asm/cputime.h> | 16 | #include <asm/cputime.h> |
24 | 17 | ||
25 | static spinlock_t cpufreq_stats_lock; | 18 | static spinlock_t cpufreq_stats_lock; |
@@ -200,22 +193,22 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy, | |||
200 | { | 193 | { |
201 | unsigned int i, j, count = 0, ret = 0; | 194 | unsigned int i, j, count = 0, ret = 0; |
202 | struct cpufreq_stats *stat; | 195 | struct cpufreq_stats *stat; |
203 | struct cpufreq_policy *data; | 196 | struct cpufreq_policy *current_policy; |
204 | unsigned int alloc_size; | 197 | unsigned int alloc_size; |
205 | unsigned int cpu = policy->cpu; | 198 | unsigned int cpu = policy->cpu; |
206 | if (per_cpu(cpufreq_stats_table, cpu)) | 199 | if (per_cpu(cpufreq_stats_table, cpu)) |
207 | return -EBUSY; | 200 | return -EBUSY; |
208 | stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL); | 201 | stat = kzalloc(sizeof(*stat), GFP_KERNEL); |
209 | if ((stat) == NULL) | 202 | if ((stat) == NULL) |
210 | return -ENOMEM; | 203 | return -ENOMEM; |
211 | 204 | ||
212 | data = cpufreq_cpu_get(cpu); | 205 | current_policy = cpufreq_cpu_get(cpu); |
213 | if (data == NULL) { | 206 | if (current_policy == NULL) { |
214 | ret = -EINVAL; | 207 | ret = -EINVAL; |
215 | goto error_get_fail; | 208 | goto error_get_fail; |
216 | } | 209 | } |
217 | 210 | ||
218 | ret = sysfs_create_group(&data->kobj, &stats_attr_group); | 211 | ret = sysfs_create_group(¤t_policy->kobj, &stats_attr_group); |
219 | if (ret) | 212 | if (ret) |
220 | goto error_out; | 213 | goto error_out; |
221 | 214 | ||
@@ -258,10 +251,10 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy, | |||
258 | stat->last_time = get_jiffies_64(); | 251 | stat->last_time = get_jiffies_64(); |
259 | stat->last_index = freq_table_get_index(stat, policy->cur); | 252 | stat->last_index = freq_table_get_index(stat, policy->cur); |
260 | spin_unlock(&cpufreq_stats_lock); | 253 | spin_unlock(&cpufreq_stats_lock); |
261 | cpufreq_cpu_put(data); | 254 | cpufreq_cpu_put(current_policy); |
262 | return 0; | 255 | return 0; |
263 | error_out: | 256 | error_out: |
264 | cpufreq_cpu_put(data); | 257 | cpufreq_cpu_put(current_policy); |
265 | error_get_fail: | 258 | error_get_fail: |
266 | kfree(stat); | 259 | kfree(stat); |
267 | per_cpu(cpufreq_stats_table, cpu) = NULL; | 260 | per_cpu(cpufreq_stats_table, cpu) = NULL; |
@@ -348,16 +341,10 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, | |||
348 | unsigned int cpu = (unsigned long)hcpu; | 341 | unsigned int cpu = (unsigned long)hcpu; |
349 | 342 | ||
350 | switch (action) { | 343 | switch (action) { |
351 | case CPU_ONLINE: | ||
352 | case CPU_ONLINE_FROZEN: | ||
353 | cpufreq_update_policy(cpu); | ||
354 | break; | ||
355 | case CPU_DOWN_PREPARE: | 344 | case CPU_DOWN_PREPARE: |
356 | case CPU_DOWN_PREPARE_FROZEN: | ||
357 | cpufreq_stats_free_sysfs(cpu); | 345 | cpufreq_stats_free_sysfs(cpu); |
358 | break; | 346 | break; |
359 | case CPU_DEAD: | 347 | case CPU_DEAD: |
360 | case CPU_DEAD_FROZEN: | ||
361 | cpufreq_stats_free_table(cpu); | 348 | cpufreq_stats_free_table(cpu); |
362 | break; | 349 | break; |
363 | } | 350 | } |
@@ -390,8 +377,6 @@ static int __init cpufreq_stats_init(void) | |||
390 | return ret; | 377 | return ret; |
391 | 378 | ||
392 | register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); | 379 | register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); |
393 | for_each_online_cpu(cpu) | ||
394 | cpufreq_update_policy(cpu); | ||
395 | 380 | ||
396 | ret = cpufreq_register_notifier(¬ifier_trans_block, | 381 | ret = cpufreq_register_notifier(¬ifier_trans_block, |
397 | CPUFREQ_TRANSITION_NOTIFIER); | 382 | CPUFREQ_TRANSITION_NOTIFIER); |
diff --git a/drivers/cpufreq/cris-artpec3-cpufreq.c b/drivers/cpufreq/cris-artpec3-cpufreq.c index ee142c490575..cb8276dd19ca 100644 --- a/drivers/cpufreq/cris-artpec3-cpufreq.c +++ b/drivers/cpufreq/cris-artpec3-cpufreq.c | |||
@@ -111,7 +111,6 @@ static struct cpufreq_driver cris_freq_driver = { | |||
111 | .init = cris_freq_cpu_init, | 111 | .init = cris_freq_cpu_init, |
112 | .exit = cris_freq_cpu_exit, | 112 | .exit = cris_freq_cpu_exit, |
113 | .name = "cris_freq", | 113 | .name = "cris_freq", |
114 | .owner = THIS_MODULE, | ||
115 | .attr = cris_freq_attr, | 114 | .attr = cris_freq_attr, |
116 | }; | 115 | }; |
117 | 116 | ||
diff --git a/drivers/cpufreq/cris-etraxfs-cpufreq.c b/drivers/cpufreq/cris-etraxfs-cpufreq.c index 12952235d5db..72328f77dc53 100644 --- a/drivers/cpufreq/cris-etraxfs-cpufreq.c +++ b/drivers/cpufreq/cris-etraxfs-cpufreq.c | |||
@@ -108,7 +108,6 @@ static struct cpufreq_driver cris_freq_driver = { | |||
108 | .init = cris_freq_cpu_init, | 108 | .init = cris_freq_cpu_init, |
109 | .exit = cris_freq_cpu_exit, | 109 | .exit = cris_freq_cpu_exit, |
110 | .name = "cris_freq", | 110 | .name = "cris_freq", |
111 | .owner = THIS_MODULE, | ||
112 | .attr = cris_freq_attr, | 111 | .attr = cris_freq_attr, |
113 | }; | 112 | }; |
114 | 113 | ||
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index a60efaeb4cf8..09f64cc83019 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c | |||
@@ -54,7 +54,7 @@ static struct acpi_processor_performance *eps_acpi_cpu_perf; | |||
54 | /* Minimum necessary to get acpi_processor_get_bios_limit() working */ | 54 | /* Minimum necessary to get acpi_processor_get_bios_limit() working */ |
55 | static int eps_acpi_init(void) | 55 | static int eps_acpi_init(void) |
56 | { | 56 | { |
57 | eps_acpi_cpu_perf = kzalloc(sizeof(struct acpi_processor_performance), | 57 | eps_acpi_cpu_perf = kzalloc(sizeof(*eps_acpi_cpu_perf), |
58 | GFP_KERNEL); | 58 | GFP_KERNEL); |
59 | if (!eps_acpi_cpu_perf) | 59 | if (!eps_acpi_cpu_perf) |
60 | return -ENOMEM; | 60 | return -ENOMEM; |
@@ -366,7 +366,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
366 | states = 2; | 366 | states = 2; |
367 | 367 | ||
368 | /* Allocate private data and frequency table for current cpu */ | 368 | /* Allocate private data and frequency table for current cpu */ |
369 | centaur = kzalloc(sizeof(struct eps_cpu_data) | 369 | centaur = kzalloc(sizeof(*centaur) |
370 | + (states + 1) * sizeof(struct cpufreq_frequency_table), | 370 | + (states + 1) * sizeof(struct cpufreq_frequency_table), |
371 | GFP_KERNEL); | 371 | GFP_KERNEL); |
372 | if (!centaur) | 372 | if (!centaur) |
@@ -436,7 +436,6 @@ static struct cpufreq_driver eps_driver = { | |||
436 | .exit = eps_cpu_exit, | 436 | .exit = eps_cpu_exit, |
437 | .get = eps_get, | 437 | .get = eps_get, |
438 | .name = "e_powersaver", | 438 | .name = "e_powersaver", |
439 | .owner = THIS_MODULE, | ||
440 | .attr = eps_attr, | 439 | .attr = eps_attr, |
441 | }; | 440 | }; |
442 | 441 | ||
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index 658d860344b0..823a400d98fd 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c | |||
@@ -274,7 +274,6 @@ static struct cpufreq_driver elanfreq_driver = { | |||
274 | .init = elanfreq_cpu_init, | 274 | .init = elanfreq_cpu_init, |
275 | .exit = elanfreq_cpu_exit, | 275 | .exit = elanfreq_cpu_exit, |
276 | .name = "elanfreq", | 276 | .name = "elanfreq", |
277 | .owner = THIS_MODULE, | ||
278 | .attr = elanfreq_attr, | 277 | .attr = elanfreq_attr, |
279 | }; | 278 | }; |
280 | 279 | ||
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 0d32f02ef4d6..0fac34439e31 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c | |||
@@ -289,7 +289,7 @@ static int __init exynos_cpufreq_init(void) | |||
289 | { | 289 | { |
290 | int ret = -EINVAL; | 290 | int ret = -EINVAL; |
291 | 291 | ||
292 | exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL); | 292 | exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL); |
293 | if (!exynos_info) | 293 | if (!exynos_info) |
294 | return -ENOMEM; | 294 | return -ENOMEM; |
295 | 295 | ||
@@ -332,7 +332,6 @@ err_cpufreq: | |||
332 | regulator_put(arm_regulator); | 332 | regulator_put(arm_regulator); |
333 | err_vdd_arm: | 333 | err_vdd_arm: |
334 | kfree(exynos_info); | 334 | kfree(exynos_info); |
335 | pr_debug("%s: failed initialization\n", __func__); | ||
336 | return -EINVAL; | 335 | return -EINVAL; |
337 | } | 336 | } |
338 | late_initcall(exynos_cpufreq_init); | 337 | late_initcall(exynos_cpufreq_init); |
diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h index 92b852ee5ddc..7f25cee8cec2 100644 --- a/drivers/cpufreq/exynos-cpufreq.h +++ b/drivers/cpufreq/exynos-cpufreq.h | |||
@@ -43,6 +43,27 @@ struct exynos_dvfs_info { | |||
43 | bool (*need_apll_change)(unsigned int, unsigned int); | 43 | bool (*need_apll_change)(unsigned int, unsigned int); |
44 | }; | 44 | }; |
45 | 45 | ||
46 | #ifdef CONFIG_ARM_EXYNOS4210_CPUFREQ | ||
46 | extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *); | 47 | extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *); |
48 | #else | ||
49 | static inline int exynos4210_cpufreq_init(struct exynos_dvfs_info *info) | ||
50 | { | ||
51 | return -EOPNOTSUPP; | ||
52 | } | ||
53 | #endif | ||
54 | #ifdef CONFIG_ARM_EXYNOS4X12_CPUFREQ | ||
47 | extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *); | 55 | extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *); |
56 | #else | ||
57 | static inline int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) | ||
58 | { | ||
59 | return -EOPNOTSUPP; | ||
60 | } | ||
61 | #endif | ||
62 | #ifdef CONFIG_ARM_EXYNOS5250_CPUFREQ | ||
48 | extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *); | 63 | extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *); |
64 | #else | ||
65 | static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) | ||
66 | { | ||
67 | return -EOPNOTSUPP; | ||
68 | } | ||
69 | #endif | ||
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index 0c74018eda47..d514c152fd1a 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c | |||
@@ -238,6 +238,9 @@ static int exynos_target(struct cpufreq_policy *policy, | |||
238 | freqs.old = dvfs_info->cur_frequency; | 238 | freqs.old = dvfs_info->cur_frequency; |
239 | freqs.new = freq_table[index].frequency; | 239 | freqs.new = freq_table[index].frequency; |
240 | 240 | ||
241 | if (freqs.old == freqs.new) | ||
242 | goto out; | ||
243 | |||
241 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 244 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
242 | 245 | ||
243 | /* Set the target frequency in all C0_3_PSTATE register */ | 246 | /* Set the target frequency in all C0_3_PSTATE register */ |
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index f0d87412cc91..f111454a7aea 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
@@ -11,10 +11,8 @@ | |||
11 | 11 | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
13 | 13 | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/cpufreq.h> | 14 | #include <linux/cpufreq.h> |
15 | #include <linux/module.h> | ||
18 | 16 | ||
19 | /********************************************************************* | 17 | /********************************************************************* |
20 | * FREQUENCY TABLE HELPERS * | 18 | * FREQUENCY TABLE HELPERS * |
diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index 3dfc99b9ca86..70442c7b5e71 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c | |||
@@ -183,7 +183,7 @@ static void gx_write_byte(int reg, int value) | |||
183 | * gx_detect_chipset: | 183 | * gx_detect_chipset: |
184 | * | 184 | * |
185 | **/ | 185 | **/ |
186 | static __init struct pci_dev *gx_detect_chipset(void) | 186 | static struct pci_dev * __init gx_detect_chipset(void) |
187 | { | 187 | { |
188 | struct pci_dev *gx_pci = NULL; | 188 | struct pci_dev *gx_pci = NULL; |
189 | 189 | ||
@@ -446,7 +446,6 @@ static struct cpufreq_driver gx_suspmod_driver = { | |||
446 | .target = cpufreq_gx_target, | 446 | .target = cpufreq_gx_target, |
447 | .init = cpufreq_gx_cpu_init, | 447 | .init = cpufreq_gx_cpu_init, |
448 | .name = "gx-suspmod", | 448 | .name = "gx-suspmod", |
449 | .owner = THIS_MODULE, | ||
450 | }; | 449 | }; |
451 | 450 | ||
452 | static int __init cpufreq_gx_init(void) | 451 | static int __init cpufreq_gx_init(void) |
@@ -466,7 +465,7 @@ static int __init cpufreq_gx_init(void) | |||
466 | 465 | ||
467 | pr_debug("geode suspend modulation available.\n"); | 466 | pr_debug("geode suspend modulation available.\n"); |
468 | 467 | ||
469 | params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL); | 468 | params = kzalloc(sizeof(*params), GFP_KERNEL); |
470 | if (params == NULL) | 469 | if (params == NULL) |
471 | return -ENOMEM; | 470 | return -ENOMEM; |
472 | 471 | ||
diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c index b61b5a3fad64..794123fcf3e3 100644 --- a/drivers/cpufreq/highbank-cpufreq.c +++ b/drivers/cpufreq/highbank-cpufreq.c | |||
@@ -69,23 +69,17 @@ static int hb_cpufreq_driver_init(void) | |||
69 | if (!of_machine_is_compatible("calxeda,highbank")) | 69 | if (!of_machine_is_compatible("calxeda,highbank")) |
70 | return -ENODEV; | 70 | return -ENODEV; |
71 | 71 | ||
72 | for_each_child_of_node(of_find_node_by_path("/cpus"), np) | ||
73 | if (of_get_property(np, "operating-points", NULL)) | ||
74 | break; | ||
75 | |||
76 | if (!np) { | ||
77 | pr_err("failed to find highbank cpufreq node\n"); | ||
78 | return -ENOENT; | ||
79 | } | ||
80 | |||
81 | cpu_dev = get_cpu_device(0); | 72 | cpu_dev = get_cpu_device(0); |
82 | if (!cpu_dev) { | 73 | if (!cpu_dev) { |
83 | pr_err("failed to get highbank cpufreq device\n"); | 74 | pr_err("failed to get highbank cpufreq device\n"); |
84 | ret = -ENODEV; | 75 | return -ENODEV; |
85 | goto out_put_node; | ||
86 | } | 76 | } |
87 | 77 | ||
88 | cpu_dev->of_node = np; | 78 | np = of_node_get(cpu_dev->of_node); |
79 | if (!np) { | ||
80 | pr_err("failed to find highbank cpufreq node\n"); | ||
81 | return -ENOENT; | ||
82 | } | ||
89 | 83 | ||
90 | cpu_clk = clk_get(cpu_dev, NULL); | 84 | cpu_clk = clk_get(cpu_dev, NULL); |
91 | if (IS_ERR(cpu_clk)) { | 85 | if (IS_ERR(cpu_clk)) { |
diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index 573c14ea802d..3e14f0317175 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c | |||
@@ -274,7 +274,7 @@ acpi_cpufreq_cpu_init ( | |||
274 | 274 | ||
275 | pr_debug("acpi_cpufreq_cpu_init\n"); | 275 | pr_debug("acpi_cpufreq_cpu_init\n"); |
276 | 276 | ||
277 | data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); | 277 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
278 | if (!data) | 278 | if (!data) |
279 | return (-ENOMEM); | 279 | return (-ENOMEM); |
280 | 280 | ||
@@ -304,7 +304,7 @@ acpi_cpufreq_cpu_init ( | |||
304 | } | 304 | } |
305 | 305 | ||
306 | /* alloc freq_table */ | 306 | /* alloc freq_table */ |
307 | data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * | 307 | data->freq_table = kmalloc(sizeof(*data->freq_table) * |
308 | (data->acpi_data.state_count + 1), | 308 | (data->acpi_data.state_count + 1), |
309 | GFP_KERNEL); | 309 | GFP_KERNEL); |
310 | if (!data->freq_table) { | 310 | if (!data->freq_table) { |
@@ -409,7 +409,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = { | |||
409 | .init = acpi_cpufreq_cpu_init, | 409 | .init = acpi_cpufreq_cpu_init, |
410 | .exit = acpi_cpufreq_cpu_exit, | 410 | .exit = acpi_cpufreq_cpu_exit, |
411 | .name = "acpi-cpufreq", | 411 | .name = "acpi-cpufreq", |
412 | .owner = THIS_MODULE, | ||
413 | .attr = acpi_cpufreq_attr, | 412 | .attr = acpi_cpufreq_attr, |
414 | }; | 413 | }; |
415 | 414 | ||
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index e37cdaedbb5b..3e396543aea4 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c | |||
@@ -117,28 +117,11 @@ static int imx6q_set_target(struct cpufreq_policy *policy, | |||
117 | * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it | 117 | * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it |
118 | * - Disable pll2_pfd2_396m_clk | 118 | * - Disable pll2_pfd2_396m_clk |
119 | */ | 119 | */ |
120 | clk_prepare_enable(pll2_pfd2_396m_clk); | ||
121 | clk_set_parent(step_clk, pll2_pfd2_396m_clk); | 120 | clk_set_parent(step_clk, pll2_pfd2_396m_clk); |
122 | clk_set_parent(pll1_sw_clk, step_clk); | 121 | clk_set_parent(pll1_sw_clk, step_clk); |
123 | if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) { | 122 | if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) { |
124 | clk_set_rate(pll1_sys_clk, freqs.new * 1000); | 123 | clk_set_rate(pll1_sys_clk, freqs.new * 1000); |
125 | /* | ||
126 | * If we are leaving 396 MHz set-point, we need to enable | ||
127 | * pll1_sys_clk and disable pll2_pfd2_396m_clk to keep | ||
128 | * their use count correct. | ||
129 | */ | ||
130 | if (freqs.old * 1000 <= clk_get_rate(pll2_pfd2_396m_clk)) { | ||
131 | clk_prepare_enable(pll1_sys_clk); | ||
132 | clk_disable_unprepare(pll2_pfd2_396m_clk); | ||
133 | } | ||
134 | clk_set_parent(pll1_sw_clk, pll1_sys_clk); | 124 | clk_set_parent(pll1_sw_clk, pll1_sys_clk); |
135 | clk_disable_unprepare(pll2_pfd2_396m_clk); | ||
136 | } else { | ||
137 | /* | ||
138 | * Disable pll1_sys_clk if pll2_pfd2_396m_clk is sufficient | ||
139 | * to provide the frequency. | ||
140 | */ | ||
141 | clk_disable_unprepare(pll1_sys_clk); | ||
142 | } | 125 | } |
143 | 126 | ||
144 | /* Ensure the arm clock divider is what we expect */ | 127 | /* Ensure the arm clock divider is what we expect */ |
@@ -221,14 +204,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
221 | 204 | ||
222 | cpu_dev = &pdev->dev; | 205 | cpu_dev = &pdev->dev; |
223 | 206 | ||
224 | np = of_find_node_by_path("/cpus/cpu@0"); | 207 | np = of_node_get(cpu_dev->of_node); |
225 | if (!np) { | 208 | if (!np) { |
226 | dev_err(cpu_dev, "failed to find cpu0 node\n"); | 209 | dev_err(cpu_dev, "failed to find cpu0 node\n"); |
227 | return -ENOENT; | 210 | return -ENOENT; |
228 | } | 211 | } |
229 | 212 | ||
230 | cpu_dev->of_node = np; | ||
231 | |||
232 | arm_clk = devm_clk_get(cpu_dev, "arm"); | 213 | arm_clk = devm_clk_get(cpu_dev, "arm"); |
233 | pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys"); | 214 | pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys"); |
234 | pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw"); | 215 | pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw"); |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 7cde885011ed..6efd96c196b2 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -665,7 +665,6 @@ static struct cpufreq_driver intel_pstate_driver = { | |||
665 | .init = intel_pstate_cpu_init, | 665 | .init = intel_pstate_cpu_init, |
666 | .exit = intel_pstate_cpu_exit, | 666 | .exit = intel_pstate_cpu_exit, |
667 | .name = "intel_pstate", | 667 | .name = "intel_pstate", |
668 | .owner = THIS_MODULE, | ||
669 | }; | 668 | }; |
670 | 669 | ||
671 | static int __initdata no_load; | 670 | static int __initdata no_load; |
diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index c233ea617366..ba10658a9394 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/clk-provider.h> | 15 | #include <linux/clk-provider.h> |
16 | #include <linux/cpufreq.h> | 16 | #include <linux/cpufreq.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of_device.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <asm/proc-fns.h> | 20 | #include <asm/proc-fns.h> |
@@ -158,7 +158,6 @@ static struct cpufreq_driver kirkwood_cpufreq_driver = { | |||
158 | .init = kirkwood_cpufreq_cpu_init, | 158 | .init = kirkwood_cpufreq_cpu_init, |
159 | .exit = kirkwood_cpufreq_cpu_exit, | 159 | .exit = kirkwood_cpufreq_cpu_exit, |
160 | .name = "kirkwood-cpufreq", | 160 | .name = "kirkwood-cpufreq", |
161 | .owner = THIS_MODULE, | ||
162 | .attr = kirkwood_cpufreq_attr, | 161 | .attr = kirkwood_cpufreq_attr, |
163 | }; | 162 | }; |
164 | 163 | ||
@@ -175,9 +174,11 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev) | |||
175 | if (IS_ERR(priv.base)) | 174 | if (IS_ERR(priv.base)) |
176 | return PTR_ERR(priv.base); | 175 | return PTR_ERR(priv.base); |
177 | 176 | ||
178 | np = of_find_node_by_path("/cpus/cpu@0"); | 177 | np = of_cpu_device_node_get(0); |
179 | if (!np) | 178 | if (!np) { |
179 | dev_err(&pdev->dev, "failed to get cpu device node\n"); | ||
180 | return -ENODEV; | 180 | return -ENODEV; |
181 | } | ||
181 | 182 | ||
182 | priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk"); | 183 | priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk"); |
183 | if (IS_ERR(priv.cpu_clk)) { | 184 | if (IS_ERR(priv.cpu_clk)) { |
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 8c49261df57d..4ada1cccb052 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c | |||
@@ -948,7 +948,6 @@ static struct cpufreq_driver longhaul_driver = { | |||
948 | .init = longhaul_cpu_init, | 948 | .init = longhaul_cpu_init, |
949 | .exit = longhaul_cpu_exit, | 949 | .exit = longhaul_cpu_exit, |
950 | .name = "longhaul", | 950 | .name = "longhaul", |
951 | .owner = THIS_MODULE, | ||
952 | .attr = longhaul_attr, | 951 | .attr = longhaul_attr, |
953 | }; | 952 | }; |
954 | 953 | ||
diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c index 0fe041d1f77f..5aa031612d53 100644 --- a/drivers/cpufreq/longrun.c +++ b/drivers/cpufreq/longrun.c | |||
@@ -286,7 +286,6 @@ static struct cpufreq_driver longrun_driver = { | |||
286 | .get = longrun_get, | 286 | .get = longrun_get, |
287 | .init = longrun_cpu_init, | 287 | .init = longrun_cpu_init, |
288 | .name = "longrun", | 288 | .name = "longrun", |
289 | .owner = THIS_MODULE, | ||
290 | }; | 289 | }; |
291 | 290 | ||
292 | static const struct x86_cpu_id longrun_ids[] = { | 291 | static const struct x86_cpu_id longrun_ids[] = { |
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index 9536852c504a..7bc3c44d34e2 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c | |||
@@ -158,7 +158,6 @@ static struct freq_attr *loongson2_table_attr[] = { | |||
158 | }; | 158 | }; |
159 | 159 | ||
160 | static struct cpufreq_driver loongson2_cpufreq_driver = { | 160 | static struct cpufreq_driver loongson2_cpufreq_driver = { |
161 | .owner = THIS_MODULE, | ||
162 | .name = "loongson2", | 161 | .name = "loongson2", |
163 | .init = loongson2_cpufreq_cpu_init, | 162 | .init = loongson2_cpufreq_cpu_init, |
164 | .verify = loongson2_cpufreq_verify, | 163 | .verify = loongson2_cpufreq_verify, |
diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c index cdd62915efaf..6168d77b296d 100644 --- a/drivers/cpufreq/maple-cpufreq.c +++ b/drivers/cpufreq/maple-cpufreq.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/completion.h> | 24 | #include <linux/completion.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/of.h> | 27 | #include <linux/of_device.h> |
28 | 28 | ||
29 | #define DBG(fmt...) pr_debug(fmt) | 29 | #define DBG(fmt...) pr_debug(fmt) |
30 | 30 | ||
@@ -190,7 +190,6 @@ static int maple_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
190 | 190 | ||
191 | static struct cpufreq_driver maple_cpufreq_driver = { | 191 | static struct cpufreq_driver maple_cpufreq_driver = { |
192 | .name = "maple", | 192 | .name = "maple", |
193 | .owner = THIS_MODULE, | ||
194 | .flags = CPUFREQ_CONST_LOOPS, | 193 | .flags = CPUFREQ_CONST_LOOPS, |
195 | .init = maple_cpufreq_cpu_init, | 194 | .init = maple_cpufreq_cpu_init, |
196 | .verify = maple_cpufreq_verify, | 195 | .verify = maple_cpufreq_verify, |
@@ -201,7 +200,6 @@ static struct cpufreq_driver maple_cpufreq_driver = { | |||
201 | 200 | ||
202 | static int __init maple_cpufreq_init(void) | 201 | static int __init maple_cpufreq_init(void) |
203 | { | 202 | { |
204 | struct device_node *cpus; | ||
205 | struct device_node *cpunode; | 203 | struct device_node *cpunode; |
206 | unsigned int psize; | 204 | unsigned int psize; |
207 | unsigned long max_freq; | 205 | unsigned long max_freq; |
@@ -217,24 +215,11 @@ static int __init maple_cpufreq_init(void) | |||
217 | !of_machine_is_compatible("Momentum,Apache")) | 215 | !of_machine_is_compatible("Momentum,Apache")) |
218 | return 0; | 216 | return 0; |
219 | 217 | ||
220 | cpus = of_find_node_by_path("/cpus"); | ||
221 | if (cpus == NULL) { | ||
222 | DBG("No /cpus node !\n"); | ||
223 | return -ENODEV; | ||
224 | } | ||
225 | |||
226 | /* Get first CPU node */ | 218 | /* Get first CPU node */ |
227 | for (cpunode = NULL; | 219 | cpunode = of_cpu_device_node_get(0); |
228 | (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { | ||
229 | const u32 *reg = of_get_property(cpunode, "reg", NULL); | ||
230 | if (reg == NULL || (*reg) != 0) | ||
231 | continue; | ||
232 | if (!strcmp(cpunode->type, "cpu")) | ||
233 | break; | ||
234 | } | ||
235 | if (cpunode == NULL) { | 220 | if (cpunode == NULL) { |
236 | printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n"); | 221 | printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n"); |
237 | goto bail_cpus; | 222 | goto bail_noprops; |
238 | } | 223 | } |
239 | 224 | ||
240 | /* Check 970FX for now */ | 225 | /* Check 970FX for now */ |
@@ -290,14 +275,11 @@ static int __init maple_cpufreq_init(void) | |||
290 | rc = cpufreq_register_driver(&maple_cpufreq_driver); | 275 | rc = cpufreq_register_driver(&maple_cpufreq_driver); |
291 | 276 | ||
292 | of_node_put(cpunode); | 277 | of_node_put(cpunode); |
293 | of_node_put(cpus); | ||
294 | 278 | ||
295 | return rc; | 279 | return rc; |
296 | 280 | ||
297 | bail_noprops: | 281 | bail_noprops: |
298 | of_node_put(cpunode); | 282 | of_node_put(cpunode); |
299 | bail_cpus: | ||
300 | of_node_put(cpus); | ||
301 | 283 | ||
302 | return rc; | 284 | return rc; |
303 | } | 285 | } |
diff --git a/drivers/cpufreq/mperf.c b/drivers/cpufreq/mperf.c deleted file mode 100644 index 911e193018ae..000000000000 --- a/drivers/cpufreq/mperf.c +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/smp.h> | ||
3 | #include <linux/module.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/cpufreq.h> | ||
6 | #include <linux/slab.h> | ||
7 | |||
8 | #include "mperf.h" | ||
9 | |||
10 | static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf); | ||
11 | |||
12 | /* Called via smp_call_function_single(), on the target CPU */ | ||
13 | static void read_measured_perf_ctrs(void *_cur) | ||
14 | { | ||
15 | struct aperfmperf *am = _cur; | ||
16 | |||
17 | get_aperfmperf(am); | ||
18 | } | ||
19 | |||
20 | /* | ||
21 | * Return the measured active (C0) frequency on this CPU since last call | ||
22 | * to this function. | ||
23 | * Input: cpu number | ||
24 | * Return: Average CPU frequency in terms of max frequency (zero on error) | ||
25 | * | ||
26 | * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance | ||
27 | * over a period of time, while CPU is in C0 state. | ||
28 | * IA32_MPERF counts at the rate of max advertised frequency | ||
29 | * IA32_APERF counts at the rate of actual CPU frequency | ||
30 | * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and | ||
31 | * no meaning should be associated with absolute values of these MSRs. | ||
32 | */ | ||
33 | unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy, | ||
34 | unsigned int cpu) | ||
35 | { | ||
36 | struct aperfmperf perf; | ||
37 | unsigned long ratio; | ||
38 | unsigned int retval; | ||
39 | |||
40 | if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1)) | ||
41 | return 0; | ||
42 | |||
43 | ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf); | ||
44 | per_cpu(acfreq_old_perf, cpu) = perf; | ||
45 | |||
46 | retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT; | ||
47 | |||
48 | return retval; | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf); | ||
51 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/cpufreq/mperf.h b/drivers/cpufreq/mperf.h deleted file mode 100644 index 5dbf2950dc22..000000000000 --- a/drivers/cpufreq/mperf.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | /* | ||
2 | * (c) 2010 Advanced Micro Devices, Inc. | ||
3 | * Your use of this code is subject to the terms and conditions of the | ||
4 | * GNU general public license version 2. See "COPYING" or | ||
5 | * http://www.gnu.org/licenses/gpl.html | ||
6 | */ | ||
7 | |||
8 | unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy, | ||
9 | unsigned int cpu); | ||
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index 9ee78170ff86..2f0a2a65c37f 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c | |||
@@ -279,7 +279,6 @@ static struct cpufreq_driver p4clockmod_driver = { | |||
279 | .exit = cpufreq_p4_cpu_exit, | 279 | .exit = cpufreq_p4_cpu_exit, |
280 | .get = cpufreq_p4_get, | 280 | .get = cpufreq_p4_get, |
281 | .name = "p4-clockmod", | 281 | .name = "p4-clockmod", |
282 | .owner = THIS_MODULE, | ||
283 | .attr = p4clockmod_attr, | 282 | .attr = p4clockmod_attr, |
284 | }; | 283 | }; |
285 | 284 | ||
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index b704da404067..534e43a60d1f 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c | |||
@@ -297,7 +297,6 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy, | |||
297 | 297 | ||
298 | static struct cpufreq_driver pas_cpufreq_driver = { | 298 | static struct cpufreq_driver pas_cpufreq_driver = { |
299 | .name = "pas-cpufreq", | 299 | .name = "pas-cpufreq", |
300 | .owner = THIS_MODULE, | ||
301 | .flags = CPUFREQ_CONST_LOOPS, | 300 | .flags = CPUFREQ_CONST_LOOPS, |
302 | .init = pas_cpufreq_cpu_init, | 301 | .init = pas_cpufreq_cpu_init, |
303 | .exit = pas_cpufreq_cpu_exit, | 302 | .exit = pas_cpufreq_cpu_exit, |
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index 1581fcc4cf4a..d81c4e5ea0ad 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c | |||
@@ -587,7 +587,6 @@ static struct cpufreq_driver pcc_cpufreq_driver = { | |||
587 | .init = pcc_cpufreq_cpu_init, | 587 | .init = pcc_cpufreq_cpu_init, |
588 | .exit = pcc_cpufreq_cpu_exit, | 588 | .exit = pcc_cpufreq_cpu_exit, |
589 | .name = "pcc-cpufreq", | 589 | .name = "pcc-cpufreq", |
590 | .owner = THIS_MODULE, | ||
591 | }; | 590 | }; |
592 | 591 | ||
593 | static int __init pcc_cpufreq_init(void) | 592 | static int __init pcc_cpufreq_init(void) |
diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index 3104fad82480..a096cd3fa23d 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/hardirq.h> | 27 | #include <linux/hardirq.h> |
28 | #include <linux/of_device.h> | ||
28 | #include <asm/prom.h> | 29 | #include <asm/prom.h> |
29 | #include <asm/machdep.h> | 30 | #include <asm/machdep.h> |
30 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
@@ -477,7 +478,6 @@ static struct cpufreq_driver pmac_cpufreq_driver = { | |||
477 | .flags = CPUFREQ_PM_NO_WARN, | 478 | .flags = CPUFREQ_PM_NO_WARN, |
478 | .attr = pmac_cpu_freqs_attr, | 479 | .attr = pmac_cpu_freqs_attr, |
479 | .name = "powermac", | 480 | .name = "powermac", |
480 | .owner = THIS_MODULE, | ||
481 | }; | 481 | }; |
482 | 482 | ||
483 | 483 | ||
@@ -649,8 +649,8 @@ static int __init pmac_cpufreq_setup(void) | |||
649 | if (strstr(cmd_line, "nocpufreq")) | 649 | if (strstr(cmd_line, "nocpufreq")) |
650 | return 0; | 650 | return 0; |
651 | 651 | ||
652 | /* Assume only one CPU */ | 652 | /* Get first CPU node */ |
653 | cpunode = of_find_node_by_type(NULL, "cpu"); | 653 | cpunode = of_cpu_device_node_get(0); |
654 | if (!cpunode) | 654 | if (!cpunode) |
655 | goto out; | 655 | goto out; |
656 | 656 | ||
diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 7ba423431cfe..3a51ad7e47c8 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/completion.h> | 23 | #include <linux/completion.h> |
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/of_device.h> | ||
25 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
26 | #include <asm/machdep.h> | 27 | #include <asm/machdep.h> |
27 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
@@ -371,7 +372,6 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
371 | 372 | ||
372 | static struct cpufreq_driver g5_cpufreq_driver = { | 373 | static struct cpufreq_driver g5_cpufreq_driver = { |
373 | .name = "powermac", | 374 | .name = "powermac", |
374 | .owner = THIS_MODULE, | ||
375 | .flags = CPUFREQ_CONST_LOOPS, | 375 | .flags = CPUFREQ_CONST_LOOPS, |
376 | .init = g5_cpufreq_cpu_init, | 376 | .init = g5_cpufreq_cpu_init, |
377 | .verify = g5_cpufreq_verify, | 377 | .verify = g5_cpufreq_verify, |
@@ -383,9 +383,8 @@ static struct cpufreq_driver g5_cpufreq_driver = { | |||
383 | 383 | ||
384 | #ifdef CONFIG_PMAC_SMU | 384 | #ifdef CONFIG_PMAC_SMU |
385 | 385 | ||
386 | static int __init g5_neo2_cpufreq_init(struct device_node *cpus) | 386 | static int __init g5_neo2_cpufreq_init(struct device_node *cpunode) |
387 | { | 387 | { |
388 | struct device_node *cpunode; | ||
389 | unsigned int psize, ssize; | 388 | unsigned int psize, ssize; |
390 | unsigned long max_freq; | 389 | unsigned long max_freq; |
391 | char *freq_method, *volt_method; | 390 | char *freq_method, *volt_method; |
@@ -405,20 +404,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) | |||
405 | else | 404 | else |
406 | return -ENODEV; | 405 | return -ENODEV; |
407 | 406 | ||
408 | /* Get first CPU node */ | ||
409 | for (cpunode = NULL; | ||
410 | (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { | ||
411 | const u32 *reg = of_get_property(cpunode, "reg", NULL); | ||
412 | if (reg == NULL || (*reg) != 0) | ||
413 | continue; | ||
414 | if (!strcmp(cpunode->type, "cpu")) | ||
415 | break; | ||
416 | } | ||
417 | if (cpunode == NULL) { | ||
418 | printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n"); | ||
419 | return -ENODEV; | ||
420 | } | ||
421 | |||
422 | /* Check 970FX for now */ | 407 | /* Check 970FX for now */ |
423 | valp = of_get_property(cpunode, "cpu-version", NULL); | 408 | valp = of_get_property(cpunode, "cpu-version", NULL); |
424 | if (!valp) { | 409 | if (!valp) { |
@@ -447,9 +432,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) | |||
447 | if (!shdr) | 432 | if (!shdr) |
448 | goto bail_noprops; | 433 | goto bail_noprops; |
449 | g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1]; | 434 | g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1]; |
450 | ssize = (shdr->len * sizeof(u32)) - | 435 | ssize = (shdr->len * sizeof(u32)) - sizeof(*shdr); |
451 | sizeof(struct smu_sdbp_header); | 436 | g5_fvt_count = ssize / sizeof(*g5_fvt_table); |
452 | g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt); | ||
453 | g5_fvt_cur = 0; | 437 | g5_fvt_cur = 0; |
454 | 438 | ||
455 | /* Sanity checking */ | 439 | /* Sanity checking */ |
@@ -537,9 +521,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) | |||
537 | #endif /* CONFIG_PMAC_SMU */ | 521 | #endif /* CONFIG_PMAC_SMU */ |
538 | 522 | ||
539 | 523 | ||
540 | static int __init g5_pm72_cpufreq_init(struct device_node *cpus) | 524 | static int __init g5_pm72_cpufreq_init(struct device_node *cpunode) |
541 | { | 525 | { |
542 | struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; | 526 | struct device_node *cpuid = NULL, *hwclock = NULL; |
543 | const u8 *eeprom = NULL; | 527 | const u8 *eeprom = NULL; |
544 | const u32 *valp; | 528 | const u32 *valp; |
545 | u64 max_freq, min_freq, ih, il; | 529 | u64 max_freq, min_freq, ih, il; |
@@ -548,17 +532,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) | |||
548 | DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and" | 532 | DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and" |
549 | " RackMac3,1...\n"); | 533 | " RackMac3,1...\n"); |
550 | 534 | ||
551 | /* Get first CPU node */ | ||
552 | for (cpunode = NULL; | ||
553 | (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { | ||
554 | if (!strcmp(cpunode->type, "cpu")) | ||
555 | break; | ||
556 | } | ||
557 | if (cpunode == NULL) { | ||
558 | printk(KERN_ERR "cpufreq: Can't find any CPU node\n"); | ||
559 | return -ENODEV; | ||
560 | } | ||
561 | |||
562 | /* Lookup the cpuid eeprom node */ | 535 | /* Lookup the cpuid eeprom node */ |
563 | cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0"); | 536 | cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0"); |
564 | if (cpuid != NULL) | 537 | if (cpuid != NULL) |
@@ -718,25 +691,25 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) | |||
718 | 691 | ||
719 | static int __init g5_cpufreq_init(void) | 692 | static int __init g5_cpufreq_init(void) |
720 | { | 693 | { |
721 | struct device_node *cpus; | 694 | struct device_node *cpunode; |
722 | int rc = 0; | 695 | int rc = 0; |
723 | 696 | ||
724 | cpus = of_find_node_by_path("/cpus"); | 697 | /* Get first CPU node */ |
725 | if (cpus == NULL) { | 698 | cpunode = of_cpu_device_node_get(0); |
726 | DBG("No /cpus node !\n"); | 699 | if (cpunode == NULL) { |
700 | pr_err("cpufreq: Can't find any CPU node\n"); | ||
727 | return -ENODEV; | 701 | return -ENODEV; |
728 | } | 702 | } |
729 | 703 | ||
730 | if (of_machine_is_compatible("PowerMac7,2") || | 704 | if (of_machine_is_compatible("PowerMac7,2") || |
731 | of_machine_is_compatible("PowerMac7,3") || | 705 | of_machine_is_compatible("PowerMac7,3") || |
732 | of_machine_is_compatible("RackMac3,1")) | 706 | of_machine_is_compatible("RackMac3,1")) |
733 | rc = g5_pm72_cpufreq_init(cpus); | 707 | rc = g5_pm72_cpufreq_init(cpunode); |
734 | #ifdef CONFIG_PMAC_SMU | 708 | #ifdef CONFIG_PMAC_SMU |
735 | else | 709 | else |
736 | rc = g5_neo2_cpufreq_init(cpus); | 710 | rc = g5_neo2_cpufreq_init(cpunode); |
737 | #endif /* CONFIG_PMAC_SMU */ | 711 | #endif /* CONFIG_PMAC_SMU */ |
738 | 712 | ||
739 | of_node_put(cpus); | ||
740 | return rc; | 713 | return rc; |
741 | } | 714 | } |
742 | 715 | ||
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index ea8e10382ec5..85f1c8c25ddc 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c | |||
@@ -207,7 +207,6 @@ static struct cpufreq_driver powernow_k6_driver = { | |||
207 | .exit = powernow_k6_cpu_exit, | 207 | .exit = powernow_k6_cpu_exit, |
208 | .get = powernow_k6_get, | 208 | .get = powernow_k6_get, |
209 | .name = "powernow-k6", | 209 | .name = "powernow-k6", |
210 | .owner = THIS_MODULE, | ||
211 | .attr = powernow_k6_attr, | 210 | .attr = powernow_k6_attr, |
212 | }; | 211 | }; |
213 | 212 | ||
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 955870877935..14ce480be8ab 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c | |||
@@ -177,7 +177,7 @@ static int get_ranges(unsigned char *pst) | |||
177 | unsigned int speed; | 177 | unsigned int speed; |
178 | u8 fid, vid; | 178 | u8 fid, vid; |
179 | 179 | ||
180 | powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * | 180 | powernow_table = kzalloc((sizeof(*powernow_table) * |
181 | (number_scales + 1)), GFP_KERNEL); | 181 | (number_scales + 1)), GFP_KERNEL); |
182 | if (!powernow_table) | 182 | if (!powernow_table) |
183 | return -ENOMEM; | 183 | return -ENOMEM; |
@@ -309,8 +309,7 @@ static int powernow_acpi_init(void) | |||
309 | goto err0; | 309 | goto err0; |
310 | } | 310 | } |
311 | 311 | ||
312 | acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance), | 312 | acpi_processor_perf = kzalloc(sizeof(*acpi_processor_perf), GFP_KERNEL); |
313 | GFP_KERNEL); | ||
314 | if (!acpi_processor_perf) { | 313 | if (!acpi_processor_perf) { |
315 | retval = -ENOMEM; | 314 | retval = -ENOMEM; |
316 | goto err0; | 315 | goto err0; |
@@ -346,7 +345,7 @@ static int powernow_acpi_init(void) | |||
346 | goto err2; | 345 | goto err2; |
347 | } | 346 | } |
348 | 347 | ||
349 | powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * | 348 | powernow_table = kzalloc((sizeof(*powernow_table) * |
350 | (number_scales + 1)), GFP_KERNEL); | 349 | (number_scales + 1)), GFP_KERNEL); |
351 | if (!powernow_table) { | 350 | if (!powernow_table) { |
352 | retval = -ENOMEM; | 351 | retval = -ENOMEM; |
@@ -497,7 +496,7 @@ static int powernow_decode_bios(int maxfid, int startvid) | |||
497 | "relevant to this CPU).\n", | 496 | "relevant to this CPU).\n", |
498 | psb->numpst); | 497 | psb->numpst); |
499 | 498 | ||
500 | p += sizeof(struct psb_s); | 499 | p += sizeof(*psb); |
501 | 500 | ||
502 | pst = (struct pst_s *) p; | 501 | pst = (struct pst_s *) p; |
503 | 502 | ||
@@ -510,12 +509,12 @@ static int powernow_decode_bios(int maxfid, int startvid) | |||
510 | (maxfid == pst->maxfid) && | 509 | (maxfid == pst->maxfid) && |
511 | (startvid == pst->startvid)) { | 510 | (startvid == pst->startvid)) { |
512 | print_pst_entry(pst, j); | 511 | print_pst_entry(pst, j); |
513 | p = (char *)pst + sizeof(struct pst_s); | 512 | p = (char *)pst + sizeof(*pst); |
514 | ret = get_ranges(p); | 513 | ret = get_ranges(p); |
515 | return ret; | 514 | return ret; |
516 | } else { | 515 | } else { |
517 | unsigned int k; | 516 | unsigned int k; |
518 | p = (char *)pst + sizeof(struct pst_s); | 517 | p = (char *)pst + sizeof(*pst); |
519 | for (k = 0; k < number_scales; k++) | 518 | for (k = 0; k < number_scales; k++) |
520 | p += 2; | 519 | p += 2; |
521 | } | 520 | } |
@@ -717,7 +716,6 @@ static struct cpufreq_driver powernow_driver = { | |||
717 | .init = powernow_cpu_init, | 716 | .init = powernow_cpu_init, |
718 | .exit = powernow_cpu_exit, | 717 | .exit = powernow_cpu_exit, |
719 | .name = "powernow-k7", | 718 | .name = "powernow-k7", |
720 | .owner = THIS_MODULE, | ||
721 | .attr = powernow_table_attr, | 719 | .attr = powernow_table_attr, |
722 | }; | 720 | }; |
723 | 721 | ||
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index c39d189217cb..2344a9ed17f3 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -623,7 +623,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, | |||
623 | if (check_pst_table(data, pst, maxvid)) | 623 | if (check_pst_table(data, pst, maxvid)) |
624 | return -EINVAL; | 624 | return -EINVAL; |
625 | 625 | ||
626 | powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) | 626 | powernow_table = kmalloc((sizeof(*powernow_table) |
627 | * (data->numps + 1)), GFP_KERNEL); | 627 | * (data->numps + 1)), GFP_KERNEL); |
628 | if (!powernow_table) { | 628 | if (!powernow_table) { |
629 | printk(KERN_ERR PFX "powernow_table memory alloc failure\n"); | 629 | printk(KERN_ERR PFX "powernow_table memory alloc failure\n"); |
@@ -793,7 +793,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
793 | } | 793 | } |
794 | 794 | ||
795 | /* fill in data->powernow_table */ | 795 | /* fill in data->powernow_table */ |
796 | powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) | 796 | powernow_table = kmalloc((sizeof(*powernow_table) |
797 | * (data->acpi_data.state_count + 1)), GFP_KERNEL); | 797 | * (data->acpi_data.state_count + 1)), GFP_KERNEL); |
798 | if (!powernow_table) { | 798 | if (!powernow_table) { |
799 | pr_debug("powernow_table memory alloc failure\n"); | 799 | pr_debug("powernow_table memory alloc failure\n"); |
@@ -1106,7 +1106,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1106 | if (rc) | 1106 | if (rc) |
1107 | return -ENODEV; | 1107 | return -ENODEV; |
1108 | 1108 | ||
1109 | data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL); | 1109 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
1110 | if (!data) { | 1110 | if (!data) { |
1111 | printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); | 1111 | printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); |
1112 | return -ENOMEM; | 1112 | return -ENOMEM; |
@@ -1240,7 +1240,6 @@ static struct cpufreq_driver cpufreq_amd64_driver = { | |||
1240 | .exit = powernowk8_cpu_exit, | 1240 | .exit = powernowk8_cpu_exit, |
1241 | .get = powernowk8_get, | 1241 | .get = powernowk8_get, |
1242 | .name = "powernow-k8", | 1242 | .name = "powernow-k8", |
1243 | .owner = THIS_MODULE, | ||
1244 | .attr = powernow_k8_attr, | 1243 | .attr = powernow_k8_attr, |
1245 | }; | 1244 | }; |
1246 | 1245 | ||
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index 3cae4529f959..60e81d524ea8 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c | |||
@@ -300,7 +300,6 @@ static struct freq_attr *corenet_cpufreq_attr[] = { | |||
300 | 300 | ||
301 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | 301 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { |
302 | .name = "ppc_cpufreq", | 302 | .name = "ppc_cpufreq", |
303 | .owner = THIS_MODULE, | ||
304 | .flags = CPUFREQ_CONST_LOOPS, | 303 | .flags = CPUFREQ_CONST_LOOPS, |
305 | .init = corenet_cpufreq_cpu_init, | 304 | .init = corenet_cpufreq_cpu_init, |
306 | .exit = __exit_p(corenet_cpufreq_cpu_exit), | 305 | .exit = __exit_p(corenet_cpufreq_cpu_exit), |
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 5936f8d6f2cc..2e448f0bbdc5 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c | |||
@@ -181,7 +181,6 @@ static struct cpufreq_driver cbe_cpufreq_driver = { | |||
181 | .init = cbe_cpufreq_cpu_init, | 181 | .init = cbe_cpufreq_cpu_init, |
182 | .exit = cbe_cpufreq_cpu_exit, | 182 | .exit = cbe_cpufreq_cpu_exit, |
183 | .name = "cbe-cpufreq", | 183 | .name = "cbe-cpufreq", |
184 | .owner = THIS_MODULE, | ||
185 | .flags = CPUFREQ_CONST_LOOPS, | 184 | .flags = CPUFREQ_CONST_LOOPS, |
186 | }; | 185 | }; |
187 | 186 | ||
diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index fb3981ac829f..8749eaf18793 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c | |||
@@ -191,7 +191,7 @@ static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) | |||
191 | return ret; | 191 | return ret; |
192 | } | 192 | } |
193 | 193 | ||
194 | static __init void pxa_cpufreq_init_voltages(void) | 194 | static void __init pxa_cpufreq_init_voltages(void) |
195 | { | 195 | { |
196 | vcc_core = regulator_get(NULL, "vcc_core"); | 196 | vcc_core = regulator_get(NULL, "vcc_core"); |
197 | if (IS_ERR(vcc_core)) { | 197 | if (IS_ERR(vcc_core)) { |
@@ -207,7 +207,7 @@ static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static __init void pxa_cpufreq_init_voltages(void) { } | 210 | static void __init pxa_cpufreq_init_voltages(void) { } |
211 | #endif | 211 | #endif |
212 | 212 | ||
213 | static void find_freq_tables(struct cpufreq_frequency_table **freq_table, | 213 | static void find_freq_tables(struct cpufreq_frequency_table **freq_table, |
diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index 9c92ef032a9e..d26306fb00d2 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c | |||
@@ -213,10 +213,12 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) | |||
213 | policy->cur = policy->min = policy->max; | 213 | policy->cur = policy->min = policy->max; |
214 | 214 | ||
215 | if (cpu_is_pxa300() || cpu_is_pxa310()) | 215 | if (cpu_is_pxa300() || cpu_is_pxa310()) |
216 | ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs)); | 216 | ret = setup_freqs_table(policy, pxa300_freqs, |
217 | ARRAY_SIZE(pxa300_freqs)); | ||
217 | 218 | ||
218 | if (cpu_is_pxa320()) | 219 | if (cpu_is_pxa320()) |
219 | ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa320_freqs)); | 220 | ret = setup_freqs_table(policy, pxa320_freqs, |
221 | ARRAY_SIZE(pxa320_freqs)); | ||
220 | 222 | ||
221 | if (ret) { | 223 | if (ret) { |
222 | pr_err("failed to setup frequency table\n"); | 224 | pr_err("failed to setup frequency table\n"); |
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index ce5b9fca9c18..22dcb81ef9d0 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c | |||
@@ -524,7 +524,6 @@ static struct freq_attr *s3c2416_cpufreq_attr[] = { | |||
524 | }; | 524 | }; |
525 | 525 | ||
526 | static struct cpufreq_driver s3c2416_cpufreq_driver = { | 526 | static struct cpufreq_driver s3c2416_cpufreq_driver = { |
527 | .owner = THIS_MODULE, | ||
528 | .flags = 0, | 527 | .flags = 0, |
529 | .verify = s3c2416_cpufreq_verify_speed, | 528 | .verify = s3c2416_cpufreq_verify_speed, |
530 | .target = s3c2416_cpufreq_set_target, | 529 | .target = s3c2416_cpufreq_set_target, |
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 87781eb20d6d..b0f343fcb7ee 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c | |||
@@ -392,7 +392,7 @@ static int s3c_cpufreq_init(struct cpufreq_policy *policy) | |||
392 | return 0; | 392 | return 0; |
393 | } | 393 | } |
394 | 394 | ||
395 | static __init int s3c_cpufreq_initclks(void) | 395 | static int __init s3c_cpufreq_initclks(void) |
396 | { | 396 | { |
397 | _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll"); | 397 | _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll"); |
398 | _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal"); | 398 | _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal"); |
@@ -522,7 +522,7 @@ int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) | |||
522 | /* Copy the board information so that each board can make this | 522 | /* Copy the board information so that each board can make this |
523 | * initdata. */ | 523 | * initdata. */ |
524 | 524 | ||
525 | ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL); | 525 | ours = kzalloc(sizeof(*ours), GFP_KERNEL); |
526 | if (ours == NULL) { | 526 | if (ours == NULL) { |
527 | printk(KERN_ERR "%s: no memory\n", __func__); | 527 | printk(KERN_ERR "%s: no memory\n", __func__); |
528 | return -ENOMEM; | 528 | return -ENOMEM; |
@@ -615,7 +615,7 @@ static int s3c_cpufreq_build_freq(void) | |||
615 | size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0); | 615 | size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0); |
616 | size++; | 616 | size++; |
617 | 617 | ||
618 | ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL); | 618 | ftab = kmalloc(sizeof(*ftab) * size, GFP_KERNEL); |
619 | if (!ftab) { | 619 | if (!ftab) { |
620 | printk(KERN_ERR "%s: no memory for tables\n", __func__); | 620 | printk(KERN_ERR "%s: no memory for tables\n", __func__); |
621 | return -ENOMEM; | 621 | return -ENOMEM; |
@@ -691,7 +691,7 @@ int __init s3c_plltab_register(struct cpufreq_frequency_table *plls, | |||
691 | struct cpufreq_frequency_table *vals; | 691 | struct cpufreq_frequency_table *vals; |
692 | unsigned int size; | 692 | unsigned int size; |
693 | 693 | ||
694 | size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1); | 694 | size = sizeof(*vals) * (plls_no + 1); |
695 | 695 | ||
696 | vals = kmalloc(size, GFP_KERNEL); | 696 | vals = kmalloc(size, GFP_KERNEL); |
697 | if (vals) { | 697 | if (vals) { |
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index 13bb4bae64ee..8a72b0c555f8 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c | |||
@@ -263,7 +263,6 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
263 | } | 263 | } |
264 | 264 | ||
265 | static struct cpufreq_driver s3c64xx_cpufreq_driver = { | 265 | static struct cpufreq_driver s3c64xx_cpufreq_driver = { |
266 | .owner = THIS_MODULE, | ||
267 | .flags = 0, | 266 | .flags = 0, |
268 | .verify = s3c64xx_cpufreq_verify_speed, | 267 | .verify = s3c64xx_cpufreq_verify_speed, |
269 | .target = s3c64xx_cpufreq_set_target, | 268 | .target = s3c64xx_cpufreq_set_target, |
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index 77a210975fc4..d6f6c6f4efa7 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c | |||
@@ -147,7 +147,6 @@ static struct cpufreq_driver sc520_freq_driver = { | |||
147 | .init = sc520_freq_cpu_init, | 147 | .init = sc520_freq_cpu_init, |
148 | .exit = sc520_freq_cpu_exit, | 148 | .exit = sc520_freq_cpu_exit, |
149 | .name = "sc520_freq", | 149 | .name = "sc520_freq", |
150 | .owner = THIS_MODULE, | ||
151 | .attr = sc520_freq_attr, | 150 | .attr = sc520_freq_attr, |
152 | }; | 151 | }; |
153 | 152 | ||
diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c index 73adb64651e8..ffc6d24b0cfb 100644 --- a/drivers/cpufreq/sh-cpufreq.c +++ b/drivers/cpufreq/sh-cpufreq.c | |||
@@ -160,7 +160,6 @@ static struct freq_attr *sh_freq_attr[] = { | |||
160 | }; | 160 | }; |
161 | 161 | ||
162 | static struct cpufreq_driver sh_cpufreq_driver = { | 162 | static struct cpufreq_driver sh_cpufreq_driver = { |
163 | .owner = THIS_MODULE, | ||
164 | .name = "sh", | 163 | .name = "sh", |
165 | .get = sh_cpufreq_get, | 164 | .get = sh_cpufreq_get, |
166 | .target = sh_cpufreq_target, | 165 | .target = sh_cpufreq_target, |
diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c index 93061a408773..cf5bc2ca16fa 100644 --- a/drivers/cpufreq/sparc-us2e-cpufreq.c +++ b/drivers/cpufreq/sparc-us2e-cpufreq.c | |||
@@ -351,12 +351,11 @@ static int __init us2e_freq_init(void) | |||
351 | struct cpufreq_driver *driver; | 351 | struct cpufreq_driver *driver; |
352 | 352 | ||
353 | ret = -ENOMEM; | 353 | ret = -ENOMEM; |
354 | driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL); | 354 | driver = kzalloc(sizeof(*driver), GFP_KERNEL); |
355 | if (!driver) | 355 | if (!driver) |
356 | goto err_out; | 356 | goto err_out; |
357 | 357 | ||
358 | us2e_freq_table = kzalloc( | 358 | us2e_freq_table = kzalloc((NR_CPUS * sizeof(*us2e_freq_table)), |
359 | (NR_CPUS * sizeof(struct us2e_freq_percpu_info)), | ||
360 | GFP_KERNEL); | 359 | GFP_KERNEL); |
361 | if (!us2e_freq_table) | 360 | if (!us2e_freq_table) |
362 | goto err_out; | 361 | goto err_out; |
@@ -366,7 +365,6 @@ static int __init us2e_freq_init(void) | |||
366 | driver->target = us2e_freq_target; | 365 | driver->target = us2e_freq_target; |
367 | driver->get = us2e_freq_get; | 366 | driver->get = us2e_freq_get; |
368 | driver->exit = us2e_freq_cpu_exit; | 367 | driver->exit = us2e_freq_cpu_exit; |
369 | driver->owner = THIS_MODULE, | ||
370 | strcpy(driver->name, "UltraSPARC-IIe"); | 368 | strcpy(driver->name, "UltraSPARC-IIe"); |
371 | 369 | ||
372 | cpufreq_us2e_driver = driver; | 370 | cpufreq_us2e_driver = driver; |
diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c index 880ee293d61e..ac76b489979d 100644 --- a/drivers/cpufreq/sparc-us3-cpufreq.c +++ b/drivers/cpufreq/sparc-us3-cpufreq.c | |||
@@ -212,12 +212,11 @@ static int __init us3_freq_init(void) | |||
212 | struct cpufreq_driver *driver; | 212 | struct cpufreq_driver *driver; |
213 | 213 | ||
214 | ret = -ENOMEM; | 214 | ret = -ENOMEM; |
215 | driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL); | 215 | driver = kzalloc(sizeof(*driver), GFP_KERNEL); |
216 | if (!driver) | 216 | if (!driver) |
217 | goto err_out; | 217 | goto err_out; |
218 | 218 | ||
219 | us3_freq_table = kzalloc( | 219 | us3_freq_table = kzalloc((NR_CPUS * sizeof(*us3_freq_table)), |
220 | (NR_CPUS * sizeof(struct us3_freq_percpu_info)), | ||
221 | GFP_KERNEL); | 220 | GFP_KERNEL); |
222 | if (!us3_freq_table) | 221 | if (!us3_freq_table) |
223 | goto err_out; | 222 | goto err_out; |
@@ -227,7 +226,6 @@ static int __init us3_freq_init(void) | |||
227 | driver->target = us3_freq_target; | 226 | driver->target = us3_freq_target; |
228 | driver->get = us3_freq_get; | 227 | driver->get = us3_freq_get; |
229 | driver->exit = us3_freq_cpu_exit; | 228 | driver->exit = us3_freq_cpu_exit; |
230 | driver->owner = THIS_MODULE, | ||
231 | strcpy(driver->name, "UltraSPARC-III"); | 229 | strcpy(driver->name, "UltraSPARC-III"); |
232 | 230 | ||
233 | cpufreq_us3_driver = driver; | 231 | cpufreq_us3_driver = driver; |
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index c3efa7f2a908..19e364fa5955 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/of.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | 24 | ||
@@ -223,7 +223,7 @@ static int spear_cpufreq_driver_init(void) | |||
223 | const __be32 *val; | 223 | const __be32 *val; |
224 | int cnt, i, ret; | 224 | int cnt, i, ret; |
225 | 225 | ||
226 | np = of_find_node_by_path("/cpus/cpu@0"); | 226 | np = of_cpu_device_node_get(0); |
227 | if (!np) { | 227 | if (!np) { |
228 | pr_err("No cpu node found"); | 228 | pr_err("No cpu node found"); |
229 | return -ENODEV; | 229 | return -ENODEV; |
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 0915e712fbdc..f897d5105842 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c | |||
@@ -575,7 +575,6 @@ static struct cpufreq_driver centrino_driver = { | |||
575 | .target = centrino_target, | 575 | .target = centrino_target, |
576 | .get = get_cur_freq, | 576 | .get = get_cur_freq, |
577 | .attr = centrino_attr, | 577 | .attr = centrino_attr, |
578 | .owner = THIS_MODULE, | ||
579 | }; | 578 | }; |
580 | 579 | ||
581 | /* | 580 | /* |
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index e2e5aa971452..5355abb69afc 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c | |||
@@ -378,7 +378,6 @@ static struct cpufreq_driver speedstep_driver = { | |||
378 | .init = speedstep_cpu_init, | 378 | .init = speedstep_cpu_init, |
379 | .exit = speedstep_cpu_exit, | 379 | .exit = speedstep_cpu_exit, |
380 | .get = speedstep_get, | 380 | .get = speedstep_get, |
381 | .owner = THIS_MODULE, | ||
382 | .attr = speedstep_attr, | 381 | .attr = speedstep_attr, |
383 | }; | 382 | }; |
384 | 383 | ||
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index f5a6b70ee6c0..abfba4f731eb 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c | |||
@@ -375,7 +375,6 @@ static struct cpufreq_driver speedstep_driver = { | |||
375 | .exit = speedstep_cpu_exit, | 375 | .exit = speedstep_cpu_exit, |
376 | .get = speedstep_get, | 376 | .get = speedstep_get, |
377 | .resume = speedstep_resume, | 377 | .resume = speedstep_resume, |
378 | .owner = THIS_MODULE, | ||
379 | .attr = speedstep_attr, | 378 | .attr = speedstep_attr, |
380 | }; | 379 | }; |
381 | 380 | ||
diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index cd66b85d927c..a7b876fdc1d8 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c | |||
@@ -255,7 +255,7 @@ static struct cpufreq_driver tegra_cpufreq_driver = { | |||
255 | 255 | ||
256 | static int __init tegra_cpufreq_init(void) | 256 | static int __init tegra_cpufreq_init(void) |
257 | { | 257 | { |
258 | cpu_clk = clk_get_sys(NULL, "cpu"); | 258 | cpu_clk = clk_get_sys(NULL, "cclk"); |
259 | if (IS_ERR(cpu_clk)) | 259 | if (IS_ERR(cpu_clk)) |
260 | return PTR_ERR(cpu_clk); | 260 | return PTR_ERR(cpu_clk); |
261 | 261 | ||
@@ -263,7 +263,7 @@ static int __init tegra_cpufreq_init(void) | |||
263 | if (IS_ERR(pll_x_clk)) | 263 | if (IS_ERR(pll_x_clk)) |
264 | return PTR_ERR(pll_x_clk); | 264 | return PTR_ERR(pll_x_clk); |
265 | 265 | ||
266 | pll_p_clk = clk_get_sys(NULL, "pll_p_cclk"); | 266 | pll_p_clk = clk_get_sys(NULL, "pll_p"); |
267 | if (IS_ERR(pll_p_clk)) | 267 | if (IS_ERR(pll_p_clk)) |
268 | return PTR_ERR(pll_p_clk); | 268 | return PTR_ERR(pll_p_clk); |
269 | 269 | ||
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index 12fc904d7dab..b225f04d8ae5 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c | |||
@@ -24,7 +24,7 @@ static struct cpufreq_driver ucv2_driver; | |||
24 | /* make sure that only the "userspace" governor is run | 24 | /* make sure that only the "userspace" governor is run |
25 | * -- anything else wouldn't make sense on this platform, anyway. | 25 | * -- anything else wouldn't make sense on this platform, anyway. |
26 | */ | 26 | */ |
27 | int ucv2_verify_speed(struct cpufreq_policy *policy) | 27 | static int ucv2_verify_speed(struct cpufreq_policy *policy) |
28 | { | 28 | { |
29 | if (policy->cpu) | 29 | if (policy->cpu) |
30 | return -EINVAL; | 30 | return -EINVAL; |
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index 0e2cd5cab4d0..b3fb81d7cf04 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | menu "CPU Idle" | ||
1 | 2 | ||
2 | menuconfig CPU_IDLE | 3 | config CPU_IDLE |
3 | bool "CPU idle PM support" | 4 | bool "CPU idle PM support" |
4 | default y if ACPI || PPC_PSERIES | 5 | default y if ACPI || PPC_PSERIES |
5 | select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE) | 6 | select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE) |
@@ -29,20 +30,13 @@ config CPU_IDLE_GOV_MENU | |||
29 | bool "Menu governor (for tickless system)" | 30 | bool "Menu governor (for tickless system)" |
30 | default y | 31 | default y |
31 | 32 | ||
32 | config CPU_IDLE_CALXEDA | 33 | menu "ARM CPU Idle Drivers" |
33 | bool "CPU Idle Driver for Calxeda processors" | 34 | depends on ARM |
34 | depends on ARCH_HIGHBANK | 35 | source "drivers/cpuidle/Kconfig.arm" |
35 | select ARM_CPU_SUSPEND | 36 | endmenu |
36 | help | ||
37 | Select this to enable cpuidle on Calxeda processors. | ||
38 | |||
39 | config CPU_IDLE_ZYNQ | ||
40 | bool "CPU Idle Driver for Xilinx Zynq processors" | ||
41 | depends on ARCH_ZYNQ | ||
42 | help | ||
43 | Select this to enable cpuidle on Xilinx Zynq processors. | ||
44 | 37 | ||
45 | endif | 38 | endif |
46 | 39 | ||
47 | config ARCH_NEEDS_CPU_IDLE_COUPLED | 40 | config ARCH_NEEDS_CPU_IDLE_COUPLED |
48 | def_bool n | 41 | def_bool n |
42 | endmenu | ||
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm new file mode 100644 index 000000000000..b3302193c15a --- /dev/null +++ b/drivers/cpuidle/Kconfig.arm | |||
@@ -0,0 +1,29 @@ | |||
1 | # | ||
2 | # ARM CPU Idle drivers | ||
3 | # | ||
4 | |||
5 | config ARM_HIGHBANK_CPUIDLE | ||
6 | bool "CPU Idle Driver for Calxeda processors" | ||
7 | depends on ARCH_HIGHBANK | ||
8 | select ARM_CPU_SUSPEND | ||
9 | help | ||
10 | Select this to enable cpuidle on Calxeda processors. | ||
11 | |||
12 | config ARM_KIRKWOOD_CPUIDLE | ||
13 | bool "CPU Idle Driver for Marvell Kirkwood SoCs" | ||
14 | depends on ARCH_KIRKWOOD | ||
15 | help | ||
16 | This adds the CPU Idle driver for Marvell Kirkwood SoCs. | ||
17 | |||
18 | config ARM_ZYNQ_CPUIDLE | ||
19 | bool "CPU Idle Driver for Xilinx Zynq processors" | ||
20 | depends on ARCH_ZYNQ | ||
21 | help | ||
22 | Select this to enable cpuidle on Xilinx Zynq processors. | ||
23 | |||
24 | config ARM_U8500_CPUIDLE | ||
25 | bool "Cpu Idle Driver for the ST-E u8500 processors" | ||
26 | depends on ARCH_U8500 | ||
27 | help | ||
28 | Select this to enable cpuidle for ST-E u8500 processors | ||
29 | |||
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index 8767a7b3eb91..0b9d200c7e45 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile | |||
@@ -5,6 +5,9 @@ | |||
5 | obj-y += cpuidle.o driver.o governor.o sysfs.o governors/ | 5 | obj-y += cpuidle.o driver.o governor.o sysfs.o governors/ |
6 | obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o | 6 | obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o |
7 | 7 | ||
8 | obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o | 8 | ################################################################################## |
9 | obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o | 9 | # ARM SoC drivers |
10 | obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o | 10 | obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o |
11 | obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o | ||
12 | obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o | ||
13 | obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o | ||
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index 2a297f86dbad..f8a86364c6b6 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c | |||
@@ -106,6 +106,7 @@ struct cpuidle_coupled { | |||
106 | cpumask_t coupled_cpus; | 106 | cpumask_t coupled_cpus; |
107 | int requested_state[NR_CPUS]; | 107 | int requested_state[NR_CPUS]; |
108 | atomic_t ready_waiting_counts; | 108 | atomic_t ready_waiting_counts; |
109 | atomic_t abort_barrier; | ||
109 | int online_count; | 110 | int online_count; |
110 | int refcnt; | 111 | int refcnt; |
111 | int prevent; | 112 | int prevent; |
@@ -122,12 +123,19 @@ static DEFINE_MUTEX(cpuidle_coupled_lock); | |||
122 | static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb); | 123 | static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb); |
123 | 124 | ||
124 | /* | 125 | /* |
125 | * The cpuidle_coupled_poked_mask mask is used to avoid calling | 126 | * The cpuidle_coupled_poke_pending mask is used to avoid calling |
126 | * __smp_call_function_single with the per cpu call_single_data struct already | 127 | * __smp_call_function_single with the per cpu call_single_data struct already |
127 | * in use. This prevents a deadlock where two cpus are waiting for each others | 128 | * in use. This prevents a deadlock where two cpus are waiting for each others |
128 | * call_single_data struct to be available | 129 | * call_single_data struct to be available |
129 | */ | 130 | */ |
130 | static cpumask_t cpuidle_coupled_poked_mask; | 131 | static cpumask_t cpuidle_coupled_poke_pending; |
132 | |||
133 | /* | ||
134 | * The cpuidle_coupled_poked mask is used to ensure that each cpu has been poked | ||
135 | * once to minimize entering the ready loop with a poke pending, which would | ||
136 | * require aborting and retrying. | ||
137 | */ | ||
138 | static cpumask_t cpuidle_coupled_poked; | ||
131 | 139 | ||
132 | /** | 140 | /** |
133 | * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus | 141 | * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus |
@@ -291,10 +299,11 @@ static inline int cpuidle_coupled_get_state(struct cpuidle_device *dev, | |||
291 | return state; | 299 | return state; |
292 | } | 300 | } |
293 | 301 | ||
294 | static void cpuidle_coupled_poked(void *info) | 302 | static void cpuidle_coupled_handle_poke(void *info) |
295 | { | 303 | { |
296 | int cpu = (unsigned long)info; | 304 | int cpu = (unsigned long)info; |
297 | cpumask_clear_cpu(cpu, &cpuidle_coupled_poked_mask); | 305 | cpumask_set_cpu(cpu, &cpuidle_coupled_poked); |
306 | cpumask_clear_cpu(cpu, &cpuidle_coupled_poke_pending); | ||
298 | } | 307 | } |
299 | 308 | ||
300 | /** | 309 | /** |
@@ -313,7 +322,7 @@ static void cpuidle_coupled_poke(int cpu) | |||
313 | { | 322 | { |
314 | struct call_single_data *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu); | 323 | struct call_single_data *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu); |
315 | 324 | ||
316 | if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poked_mask)) | 325 | if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poke_pending)) |
317 | __smp_call_function_single(cpu, csd, 0); | 326 | __smp_call_function_single(cpu, csd, 0); |
318 | } | 327 | } |
319 | 328 | ||
@@ -340,30 +349,19 @@ static void cpuidle_coupled_poke_others(int this_cpu, | |||
340 | * @coupled: the struct coupled that contains the current cpu | 349 | * @coupled: the struct coupled that contains the current cpu |
341 | * @next_state: the index in drv->states of the requested state for this cpu | 350 | * @next_state: the index in drv->states of the requested state for this cpu |
342 | * | 351 | * |
343 | * Updates the requested idle state for the specified cpuidle device, | 352 | * Updates the requested idle state for the specified cpuidle device. |
344 | * poking all coupled cpus out of idle if necessary to let them see the new | 353 | * Returns the number of waiting cpus. |
345 | * state. | ||
346 | */ | 354 | */ |
347 | static void cpuidle_coupled_set_waiting(int cpu, | 355 | static int cpuidle_coupled_set_waiting(int cpu, |
348 | struct cpuidle_coupled *coupled, int next_state) | 356 | struct cpuidle_coupled *coupled, int next_state) |
349 | { | 357 | { |
350 | int w; | ||
351 | |||
352 | coupled->requested_state[cpu] = next_state; | 358 | coupled->requested_state[cpu] = next_state; |
353 | 359 | ||
354 | /* | 360 | /* |
355 | * If this is the last cpu to enter the waiting state, poke | ||
356 | * all the other cpus out of their waiting state so they can | ||
357 | * enter a deeper state. This can race with one of the cpus | ||
358 | * exiting the waiting state due to an interrupt and | ||
359 | * decrementing waiting_count, see comment below. | ||
360 | * | ||
361 | * The atomic_inc_return provides a write barrier to order the write | 361 | * The atomic_inc_return provides a write barrier to order the write |
362 | * to requested_state with the later write that increments ready_count. | 362 | * to requested_state with the later write that increments ready_count. |
363 | */ | 363 | */ |
364 | w = atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK; | 364 | return atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK; |
365 | if (w == coupled->online_count) | ||
366 | cpuidle_coupled_poke_others(cpu, coupled); | ||
367 | } | 365 | } |
368 | 366 | ||
369 | /** | 367 | /** |
@@ -410,19 +408,33 @@ static void cpuidle_coupled_set_done(int cpu, struct cpuidle_coupled *coupled) | |||
410 | * been processed and the poke bit has been cleared. | 408 | * been processed and the poke bit has been cleared. |
411 | * | 409 | * |
412 | * Other interrupts may also be processed while interrupts are enabled, so | 410 | * Other interrupts may also be processed while interrupts are enabled, so |
413 | * need_resched() must be tested after turning interrupts off again to make sure | 411 | * need_resched() must be tested after this function returns to make sure |
414 | * the interrupt didn't schedule work that should take the cpu out of idle. | 412 | * the interrupt didn't schedule work that should take the cpu out of idle. |
415 | * | 413 | * |
416 | * Returns 0 if need_resched was false, -EINTR if need_resched was true. | 414 | * Returns 0 if no poke was pending, 1 if a poke was cleared. |
417 | */ | 415 | */ |
418 | static int cpuidle_coupled_clear_pokes(int cpu) | 416 | static int cpuidle_coupled_clear_pokes(int cpu) |
419 | { | 417 | { |
418 | if (!cpumask_test_cpu(cpu, &cpuidle_coupled_poke_pending)) | ||
419 | return 0; | ||
420 | |||
420 | local_irq_enable(); | 421 | local_irq_enable(); |
421 | while (cpumask_test_cpu(cpu, &cpuidle_coupled_poked_mask)) | 422 | while (cpumask_test_cpu(cpu, &cpuidle_coupled_poke_pending)) |
422 | cpu_relax(); | 423 | cpu_relax(); |
423 | local_irq_disable(); | 424 | local_irq_disable(); |
424 | 425 | ||
425 | return need_resched() ? -EINTR : 0; | 426 | return 1; |
427 | } | ||
428 | |||
429 | static bool cpuidle_coupled_any_pokes_pending(struct cpuidle_coupled *coupled) | ||
430 | { | ||
431 | cpumask_t cpus; | ||
432 | int ret; | ||
433 | |||
434 | cpumask_and(&cpus, cpu_online_mask, &coupled->coupled_cpus); | ||
435 | ret = cpumask_and(&cpus, &cpuidle_coupled_poke_pending, &cpus); | ||
436 | |||
437 | return ret; | ||
426 | } | 438 | } |
427 | 439 | ||
428 | /** | 440 | /** |
@@ -449,31 +461,56 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev, | |||
449 | { | 461 | { |
450 | int entered_state = -1; | 462 | int entered_state = -1; |
451 | struct cpuidle_coupled *coupled = dev->coupled; | 463 | struct cpuidle_coupled *coupled = dev->coupled; |
464 | int w; | ||
452 | 465 | ||
453 | if (!coupled) | 466 | if (!coupled) |
454 | return -EINVAL; | 467 | return -EINVAL; |
455 | 468 | ||
456 | while (coupled->prevent) { | 469 | while (coupled->prevent) { |
457 | if (cpuidle_coupled_clear_pokes(dev->cpu)) { | 470 | cpuidle_coupled_clear_pokes(dev->cpu); |
471 | if (need_resched()) { | ||
458 | local_irq_enable(); | 472 | local_irq_enable(); |
459 | return entered_state; | 473 | return entered_state; |
460 | } | 474 | } |
461 | entered_state = cpuidle_enter_state(dev, drv, | 475 | entered_state = cpuidle_enter_state(dev, drv, |
462 | dev->safe_state_index); | 476 | dev->safe_state_index); |
477 | local_irq_disable(); | ||
463 | } | 478 | } |
464 | 479 | ||
465 | /* Read barrier ensures online_count is read after prevent is cleared */ | 480 | /* Read barrier ensures online_count is read after prevent is cleared */ |
466 | smp_rmb(); | 481 | smp_rmb(); |
467 | 482 | ||
468 | cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state); | 483 | reset: |
484 | cpumask_clear_cpu(dev->cpu, &cpuidle_coupled_poked); | ||
485 | |||
486 | w = cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state); | ||
487 | /* | ||
488 | * If this is the last cpu to enter the waiting state, poke | ||
489 | * all the other cpus out of their waiting state so they can | ||
490 | * enter a deeper state. This can race with one of the cpus | ||
491 | * exiting the waiting state due to an interrupt and | ||
492 | * decrementing waiting_count, see comment below. | ||
493 | */ | ||
494 | if (w == coupled->online_count) { | ||
495 | cpumask_set_cpu(dev->cpu, &cpuidle_coupled_poked); | ||
496 | cpuidle_coupled_poke_others(dev->cpu, coupled); | ||
497 | } | ||
469 | 498 | ||
470 | retry: | 499 | retry: |
471 | /* | 500 | /* |
472 | * Wait for all coupled cpus to be idle, using the deepest state | 501 | * Wait for all coupled cpus to be idle, using the deepest state |
473 | * allowed for a single cpu. | 502 | * allowed for a single cpu. If this was not the poking cpu, wait |
503 | * for at least one poke before leaving to avoid a race where | ||
504 | * two cpus could arrive at the waiting loop at the same time, | ||
505 | * but the first of the two to arrive could skip the loop without | ||
506 | * processing the pokes from the last to arrive. | ||
474 | */ | 507 | */ |
475 | while (!cpuidle_coupled_cpus_waiting(coupled)) { | 508 | while (!cpuidle_coupled_cpus_waiting(coupled) || |
476 | if (cpuidle_coupled_clear_pokes(dev->cpu)) { | 509 | !cpumask_test_cpu(dev->cpu, &cpuidle_coupled_poked)) { |
510 | if (cpuidle_coupled_clear_pokes(dev->cpu)) | ||
511 | continue; | ||
512 | |||
513 | if (need_resched()) { | ||
477 | cpuidle_coupled_set_not_waiting(dev->cpu, coupled); | 514 | cpuidle_coupled_set_not_waiting(dev->cpu, coupled); |
478 | goto out; | 515 | goto out; |
479 | } | 516 | } |
@@ -485,14 +522,22 @@ retry: | |||
485 | 522 | ||
486 | entered_state = cpuidle_enter_state(dev, drv, | 523 | entered_state = cpuidle_enter_state(dev, drv, |
487 | dev->safe_state_index); | 524 | dev->safe_state_index); |
525 | local_irq_disable(); | ||
488 | } | 526 | } |
489 | 527 | ||
490 | if (cpuidle_coupled_clear_pokes(dev->cpu)) { | 528 | cpuidle_coupled_clear_pokes(dev->cpu); |
529 | if (need_resched()) { | ||
491 | cpuidle_coupled_set_not_waiting(dev->cpu, coupled); | 530 | cpuidle_coupled_set_not_waiting(dev->cpu, coupled); |
492 | goto out; | 531 | goto out; |
493 | } | 532 | } |
494 | 533 | ||
495 | /* | 534 | /* |
535 | * Make sure final poke status for this cpu is visible before setting | ||
536 | * cpu as ready. | ||
537 | */ | ||
538 | smp_wmb(); | ||
539 | |||
540 | /* | ||
496 | * All coupled cpus are probably idle. There is a small chance that | 541 | * All coupled cpus are probably idle. There is a small chance that |
497 | * one of the other cpus just became active. Increment the ready count, | 542 | * one of the other cpus just became active. Increment the ready count, |
498 | * and spin until all coupled cpus have incremented the counter. Once a | 543 | * and spin until all coupled cpus have incremented the counter. Once a |
@@ -511,6 +556,28 @@ retry: | |||
511 | cpu_relax(); | 556 | cpu_relax(); |
512 | } | 557 | } |
513 | 558 | ||
559 | /* | ||
560 | * Make sure read of all cpus ready is done before reading pending pokes | ||
561 | */ | ||
562 | smp_rmb(); | ||
563 | |||
564 | /* | ||
565 | * There is a small chance that a cpu left and reentered idle after this | ||
566 | * cpu saw that all cpus were waiting. The cpu that reentered idle will | ||
567 | * have sent this cpu a poke, which will still be pending after the | ||
568 | * ready loop. The pending interrupt may be lost by the interrupt | ||
569 | * controller when entering the deep idle state. It's not possible to | ||
570 | * clear a pending interrupt without turning interrupts on and handling | ||
571 | * it, and it's too late to turn on interrupts here, so reset the | ||
572 | * coupled idle state of all cpus and retry. | ||
573 | */ | ||
574 | if (cpuidle_coupled_any_pokes_pending(coupled)) { | ||
575 | cpuidle_coupled_set_done(dev->cpu, coupled); | ||
576 | /* Wait for all cpus to see the pending pokes */ | ||
577 | cpuidle_coupled_parallel_barrier(dev, &coupled->abort_barrier); | ||
578 | goto reset; | ||
579 | } | ||
580 | |||
514 | /* all cpus have acked the coupled state */ | 581 | /* all cpus have acked the coupled state */ |
515 | next_state = cpuidle_coupled_get_state(dev, coupled); | 582 | next_state = cpuidle_coupled_get_state(dev, coupled); |
516 | 583 | ||
@@ -596,7 +663,7 @@ have_coupled: | |||
596 | coupled->refcnt++; | 663 | coupled->refcnt++; |
597 | 664 | ||
598 | csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu); | 665 | csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu); |
599 | csd->func = cpuidle_coupled_poked; | 666 | csd->func = cpuidle_coupled_handle_poke; |
600 | csd->info = (void *)(unsigned long)dev->cpu; | 667 | csd->info = (void *)(unsigned long)dev->cpu; |
601 | 668 | ||
602 | return 0; | 669 | return 0; |
diff --git a/drivers/cpuidle/cpuidle-calxeda.c b/drivers/cpuidle/cpuidle-calxeda.c index 0e6e408c0a63..346058479572 100644 --- a/drivers/cpuidle/cpuidle-calxeda.c +++ b/drivers/cpuidle/cpuidle-calxeda.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <asm/cp15.h> | 35 | #include <asm/cp15.h> |
36 | 36 | ||
37 | extern void highbank_set_cpu_jump(int cpu, void *jump_addr); | 37 | extern void highbank_set_cpu_jump(int cpu, void *jump_addr); |
38 | extern void *scu_base_addr; | 38 | extern void __iomem *scu_base_addr; |
39 | 39 | ||
40 | static noinline void calxeda_idle_restore(void) | 40 | static noinline void calxeda_idle_restore(void) |
41 | { | 41 | { |
diff --git a/drivers/cpuidle/cpuidle-kirkwood.c b/drivers/cpuidle/cpuidle-kirkwood.c index 521b0a7fdd89..41ba843251b8 100644 --- a/drivers/cpuidle/cpuidle-kirkwood.c +++ b/drivers/cpuidle/cpuidle-kirkwood.c | |||
@@ -60,9 +60,6 @@ static int kirkwood_cpuidle_probe(struct platform_device *pdev) | |||
60 | struct resource *res; | 60 | struct resource *res; |
61 | 61 | ||
62 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 62 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
63 | if (res == NULL) | ||
64 | return -EINVAL; | ||
65 | |||
66 | ddr_operation_base = devm_ioremap_resource(&pdev->dev, res); | 63 | ddr_operation_base = devm_ioremap_resource(&pdev->dev, res); |
67 | if (IS_ERR(ddr_operation_base)) | 64 | if (IS_ERR(ddr_operation_base)) |
68 | return PTR_ERR(ddr_operation_base); | 65 | return PTR_ERR(ddr_operation_base); |
@@ -70,7 +67,7 @@ static int kirkwood_cpuidle_probe(struct platform_device *pdev) | |||
70 | return cpuidle_register(&kirkwood_idle_driver, NULL); | 67 | return cpuidle_register(&kirkwood_idle_driver, NULL); |
71 | } | 68 | } |
72 | 69 | ||
73 | int kirkwood_cpuidle_remove(struct platform_device *pdev) | 70 | static int kirkwood_cpuidle_remove(struct platform_device *pdev) |
74 | { | 71 | { |
75 | cpuidle_unregister(&kirkwood_idle_driver); | 72 | cpuidle_unregister(&kirkwood_idle_driver); |
76 | return 0; | 73 | return 0; |
diff --git a/drivers/cpuidle/cpuidle-ux500.c b/drivers/cpuidle/cpuidle-ux500.c new file mode 100644 index 000000000000..e0564652af35 --- /dev/null +++ b/drivers/cpuidle/cpuidle-ux500.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Linaro : Daniel Lezcano <daniel.lezcano@linaro.org> (IBM) | ||
3 | * | ||
4 | * Based on the work of Rickard Andersson <rickard.andersson@stericsson.com> | ||
5 | * and Jonas Aaberg <jonas.aberg@stericsson.com>. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/cpuidle.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/atomic.h> | ||
16 | #include <linux/smp.h> | ||
17 | #include <linux/mfd/dbx500-prcmu.h> | ||
18 | #include <linux/platform_data/arm-ux500-pm.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
21 | #include <asm/cpuidle.h> | ||
22 | #include <asm/proc-fns.h> | ||
23 | |||
24 | static atomic_t master = ATOMIC_INIT(0); | ||
25 | static DEFINE_SPINLOCK(master_lock); | ||
26 | |||
27 | static inline int ux500_enter_idle(struct cpuidle_device *dev, | ||
28 | struct cpuidle_driver *drv, int index) | ||
29 | { | ||
30 | int this_cpu = smp_processor_id(); | ||
31 | bool recouple = false; | ||
32 | |||
33 | if (atomic_inc_return(&master) == num_online_cpus()) { | ||
34 | |||
35 | /* With this lock, we prevent the other cpu to exit and enter | ||
36 | * this function again and become the master */ | ||
37 | if (!spin_trylock(&master_lock)) | ||
38 | goto wfi; | ||
39 | |||
40 | /* decouple the gic from the A9 cores */ | ||
41 | if (prcmu_gic_decouple()) { | ||
42 | spin_unlock(&master_lock); | ||
43 | goto out; | ||
44 | } | ||
45 | |||
46 | /* If an error occur, we will have to recouple the gic | ||
47 | * manually */ | ||
48 | recouple = true; | ||
49 | |||
50 | /* At this state, as the gic is decoupled, if the other | ||
51 | * cpu is in WFI, we have the guarantee it won't be wake | ||
52 | * up, so we can safely go to retention */ | ||
53 | if (!prcmu_is_cpu_in_wfi(this_cpu ? 0 : 1)) | ||
54 | goto out; | ||
55 | |||
56 | /* The prcmu will be in charge of watching the interrupts | ||
57 | * and wake up the cpus */ | ||
58 | if (prcmu_copy_gic_settings()) | ||
59 | goto out; | ||
60 | |||
61 | /* Check in the meantime an interrupt did | ||
62 | * not occur on the gic ... */ | ||
63 | if (prcmu_gic_pending_irq()) | ||
64 | goto out; | ||
65 | |||
66 | /* ... and the prcmu */ | ||
67 | if (prcmu_pending_irq()) | ||
68 | goto out; | ||
69 | |||
70 | /* Go to the retention state, the prcmu will wait for the | ||
71 | * cpu to go WFI and this is what happens after exiting this | ||
72 | * 'master' critical section */ | ||
73 | if (prcmu_set_power_state(PRCMU_AP_IDLE, true, true)) | ||
74 | goto out; | ||
75 | |||
76 | /* When we switch to retention, the prcmu is in charge | ||
77 | * of recoupling the gic automatically */ | ||
78 | recouple = false; | ||
79 | |||
80 | spin_unlock(&master_lock); | ||
81 | } | ||
82 | wfi: | ||
83 | cpu_do_idle(); | ||
84 | out: | ||
85 | atomic_dec(&master); | ||
86 | |||
87 | if (recouple) { | ||
88 | prcmu_gic_recouple(); | ||
89 | spin_unlock(&master_lock); | ||
90 | } | ||
91 | |||
92 | return index; | ||
93 | } | ||
94 | |||
95 | static struct cpuidle_driver ux500_idle_driver = { | ||
96 | .name = "ux500_idle", | ||
97 | .owner = THIS_MODULE, | ||
98 | .states = { | ||
99 | ARM_CPUIDLE_WFI_STATE, | ||
100 | { | ||
101 | .enter = ux500_enter_idle, | ||
102 | .exit_latency = 70, | ||
103 | .target_residency = 260, | ||
104 | .flags = CPUIDLE_FLAG_TIME_VALID | | ||
105 | CPUIDLE_FLAG_TIMER_STOP, | ||
106 | .name = "ApIdle", | ||
107 | .desc = "ARM Retention", | ||
108 | }, | ||
109 | }, | ||
110 | .safe_state_index = 0, | ||
111 | .state_count = 2, | ||
112 | }; | ||
113 | |||
114 | static int __init dbx500_cpuidle_probe(struct platform_device *pdev) | ||
115 | { | ||
116 | /* Configure wake up reasons */ | ||
117 | prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | | ||
118 | PRCMU_WAKEUP(ABB)); | ||
119 | |||
120 | return cpuidle_register(&ux500_idle_driver, NULL); | ||
121 | } | ||
122 | |||
123 | static struct platform_driver dbx500_cpuidle_plat_driver = { | ||
124 | .driver = { | ||
125 | .name = "cpuidle-dbx500", | ||
126 | .owner = THIS_MODULE, | ||
127 | }, | ||
128 | .probe = dbx500_cpuidle_probe, | ||
129 | }; | ||
130 | |||
131 | module_platform_driver(dbx500_cpuidle_plat_driver); | ||
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index fdc432f18022..d75040ddd2b3 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -42,8 +42,6 @@ void disable_cpuidle(void) | |||
42 | off = 1; | 42 | off = 1; |
43 | } | 43 | } |
44 | 44 | ||
45 | static int __cpuidle_register_device(struct cpuidle_device *dev); | ||
46 | |||
47 | /** | 45 | /** |
48 | * cpuidle_play_dead - cpu off-lining | 46 | * cpuidle_play_dead - cpu off-lining |
49 | * | 47 | * |
@@ -278,7 +276,7 @@ static void poll_idle_init(struct cpuidle_driver *drv) {} | |||
278 | */ | 276 | */ |
279 | int cpuidle_enable_device(struct cpuidle_device *dev) | 277 | int cpuidle_enable_device(struct cpuidle_device *dev) |
280 | { | 278 | { |
281 | int ret, i; | 279 | int ret; |
282 | struct cpuidle_driver *drv; | 280 | struct cpuidle_driver *drv; |
283 | 281 | ||
284 | if (!dev) | 282 | if (!dev) |
@@ -292,15 +290,12 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
292 | if (!drv || !cpuidle_curr_governor) | 290 | if (!drv || !cpuidle_curr_governor) |
293 | return -EIO; | 291 | return -EIO; |
294 | 292 | ||
293 | if (!dev->registered) | ||
294 | return -EINVAL; | ||
295 | |||
295 | if (!dev->state_count) | 296 | if (!dev->state_count) |
296 | dev->state_count = drv->state_count; | 297 | dev->state_count = drv->state_count; |
297 | 298 | ||
298 | if (dev->registered == 0) { | ||
299 | ret = __cpuidle_register_device(dev); | ||
300 | if (ret) | ||
301 | return ret; | ||
302 | } | ||
303 | |||
304 | poll_idle_init(drv); | 299 | poll_idle_init(drv); |
305 | 300 | ||
306 | ret = cpuidle_add_device_sysfs(dev); | 301 | ret = cpuidle_add_device_sysfs(dev); |
@@ -311,12 +306,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
311 | (ret = cpuidle_curr_governor->enable(drv, dev))) | 306 | (ret = cpuidle_curr_governor->enable(drv, dev))) |
312 | goto fail_sysfs; | 307 | goto fail_sysfs; |
313 | 308 | ||
314 | for (i = 0; i < dev->state_count; i++) { | ||
315 | dev->states_usage[i].usage = 0; | ||
316 | dev->states_usage[i].time = 0; | ||
317 | } | ||
318 | dev->last_residency = 0; | ||
319 | |||
320 | smp_wmb(); | 309 | smp_wmb(); |
321 | 310 | ||
322 | dev->enabled = 1; | 311 | dev->enabled = 1; |
@@ -360,6 +349,23 @@ void cpuidle_disable_device(struct cpuidle_device *dev) | |||
360 | 349 | ||
361 | EXPORT_SYMBOL_GPL(cpuidle_disable_device); | 350 | EXPORT_SYMBOL_GPL(cpuidle_disable_device); |
362 | 351 | ||
352 | static void __cpuidle_unregister_device(struct cpuidle_device *dev) | ||
353 | { | ||
354 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); | ||
355 | |||
356 | list_del(&dev->device_list); | ||
357 | per_cpu(cpuidle_devices, dev->cpu) = NULL; | ||
358 | module_put(drv->owner); | ||
359 | } | ||
360 | |||
361 | static int __cpuidle_device_init(struct cpuidle_device *dev) | ||
362 | { | ||
363 | memset(dev->states_usage, 0, sizeof(dev->states_usage)); | ||
364 | dev->last_residency = 0; | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
363 | /** | 369 | /** |
364 | * __cpuidle_register_device - internal register function called before register | 370 | * __cpuidle_register_device - internal register function called before register |
365 | * and enable routines | 371 | * and enable routines |
@@ -377,24 +383,15 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) | |||
377 | 383 | ||
378 | per_cpu(cpuidle_devices, dev->cpu) = dev; | 384 | per_cpu(cpuidle_devices, dev->cpu) = dev; |
379 | list_add(&dev->device_list, &cpuidle_detected_devices); | 385 | list_add(&dev->device_list, &cpuidle_detected_devices); |
380 | ret = cpuidle_add_sysfs(dev); | ||
381 | if (ret) | ||
382 | goto err_sysfs; | ||
383 | 386 | ||
384 | ret = cpuidle_coupled_register_device(dev); | 387 | ret = cpuidle_coupled_register_device(dev); |
385 | if (ret) | 388 | if (ret) { |
386 | goto err_coupled; | 389 | __cpuidle_unregister_device(dev); |
390 | return ret; | ||
391 | } | ||
387 | 392 | ||
388 | dev->registered = 1; | 393 | dev->registered = 1; |
389 | return 0; | 394 | return 0; |
390 | |||
391 | err_coupled: | ||
392 | cpuidle_remove_sysfs(dev); | ||
393 | err_sysfs: | ||
394 | list_del(&dev->device_list); | ||
395 | per_cpu(cpuidle_devices, dev->cpu) = NULL; | ||
396 | module_put(drv->owner); | ||
397 | return ret; | ||
398 | } | 395 | } |
399 | 396 | ||
400 | /** | 397 | /** |
@@ -403,25 +400,44 @@ err_sysfs: | |||
403 | */ | 400 | */ |
404 | int cpuidle_register_device(struct cpuidle_device *dev) | 401 | int cpuidle_register_device(struct cpuidle_device *dev) |
405 | { | 402 | { |
406 | int ret; | 403 | int ret = -EBUSY; |
407 | 404 | ||
408 | if (!dev) | 405 | if (!dev) |
409 | return -EINVAL; | 406 | return -EINVAL; |
410 | 407 | ||
411 | mutex_lock(&cpuidle_lock); | 408 | mutex_lock(&cpuidle_lock); |
412 | 409 | ||
413 | if ((ret = __cpuidle_register_device(dev))) { | 410 | if (dev->registered) |
414 | mutex_unlock(&cpuidle_lock); | 411 | goto out_unlock; |
415 | return ret; | 412 | |
416 | } | 413 | ret = __cpuidle_device_init(dev); |
414 | if (ret) | ||
415 | goto out_unlock; | ||
416 | |||
417 | ret = __cpuidle_register_device(dev); | ||
418 | if (ret) | ||
419 | goto out_unlock; | ||
420 | |||
421 | ret = cpuidle_add_sysfs(dev); | ||
422 | if (ret) | ||
423 | goto out_unregister; | ||
424 | |||
425 | ret = cpuidle_enable_device(dev); | ||
426 | if (ret) | ||
427 | goto out_sysfs; | ||
417 | 428 | ||
418 | cpuidle_enable_device(dev); | ||
419 | cpuidle_install_idle_handler(); | 429 | cpuidle_install_idle_handler(); |
420 | 430 | ||
431 | out_unlock: | ||
421 | mutex_unlock(&cpuidle_lock); | 432 | mutex_unlock(&cpuidle_lock); |
422 | 433 | ||
423 | return 0; | 434 | return ret; |
424 | 435 | ||
436 | out_sysfs: | ||
437 | cpuidle_remove_sysfs(dev); | ||
438 | out_unregister: | ||
439 | __cpuidle_unregister_device(dev); | ||
440 | goto out_unlock; | ||
425 | } | 441 | } |
426 | 442 | ||
427 | EXPORT_SYMBOL_GPL(cpuidle_register_device); | 443 | EXPORT_SYMBOL_GPL(cpuidle_register_device); |
@@ -432,8 +448,6 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); | |||
432 | */ | 448 | */ |
433 | void cpuidle_unregister_device(struct cpuidle_device *dev) | 449 | void cpuidle_unregister_device(struct cpuidle_device *dev) |
434 | { | 450 | { |
435 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); | ||
436 | |||
437 | if (dev->registered == 0) | 451 | if (dev->registered == 0) |
438 | return; | 452 | return; |
439 | 453 | ||
@@ -442,14 +456,12 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) | |||
442 | cpuidle_disable_device(dev); | 456 | cpuidle_disable_device(dev); |
443 | 457 | ||
444 | cpuidle_remove_sysfs(dev); | 458 | cpuidle_remove_sysfs(dev); |
445 | list_del(&dev->device_list); | 459 | |
446 | per_cpu(cpuidle_devices, dev->cpu) = NULL; | 460 | __cpuidle_unregister_device(dev); |
447 | 461 | ||
448 | cpuidle_coupled_unregister_device(dev); | 462 | cpuidle_coupled_unregister_device(dev); |
449 | 463 | ||
450 | cpuidle_resume_and_unlock(); | 464 | cpuidle_resume_and_unlock(); |
451 | |||
452 | module_put(drv->owner); | ||
453 | } | 465 | } |
454 | 466 | ||
455 | EXPORT_SYMBOL_GPL(cpuidle_unregister_device); | 467 | EXPORT_SYMBOL_GPL(cpuidle_unregister_device); |
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 9b784051ec12..9f08e8cce1af 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c | |||
@@ -192,14 +192,4 @@ static int __init init_ladder(void) | |||
192 | return cpuidle_register_governor(&ladder_governor); | 192 | return cpuidle_register_governor(&ladder_governor); |
193 | } | 193 | } |
194 | 194 | ||
195 | /** | 195 | postcore_initcall(init_ladder); |
196 | * exit_ladder - exits the governor | ||
197 | */ | ||
198 | static void __exit exit_ladder(void) | ||
199 | { | ||
200 | cpuidle_unregister_governor(&ladder_governor); | ||
201 | } | ||
202 | |||
203 | MODULE_LICENSE("GPL"); | ||
204 | module_init(init_ladder); | ||
205 | module_exit(exit_ladder); | ||
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index bc580b67a652..cf7f2f0e4ef5 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -21,6 +21,15 @@ | |||
21 | #include <linux/math64.h> | 21 | #include <linux/math64.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
24 | /* | ||
25 | * Please note when changing the tuning values: | ||
26 | * If (MAX_INTERESTING-1) * RESOLUTION > UINT_MAX, the result of | ||
27 | * a scaling operation multiplication may overflow on 32 bit platforms. | ||
28 | * In that case, #define RESOLUTION as ULL to get 64 bit result: | ||
29 | * #define RESOLUTION 1024ULL | ||
30 | * | ||
31 | * The default values do not overflow. | ||
32 | */ | ||
24 | #define BUCKETS 12 | 33 | #define BUCKETS 12 |
25 | #define INTERVALS 8 | 34 | #define INTERVALS 8 |
26 | #define RESOLUTION 1024 | 35 | #define RESOLUTION 1024 |
@@ -114,11 +123,11 @@ struct menu_device { | |||
114 | int needs_update; | 123 | int needs_update; |
115 | 124 | ||
116 | unsigned int expected_us; | 125 | unsigned int expected_us; |
117 | u64 predicted_us; | 126 | unsigned int predicted_us; |
118 | unsigned int exit_us; | 127 | unsigned int exit_us; |
119 | unsigned int bucket; | 128 | unsigned int bucket; |
120 | u64 correction_factor[BUCKETS]; | 129 | unsigned int correction_factor[BUCKETS]; |
121 | u32 intervals[INTERVALS]; | 130 | unsigned int intervals[INTERVALS]; |
122 | int interval_ptr; | 131 | int interval_ptr; |
123 | }; | 132 | }; |
124 | 133 | ||
@@ -199,16 +208,20 @@ static u64 div_round64(u64 dividend, u32 divisor) | |||
199 | */ | 208 | */ |
200 | static void get_typical_interval(struct menu_device *data) | 209 | static void get_typical_interval(struct menu_device *data) |
201 | { | 210 | { |
202 | int i = 0, divisor = 0; | 211 | int i, divisor; |
203 | uint64_t max = 0, avg = 0, stddev = 0; | 212 | unsigned int max, thresh; |
204 | int64_t thresh = LLONG_MAX; /* Discard outliers above this value. */ | 213 | uint64_t avg, stddev; |
214 | |||
215 | thresh = UINT_MAX; /* Discard outliers above this value */ | ||
205 | 216 | ||
206 | again: | 217 | again: |
207 | 218 | ||
208 | /* first calculate average and standard deviation of the past */ | 219 | /* First calculate the average of past intervals */ |
209 | max = avg = divisor = stddev = 0; | 220 | max = 0; |
221 | avg = 0; | ||
222 | divisor = 0; | ||
210 | for (i = 0; i < INTERVALS; i++) { | 223 | for (i = 0; i < INTERVALS; i++) { |
211 | int64_t value = data->intervals[i]; | 224 | unsigned int value = data->intervals[i]; |
212 | if (value <= thresh) { | 225 | if (value <= thresh) { |
213 | avg += value; | 226 | avg += value; |
214 | divisor++; | 227 | divisor++; |
@@ -218,15 +231,38 @@ again: | |||
218 | } | 231 | } |
219 | do_div(avg, divisor); | 232 | do_div(avg, divisor); |
220 | 233 | ||
234 | /* Then try to determine standard deviation */ | ||
235 | stddev = 0; | ||
221 | for (i = 0; i < INTERVALS; i++) { | 236 | for (i = 0; i < INTERVALS; i++) { |
222 | int64_t value = data->intervals[i]; | 237 | unsigned int value = data->intervals[i]; |
223 | if (value <= thresh) { | 238 | if (value <= thresh) { |
224 | int64_t diff = value - avg; | 239 | int64_t diff = value - avg; |
225 | stddev += diff * diff; | 240 | stddev += diff * diff; |
226 | } | 241 | } |
227 | } | 242 | } |
228 | do_div(stddev, divisor); | 243 | do_div(stddev, divisor); |
229 | stddev = int_sqrt(stddev); | 244 | /* |
245 | * The typical interval is obtained when standard deviation is small | ||
246 | * or standard deviation is small compared to the average interval. | ||
247 | * | ||
248 | * int_sqrt() formal parameter type is unsigned long. When the | ||
249 | * greatest difference to an outlier exceeds ~65 ms * sqrt(divisor) | ||
250 | * the resulting squared standard deviation exceeds the input domain | ||
251 | * of int_sqrt on platforms where unsigned long is 32 bits in size. | ||
252 | * In such case reject the candidate average. | ||
253 | * | ||
254 | * Use this result only if there is no timer to wake us up sooner. | ||
255 | */ | ||
256 | if (likely(stddev <= ULONG_MAX)) { | ||
257 | stddev = int_sqrt(stddev); | ||
258 | if (((avg > stddev * 6) && (divisor * 4 >= INTERVALS * 3)) | ||
259 | || stddev <= 20) { | ||
260 | if (data->expected_us > avg) | ||
261 | data->predicted_us = avg; | ||
262 | return; | ||
263 | } | ||
264 | } | ||
265 | |||
230 | /* | 266 | /* |
231 | * If we have outliers to the upside in our distribution, discard | 267 | * If we have outliers to the upside in our distribution, discard |
232 | * those by setting the threshold to exclude these outliers, then | 268 | * those by setting the threshold to exclude these outliers, then |
@@ -235,20 +271,12 @@ again: | |||
235 | * | 271 | * |
236 | * This can deal with workloads that have long pauses interspersed | 272 | * This can deal with workloads that have long pauses interspersed |
237 | * with sporadic activity with a bunch of short pauses. | 273 | * with sporadic activity with a bunch of short pauses. |
238 | * | ||
239 | * The typical interval is obtained when standard deviation is small | ||
240 | * or standard deviation is small compared to the average interval. | ||
241 | */ | 274 | */ |
242 | if (((avg > stddev * 6) && (divisor * 4 >= INTERVALS * 3)) | 275 | if ((divisor * 4) <= INTERVALS * 3) |
243 | || stddev <= 20) { | ||
244 | data->predicted_us = avg; | ||
245 | return; | 276 | return; |
246 | 277 | ||
247 | } else if ((divisor * 4) > INTERVALS * 3) { | 278 | thresh = max - 1; |
248 | /* Exclude the max interval */ | 279 | goto again; |
249 | thresh = max - 1; | ||
250 | goto again; | ||
251 | } | ||
252 | } | 280 | } |
253 | 281 | ||
254 | /** | 282 | /** |
@@ -293,8 +321,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
293 | if (data->correction_factor[data->bucket] == 0) | 321 | if (data->correction_factor[data->bucket] == 0) |
294 | data->correction_factor[data->bucket] = RESOLUTION * DECAY; | 322 | data->correction_factor[data->bucket] = RESOLUTION * DECAY; |
295 | 323 | ||
296 | /* Make sure to round up for half microseconds */ | 324 | /* |
297 | data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket], | 325 | * Force the result of multiplication to be 64 bits even if both |
326 | * operands are 32 bits. | ||
327 | * Make sure to round up for half microseconds. | ||
328 | */ | ||
329 | data->predicted_us = div_round64((uint64_t)data->expected_us * | ||
330 | data->correction_factor[data->bucket], | ||
298 | RESOLUTION * DECAY); | 331 | RESOLUTION * DECAY); |
299 | 332 | ||
300 | get_typical_interval(data); | 333 | get_typical_interval(data); |
@@ -360,7 +393,7 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
360 | unsigned int last_idle_us = cpuidle_get_last_residency(dev); | 393 | unsigned int last_idle_us = cpuidle_get_last_residency(dev); |
361 | struct cpuidle_state *target = &drv->states[last_idx]; | 394 | struct cpuidle_state *target = &drv->states[last_idx]; |
362 | unsigned int measured_us; | 395 | unsigned int measured_us; |
363 | u64 new_factor; | 396 | unsigned int new_factor; |
364 | 397 | ||
365 | /* | 398 | /* |
366 | * Ugh, this idle state doesn't support residency measurements, so we | 399 | * Ugh, this idle state doesn't support residency measurements, so we |
@@ -381,10 +414,9 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
381 | measured_us -= data->exit_us; | 414 | measured_us -= data->exit_us; |
382 | 415 | ||
383 | 416 | ||
384 | /* update our correction ratio */ | 417 | /* Update our correction ratio */ |
385 | 418 | new_factor = data->correction_factor[data->bucket]; | |
386 | new_factor = data->correction_factor[data->bucket] | 419 | new_factor -= new_factor / DECAY; |
387 | * (DECAY - 1) / DECAY; | ||
388 | 420 | ||
389 | if (data->expected_us > 0 && measured_us < MAX_INTERESTING) | 421 | if (data->expected_us > 0 && measured_us < MAX_INTERESTING) |
390 | new_factor += RESOLUTION * measured_us / data->expected_us; | 422 | new_factor += RESOLUTION * measured_us / data->expected_us; |
@@ -397,9 +429,11 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
397 | 429 | ||
398 | /* | 430 | /* |
399 | * We don't want 0 as factor; we always want at least | 431 | * We don't want 0 as factor; we always want at least |
400 | * a tiny bit of estimated time. | 432 | * a tiny bit of estimated time. Fortunately, due to rounding, |
433 | * new_factor will stay nonzero regardless of measured_us values | ||
434 | * and the compiler can eliminate this test as long as DECAY > 1. | ||
401 | */ | 435 | */ |
402 | if (new_factor == 0) | 436 | if (DECAY == 1 && unlikely(new_factor == 0)) |
403 | new_factor = 1; | 437 | new_factor = 1; |
404 | 438 | ||
405 | data->correction_factor[data->bucket] = new_factor; | 439 | data->correction_factor[data->bucket] = new_factor; |
@@ -442,14 +476,4 @@ static int __init init_menu(void) | |||
442 | return cpuidle_register_governor(&menu_governor); | 476 | return cpuidle_register_governor(&menu_governor); |
443 | } | 477 | } |
444 | 478 | ||
445 | /** | 479 | postcore_initcall(init_menu); |
446 | * exit_menu - exits the governor | ||
447 | */ | ||
448 | static void __exit exit_menu(void) | ||
449 | { | ||
450 | cpuidle_unregister_governor(&menu_governor); | ||
451 | } | ||
452 | |||
453 | MODULE_LICENSE("GPL"); | ||
454 | module_init(init_menu); | ||
455 | module_exit(exit_menu); | ||
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 428754af6236..8739cc05228c 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c | |||
@@ -11,8 +11,10 @@ | |||
11 | #include <linux/sysfs.h> | 11 | #include <linux/sysfs.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/cpu.h> | 13 | #include <linux/cpu.h> |
14 | #include <linux/completion.h> | ||
14 | #include <linux/capability.h> | 15 | #include <linux/capability.h> |
15 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/kobject.h> | ||
16 | 18 | ||
17 | #include "cpuidle.h" | 19 | #include "cpuidle.h" |
18 | 20 | ||
@@ -33,7 +35,8 @@ static ssize_t show_available_governors(struct device *dev, | |||
33 | 35 | ||
34 | mutex_lock(&cpuidle_lock); | 36 | mutex_lock(&cpuidle_lock); |
35 | list_for_each_entry(tmp, &cpuidle_governors, governor_list) { | 37 | list_for_each_entry(tmp, &cpuidle_governors, governor_list) { |
36 | if (i >= (ssize_t) ((PAGE_SIZE/sizeof(char)) - CPUIDLE_NAME_LEN - 2)) | 38 | if (i >= (ssize_t) ((PAGE_SIZE/sizeof(char)) - |
39 | CPUIDLE_NAME_LEN - 2)) | ||
37 | goto out; | 40 | goto out; |
38 | i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name); | 41 | i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name); |
39 | } | 42 | } |
@@ -166,13 +169,28 @@ struct cpuidle_attr { | |||
166 | #define define_one_rw(_name, show, store) \ | 169 | #define define_one_rw(_name, show, store) \ |
167 | static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store) | 170 | static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store) |
168 | 171 | ||
169 | #define kobj_to_cpuidledev(k) container_of(k, struct cpuidle_device, kobj) | ||
170 | #define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr) | 172 | #define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr) |
171 | static ssize_t cpuidle_show(struct kobject * kobj, struct attribute * attr ,char * buf) | 173 | |
174 | struct cpuidle_device_kobj { | ||
175 | struct cpuidle_device *dev; | ||
176 | struct completion kobj_unregister; | ||
177 | struct kobject kobj; | ||
178 | }; | ||
179 | |||
180 | static inline struct cpuidle_device *to_cpuidle_device(struct kobject *kobj) | ||
181 | { | ||
182 | struct cpuidle_device_kobj *kdev = | ||
183 | container_of(kobj, struct cpuidle_device_kobj, kobj); | ||
184 | |||
185 | return kdev->dev; | ||
186 | } | ||
187 | |||
188 | static ssize_t cpuidle_show(struct kobject *kobj, struct attribute *attr, | ||
189 | char *buf) | ||
172 | { | 190 | { |
173 | int ret = -EIO; | 191 | int ret = -EIO; |
174 | struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); | 192 | struct cpuidle_device *dev = to_cpuidle_device(kobj); |
175 | struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr); | 193 | struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr); |
176 | 194 | ||
177 | if (cattr->show) { | 195 | if (cattr->show) { |
178 | mutex_lock(&cpuidle_lock); | 196 | mutex_lock(&cpuidle_lock); |
@@ -182,12 +200,12 @@ static ssize_t cpuidle_show(struct kobject * kobj, struct attribute * attr ,char | |||
182 | return ret; | 200 | return ret; |
183 | } | 201 | } |
184 | 202 | ||
185 | static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr, | 203 | static ssize_t cpuidle_store(struct kobject *kobj, struct attribute *attr, |
186 | const char * buf, size_t count) | 204 | const char *buf, size_t count) |
187 | { | 205 | { |
188 | int ret = -EIO; | 206 | int ret = -EIO; |
189 | struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); | 207 | struct cpuidle_device *dev = to_cpuidle_device(kobj); |
190 | struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr); | 208 | struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr); |
191 | 209 | ||
192 | if (cattr->store) { | 210 | if (cattr->store) { |
193 | mutex_lock(&cpuidle_lock); | 211 | mutex_lock(&cpuidle_lock); |
@@ -204,9 +222,10 @@ static const struct sysfs_ops cpuidle_sysfs_ops = { | |||
204 | 222 | ||
205 | static void cpuidle_sysfs_release(struct kobject *kobj) | 223 | static void cpuidle_sysfs_release(struct kobject *kobj) |
206 | { | 224 | { |
207 | struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); | 225 | struct cpuidle_device_kobj *kdev = |
226 | container_of(kobj, struct cpuidle_device_kobj, kobj); | ||
208 | 227 | ||
209 | complete(&dev->kobj_unregister); | 228 | complete(&kdev->kobj_unregister); |
210 | } | 229 | } |
211 | 230 | ||
212 | static struct kobj_type ktype_cpuidle = { | 231 | static struct kobj_type ktype_cpuidle = { |
@@ -237,8 +256,8 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \ | |||
237 | 256 | ||
238 | #define define_store_state_ull_function(_name) \ | 257 | #define define_store_state_ull_function(_name) \ |
239 | static ssize_t store_state_##_name(struct cpuidle_state *state, \ | 258 | static ssize_t store_state_##_name(struct cpuidle_state *state, \ |
240 | struct cpuidle_state_usage *state_usage, \ | 259 | struct cpuidle_state_usage *state_usage, \ |
241 | const char *buf, size_t size) \ | 260 | const char *buf, size_t size) \ |
242 | { \ | 261 | { \ |
243 | unsigned long long value; \ | 262 | unsigned long long value; \ |
244 | int err; \ | 263 | int err; \ |
@@ -256,14 +275,16 @@ static ssize_t store_state_##_name(struct cpuidle_state *state, \ | |||
256 | 275 | ||
257 | #define define_show_state_ull_function(_name) \ | 276 | #define define_show_state_ull_function(_name) \ |
258 | static ssize_t show_state_##_name(struct cpuidle_state *state, \ | 277 | static ssize_t show_state_##_name(struct cpuidle_state *state, \ |
259 | struct cpuidle_state_usage *state_usage, char *buf) \ | 278 | struct cpuidle_state_usage *state_usage, \ |
279 | char *buf) \ | ||
260 | { \ | 280 | { \ |
261 | return sprintf(buf, "%llu\n", state_usage->_name);\ | 281 | return sprintf(buf, "%llu\n", state_usage->_name);\ |
262 | } | 282 | } |
263 | 283 | ||
264 | #define define_show_state_str_function(_name) \ | 284 | #define define_show_state_str_function(_name) \ |
265 | static ssize_t show_state_##_name(struct cpuidle_state *state, \ | 285 | static ssize_t show_state_##_name(struct cpuidle_state *state, \ |
266 | struct cpuidle_state_usage *state_usage, char *buf) \ | 286 | struct cpuidle_state_usage *state_usage, \ |
287 | char *buf) \ | ||
267 | { \ | 288 | { \ |
268 | if (state->_name[0] == '\0')\ | 289 | if (state->_name[0] == '\0')\ |
269 | return sprintf(buf, "<null>\n");\ | 290 | return sprintf(buf, "<null>\n");\ |
@@ -309,8 +330,9 @@ struct cpuidle_state_kobj { | |||
309 | #define kobj_to_state(k) (kobj_to_state_obj(k)->state) | 330 | #define kobj_to_state(k) (kobj_to_state_obj(k)->state) |
310 | #define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage) | 331 | #define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage) |
311 | #define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr) | 332 | #define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr) |
312 | static ssize_t cpuidle_state_show(struct kobject * kobj, | 333 | |
313 | struct attribute * attr ,char * buf) | 334 | static ssize_t cpuidle_state_show(struct kobject *kobj, struct attribute *attr, |
335 | char * buf) | ||
314 | { | 336 | { |
315 | int ret = -EIO; | 337 | int ret = -EIO; |
316 | struct cpuidle_state *state = kobj_to_state(kobj); | 338 | struct cpuidle_state *state = kobj_to_state(kobj); |
@@ -323,8 +345,8 @@ static ssize_t cpuidle_state_show(struct kobject * kobj, | |||
323 | return ret; | 345 | return ret; |
324 | } | 346 | } |
325 | 347 | ||
326 | static ssize_t cpuidle_state_store(struct kobject *kobj, | 348 | static ssize_t cpuidle_state_store(struct kobject *kobj, struct attribute *attr, |
327 | struct attribute *attr, const char *buf, size_t size) | 349 | const char *buf, size_t size) |
328 | { | 350 | { |
329 | int ret = -EIO; | 351 | int ret = -EIO; |
330 | struct cpuidle_state *state = kobj_to_state(kobj); | 352 | struct cpuidle_state *state = kobj_to_state(kobj); |
@@ -371,6 +393,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) | |||
371 | { | 393 | { |
372 | int i, ret = -ENOMEM; | 394 | int i, ret = -ENOMEM; |
373 | struct cpuidle_state_kobj *kobj; | 395 | struct cpuidle_state_kobj *kobj; |
396 | struct cpuidle_device_kobj *kdev = device->kobj_dev; | ||
374 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device); | 397 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device); |
375 | 398 | ||
376 | /* state statistics */ | 399 | /* state statistics */ |
@@ -383,7 +406,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) | |||
383 | init_completion(&kobj->kobj_unregister); | 406 | init_completion(&kobj->kobj_unregister); |
384 | 407 | ||
385 | ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, | 408 | ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, |
386 | &device->kobj, "state%d", i); | 409 | &kdev->kobj, "state%d", i); |
387 | if (ret) { | 410 | if (ret) { |
388 | kfree(kobj); | 411 | kfree(kobj); |
389 | goto error_state; | 412 | goto error_state; |
@@ -449,8 +472,8 @@ static void cpuidle_driver_sysfs_release(struct kobject *kobj) | |||
449 | complete(&driver_kobj->kobj_unregister); | 472 | complete(&driver_kobj->kobj_unregister); |
450 | } | 473 | } |
451 | 474 | ||
452 | static ssize_t cpuidle_driver_show(struct kobject *kobj, struct attribute * attr, | 475 | static ssize_t cpuidle_driver_show(struct kobject *kobj, struct attribute *attr, |
453 | char * buf) | 476 | char *buf) |
454 | { | 477 | { |
455 | int ret = -EIO; | 478 | int ret = -EIO; |
456 | struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj); | 479 | struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj); |
@@ -500,6 +523,7 @@ static struct kobj_type ktype_driver_cpuidle = { | |||
500 | static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) | 523 | static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) |
501 | { | 524 | { |
502 | struct cpuidle_driver_kobj *kdrv; | 525 | struct cpuidle_driver_kobj *kdrv; |
526 | struct cpuidle_device_kobj *kdev = dev->kobj_dev; | ||
503 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); | 527 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); |
504 | int ret; | 528 | int ret; |
505 | 529 | ||
@@ -511,7 +535,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) | |||
511 | init_completion(&kdrv->kobj_unregister); | 535 | init_completion(&kdrv->kobj_unregister); |
512 | 536 | ||
513 | ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle, | 537 | ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle, |
514 | &dev->kobj, "driver"); | 538 | &kdev->kobj, "driver"); |
515 | if (ret) { | 539 | if (ret) { |
516 | kfree(kdrv); | 540 | kfree(kdrv); |
517 | return ret; | 541 | return ret; |
@@ -580,16 +604,28 @@ void cpuidle_remove_device_sysfs(struct cpuidle_device *device) | |||
580 | */ | 604 | */ |
581 | int cpuidle_add_sysfs(struct cpuidle_device *dev) | 605 | int cpuidle_add_sysfs(struct cpuidle_device *dev) |
582 | { | 606 | { |
607 | struct cpuidle_device_kobj *kdev; | ||
583 | struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); | 608 | struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); |
584 | int error; | 609 | int error; |
585 | 610 | ||
586 | init_completion(&dev->kobj_unregister); | 611 | kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); |
612 | if (!kdev) | ||
613 | return -ENOMEM; | ||
614 | kdev->dev = dev; | ||
615 | dev->kobj_dev = kdev; | ||
587 | 616 | ||
588 | error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &cpu_dev->kobj, | 617 | init_completion(&kdev->kobj_unregister); |
589 | "cpuidle"); | 618 | |
590 | if (!error) | 619 | error = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj, |
591 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 620 | "cpuidle"); |
592 | return error; | 621 | if (error) { |
622 | kfree(kdev); | ||
623 | return error; | ||
624 | } | ||
625 | |||
626 | kobject_uevent(&kdev->kobj, KOBJ_ADD); | ||
627 | |||
628 | return 0; | ||
593 | } | 629 | } |
594 | 630 | ||
595 | /** | 631 | /** |
@@ -598,6 +634,9 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) | |||
598 | */ | 634 | */ |
599 | void cpuidle_remove_sysfs(struct cpuidle_device *dev) | 635 | void cpuidle_remove_sysfs(struct cpuidle_device *dev) |
600 | { | 636 | { |
601 | kobject_put(&dev->kobj); | 637 | struct cpuidle_device_kobj *kdev = dev->kobj_dev; |
602 | wait_for_completion(&dev->kobj_unregister); | 638 | |
639 | kobject_put(&kdev->kobj); | ||
640 | wait_for_completion(&kdev->kobj_unregister); | ||
641 | kfree(kdev); | ||
603 | } | 642 | } |
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index f1a6796b165c..140c8ef50529 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
@@ -520,11 +520,12 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) | |||
520 | ide_port_for_each_present_dev(i, drive, hwif) { | 520 | ide_port_for_each_present_dev(i, drive, hwif) { |
521 | if (drive->acpidata->obj_handle) | 521 | if (drive->acpidata->obj_handle) |
522 | acpi_bus_set_power(drive->acpidata->obj_handle, | 522 | acpi_bus_set_power(drive->acpidata->obj_handle, |
523 | on ? ACPI_STATE_D0 : ACPI_STATE_D3); | 523 | on ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD); |
524 | } | 524 | } |
525 | 525 | ||
526 | if (!on) | 526 | if (!on) |
527 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3); | 527 | acpi_bus_set_power(hwif->acpidata->obj_handle, |
528 | ACPI_STATE_D3_COLD); | ||
528 | } | 529 | } |
529 | 530 | ||
530 | /** | 531 | /** |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 3c157faee645..0d68eb1a5ec5 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -3094,6 +3094,10 @@ static struct mfd_cell db8500_prcmu_devs[] = { | |||
3094 | .pdata_size = sizeof(db8500_cpufreq_table), | 3094 | .pdata_size = sizeof(db8500_cpufreq_table), |
3095 | }, | 3095 | }, |
3096 | { | 3096 | { |
3097 | .name = "cpuidle-dbx500", | ||
3098 | .of_compatible = "stericsson,cpuidle-dbx500", | ||
3099 | }, | ||
3100 | { | ||
3097 | .name = "db8500-thermal", | 3101 | .name = "db8500-thermal", |
3098 | .num_resources = ARRAY_SIZE(db8500_thsens_resources), | 3102 | .num_resources = ARRAY_SIZE(db8500_thsens_resources), |
3099 | .resources = db8500_thsens_resources, | 3103 | .resources = db8500_thsens_resources, |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 1c3c79c79742..e486e416d5a0 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * 2 of the License, or (at your option) any later version. | 18 | * 2 of the License, or (at your option) any later version. |
19 | */ | 19 | */ |
20 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
21 | #include <linux/cpu.h> | ||
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
23 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
@@ -231,6 +232,100 @@ const void *of_get_property(const struct device_node *np, const char *name, | |||
231 | } | 232 | } |
232 | EXPORT_SYMBOL(of_get_property); | 233 | EXPORT_SYMBOL(of_get_property); |
233 | 234 | ||
235 | /* | ||
236 | * arch_match_cpu_phys_id - Match the given logical CPU and physical id | ||
237 | * | ||
238 | * @cpu: logical cpu index of a core/thread | ||
239 | * @phys_id: physical identifier of a core/thread | ||
240 | * | ||
241 | * CPU logical to physical index mapping is architecture specific. | ||
242 | * However this __weak function provides a default match of physical | ||
243 | * id to logical cpu index. phys_id provided here is usually values read | ||
244 | * from the device tree which must match the hardware internal registers. | ||
245 | * | ||
246 | * Returns true if the physical identifier and the logical cpu index | ||
247 | * correspond to the same core/thread, false otherwise. | ||
248 | */ | ||
249 | bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id) | ||
250 | { | ||
251 | return (u32)phys_id == cpu; | ||
252 | } | ||
253 | |||
254 | /** | ||
255 | * Checks if the given "prop_name" property holds the physical id of the | ||
256 | * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not | ||
257 | * NULL, local thread number within the core is returned in it. | ||
258 | */ | ||
259 | static bool __of_find_n_match_cpu_property(struct device_node *cpun, | ||
260 | const char *prop_name, int cpu, unsigned int *thread) | ||
261 | { | ||
262 | const __be32 *cell; | ||
263 | int ac, prop_len, tid; | ||
264 | u64 hwid; | ||
265 | |||
266 | ac = of_n_addr_cells(cpun); | ||
267 | cell = of_get_property(cpun, prop_name, &prop_len); | ||
268 | if (!cell) | ||
269 | return false; | ||
270 | prop_len /= sizeof(*cell); | ||
271 | for (tid = 0; tid < prop_len; tid++) { | ||
272 | hwid = of_read_number(cell, ac); | ||
273 | if (arch_match_cpu_phys_id(cpu, hwid)) { | ||
274 | if (thread) | ||
275 | *thread = tid; | ||
276 | return true; | ||
277 | } | ||
278 | cell += ac; | ||
279 | } | ||
280 | return false; | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * of_get_cpu_node - Get device node associated with the given logical CPU | ||
285 | * | ||
286 | * @cpu: CPU number(logical index) for which device node is required | ||
287 | * @thread: if not NULL, local thread number within the physical core is | ||
288 | * returned | ||
289 | * | ||
290 | * The main purpose of this function is to retrieve the device node for the | ||
291 | * given logical CPU index. It should be used to initialize the of_node in | ||
292 | * cpu device. Once of_node in cpu device is populated, all the further | ||
293 | * references can use that instead. | ||
294 | * | ||
295 | * CPU logical to physical index mapping is architecture specific and is built | ||
296 | * before booting secondary cores. This function uses arch_match_cpu_phys_id | ||
297 | * which can be overridden by architecture specific implementation. | ||
298 | * | ||
299 | * Returns a node pointer for the logical cpu if found, else NULL. | ||
300 | */ | ||
301 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | ||
302 | { | ||
303 | struct device_node *cpun, *cpus; | ||
304 | |||
305 | cpus = of_find_node_by_path("/cpus"); | ||
306 | if (!cpus) { | ||
307 | pr_warn("Missing cpus node, bailing out\n"); | ||
308 | return NULL; | ||
309 | } | ||
310 | |||
311 | for_each_child_of_node(cpus, cpun) { | ||
312 | if (of_node_cmp(cpun->type, "cpu")) | ||
313 | continue; | ||
314 | /* Check for non-standard "ibm,ppc-interrupt-server#s" property | ||
315 | * for thread ids on PowerPC. If it doesn't exist fallback to | ||
316 | * standard "reg" property. | ||
317 | */ | ||
318 | if (IS_ENABLED(CONFIG_PPC) && | ||
319 | __of_find_n_match_cpu_property(cpun, | ||
320 | "ibm,ppc-interrupt-server#s", cpu, thread)) | ||
321 | return cpun; | ||
322 | if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) | ||
323 | return cpun; | ||
324 | } | ||
325 | return NULL; | ||
326 | } | ||
327 | EXPORT_SYMBOL(of_get_cpu_node); | ||
328 | |||
234 | /** Checks if the given "compat" string matches one of the strings in | 329 | /** Checks if the given "compat" string matches one of the strings in |
235 | * the device's "compatible" property | 330 | * the device's "compatible" property |
236 | */ | 331 | */ |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 6fdd49c6f0b9..f4e028924667 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) | 49 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) |
50 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) | 50 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) |
51 | 51 | ||
52 | struct acpiphp_context; | ||
52 | struct acpiphp_bridge; | 53 | struct acpiphp_bridge; |
53 | struct acpiphp_slot; | 54 | struct acpiphp_slot; |
54 | 55 | ||
@@ -59,6 +60,7 @@ struct slot { | |||
59 | struct hotplug_slot *hotplug_slot; | 60 | struct hotplug_slot *hotplug_slot; |
60 | struct acpiphp_slot *acpi_slot; | 61 | struct acpiphp_slot *acpi_slot; |
61 | struct hotplug_slot_info info; | 62 | struct hotplug_slot_info info; |
63 | unsigned int sun; /* ACPI _SUN (Slot User Number) value */ | ||
62 | }; | 64 | }; |
63 | 65 | ||
64 | static inline const char *slot_name(struct slot *slot) | 66 | static inline const char *slot_name(struct slot *slot) |
@@ -75,15 +77,11 @@ struct acpiphp_bridge { | |||
75 | struct list_head list; | 77 | struct list_head list; |
76 | struct list_head slots; | 78 | struct list_head slots; |
77 | struct kref ref; | 79 | struct kref ref; |
78 | acpi_handle handle; | ||
79 | 80 | ||
80 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ | 81 | struct acpiphp_context *context; |
81 | struct acpiphp_func *func; | ||
82 | 82 | ||
83 | int nr_slots; | 83 | int nr_slots; |
84 | 84 | ||
85 | u32 flags; | ||
86 | |||
87 | /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */ | 85 | /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */ |
88 | struct pci_bus *pci_bus; | 86 | struct pci_bus *pci_bus; |
89 | 87 | ||
@@ -99,15 +97,13 @@ struct acpiphp_bridge { | |||
99 | */ | 97 | */ |
100 | struct acpiphp_slot { | 98 | struct acpiphp_slot { |
101 | struct list_head node; | 99 | struct list_head node; |
102 | struct acpiphp_bridge *bridge; /* parent */ | 100 | struct pci_bus *bus; |
103 | struct list_head funcs; /* one slot may have different | 101 | struct list_head funcs; /* one slot may have different |
104 | objects (i.e. for each function) */ | 102 | objects (i.e. for each function) */ |
105 | struct slot *slot; | 103 | struct slot *slot; |
106 | struct mutex crit_sect; | 104 | struct mutex crit_sect; |
107 | 105 | ||
108 | u8 device; /* pci device# */ | 106 | u8 device; /* pci device# */ |
109 | |||
110 | unsigned long long sun; /* ACPI _SUN (slot unique number) */ | ||
111 | u32 flags; /* see below */ | 107 | u32 flags; /* see below */ |
112 | }; | 108 | }; |
113 | 109 | ||
@@ -119,16 +115,32 @@ struct acpiphp_slot { | |||
119 | * typically 8 objects per slot (i.e. for each PCI function) | 115 | * typically 8 objects per slot (i.e. for each PCI function) |
120 | */ | 116 | */ |
121 | struct acpiphp_func { | 117 | struct acpiphp_func { |
122 | struct acpiphp_slot *slot; /* parent */ | 118 | struct acpiphp_bridge *parent; |
119 | struct acpiphp_slot *slot; | ||
123 | 120 | ||
124 | struct list_head sibling; | 121 | struct list_head sibling; |
125 | struct notifier_block nb; | ||
126 | acpi_handle handle; | ||
127 | 122 | ||
128 | u8 function; /* pci function# */ | 123 | u8 function; /* pci function# */ |
129 | u32 flags; /* see below */ | 124 | u32 flags; /* see below */ |
130 | }; | 125 | }; |
131 | 126 | ||
127 | struct acpiphp_context { | ||
128 | acpi_handle handle; | ||
129 | struct acpiphp_func func; | ||
130 | struct acpiphp_bridge *bridge; | ||
131 | unsigned int refcount; | ||
132 | }; | ||
133 | |||
134 | static inline struct acpiphp_context *func_to_context(struct acpiphp_func *func) | ||
135 | { | ||
136 | return container_of(func, struct acpiphp_context, func); | ||
137 | } | ||
138 | |||
139 | static inline acpi_handle func_to_handle(struct acpiphp_func *func) | ||
140 | { | ||
141 | return func_to_context(func)->handle; | ||
142 | } | ||
143 | |||
132 | /* | 144 | /* |
133 | * struct acpiphp_attention_info - device specific attention registration | 145 | * struct acpiphp_attention_info - device specific attention registration |
134 | * | 146 | * |
@@ -142,45 +154,32 @@ struct acpiphp_attention_info | |||
142 | struct module *owner; | 154 | struct module *owner; |
143 | }; | 155 | }; |
144 | 156 | ||
145 | /* PCI bus bridge HID */ | ||
146 | #define ACPI_PCI_HOST_HID "PNP0A03" | ||
147 | |||
148 | /* ACPI _STA method value (ignore bit 4; battery present) */ | 157 | /* ACPI _STA method value (ignore bit 4; battery present) */ |
149 | #define ACPI_STA_ALL (0x0000000f) | 158 | #define ACPI_STA_ALL (0x0000000f) |
150 | 159 | ||
151 | /* bridge flags */ | ||
152 | #define BRIDGE_HAS_EJ0 (0x00000001) | ||
153 | |||
154 | /* slot flags */ | 160 | /* slot flags */ |
155 | 161 | ||
156 | #define SLOT_POWEREDON (0x00000001) | 162 | #define SLOT_ENABLED (0x00000001) |
157 | #define SLOT_ENABLED (0x00000002) | ||
158 | #define SLOT_MULTIFUNCTION (0x00000004) | ||
159 | 163 | ||
160 | /* function flags */ | 164 | /* function flags */ |
161 | 165 | ||
162 | #define FUNC_HAS_STA (0x00000001) | 166 | #define FUNC_HAS_STA (0x00000001) |
163 | #define FUNC_HAS_EJ0 (0x00000002) | 167 | #define FUNC_HAS_EJ0 (0x00000002) |
164 | #define FUNC_HAS_PS0 (0x00000010) | 168 | #define FUNC_HAS_DCK (0x00000004) |
165 | #define FUNC_HAS_PS1 (0x00000020) | ||
166 | #define FUNC_HAS_PS2 (0x00000040) | ||
167 | #define FUNC_HAS_PS3 (0x00000080) | ||
168 | #define FUNC_HAS_DCK (0x00000100) | ||
169 | 169 | ||
170 | /* function prototypes */ | 170 | /* function prototypes */ |
171 | 171 | ||
172 | /* acpiphp_core.c */ | 172 | /* acpiphp_core.c */ |
173 | int acpiphp_register_attention(struct acpiphp_attention_info*info); | 173 | int acpiphp_register_attention(struct acpiphp_attention_info*info); |
174 | int acpiphp_unregister_attention(struct acpiphp_attention_info *info); | 174 | int acpiphp_unregister_attention(struct acpiphp_attention_info *info); |
175 | int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); | 175 | int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot, unsigned int sun); |
176 | void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); | 176 | void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); |
177 | 177 | ||
178 | /* acpiphp_glue.c */ | 178 | /* acpiphp_glue.c */ |
179 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); | 179 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); |
180 | 180 | ||
181 | int acpiphp_enable_slot(struct acpiphp_slot *slot); | 181 | int acpiphp_enable_slot(struct acpiphp_slot *slot); |
182 | int acpiphp_disable_slot(struct acpiphp_slot *slot); | 182 | int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot); |
183 | int acpiphp_eject_slot(struct acpiphp_slot *slot); | ||
184 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot); | 183 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot); |
185 | u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); | 184 | u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); |
186 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); | 185 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index ca8127950fcd..bf2203ef1308 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -155,15 +155,11 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) | |||
155 | static int disable_slot(struct hotplug_slot *hotplug_slot) | 155 | static int disable_slot(struct hotplug_slot *hotplug_slot) |
156 | { | 156 | { |
157 | struct slot *slot = hotplug_slot->private; | 157 | struct slot *slot = hotplug_slot->private; |
158 | int retval; | ||
159 | 158 | ||
160 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); | 159 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); |
161 | 160 | ||
162 | /* disable the specified slot */ | 161 | /* disable the specified slot */ |
163 | retval = acpiphp_disable_slot(slot->acpi_slot); | 162 | return acpiphp_disable_and_eject_slot(slot->acpi_slot); |
164 | if (!retval) | ||
165 | retval = acpiphp_eject_slot(slot->acpi_slot); | ||
166 | return retval; | ||
167 | } | 163 | } |
168 | 164 | ||
169 | 165 | ||
@@ -290,7 +286,8 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
290 | } | 286 | } |
291 | 287 | ||
292 | /* callback routine to initialize 'struct slot' for each slot */ | 288 | /* callback routine to initialize 'struct slot' for each slot */ |
293 | int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) | 289 | int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot, |
290 | unsigned int sun) | ||
294 | { | 291 | { |
295 | struct slot *slot; | 292 | struct slot *slot; |
296 | int retval = -ENOMEM; | 293 | int retval = -ENOMEM; |
@@ -317,12 +314,11 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) | |||
317 | slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); | 314 | slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); |
318 | 315 | ||
319 | acpiphp_slot->slot = slot; | 316 | acpiphp_slot->slot = slot; |
320 | snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun); | 317 | slot->sun = sun; |
318 | snprintf(name, SLOT_NAME_SIZE, "%u", sun); | ||
321 | 319 | ||
322 | retval = pci_hp_register(slot->hotplug_slot, | 320 | retval = pci_hp_register(slot->hotplug_slot, acpiphp_slot->bus, |
323 | acpiphp_slot->bridge->pci_bus, | 321 | acpiphp_slot->device, name); |
324 | acpiphp_slot->device, | ||
325 | name); | ||
326 | if (retval == -EBUSY) | 322 | if (retval == -EBUSY) |
327 | goto error_hpslot; | 323 | goto error_hpslot; |
328 | if (retval) { | 324 | if (retval) { |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 59df8575a48c..8054ddcdaed0 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/pci.h> | 46 | #include <linux/pci.h> |
47 | #include <linux/pci_hotplug.h> | 47 | #include <linux/pci_hotplug.h> |
48 | #include <linux/pci-acpi.h> | 48 | #include <linux/pci-acpi.h> |
49 | #include <linux/pm_runtime.h> | ||
49 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
50 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
51 | #include <linux/acpi.h> | 52 | #include <linux/acpi.h> |
@@ -55,28 +56,82 @@ | |||
55 | 56 | ||
56 | static LIST_HEAD(bridge_list); | 57 | static LIST_HEAD(bridge_list); |
57 | static DEFINE_MUTEX(bridge_mutex); | 58 | static DEFINE_MUTEX(bridge_mutex); |
59 | static DEFINE_MUTEX(acpiphp_context_lock); | ||
58 | 60 | ||
59 | #define MY_NAME "acpiphp_glue" | 61 | #define MY_NAME "acpiphp_glue" |
60 | 62 | ||
61 | static void handle_hotplug_event_bridge (acpi_handle, u32, void *); | 63 | static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); |
62 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 64 | static void acpiphp_sanitize_bus(struct pci_bus *bus); |
63 | static void acpiphp_set_hpp_values(struct pci_bus *bus); | 65 | static void acpiphp_set_hpp_values(struct pci_bus *bus); |
64 | static void hotplug_event_func(acpi_handle handle, u32 type, void *context); | 66 | static void hotplug_event(acpi_handle handle, u32 type, void *data); |
65 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); | ||
66 | static void free_bridge(struct kref *kref); | 67 | static void free_bridge(struct kref *kref); |
67 | 68 | ||
68 | /* callback routine to check for the existence of a pci dock device */ | 69 | static void acpiphp_context_handler(acpi_handle handle, void *context) |
69 | static acpi_status | ||
70 | is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
71 | { | 70 | { |
72 | int *count = (int *)context; | 71 | /* Intentionally empty. */ |
72 | } | ||
73 | 73 | ||
74 | if (is_dock_device(handle)) { | 74 | /** |
75 | (*count)++; | 75 | * acpiphp_init_context - Create hotplug context and grab a reference to it. |
76 | return AE_CTRL_TERMINATE; | 76 | * @handle: ACPI object handle to create the context for. |
77 | } else { | 77 | * |
78 | return AE_OK; | 78 | * Call under acpiphp_context_lock. |
79 | */ | ||
80 | static struct acpiphp_context *acpiphp_init_context(acpi_handle handle) | ||
81 | { | ||
82 | struct acpiphp_context *context; | ||
83 | acpi_status status; | ||
84 | |||
85 | context = kzalloc(sizeof(*context), GFP_KERNEL); | ||
86 | if (!context) | ||
87 | return NULL; | ||
88 | |||
89 | context->handle = handle; | ||
90 | context->refcount = 1; | ||
91 | status = acpi_attach_data(handle, acpiphp_context_handler, context); | ||
92 | if (ACPI_FAILURE(status)) { | ||
93 | kfree(context); | ||
94 | return NULL; | ||
79 | } | 95 | } |
96 | return context; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * acpiphp_get_context - Get hotplug context and grab a reference to it. | ||
101 | * @handle: ACPI object handle to get the context for. | ||
102 | * | ||
103 | * Call under acpiphp_context_lock. | ||
104 | */ | ||
105 | static struct acpiphp_context *acpiphp_get_context(acpi_handle handle) | ||
106 | { | ||
107 | struct acpiphp_context *context = NULL; | ||
108 | acpi_status status; | ||
109 | void *data; | ||
110 | |||
111 | status = acpi_get_data(handle, acpiphp_context_handler, &data); | ||
112 | if (ACPI_SUCCESS(status)) { | ||
113 | context = data; | ||
114 | context->refcount++; | ||
115 | } | ||
116 | return context; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * acpiphp_put_context - Drop a reference to ACPI hotplug context. | ||
121 | * @handle: ACPI object handle to put the context for. | ||
122 | * | ||
123 | * The context object is removed if there are no more references to it. | ||
124 | * | ||
125 | * Call under acpiphp_context_lock. | ||
126 | */ | ||
127 | static void acpiphp_put_context(struct acpiphp_context *context) | ||
128 | { | ||
129 | if (--context->refcount) | ||
130 | return; | ||
131 | |||
132 | WARN_ON(context->bridge); | ||
133 | acpi_detach_data(context->handle, acpiphp_context_handler); | ||
134 | kfree(context); | ||
80 | } | 135 | } |
81 | 136 | ||
82 | static inline void get_bridge(struct acpiphp_bridge *bridge) | 137 | static inline void get_bridge(struct acpiphp_bridge *bridge) |
@@ -91,25 +146,36 @@ static inline void put_bridge(struct acpiphp_bridge *bridge) | |||
91 | 146 | ||
92 | static void free_bridge(struct kref *kref) | 147 | static void free_bridge(struct kref *kref) |
93 | { | 148 | { |
149 | struct acpiphp_context *context; | ||
94 | struct acpiphp_bridge *bridge; | 150 | struct acpiphp_bridge *bridge; |
95 | struct acpiphp_slot *slot, *next; | 151 | struct acpiphp_slot *slot, *next; |
96 | struct acpiphp_func *func, *tmp; | 152 | struct acpiphp_func *func, *tmp; |
97 | 153 | ||
154 | mutex_lock(&acpiphp_context_lock); | ||
155 | |||
98 | bridge = container_of(kref, struct acpiphp_bridge, ref); | 156 | bridge = container_of(kref, struct acpiphp_bridge, ref); |
99 | 157 | ||
100 | list_for_each_entry_safe(slot, next, &bridge->slots, node) { | 158 | list_for_each_entry_safe(slot, next, &bridge->slots, node) { |
101 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { | 159 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) |
102 | kfree(func); | 160 | acpiphp_put_context(func_to_context(func)); |
103 | } | 161 | |
104 | kfree(slot); | 162 | kfree(slot); |
105 | } | 163 | } |
106 | 164 | ||
107 | /* Release reference acquired by acpiphp_bridge_handle_to_function() */ | 165 | context = bridge->context; |
108 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) | 166 | /* Root bridges will not have hotplug context. */ |
109 | put_bridge(bridge->func->slot->bridge); | 167 | if (context) { |
168 | /* Release the reference taken by acpiphp_enumerate_slots(). */ | ||
169 | put_bridge(context->func.parent); | ||
170 | context->bridge = NULL; | ||
171 | acpiphp_put_context(context); | ||
172 | } | ||
173 | |||
110 | put_device(&bridge->pci_bus->dev); | 174 | put_device(&bridge->pci_bus->dev); |
111 | pci_dev_put(bridge->pci_dev); | 175 | pci_dev_put(bridge->pci_dev); |
112 | kfree(bridge); | 176 | kfree(bridge); |
177 | |||
178 | mutex_unlock(&acpiphp_context_lock); | ||
113 | } | 179 | } |
114 | 180 | ||
115 | /* | 181 | /* |
@@ -119,15 +185,14 @@ static void free_bridge(struct kref *kref) | |||
119 | * TBD - figure out a way to only call fixups for | 185 | * TBD - figure out a way to only call fixups for |
120 | * systems that require them. | 186 | * systems that require them. |
121 | */ | 187 | */ |
122 | static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | 188 | static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) |
123 | void *v) | ||
124 | { | 189 | { |
125 | struct acpiphp_func *func = container_of(nb, struct acpiphp_func, nb); | 190 | struct acpiphp_context *context = data; |
126 | struct pci_bus *bus = func->slot->bridge->pci_bus; | 191 | struct pci_bus *bus = context->func.slot->bus; |
127 | u32 buses; | 192 | u32 buses; |
128 | 193 | ||
129 | if (!bus->self) | 194 | if (!bus->self) |
130 | return NOTIFY_OK; | 195 | return; |
131 | 196 | ||
132 | /* fixup bad _DCK function that rewrites | 197 | /* fixup bad _DCK function that rewrites |
133 | * secondary bridge on slot | 198 | * secondary bridge on slot |
@@ -143,12 +208,12 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | |||
143 | | ((unsigned int)(bus->busn_res.end) << 16); | 208 | | ((unsigned int)(bus->busn_res.end) << 16); |
144 | pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); | 209 | pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); |
145 | } | 210 | } |
146 | return NOTIFY_OK; | ||
147 | } | 211 | } |
148 | 212 | ||
149 | 213 | ||
150 | static const struct acpi_dock_ops acpiphp_dock_ops = { | 214 | static const struct acpi_dock_ops acpiphp_dock_ops = { |
151 | .handler = hotplug_event_func, | 215 | .fixup = post_dock_fixups, |
216 | .handler = hotplug_event, | ||
152 | }; | 217 | }; |
153 | 218 | ||
154 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ | 219 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ |
@@ -182,129 +247,118 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) | |||
182 | 247 | ||
183 | static void acpiphp_dock_init(void *data) | 248 | static void acpiphp_dock_init(void *data) |
184 | { | 249 | { |
185 | struct acpiphp_func *func = data; | 250 | struct acpiphp_context *context = data; |
186 | 251 | ||
187 | get_bridge(func->slot->bridge); | 252 | get_bridge(context->func.parent); |
188 | } | 253 | } |
189 | 254 | ||
190 | static void acpiphp_dock_release(void *data) | 255 | static void acpiphp_dock_release(void *data) |
191 | { | 256 | { |
192 | struct acpiphp_func *func = data; | 257 | struct acpiphp_context *context = data; |
193 | 258 | ||
194 | put_bridge(func->slot->bridge); | 259 | put_bridge(context->func.parent); |
195 | } | 260 | } |
196 | 261 | ||
197 | /* callback routine to register each ACPI PCI slot object */ | 262 | /* callback routine to register each ACPI PCI slot object */ |
198 | static acpi_status | 263 | static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, |
199 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | 264 | void **rv) |
200 | { | 265 | { |
201 | struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context; | 266 | struct acpiphp_bridge *bridge = data; |
267 | struct acpiphp_context *context; | ||
202 | struct acpiphp_slot *slot; | 268 | struct acpiphp_slot *slot; |
203 | struct acpiphp_func *newfunc; | 269 | struct acpiphp_func *newfunc; |
204 | acpi_handle tmp; | ||
205 | acpi_status status = AE_OK; | 270 | acpi_status status = AE_OK; |
206 | unsigned long long adr, sun; | 271 | unsigned long long adr; |
207 | int device, function, retval, found = 0; | 272 | int device, function; |
208 | struct pci_bus *pbus = bridge->pci_bus; | 273 | struct pci_bus *pbus = bridge->pci_bus; |
209 | struct pci_dev *pdev; | 274 | struct pci_dev *pdev = bridge->pci_dev; |
210 | u32 val; | 275 | u32 val; |
211 | 276 | ||
212 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) | 277 | if (pdev && device_is_managed_by_native_pciehp(pdev)) |
213 | return AE_OK; | 278 | return AE_OK; |
214 | 279 | ||
215 | status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); | 280 | status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); |
216 | if (ACPI_FAILURE(status)) { | 281 | if (ACPI_FAILURE(status)) { |
217 | warn("can't evaluate _ADR (%#x)\n", status); | 282 | acpi_handle_warn(handle, "can't evaluate _ADR (%#x)\n", status); |
218 | return AE_OK; | 283 | return AE_OK; |
219 | } | 284 | } |
220 | 285 | ||
221 | device = (adr >> 16) & 0xffff; | 286 | device = (adr >> 16) & 0xffff; |
222 | function = adr & 0xffff; | 287 | function = adr & 0xffff; |
223 | 288 | ||
224 | pdev = bridge->pci_dev; | 289 | mutex_lock(&acpiphp_context_lock); |
225 | if (pdev && device_is_managed_by_native_pciehp(pdev)) | 290 | context = acpiphp_init_context(handle); |
226 | return AE_OK; | 291 | if (!context) { |
227 | 292 | mutex_unlock(&acpiphp_context_lock); | |
228 | newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); | 293 | acpi_handle_err(handle, "No hotplug context\n"); |
229 | if (!newfunc) | 294 | return AE_NOT_EXIST; |
230 | return AE_NO_MEMORY; | 295 | } |
231 | 296 | newfunc = &context->func; | |
232 | newfunc->handle = handle; | ||
233 | newfunc->function = function; | 297 | newfunc->function = function; |
298 | newfunc->parent = bridge; | ||
299 | mutex_unlock(&acpiphp_context_lock); | ||
234 | 300 | ||
235 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp))) | 301 | if (acpi_has_method(handle, "_EJ0")) |
236 | newfunc->flags = FUNC_HAS_EJ0; | 302 | newfunc->flags = FUNC_HAS_EJ0; |
237 | 303 | ||
238 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp))) | 304 | if (acpi_has_method(handle, "_STA")) |
239 | newfunc->flags |= FUNC_HAS_STA; | 305 | newfunc->flags |= FUNC_HAS_STA; |
240 | 306 | ||
241 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS0", &tmp))) | 307 | if (acpi_has_method(handle, "_DCK")) |
242 | newfunc->flags |= FUNC_HAS_PS0; | ||
243 | |||
244 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp))) | ||
245 | newfunc->flags |= FUNC_HAS_PS3; | ||
246 | |||
247 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp))) | ||
248 | newfunc->flags |= FUNC_HAS_DCK; | 308 | newfunc->flags |= FUNC_HAS_DCK; |
249 | 309 | ||
250 | status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun); | ||
251 | if (ACPI_FAILURE(status)) { | ||
252 | /* | ||
253 | * use the count of the number of slots we've found | ||
254 | * for the number of the slot | ||
255 | */ | ||
256 | sun = bridge->nr_slots+1; | ||
257 | } | ||
258 | |||
259 | /* search for objects that share the same slot */ | 310 | /* search for objects that share the same slot */ |
260 | list_for_each_entry(slot, &bridge->slots, node) | 311 | list_for_each_entry(slot, &bridge->slots, node) |
261 | if (slot->device == device) { | 312 | if (slot->device == device) |
262 | if (slot->sun != sun) | 313 | goto slot_found; |
263 | warn("sibling found, but _SUN doesn't match!\n"); | ||
264 | found = 1; | ||
265 | break; | ||
266 | } | ||
267 | 314 | ||
268 | if (!found) { | 315 | slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); |
269 | slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); | 316 | if (!slot) { |
270 | if (!slot) { | 317 | status = AE_NO_MEMORY; |
271 | kfree(newfunc); | 318 | goto err; |
272 | return AE_NO_MEMORY; | 319 | } |
273 | } | ||
274 | 320 | ||
275 | slot->bridge = bridge; | 321 | slot->bus = bridge->pci_bus; |
276 | slot->device = device; | 322 | slot->device = device; |
277 | slot->sun = sun; | 323 | INIT_LIST_HEAD(&slot->funcs); |
278 | INIT_LIST_HEAD(&slot->funcs); | 324 | mutex_init(&slot->crit_sect); |
279 | mutex_init(&slot->crit_sect); | 325 | |
326 | list_add_tail(&slot->node, &bridge->slots); | ||
327 | |||
328 | /* Register slots for ejectable funtions only. */ | ||
329 | if (acpi_pci_check_ejectable(pbus, handle) || is_dock_device(handle)) { | ||
330 | unsigned long long sun; | ||
331 | int retval; | ||
280 | 332 | ||
281 | mutex_lock(&bridge_mutex); | ||
282 | list_add_tail(&slot->node, &bridge->slots); | ||
283 | mutex_unlock(&bridge_mutex); | ||
284 | bridge->nr_slots++; | 333 | bridge->nr_slots++; |
334 | status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun); | ||
335 | if (ACPI_FAILURE(status)) | ||
336 | sun = bridge->nr_slots; | ||
285 | 337 | ||
286 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", | 338 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", |
287 | slot->sun, pci_domain_nr(pbus), pbus->number, device); | 339 | sun, pci_domain_nr(pbus), pbus->number, device); |
288 | retval = acpiphp_register_hotplug_slot(slot); | 340 | |
341 | retval = acpiphp_register_hotplug_slot(slot, sun); | ||
289 | if (retval) { | 342 | if (retval) { |
343 | slot->slot = NULL; | ||
344 | bridge->nr_slots--; | ||
290 | if (retval == -EBUSY) | 345 | if (retval == -EBUSY) |
291 | warn("Slot %llu already registered by another " | 346 | warn("Slot %llu already registered by another " |
292 | "hotplug driver\n", slot->sun); | 347 | "hotplug driver\n", sun); |
293 | else | 348 | else |
294 | warn("acpiphp_register_hotplug_slot failed " | 349 | warn("acpiphp_register_hotplug_slot failed " |
295 | "(err code = 0x%x)\n", retval); | 350 | "(err code = 0x%x)\n", retval); |
296 | goto err_exit; | ||
297 | } | 351 | } |
352 | /* Even if the slot registration fails, we can still use it. */ | ||
298 | } | 353 | } |
299 | 354 | ||
355 | slot_found: | ||
300 | newfunc->slot = slot; | 356 | newfunc->slot = slot; |
301 | mutex_lock(&bridge_mutex); | ||
302 | list_add_tail(&newfunc->sibling, &slot->funcs); | 357 | list_add_tail(&newfunc->sibling, &slot->funcs); |
303 | mutex_unlock(&bridge_mutex); | ||
304 | 358 | ||
305 | if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function), | 359 | if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function), |
306 | &val, 60*1000)) | 360 | &val, 60*1000)) |
307 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); | 361 | slot->flags |= SLOT_ENABLED; |
308 | 362 | ||
309 | if (is_dock_device(handle)) { | 363 | if (is_dock_device(handle)) { |
310 | /* we don't want to call this device's _EJ0 | 364 | /* we don't want to call this device's _EJ0 |
@@ -313,136 +367,46 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
313 | */ | 367 | */ |
314 | newfunc->flags &= ~FUNC_HAS_EJ0; | 368 | newfunc->flags &= ~FUNC_HAS_EJ0; |
315 | if (register_hotplug_dock_device(handle, | 369 | if (register_hotplug_dock_device(handle, |
316 | &acpiphp_dock_ops, newfunc, | 370 | &acpiphp_dock_ops, context, |
317 | acpiphp_dock_init, acpiphp_dock_release)) | 371 | acpiphp_dock_init, acpiphp_dock_release)) |
318 | dbg("failed to register dock device\n"); | 372 | dbg("failed to register dock device\n"); |
319 | |||
320 | /* we need to be notified when dock events happen | ||
321 | * outside of the hotplug operation, since we may | ||
322 | * need to do fixups before we can hotplug. | ||
323 | */ | ||
324 | newfunc->nb.notifier_call = post_dock_fixups; | ||
325 | if (register_dock_notifier(&newfunc->nb)) | ||
326 | dbg("failed to register a dock notifier"); | ||
327 | } | 373 | } |
328 | 374 | ||
329 | /* install notify handler */ | 375 | /* install notify handler */ |
330 | if (!(newfunc->flags & FUNC_HAS_DCK)) { | 376 | if (!(newfunc->flags & FUNC_HAS_DCK)) { |
331 | status = acpi_install_notify_handler(handle, | 377 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
332 | ACPI_SYSTEM_NOTIFY, | 378 | handle_hotplug_event, |
333 | handle_hotplug_event_func, | 379 | context); |
334 | newfunc); | ||
335 | |||
336 | if (ACPI_FAILURE(status)) | 380 | if (ACPI_FAILURE(status)) |
337 | err("failed to register interrupt notify handler\n"); | 381 | acpi_handle_err(handle, |
338 | } else | 382 | "failed to install notify handler\n"); |
339 | status = AE_OK; | ||
340 | |||
341 | return status; | ||
342 | |||
343 | err_exit: | ||
344 | bridge->nr_slots--; | ||
345 | mutex_lock(&bridge_mutex); | ||
346 | list_del(&slot->node); | ||
347 | mutex_unlock(&bridge_mutex); | ||
348 | kfree(slot); | ||
349 | kfree(newfunc); | ||
350 | |||
351 | return AE_OK; | ||
352 | } | ||
353 | |||
354 | |||
355 | /* see if it's worth looking at this bridge */ | ||
356 | static int detect_ejectable_slots(acpi_handle handle) | ||
357 | { | ||
358 | int found = acpi_pci_detect_ejectable(handle); | ||
359 | if (!found) { | ||
360 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
361 | is_pci_dock_device, NULL, (void *)&found, NULL); | ||
362 | } | ||
363 | return found; | ||
364 | } | ||
365 | |||
366 | /* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */ | ||
367 | static void init_bridge_misc(struct acpiphp_bridge *bridge) | ||
368 | { | ||
369 | acpi_status status; | ||
370 | |||
371 | /* must be added to the list prior to calling register_slot */ | ||
372 | mutex_lock(&bridge_mutex); | ||
373 | list_add(&bridge->list, &bridge_list); | ||
374 | mutex_unlock(&bridge_mutex); | ||
375 | |||
376 | /* register all slot objects under this bridge */ | ||
377 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, | ||
378 | register_slot, NULL, bridge, NULL); | ||
379 | if (ACPI_FAILURE(status)) { | ||
380 | mutex_lock(&bridge_mutex); | ||
381 | list_del(&bridge->list); | ||
382 | mutex_unlock(&bridge_mutex); | ||
383 | return; | ||
384 | } | 383 | } |
385 | 384 | ||
386 | /* install notify handler for P2P bridges */ | 385 | return AE_OK; |
387 | if (!pci_is_root_bus(bridge->pci_bus)) { | ||
388 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { | ||
389 | status = acpi_remove_notify_handler(bridge->func->handle, | ||
390 | ACPI_SYSTEM_NOTIFY, | ||
391 | handle_hotplug_event_func); | ||
392 | if (ACPI_FAILURE(status)) | ||
393 | err("failed to remove notify handler\n"); | ||
394 | } | ||
395 | status = acpi_install_notify_handler(bridge->handle, | ||
396 | ACPI_SYSTEM_NOTIFY, | ||
397 | handle_hotplug_event_bridge, | ||
398 | bridge); | ||
399 | |||
400 | if (ACPI_FAILURE(status)) { | ||
401 | err("failed to register interrupt notify handler\n"); | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | |||
406 | |||
407 | /* find acpiphp_func from acpiphp_bridge */ | ||
408 | static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) | ||
409 | { | ||
410 | struct acpiphp_bridge *bridge; | ||
411 | struct acpiphp_slot *slot; | ||
412 | struct acpiphp_func *func = NULL; | ||
413 | |||
414 | mutex_lock(&bridge_mutex); | ||
415 | list_for_each_entry(bridge, &bridge_list, list) { | ||
416 | list_for_each_entry(slot, &bridge->slots, node) { | ||
417 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
418 | if (func->handle == handle) { | ||
419 | get_bridge(func->slot->bridge); | ||
420 | mutex_unlock(&bridge_mutex); | ||
421 | return func; | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | mutex_unlock(&bridge_mutex); | ||
427 | 386 | ||
428 | return NULL; | 387 | err: |
388 | mutex_lock(&acpiphp_context_lock); | ||
389 | acpiphp_put_context(context); | ||
390 | mutex_unlock(&acpiphp_context_lock); | ||
391 | return status; | ||
429 | } | 392 | } |
430 | 393 | ||
431 | |||
432 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) | 394 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) |
433 | { | 395 | { |
434 | struct acpiphp_bridge *bridge; | 396 | struct acpiphp_context *context; |
435 | 397 | struct acpiphp_bridge *bridge = NULL; | |
436 | mutex_lock(&bridge_mutex); | 398 | |
437 | list_for_each_entry(bridge, &bridge_list, list) | 399 | mutex_lock(&acpiphp_context_lock); |
438 | if (bridge->handle == handle) { | 400 | context = acpiphp_get_context(handle); |
401 | if (context) { | ||
402 | bridge = context->bridge; | ||
403 | if (bridge) | ||
439 | get_bridge(bridge); | 404 | get_bridge(bridge); |
440 | mutex_unlock(&bridge_mutex); | ||
441 | return bridge; | ||
442 | } | ||
443 | mutex_unlock(&bridge_mutex); | ||
444 | 405 | ||
445 | return NULL; | 406 | acpiphp_put_context(context); |
407 | } | ||
408 | mutex_unlock(&acpiphp_context_lock); | ||
409 | return bridge; | ||
446 | } | 410 | } |
447 | 411 | ||
448 | static void cleanup_bridge(struct acpiphp_bridge *bridge) | 412 | static void cleanup_bridge(struct acpiphp_bridge *bridge) |
@@ -450,40 +414,24 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
450 | struct acpiphp_slot *slot; | 414 | struct acpiphp_slot *slot; |
451 | struct acpiphp_func *func; | 415 | struct acpiphp_func *func; |
452 | acpi_status status; | 416 | acpi_status status; |
453 | acpi_handle handle = bridge->handle; | ||
454 | |||
455 | if (!pci_is_root_bus(bridge->pci_bus)) { | ||
456 | status = acpi_remove_notify_handler(handle, | ||
457 | ACPI_SYSTEM_NOTIFY, | ||
458 | handle_hotplug_event_bridge); | ||
459 | if (ACPI_FAILURE(status)) | ||
460 | err("failed to remove notify handler\n"); | ||
461 | } | ||
462 | |||
463 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { | ||
464 | status = acpi_install_notify_handler(bridge->func->handle, | ||
465 | ACPI_SYSTEM_NOTIFY, | ||
466 | handle_hotplug_event_func, | ||
467 | bridge->func); | ||
468 | if (ACPI_FAILURE(status)) | ||
469 | err("failed to install interrupt notify handler\n"); | ||
470 | } | ||
471 | 417 | ||
472 | list_for_each_entry(slot, &bridge->slots, node) { | 418 | list_for_each_entry(slot, &bridge->slots, node) { |
473 | list_for_each_entry(func, &slot->funcs, sibling) { | 419 | list_for_each_entry(func, &slot->funcs, sibling) { |
474 | if (is_dock_device(func->handle)) { | 420 | acpi_handle handle = func_to_handle(func); |
475 | unregister_hotplug_dock_device(func->handle); | 421 | |
476 | unregister_dock_notifier(&func->nb); | 422 | if (is_dock_device(handle)) |
477 | } | 423 | unregister_hotplug_dock_device(handle); |
424 | |||
478 | if (!(func->flags & FUNC_HAS_DCK)) { | 425 | if (!(func->flags & FUNC_HAS_DCK)) { |
479 | status = acpi_remove_notify_handler(func->handle, | 426 | status = acpi_remove_notify_handler(handle, |
480 | ACPI_SYSTEM_NOTIFY, | 427 | ACPI_SYSTEM_NOTIFY, |
481 | handle_hotplug_event_func); | 428 | handle_hotplug_event); |
482 | if (ACPI_FAILURE(status)) | 429 | if (ACPI_FAILURE(status)) |
483 | err("failed to remove notify handler\n"); | 430 | err("failed to remove notify handler\n"); |
484 | } | 431 | } |
485 | } | 432 | } |
486 | acpiphp_unregister_hotplug_slot(slot); | 433 | if (slot->slot) |
434 | acpiphp_unregister_hotplug_slot(slot); | ||
487 | } | 435 | } |
488 | 436 | ||
489 | mutex_lock(&bridge_mutex); | 437 | mutex_lock(&bridge_mutex); |
@@ -491,71 +439,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
491 | mutex_unlock(&bridge_mutex); | 439 | mutex_unlock(&bridge_mutex); |
492 | } | 440 | } |
493 | 441 | ||
494 | static int power_on_slot(struct acpiphp_slot *slot) | ||
495 | { | ||
496 | acpi_status status; | ||
497 | struct acpiphp_func *func; | ||
498 | int retval = 0; | ||
499 | |||
500 | /* if already enabled, just skip */ | ||
501 | if (slot->flags & SLOT_POWEREDON) | ||
502 | goto err_exit; | ||
503 | |||
504 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
505 | if (func->flags & FUNC_HAS_PS0) { | ||
506 | dbg("%s: executing _PS0\n", __func__); | ||
507 | status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); | ||
508 | if (ACPI_FAILURE(status)) { | ||
509 | warn("%s: _PS0 failed\n", __func__); | ||
510 | retval = -1; | ||
511 | goto err_exit; | ||
512 | } else | ||
513 | break; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | /* TBD: evaluate _STA to check if the slot is enabled */ | ||
518 | |||
519 | slot->flags |= SLOT_POWEREDON; | ||
520 | |||
521 | err_exit: | ||
522 | return retval; | ||
523 | } | ||
524 | |||
525 | |||
526 | static int power_off_slot(struct acpiphp_slot *slot) | ||
527 | { | ||
528 | acpi_status status; | ||
529 | struct acpiphp_func *func; | ||
530 | |||
531 | int retval = 0; | ||
532 | |||
533 | /* if already disabled, just skip */ | ||
534 | if ((slot->flags & SLOT_POWEREDON) == 0) | ||
535 | goto err_exit; | ||
536 | |||
537 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
538 | if (func->flags & FUNC_HAS_PS3) { | ||
539 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); | ||
540 | if (ACPI_FAILURE(status)) { | ||
541 | warn("%s: _PS3 failed\n", __func__); | ||
542 | retval = -1; | ||
543 | goto err_exit; | ||
544 | } else | ||
545 | break; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | /* TBD: evaluate _STA to check if the slot is disabled */ | ||
550 | |||
551 | slot->flags &= (~SLOT_POWEREDON); | ||
552 | |||
553 | err_exit: | ||
554 | return retval; | ||
555 | } | ||
556 | |||
557 | |||
558 | |||
559 | /** | 442 | /** |
560 | * acpiphp_max_busnr - return the highest reserved bus number under the given bus. | 443 | * acpiphp_max_busnr - return the highest reserved bus number under the given bus. |
561 | * @bus: bus to start search with | 444 | * @bus: bus to start search with |
@@ -583,52 +466,32 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) | |||
583 | return max; | 466 | return max; |
584 | } | 467 | } |
585 | 468 | ||
586 | |||
587 | /** | 469 | /** |
588 | * acpiphp_bus_add - add a new bus to acpi subsystem | 470 | * acpiphp_bus_trim - Trim device objects in an ACPI namespace subtree. |
589 | * @func: acpiphp_func of the bridge | 471 | * @handle: ACPI device object handle to start from. |
590 | */ | 472 | */ |
591 | static int acpiphp_bus_add(struct acpiphp_func *func) | 473 | static void acpiphp_bus_trim(acpi_handle handle) |
592 | { | 474 | { |
593 | struct acpi_device *device; | 475 | struct acpi_device *adev = NULL; |
594 | int ret_val; | ||
595 | |||
596 | if (!acpi_bus_get_device(func->handle, &device)) { | ||
597 | dbg("bus exists... trim\n"); | ||
598 | /* this shouldn't be in here, so remove | ||
599 | * the bus then re-add it... | ||
600 | */ | ||
601 | acpi_bus_trim(device); | ||
602 | } | ||
603 | |||
604 | ret_val = acpi_bus_scan(func->handle); | ||
605 | if (!ret_val) | ||
606 | ret_val = acpi_bus_get_device(func->handle, &device); | ||
607 | |||
608 | if (ret_val) | ||
609 | dbg("error adding bus, %x\n", -ret_val); | ||
610 | 476 | ||
611 | return ret_val; | 477 | acpi_bus_get_device(handle, &adev); |
478 | if (adev) | ||
479 | acpi_bus_trim(adev); | ||
612 | } | 480 | } |
613 | 481 | ||
614 | |||
615 | /** | 482 | /** |
616 | * acpiphp_bus_trim - trim a bus from acpi subsystem | 483 | * acpiphp_bus_add - Scan ACPI namespace subtree. |
617 | * @handle: handle to acpi namespace | 484 | * @handle: ACPI object handle to start the scan from. |
618 | */ | 485 | */ |
619 | static int acpiphp_bus_trim(acpi_handle handle) | 486 | static void acpiphp_bus_add(acpi_handle handle) |
620 | { | 487 | { |
621 | struct acpi_device *device; | 488 | struct acpi_device *adev = NULL; |
622 | int retval; | ||
623 | |||
624 | retval = acpi_bus_get_device(handle, &device); | ||
625 | if (retval) { | ||
626 | dbg("acpi_device not found\n"); | ||
627 | return retval; | ||
628 | } | ||
629 | 489 | ||
630 | acpi_bus_trim(device); | 490 | acpiphp_bus_trim(handle); |
631 | return 0; | 491 | acpi_bus_scan(handle); |
492 | acpi_bus_get_device(handle, &adev); | ||
493 | if (adev) | ||
494 | acpi_device_set_power(adev, ACPI_STATE_D0); | ||
632 | } | 495 | } |
633 | 496 | ||
634 | static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) | 497 | static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) |
@@ -645,7 +508,8 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) | |||
645 | params[1].type = ACPI_TYPE_INTEGER; | 508 | params[1].type = ACPI_TYPE_INTEGER; |
646 | params[1].integer.value = 1; | 509 | params[1].integer.value = 1; |
647 | /* _REG is optional, we don't care about if there is failure */ | 510 | /* _REG is optional, we don't care about if there is failure */ |
648 | acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL); | 511 | acpi_evaluate_object(func_to_handle(func), "_REG", &arg_list, |
512 | NULL); | ||
649 | } | 513 | } |
650 | } | 514 | } |
651 | 515 | ||
@@ -653,59 +517,44 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) | |||
653 | { | 517 | { |
654 | struct acpiphp_func *func; | 518 | struct acpiphp_func *func; |
655 | 519 | ||
656 | if (!dev->subordinate) | ||
657 | return; | ||
658 | |||
659 | /* quirk, or pcie could set it already */ | 520 | /* quirk, or pcie could set it already */ |
660 | if (dev->is_hotplug_bridge) | 521 | if (dev->is_hotplug_bridge) |
661 | return; | 522 | return; |
662 | 523 | ||
663 | if (PCI_SLOT(dev->devfn) != slot->device) | ||
664 | return; | ||
665 | |||
666 | list_for_each_entry(func, &slot->funcs, sibling) { | 524 | list_for_each_entry(func, &slot->funcs, sibling) { |
667 | if (PCI_FUNC(dev->devfn) == func->function) { | 525 | if (PCI_FUNC(dev->devfn) == func->function) { |
668 | /* check if this bridge has ejectable slots */ | 526 | dev->is_hotplug_bridge = 1; |
669 | if ((detect_ejectable_slots(func->handle) > 0)) | ||
670 | dev->is_hotplug_bridge = 1; | ||
671 | break; | 527 | break; |
672 | } | 528 | } |
673 | } | 529 | } |
674 | } | 530 | } |
675 | 531 | ||
676 | /** | 532 | /** |
677 | * enable_device - enable, configure a slot | 533 | * enable_slot - enable, configure a slot |
678 | * @slot: slot to be enabled | 534 | * @slot: slot to be enabled |
679 | * | 535 | * |
680 | * This function should be called per *physical slot*, | 536 | * This function should be called per *physical slot*, |
681 | * not per each slot object in ACPI namespace. | 537 | * not per each slot object in ACPI namespace. |
682 | */ | 538 | */ |
683 | static int __ref enable_device(struct acpiphp_slot *slot) | 539 | static void __ref enable_slot(struct acpiphp_slot *slot) |
684 | { | 540 | { |
685 | struct pci_dev *dev; | 541 | struct pci_dev *dev; |
686 | struct pci_bus *bus = slot->bridge->pci_bus; | 542 | struct pci_bus *bus = slot->bus; |
687 | struct acpiphp_func *func; | 543 | struct acpiphp_func *func; |
688 | int num, max, pass; | 544 | int max, pass; |
689 | LIST_HEAD(add_list); | 545 | LIST_HEAD(add_list); |
690 | 546 | ||
691 | if (slot->flags & SLOT_ENABLED) | ||
692 | goto err_exit; | ||
693 | |||
694 | list_for_each_entry(func, &slot->funcs, sibling) | 547 | list_for_each_entry(func, &slot->funcs, sibling) |
695 | acpiphp_bus_add(func); | 548 | acpiphp_bus_add(func_to_handle(func)); |
696 | 549 | ||
697 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); | 550 | pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); |
698 | if (num == 0) { | ||
699 | /* Maybe only part of funcs are added. */ | ||
700 | dbg("No new device found\n"); | ||
701 | goto err_exit; | ||
702 | } | ||
703 | 551 | ||
704 | max = acpiphp_max_busnr(bus); | 552 | max = acpiphp_max_busnr(bus); |
705 | for (pass = 0; pass < 2; pass++) { | 553 | for (pass = 0; pass < 2; pass++) { |
706 | list_for_each_entry(dev, &bus->devices, bus_list) { | 554 | list_for_each_entry(dev, &bus->devices, bus_list) { |
707 | if (PCI_SLOT(dev->devfn) != slot->device) | 555 | if (PCI_SLOT(dev->devfn) != slot->device) |
708 | continue; | 556 | continue; |
557 | |||
709 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 558 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
710 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { | 559 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { |
711 | max = pci_scan_bridge(bus, dev, max, pass); | 560 | max = pci_scan_bridge(bus, dev, max, pass); |
@@ -744,16 +593,12 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
744 | continue; | 593 | continue; |
745 | } | 594 | } |
746 | } | 595 | } |
747 | |||
748 | |||
749 | err_exit: | ||
750 | return 0; | ||
751 | } | 596 | } |
752 | 597 | ||
753 | /* return first device in slot, acquiring a reference on it */ | 598 | /* return first device in slot, acquiring a reference on it */ |
754 | static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) | 599 | static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) |
755 | { | 600 | { |
756 | struct pci_bus *bus = slot->bridge->pci_bus; | 601 | struct pci_bus *bus = slot->bus; |
757 | struct pci_dev *dev; | 602 | struct pci_dev *dev; |
758 | struct pci_dev *ret = NULL; | 603 | struct pci_dev *ret = NULL; |
759 | 604 | ||
@@ -769,16 +614,16 @@ static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) | |||
769 | } | 614 | } |
770 | 615 | ||
771 | /** | 616 | /** |
772 | * disable_device - disable a slot | 617 | * disable_slot - disable a slot |
773 | * @slot: ACPI PHP slot | 618 | * @slot: ACPI PHP slot |
774 | */ | 619 | */ |
775 | static int disable_device(struct acpiphp_slot *slot) | 620 | static void disable_slot(struct acpiphp_slot *slot) |
776 | { | 621 | { |
777 | struct acpiphp_func *func; | 622 | struct acpiphp_func *func; |
778 | struct pci_dev *pdev; | 623 | struct pci_dev *pdev; |
779 | 624 | ||
780 | /* | 625 | /* |
781 | * enable_device() enumerates all functions in this device via | 626 | * enable_slot() enumerates all functions in this device via |
782 | * pci_scan_slot(), whether they have associated ACPI hotplug | 627 | * pci_scan_slot(), whether they have associated ACPI hotplug |
783 | * methods (_EJ0, etc.) or not. Therefore, we remove all functions | 628 | * methods (_EJ0, etc.) or not. Therefore, we remove all functions |
784 | * here. | 629 | * here. |
@@ -788,13 +633,10 @@ static int disable_device(struct acpiphp_slot *slot) | |||
788 | pci_dev_put(pdev); | 633 | pci_dev_put(pdev); |
789 | } | 634 | } |
790 | 635 | ||
791 | list_for_each_entry(func, &slot->funcs, sibling) { | 636 | list_for_each_entry(func, &slot->funcs, sibling) |
792 | acpiphp_bus_trim(func->handle); | 637 | acpiphp_bus_trim(func_to_handle(func)); |
793 | } | ||
794 | 638 | ||
795 | slot->flags &= (~SLOT_ENABLED); | 639 | slot->flags &= (~SLOT_ENABLED); |
796 | |||
797 | return 0; | ||
798 | } | 640 | } |
799 | 641 | ||
800 | 642 | ||
@@ -812,18 +654,21 @@ static int disable_device(struct acpiphp_slot *slot) | |||
812 | */ | 654 | */ |
813 | static unsigned int get_slot_status(struct acpiphp_slot *slot) | 655 | static unsigned int get_slot_status(struct acpiphp_slot *slot) |
814 | { | 656 | { |
815 | acpi_status status; | ||
816 | unsigned long long sta = 0; | 657 | unsigned long long sta = 0; |
817 | u32 dvid; | ||
818 | struct acpiphp_func *func; | 658 | struct acpiphp_func *func; |
819 | 659 | ||
820 | list_for_each_entry(func, &slot->funcs, sibling) { | 660 | list_for_each_entry(func, &slot->funcs, sibling) { |
821 | if (func->flags & FUNC_HAS_STA) { | 661 | if (func->flags & FUNC_HAS_STA) { |
822 | status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); | 662 | acpi_status status; |
663 | |||
664 | status = acpi_evaluate_integer(func_to_handle(func), | ||
665 | "_STA", NULL, &sta); | ||
823 | if (ACPI_SUCCESS(status) && sta) | 666 | if (ACPI_SUCCESS(status) && sta) |
824 | break; | 667 | break; |
825 | } else { | 668 | } else { |
826 | pci_bus_read_config_dword(slot->bridge->pci_bus, | 669 | u32 dvid; |
670 | |||
671 | pci_bus_read_config_dword(slot->bus, | ||
827 | PCI_DEVFN(slot->device, | 672 | PCI_DEVFN(slot->device, |
828 | func->function), | 673 | func->function), |
829 | PCI_VENDOR_ID, &dvid); | 674 | PCI_VENDOR_ID, &dvid); |
@@ -838,34 +683,42 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
838 | } | 683 | } |
839 | 684 | ||
840 | /** | 685 | /** |
841 | * acpiphp_eject_slot - physically eject the slot | 686 | * trim_stale_devices - remove PCI devices that are not responding. |
842 | * @slot: ACPI PHP slot | 687 | * @dev: PCI device to start walking the hierarchy from. |
843 | */ | 688 | */ |
844 | int acpiphp_eject_slot(struct acpiphp_slot *slot) | 689 | static void trim_stale_devices(struct pci_dev *dev) |
845 | { | 690 | { |
846 | acpi_status status; | 691 | acpi_handle handle = ACPI_HANDLE(&dev->dev); |
847 | struct acpiphp_func *func; | 692 | struct pci_bus *bus = dev->subordinate; |
848 | struct acpi_object_list arg_list; | 693 | bool alive = false; |
849 | union acpi_object arg; | ||
850 | 694 | ||
851 | list_for_each_entry(func, &slot->funcs, sibling) { | 695 | if (handle) { |
852 | /* We don't want to call _EJ0 on non-existing functions. */ | 696 | acpi_status status; |
853 | if ((func->flags & FUNC_HAS_EJ0)) { | 697 | unsigned long long sta; |
854 | /* _EJ0 method take one argument */ | 698 | |
855 | arg_list.count = 1; | 699 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
856 | arg_list.pointer = &arg; | 700 | alive = ACPI_SUCCESS(status) && sta == ACPI_STA_ALL; |
857 | arg.type = ACPI_TYPE_INTEGER; | 701 | } |
858 | arg.integer.value = 1; | 702 | if (!alive) { |
859 | 703 | u32 v; | |
860 | status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); | 704 | |
861 | if (ACPI_FAILURE(status)) { | 705 | /* Check if the device responds. */ |
862 | warn("%s: _EJ0 failed\n", __func__); | 706 | alive = pci_bus_read_dev_vendor_id(dev->bus, dev->devfn, &v, 0); |
863 | return -1; | 707 | } |
864 | } else | 708 | if (!alive) { |
865 | break; | 709 | pci_stop_and_remove_bus_device(dev); |
866 | } | 710 | if (handle) |
711 | acpiphp_bus_trim(handle); | ||
712 | } else if (bus) { | ||
713 | struct pci_dev *child, *tmp; | ||
714 | |||
715 | /* The device is a bridge. so check the bus below it. */ | ||
716 | pm_runtime_get_sync(&dev->dev); | ||
717 | list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) | ||
718 | trim_stale_devices(child); | ||
719 | |||
720 | pm_runtime_put(&dev->dev); | ||
867 | } | 721 | } |
868 | return 0; | ||
869 | } | 722 | } |
870 | 723 | ||
871 | /** | 724 | /** |
@@ -875,43 +728,30 @@ int acpiphp_eject_slot(struct acpiphp_slot *slot) | |||
875 | * Iterate over all slots under this bridge and make sure that if a | 728 | * Iterate over all slots under this bridge and make sure that if a |
876 | * card is present they are enabled, and if not they are disabled. | 729 | * card is present they are enabled, and if not they are disabled. |
877 | */ | 730 | */ |
878 | static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) | 731 | static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) |
879 | { | 732 | { |
880 | struct acpiphp_slot *slot; | 733 | struct acpiphp_slot *slot; |
881 | int retval = 0; | ||
882 | int enabled, disabled; | ||
883 | |||
884 | enabled = disabled = 0; | ||
885 | 734 | ||
886 | list_for_each_entry(slot, &bridge->slots, node) { | 735 | list_for_each_entry(slot, &bridge->slots, node) { |
887 | unsigned int status = get_slot_status(slot); | 736 | struct pci_bus *bus = slot->bus; |
888 | if (slot->flags & SLOT_ENABLED) { | 737 | struct pci_dev *dev, *tmp; |
889 | if (status == ACPI_STA_ALL) | 738 | |
890 | continue; | 739 | mutex_lock(&slot->crit_sect); |
891 | retval = acpiphp_disable_slot(slot); | 740 | /* wake up all functions */ |
892 | if (retval) { | 741 | if (get_slot_status(slot) == ACPI_STA_ALL) { |
893 | err("Error occurred in disabling\n"); | 742 | /* remove stale devices if any */ |
894 | goto err_exit; | 743 | list_for_each_entry_safe(dev, tmp, &bus->devices, |
895 | } else { | 744 | bus_list) |
896 | acpiphp_eject_slot(slot); | 745 | if (PCI_SLOT(dev->devfn) == slot->device) |
897 | } | 746 | trim_stale_devices(dev); |
898 | disabled++; | 747 | |
748 | /* configure all functions */ | ||
749 | enable_slot(slot); | ||
899 | } else { | 750 | } else { |
900 | if (status != ACPI_STA_ALL) | 751 | disable_slot(slot); |
901 | continue; | ||
902 | retval = acpiphp_enable_slot(slot); | ||
903 | if (retval) { | ||
904 | err("Error occurred in enabling\n"); | ||
905 | goto err_exit; | ||
906 | } | ||
907 | enabled++; | ||
908 | } | 752 | } |
753 | mutex_unlock(&slot->crit_sect); | ||
909 | } | 754 | } |
910 | |||
911 | dbg("%s: %d enabled, %d disabled\n", __func__, enabled, disabled); | ||
912 | |||
913 | err_exit: | ||
914 | return retval; | ||
915 | } | 755 | } |
916 | 756 | ||
917 | static void acpiphp_set_hpp_values(struct pci_bus *bus) | 757 | static void acpiphp_set_hpp_values(struct pci_bus *bus) |
@@ -950,25 +790,6 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
950 | * ACPI event handlers | 790 | * ACPI event handlers |
951 | */ | 791 | */ |
952 | 792 | ||
953 | static acpi_status | ||
954 | check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
955 | { | ||
956 | struct acpiphp_bridge *bridge; | ||
957 | char objname[64]; | ||
958 | struct acpi_buffer buffer = { .length = sizeof(objname), | ||
959 | .pointer = objname }; | ||
960 | |||
961 | bridge = acpiphp_handle_to_bridge(handle); | ||
962 | if (bridge) { | ||
963 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
964 | dbg("%s: re-enumerating slots under %s\n", | ||
965 | __func__, objname); | ||
966 | acpiphp_check_bridge(bridge); | ||
967 | put_bridge(bridge); | ||
968 | } | ||
969 | return AE_OK ; | ||
970 | } | ||
971 | |||
972 | void acpiphp_check_host_bridge(acpi_handle handle) | 793 | void acpiphp_check_host_bridge(acpi_handle handle) |
973 | { | 794 | { |
974 | struct acpiphp_bridge *bridge; | 795 | struct acpiphp_bridge *bridge; |
@@ -978,27 +799,23 @@ void acpiphp_check_host_bridge(acpi_handle handle) | |||
978 | acpiphp_check_bridge(bridge); | 799 | acpiphp_check_bridge(bridge); |
979 | put_bridge(bridge); | 800 | put_bridge(bridge); |
980 | } | 801 | } |
981 | |||
982 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
983 | ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); | ||
984 | } | 802 | } |
985 | 803 | ||
986 | static void _handle_hotplug_event_bridge(struct work_struct *work) | 804 | static void hotplug_event(acpi_handle handle, u32 type, void *data) |
987 | { | 805 | { |
806 | struct acpiphp_context *context = data; | ||
807 | struct acpiphp_func *func = &context->func; | ||
988 | struct acpiphp_bridge *bridge; | 808 | struct acpiphp_bridge *bridge; |
989 | char objname[64]; | 809 | char objname[64]; |
990 | struct acpi_buffer buffer = { .length = sizeof(objname), | 810 | struct acpi_buffer buffer = { .length = sizeof(objname), |
991 | .pointer = objname }; | 811 | .pointer = objname }; |
992 | struct acpi_hp_work *hp_work; | ||
993 | acpi_handle handle; | ||
994 | u32 type; | ||
995 | 812 | ||
996 | hp_work = container_of(work, struct acpi_hp_work, work); | 813 | mutex_lock(&acpiphp_context_lock); |
997 | handle = hp_work->handle; | 814 | bridge = context->bridge; |
998 | type = hp_work->type; | 815 | if (bridge) |
999 | bridge = (struct acpiphp_bridge *)hp_work->context; | 816 | get_bridge(bridge); |
1000 | 817 | ||
1001 | acpi_scan_lock_acquire(); | 818 | mutex_unlock(&acpiphp_context_lock); |
1002 | 819 | ||
1003 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 820 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
1004 | 821 | ||
@@ -1007,188 +824,129 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
1007 | /* bus re-enumerate */ | 824 | /* bus re-enumerate */ |
1008 | dbg("%s: Bus check notify on %s\n", __func__, objname); | 825 | dbg("%s: Bus check notify on %s\n", __func__, objname); |
1009 | dbg("%s: re-enumerating slots under %s\n", __func__, objname); | 826 | dbg("%s: re-enumerating slots under %s\n", __func__, objname); |
1010 | acpiphp_check_bridge(bridge); | 827 | if (bridge) { |
1011 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | 828 | acpiphp_check_bridge(bridge); |
1012 | ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); | 829 | } else { |
830 | struct acpiphp_slot *slot = func->slot; | ||
831 | |||
832 | mutex_lock(&slot->crit_sect); | ||
833 | enable_slot(slot); | ||
834 | mutex_unlock(&slot->crit_sect); | ||
835 | } | ||
1013 | break; | 836 | break; |
1014 | 837 | ||
1015 | case ACPI_NOTIFY_DEVICE_CHECK: | 838 | case ACPI_NOTIFY_DEVICE_CHECK: |
1016 | /* device check */ | 839 | /* device check */ |
1017 | dbg("%s: Device check notify on %s\n", __func__, objname); | 840 | dbg("%s: Device check notify on %s\n", __func__, objname); |
1018 | acpiphp_check_bridge(bridge); | 841 | if (bridge) |
1019 | break; | 842 | acpiphp_check_bridge(bridge); |
843 | else | ||
844 | acpiphp_check_bridge(func->parent); | ||
1020 | 845 | ||
1021 | case ACPI_NOTIFY_DEVICE_WAKE: | ||
1022 | /* wake event */ | ||
1023 | dbg("%s: Device wake notify on %s\n", __func__, objname); | ||
1024 | break; | 846 | break; |
1025 | 847 | ||
1026 | case ACPI_NOTIFY_EJECT_REQUEST: | 848 | case ACPI_NOTIFY_EJECT_REQUEST: |
1027 | /* request device eject */ | 849 | /* request device eject */ |
1028 | dbg("%s: Device eject notify on %s\n", __func__, objname); | 850 | dbg("%s: Device eject notify on %s\n", __func__, objname); |
1029 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { | 851 | acpiphp_disable_and_eject_slot(func->slot); |
1030 | struct acpiphp_slot *slot; | ||
1031 | slot = bridge->func->slot; | ||
1032 | if (!acpiphp_disable_slot(slot)) | ||
1033 | acpiphp_eject_slot(slot); | ||
1034 | } | ||
1035 | break; | 852 | break; |
853 | } | ||
1036 | 854 | ||
1037 | case ACPI_NOTIFY_FREQUENCY_MISMATCH: | 855 | if (bridge) |
1038 | printk(KERN_ERR "Device %s cannot be configured due" | 856 | put_bridge(bridge); |
1039 | " to a frequency mismatch\n", objname); | 857 | } |
1040 | break; | ||
1041 | 858 | ||
1042 | case ACPI_NOTIFY_BUS_MODE_MISMATCH: | 859 | static void hotplug_event_work(struct work_struct *work) |
1043 | printk(KERN_ERR "Device %s cannot be configured due" | 860 | { |
1044 | " to a bus mode mismatch\n", objname); | 861 | struct acpiphp_context *context; |
1045 | break; | 862 | struct acpi_hp_work *hp_work; |
1046 | 863 | ||
1047 | case ACPI_NOTIFY_POWER_FAULT: | 864 | hp_work = container_of(work, struct acpi_hp_work, work); |
1048 | printk(KERN_ERR "Device %s has suffered a power fault\n", | 865 | context = hp_work->context; |
1049 | objname); | 866 | acpi_scan_lock_acquire(); |
1050 | break; | ||
1051 | 867 | ||
1052 | default: | 868 | hotplug_event(hp_work->handle, hp_work->type, context); |
1053 | warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); | ||
1054 | break; | ||
1055 | } | ||
1056 | 869 | ||
1057 | acpi_scan_lock_release(); | 870 | acpi_scan_lock_release(); |
1058 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | 871 | kfree(hp_work); /* allocated in handle_hotplug_event() */ |
1059 | put_bridge(bridge); | 872 | put_bridge(context->func.parent); |
1060 | } | 873 | } |
1061 | 874 | ||
1062 | /** | 875 | /** |
1063 | * handle_hotplug_event_bridge - handle ACPI event on bridges | 876 | * handle_hotplug_event - handle ACPI hotplug event |
1064 | * @handle: Notify()'ed acpi_handle | 877 | * @handle: Notify()'ed acpi_handle |
1065 | * @type: Notify code | 878 | * @type: Notify code |
1066 | * @context: pointer to acpiphp_bridge structure | 879 | * @data: pointer to acpiphp_context structure |
1067 | * | 880 | * |
1068 | * Handles ACPI event notification on {host,p2p} bridges. | 881 | * Handles ACPI event notification on slots. |
1069 | */ | 882 | */ |
1070 | static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | 883 | static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) |
1071 | void *context) | ||
1072 | { | 884 | { |
1073 | struct acpiphp_bridge *bridge = context; | 885 | struct acpiphp_context *context; |
1074 | |||
1075 | /* | ||
1076 | * Currently the code adds all hotplug events to the kacpid_wq | ||
1077 | * queue when it should add hotplug events to the kacpi_hotplug_wq. | ||
1078 | * The proper way to fix this is to reorganize the code so that | ||
1079 | * drivers (dock, etc.) do not call acpi_os_execute(), etc. | ||
1080 | * For now just re-add this work to the kacpi_hotplug_wq so we | ||
1081 | * don't deadlock on hotplug actions. | ||
1082 | */ | ||
1083 | get_bridge(bridge); | ||
1084 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); | ||
1085 | } | ||
1086 | |||
1087 | static void hotplug_event_func(acpi_handle handle, u32 type, void *context) | ||
1088 | { | ||
1089 | struct acpiphp_func *func = context; | ||
1090 | char objname[64]; | ||
1091 | struct acpi_buffer buffer = { .length = sizeof(objname), | ||
1092 | .pointer = objname }; | ||
1093 | |||
1094 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
1095 | 886 | ||
1096 | switch (type) { | 887 | switch (type) { |
1097 | case ACPI_NOTIFY_BUS_CHECK: | 888 | case ACPI_NOTIFY_BUS_CHECK: |
1098 | /* bus re-enumerate */ | ||
1099 | dbg("%s: Bus check notify on %s\n", __func__, objname); | ||
1100 | acpiphp_enable_slot(func->slot); | ||
1101 | break; | ||
1102 | |||
1103 | case ACPI_NOTIFY_DEVICE_CHECK: | 889 | case ACPI_NOTIFY_DEVICE_CHECK: |
1104 | /* device check : re-enumerate from parent bus */ | ||
1105 | dbg("%s: Device check notify on %s\n", __func__, objname); | ||
1106 | acpiphp_check_bridge(func->slot->bridge); | ||
1107 | break; | ||
1108 | |||
1109 | case ACPI_NOTIFY_DEVICE_WAKE: | ||
1110 | /* wake event */ | ||
1111 | dbg("%s: Device wake notify on %s\n", __func__, objname); | ||
1112 | break; | ||
1113 | |||
1114 | case ACPI_NOTIFY_EJECT_REQUEST: | 890 | case ACPI_NOTIFY_EJECT_REQUEST: |
1115 | /* request device eject */ | ||
1116 | dbg("%s: Device eject notify on %s\n", __func__, objname); | ||
1117 | if (!(acpiphp_disable_slot(func->slot))) | ||
1118 | acpiphp_eject_slot(func->slot); | ||
1119 | break; | 891 | break; |
1120 | 892 | ||
1121 | default: | 893 | case ACPI_NOTIFY_DEVICE_WAKE: |
1122 | warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); | 894 | return; |
1123 | break; | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | static void _handle_hotplug_event_func(struct work_struct *work) | ||
1128 | { | ||
1129 | struct acpi_hp_work *hp_work; | ||
1130 | struct acpiphp_func *func; | ||
1131 | 895 | ||
1132 | hp_work = container_of(work, struct acpi_hp_work, work); | 896 | case ACPI_NOTIFY_FREQUENCY_MISMATCH: |
1133 | func = hp_work->context; | 897 | acpi_handle_err(handle, "Device cannot be configured due " |
1134 | acpi_scan_lock_acquire(); | 898 | "to a frequency mismatch\n"); |
899 | return; | ||
1135 | 900 | ||
1136 | hotplug_event_func(hp_work->handle, hp_work->type, func); | 901 | case ACPI_NOTIFY_BUS_MODE_MISMATCH: |
902 | acpi_handle_err(handle, "Device cannot be configured due " | ||
903 | "to a bus mode mismatch\n"); | ||
904 | return; | ||
1137 | 905 | ||
1138 | acpi_scan_lock_release(); | 906 | case ACPI_NOTIFY_POWER_FAULT: |
1139 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ | 907 | acpi_handle_err(handle, "Device has suffered a power fault\n"); |
1140 | put_bridge(func->slot->bridge); | 908 | return; |
1141 | } | ||
1142 | 909 | ||
1143 | /** | 910 | default: |
1144 | * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) | 911 | acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type); |
1145 | * @handle: Notify()'ed acpi_handle | 912 | return; |
1146 | * @type: Notify code | 913 | } |
1147 | * @context: pointer to acpiphp_func structure | ||
1148 | * | ||
1149 | * Handles ACPI event notification on slots. | ||
1150 | */ | ||
1151 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, | ||
1152 | void *context) | ||
1153 | { | ||
1154 | struct acpiphp_func *func = context; | ||
1155 | 914 | ||
1156 | /* | 915 | mutex_lock(&acpiphp_context_lock); |
1157 | * Currently the code adds all hotplug events to the kacpid_wq | 916 | context = acpiphp_get_context(handle); |
1158 | * queue when it should add hotplug events to the kacpi_hotplug_wq. | 917 | if (context) { |
1159 | * The proper way to fix this is to reorganize the code so that | 918 | get_bridge(context->func.parent); |
1160 | * drivers (dock, etc.) do not call acpi_os_execute(), etc. | 919 | acpiphp_put_context(context); |
1161 | * For now just re-add this work to the kacpi_hotplug_wq so we | 920 | alloc_acpi_hp_work(handle, type, context, hotplug_event_work); |
1162 | * don't deadlock on hotplug actions. | 921 | } |
1163 | */ | 922 | mutex_unlock(&acpiphp_context_lock); |
1164 | get_bridge(func->slot->bridge); | ||
1165 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); | ||
1166 | } | 923 | } |
1167 | 924 | ||
1168 | /* | 925 | /* |
1169 | * Create hotplug slots for the PCI bus. | 926 | * Create hotplug slots for the PCI bus. |
1170 | * It should always return 0 to avoid skipping following notifiers. | 927 | * It should always return 0 to avoid skipping following notifiers. |
1171 | */ | 928 | */ |
1172 | void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) | 929 | void acpiphp_enumerate_slots(struct pci_bus *bus) |
1173 | { | 930 | { |
1174 | acpi_handle dummy_handle; | ||
1175 | struct acpiphp_bridge *bridge; | 931 | struct acpiphp_bridge *bridge; |
932 | acpi_handle handle; | ||
933 | acpi_status status; | ||
1176 | 934 | ||
1177 | if (acpiphp_disabled) | 935 | if (acpiphp_disabled) |
1178 | return; | 936 | return; |
1179 | 937 | ||
1180 | if (detect_ejectable_slots(handle) <= 0) | 938 | handle = ACPI_HANDLE(bus->bridge); |
939 | if (!handle) | ||
1181 | return; | 940 | return; |
1182 | 941 | ||
1183 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | 942 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); |
1184 | if (bridge == NULL) { | 943 | if (!bridge) { |
1185 | err("out of memory\n"); | 944 | acpi_handle_err(handle, "No memory for bridge object\n"); |
1186 | return; | 945 | return; |
1187 | } | 946 | } |
1188 | 947 | ||
1189 | INIT_LIST_HEAD(&bridge->slots); | 948 | INIT_LIST_HEAD(&bridge->slots); |
1190 | kref_init(&bridge->ref); | 949 | kref_init(&bridge->ref); |
1191 | bridge->handle = handle; | ||
1192 | bridge->pci_dev = pci_dev_get(bus->self); | 950 | bridge->pci_dev = pci_dev_get(bus->self); |
1193 | bridge->pci_bus = bus; | 951 | bridge->pci_bus = bus; |
1194 | 952 | ||
@@ -1199,31 +957,62 @@ void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) | |||
1199 | */ | 957 | */ |
1200 | get_device(&bus->dev); | 958 | get_device(&bus->dev); |
1201 | 959 | ||
1202 | if (!pci_is_root_bus(bridge->pci_bus) && | 960 | if (!pci_is_root_bus(bridge->pci_bus)) { |
1203 | ACPI_SUCCESS(acpi_get_handle(bridge->handle, | 961 | struct acpiphp_context *context; |
1204 | "_EJ0", &dummy_handle))) { | 962 | |
1205 | dbg("found ejectable p2p bridge\n"); | 963 | /* |
1206 | bridge->flags |= BRIDGE_HAS_EJ0; | 964 | * This bridge should have been registered as a hotplug function |
1207 | bridge->func = acpiphp_bridge_handle_to_function(handle); | 965 | * under its parent, so the context has to be there. If not, we |
966 | * are in deep goo. | ||
967 | */ | ||
968 | mutex_lock(&acpiphp_context_lock); | ||
969 | context = acpiphp_get_context(handle); | ||
970 | if (WARN_ON(!context)) { | ||
971 | mutex_unlock(&acpiphp_context_lock); | ||
972 | put_device(&bus->dev); | ||
973 | kfree(bridge); | ||
974 | return; | ||
975 | } | ||
976 | bridge->context = context; | ||
977 | context->bridge = bridge; | ||
978 | /* Get a reference to the parent bridge. */ | ||
979 | get_bridge(context->func.parent); | ||
980 | mutex_unlock(&acpiphp_context_lock); | ||
1208 | } | 981 | } |
1209 | 982 | ||
1210 | init_bridge_misc(bridge); | 983 | /* must be added to the list prior to calling register_slot */ |
984 | mutex_lock(&bridge_mutex); | ||
985 | list_add(&bridge->list, &bridge_list); | ||
986 | mutex_unlock(&bridge_mutex); | ||
987 | |||
988 | /* register all slot objects under this bridge */ | ||
989 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, | ||
990 | register_slot, NULL, bridge, NULL); | ||
991 | if (ACPI_FAILURE(status)) { | ||
992 | acpi_handle_err(handle, "failed to register slots\n"); | ||
993 | cleanup_bridge(bridge); | ||
994 | put_bridge(bridge); | ||
995 | } | ||
1211 | } | 996 | } |
1212 | 997 | ||
1213 | /* Destroy hotplug slots associated with the PCI bus */ | 998 | /* Destroy hotplug slots associated with the PCI bus */ |
1214 | void acpiphp_remove_slots(struct pci_bus *bus) | 999 | void acpiphp_remove_slots(struct pci_bus *bus) |
1215 | { | 1000 | { |
1216 | struct acpiphp_bridge *bridge, *tmp; | 1001 | struct acpiphp_bridge *bridge; |
1217 | 1002 | ||
1218 | if (acpiphp_disabled) | 1003 | if (acpiphp_disabled) |
1219 | return; | 1004 | return; |
1220 | 1005 | ||
1221 | list_for_each_entry_safe(bridge, tmp, &bridge_list, list) | 1006 | mutex_lock(&bridge_mutex); |
1007 | list_for_each_entry(bridge, &bridge_list, list) | ||
1222 | if (bridge->pci_bus == bus) { | 1008 | if (bridge->pci_bus == bus) { |
1009 | mutex_unlock(&bridge_mutex); | ||
1223 | cleanup_bridge(bridge); | 1010 | cleanup_bridge(bridge); |
1224 | put_bridge(bridge); | 1011 | put_bridge(bridge); |
1225 | break; | 1012 | return; |
1226 | } | 1013 | } |
1014 | |||
1015 | mutex_unlock(&bridge_mutex); | ||
1227 | } | 1016 | } |
1228 | 1017 | ||
1229 | /** | 1018 | /** |
@@ -1232,51 +1021,39 @@ void acpiphp_remove_slots(struct pci_bus *bus) | |||
1232 | */ | 1021 | */ |
1233 | int acpiphp_enable_slot(struct acpiphp_slot *slot) | 1022 | int acpiphp_enable_slot(struct acpiphp_slot *slot) |
1234 | { | 1023 | { |
1235 | int retval; | ||
1236 | |||
1237 | mutex_lock(&slot->crit_sect); | 1024 | mutex_lock(&slot->crit_sect); |
1025 | /* configure all functions */ | ||
1026 | if (!(slot->flags & SLOT_ENABLED)) | ||
1027 | enable_slot(slot); | ||
1238 | 1028 | ||
1239 | /* wake up all functions */ | ||
1240 | retval = power_on_slot(slot); | ||
1241 | if (retval) | ||
1242 | goto err_exit; | ||
1243 | |||
1244 | if (get_slot_status(slot) == ACPI_STA_ALL) { | ||
1245 | /* configure all functions */ | ||
1246 | retval = enable_device(slot); | ||
1247 | if (retval) | ||
1248 | power_off_slot(slot); | ||
1249 | } else { | ||
1250 | dbg("%s: Slot status is not ACPI_STA_ALL\n", __func__); | ||
1251 | power_off_slot(slot); | ||
1252 | } | ||
1253 | |||
1254 | err_exit: | ||
1255 | mutex_unlock(&slot->crit_sect); | 1029 | mutex_unlock(&slot->crit_sect); |
1256 | return retval; | 1030 | return 0; |
1257 | } | 1031 | } |
1258 | 1032 | ||
1259 | /** | 1033 | /** |
1260 | * acpiphp_disable_slot - power off slot | 1034 | * acpiphp_disable_and_eject_slot - power off and eject slot |
1261 | * @slot: ACPI PHP slot | 1035 | * @slot: ACPI PHP slot |
1262 | */ | 1036 | */ |
1263 | int acpiphp_disable_slot(struct acpiphp_slot *slot) | 1037 | int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot) |
1264 | { | 1038 | { |
1039 | struct acpiphp_func *func; | ||
1265 | int retval = 0; | 1040 | int retval = 0; |
1266 | 1041 | ||
1267 | mutex_lock(&slot->crit_sect); | 1042 | mutex_lock(&slot->crit_sect); |
1268 | 1043 | ||
1269 | /* unconfigure all functions */ | 1044 | /* unconfigure all functions */ |
1270 | retval = disable_device(slot); | 1045 | disable_slot(slot); |
1271 | if (retval) | 1046 | |
1272 | goto err_exit; | 1047 | list_for_each_entry(func, &slot->funcs, sibling) |
1048 | if (func->flags & FUNC_HAS_EJ0) { | ||
1049 | acpi_handle handle = func_to_handle(func); | ||
1273 | 1050 | ||
1274 | /* power off all functions */ | 1051 | if (ACPI_FAILURE(acpi_evaluate_ej0(handle))) |
1275 | retval = power_off_slot(slot); | 1052 | acpi_handle_err(handle, "_EJ0 failed\n"); |
1276 | if (retval) | 1053 | |
1277 | goto err_exit; | 1054 | break; |
1055 | } | ||
1278 | 1056 | ||
1279 | err_exit: | ||
1280 | mutex_unlock(&slot->crit_sect); | 1057 | mutex_unlock(&slot->crit_sect); |
1281 | return retval; | 1058 | return retval; |
1282 | } | 1059 | } |
@@ -1288,7 +1065,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) | |||
1288 | */ | 1065 | */ |
1289 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot) | 1066 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot) |
1290 | { | 1067 | { |
1291 | return (slot->flags & SLOT_POWEREDON); | 1068 | return (slot->flags & SLOT_ENABLED); |
1292 | } | 1069 | } |
1293 | 1070 | ||
1294 | 1071 | ||
@@ -1298,11 +1075,7 @@ u8 acpiphp_get_power_status(struct acpiphp_slot *slot) | |||
1298 | */ | 1075 | */ |
1299 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) | 1076 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) |
1300 | { | 1077 | { |
1301 | unsigned int sta; | 1078 | return !(get_slot_status(slot) & ACPI_STA_DEVICE_UI); |
1302 | |||
1303 | sta = get_slot_status(slot); | ||
1304 | |||
1305 | return (sta & ACPI_STA_DEVICE_UI) ? 0 : 1; | ||
1306 | } | 1079 | } |
1307 | 1080 | ||
1308 | 1081 | ||
@@ -1312,9 +1085,5 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) | |||
1312 | */ | 1085 | */ |
1313 | u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot) | 1086 | u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot) |
1314 | { | 1087 | { |
1315 | unsigned int sta; | 1088 | return !!get_slot_status(slot); |
1316 | |||
1317 | sta = get_slot_status(slot); | ||
1318 | |||
1319 | return (sta == 0) ? 0 : 1; | ||
1320 | } | 1089 | } |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index c35e8ad6db01..2f5786c8522c 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -66,7 +66,7 @@ do { \ | |||
66 | #define IBM_HARDWARE_ID1 "IBM37D0" | 66 | #define IBM_HARDWARE_ID1 "IBM37D0" |
67 | #define IBM_HARDWARE_ID2 "IBM37D4" | 67 | #define IBM_HARDWARE_ID2 "IBM37D4" |
68 | 68 | ||
69 | #define hpslot_to_sun(A) (((struct slot *)((A)->private))->acpi_slot->sun) | 69 | #define hpslot_to_sun(A) (((struct slot *)((A)->private))->sun) |
70 | 70 | ||
71 | /* union apci_descriptor - allows access to the | 71 | /* union apci_descriptor - allows access to the |
72 | * various device descriptors that are embedded in the | 72 | * various device descriptors that are embedded in the |
@@ -270,7 +270,6 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context) | |||
270 | 270 | ||
271 | if (subevent == 0x80) { | 271 | if (subevent == 0x80) { |
272 | dbg("%s: generationg bus event\n", __func__); | 272 | dbg("%s: generationg bus event\n", __func__); |
273 | acpi_bus_generate_proc_event(note->device, note->event, detail); | ||
274 | acpi_bus_generate_netlink_event(note->device->pnp.device_class, | 273 | acpi_bus_generate_netlink_event(note->device->pnp.device_class, |
275 | dev_name(¬e->device->dev), | 274 | dev_name(¬e->device->dev), |
276 | note->event, detail); | 275 | note->event, detail); |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 01e264fb50e0..7c29ee4ed0ae 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -210,7 +210,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
210 | } | 210 | } |
211 | 211 | ||
212 | if (!error) | 212 | if (!error) |
213 | dev_info(&dev->dev, "power state changed by ACPI to %s\n", | 213 | dev_dbg(&dev->dev, "power state changed by ACPI to %s\n", |
214 | acpi_power_state_string(state_conv[state])); | 214 | acpi_power_state_string(state_conv[state])); |
215 | 215 | ||
216 | return error; | 216 | return error; |
@@ -290,24 +290,16 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { | |||
290 | 290 | ||
291 | void acpi_pci_add_bus(struct pci_bus *bus) | 291 | void acpi_pci_add_bus(struct pci_bus *bus) |
292 | { | 292 | { |
293 | acpi_handle handle = NULL; | 293 | if (acpi_pci_disabled || !bus->bridge) |
294 | |||
295 | if (bus->bridge) | ||
296 | handle = ACPI_HANDLE(bus->bridge); | ||
297 | if (acpi_pci_disabled || handle == NULL) | ||
298 | return; | 294 | return; |
299 | 295 | ||
300 | acpi_pci_slot_enumerate(bus, handle); | 296 | acpi_pci_slot_enumerate(bus); |
301 | acpiphp_enumerate_slots(bus, handle); | 297 | acpiphp_enumerate_slots(bus); |
302 | } | 298 | } |
303 | 299 | ||
304 | void acpi_pci_remove_bus(struct pci_bus *bus) | 300 | void acpi_pci_remove_bus(struct pci_bus *bus) |
305 | { | 301 | { |
306 | /* | 302 | if (acpi_pci_disabled || !bus->bridge) |
307 | * bus->bridge->acpi_node.handle has already been reset to NULL | ||
308 | * when acpi_pci_remove_bus() is called, so don't check ACPI handle. | ||
309 | */ | ||
310 | if (acpi_pci_disabled) | ||
311 | return; | 303 | return; |
312 | 304 | ||
313 | acpiphp_remove_slots(bus); | 305 | acpiphp_remove_slots(bus); |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 8e268da6fdbd..0e9c169b42f8 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -1543,7 +1543,6 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event) | |||
1543 | 1543 | ||
1544 | /* TODO Find a better way to handle events count. */ | 1544 | /* TODO Find a better way to handle events count. */ |
1545 | count = asus->event_count[event % 128]++; | 1545 | count = asus->event_count[event % 128]++; |
1546 | acpi_bus_generate_proc_event(asus->device, event, count); | ||
1547 | acpi_bus_generate_netlink_event(asus->device->pnp.device_class, | 1546 | acpi_bus_generate_netlink_event(asus->device->pnp.device_class, |
1548 | dev_name(&asus->device->dev), event, | 1547 | dev_name(&asus->device->dev), event, |
1549 | count); | 1548 | count); |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 5d26e70bed6c..a6afd4108beb 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -1269,7 +1269,6 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event) | |||
1269 | if (event > ACPI_MAX_SYS_NOTIFY) | 1269 | if (event > ACPI_MAX_SYS_NOTIFY) |
1270 | return; | 1270 | return; |
1271 | count = eeepc->event_count[event % 128]++; | 1271 | count = eeepc->event_count[event % 128]++; |
1272 | acpi_bus_generate_proc_event(device, event, count); | ||
1273 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 1272 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
1274 | dev_name(&device->dev), event, | 1273 | dev_name(&device->dev), event, |
1275 | count); | 1274 | count); |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 1c9386e7c58c..52b8a97efde1 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -773,8 +773,6 @@ static void acpi_fujitsu_notify(struct acpi_device *device, u32 event) | |||
773 | else | 773 | else |
774 | set_lcd_level(newb); | 774 | set_lcd_level(newb); |
775 | } | 775 | } |
776 | acpi_bus_generate_proc_event(fujitsu->dev, | ||
777 | ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0); | ||
778 | keycode = KEY_BRIGHTNESSUP; | 776 | keycode = KEY_BRIGHTNESSUP; |
779 | } else if (oldb > newb) { | 777 | } else if (oldb > newb) { |
780 | if (disable_brightness_adjust != 1) { | 778 | if (disable_brightness_adjust != 1) { |
@@ -783,8 +781,6 @@ static void acpi_fujitsu_notify(struct acpi_device *device, u32 event) | |||
783 | else | 781 | else |
784 | set_lcd_level(newb); | 782 | set_lcd_level(newb); |
785 | } | 783 | } |
786 | acpi_bus_generate_proc_event(fujitsu->dev, | ||
787 | ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0); | ||
788 | keycode = KEY_BRIGHTNESSDOWN; | 784 | keycode = KEY_BRIGHTNESSDOWN; |
789 | } | 785 | } |
790 | break; | 786 | break; |
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 4add9a31bf60..984253da365d 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
@@ -464,9 +464,6 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) | |||
464 | "error getting hotkey status\n")); | 464 | "error getting hotkey status\n")); |
465 | return; | 465 | return; |
466 | } | 466 | } |
467 | |||
468 | acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result); | ||
469 | |||
470 | if (!sparse_keymap_report_event(hotk_input_dev, | 467 | if (!sparse_keymap_report_event(hotk_input_dev, |
471 | result & 0xf, result & 0x80, false)) | 468 | result & 0xf, result & 0x80, false)) |
472 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 469 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 3a1b6bf326a8..d3fd52036fd6 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -1275,9 +1275,6 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) | |||
1275 | ev_type = HOTKEY; | 1275 | ev_type = HOTKEY; |
1276 | sony_laptop_report_input_event(real_ev); | 1276 | sony_laptop_report_input_event(real_ev); |
1277 | } | 1277 | } |
1278 | |||
1279 | acpi_bus_generate_proc_event(sony_nc_acpi_device, ev_type, real_ev); | ||
1280 | |||
1281 | acpi_bus_generate_netlink_event(sony_nc_acpi_device->pnp.device_class, | 1278 | acpi_bus_generate_netlink_event(sony_nc_acpi_device->pnp.device_class, |
1282 | dev_name(&sony_nc_acpi_device->dev), ev_type, real_ev); | 1279 | dev_name(&sony_nc_acpi_device->dev), ev_type, real_ev); |
1283 | } | 1280 | } |
@@ -4246,7 +4243,6 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) | |||
4246 | 4243 | ||
4247 | found: | 4244 | found: |
4248 | sony_laptop_report_input_event(device_event); | 4245 | sony_laptop_report_input_event(device_event); |
4249 | acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event); | ||
4250 | sonypi_compat_report_event(device_event); | 4246 | sonypi_compat_report_event(device_event); |
4251 | return IRQ_HANDLED; | 4247 | return IRQ_HANDLED; |
4252 | } | 4248 | } |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 54d31c0a9840..be67e5e28d18 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -2022,8 +2022,6 @@ static u32 hotkey_driver_mask; /* events needed by the driver */ | |||
2022 | static u32 hotkey_user_mask; /* events visible to userspace */ | 2022 | static u32 hotkey_user_mask; /* events visible to userspace */ |
2023 | static u32 hotkey_acpi_mask; /* events enabled in firmware */ | 2023 | static u32 hotkey_acpi_mask; /* events enabled in firmware */ |
2024 | 2024 | ||
2025 | static unsigned int hotkey_report_mode; | ||
2026 | |||
2027 | static u16 *hotkey_keycode_map; | 2025 | static u16 *hotkey_keycode_map; |
2028 | 2026 | ||
2029 | static struct attribute_set *hotkey_dev_attributes; | 2027 | static struct attribute_set *hotkey_dev_attributes; |
@@ -2282,10 +2280,6 @@ static struct tp_acpi_drv_struct ibm_hotkey_acpidriver; | |||
2282 | static void tpacpi_hotkey_send_key(unsigned int scancode) | 2280 | static void tpacpi_hotkey_send_key(unsigned int scancode) |
2283 | { | 2281 | { |
2284 | tpacpi_input_send_key_masked(scancode); | 2282 | tpacpi_input_send_key_masked(scancode); |
2285 | if (hotkey_report_mode < 2) { | ||
2286 | acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, | ||
2287 | 0x80, TP_HKEY_EV_HOTKEY_BASE + scancode); | ||
2288 | } | ||
2289 | } | 2283 | } |
2290 | 2284 | ||
2291 | static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m) | 2285 | static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m) |
@@ -2882,18 +2876,6 @@ static void hotkey_tablet_mode_notify_change(void) | |||
2882 | "hotkey_tablet_mode"); | 2876 | "hotkey_tablet_mode"); |
2883 | } | 2877 | } |
2884 | 2878 | ||
2885 | /* sysfs hotkey report_mode -------------------------------------------- */ | ||
2886 | static ssize_t hotkey_report_mode_show(struct device *dev, | ||
2887 | struct device_attribute *attr, | ||
2888 | char *buf) | ||
2889 | { | ||
2890 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
2891 | (hotkey_report_mode != 0) ? hotkey_report_mode : 1); | ||
2892 | } | ||
2893 | |||
2894 | static struct device_attribute dev_attr_hotkey_report_mode = | ||
2895 | __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL); | ||
2896 | |||
2897 | /* sysfs wakeup reason (pollable) -------------------------------------- */ | 2879 | /* sysfs wakeup reason (pollable) -------------------------------------- */ |
2898 | static ssize_t hotkey_wakeup_reason_show(struct device *dev, | 2880 | static ssize_t hotkey_wakeup_reason_show(struct device *dev, |
2899 | struct device_attribute *attr, | 2881 | struct device_attribute *attr, |
@@ -2935,7 +2917,6 @@ static struct attribute *hotkey_attributes[] __initdata = { | |||
2935 | &dev_attr_hotkey_enable.attr, | 2917 | &dev_attr_hotkey_enable.attr, |
2936 | &dev_attr_hotkey_bios_enabled.attr, | 2918 | &dev_attr_hotkey_bios_enabled.attr, |
2937 | &dev_attr_hotkey_bios_mask.attr, | 2919 | &dev_attr_hotkey_bios_mask.attr, |
2938 | &dev_attr_hotkey_report_mode.attr, | ||
2939 | &dev_attr_hotkey_wakeup_reason.attr, | 2920 | &dev_attr_hotkey_wakeup_reason.attr, |
2940 | &dev_attr_hotkey_wakeup_hotunplug_complete.attr, | 2921 | &dev_attr_hotkey_wakeup_hotunplug_complete.attr, |
2941 | &dev_attr_hotkey_mask.attr, | 2922 | &dev_attr_hotkey_mask.attr, |
@@ -3439,11 +3420,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3439 | "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n", | 3420 | "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n", |
3440 | hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask); | 3421 | hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask); |
3441 | 3422 | ||
3442 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | ||
3443 | "legacy ibm/hotkey event reporting over procfs %s\n", | ||
3444 | (hotkey_report_mode < 2) ? | ||
3445 | "enabled" : "disabled"); | ||
3446 | |||
3447 | tpacpi_inputdev->open = &hotkey_inputdev_open; | 3423 | tpacpi_inputdev->open = &hotkey_inputdev_open; |
3448 | tpacpi_inputdev->close = &hotkey_inputdev_close; | 3424 | tpacpi_inputdev->close = &hotkey_inputdev_close; |
3449 | 3425 | ||
@@ -3737,13 +3713,6 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3737 | "event happened to %s\n", TPACPI_MAIL); | 3713 | "event happened to %s\n", TPACPI_MAIL); |
3738 | } | 3714 | } |
3739 | 3715 | ||
3740 | /* Legacy events */ | ||
3741 | if (!ignore_acpi_ev && | ||
3742 | (send_acpi_ev || hotkey_report_mode < 2)) { | ||
3743 | acpi_bus_generate_proc_event(ibm->acpi->device, | ||
3744 | event, hkey); | ||
3745 | } | ||
3746 | |||
3747 | /* netlink events */ | 3716 | /* netlink events */ |
3748 | if (!ignore_acpi_ev && send_acpi_ev) { | 3717 | if (!ignore_acpi_ev && send_acpi_ev) { |
3749 | acpi_bus_generate_netlink_event( | 3718 | acpi_bus_generate_netlink_event( |
@@ -8840,11 +8809,6 @@ module_param(brightness_enable, uint, 0444); | |||
8840 | MODULE_PARM_DESC(brightness_enable, | 8809 | MODULE_PARM_DESC(brightness_enable, |
8841 | "Enables backlight control when 1, disables when 0"); | 8810 | "Enables backlight control when 1, disables when 0"); |
8842 | 8811 | ||
8843 | module_param(hotkey_report_mode, uint, 0444); | ||
8844 | MODULE_PARM_DESC(hotkey_report_mode, | ||
8845 | "used for backwards compatibility with userspace, " | ||
8846 | "see documentation"); | ||
8847 | |||
8848 | #ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT | 8812 | #ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT |
8849 | module_param_named(volume_mode, volume_mode, uint, 0444); | 8813 | module_param_named(volume_mode, volume_mode, uint, 0444); |
8850 | MODULE_PARM_DESC(volume_mode, | 8814 | MODULE_PARM_DESC(volume_mode, |
@@ -8975,10 +8939,6 @@ static int __init thinkpad_acpi_module_init(void) | |||
8975 | 8939 | ||
8976 | tpacpi_lifecycle = TPACPI_LIFE_INIT; | 8940 | tpacpi_lifecycle = TPACPI_LIFE_INIT; |
8977 | 8941 | ||
8978 | /* Parameter checking */ | ||
8979 | if (hotkey_report_mode > 2) | ||
8980 | return -EINVAL; | ||
8981 | |||
8982 | /* Driver-level probe */ | 8942 | /* Driver-level probe */ |
8983 | 8943 | ||
8984 | ret = get_thinkpad_model_data(&thinkpad_id); | 8944 | ret = get_thinkpad_model_data(&thinkpad_id); |
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 00e94032531a..12adb43a0693 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -154,7 +154,7 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv) | |||
154 | return 1; | 154 | return 1; |
155 | } | 155 | } |
156 | 156 | ||
157 | static int pnp_bus_suspend(struct device *dev, pm_message_t state) | 157 | static int __pnp_bus_suspend(struct device *dev, pm_message_t state) |
158 | { | 158 | { |
159 | struct pnp_dev *pnp_dev = to_pnp_dev(dev); | 159 | struct pnp_dev *pnp_dev = to_pnp_dev(dev); |
160 | struct pnp_driver *pnp_drv = pnp_dev->driver; | 160 | struct pnp_driver *pnp_drv = pnp_dev->driver; |
@@ -180,6 +180,16 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state) | |||
180 | return 0; | 180 | return 0; |
181 | } | 181 | } |
182 | 182 | ||
183 | static int pnp_bus_suspend(struct device *dev) | ||
184 | { | ||
185 | return __pnp_bus_suspend(dev, PMSG_SUSPEND); | ||
186 | } | ||
187 | |||
188 | static int pnp_bus_freeze(struct device *dev) | ||
189 | { | ||
190 | return __pnp_bus_suspend(dev, PMSG_FREEZE); | ||
191 | } | ||
192 | |||
183 | static int pnp_bus_resume(struct device *dev) | 193 | static int pnp_bus_resume(struct device *dev) |
184 | { | 194 | { |
185 | struct pnp_dev *pnp_dev = to_pnp_dev(dev); | 195 | struct pnp_dev *pnp_dev = to_pnp_dev(dev); |
@@ -210,14 +220,19 @@ static int pnp_bus_resume(struct device *dev) | |||
210 | return 0; | 220 | return 0; |
211 | } | 221 | } |
212 | 222 | ||
223 | static const struct dev_pm_ops pnp_bus_dev_pm_ops = { | ||
224 | .suspend = pnp_bus_suspend, | ||
225 | .freeze = pnp_bus_freeze, | ||
226 | .resume = pnp_bus_resume, | ||
227 | }; | ||
228 | |||
213 | struct bus_type pnp_bus_type = { | 229 | struct bus_type pnp_bus_type = { |
214 | .name = "pnp", | 230 | .name = "pnp", |
215 | .match = pnp_bus_match, | 231 | .match = pnp_bus_match, |
216 | .probe = pnp_device_probe, | 232 | .probe = pnp_device_probe, |
217 | .remove = pnp_device_remove, | 233 | .remove = pnp_device_remove, |
218 | .shutdown = pnp_device_shutdown, | 234 | .shutdown = pnp_device_shutdown, |
219 | .suspend = pnp_bus_suspend, | 235 | .pm = &pnp_bus_dev_pm_ops, |
220 | .resume = pnp_bus_resume, | ||
221 | .dev_attrs = pnp_interface_attrs, | 236 | .dev_attrs = pnp_interface_attrs, |
222 | }; | 237 | }; |
223 | 238 | ||
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 55cd459a3908..34049b0b4c73 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -131,7 +131,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) | |||
131 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ | 131 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ |
132 | ret = 0; | 132 | ret = 0; |
133 | if (acpi_bus_power_manageable(handle)) | 133 | if (acpi_bus_power_manageable(handle)) |
134 | acpi_bus_set_power(handle, ACPI_STATE_D3); | 134 | acpi_bus_set_power(handle, ACPI_STATE_D3_COLD); |
135 | /* continue even if acpi_bus_set_power() fails */ | 135 | /* continue even if acpi_bus_set_power() fails */ |
136 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) | 136 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) |
137 | ret = -ENODEV; | 137 | ret = -ENODEV; |
@@ -174,10 +174,10 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) | |||
174 | 174 | ||
175 | if (acpi_bus_power_manageable(handle)) { | 175 | if (acpi_bus_power_manageable(handle)) { |
176 | int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL, | 176 | int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL, |
177 | ACPI_STATE_D3); | 177 | ACPI_STATE_D3_COLD); |
178 | if (power_state < 0) | 178 | if (power_state < 0) |
179 | power_state = (state.event == PM_EVENT_ON) ? | 179 | power_state = (state.event == PM_EVENT_ON) ? |
180 | ACPI_STATE_D0 : ACPI_STATE_D3; | 180 | ACPI_STATE_D0 : ACPI_STATE_D3_COLD; |
181 | 181 | ||
182 | /* | 182 | /* |
183 | * acpi_bus_set_power() often fails (keyboard port can't be | 183 | * acpi_bus_set_power() often fails (keyboard port can't be |
diff --git a/drivers/xen/acpi.c b/drivers/xen/acpi.c index 119d42a2bf57..90307c0b630c 100644 --- a/drivers/xen/acpi.c +++ b/drivers/xen/acpi.c | |||
@@ -35,28 +35,43 @@ | |||
35 | #include <asm/xen/hypercall.h> | 35 | #include <asm/xen/hypercall.h> |
36 | #include <asm/xen/hypervisor.h> | 36 | #include <asm/xen/hypervisor.h> |
37 | 37 | ||
38 | int xen_acpi_notify_hypervisor_state(u8 sleep_state, | 38 | static int xen_acpi_notify_hypervisor_state(u8 sleep_state, |
39 | u32 pm1a_cnt, u32 pm1b_cnt) | 39 | u32 val_a, u32 val_b, |
40 | bool extended) | ||
40 | { | 41 | { |
42 | unsigned int bits = extended ? 8 : 16; | ||
43 | |||
41 | struct xen_platform_op op = { | 44 | struct xen_platform_op op = { |
42 | .cmd = XENPF_enter_acpi_sleep, | 45 | .cmd = XENPF_enter_acpi_sleep, |
43 | .interface_version = XENPF_INTERFACE_VERSION, | 46 | .interface_version = XENPF_INTERFACE_VERSION, |
44 | .u = { | 47 | .u.enter_acpi_sleep = { |
45 | .enter_acpi_sleep = { | 48 | .val_a = (u16)val_a, |
46 | .pm1a_cnt_val = (u16)pm1a_cnt, | 49 | .val_b = (u16)val_b, |
47 | .pm1b_cnt_val = (u16)pm1b_cnt, | 50 | .sleep_state = sleep_state, |
48 | .sleep_state = sleep_state, | 51 | .flags = extended ? XENPF_ACPI_SLEEP_EXTENDED : 0, |
49 | }, | ||
50 | }, | 52 | }, |
51 | }; | 53 | }; |
52 | 54 | ||
53 | if ((pm1a_cnt & 0xffff0000) || (pm1b_cnt & 0xffff0000)) { | 55 | if (WARN((val_a & (~0 << bits)) || (val_b & (~0 << bits)), |
54 | WARN(1, "Using more than 16bits of PM1A/B 0x%x/0x%x!" | 56 | "Using more than %u bits of sleep control values %#x/%#x!" |
55 | "Email xen-devel@lists.xensource.com Thank you.\n", \ | 57 | "Email xen-devel@lists.xen.org - Thank you.\n", \ |
56 | pm1a_cnt, pm1b_cnt); | 58 | bits, val_a, val_b)) |
57 | return -1; | 59 | return -1; |
58 | } | ||
59 | 60 | ||
60 | HYPERVISOR_dom0_op(&op); | 61 | HYPERVISOR_dom0_op(&op); |
61 | return 1; | 62 | return 1; |
62 | } | 63 | } |
64 | |||
65 | int xen_acpi_notify_hypervisor_sleep(u8 sleep_state, | ||
66 | u32 pm1a_cnt, u32 pm1b_cnt) | ||
67 | { | ||
68 | return xen_acpi_notify_hypervisor_state(sleep_state, pm1a_cnt, | ||
69 | pm1b_cnt, false); | ||
70 | } | ||
71 | |||
72 | int xen_acpi_notify_hypervisor_extended_sleep(u8 sleep_state, | ||
73 | u32 val_a, u32 val_b) | ||
74 | { | ||
75 | return xen_acpi_notify_hypervisor_state(sleep_state, val_a, | ||
76 | val_b, true); | ||
77 | } | ||