Skip to contentSkip to conversation

EDAC, dsm_edac: Wrap ACPI DSM methods for address translation

PATCH Superseded Luck, Tony 1 participant 1 message Sep 24, 2018 EDAC-core

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Luck, Tony

author maintainer
#0 lore raw

PATCH 4/5 EDAC, dsm_edac: Wrap ACPI DSM methods for address translation

From: Qiuxu Zhuo <[email protected]>

Some machines provide BIOS ACPI DSM (Device Specific Method) to translate memory system address to DRAM address (socket, memory controller, channel, rank, bank, row, column). This patch wraps the DSM methods, and registers them to EDAC core.

Specification for this translation method is at:

	https://cdrdv2.intel.com/v1/dl/getContent/603354

---

The specification is currently behind a click-through license. I'll see if I can get that fixed.

 drivers/edac/Kconfig    |   9 ++
 drivers/edac/Makefile   |   1 +
 drivers/edac/dsm_edac.c | 223 ++++++++++++++++++++++++++++++++++++++++
 drivers/edac/edac_mc.c  |  36 +++++++
 drivers/edac/edac_mc.h  |  64 ++++++++++++
 5 files changed, 333 insertions(+)
 create mode 100644 drivers/edac/dsm_edac.c
drivers/edac/Kconfig +9 -0
index 57304b2e989f..1b2e0ae6158f 100644
@@ -222,6 +222,15 @@ config EDAC_I7300
 	  Support for error detection and correction the Intel
 	  Clarksboro MCH (Intel 7300 chipset).
 
+config EDAC_DSM
+	tristate "Address translation interface via ACPI DSM"
+	depends on X86_64 && ACPI
+	help
+	  Some of machines provide BIOS ACPI DSM (Device Specific Method)
+	  to translate memory system address to DRAM address (socket, memory
+	  controller, channel, rank, bank, row, column). By enabling this
+	  option, the wrapped DSM methods are registered to EDAC core.
+
 config EDAC_SBRIDGE
 	tristate "Intel Sandy-Bridge/Ivy-Bridge/Haswell Integrated MC"
 	depends on PCI && X86_64 && X86_MCE_INTEL && PCI_MMCONFIG
drivers/edac/Makefile +1 -0
index 02b43a7d8c3e..0238c9127730 100644
@@ -29,6 +29,7 @@ obj-$(CONFIG_EDAC_I5100)		+= i5100_edac.o
 obj-$(CONFIG_EDAC_I5400)		+= i5400_edac.o
 obj-$(CONFIG_EDAC_I7300)		+= i7300_edac.o
 obj-$(CONFIG_EDAC_I7CORE)		+= i7core_edac.o
+obj-$(CONFIG_EDAC_DSM)			+= dsm_edac.o
 obj-$(CONFIG_EDAC_SBRIDGE)		+= sb_edac.o
 obj-$(CONFIG_EDAC_SKX)			+= skx_edac.o
 obj-$(CONFIG_EDAC_PND2)			+= pnd2_edac.o
drivers/edac/dsm_edac.c new file +223 -0

223 lines not on this page · raw message

drivers/edac/edac_mc.c +36 -0
index 7d3edd713932..ba27feafc976 100644
@@ -57,6 +57,8 @@ static const char *edac_mc_owner;
 
 static struct bus_type mc_bus[EDAC_MAX_MCS];
 
+static const struct edac_dsm_operations *edac_dsm_ops;
+
 int edac_get_report_status(void)
 {
 	return edac_report;
@@ -1259,3 +1261,37 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
 	edac_raw_mc_handle_error(type, mci, e);
 }
 EXPORT_SYMBOL_GPL(edac_mc_handle_error);
+
+const struct edac_dsm_operations *edac_dsm_get_ops(void)
+{
+	if (edac_dsm_ops && try_module_get(edac_dsm_ops->owner))
+		return edac_dsm_ops;
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(edac_dsm_get_ops);
+
+void edac_dsm_put_ops(const struct edac_dsm_operations *ops)
+{
+	if (ops)
+		module_put(ops->owner);
+}
+EXPORT_SYMBOL_GPL(edac_dsm_put_ops);
+
+int edac_dsm_register_ops(const struct edac_dsm_operations *ops)
+{
+	if (edac_dsm_ops)
+		return -EEXIST;
+
+	edac_dsm_ops = ops;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(edac_dsm_register_ops);
+
+void edac_dsm_unregister_ops(const struct edac_dsm_operations *ops)
+{
+	if (edac_dsm_ops == ops)
+		edac_dsm_ops = NULL;
+}
+EXPORT_SYMBOL_GPL(edac_dsm_unregister_ops);
drivers/edac/edac_mc.h +64 -0

70 lines not on this page · raw message