]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
EDAC: Remove the legacy EDAC sysfs interface
authorAvadhut Naik <avadhut.naik@amd.com>
Thu, 6 Nov 2025 01:54:46 +0000 (01:54 +0000)
committerBorislav Petkov (AMD) <bp@alien8.de>
Thu, 6 Nov 2025 12:21:29 +0000 (13:21 +0100)
Commit

  199747106934 ("edac: add a new per-dimm API and make the old per-virtual-rank API obsolete")

introduced a new per-DIMM sysfs interface for EDAC making the old
per-virtual-rank sysfs interface obsolete.

Since this new sysfs interface was introduced more than a decade ago, remove
the obsolete legacy interface.

Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/20251106015727.1987246-1-avadhut.naik@amd.com
Documentation/admin-guide/RAS/main.rst
arch/loongarch/configs/loongson3_defconfig
drivers/edac/Kconfig
drivers/edac/edac_mc_sysfs.c

index 447bfde509fb6bb50e3454cfcd701be0a9f25c63..5a45db32c49b091b07cb1b0f94f32dd1d2fe062c 100644 (file)
@@ -406,24 +406,8 @@ index of the MC::
                   |->mc2
                   ....
 
-Under each ``mcX`` directory each ``csrowX`` is again represented by a
-``csrowX``, where ``X`` is the csrow index::
-
-       .../mc/mc0/
-               |
-               |->csrow0
-               |->csrow2
-               |->csrow3
-               ....
-
-Notice that there is no csrow1, which indicates that csrow0 is composed
-of a single ranked DIMMs. This should also apply in both Channels, in
-order to have dual-channel mode be operational. Since both csrow2 and
-csrow3 are populated, this indicates a dual ranked set of DIMMs for
-channels 0 and 1.
-
-Within each of the ``mcX`` and ``csrowX`` directories are several EDAC
-control and attribute files.
+Within each of the ``mcX`` directory are several EDAC control and
+attribute files.
 
 ``mcX`` directories
 -------------------
