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