diff options
Diffstat (limited to 'drivers/acpi/acpi_extlog.c')
-rw-r--r-- | drivers/acpi/acpi_extlog.c | 62 |
1 files changed, 12 insertions, 50 deletions
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index a6869e110ce5..94166680b3a3 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/acpi.h> | 11 | #include <linux/acpi.h> |
12 | #include <acpi/acpi_bus.h> | ||
13 | #include <linux/cper.h> | 12 | #include <linux/cper.h> |
14 | #include <linux/ratelimit.h> | 13 | #include <linux/ratelimit.h> |
15 | #include <asm/cpu.h> | 14 | #include <asm/cpu.h> |
@@ -20,11 +19,9 @@ | |||
20 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ | 19 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ |
21 | 20 | ||
22 | #define EXTLOG_DSM_REV 0x0 | 21 | #define EXTLOG_DSM_REV 0x0 |
23 | #define EXTLOG_FN_QUERY 0x0 | ||
24 | #define EXTLOG_FN_ADDR 0x1 | 22 | #define EXTLOG_FN_ADDR 0x1 |
25 | 23 | ||
26 | #define FLAG_OS_OPTIN BIT(0) | 24 | #define FLAG_OS_OPTIN BIT(0) |
27 | #define EXTLOG_QUERY_L1_EXIST BIT(1) | ||
28 | #define ELOG_ENTRY_VALID (1ULL<<63) | 25 | #define ELOG_ENTRY_VALID (1ULL<<63) |
29 | #define ELOG_ENTRY_LEN 0x1000 | 26 | #define ELOG_ENTRY_LEN 0x1000 |
30 | 27 | ||
@@ -43,7 +40,7 @@ struct extlog_l1_head { | |||
43 | u8 rev1[12]; | 40 | u8 rev1[12]; |
44 | }; | 41 | }; |
45 | 42 | ||
46 | static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; | 43 | static u8 extlog_dsm_uuid[] __initdata = "663E35AF-CC10-41A4-88EA-5470AF055295"; |
47 | 44 | ||
48 | /* L1 table related physical address */ | 45 | /* L1 table related physical address */ |
49 | static u64 elog_base; | 46 | static u64 elog_base; |
@@ -153,62 +150,27 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, | |||
153 | return NOTIFY_DONE; | 150 | return NOTIFY_DONE; |
154 | } | 151 | } |
155 | 152 | ||
156 | static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret) | 153 | static bool __init extlog_get_l1addr(void) |
157 | { | 154 | { |
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]; | 155 | u8 uuid[16]; |
162 | int i; | 156 | acpi_handle handle; |
157 | union acpi_object *obj; | ||
163 | 158 | ||
164 | acpi_str_to_uuid(extlog_dsm_uuid, uuid); | 159 | 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 | 160 | ||
201 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) | 161 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) |
202 | return false; | 162 | return false; |
203 | 163 | 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; | 164 | return false; |
207 | 165 | obj = acpi_evaluate_dsm_typed(handle, uuid, EXTLOG_DSM_REV, | |
208 | if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret)) | 166 | EXTLOG_FN_ADDR, NULL, ACPI_TYPE_INTEGER); |
167 | if (!obj) { | ||
209 | return false; | 168 | return false; |
169 | } else { | ||
170 | l1_dirbase = obj->integer.value; | ||
171 | ACPI_FREE(obj); | ||
172 | } | ||
210 | 173 | ||
211 | l1_dirbase = ret; | ||
212 | /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ | 174 | /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ |
213 | if (l1_dirbase & ((1 << 12) - 1)) { | 175 | if (l1_dirbase & ((1 << 12) - 1)) { |
214 | pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", | 176 | pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", |