diff options
author | Lv Zheng <lv.zheng@intel.com> | 2016-09-07 02:07:24 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-09-09 20:43:03 -0400 |
commit | ac0f06ebb815dabe42f2b2886ee9f879a2170ce4 (patch) | |
tree | 59cd81530337d1b16b388dadf0586aeb36bd8e48 /drivers/acpi/acpica | |
parent | 441ad11d078f35093ceaf510742df423c2d89a3b (diff) |
ACPICA: Tables: Tune table mutex to be a leaf lock
ACPICA commit f564d57c6501b97a2871f0b4c048e79910f71783
This patch tunes MTX_TABLES into a leaf lock by always ensuring it is
released before holding other locks.
This patch also collects all table loading related functions into
acpi_tb_load_table() (invoked by load_table opcode) and
acpi_tb_install_and_load_table() (invoked by Load opcode and acpi_load_table()) so
that we can have lock tuning code collected at the boundary of these 2
functions. Lv Zheng.
Link: https://github.com/acpica/acpica/commit/f564d57c
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Dutch Guy <lucht_piloot@gmx.net>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/actables.h | 8 | ||||
-rw-r--r-- | drivers/acpi/acpica/exconfig.c | 105 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbdata.c | 140 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbfind.c | 10 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbxfload.c | 50 |
5 files changed, 182 insertions, 131 deletions
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 9469cd4106c3..e85953b6fa0e 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -123,6 +123,14 @@ acpi_tb_install_standard_table(acpi_physical_address address, | |||
123 | 123 | ||
124 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc); | 124 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc); |
125 | 125 | ||
126 | acpi_status | ||
127 | acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node); | ||
128 | |||
129 | acpi_status | ||
130 | acpi_tb_install_and_load_table(struct acpi_table_header *table, | ||
131 | acpi_physical_address address, | ||
132 | u8 flags, u8 override, u32 *table_index); | ||
133 | |||
126 | void acpi_tb_terminate(void); | 134 | void acpi_tb_terminate(void); |
127 | 135 | ||
128 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index); | 136 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index); |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 578d5c832325..421836a7a5b9 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -55,9 +55,7 @@ ACPI_MODULE_NAME("exconfig") | |||
55 | 55 | ||
56 | /* Local prototypes */ | 56 | /* Local prototypes */ |
57 | static acpi_status | 57 | static acpi_status |
58 | acpi_ex_add_table(u32 table_index, | 58 | acpi_ex_add_table(u32 table_index, union acpi_operand_object **ddb_handle); |
59 | struct acpi_namespace_node *parent_node, | ||
60 | union acpi_operand_object **ddb_handle); | ||
61 | 59 | ||
62 | static acpi_status | 60 | static acpi_status |
63 | acpi_ex_region_read(union acpi_operand_object *obj_desc, | 61 | acpi_ex_region_read(union acpi_operand_object *obj_desc, |
@@ -79,13 +77,9 @@ acpi_ex_region_read(union acpi_operand_object *obj_desc, | |||
79 | ******************************************************************************/ | 77 | ******************************************************************************/ |
80 | 78 | ||
81 | static acpi_status | 79 | static acpi_status |
82 | acpi_ex_add_table(u32 table_index, | 80 | acpi_ex_add_table(u32 table_index, union acpi_operand_object **ddb_handle) |
83 | struct acpi_namespace_node *parent_node, | ||
84 | union acpi_operand_object **ddb_handle) | ||
85 | { | 81 | { |
86 | union acpi_operand_object *obj_desc; | 82 | union acpi_operand_object *obj_desc; |
87 | acpi_status status; | ||
88 | acpi_owner_id owner_id; | ||
89 | 83 | ||
90 | ACPI_FUNCTION_TRACE(ex_add_table); | 84 | ACPI_FUNCTION_TRACE(ex_add_table); |
91 | 85 | ||
@@ -100,40 +94,8 @@ acpi_ex_add_table(u32 table_index, | |||
100 | 94 | ||
101 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; | 95 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; |
102 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; | 96 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; |
103 | *ddb_handle = obj_desc; | ||
104 | |||
105 | /* Install the new table into the local data structures */ | ||
106 | |||
107 | obj_desc->reference.value = table_index; | 97 | obj_desc->reference.value = table_index; |
108 | 98 | *ddb_handle = obj_desc; | |
109 | /* Add the table to the namespace */ | ||
110 | |||
111 | status = acpi_ns_load_table(table_index, parent_node); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | acpi_ut_remove_reference(obj_desc); | ||
114 | *ddb_handle = NULL; | ||
115 | return_ACPI_STATUS(status); | ||
116 | } | ||
117 | |||
118 | /* Execute any module-level code that was found in the table */ | ||
119 | |||
120 | acpi_ex_exit_interpreter(); | ||
121 | if (!acpi_gbl_parse_table_as_term_list | ||
122 | && acpi_gbl_group_module_level_code) { | ||
123 | acpi_ns_exec_module_code_list(); | ||
124 | } | ||
125 | acpi_ex_enter_interpreter(); | ||
126 | |||
127 | /* | ||
128 | * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is | ||
129 | * responsible for discovering any new wake GPEs by running _PRW methods | ||
130 | * that may have been loaded by this table. | ||
131 | */ | ||
132 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
133 | if (ACPI_SUCCESS(status)) { | ||
134 | acpi_ev_update_gpes(owner_id); | ||
135 | } | ||
136 | |||
137 | return_ACPI_STATUS(AE_OK); | 99 | return_ACPI_STATUS(AE_OK); |
138 | } | 100 | } |
139 | 101 | ||
@@ -160,16 +122,17 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
160 | struct acpi_namespace_node *start_node; | 122 | struct acpi_namespace_node *start_node; |
161 | struct acpi_namespace_node *parameter_node = NULL; | 123 | struct acpi_namespace_node *parameter_node = NULL; |
162 | union acpi_operand_object *ddb_handle; | 124 | union acpi_operand_object *ddb_handle; |
163 | struct acpi_table_header *table; | ||
164 | u32 table_index; | 125 | u32 table_index; |
165 | 126 | ||
166 | ACPI_FUNCTION_TRACE(ex_load_table_op); | 127 | ACPI_FUNCTION_TRACE(ex_load_table_op); |
167 | 128 | ||
168 | /* Find the ACPI table in the RSDT/XSDT */ | 129 | /* Find the ACPI table in the RSDT/XSDT */ |
169 | 130 | ||
131 | acpi_ex_exit_interpreter(); | ||
170 | status = acpi_tb_find_table(operand[0]->string.pointer, | 132 | status = acpi_tb_find_table(operand[0]->string.pointer, |
171 | operand[1]->string.pointer, | 133 | operand[1]->string.pointer, |
172 | operand[2]->string.pointer, &table_index); | 134 | operand[2]->string.pointer, &table_index); |
135 | acpi_ex_enter_interpreter(); | ||
173 | if (ACPI_FAILURE(status)) { | 136 | if (ACPI_FAILURE(status)) { |
174 | if (status != AE_NOT_FOUND) { | 137 | if (status != AE_NOT_FOUND) { |
175 | return_ACPI_STATUS(status); | 138 | return_ACPI_STATUS(status); |
@@ -232,7 +195,15 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
232 | 195 | ||
233 | /* Load the table into the namespace */ | 196 | /* Load the table into the namespace */ |
234 | 197 | ||
235 | status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); | 198 | ACPI_INFO(("Dynamic OEM Table Load:")); |
199 | acpi_ex_exit_interpreter(); | ||
200 | status = acpi_tb_load_table(table_index, parent_node); | ||
201 | acpi_ex_enter_interpreter(); | ||
202 | if (ACPI_FAILURE(status)) { | ||
203 | return_ACPI_STATUS(status); | ||
204 | } | ||
205 | |||
206 | status = acpi_ex_add_table(table_index, &ddb_handle); | ||
236 | if (ACPI_FAILURE(status)) { | 207 | if (ACPI_FAILURE(status)) { |
237 | return_ACPI_STATUS(status); | 208 | return_ACPI_STATUS(status); |
238 | } | 209 | } |
@@ -255,19 +226,6 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
255 | } | 226 | } |
256 | } | 227 | } |
257 | 228 | ||
258 | status = acpi_get_table_by_index(table_index, &table); | ||
259 | if (ACPI_SUCCESS(status)) { | ||
260 | ACPI_INFO(("Dynamic OEM Table Load:")); | ||
261 | acpi_tb_print_table_header(0, table); | ||
262 | } | ||
263 | |||
264 | /* Invoke table handler if present */ | ||
265 | |||
266 | if (acpi_gbl_table_handler) { | ||
267 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
268 | acpi_gbl_table_handler_context); | ||
269 | } | ||
270 | |||
271 | *return_desc = ddb_handle; | 229 | *return_desc = ddb_handle; |
272 | return_ACPI_STATUS(status); | 230 | return_ACPI_STATUS(status); |
273 | } | 231 | } |
@@ -478,13 +436,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
478 | /* Install the new table into the local data structures */ | 436 | /* Install the new table into the local data structures */ |
479 | 437 | ||
480 | ACPI_INFO(("Dynamic OEM Table Load:")); | 438 | ACPI_INFO(("Dynamic OEM Table Load:")); |
481 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 439 | acpi_ex_exit_interpreter(); |
482 | 440 | status = | |
483 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), | 441 | acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table), |
484 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | 442 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, |
485 | TRUE, TRUE, &table_index); | 443 | TRUE, &table_index); |
486 | 444 | acpi_ex_enter_interpreter(); | |
487 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
488 | if (ACPI_FAILURE(status)) { | 445 | if (ACPI_FAILURE(status)) { |
489 | 446 | ||
490 | /* Delete allocated table buffer */ | 447 | /* Delete allocated table buffer */ |
@@ -494,25 +451,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
494 | } | 451 | } |
495 | 452 | ||
496 | /* | 453 | /* |
497 | * Note: Now table is "INSTALLED", it must be validated before | ||
498 | * loading. | ||
499 | */ | ||
500 | status = | ||
501 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | ||
502 | tables[table_index]); | ||
503 | if (ACPI_FAILURE(status)) { | ||
504 | return_ACPI_STATUS(status); | ||
505 | } | ||
506 | |||
507 | /* | ||
508 | * Add the table to the namespace. | 454 | * Add the table to the namespace. |
509 | * | 455 | * |
510 | * Note: Load the table objects relative to the root of the namespace. | 456 | * Note: Load the table objects relative to the root of the namespace. |
511 | * This appears to go against the ACPI specification, but we do it for | 457 | * This appears to go against the ACPI specification, but we do it for |
512 | * compatibility with other ACPI implementations. | 458 | * compatibility with other ACPI implementations. |
513 | */ | 459 | */ |
514 | status = | 460 | status = acpi_ex_add_table(table_index, &ddb_handle); |
515 | acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); | ||
516 | if (ACPI_FAILURE(status)) { | 461 | if (ACPI_FAILURE(status)) { |
517 | 462 | ||
518 | /* On error, table_ptr was deallocated above */ | 463 | /* On error, table_ptr was deallocated above */ |
@@ -535,14 +480,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
535 | /* Remove the reference by added by acpi_ex_store above */ | 480 | /* Remove the reference by added by acpi_ex_store above */ |
536 | 481 | ||
537 | acpi_ut_remove_reference(ddb_handle); | 482 | acpi_ut_remove_reference(ddb_handle); |
538 | |||
539 | /* Invoke table handler if present */ | ||
540 | |||
541 | if (acpi_gbl_table_handler) { | ||
542 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
543 | acpi_gbl_table_handler_context); | ||
544 | } | ||
545 | |||
546 | return_ACPI_STATUS(status); | 483 | return_ACPI_STATUS(status); |
547 | } | 484 | } |
548 | 485 | ||
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c index 1388a19e5db8..7e93fd6d30d5 100644 --- a/drivers/acpi/acpica/tbdata.c +++ b/drivers/acpi/acpica/tbdata.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | #include "actables.h" | 47 | #include "actables.h" |
48 | #include "acevents.h" | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_TABLES | 50 | #define _COMPONENT ACPI_TABLES |
50 | ACPI_MODULE_NAME("tbdata") | 51 | ACPI_MODULE_NAME("tbdata") |
@@ -771,3 +772,142 @@ void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) | |||
771 | 772 | ||
772 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 773 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
773 | } | 774 | } |
775 | |||
776 | /******************************************************************************* | ||
777 | * | ||
778 | * FUNCTION: acpi_tb_load_table | ||
779 | * | ||
780 | * PARAMETERS: table_index - Table index | ||
781 | * parent_node - Where table index is returned | ||
782 | * | ||
783 | * RETURN: Status | ||
784 | * | ||
785 | * DESCRIPTION: Load an ACPI table | ||
786 | * | ||
787 | ******************************************************************************/ | ||
788 | |||
789 | acpi_status | ||
790 | acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) | ||
791 | { | ||
792 | struct acpi_table_header *table; | ||
793 | acpi_status status; | ||
794 | acpi_owner_id owner_id; | ||
795 | |||
796 | ACPI_FUNCTION_TRACE(tb_load_table); | ||
797 | |||
798 | /* | ||
799 | * Note: Now table is "INSTALLED", it must be validated before | ||
800 | * using. | ||
801 | */ | ||
802 | status = acpi_get_table_by_index(table_index, &table); | ||
803 | if (ACPI_FAILURE(status)) { | ||
804 | return_ACPI_STATUS(status); | ||
805 | } | ||
806 | |||
807 | status = acpi_ns_load_table(table_index, parent_node); | ||
808 | |||
809 | /* Execute any module-level code that was found in the table */ | ||
810 | |||
811 | if (!acpi_gbl_parse_table_as_term_list | ||
812 | && acpi_gbl_group_module_level_code) { | ||
813 | acpi_ns_exec_module_code_list(); | ||
814 | } | ||
815 | |||
816 | /* | ||
817 | * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is | ||
818 | * responsible for discovering any new wake GPEs by running _PRW methods | ||
819 | * that may have been loaded by this table. | ||
820 | */ | ||
821 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
822 | if (ACPI_SUCCESS(status)) { | ||
823 | acpi_ev_update_gpes(owner_id); | ||
824 | } | ||
825 | |||
826 | /* Invoke table handler if present */ | ||
827 | |||
828 | if (acpi_gbl_table_handler) { | ||
829 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
830 | acpi_gbl_table_handler_context); | ||
831 | } | ||
832 | |||
833 | return_ACPI_STATUS(status); | ||
834 | } | ||
835 | |||
836 | /******************************************************************************* | ||
837 | * | ||
838 | * FUNCTION: acpi_tb_install_and_load_table | ||
839 | * | ||
840 | * PARAMETERS: table - Pointer to the table | ||
841 | * address - Physical address of the table | ||
842 | * flags - Allocation flags of the table | ||
843 | * table_index - Where table index is returned | ||
844 | * | ||
845 | * RETURN: Status | ||
846 | * | ||
847 | * DESCRIPTION: Install and load an ACPI table | ||
848 | * | ||
849 | ******************************************************************************/ | ||
850 | |||
851 | acpi_status | ||
852 | acpi_tb_install_and_load_table(struct acpi_table_header *table, | ||
853 | acpi_physical_address address, | ||
854 | u8 flags, u8 override, u32 *table_index) | ||
855 | { | ||
856 | acpi_status status; | ||
857 | u32 i; | ||
858 | acpi_owner_id owner_id; | ||
859 | |||
860 | ACPI_FUNCTION_TRACE(acpi_load_table); | ||
861 | |||
862 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
863 | |||
864 | /* Install the table and load it into the namespace */ | ||
865 | |||
866 | status = acpi_tb_install_standard_table(address, flags, TRUE, | ||
867 | override, &i); | ||
868 | if (ACPI_FAILURE(status)) { | ||
869 | goto unlock_and_exit; | ||
870 | } | ||
871 | |||
872 | /* | ||
873 | * Note: Now table is "INSTALLED", it must be validated before | ||
874 | * using. | ||
875 | */ | ||
876 | status = acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]); | ||
877 | if (ACPI_FAILURE(status)) { | ||
878 | goto unlock_and_exit; | ||
879 | } | ||
880 | |||
881 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
882 | status = acpi_ns_load_table(i, acpi_gbl_root_node); | ||
883 | |||
884 | /* Execute any module-level code that was found in the table */ | ||
885 | |||
886 | if (!acpi_gbl_parse_table_as_term_list | ||
887 | && acpi_gbl_group_module_level_code) { | ||
888 | acpi_ns_exec_module_code_list(); | ||
889 | } | ||
890 | |||
891 | /* | ||
892 | * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is | ||
893 | * responsible for discovering any new wake GPEs by running _PRW methods | ||
894 | * that may have been loaded by this table. | ||
895 | */ | ||
896 | status = acpi_tb_get_owner_id(i, &owner_id); | ||
897 | if (ACPI_SUCCESS(status)) { | ||
898 | acpi_ev_update_gpes(owner_id); | ||
899 | } | ||
900 | |||
901 | /* Invoke table handler if present */ | ||
902 | |||
903 | if (acpi_gbl_table_handler) { | ||
904 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
905 | acpi_gbl_table_handler_context); | ||
906 | } | ||
907 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
908 | |||
909 | unlock_and_exit: | ||
910 | *table_index = i; | ||
911 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
912 | return_ACPI_STATUS(status); | ||
913 | } | ||
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index e348d616e60f..a3f7b3789cdc 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c | |||
@@ -68,7 +68,7 @@ acpi_status | |||
68 | acpi_tb_find_table(char *signature, | 68 | acpi_tb_find_table(char *signature, |
69 | char *oem_id, char *oem_table_id, u32 *table_index) | 69 | char *oem_id, char *oem_table_id, u32 *table_index) |
70 | { | 70 | { |
71 | acpi_status status; | 71 | acpi_status status = AE_OK; |
72 | struct acpi_table_header header; | 72 | struct acpi_table_header header; |
73 | u32 i; | 73 | u32 i; |
74 | 74 | ||
@@ -96,6 +96,7 @@ acpi_tb_find_table(char *signature, | |||
96 | 96 | ||
97 | /* Search for the table */ | 97 | /* Search for the table */ |
98 | 98 | ||
99 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
99 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | 100 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { |
100 | if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature), | 101 | if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature), |
101 | header.signature, ACPI_NAME_SIZE)) { | 102 | header.signature, ACPI_NAME_SIZE)) { |
@@ -115,7 +116,7 @@ acpi_tb_find_table(char *signature, | |||
115 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | 116 | acpi_tb_validate_table(&acpi_gbl_root_table_list. |
116 | tables[i]); | 117 | tables[i]); |
117 | if (ACPI_FAILURE(status)) { | 118 | if (ACPI_FAILURE(status)) { |
118 | return_ACPI_STATUS(status); | 119 | goto unlock_and_exit; |
119 | } | 120 | } |
120 | 121 | ||
121 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | 122 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
@@ -144,9 +145,12 @@ acpi_tb_find_table(char *signature, | |||
144 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | 145 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, |
145 | "Found table [%4.4s]\n", | 146 | "Found table [%4.4s]\n", |
146 | header.signature)); | 147 | header.signature)); |
147 | return_ACPI_STATUS(AE_OK); | 148 | goto unlock_and_exit; |
148 | } | 149 | } |
149 | } | 150 | } |
151 | status = AE_NOT_FOUND; | ||
150 | 152 | ||
153 | unlock_and_exit: | ||
154 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
151 | return_ACPI_STATUS(AE_NOT_FOUND); | 155 | return_ACPI_STATUS(AE_NOT_FOUND); |
152 | } | 156 | } |
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 608871212d8c..870ad6445466 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c | |||
@@ -189,11 +189,11 @@ acpi_status acpi_tb_load_namespace(void) | |||
189 | memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT, | 189 | memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT, |
190 | sizeof(struct acpi_table_header)); | 190 | sizeof(struct acpi_table_header)); |
191 | 191 | ||
192 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
193 | |||
194 | /* Load and parse tables */ | 192 | /* Load and parse tables */ |
195 | 193 | ||
194 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
196 | status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node); | 195 | status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node); |
196 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
197 | if (ACPI_FAILURE(status)) { | 197 | if (ACPI_FAILURE(status)) { |
198 | ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed")); | 198 | ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed")); |
199 | tables_failed++; | 199 | tables_failed++; |
@@ -203,7 +203,6 @@ acpi_status acpi_tb_load_namespace(void) | |||
203 | 203 | ||
204 | /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ | 204 | /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ |
205 | 205 | ||
206 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
207 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | 206 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { |
208 | table = &acpi_gbl_root_table_list.tables[i]; | 207 | table = &acpi_gbl_root_table_list.tables[i]; |
209 | 208 | ||
@@ -221,6 +220,7 @@ acpi_status acpi_tb_load_namespace(void) | |||
221 | 220 | ||
222 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 221 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
223 | status = acpi_ns_load_table(i, acpi_gbl_root_node); | 222 | status = acpi_ns_load_table(i, acpi_gbl_root_node); |
223 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
224 | if (ACPI_FAILURE(status)) { | 224 | if (ACPI_FAILURE(status)) { |
225 | ACPI_EXCEPTION((AE_INFO, status, | 225 | ACPI_EXCEPTION((AE_INFO, status, |
226 | "(%4.4s:%8.8s) while loading table", | 226 | "(%4.4s:%8.8s) while loading table", |
@@ -236,8 +236,6 @@ acpi_status acpi_tb_load_namespace(void) | |||
236 | } else { | 236 | } else { |
237 | tables_loaded++; | 237 | tables_loaded++; |
238 | } | 238 | } |
239 | |||
240 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
241 | } | 239 | } |
242 | 240 | ||
243 | if (!tables_failed) { | 241 | if (!tables_failed) { |
@@ -325,49 +323,13 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
325 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 323 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
326 | } | 324 | } |
327 | 325 | ||
328 | /* Must acquire the interpreter lock during this operation */ | ||
329 | |||
330 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
331 | if (ACPI_FAILURE(status)) { | ||
332 | return_ACPI_STATUS(status); | ||
333 | } | ||
334 | |||
335 | /* Install the table and load it into the namespace */ | 326 | /* Install the table and load it into the namespace */ |
336 | 327 | ||
337 | ACPI_INFO(("Host-directed Dynamic ACPI Table Load:")); | 328 | ACPI_INFO(("Host-directed Dynamic ACPI Table Load:")); |
338 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
339 | |||
340 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), | ||
341 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, | ||
342 | TRUE, FALSE, &table_index); | ||
343 | |||
344 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
345 | if (ACPI_FAILURE(status)) { | ||
346 | goto unlock_and_exit; | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * Note: Now table is "INSTALLED", it must be validated before | ||
351 | * using. | ||
352 | */ | ||
353 | status = | 329 | status = |
354 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | 330 | acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table), |
355 | tables[table_index]); | 331 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, |
356 | if (ACPI_FAILURE(status)) { | 332 | FALSE, &table_index); |
357 | goto unlock_and_exit; | ||
358 | } | ||
359 | |||
360 | status = acpi_ns_load_table(table_index, acpi_gbl_root_node); | ||
361 | |||
362 | /* Invoke table handler if present */ | ||
363 | |||
364 | if (acpi_gbl_table_handler) { | ||
365 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
366 | acpi_gbl_table_handler_context); | ||
367 | } | ||
368 | |||
369 | unlock_and_exit: | ||
370 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | ||
371 | return_ACPI_STATUS(status); | 333 | return_ACPI_STATUS(status); |
372 | } | 334 | } |
373 | 335 | ||