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

Commit b271b212 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull EDAC updates from Borislav Petkov:

 - Support for ZynqMP DDR controller support to synopsys_edac along with
   a driver cleanup and generalization for the addition of support for
   the new IP. (Manish Narani)

 - Removal of the /sys/bus/edac devices hierarchy. This enabled us to
   get rid of the silly memory controllers maximum number notion. (Tony
   Luck and Borislav Petkov)

 - skx_edac improvements and fixes. (Qiuxu Zhuo and Tony Luck)

 - The usual garden variety of small cleanups and fixes.

* tag 'edac_for_4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp: (25 commits)
  EDAC, fsl_ddr: Add LS1021A to the list of supported hardware
  EDAC, i5000: Remove set but not used local variables
  MAINTAINERS, EDAC: Drop bouncing email
  EDAC, i82975x: Fix spelling mistake "reserverd" -> "reserved"
  EDAC, fsl: Move error injection under CONFIG_EDAC_DEBUG
  EDAC, skx: Let EDAC core show the decoded result for debugfs
  EDAC, skx: Move debugfs node under EDAC's hierarchy
  EDAC, skx: Prepend hex formatting with '0x'
  EDAC, skx: Fix function calling order in skx_exit()
  EDAC: Drop per-memory controller buses
  EDAC: Don't add devices under /sys/bus/edac
  EDAC: Fix indentation issues in several EDAC drivers
  EDAC, skx: Fix randconfig builds in a better way
  EDAC, i82975x: Remove set but not used variable dtype
  EDAC, qcom_edac: Remove irq_handled local variable
  EDAC, synopsys: Add Error Injection support for ZynqMP DDR controller
  EDAC, synopsys: Add ECC support for ZynqMP DDR controller
  EDAC, synopsys: Add macro defines for ZynqMP DDRC
  dt: bindings: Document ZynqMP DDRC in Synopsys documentation
  EDAC, synopsys: Add error handling for the of_device_get_match_data() result
  ...
parents 8e61e7b5 75dfa870
Loading
Loading
Loading
Loading
+22 −5
Original line number Original line Diff line number Diff line
Binding for Synopsys IntelliDDR Multi Protocol Memory Controller
Binding for Synopsys IntelliDDR Multi Protocol Memory Controller


This controller has an optional ECC support in half-bus width (16-bit)
The ZynqMP DDR ECC controller has an optional ECC support in 64-bit and 32-bit
configuration. The ECC controller corrects one bit error and detects
bus width configurations.
two bit errors.

The Zynq DDR ECC controller has an optional ECC support in half-bus width
(16-bit) configuration.

These both ECC controllers correct single bit ECC errors and detect double bit
ECC errors.


Required properties:
Required properties:
 - compatible: Should be 'xlnx,zynq-ddrc-a05'
 - compatible: One of:
 - reg: Base address and size of the controllers memory area
	- 'xlnx,zynq-ddrc-a05' : Zynq DDR ECC controller
	- 'xlnx,zynqmp-ddrc-2.40a' : ZynqMP DDR ECC controller
 - reg: Should contain DDR controller registers location and length.

Required properties for "xlnx,zynqmp-ddrc-2.40a":
 - interrupts: Property with a value describing the interrupt number.


Example:
Example:
	memory-controller@f8006000 {
	memory-controller@f8006000 {
		compatible = "xlnx,zynq-ddrc-a05";
		compatible = "xlnx,zynq-ddrc-a05";
		reg = <0xf8006000 0x1000>;
		reg = <0xf8006000 0x1000>;
	};
	};

	mc: memory-controller@fd070000 {
		compatible = "xlnx,zynqmp-ddrc-2.40a";
		reg = <0x0 0xfd070000 0x0 0x30000>;
		interrupt-parent = <&gic>;
		interrupts = <0 112 4>;
	};
+0 −1
Original line number Original line Diff line number Diff line
@@ -5445,7 +5445,6 @@ S: Maintained
F:	drivers/edac/i82443bxgx_edac.c
F:	drivers/edac/i82443bxgx_edac.c


EDAC-I82975X
EDAC-I82975X
M:	Ranganathan Desikan <ravi@jetztechnologies.com>
M:	"Arvind R." <arvino55@gmail.com>
M:	"Arvind R." <arvino55@gmail.com>
L:	linux-edac@vger.kernel.org
L:	linux-edac@vger.kernel.org
S:	Maintained
S:	Maintained
+3 −3
Original line number Original line Diff line number Diff line
@@ -231,10 +231,10 @@ config EDAC_SBRIDGE


config EDAC_SKX
config EDAC_SKX
	tristate "Intel Skylake server Integrated MC"
	tristate "Intel Skylake server Integrated MC"
	depends on PCI && X86_64 && X86_MCE_INTEL && PCI_MMCONFIG
	depends on PCI && X86_64 && X86_MCE_INTEL && PCI_MMCONFIG && ACPI
	depends on ACPI_NFIT || !ACPI_NFIT # if ACPI_NFIT=m, EDAC_SKX can't be y
	depends on ACPI_NFIT || !ACPI_NFIT # if ACPI_NFIT=m, EDAC_SKX can't be y
	select DMI
	select DMI
	select ACPI_ADXL if ACPI
	select ACPI_ADXL
	help
	help
	  Support for error detection and correction the Intel
	  Support for error detection and correction the Intel
	  Skylake server Integrated Memory Controllers. If your
	  Skylake server Integrated Memory Controllers. If your
@@ -442,7 +442,7 @@ config EDAC_ALTERA_SDMMC


