Skip to content

Commit 36168d7

Browse files
committed
Merge tag 'edac_for_4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
Pull EDAC updates from Borislav Petkov: "The EDAC tree was busier than usual this cycle as the shortlog below shows. Also, this pull request is carrying an ACPI DSM driver which is used to ask the platform to supply the DIMM location of a reported hardware error and thus simplify all the EDAC logic when trying to map the error address to the respective DIMM. Core EDAC updates: - amd64_edac: AMD family 0x17, models 0x10-0x2f support (Michael Jin) Hygon Dhyana support (Pu Wen) - sb_edac: New maintainer + fixes (Tony Luck) Error reporting improvements and fixes (Qiuxu Zhuo) - ghes_edac: SMBIOS handle type 17 for DIMM locating and per-DIMM error accounting (Fan Wu) - altera_edac: Stratix10 support and refactoring (Thor Thayer) Out of tree addition: - acpi_adxl: Address Translation interface using an ACPI DSM (Tony Luck) - the usual amount of other misc fixes and cleanups all over" * tag 'edac_for_4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp: (22 commits) ACPI/ADXL: Add address translation interface using an ACPI DSM EDAC, thunderx: Fix memory leak in thunderx_l2c_threaded_isr() EDAC, skx_edac: Fix logical channel intermediate decoding EDAC, {i7core,sb,skx}_edac: Fix uncorrected error counting EDAC, altera: Work around int-to-pointer-cast warnings EDAC, amd64: Add Hygon Dhyana support EDAC: Raise the maximum number of memory controllers arm64: dts: stratix10: Add peripheral EDAC nodes EDAC, altera: Add Stratix10 peripheral support EDAC, altera: Merge Stratix10 into the Arria10 SDRAM probe routine arm64: dts: stratix10: Add SDRAM node EDAC, altera: Combine Stratix10 and Arria10 probe functions arm64: dts: stratix10: Additions to EDAC System Manager EDAC, i7core: Remove set but not used variable pvt EDAC, ghes: Use CPER module handles to locate DIMMs EDAC: Correct DIMM capacity unit symbol EDAC, sb_edac: Fix signedness bugs in *_get_ha() functions EDAC, sb_edac: Fix reporting for patrol scrubber errors EDAC, sb_edac: Return early on ADDRV bit and address type test MAINTAINERS: Update maintainer for drivers/edac/sb_edac.c ...
2 parents 6078e07 + 4cf841e commit 36168d7

File tree

18 files changed

+715
-557
lines changed

18 files changed

+715
-557
lines changed

MAINTAINERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5364,7 +5364,8 @@ S: Maintained
53645364
F: drivers/edac/r82600_edac.c
53655365

53665366
EDAC-SBRIDGE
5367-
M: Mauro Carvalho Chehab <mchehab@kernel.org>
5367+
M: Tony Luck <tony.luck@intel.com>
5368+
R: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
53685369
L: linux-edac@vger.kernel.org
53695370
S: Maintained
53705371
F: drivers/edac/sb_edac.c

arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,16 +473,51 @@
473473
status = "disabled";
474474
};
475475

476+
sdr: sdr@f8011100 {
477+
compatible = "altr,sdr-ctl", "syscon";
478+
reg = <0xf8011100 0xc0>;
479+
};
480+
476481
eccmgr {
477-
compatible = "altr,socfpga-s10-ecc-manager";
482+
compatible = "altr,socfpga-a10-ecc-manager";
483+
altr,sysmgr-syscon = <&sysmgr>;
484+
#address-cells = <1>;
485+
#size-cells = <1>;
478486
interrupts = <0 15 4>, <0 95 4>;
479487
interrupt-controller;
480488
#interrupt-cells = <2>;
489+
ranges;
481490

482491
sdramedac {
483492
compatible = "altr,sdram-edac-s10";
493+
altr,sdr-syscon = <&sdr>;
484494
interrupts = <16 4>, <48 4>;
485495
};
496+
497+
usb0-ecc@ff8c4000 {
498+
compatible = "altr,socfpga-usb-ecc";
499+
reg = <0xff8c4000 0x100>;
500+
altr,ecc-parent = <&usb0>;
501+
interrupts = <2 4>,
502+
<34 4>;
503+
};
504+
505+
emac0-rx-ecc@ff8c0000 {
506+
compatible = "altr,socfpga-eth-mac-ecc";
507+
reg = <0xff8c0000 0x100>;
508+
altr,ecc-parent = <&gmac0>;
509+
interrupts = <4 4>,
510+
<36 4>;
511+
};
512+
513+
emac0-tx-ecc@ff8c0400 {
514+
compatible = "altr,socfpga-eth-mac-ecc";
515+
reg = <0xff8c0400 0x100>;
516+
altr,ecc-parent = <&gmac0>;
517+
interrupts = <5 4>,
518+
<37 4>;
519+
};
520+
486521
};
487522

