Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

EDAC: Remove the legacy EDAC sysfs interface

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

authored by

Avadhut Naik and committed by
Borislav Petkov (AMD)
8616025a 6a857969

+3 -552
+3 -139
Documentation/admin-guide/RAS/main.rst
··· 406 406 |->mc2 407 407 .... 408 408 409 - Under each ``mcX`` directory each ``csrowX`` is again represented by a 410 - ``csrowX``, where ``X`` is the csrow index:: 411 - 412 - .../mc/mc0/ 413 - | 414 - |->csrow0 415 - |->csrow2 416 - |->csrow3 417 - .... 418 - 419 - Notice that there is no csrow1, which indicates that csrow0 is composed 420 - of a single ranked DIMMs. This should also apply in both Channels, in 421 - order to have dual-channel mode be operational. Since both csrow2 and 422 - csrow3 are populated, this indicates a dual ranked set of DIMMs for 423 - channels 0 and 1. 424 - 425 - Within each of the ``mcX`` and ``csrowX`` directories are several EDAC 426 - control and attribute files. 409 + Within each of the ``mcX`` directory are several EDAC control and 410 + attribute files. 427 411 428 412 ``mcX`` directories 429 413 ------------------- ··· 553 569 - Unbuffered-DDR 554 570 555 571 .. [#f5] On some systems, the memory controller doesn't have any logic 556 - to identify the memory module. On such systems, the directory is called ``rankX`` and works on a similar way as the ``csrowX`` directories. 572 + to identify the memory module. On such systems, the directory is called ``rankX``. 557 573 On modern Intel memory controllers, the memory controller identifies the 558 574 memory modules directly. On such systems, the directory is called ``dimmX``. 559 575 560 576 .. [#f6] There are also some ``power`` directories and ``subsystem`` 561 577 symlinks inside the sysfs mapping that are automatically created by 562 578 the sysfs subsystem. Currently, they serve no purpose. 563 - 564 - ``csrowX`` directories 565 - ---------------------- 566 - 567 - When CONFIG_EDAC_LEGACY_SYSFS is enabled, sysfs will contain the ``csrowX`` 568 - directories. As this API doesn't work properly for Rambus, FB-DIMMs and 569 - modern Intel Memory Controllers, this is being deprecated in favor of 570 - ``dimmX`` directories. 571 - 572 - In the ``csrowX`` directories are EDAC control and attribute files for 573 - this ``X`` instance of csrow: 574 - 575 - 576 - - ``ue_count`` - Total Uncorrectable Errors count attribute file 577 - 578 - This attribute file displays the total count of uncorrectable 579 - errors that have occurred on this csrow. If panic_on_ue is set 580 - this counter will not have a chance to increment, since EDAC 581 - will panic the system. 582 - 583 - 584 - - ``ce_count`` - Total Correctable Errors count attribute file 585 - 586 - This attribute file displays the total count of correctable 587 - errors that have occurred on this csrow. This count is very 588 - important to examine. CEs provide early indications that a 589 - DIMM is beginning to fail. This count field should be 590 - monitored for non-zero values and report such information 591 - to the system administrator. 592 - 593 - 594 - - ``size_mb`` - Total memory managed by this csrow attribute file 595 - 596 - This attribute file displays, in count of megabytes, the memory 597 - that this csrow contains. 598 - 599 - 600 - - ``mem_type`` - Memory Type attribute file 601 - 602 - This attribute file will display what type of memory is currently 603 - on this csrow. Normally, either buffered or unbuffered memory. 604 - Examples: 605 - 606 - - Registered-DDR 607 - - Unbuffered-DDR 608 - 609 - 610 - - ``edac_mode`` - EDAC Mode of operation attribute file 611 - 612 - This attribute file will display what type of Error detection 613 - and correction is being utilized. 614 - 615 - 616 - - ``dev_type`` - Device type attribute file 617 - 618 - This attribute file will display what type of DRAM device is 619 - being utilized on this DIMM. 620 - Examples: 621 - 622 - - x1 623 - - x2 624 - - x4 625 - - x8 626 - 627 - 628 - - ``ch0_ce_count`` - Channel 0 CE Count attribute file 629 - 630 - This attribute file will display the count of CEs on this 631 - DIMM located in channel 0. 632 - 633 - 634 - - ``ch0_ue_count`` - Channel 0 UE Count attribute file 635 - 636 - This attribute file will display the count of UEs on this 637 - DIMM located in channel 0. 638 - 639 - 640 - - ``ch0_dimm_label`` - Channel 0 DIMM Label control file 641 - 642 - 643 - This control file allows this DIMM to have a label assigned 644 - to it. With this label in the module, when errors occur 645 - the output can provide the DIMM label in the system log. 646 - This becomes vital for panic events to isolate the 647 - cause of the UE event. 648 - 649 - DIMM Labels must be assigned after booting, with information 650 - that correctly identifies the physical slot with its 651 - silk screen label. This information is currently very 652 - motherboard specific and determination of this information 653 - must occur in userland at this time. 654 - 655 - 656 - - ``ch1_ce_count`` - Channel 1 CE Count attribute file 657 - 658 - 659 - This attribute file will display the count of CEs on this 660 - DIMM located in channel 1. 661 - 662 - 663 - - ``ch1_ue_count`` - Channel 1 UE Count attribute file 664 - 665 - 666 - This attribute file will display the count of UEs on this 667 - DIMM located in channel 0. 668 - 669 - 670 - - ``ch1_dimm_label`` - Channel 1 DIMM Label control file 671 - 672 - This control file allows this DIMM to have a label assigned 673 - to it. With this label in the module, when errors occur 674 - the output can provide the DIMM label in the system log. 675 - This becomes vital for panic events to isolate the 676 - cause of the UE event. 677 - 678 - DIMM Labels must be assigned after booting, with information 679 - that correctly identifies the physical slot with its 680 - silk screen label. This information is currently very 681 - motherboard specific and determination of this information 682 - must occur in userland at this time. 683 579 684 580 685 581 System Logging
-1
arch/loongarch/configs/loongson3_defconfig
··· 917 917 CONFIG_MMC_LOONGSON2=m 918 918 CONFIG_INFINIBAND=m 919 919 CONFIG_EDAC=y 920 - # CONFIG_EDAC_LEGACY_SYSFS is not set 921 920 CONFIG_EDAC_LOONGSON=y 922 921 CONFIG_RTC_CLASS=y 923 922 CONFIG_RTC_DRV_EFI=y
-8
drivers/edac/Kconfig
··· 23 23 24 24 if EDAC 25 25 26 - config EDAC_LEGACY_SYSFS 27 - bool "EDAC legacy sysfs" 28 - default y 29 - help 30 - Enable the compatibility sysfs nodes. 31 - Use 'Y' if your edac utilities aren't ported to work with the newer 32 - structures. 33 - 34 26 config EDAC_DEBUG 35 27 bool "Debugging" 36 28 select DEBUG_FS
-404
drivers/edac/edac_mc_sysfs.c
··· 115 115 [EDAC_S16ECD16ED] = "S16ECD16ED" 116 116 }; 117 117 118 - #ifdef CONFIG_EDAC_LEGACY_SYSFS 119 - /* 120 - * EDAC sysfs CSROW data structures and methods 121 - */ 122 - 123 - #define to_csrow(k) container_of(k, struct csrow_info, dev) 124 - 125 - /* 126 - * We need it to avoid namespace conflicts between the legacy API 127 - * and the per-dimm/per-rank one 128 - */ 129 - #define DEVICE_ATTR_LEGACY(_name, _mode, _show, _store) \ 130 - static struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store) 131 - 132 - struct dev_ch_attribute { 133 - struct device_attribute attr; 134 - unsigned int channel; 135 - }; 136 - 137 - #define DEVICE_CHANNEL(_name, _mode, _show, _store, _var) \ 138 - static struct dev_ch_attribute dev_attr_legacy_##_name = \ 139 - { __ATTR(_name, _mode, _show, _store), (_var) } 140 - 141 - #define to_channel(k) (container_of(k, struct dev_ch_attribute, attr)->channel) 142 - 143 - /* Set of more default csrow<id> attribute show/store functions */ 144 - static ssize_t csrow_ue_count_show(struct device *dev, 145 - struct device_attribute *mattr, char *data) 146 - { 147 - struct csrow_info *csrow = to_csrow(dev); 148 - 149 - return sysfs_emit(data, "%u\n", csrow->ue_count); 150 - } 151 - 152 - static ssize_t csrow_ce_count_show(struct device *dev, 153 - struct device_attribute *mattr, char *data) 154 - { 155 - struct csrow_info *csrow = to_csrow(dev); 156 - 157 - return sysfs_emit(data, "%u\n", csrow->ce_count); 158 - } 159 - 160 - static ssize_t csrow_size_show(struct device *dev, 161 - struct device_attribute *mattr, char *data) 162 - { 163 - struct csrow_info *csrow = to_csrow(dev); 164 - int i; 165 - u32 nr_pages = 0; 166 - 167 - for (i = 0; i < csrow->nr_channels; i++) 168 - nr_pages += csrow->channels[i]->dimm->nr_pages; 169 - return sysfs_emit(data, "%u\n", PAGES_TO_MiB(nr_pages)); 170 - } 171 - 172 - static ssize_t csrow_mem_type_show(struct device *dev, 173 - struct device_attribute *mattr, char *data) 174 - { 175 - struct csrow_info *csrow = to_csrow(dev); 176 - 177 - return sysfs_emit(data, "%s\n", edac_mem_types[csrow->channels[0]->dimm->mtype]); 178 - } 179 - 180 - static ssize_t csrow_dev_type_show(struct device *dev, 181 - struct device_attribute *mattr, char *data) 182 - { 183 - struct csrow_info *csrow = to_csrow(dev); 184 - 185 - return sysfs_emit(data, "%s\n", dev_types[csrow->channels[0]->dimm->dtype]); 186 - } 187 - 188 - static ssize_t csrow_edac_mode_show(struct device *dev, 189 - struct device_attribute *mattr, 190 - char *data) 191 - { 192 - struct csrow_info *csrow = to_csrow(dev); 193 - 194 - return sysfs_emit(data, "%s\n", edac_caps[csrow->channels[0]->dimm->edac_mode]); 195 - } 196 - 197 - /* show/store functions for DIMM Label attributes */ 198 - static ssize_t channel_dimm_label_show(struct device *dev, 199 - struct device_attribute *mattr, 200 - char *data) 201 - { 202 - struct csrow_info *csrow = to_csrow(dev); 203 - unsigned int chan = to_channel(mattr); 204 - struct rank_info *rank = csrow->channels[chan]; 205 - 206 - /* if field has not been initialized, there is nothing to send */ 207 - if (!rank->dimm->label[0]) 208 - return 0; 209 - 210 - return sysfs_emit(data, "%s\n", rank->dimm->label); 211 - } 212 - 213 - static ssize_t channel_dimm_label_store(struct device *dev, 214 - struct device_attribute *mattr, 215 - const char *data, size_t count) 216 - { 217 - struct csrow_info *csrow = to_csrow(dev); 218 - unsigned int chan = to_channel(mattr); 219 - struct rank_info *rank = csrow->channels[chan]; 220 - size_t copy_count = count; 221 - 222 - if (count == 0) 223 - return -EINVAL; 224 - 225 - if (data[count - 1] == '\0' || data[count - 1] == '\n') 226 - copy_count -= 1; 227 - 228 - if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label)) 229 - return -EINVAL; 230 - 231 - memcpy(rank->dimm->label, data, copy_count); 232 - rank->dimm->label[copy_count] = '\0'; 233 - 234 - return count; 235 - } 236 - 237 - /* show function for dynamic chX_ce_count attribute */ 238 - static ssize_t channel_ce_count_show(struct device *dev, 239 - struct device_attribute *mattr, char *data) 240 - { 241 - struct csrow_info *csrow = to_csrow(dev); 242 - unsigned int chan = to_channel(mattr); 243 - struct rank_info *rank = csrow->channels[chan]; 244 - 245 - return sysfs_emit(data, "%u\n", rank->ce_count); 246 - } 247 - 248 - /* cwrow<id>/attribute files */ 249 - DEVICE_ATTR_LEGACY(size_mb, S_IRUGO, csrow_size_show, NULL); 250 - DEVICE_ATTR_LEGACY(dev_type, S_IRUGO, csrow_dev_type_show, NULL); 251 - DEVICE_ATTR_LEGACY(mem_type, S_IRUGO, csrow_mem_type_show, NULL); 252 - DEVICE_ATTR_LEGACY(edac_mode, S_IRUGO, csrow_edac_mode_show, NULL); 253 - DEVICE_ATTR_LEGACY(ue_count, S_IRUGO, csrow_ue_count_show, NULL); 254 - DEVICE_ATTR_LEGACY(ce_count, S_IRUGO, csrow_ce_count_show, NULL); 255 - 256 - /* default attributes of the CSROW<id> object */ 257 - static struct attribute *csrow_attrs[] = { 258 - &dev_attr_legacy_dev_type.attr, 259 - &dev_attr_legacy_mem_type.attr, 260 - &dev_attr_legacy_edac_mode.attr, 261 - &dev_attr_legacy_size_mb.attr, 262 - &dev_attr_legacy_ue_count.attr, 263 - &dev_attr_legacy_ce_count.attr, 264 - NULL, 265 - }; 266 - 267 - static const struct attribute_group csrow_attr_grp = { 268 - .attrs = csrow_attrs, 269 - }; 270 - 271 - static const struct attribute_group *csrow_attr_groups[] = { 272 - &csrow_attr_grp, 273 - NULL 274 - }; 275 - 276 - static const struct device_type csrow_attr_type = { 277 - .groups = csrow_attr_groups, 278 - }; 279 - 280 - /* 281 - * possible dynamic channel DIMM Label attribute files 282 - * 283 - */ 284 - DEVICE_CHANNEL(ch0_dimm_label, S_IRUGO | S_IWUSR, 285 - channel_dimm_label_show, channel_dimm_label_store, 0); 286 - DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR, 287 - channel_dimm_label_show, channel_dimm_label_store, 1); 288 - DEVICE_CHANNEL(ch2_dimm_label, S_IRUGO | S_IWUSR, 289 - channel_dimm_label_show, channel_dimm_label_store, 2); 290 - DEVICE_CHANNEL(ch3_dimm_label, S_IRUGO | S_IWUSR, 291 - channel_dimm_label_show, channel_dimm_label_store, 3); 292 - DEVICE_CHANNEL(ch4_dimm_label, S_IRUGO | S_IWUSR, 293 - channel_dimm_label_show, channel_dimm_label_store, 4); 294 - DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR, 295 - channel_dimm_label_show, channel_dimm_label_store, 5); 296 - DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | S_IWUSR, 297 - channel_dimm_label_show, channel_dimm_label_store, 6); 298 - DEVICE_CHANNEL(ch7_dimm_label, S_IRUGO | S_IWUSR, 299 - channel_dimm_label_show, channel_dimm_label_store, 7); 300 - DEVICE_CHANNEL(ch8_dimm_label, S_IRUGO | S_IWUSR, 301 - channel_dimm_label_show, channel_dimm_label_store, 8); 302 - DEVICE_CHANNEL(ch9_dimm_label, S_IRUGO | S_IWUSR, 303 - channel_dimm_label_show, channel_dimm_label_store, 9); 304 - DEVICE_CHANNEL(ch10_dimm_label, S_IRUGO | S_IWUSR, 305 - channel_dimm_label_show, channel_dimm_label_store, 10); 306 - DEVICE_CHANNEL(ch11_dimm_label, S_IRUGO | S_IWUSR, 307 - channel_dimm_label_show, channel_dimm_label_store, 11); 308 - DEVICE_CHANNEL(ch12_dimm_label, S_IRUGO | S_IWUSR, 309 - channel_dimm_label_show, channel_dimm_label_store, 12); 310 - DEVICE_CHANNEL(ch13_dimm_label, S_IRUGO | S_IWUSR, 311 - channel_dimm_label_show, channel_dimm_label_store, 13); 312 - DEVICE_CHANNEL(ch14_dimm_label, S_IRUGO | S_IWUSR, 313 - channel_dimm_label_show, channel_dimm_label_store, 14); 314 - DEVICE_CHANNEL(ch15_dimm_label, S_IRUGO | S_IWUSR, 315 - channel_dimm_label_show, channel_dimm_label_store, 15); 316 - 317 - /* Total possible dynamic DIMM Label attribute file table */ 318 - static struct attribute *dynamic_csrow_dimm_attr[] = { 319 - &dev_attr_legacy_ch0_dimm_label.attr.attr, 320 - &dev_attr_legacy_ch1_dimm_label.attr.attr, 321 - &dev_attr_legacy_ch2_dimm_label.attr.attr, 322 - &dev_attr_legacy_ch3_dimm_label.attr.attr, 323 - &dev_attr_legacy_ch4_dimm_label.attr.attr, 324 - &dev_attr_legacy_ch5_dimm_label.attr.attr, 325 - &dev_attr_legacy_ch6_dimm_label.attr.attr, 326 - &dev_attr_legacy_ch7_dimm_label.attr.attr, 327 - &dev_attr_legacy_ch8_dimm_label.attr.attr, 328 - &dev_attr_legacy_ch9_dimm_label.attr.attr, 329 - &dev_attr_legacy_ch10_dimm_label.attr.attr, 330 - &dev_attr_legacy_ch11_dimm_label.attr.attr, 331 - &dev_attr_legacy_ch12_dimm_label.attr.attr, 332 - &dev_attr_legacy_ch13_dimm_label.attr.attr, 333 - &dev_attr_legacy_ch14_dimm_label.attr.attr, 334 - &dev_attr_legacy_ch15_dimm_label.attr.attr, 335 - NULL 336 - }; 337 - 338 - /* possible dynamic channel ce_count attribute files */ 339 - DEVICE_CHANNEL(ch0_ce_count, S_IRUGO, 340 - channel_ce_count_show, NULL, 0); 341 - DEVICE_CHANNEL(ch1_ce_count, S_IRUGO, 342 - channel_ce_count_show, NULL, 1); 343 - DEVICE_CHANNEL(ch2_ce_count, S_IRUGO, 344 - channel_ce_count_show, NULL, 2); 345 - DEVICE_CHANNEL(ch3_ce_count, S_IRUGO, 346 - channel_ce_count_show, NULL, 3); 347 - DEVICE_CHANNEL(ch4_ce_count, S_IRUGO, 348 - channel_ce_count_show, NULL, 4); 349 - DEVICE_CHANNEL(ch5_ce_count, S_IRUGO, 350 - channel_ce_count_show, NULL, 5); 351 - DEVICE_CHANNEL(ch6_ce_count, S_IRUGO, 352 - channel_ce_count_show, NULL, 6); 353 - DEVICE_CHANNEL(ch7_ce_count, S_IRUGO, 354 - channel_ce_count_show, NULL, 7); 355 - DEVICE_CHANNEL(ch8_ce_count, S_IRUGO, 356 - channel_ce_count_show, NULL, 8); 357 - DEVICE_CHANNEL(ch9_ce_count, S_IRUGO, 358 - channel_ce_count_show, NULL, 9); 359 - DEVICE_CHANNEL(ch10_ce_count, S_IRUGO, 360 - channel_ce_count_show, NULL, 10); 361 - DEVICE_CHANNEL(ch11_ce_count, S_IRUGO, 362 - channel_ce_count_show, NULL, 11); 363 - DEVICE_CHANNEL(ch12_ce_count, S_IRUGO, 364 - channel_ce_count_show, NULL, 12); 365 - DEVICE_CHANNEL(ch13_ce_count, S_IRUGO, 366 - channel_ce_count_show, NULL, 13); 367 - DEVICE_CHANNEL(ch14_ce_count, S_IRUGO, 368 - channel_ce_count_show, NULL, 14); 369 - DEVICE_CHANNEL(ch15_ce_count, S_IRUGO, 370 - channel_ce_count_show, NULL, 15); 371 - 372 - /* Total possible dynamic ce_count attribute file table */ 373 - static struct attribute *dynamic_csrow_ce_count_attr[] = { 374 - &dev_attr_legacy_ch0_ce_count.attr.attr, 375 - &dev_attr_legacy_ch1_ce_count.attr.attr, 376 - &dev_attr_legacy_ch2_ce_count.attr.attr, 377 - &dev_attr_legacy_ch3_ce_count.attr.attr, 378 - &dev_attr_legacy_ch4_ce_count.attr.attr, 379 - &dev_attr_legacy_ch5_ce_count.attr.attr, 380 - &dev_attr_legacy_ch6_ce_count.attr.attr, 381 - &dev_attr_legacy_ch7_ce_count.attr.attr, 382 - &dev_attr_legacy_ch8_ce_count.attr.attr, 383 - &dev_attr_legacy_ch9_ce_count.attr.attr, 384 - &dev_attr_legacy_ch10_ce_count.attr.attr, 385 - &dev_attr_legacy_ch11_ce_count.attr.attr, 386 - &dev_attr_legacy_ch12_ce_count.attr.attr, 387 - &dev_attr_legacy_ch13_ce_count.attr.attr, 388 - &dev_attr_legacy_ch14_ce_count.attr.attr, 389 - &dev_attr_legacy_ch15_ce_count.attr.attr, 390 - NULL 391 - }; 392 - 393 - static umode_t csrow_dev_is_visible(struct kobject *kobj, 394 - struct attribute *attr, int idx) 395 - { 396 - struct device *dev = kobj_to_dev(kobj); 397 - struct csrow_info *csrow = container_of(dev, struct csrow_info, dev); 398 - 399 - if (idx >= csrow->nr_channels) 400 - return 0; 401 - 402 - if (idx >= ARRAY_SIZE(dynamic_csrow_ce_count_attr) - 1) { 403 - WARN_ONCE(1, "idx: %d\n", idx); 404 - return 0; 405 - } 406 - 407 - /* Only expose populated DIMMs */ 408 - if (!csrow->channels[idx]->dimm->nr_pages) 409 - return 0; 410 - 411 - return attr->mode; 412 - } 413 - 414 - 415 - static const struct attribute_group csrow_dev_dimm_group = { 416 - .attrs = dynamic_csrow_dimm_attr, 417 - .is_visible = csrow_dev_is_visible, 418 - }; 419 - 420 - static const struct attribute_group csrow_dev_ce_count_group = { 421 - .attrs = dynamic_csrow_ce_count_attr, 422 - .is_visible = csrow_dev_is_visible, 423 - }; 424 - 425 - static const struct attribute_group *csrow_dev_groups[] = { 426 - &csrow_dev_dimm_group, 427 - &csrow_dev_ce_count_group, 428 - NULL 429 - }; 430 - 431 - static void csrow_release(struct device *dev) 432 - { 433 - /* 434 - * Nothing to do, just unregister sysfs here. The mci 435 - * device owns the data and will also release it. 436 - */ 437 - } 438 - 439 - static inline int nr_pages_per_csrow(struct csrow_info *csrow) 440 - { 441 - int chan, nr_pages = 0; 442 - 443 - for (chan = 0; chan < csrow->nr_channels; chan++) 444 - nr_pages += csrow->channels[chan]->dimm->nr_pages; 445 - 446 - return nr_pages; 447 - } 448 - 449 - /* Create a CSROW object under specified edac_mc_device */ 450 - static int edac_create_csrow_object(struct mem_ctl_info *mci, 451 - struct csrow_info *csrow, int index) 452 - { 453 - int err; 454 - 455 - csrow->dev.type = &csrow_attr_type; 456 - csrow->dev.groups = csrow_dev_groups; 457 - csrow->dev.release = csrow_release; 458 - device_initialize(&csrow->dev); 459 - csrow->dev.parent = &mci->dev; 460 - csrow->mci = mci; 461 - dev_set_name(&csrow->dev, "csrow%d", index); 462 - dev_set_drvdata(&csrow->dev, csrow); 463 - 464 - err = device_add(&csrow->dev); 465 - if (err) { 466 - edac_dbg(1, "failure: create device %s\n", dev_name(&csrow->dev)); 467 - put_device(&csrow->dev); 468 - return err; 469 - } 470 - 471 - edac_dbg(0, "device %s created\n", dev_name(&csrow->dev)); 472 - 473 - return 0; 474 - } 475 - 476 - /* Create a CSROW object under specified edac_mc_device */ 477 - static int edac_create_csrow_objects(struct mem_ctl_info *mci) 478 - { 479 - int err, i; 480 - struct csrow_info *csrow; 481 - 482 - for (i = 0; i < mci->nr_csrows; i++) { 483 - csrow = mci->csrows[i]; 484 - if (!nr_pages_per_csrow(csrow)) 485 - continue; 486 - err = edac_create_csrow_object(mci, mci->csrows[i], i); 487 - if (err < 0) 488 - goto error; 489 - } 490 - return 0; 491 - 492 - error: 493 - for (--i; i >= 0; i--) { 494 - if (device_is_registered(&mci->csrows[i]->dev)) 495 - device_unregister(&mci->csrows[i]->dev); 496 - } 497 - 498 - return err; 499 - } 500 - 501 - static void edac_delete_csrow_objects(struct mem_ctl_info *mci) 502 - { 503 - int i; 504 - 505 - for (i = 0; i < mci->nr_csrows; i++) { 506 - if (device_is_registered(&mci->csrows[i]->dev)) 507 - device_unregister(&mci->csrows[i]->dev); 508 - } 509 - } 510 - 511 - #endif 512 - 513 118 /* 514 119 * Per-dimm (or per-rank) devices 515 120 */ ··· 594 989 goto fail; 595 990 } 596 991 597 - #ifdef CONFIG_EDAC_LEGACY_SYSFS 598 - err = edac_create_csrow_objects(mci); 599 - if (err < 0) 600 - goto fail; 601 - #endif 602 - 603 992 edac_create_debugfs_nodes(mci); 604 993 return 0; 605 994 ··· 617 1018 618 1019 #ifdef CONFIG_EDAC_DEBUG 619 1020 edac_debugfs_remove_recursive(mci->debugfs); 620 - #endif 621 - #ifdef CONFIG_EDAC_LEGACY_SYSFS 622 - edac_delete_csrow_objects(mci); 623 1021 #endif 624 1022 625 1023 mci_for_each_dimm(mci, dimm) {