diff options
-rw-r--r-- | drivers/acpi/acpi_extlog.c | 61 |
1 files changed, 12 insertions, 49 deletions
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index a6869e110ce5..928c4db83ddf 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c | |||
@@ -20,11 +20,9 @@ | |||
20 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ | 20 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ |
21 | 21 | ||
22 | #define EXTLOG_DSM_REV 0x0 | 22 | #define EXTLOG_DSM_REV 0x0 |
23 | #define EXTLOG_FN_QUERY 0x0 | ||
24 | #define EXTLOG_FN_ADDR 0x1 | 23 | #define EXTLOG_FN_ADDR 0x1 |
25 | 24 | ||
26 | #define FLAG_OS_OPTIN BIT(0) | 25 | #define FLAG_OS_OPTIN BIT(0) |
27 | #define EXTLOG_QUERY_L1_EXIST BIT(1) | ||
28 | #define ELOG_ENTRY_VALID (1ULL<<63) | 26 | #define ELOG_ENTRY_VALID (1ULL<<63) |
29 | #define ELOG_ENTRY_LEN 0x1000 | 27 | #define ELOG_ENTRY_LEN 0x1000 |
30 | 28 | ||
@@ -43,7 +41,7 @@ struct extlog_l1_head { | |||
43 | u8 rev1[12]; | 41 | u8 rev1[12]; |
44 | }; | 42 | }; |
45 | 43 | ||
46 | static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; | 44 | static u8 extlog_dsm_uuid[] __initdata = "663E35AF-CC10-41A4-88EA-5470AF055295"; |
47 | 45 | ||
48 | /* L1 table related physical address */ | 46 | /* L1 table related physical address */ |
49 | static u64 elog_base; | 47 | static u64 elog_base; |
@@ -153,62 +151,27 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, | |||
153 | return NOTIFY_DONE; | 151 | return NOTIFY_DONE; |
154 | } | 152 | } |
155 | 153 | ||
156 | static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret) | 154 | static bool __init extlog_get_l1addr(void) |
157 | { | 155 | { |
158 | struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
159 | struct acpi_object_list input; | ||
160 | union acpi_object params[4], *obj; | ||
161 | u8 uuid[16]; | 156 | u8 uuid[16]; |
162 | int i; | 157 | acpi_handle handle; |
158 | union acpi_object *obj; | ||
163 | 159 | ||
164 | acpi_str_to_uuid(extlog_dsm_uuid, uuid); | 160 | acpi_str_to_uuid(extlog_dsm_uuid, uuid); |
165 | input.count = 4; | ||
166 | input.pointer = params; | ||
167 | params[0].type = ACPI_TYPE_BUFFER; | ||
168 | params[0].buffer.length = 16; | ||
169 | params[0].buffer.pointer = uuid; | ||
170 | params[1].type = ACPI_TYPE_INTEGER; | ||
171 | params[1].integer.value = rev; | ||
172 | params[2].type = ACPI_TYPE_INTEGER; | ||
173 | params[2].integer.value = func; | ||
174 | params[3].type = ACPI_TYPE_PACKAGE; | ||
175 | params[3].package.count = 0; | ||
176 | params[3].package.elements = NULL; | ||
177 | |||
178 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf))) | ||
179 | return -1; | ||
180 | |||
181 | *ret = 0; | ||
182 | obj = (union acpi_object *)buf.pointer; | ||
183 | if (obj->type == ACPI_TYPE_INTEGER) { | ||
184 | *ret = obj->integer.value; | ||
185 | } else if (obj->type == ACPI_TYPE_BUFFER) { | ||
186 | if (obj->buffer.length <= 8) { | ||
187 | for (i = 0; i < obj->buffer.length; i++) | ||
188 | *ret |= (obj->buffer.pointer[i] << (i * 8)); | ||
189 | } | ||
190 | } | ||
191 | kfree(buf.pointer); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static bool extlog_get_l1addr(void) | ||
197 | { | ||
198 | acpi_handle handle; | ||
199 | u64 ret; | ||
200 | 161 | ||
201 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) | 162 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) |
202 | return false; | 163 | return false; |
203 | 164 | if (!acpi_check_dsm(handle, uuid, EXTLOG_DSM_REV, 1 << EXTLOG_FN_ADDR)) | |
204 | if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_QUERY, &ret) || | ||
205 | !(ret & EXTLOG_QUERY_L1_EXIST)) | ||
206 | return false; | 165 | return false; |
207 | 166 | obj = acpi_evaluate_dsm_typed(handle, uuid, EXTLOG_DSM_REV, | |
208 | if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret)) | 167 | EXTLOG_FN_ADDR, NULL, ACPI_TYPE_INTEGER); |
168 | if (!obj) { | ||
209 | return false; | 169 | return false; |
170 | } else { | ||
171 | l1_dirbase = obj->integer.value; | ||
172 | ACPI_FREE(obj); | ||
173 | } | ||
210 | 174 | ||
211 | l1_dirbase = ret; | ||
212 | /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ | 175 | /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ |
213 | if (l1_dirbase & ((1 << 12) - 1)) { | 176 | if (l1_dirbase & ((1 << 12) - 1)) { |
214 | pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", | 177 | pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", |