Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd972f92 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull EDAC updates from Borislav Petkov:
 "Noteworthy is the NVDIMM support:

   - NVDIMM support to EDAC (Tony Luck)

   - misc fixes"

* tag 'edac_for_4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
  EDAC, sb_edac: Remove variable length array usage
  EDAC, skx_edac: Detect non-volatile DIMMs
  firmware, DMI: Add function to look up a handle and return DIMM size
  acpi, nfit: Add function to look up nvdimm device and provide SMBIOS handle
  EDAC: Add new memory type for non-volatile DIMMs
  EDAC: Drop duplicated array of strings for memory type names
  EDAC, layerscape: Allow building for LS1021A
parents 3c8ba0d6 6fd05266
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/nd.h>
#include <asm/cacheflush.h>
#include <acpi/nfit.h>
#include "nfit.h"

/*
@@ -690,6 +691,32 @@ static bool add_memdev(struct acpi_nfit_desc *acpi_desc,
	return true;
}

int nfit_get_smbios_id(u32 device_handle, u16 *flags)
{
	struct acpi_nfit_memory_map *memdev;
	struct acpi_nfit_desc *acpi_desc;
	struct nfit_mem *nfit_mem;

	mutex_lock(&acpi_desc_lock);
	list_for_each_entry(acpi_desc, &acpi_descs, list) {
		mutex_lock(&acpi_desc->init_mutex);
		list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
			memdev = __to_nfit_memdev(nfit_mem);
			if (memdev->device_handle == device_handle) {
				mutex_unlock(&acpi_desc->init_mutex);
				mutex_unlock(&acpi_desc_lock);
				*flags = memdev->flags;
				return memdev->physical_id;
			}
		}
		mutex_unlock(&acpi_desc->init_mutex);
	}
	mutex_unlock(&acpi_desc_lock);

	return -ENODEV;
}
EXPORT_SYMBOL_GPL(nfit_get_smbios_id);

/*
 * An implementation may provide a truncated control region if no block windows
 * are defined.
+5 −2
Original line number Diff line number Diff line
@@ -232,9 +232,12 @@ config EDAC_SBRIDGE
config EDAC_SKX
	tristate "Intel Skylake server Integrated MC"
	depends on PCI && X86_64 && X86_MCE_INTEL && PCI_MMCONFIG
	select DMI
	help
	  Support for error detection and correction the Intel
	  Skylake server Integrated Memory Controllers.
	  Skylake server Integrated Memory Controllers. If your
	  system has non-volatile DIMMs you should also manually
	  select CONFIG_ACPI_NFIT.

config EDAC_PND2
	tristate "Intel Pondicherry2"
@@ -254,7 +257,7 @@ config EDAC_MPC85XX

config EDAC_LAYERSCAPE
	tristate "Freescale Layerscape DDR"
	depends on ARCH_LAYERSCAPE
	depends on ARCH_LAYERSCAPE || SOC_LS1021A
	help
	  Support for error detection and correction on Freescale memory
	  controllers on Layerscape SoCs.
+21 −20
Original line number Diff line number Diff line
@@ -195,26 +195,27 @@ static void edac_mc_dump_mci(struct mem_ctl_info *mci)
#endif				/* CONFIG_EDAC_DEBUG */

const char * const edac_mem_types[] = {
	[MEM_EMPTY]	= "Empty csrow",
	[MEM_RESERVED]	= "Reserved csrow type",
	[MEM_UNKNOWN]	= "Unknown csrow type",
	[MEM_FPM]	= "Fast page mode RAM",
	[MEM_EDO]	= "Extended data out RAM",
	[MEM_BEDO]	= "Burst Extended data out RAM",
	[MEM_SDR]	= "Single data rate SDRAM",
	[MEM_RDR]	= "Registered single data rate SDRAM",
	[MEM_DDR]	= "Double data rate SDRAM",
	[MEM_RDDR]	= "Registered Double data rate SDRAM",
	[MEM_RMBS]	= "Rambus DRAM",
	[MEM_DDR2]	= "Unbuffered DDR2 RAM",
	[MEM_FB_DDR2]	= "Fully buffered DDR2",
	[MEM_RDDR2]	= "Registered DDR2 RAM",
	[MEM_XDR]	= "Rambus XDR",
	[MEM_DDR3]	= "Unbuffered DDR3 RAM",
	[MEM_RDDR3]	= "Registered DDR3 RAM",
	[MEM_LRDDR3]	= "Load-Reduced DDR3 RAM",
	[MEM_DDR4]	= "Unbuffered DDR4 RAM",
	[MEM_RDDR4]	= "Registered DDR4 RAM",
	[MEM_EMPTY]	= "Empty",
	[MEM_RESERVED]	= "Reserved",
	[MEM_UNKNOWN]	= "Unknown",
	[MEM_FPM]	= "FPM",
	[MEM_EDO]	= "EDO",
	[MEM_BEDO]	= "BEDO",
	[MEM_SDR]	= "Unbuffered-SDR",
	[MEM_RDR]	= "Registered-SDR",
	[MEM_DDR]	= "Unbuffered-DDR",
	[MEM_RDDR]	= "Registered-DDR",
	[MEM_RMBS]	= "RMBS",
	[MEM_DDR2]	= "Unbuffered-DDR2",
	[MEM_FB_DDR2]	= "FullyBuffered-DDR2",
	[MEM_RDDR2]	= "Registered-DDR2",
	[MEM_XDR]	= "XDR",
	[MEM_DDR3]	= "Unbuffered-DDR3",
	[MEM_RDDR3]	= "Registered-DDR3",
	[MEM_LRDDR3]	= "Load-Reduced-DDR3-RAM",
	[MEM_DDR4]	= "Unbuffered-DDR4",
	[MEM_RDDR4]	= "Registered-DDR4",
	[MEM_NVDIMM]	= "Non-volatile-RAM",
};
EXPORT_SYMBOL_GPL(edac_mem_types);