@@ -569,7 +553,7 @@ this ``X`` memory module:
                - Unbuffered-DDR
 
 .. [#f5] On some systems, the memory controller doesn't have any logic
-  to identify the memory module. On such systems, the directory is called ``rankX`` and works on a similar way as the ``csrowX`` directories.
+  to identify the memory module. On such systems, the directory is called ``rankX``.
   On modern Intel memory controllers, the memory controller identifies the
   memory modules directly. On such systems, the directory is called ``dimmX``.
 
@@ -577,126 +561,6 @@ this ``X`` memory module:
   symlinks inside the sysfs mapping that are automatically created by
   the sysfs subsystem. Currently, they serve no purpose.
 
-``csrowX`` directories
-----------------------
-
-When CONFIG_EDAC_LEGACY_SYSFS is enabled, sysfs will contain the ``csrowX``
-directories. As this API doesn't work properly for Rambus, FB-DIMMs and
-modern Intel Memory Controllers, this is being deprecated in favor of
-``dimmX`` directories.
-
-In the ``csrowX`` directories are EDAC control and attribute files for
-this ``X`` instance of csrow:
-
-
-- ``ue_count`` - Total Uncorrectable Errors count attribute file
-
-       This attribute file displays the total count of uncorrectable
-       errors that have occurred on this csrow. If panic_on_ue is set
-       this counter will not have a chance to increment, since EDAC
-       will panic the system.
-
-
-- ``ce_count`` - Total Correctable Errors count attribute file
-
-       This attribute file displays the total count of correctable
-       errors that have occurred on this csrow. This count is very
-       important to examine. CEs provide early indications that a
-       DIMM is beginning to fail. This count field should be
-       monitored for non-zero values and report such information
-       to the system administrator.
-
-
-- ``size_mb`` - Total memory managed by this csrow attribute file
-
-       This attribute file displays, in count of megabytes, the memory
-       that this csrow contains.
-
-
-- ``mem_type`` - Memory Type attribute file
-
-       This attribute file will display what type of memory is currently
-       on this csrow. Normally, either buffered or unbuffered memory.
-       Examples:
-
-               - Registered-DDR
-               - Unbuffered-DDR
-
-
-- ``edac_mode`` - EDAC Mode of operation attribute file
-
-       This attribute file will display what type of Error detection
-       and correction is being utilized.
-
-
-- ``dev_type`` - Device type attribute file
-
-       This attribute file will display what type of DRAM device is
-       being utilized on this DIMM.
-       Examples:
-
-               - x1
-               - x2
-               - x4
-               - x8
-
-
-- ``ch0_ce_count`` - Channel 0 CE Count attribute file
-
-       This attribute file will display the count of CEs on this
-       DIMM located in channel 0.
-
-
-- ``ch0_ue_count`` - Channel 0 UE Count attribute file
-
-       This attribute file will display the count of UEs on this
-       DIMM located in channel 0.
-
-
-- ``ch0_dimm_label`` - Channel 0 DIMM Label control file
-
-
-       This control file allows this DIMM to have a label assigned
-       to it. With this label in the module, when errors occur
-       the output can provide the DIMM label in the system log.
-       This becomes vital for panic events to isolate the
-       cause of the UE event.
-
-       DIMM Labels must be assigned after booting, with information
-       that correctly identifies the physical slot with its
-       silk screen label. This information is currently very
-       motherboard specific and determination of this information
-       must occur in userland at this time.
-
-
-- ``ch1_ce_count`` - Channel 1 CE Count attribute file
-
-
-       This attribute file will display the count of CEs on this
-       DIMM located in channel 1.
-
-
-- ``ch1_ue_count`` - Channel 1 UE Count attribute file
-
-
-       This attribute file will display the count of UEs on this
-       DIMM located in channel 0.
-
-
-- ``ch1_dimm_label`` - Channel 1 DIMM Label control file
-
-       This control file allows this DIMM to have a label assigned
-       to it. With this label in the module, when errors occur
-       the output can provide the DIMM label in the system log.
-       This becomes vital for panic events to isolate the
-       cause of the UE event.
-
-       DIMM Labels must be assigned after booting, with information
-       that correctly identifies the physical slot with its
-       silk screen label. This information is currently very
-       motherboard specific and determination of this information
-       must occur in userland at this time.
-
 
 System Logging
 --------------
index 3e838c229cd5ef8ce1c2c1d235fc1113b2a7a0d1..50e1304e7a6f4ad9b064b747c4925179f1cc2ba3 100644 (file)
@@ -917,7 +917,6 @@ CONFIG_MMC=y
 CONFIG_MMC_LOONGSON2=m
 CONFIG_INFINIBAND=m
 CONFIG_EDAC=y
-# CONFIG_EDAC_LEGACY_SYSFS is not set
 CONFIG_EDAC_LOONGSON=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_EFI=y
index 39352b9b7a7e453387efa34605151e4348333ddc..9a7ff42064e9bf05e68c3b0b816d19555d871f1d 100644 (file)
@@ -23,14 +23,6 @@ menuconfig EDAC
 
 if EDAC
 
-config EDAC_LEGACY_SYSFS
-       bool "EDAC legacy sysfs"
-       default y
-       help
-         Enable the compatibility sysfs nodes.
-         Use 'Y' if your edac utilities aren't ported to work with the newer
-         structures.
-
 config EDAC_DEBUG
        bool "Debugging"
        select DEBUG_FS
index 8689631f1905361ab39584ef31614adbb4ced2e1..091cc6aae8a998facd8c505baeeddee433570034 100644 (file)
@@ -115,401 +115,6 @@ static const char * const edac_caps[] = {
        [EDAC_S16ECD16ED] = "S16ECD16ED"
 };
 
-#ifdef CONFIG_EDAC_LEGACY_SYSFS
-/*
- * EDAC sysfs CSROW data structures and methods
- */
-
-#define to_csrow(k) container_of(k, struct csrow_info, dev)
-
-/*
- * We need it to avoid namespace conflicts between the legacy API
- * and the per-dimm/per-rank one
- */
-#define DEVICE_ATTR_LEGACY(_name, _mode, _show, _store) \
-       static struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store)
-
-struct dev_ch_attribute {
-       struct device_attribute attr;
-       unsigned int channel;
-};
-
-#define DEVICE_CHANNEL(_name, _mode, _show, _store, _var) \
-       static struct dev_ch_attribute dev_attr_legacy_##_name = \
-               { __ATTR(_name, _mode, _show, _store), (_var) }
-
-#define to_channel(k) (container_of(k, struct dev_ch_attribute, attr)->channel)
-
-/* Set of more default csrow<id> attribute show/store functions */
-static ssize_t csrow_ue_count_show(struct device *dev,
-                                  struct device_attribute *mattr, char *data)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-
-       return sysfs_emit(data, "%u\n", csrow->ue_count);
-}
-
-static ssize_t csrow_ce_count_show(struct device *dev,
-                                  struct device_attribute *mattr, char *data)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-
-       return sysfs_emit(data, "%u\n", csrow->ce_count);
-}
-
-static ssize_t csrow_size_show(struct device *dev,
-                              struct device_attribute *mattr, char *data)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-       int i;
-       u32 nr_pages = 0;
-
-       for (i = 0; i < csrow->nr_channels; i++)
-               nr_pages += csrow->channels[i]->dimm->nr_pages;
-       return sysfs_emit(data, "%u\n", PAGES_TO_MiB(nr_pages));
-}
-
-static ssize_t csrow_mem_type_show(struct device *dev,
-                                  struct device_attribute *mattr, char *data)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-
-       return sysfs_emit(data, "%s\n", edac_mem_types[csrow->channels[0]->dimm->mtype]);
-}
-
-static ssize_t csrow_dev_type_show(struct device *dev,
-                                  struct device_attribute *mattr, char *data)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-
-       return sysfs_emit(data, "%s\n", dev_types[csrow->channels[0]->dimm->dtype]);
-}
-
-static ssize_t csrow_edac_mode_show(struct device *dev,
-                                   struct device_attribute *mattr,
-                                   char *data)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-
-       return sysfs_emit(data, "%s\n", edac_caps[csrow->channels[0]->dimm->edac_mode]);
-}
-
-/* show/store functions for DIMM Label attributes */
-static ssize_t channel_dimm_label_show(struct device *dev,
-                                      struct device_attribute *mattr,
-                                      char *data)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-       unsigned int chan = to_channel(mattr);
-       struct rank_info *rank = csrow->channels[chan];
-
-       /* if field has not been initialized, there is nothing to send */
-       if (!rank->dimm->label[0])
-               return 0;
-
-       return sysfs_emit(data, "%s\n", rank->dimm->label);
-}
-
-static ssize_t channel_dimm_label_store(struct device *dev,
-                                       struct device_attribute *mattr,
-                                       const char *data, size_t count)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-       unsigned int chan = to_channel(mattr);
-       struct rank_info *rank = csrow->channels[chan];
-       size_t copy_count = count;
-
-       if (count == 0)
-               return -EINVAL;
-
-       if (data[count - 1] == '\0' || data[count - 1] == '\n')
-               copy_count -= 1;
-
-       if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label))
-               return -EINVAL;
-
-       memcpy(rank->dimm->label, data, copy_count);
-       rank->dimm->label[copy_count] = '\0';
-
-       return count;
-}
-
-/* show function for dynamic chX_ce_count attribute */
-static ssize_t channel_ce_count_show(struct device *dev,
-                                    struct device_attribute *mattr, char *data)
-{
-       struct csrow_info *csrow = to_csrow(dev);
-       unsigned int chan = to_channel(mattr);
-       struct rank_info *rank = csrow->channels[chan];
-
-       return sysfs_emit(data, "%u\n", rank->ce_count);
-}
-
-/* cwrow<id>/attribute files */
-DEVICE_ATTR_LEGACY(size_mb, S_IRUGO, csrow_size_show, NULL);
-DEVICE_ATTR_LEGACY(dev_type, S_IRUGO, csrow_dev_type_show, NULL);
-DEVICE_ATTR_LEGACY(mem_type, S_IRUGO, csrow_mem_type_show, NULL);
-DEVICE_ATTR_LEGACY(edac_mode, S_IRUGO, csrow_edac_mode_show, NULL);
-DEVICE_ATTR_LEGACY(ue_count, S_IRUGO, csrow_ue_count_show, NULL);
-DEVICE_ATTR_LEGACY(ce_count, S_IRUGO, csrow_ce_count_show, NULL);
-
-/* default attributes of the CSROW<id> object */
-static struct attribute *csrow_attrs[] = {
-       &dev_attr_legacy_dev_type.attr,
-       &dev_attr_legacy_mem_type.attr,
-       &dev_attr_legacy_edac_mode.attr,
-       &dev_attr_legacy_size_mb.attr,
-       &dev_attr_legacy_ue_count.attr,
-       &dev_attr_legacy_ce_count.attr,
-       NULL,
-};
-
-static const struct attribute_group csrow_attr_grp = {
-       .attrs  = csrow_attrs,
-};
-
-static const struct attribute_group *csrow_attr_groups[] = {
-       &csrow_attr_grp,
-       NULL
-};
-
-static const struct device_type csrow_attr_type = {
-       .groups         = csrow_attr_groups,
-};
-
-/*
- * possible dynamic channel DIMM Label attribute files
- *
- */
-DEVICE_CHANNEL(ch0_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 0);
-DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 1);
-DEVICE_CHANNEL(ch2_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 2);
-DEVICE_CHANNEL(ch3_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 3);
-DEVICE_CHANNEL(ch4_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 4);
-DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 5);
-DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 6);
-DEVICE_CHANNEL(ch7_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 7);
-DEVICE_CHANNEL(ch8_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 8);
-DEVICE_CHANNEL(ch9_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 9);
-DEVICE_CHANNEL(ch10_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 10);
-DEVICE_CHANNEL(ch11_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 11);
-DEVICE_CHANNEL(ch12_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 12);
-DEVICE_CHANNEL(ch13_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 13);
-DEVICE_CHANNEL(ch14_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 14);
-DEVICE_CHANNEL(ch15_dimm_label, S_IRUGO | S_IWUSR,
-       channel_dimm_label_show, channel_dimm_label_store, 15);
-
-/* Total possible dynamic DIMM Label attribute file table */
-static struct attribute *dynamic_csrow_dimm_attr[] = {
-       &dev_attr_legacy_ch0_dimm_label.attr.attr,
-       &dev_attr_legacy_ch1_dimm_label.attr.attr,
-       &dev_attr_legacy_ch2_dimm_label.attr.attr,
-       &dev_attr_legacy_ch3_dimm_label.attr.attr,
-       &dev_attr_legacy_ch4_dimm_label.attr.attr,
-       &dev_attr_legacy_ch5_dimm_label.attr.attr,
-       &dev_attr_legacy_ch6_dimm_label.attr.attr,
-       &dev_attr_legacy_ch7_dimm_label.attr.attr,
-       &dev_attr_legacy_ch8_dimm_label.attr.attr,
-       &dev_attr_legacy_ch9_dimm_label.attr.attr,
-       &dev_attr_legacy_ch10_dimm_label.attr.attr,
-       &dev_attr_legacy_ch11_dimm_label.attr.attr,
-       &dev_attr_legacy_ch12_dimm_label.attr.attr,
-       &dev_attr_legacy_ch13_dimm_label.attr.attr,
-       &dev_attr_legacy_ch14_dimm_label.attr.attr,
-       &dev_attr_legacy_ch15_dimm_label.attr.attr,
-       NULL
-};
-
-/* possible dynamic channel ce_count attribute files */
-DEVICE_CHANNEL(ch0_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 0);
-DEVICE_CHANNEL(ch1_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 1);
-DEVICE_CHANNEL(ch2_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 2);
-DEVICE_CHANNEL(ch3_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 3);
-DEVICE_CHANNEL(ch4_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 4);
-DEVICE_CHANNEL(ch5_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 5);
-DEVICE_CHANNEL(ch6_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 6);
-DEVICE_CHANNEL(ch7_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 7);
-DEVICE_CHANNEL(ch8_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 8);
-DEVICE_CHANNEL(ch9_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 9);
-DEVICE_CHANNEL(ch10_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 10);
-DEVICE_CHANNEL(ch11_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 11);
-DEVICE_CHANNEL(ch12_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 12);
-DEVICE_CHANNEL(ch13_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 13);
-DEVICE_CHANNEL(ch14_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 14);
-DEVICE_CHANNEL(ch15_ce_count, S_IRUGO,
-                  channel_ce_count_show, NULL, 15);
-
-/* Total possible dynamic ce_count attribute file table */
-static struct attribute *dynamic_csrow_ce_count_attr[] = {
-       &dev_attr_legacy_ch0_ce_count.attr.attr,
-       &dev_attr_legacy_ch1_ce_count.attr.attr,
-       &dev_attr_legacy_ch2_ce_count.attr.attr,
-       &dev_attr_legacy_ch3_ce_count.attr.attr,
-       &dev_attr_legacy_ch4_ce_count.attr.attr,
-       &dev_attr_legacy_ch5_ce_count.attr.attr,
-       &dev_attr_legacy_ch6_ce_count.attr.attr,
-       &dev_attr_legacy_ch7_ce_count.attr.attr,
-       &dev_attr_legacy_ch8_ce_count.attr.attr,
-       &dev_attr_legacy_ch9_ce_count.attr.attr,
-       &dev_attr_legacy_ch10_ce_count.attr.attr,
-       &dev_attr_legacy_ch11_ce_count.attr.attr,
-       &dev_attr_legacy_ch12_ce_count.attr.attr,
-       &dev_attr_legacy_ch13_ce_count.attr.attr,
-       &dev_attr_legacy_ch14_ce_count.attr.attr,
-       &dev_attr_legacy_ch15_ce_count.attr.attr,
-       NULL
-};
-
-static umode_t csrow_dev_is_visible(struct kobject *kobj,
-                                   struct attribute *attr, int idx)
-{
-       struct device *dev = kobj_to_dev(kobj);
-       struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
-
-       if (idx >= csrow->nr_channels)
-               return 0;
-
-       if (idx >= ARRAY_SIZE(dynamic_csrow_ce_count_attr) - 1) {
-               WARN_ONCE(1, "idx: %d\n", idx);
-               return 0;
-       }
-
-       /* Only expose populated DIMMs */
-       if (!csrow->channels[idx]->dimm->nr_pages)
-               return 0;
-
-       return attr->mode;
-}
-
-
-static const struct attribute_group csrow_dev_dimm_group = {
-       .attrs = dynamic_csrow_dimm_attr,
-       .is_visible = csrow_dev_is_visible,
-};
-
-static const struct attribute_group csrow_dev_ce_count_group = {
-       .attrs = dynamic_csrow_ce_count_attr,
-       .is_visible = csrow_dev_is_visible,
-};
-
-static const struct attribute_group *csrow_dev_groups[] = {
-       &csrow_dev_dimm_group,
-       &csrow_dev_ce_count_group,
-       NULL
-};
-
-static void csrow_release(struct device *dev)
-{
-       /*
-        * Nothing to do, just unregister sysfs here. The mci
-        * device owns the data and will also release it.
-        */
-}
-
-static inline int nr_pages_per_csrow(struct csrow_info *csrow)
-{
-       int chan, nr_pages = 0;
-
-       for (chan = 0; chan < csrow->nr_channels; chan++)
-               nr_pages += csrow->channels[chan]->dimm->nr_pages;
-
-       return nr_pages;
-}
-
-/* Create a CSROW object under specified edac_mc_device */
-static int edac_create_csrow_object(struct mem_ctl_info *mci,
-                                   struct csrow_info *csrow, int index)
-{
-       int err;
-
-       csrow->dev.type = &csrow_attr_type;
-       csrow->dev.groups = csrow_dev_groups;
-       csrow->dev.release = csrow_release;
-       device_initialize(&csrow->dev);
-       csrow->dev.parent = &mci->dev;
-       csrow->mci = mci;
-       dev_set_name(&csrow->dev, "csrow%d", index);
-       dev_set_drvdata(&csrow->dev, csrow);
-
-       err = device_add(&csrow->dev);
-       if (err) {
-               edac_dbg(1, "failure: create device %s\n", dev_name(&csrow->dev));
-               put_device(&csrow->dev);
-               return err;
-       }
-
-       edac_dbg(0, "device %s created\n", dev_name(&csrow->dev));
-
-       return 0;
-}
-
-/* Create a CSROW object under specified edac_mc_device */
-static int edac_create_csrow_objects(struct mem_ctl_info *mci)
-{
-       int err, i;
-       struct csrow_info *csrow;
-
-       for (i = 0; i < mci->nr_csrows; i++) {
-               csrow = mci->csrows[i];
-               if (!nr_pages_per_csrow(csrow))
-                       continue;
-               err = edac_create_csrow_object(mci, mci->csrows[i], i);
-               if (err < 0)
-                       goto error;
-       }
-       return 0;
-
-error:
-       for (--i; i >= 0; i--) {
-               if (device_is_registered(&mci->csrows[i]->dev))
-                       device_unregister(&mci->csrows[i]->dev);
-       }
-
-       return err;
-}
-
-static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
-{
-       int i;
-
-       for (i = 0; i < mci->nr_csrows; i++) {
-               if (device_is_registered(&mci->csrows[i]->dev))
-                       device_unregister(&mci->csrows[i]->dev);
-       }
-}
-
-#endif
-
 /*
  * Per-dimm (or per-rank) devices
  */
@@ -989,12 +594,6 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
                        goto fail;
        }
 
-#ifdef CONFIG_EDAC_LEGACY_SYSFS
-       err = edac_create_csrow_objects(mci);
-       if (err < 0)
-               goto fail;
-#endif
-
        edac_create_debugfs_nodes(mci);
        return 0;
 
@@ -1019,9 +618,6 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
 #ifdef CONFIG_EDAC_DEBUG
        edac_debugfs_remove_recursive(mci->debugfs);
 #endif
-#ifdef CONFIG_EDAC_LEGACY_SYSFS
-       edac_delete_csrow_objects(mci);
-#endif
 
        mci_for_each_dimm(mci, dimm) {
                if (!device_is_registered(&dimm->dev))