config EDAC_SYNOPSYS
config EDAC_SYNOPSYS
	tristate "Synopsys DDR Memory Controller"
	tristate "Synopsys DDR Memory Controller"
	depends on ARCH_ZYNQ
	depends on ARCH_ZYNQ || ARCH_ZYNQMP
	help
	help
	  Support for error detection and correction on the Synopsys DDR
	  Support for error detection and correction on the Synopsys DDR
	  memory controller.
	  memory controller.
+1 −8
Original line number Original line Diff line number Diff line
@@ -55,8 +55,6 @@ static LIST_HEAD(mc_devices);
 */
 */
static const char *edac_mc_owner;
static const char *edac_mc_owner;


static struct bus_type mc_bus[EDAC_MAX_MCS];

int edac_get_report_status(void)
int edac_get_report_status(void)
{
{
	return edac_report;
	return edac_report;
@@ -716,11 +714,6 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
	int ret = -EINVAL;
	int ret = -EINVAL;
	edac_dbg(0, "\n");
	edac_dbg(0, "\n");


	if (mci->mc_idx >= EDAC_MAX_MCS) {
		pr_warn_once("Too many memory controllers: %d\n", mci->mc_idx);
		return -ENODEV;
	}

#ifdef CONFIG_EDAC_DEBUG
#ifdef CONFIG_EDAC_DEBUG
	if (edac_debug_level >= 3)
	if (edac_debug_level >= 3)
		edac_mc_dump_mci(mci);
		edac_mc_dump_mci(mci);
@@ -760,7 +753,7 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
	/* set load time so that error rate can be tracked */
	/* set load time so that error rate can be tracked */
	mci->start_time = jiffies;
	mci->start_time = jiffies;


	mci->bus = &mc_bus[mci->mc_idx];
	mci->bus = edac_get_sysfs_subsys();


	if (edac_create_sysfs_mci_device(mci, groups)) {
	if (edac_create_sysfs_mci_device(mci, groups)) {
		edac_mc_printk(mci, KERN_WARNING,
		edac_mc_printk(mci, KERN_WARNING,
+2 −31
Original line number Original line Diff line number Diff line
@@ -405,7 +405,6 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
				    struct csrow_info *csrow, int index)
				    struct csrow_info *csrow, int index)
{
{
	csrow->dev.type = &csrow_attr_type;
	csrow->dev.type = &csrow_attr_type;
	csrow->dev.bus = mci->bus;
	csrow->dev.groups = csrow_dev_groups;
	csrow->dev.groups = csrow_dev_groups;
	device_initialize(&csrow->dev);
	device_initialize(&csrow->dev);
	csrow->dev.parent = &mci->dev;
	csrow->dev.parent = &mci->dev;
@@ -636,7 +635,6 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci,
	dimm->mci = mci;
	dimm->mci = mci;


	dimm->dev.type = &dimm_attr_type;
	dimm->dev.type = &dimm_attr_type;
	dimm->dev.bus = mci->bus;
	device_initialize(&dimm->dev);
	device_initialize(&dimm->dev);


	dimm->dev.parent = &mci->dev;
	dimm->dev.parent = &mci->dev;
@@ -914,33 +912,13 @@ static const struct device_type mci_attr_type = {
int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
				 const struct attribute_group **groups)
				 const struct attribute_group **groups)
{
{
	char *name;
	int i, err;
	int i, err;


	/*
	 * The memory controller needs its own bus, in order to avoid
	 * namespace conflicts at /sys/bus/edac.
	 */
	name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
	if (!name)
		return -ENOMEM;

	mci->bus->name = name;

	edac_dbg(0, "creating bus %s\n", mci->bus->name);

	err = bus_register(mci->bus);
	if (err < 0) {
		kfree(name);
		return err;
	}

	/* get the /sys/devices/system/edac subsys reference */
	/* get the /sys/devices/system/edac subsys reference */
	mci->dev.type = &mci_attr_type;
	mci->dev.type = &mci_attr_type;
	device_initialize(&mci->dev);
	device_initialize(&mci->dev);


	mci->dev.parent = mci_pdev;
	mci->dev.parent = mci_pdev;
	mci->dev.bus = mci->bus;
	mci->dev.groups = groups;
	mci->dev.groups = groups;
	dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
	dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
	dev_set_drvdata(&mci->dev, mci);
	dev_set_drvdata(&mci->dev, mci);
@@ -950,7 +928,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
	err = device_add(&mci->dev);
	err = device_add(&mci->dev);
	if (err < 0) {
	if (err < 0) {
		edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev));
		edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev));
		goto fail_unregister_bus;
		goto out;
	}
	}


	/*
	/*
@@ -998,10 +976,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
		device_unregister(&dimm->dev);
		device_unregister(&dimm->dev);
	}
	}
	device_unregister(&mci->dev);
	device_unregister(&mci->dev);
fail_unregister_bus:
	bus_unregister(mci->bus);
	kfree(name);


out:
	return err;
	return err;
}
}


@@ -1032,13 +1008,8 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)


void edac_unregister_sysfs(struct mem_ctl_info *mci)
void edac_unregister_sysfs(struct mem_ctl_info *mci)
{
{
	struct bus_type *bus = mci->bus;
	const char *name = mci->bus->name;

	edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
	edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
	device_unregister(&mci->dev);
	device_unregister(&mci->dev);
	bus_unregister(bus);
	kfree(name);
}
}


static void mc_attr_release(struct device *dev)
static void mc_attr_release(struct device *dev)
Loading