488523
qspi: spi@ff8d2000 {

drivers/acpi/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,9 @@ config ACPI_EXTLOG
492492
driver adds support for that functionality with corresponding
493493
tracepoint which carries that information to userspace.
494494

495+
config ACPI_ADXL
496+
bool
497+
495498
menuconfig PMIC_OPREGION
496499
bool "PMIC (Power Management Integrated Circuit) operation region support"
497500
help

drivers/acpi/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ acpi-$(CONFIG_ACPI_LPIT) += acpi_lpit.o
6161
acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o
6262
acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o
6363

64+
# Address translation
65+
acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o
66+
6467
# These are (potentially) separate modules
6568

6669
# IPMI may be used by other drivers, so it has to initialise before them

drivers/acpi/acpi_adxl.c

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Address translation interface via ACPI DSM.
4+
* Copyright (C) 2018 Intel Corporation
5+
*
6+
* Specification for this interface is available at:
7+
*
8+
* https://cdrdv2.intel.com/v1/dl/getContent/603354
9+
*/
10+
11+
#include <linux/acpi.h>
12+
#include <linux/adxl.h>
13+
14+
#define ADXL_REVISION 0x1
15+
#define ADXL_IDX_GET_ADDR_PARAMS 0x1
16+
#define ADXL_IDX_FORWARD_TRANSLATE 0x2
17+
#define ACPI_ADXL_PATH "\\_SB.ADXL"
18+
19+
/*
20+
* The specification doesn't provide a limit on how many
21+
* components are in a memory address. But since we allocate
22+
* memory based on the number the BIOS tells us, we should
23+
* defend against insane values.
24+
*/
25+
#define ADXL_MAX_COMPONENTS 500
26+
27+
#undef pr_fmt
28+
#define pr_fmt(fmt) "ADXL: " fmt
29+
30+
static acpi_handle handle;
31+
static union acpi_object *params;
32+
static const guid_t adxl_guid =
33+
GUID_INIT(0xAA3C050A, 0x7EA4, 0x4C1F,
34+
0xAF, 0xDA, 0x12, 0x67, 0xDF, 0xD3, 0xD4, 0x8D);
35+
36+
static int adxl_count;
37+
static char **adxl_component_names;
38+
39+
static union acpi_object *adxl_dsm(int cmd, union acpi_object argv[])
40+
{
41+
union acpi_object *obj, *o;
42+
43+
obj = acpi_evaluate_dsm_typed(handle, &adxl_guid, ADXL_REVISION,
44+
cmd, argv, ACPI_TYPE_PACKAGE);
45+
if (!obj) {
46+
pr_info("DSM call failed for cmd=%d\n", cmd);
47+
return NULL;
48+
}
49+
50+
if (obj->package.count != 2) {
51+
pr_info("Bad pkg count %d\n", obj->package.count);
52+
goto err;
53+
}
54+
55+
o = obj->package.elements;
56+
if (o->type != ACPI_TYPE_INTEGER) {
57+
pr_info("Bad 1st element type %d\n", o->type);
58+
goto err;
59+
}
60+
if (o->integer.value) {
61+
pr_info("Bad ret val %llu\n", o->integer.value);
62+
goto err;
63+
}
64+
65+
o = obj->package.elements + 1;
66+
if (o->type != ACPI_TYPE_PACKAGE) {
67+
pr_info("Bad 2nd element type %d\n", o->type);
68+
goto err;
69+
}
70+
return obj;
71+
72+
err:
73+
ACPI_FREE(obj);
74+
return NULL;
75+
}
76+
77+
/**
78+
* adxl_get_component_names - get list of memory component names
79+
* Returns NULL terminated list of string names
80+
*
81+
* Give the caller a pointer to the list of memory component names
82+
* e.g. { "SystemAddress", "ProcessorSocketId", "ChannelId", ... NULL }
83+
* Caller should count how many strings in order to allocate a buffer
84+
* for the return from adxl_decode().
85+
*/
86+
const char * const *adxl_get_component_names(void)
87+
{
88+
return (const char * const *)adxl_component_names;
89+
}
90+
EXPORT_SYMBOL_GPL(adxl_get_component_names);
91+
92+
/**
93+
* adxl_decode - ask BIOS to decode a system address to memory address
94+
* @addr: the address to decode
95+
* @component_values: pointer to array of values for each component
96+
* Returns 0 on success, negative error code otherwise
97+
*
98+
* The index of each value returned in the array matches the index of
99+
* each component name returned by adxl_get_component_names().
100+
* Components that are not defined for this address translation (e.g.
101+
* mirror channel number for a non-mirrored address) are set to ~0ull.
102+
*/
103+
int adxl_decode(u64 addr, u64 component_values[])
104+
{
105+
union acpi_object argv4[2], *results, *r;
106+
int i, cnt;
107+
108+
if (!adxl_component_names)
109+
return -EOPNOTSUPP;
110+
111+
argv4[0].type = ACPI_TYPE_PACKAGE;
112+
argv4[0].package.count = 1;
113+
argv4[0].package.elements = &argv4[1];
114+
argv4[1].integer.type = ACPI_TYPE_INTEGER;
115+
argv4[1].integer.value = addr;
116+
117+
results = adxl_dsm(ADXL_IDX_FORWARD_TRANSLATE, argv4);
118+
if (!results)
119+
return -EINVAL;
120+
121+
r = results->package.elements + 1;
122+
cnt = r->package.count;
123+
if (cnt != adxl_count) {
124+
ACPI_FREE(results);
125+
return -EINVAL;
126+
}
127+
r = r->package.elements;
128+
129+
for (i = 0; i < cnt; i++)
130+
component_values[i] = r[i].integer.value;
131+
132+
ACPI_FREE(results);
133+
134+
return 0;
135+
}
136+
EXPORT_SYMBOL_GPL(adxl_decode);
137+
138+
static int __init adxl_init(void)
139+
{
140+
char *path = ACPI_ADXL_PATH;
141+
union acpi_object *p;
142+
acpi_status status;
143+
int i;
144+
145+
status = acpi_get_handle(NULL, path, &handle);
146+
if (ACPI_FAILURE(status)) {
147+
pr_debug("No ACPI handle for path %s\n", path);
148+
return -ENODEV;
149+
}
150+
151+
if (!acpi_has_method(handle, "_DSM")) {
152+
pr_info("No DSM method\n");
153+
return -ENODEV;
154+
}
155+
156+
if (!acpi_check_dsm(handle, &adxl_guid, ADXL_REVISION,
157+
ADXL_IDX_GET_ADDR_PARAMS |
158+
ADXL_IDX_FORWARD_TRANSLATE)) {
159+
pr_info("DSM method does not support forward translate\n");
160+
return -ENODEV;
161+
}
162+
163+
params = adxl_dsm(ADXL_IDX_GET_ADDR_PARAMS, NULL);
164+
if (!params) {
165+
pr_info("Failed to get component names\n");
166+
return -ENODEV;
167+
}
168+
169+
p = params->package.elements + 1;
170+
adxl_count = p->package.count;
171+
if (adxl_count > ADXL_MAX_COMPONENTS) {
172+
pr_info("Insane number of address component names %d\n", adxl_count);
173+
ACPI_FREE(params);
174+
return -ENODEV;
175+
}
176+
p = p->package.elements;
177+
178+
/*
179+
* Allocate one extra for NULL termination.
180+
*/
181+
adxl_component_names = kcalloc(adxl_count + 1, sizeof(char *), GFP_KERNEL);
182+
if (!adxl_component_names) {
183+
ACPI_FREE(params);
184+
return -ENOMEM;
185+
}
186+
187+
for (i = 0; i < adxl_count; i++)
188+
adxl_component_names[i] = p[i].string.pointer;
189+
190+
return 0;
191+
}
192+
subsys_initcall(adxl_init);

0 commit comments

Comments
 (0)