| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for Pondicherry2 memory controller. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2016, Intel Corporation. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 8 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | 6 | * |
|---|
| 15 | 7 | * [Derived from sb_edac.c] |
|---|
| 16 | 8 | * |
|---|
| .. | .. |
|---|
| 206 | 198 | switch (sz) { |
|---|
| 207 | 199 | case 8: |
|---|
| 208 | 200 | ret = _apl_rd_reg(port, off + 4, op, (u32 *)(data + 4)); |
|---|
| 209 | | - /* fall through */ |
|---|
| 201 | + fallthrough; |
|---|
| 210 | 202 | case 4: |
|---|
| 211 | 203 | ret |= _apl_rd_reg(port, off, op, (u32 *)data); |
|---|
| 212 | 204 | pnd2_printk(KERN_DEBUG, "%s=%x%08x ret=%d\n", name, |
|---|
| .. | .. |
|---|
| 1163 | 1155 | u32 optypenum = GET_BITFIELD(m->status, 4, 6); |
|---|
| 1164 | 1156 | int rc; |
|---|
| 1165 | 1157 | |
|---|
| 1166 | | - tp_event = uc_err ? (ripv ? HW_EVENT_ERR_FATAL : HW_EVENT_ERR_UNCORRECTED) : |
|---|
| 1158 | + tp_event = uc_err ? (ripv ? HW_EVENT_ERR_UNCORRECTED : HW_EVENT_ERR_FATAL) : |
|---|
| 1167 | 1159 | HW_EVENT_ERR_CORRECTED; |
|---|
| 1168 | 1160 | |
|---|
| 1169 | 1161 | /* |
|---|
| .. | .. |
|---|
| 1239 | 1231 | if (!(chan_mask & BIT(i))) |
|---|
| 1240 | 1232 | continue; |
|---|
| 1241 | 1233 | |
|---|
| 1242 | | - dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, 0, 0); |
|---|
| 1234 | + dimm = edac_get_dimm(mci, i, 0, 0); |
|---|
| 1243 | 1235 | if (!dimm) { |
|---|
| 1244 | 1236 | edac_dbg(0, "No allocated DIMM for channel %d\n", i); |
|---|
| 1245 | 1237 | continue; |
|---|
| .. | .. |
|---|
| 1319 | 1311 | if (!ranks_of_dimm[j]) |
|---|
| 1320 | 1312 | continue; |
|---|
| 1321 | 1313 | |
|---|
| 1322 | | - dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, j, 0); |
|---|
| 1314 | + dimm = edac_get_dimm(mci, i, j, 0); |
|---|
| 1323 | 1315 | if (!dimm) { |
|---|
| 1324 | 1316 | edac_dbg(0, "No allocated DIMM for channel %d DIMM %d\n", i, j); |
|---|
| 1325 | 1317 | continue; |
|---|
| .. | .. |
|---|
| 1404 | 1396 | struct dram_addr daddr; |
|---|
| 1405 | 1397 | char *type; |
|---|
| 1406 | 1398 | |
|---|
| 1407 | | - if (edac_get_report_status() == EDAC_REPORTING_DISABLED) |
|---|
| 1408 | | - return NOTIFY_DONE; |
|---|
| 1409 | | - |
|---|
| 1410 | 1399 | mci = pnd2_mci; |
|---|
| 1411 | | - if (!mci) |
|---|
| 1400 | + if (!mci || (mce->kflags & MCE_HANDLED_CEC)) |
|---|
| 1412 | 1401 | return NOTIFY_DONE; |
|---|
| 1413 | 1402 | |
|---|
| 1414 | 1403 | /* |
|---|
| .. | .. |
|---|
| 1437 | 1426 | pnd2_mce_output_error(mci, mce, &daddr); |
|---|
| 1438 | 1427 | |
|---|
| 1439 | 1428 | /* Advice mcelog that the error were handled */ |
|---|
| 1440 | | - return NOTIFY_STOP; |
|---|
| 1429 | + mce->kflags |= MCE_HANDLED_EDAC; |
|---|
| 1430 | + return NOTIFY_OK; |
|---|
| 1441 | 1431 | } |
|---|
| 1442 | 1432 | |
|---|
| 1443 | 1433 | static struct notifier_block pnd2_mce_dec = { |
|---|
| 1444 | 1434 | .notifier_call = pnd2_mce_check_error, |
|---|
| 1435 | + .priority = MCE_PRIO_EDAC, |
|---|
| 1445 | 1436 | }; |
|---|
| 1446 | 1437 | |
|---|
| 1447 | 1438 | #ifdef CONFIG_EDAC_DEBUG |
|---|
| .. | .. |
|---|
| 1545 | 1536 | }; |
|---|
| 1546 | 1537 | |
|---|
| 1547 | 1538 | static const struct x86_cpu_id pnd2_cpuids[] = { |
|---|
| 1548 | | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT, 0, (kernel_ulong_t)&apl_ops }, |
|---|
| 1549 | | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT_X, 0, (kernel_ulong_t)&dnv_ops }, |
|---|
| 1539 | + X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &apl_ops), |
|---|
| 1540 | + X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &dnv_ops), |
|---|
| 1550 | 1541 | { } |
|---|
| 1551 | 1542 | }; |
|---|
| 1552 | 1543 | MODULE_DEVICE_TABLE(x86cpu, pnd2_cpuids); |
|---|
| .. | .. |
|---|
| 1563 | 1554 | if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) |
|---|
| 1564 | 1555 | return -EBUSY; |
|---|
| 1565 | 1556 | |
|---|
| 1557 | + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) |
|---|
| 1558 | + return -ENODEV; |
|---|
| 1559 | + |
|---|
| 1566 | 1560 | id = x86_match_cpu(pnd2_cpuids); |
|---|
| 1567 | 1561 | if (!id) |
|---|
| 1568 | 1562 | return -ENODEV; |
|---|