+2 −24
Original line number Diff line number Diff line
@@ -91,28 +91,6 @@ static struct device *mci_pdev;
/*
 * various constants for Memory Controllers
 */
static const char * const mem_types[] = {
	[MEM_EMPTY] = "Empty",
	[MEM_RESERVED] = "Reserved",
	[MEM_UNKNOWN] = "Unknown",
	[MEM_FPM] = "FPM",
	[MEM_EDO] = "EDO",
	[MEM_BEDO] = "BEDO",
	[MEM_SDR] = "Unbuffered-SDR",
	[MEM_RDR] = "Registered-SDR",
	[MEM_DDR] = "Unbuffered-DDR",
	[MEM_RDDR] = "Registered-DDR",
	[MEM_RMBS] = "RMBS",
	[MEM_DDR2] = "Unbuffered-DDR2",
	[MEM_FB_DDR2] = "FullyBuffered-DDR2",
	[MEM_RDDR2] = "Registered-DDR2",
	[MEM_XDR] = "XDR",
	[MEM_DDR3] = "Unbuffered-DDR3",
	[MEM_RDDR3] = "Registered-DDR3",
	[MEM_DDR4] = "Unbuffered-DDR4",
	[MEM_RDDR4] = "Registered-DDR4"
};

static const char * const dev_types[] = {
	[DEV_UNKNOWN] = "Unknown",
	[DEV_X1] = "x1",
@@ -196,7 +174,7 @@ static ssize_t csrow_mem_type_show(struct device *dev,
{
	struct csrow_info *csrow = to_csrow(dev);

	return sprintf(data, "%s\n", mem_types[csrow->channels[0]->dimm->mtype]);
	return sprintf(data, "%s\n", edac_mem_types[csrow->channels[0]->dimm->mtype]);
}

static ssize_t csrow_dev_type_show(struct device *dev,
@@ -549,7 +527,7 @@ static ssize_t dimmdev_mem_type_show(struct device *dev,
{
	struct dimm_info *dimm = to_dimm(dev);

	return sprintf(data, "%s\n", mem_types[dimm->mtype]);
	return sprintf(data, "%s\n", edac_mem_types[dimm->mtype]);
}

static ssize_t dimmdev_dev_type_show(struct device *dev,
+5 −7
Original line number Diff line number Diff line
@@ -110,6 +110,10 @@ static const u32 knl_interleave_list[] = {
	0xdc, 0xe4, 0xec, 0xf4, 0xfc, /* 15-19 */
	0x104, 0x10c, 0x114, 0x11c,   /* 20-23 */
};
#define MAX_INTERLEAVE							\
	(max_t(unsigned int, ARRAY_SIZE(sbridge_interleave_list),	\
	       max_t(unsigned int, ARRAY_SIZE(ibridge_interleave_list),	\
		     ARRAY_SIZE(knl_interleave_list))))

struct interleave_pkg {
	unsigned char start;
@@ -321,7 +325,6 @@ struct sbridge_info {
	const u32	*interleave_list;
	const struct interleave_pkg *interleave_pkg;
	u8		max_sad;
	u8		max_interleave;
	u8		(*get_node_id)(struct sbridge_pvt *pvt);
	enum mem_type	(*get_memory_type)(struct sbridge_pvt *pvt);
	enum dev_type	(*get_width)(struct sbridge_pvt *pvt, u32 mtr);
@@ -1899,7 +1902,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
	int			n_rir, n_sads, n_tads, sad_way, sck_xch;
	int			sad_interl, idx, base_ch;
	int			interleave_mode, shiftup = 0;
	unsigned		sad_interleave[pvt->info.max_interleave];
	unsigned int		sad_interleave[MAX_INTERLEAVE];
	u32			reg, dram_rule;
	u8			ch_way, sck_way, pkg, sad_ha = 0;
	u32			tad_offset;
@@ -3169,7 +3172,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
		pvt->info.dram_attr = dram_attr;
		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
		pvt->info.interleave_list = ibridge_interleave_list;
		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
		pvt->info.interleave_pkg = ibridge_interleave_pkg;
		pvt->info.get_width = ibridge_get_width;

@@ -3194,7 +3196,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
		pvt->info.dram_attr = dram_attr;
		pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule);
		pvt->info.interleave_list = sbridge_interleave_list;
		pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
		pvt->info.interleave_pkg = sbridge_interleave_pkg;
		pvt->info.get_width = sbridge_get_width;

@@ -3219,7 +3220,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
		pvt->info.dram_attr = dram_attr;
		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
		pvt->info.interleave_list = ibridge_interleave_list;
		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
		pvt->info.interleave_pkg = ibridge_interleave_pkg;
		pvt->info.get_width = ibridge_get_width;

@@ -3244,7 +3244,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
		pvt->info.dram_attr = dram_attr;
		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
		pvt->info.interleave_list = ibridge_interleave_list;
		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
		pvt->info.interleave_pkg = ibridge_interleave_pkg;
		pvt->info.get_width = broadwell_get_width;

@@ -3269,7 +3268,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
		pvt->info.dram_attr = dram_attr_knl;
		pvt->info.max_sad = ARRAY_SIZE(knl_dram_rule);
		pvt->info.interleave_list = knl_interleave_list;
		pvt->info.max_interleave = ARRAY_SIZE(knl_interleave_list);
		pvt->info.interleave_pkg = ibridge_interleave_pkg;
		pvt->info.get_width = knl_get_width;

Loading