858 lines · c
1/*2 * file for managing the edac_device subsystem of devices for EDAC3 *4 * (C) 2007 SoftwareBitMaker5 *6 * This file may be distributed under the terms of the7 * GNU General Public License.8 *9 * Written Doug Thompson <norsk5@xmission.com>10 *11 */12 13#include <linux/ctype.h>14#include <linux/module.h>15#include <linux/slab.h>16#include <linux/edac.h>17 18#include "edac_device.h"19#include "edac_module.h"20 21#define EDAC_DEVICE_SYMLINK "device"22 23#define to_edacdev(k) container_of(k, struct edac_device_ctl_info, kobj)24#define to_edacdev_attr(a) container_of(a, struct edacdev_attribute, attr)25 26 27/*28 * Set of edac_device_ctl_info attribute store/show functions29 */30 31/* 'log_ue' */32static ssize_t edac_device_ctl_log_ue_show(struct edac_device_ctl_info33 *ctl_info, char *data)34{35 return sprintf(data, "%u\n", ctl_info->log_ue);36}37 38static ssize_t edac_device_ctl_log_ue_store(struct edac_device_ctl_info39 *ctl_info, const char *data,40 size_t count)41{42 /* if parameter is zero, turn off flag, if non-zero turn on flag */43 ctl_info->log_ue = (simple_strtoul(data, NULL, 0) != 0);44 45 return count;46}47 48/* 'log_ce' */49static ssize_t edac_device_ctl_log_ce_show(struct edac_device_ctl_info50 *ctl_info, char *data)51{52 return sprintf(data, "%u\n", ctl_info->log_ce);53}54 55static ssize_t edac_device_ctl_log_ce_store(struct edac_device_ctl_info56 *ctl_info, const char *data,57 size_t count)58{59 /* if parameter is zero, turn off flag, if non-zero turn on flag */60 ctl_info->log_ce = (simple_strtoul(data, NULL, 0) != 0);61 62 return count;63}64 65/* 'panic_on_ue' */66static ssize_t edac_device_ctl_panic_on_ue_show(struct edac_device_ctl_info67 *ctl_info, char *data)68{69 return sprintf(data, "%u\n", ctl_info->panic_on_ue);70}71 72static ssize_t edac_device_ctl_panic_on_ue_store(struct edac_device_ctl_info73 *ctl_info, const char *data,74 size_t count)75{76 /* if parameter is zero, turn off flag, if non-zero turn on flag */77 ctl_info->panic_on_ue = (simple_strtoul(data, NULL, 0) != 0);78 79 return count;80}81 82/* 'poll_msec' show and store functions*/83static ssize_t edac_device_ctl_poll_msec_show(struct edac_device_ctl_info84 *ctl_info, char *data)85{86 return sprintf(data, "%u\n", ctl_info->poll_msec);87}88 89static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info90 *ctl_info, const char *data,91 size_t count)92{93 unsigned long value;94 95 /* get the value and enforce that it is non-zero, must be at least96 * one millisecond for the delay period, between scans97 * Then cancel last outstanding delay for the work request98 * and set a new one.99 */100 value = simple_strtoul(data, NULL, 0);101 edac_device_reset_delay_period(ctl_info, value);102 103 return count;104}105 106/* edac_device_ctl_info specific attribute structure */107struct ctl_info_attribute {108 struct attribute attr;109 ssize_t(*show) (struct edac_device_ctl_info *, char *);110 ssize_t(*store) (struct edac_device_ctl_info *, const char *, size_t);111};112 113#define to_ctl_info(k) container_of(k, struct edac_device_ctl_info, kobj)114#define to_ctl_info_attr(a) container_of(a,struct ctl_info_attribute,attr)115 116/* Function to 'show' fields from the edac_dev 'ctl_info' structure */117static ssize_t edac_dev_ctl_info_show(struct kobject *kobj,118 struct attribute *attr, char *buffer)119{120 struct edac_device_ctl_info *edac_dev = to_ctl_info(kobj);121 struct ctl_info_attribute *ctl_info_attr = to_ctl_info_attr(attr);122 123 if (ctl_info_attr->show)124 return ctl_info_attr->show(edac_dev, buffer);125 return -EIO;126}127 128/* Function to 'store' fields into the edac_dev 'ctl_info' structure */129static ssize_t edac_dev_ctl_info_store(struct kobject *kobj,130 struct attribute *attr,131 const char *buffer, size_t count)132{133 struct edac_device_ctl_info *edac_dev = to_ctl_info(kobj);134 struct ctl_info_attribute *ctl_info_attr = to_ctl_info_attr(attr);135 136 if (ctl_info_attr->store)137 return ctl_info_attr->store(edac_dev, buffer, count);138 return -EIO;139}140 141/* edac_dev file operations for an 'ctl_info' */142static const struct sysfs_ops device_ctl_info_ops = {143 .show = edac_dev_ctl_info_show,144 .store = edac_dev_ctl_info_store145};146 147#define CTL_INFO_ATTR(_name,_mode,_show,_store) \148static struct ctl_info_attribute attr_ctl_info_##_name = { \149 .attr = {.name = __stringify(_name), .mode = _mode }, \150 .show = _show, \151 .store = _store, \152};153 154/* Declare the various ctl_info attributes here and their respective ops */155CTL_INFO_ATTR(log_ue, S_IRUGO | S_IWUSR,156 edac_device_ctl_log_ue_show, edac_device_ctl_log_ue_store);157CTL_INFO_ATTR(log_ce, S_IRUGO | S_IWUSR,158 edac_device_ctl_log_ce_show, edac_device_ctl_log_ce_store);159CTL_INFO_ATTR(panic_on_ue, S_IRUGO | S_IWUSR,160 edac_device_ctl_panic_on_ue_show,161 edac_device_ctl_panic_on_ue_store);162CTL_INFO_ATTR(poll_msec, S_IRUGO | S_IWUSR,163 edac_device_ctl_poll_msec_show, edac_device_ctl_poll_msec_store);164 165/* Base Attributes of the EDAC_DEVICE ECC object */166static struct attribute *device_ctrl_attrs[] = {167 &attr_ctl_info_panic_on_ue.attr,168 &attr_ctl_info_log_ue.attr,169 &attr_ctl_info_log_ce.attr,170 &attr_ctl_info_poll_msec.attr,171 NULL,172};173ATTRIBUTE_GROUPS(device_ctrl);174 175/*176 * edac_device_ctrl_master_release177 *178 * called when the reference count for the 'main' kobj179 * for a edac_device control struct reaches zero180 *181 * Reference count model:182 * One 'main' kobject for each control structure allocated.183 * That main kobj is initially set to one AND184 * the reference count for the EDAC 'core' module is185 * bumped by one, thus added 'keep in memory' dependency.186 *187 * Each new internal kobj (in instances and blocks) then188 * bumps the 'main' kobject.189 *190 * When they are released their release functions decrement191 * the 'main' kobj.192 *193 * When the main kobj reaches zero (0) then THIS function194 * is called which then decrements the EDAC 'core' module.195 * When the module reference count reaches zero then the196 * module no longer has dependency on keeping the release197 * function code in memory and module can be unloaded.198 *199 * This will support several control objects as well, each200 * with its own 'main' kobj.201 */202static void edac_device_ctrl_master_release(struct kobject *kobj)203{204 struct edac_device_ctl_info *edac_dev = to_edacdev(kobj);205 206 edac_dbg(4, "control index=%d\n", edac_dev->dev_idx);207 208 /* decrement the EDAC CORE module ref count */209 module_put(edac_dev->owner);210 211 __edac_device_free_ctl_info(edac_dev);212}213 214/* ktype for the main (master) kobject */215static struct kobj_type ktype_device_ctrl = {216 .release = edac_device_ctrl_master_release,217 .sysfs_ops = &device_ctl_info_ops,218 .default_groups = device_ctrl_groups,219};220 221/*222 * edac_device_register_sysfs_main_kobj223 *224 * perform the high level setup for the new edac_device instance225 *226 * Return: 0 SUCCESS227 * !0 FAILURE228 */229int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)230{231 struct device *dev_root;232 const struct bus_type *edac_subsys;233 int err = -ENODEV;234 235 edac_dbg(1, "\n");236 237 /* get the /sys/devices/system/edac reference */238 edac_subsys = edac_get_sysfs_subsys();239 240 /* Point to the 'edac_subsys' this instance 'reports' to */241 edac_dev->edac_subsys = edac_subsys;242 243 /* Init the devices's kobject */244 memset(&edac_dev->kobj, 0, sizeof(struct kobject));245 246 /* Record which module 'owns' this control structure247 * and bump the ref count of the module248 */249 edac_dev->owner = THIS_MODULE;250 251 if (!try_module_get(edac_dev->owner))252 goto err_out;253 254 /* register */255 dev_root = bus_get_dev_root(edac_subsys);256 if (dev_root) {257 err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl,258 &dev_root->kobj, "%s", edac_dev->name);259 put_device(dev_root);260 }261 if (err) {262 edac_dbg(1, "Failed to register '.../edac/%s'\n",263 edac_dev->name);264 goto err_kobj_reg;265 }266 kobject_uevent(&edac_dev->kobj, KOBJ_ADD);267 268 /* At this point, to 'free' the control struct,269 * edac_device_unregister_sysfs_main_kobj() must be used270 */271 272 edac_dbg(4, "Registered '.../edac/%s' kobject\n", edac_dev->name);273 274 return 0;275 276 /* Error exit stack */277err_kobj_reg:278 kobject_put(&edac_dev->kobj);279 module_put(edac_dev->owner);280 281err_out:282 return err;283}284 285/*286 * edac_device_unregister_sysfs_main_kobj:287 * the '..../edac/<name>' kobject288 */289void edac_device_unregister_sysfs_main_kobj(struct edac_device_ctl_info *dev)290{291 edac_dbg(0, "\n");292 edac_dbg(4, "name of kobject is: %s\n", kobject_name(&dev->kobj));293 294 /*295 * Unregister the edac device's kobject and296 * allow for reference count to reach 0 at which point297 * the callback will be called to:298 * a) module_put() this module299 * b) 'kfree' the memory300 */301 kobject_put(&dev->kobj);302}303 304/* edac_dev -> instance information */305 306/*307 * Set of low-level instance attribute show functions308 */309static ssize_t instance_ue_count_show(struct edac_device_instance *instance,310 char *data)311{312 return sprintf(data, "%u\n", instance->counters.ue_count);313}314 315static ssize_t instance_ce_count_show(struct edac_device_instance *instance,316 char *data)317{318 return sprintf(data, "%u\n", instance->counters.ce_count);319}320 321#define to_instance(k) container_of(k, struct edac_device_instance, kobj)322#define to_instance_attr(a) container_of(a,struct instance_attribute,attr)323 324/* DEVICE instance kobject release() function */325static void edac_device_ctrl_instance_release(struct kobject *kobj)326{327 struct edac_device_instance *instance;328 329 edac_dbg(1, "\n");330 331 /* map from this kobj to the main control struct332 * and then dec the main kobj count333 */334 instance = to_instance(kobj);335 kobject_put(&instance->ctl->kobj);336}337 338/* instance specific attribute structure */339struct instance_attribute {340 struct attribute attr;341 ssize_t(*show) (struct edac_device_instance *, char *);342 ssize_t(*store) (struct edac_device_instance *, const char *, size_t);343};344 345/* Function to 'show' fields from the edac_dev 'instance' structure */346static ssize_t edac_dev_instance_show(struct kobject *kobj,347 struct attribute *attr, char *buffer)348{349 struct edac_device_instance *instance = to_instance(kobj);350 struct instance_attribute *instance_attr = to_instance_attr(attr);351 352 if (instance_attr->show)353 return instance_attr->show(instance, buffer);354 return -EIO;355}356 357/* Function to 'store' fields into the edac_dev 'instance' structure */358static ssize_t edac_dev_instance_store(struct kobject *kobj,359 struct attribute *attr,360 const char *buffer, size_t count)361{362 struct edac_device_instance *instance = to_instance(kobj);363 struct instance_attribute *instance_attr = to_instance_attr(attr);364 365 if (instance_attr->store)366 return instance_attr->store(instance, buffer, count);367 return -EIO;368}369 370/* edac_dev file operations for an 'instance' */371static const struct sysfs_ops device_instance_ops = {372 .show = edac_dev_instance_show,373 .store = edac_dev_instance_store374};375 376#define INSTANCE_ATTR(_name,_mode,_show,_store) \377static struct instance_attribute attr_instance_##_name = { \378 .attr = {.name = __stringify(_name), .mode = _mode }, \379 .show = _show, \380 .store = _store, \381};382 383/*384 * Define attributes visible for the edac_device instance object385 * Each contains a pointer to a show and an optional set386 * function pointer that does the low level output/input387 */388INSTANCE_ATTR(ce_count, S_IRUGO, instance_ce_count_show, NULL);389INSTANCE_ATTR(ue_count, S_IRUGO, instance_ue_count_show, NULL);390 391/* list of edac_dev 'instance' attributes */392static struct attribute *device_instance_attrs[] = {393 &attr_instance_ce_count.attr,394 &attr_instance_ue_count.attr,395 NULL,396};397ATTRIBUTE_GROUPS(device_instance);398 399/* The 'ktype' for each edac_dev 'instance' */400static struct kobj_type ktype_instance_ctrl = {401 .release = edac_device_ctrl_instance_release,402 .sysfs_ops = &device_instance_ops,403 .default_groups = device_instance_groups,404};405 406/* edac_dev -> instance -> block information */407 408#define to_block(k) container_of(k, struct edac_device_block, kobj)409#define to_block_attr(a) \410 container_of(a, struct edac_dev_sysfs_block_attribute, attr)411 412/*413 * Set of low-level block attribute show functions414 */415static ssize_t block_ue_count_show(struct kobject *kobj,416 struct attribute *attr, char *data)417{418 struct edac_device_block *block = to_block(kobj);419 420 return sprintf(data, "%u\n", block->counters.ue_count);421}422 423static ssize_t block_ce_count_show(struct kobject *kobj,424 struct attribute *attr, char *data)425{426 struct edac_device_block *block = to_block(kobj);427 428 return sprintf(data, "%u\n", block->counters.ce_count);429}430 431/* DEVICE block kobject release() function */432static void edac_device_ctrl_block_release(struct kobject *kobj)433{434 struct edac_device_block *block;435 436 edac_dbg(1, "\n");437 438 /* get the container of the kobj */439 block = to_block(kobj);440 441 /* map from 'block kobj' to 'block->instance->controller->main_kobj'442 * now 'release' the block kobject443 */444 kobject_put(&block->instance->ctl->kobj);445}446 447 448/* Function to 'show' fields from the edac_dev 'block' structure */449static ssize_t edac_dev_block_show(struct kobject *kobj,450 struct attribute *attr, char *buffer)451{452 struct edac_dev_sysfs_block_attribute *block_attr =453 to_block_attr(attr);454 455 if (block_attr->show)456 return block_attr->show(kobj, attr, buffer);457 return -EIO;458}459 460/* edac_dev file operations for a 'block' */461static const struct sysfs_ops device_block_ops = {462 .show = edac_dev_block_show,463};464 465#define BLOCK_ATTR(_name,_mode,_show) \466static struct edac_dev_sysfs_block_attribute attr_block_##_name = { \467 .attr = {.name = __stringify(_name), .mode = _mode }, \468 .show = _show, \469};470 471BLOCK_ATTR(ce_count, S_IRUGO, block_ce_count_show);472BLOCK_ATTR(ue_count, S_IRUGO, block_ue_count_show);473 474/* list of edac_dev 'block' attributes */475static struct attribute *device_block_attrs[] = {476 &attr_block_ce_count.attr,477 &attr_block_ue_count.attr,478 NULL,479};480ATTRIBUTE_GROUPS(device_block);481 482/* The 'ktype' for each edac_dev 'block' */483static struct kobj_type ktype_block_ctrl = {484 .release = edac_device_ctrl_block_release,485 .sysfs_ops = &device_block_ops,486 .default_groups = device_block_groups,487};488 489/* block ctor/dtor code */490 491/*492 * edac_device_create_block493 */494static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,495 struct edac_device_instance *instance,496 struct edac_device_block *block)497{498 int i;499 int err;500 struct edac_dev_sysfs_block_attribute *sysfs_attrib;501 struct kobject *main_kobj;502 503 edac_dbg(4, "Instance '%s' inst_p=%p block '%s' block_p=%p\n",504 instance->name, instance, block->name, block);505 edac_dbg(4, "block kobj=%p block kobj->parent=%p\n",506 &block->kobj, &block->kobj.parent);507 508 /* init this block's kobject */509 memset(&block->kobj, 0, sizeof(struct kobject));510 511 /* bump the main kobject's reference count for this controller512 * and this instance is dependent on the main513 */514 main_kobj = kobject_get(&edac_dev->kobj);515 if (!main_kobj) {516 err = -ENODEV;517 goto err_out;518 }519 520 /* Add this block's kobject */521 err = kobject_init_and_add(&block->kobj, &ktype_block_ctrl,522 &instance->kobj,523 "%s", block->name);524 if (err) {525 edac_dbg(1, "Failed to register instance '%s'\n", block->name);526 kobject_put(main_kobj);527 err = -ENODEV;528 goto err_out;529 }530 531 /* If there are driver level block attributes, then added them532 * to the block kobject533 */534 sysfs_attrib = block->block_attributes;535 if (sysfs_attrib && block->nr_attribs) {536 for (i = 0; i < block->nr_attribs; i++, sysfs_attrib++) {537 538 edac_dbg(4, "creating block attrib='%s' attrib->%p to kobj=%p\n",539 sysfs_attrib->attr.name,540 sysfs_attrib, &block->kobj);541 542 /* Create each block_attribute file */543 err = sysfs_create_file(&block->kobj,544 &sysfs_attrib->attr);545 if (err)546 goto err_on_attrib;547 }548 }549 kobject_uevent(&block->kobj, KOBJ_ADD);550 551 return 0;552 553 /* Error unwind stack */554err_on_attrib:555 kobject_put(&block->kobj);556 557err_out:558 return err;559}560 561/*562 * edac_device_delete_block(edac_dev,block);563 */564static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev,565 struct edac_device_block *block)566{567 struct edac_dev_sysfs_block_attribute *sysfs_attrib;568 int i;569 570 /* if this block has 'attributes' then we need to iterate over the list571 * and 'remove' the attributes on this block572 */573 sysfs_attrib = block->block_attributes;574 if (sysfs_attrib && block->nr_attribs) {575 for (i = 0; i < block->nr_attribs; i++, sysfs_attrib++) {576 577 /* remove each block_attrib file */578 sysfs_remove_file(&block->kobj,579 (struct attribute *) sysfs_attrib);580 }581 }582 583 /* unregister this block's kobject, SEE:584 * edac_device_ctrl_block_release() callback operation585 */586 kobject_put(&block->kobj);587}588 589/* instance ctor/dtor code */590 591/*592 * edac_device_create_instance593 * create just one instance of an edac_device 'instance'594 */595static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,596 int idx)597{598 int i, j;599 int err;600 struct edac_device_instance *instance;601 struct kobject *main_kobj;602 603 instance = &edac_dev->instances[idx];604 605 /* Init the instance's kobject */606 memset(&instance->kobj, 0, sizeof(struct kobject));607 608 instance->ctl = edac_dev;609 610 /* bump the main kobject's reference count for this controller611 * and this instance is dependent on the main612 */613 main_kobj = kobject_get(&edac_dev->kobj);614 if (!main_kobj) {615 err = -ENODEV;616 goto err_out;617 }618 619 /* Formally register this instance's kobject under the edac_device */620 err = kobject_init_and_add(&instance->kobj, &ktype_instance_ctrl,621 &edac_dev->kobj, "%s", instance->name);622 if (err != 0) {623 edac_dbg(2, "Failed to register instance '%s'\n",624 instance->name);625 kobject_put(main_kobj);626 goto err_out;627 }628 629 edac_dbg(4, "now register '%d' blocks for instance %d\n",630 instance->nr_blocks, idx);631 632 /* register all blocks of this instance */633 for (i = 0; i < instance->nr_blocks; i++) {634 err = edac_device_create_block(edac_dev, instance,635 &instance->blocks[i]);636 if (err) {637 /* If any fail, remove all previous ones */638 for (j = 0; j < i; j++)639 edac_device_delete_block(edac_dev,640 &instance->blocks[j]);641 goto err_release_instance_kobj;642 }643 }644 kobject_uevent(&instance->kobj, KOBJ_ADD);645 646 edac_dbg(4, "Registered instance %d '%s' kobject\n",647 idx, instance->name);648 649 return 0;650 651 /* error unwind stack */652err_release_instance_kobj:653 kobject_put(&instance->kobj);654 655err_out:656 return err;657}658 659/*660 * edac_device_remove_instance661 * remove an edac_device instance662 */663static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev,664 int idx)665{666 struct edac_device_instance *instance;667 int i;668 669 instance = &edac_dev->instances[idx];670 671 /* unregister all blocks in this instance */672 for (i = 0; i < instance->nr_blocks; i++)673 edac_device_delete_block(edac_dev, &instance->blocks[i]);674 675 /* unregister this instance's kobject, SEE:676 * edac_device_ctrl_instance_release() for callback operation677 */678 kobject_put(&instance->kobj);679}680 681/*682 * edac_device_create_instances683 * create the first level of 'instances' for this device684 * (ie 'cache' might have 'cache0', 'cache1', 'cache2', etc685 */686static int edac_device_create_instances(struct edac_device_ctl_info *edac_dev)687{688 int i, j;689 int err;690 691 edac_dbg(0, "\n");692 693 /* iterate over creation of the instances */694 for (i = 0; i < edac_dev->nr_instances; i++) {695 err = edac_device_create_instance(edac_dev, i);696 if (err) {697 /* unwind previous instances on error */698 for (j = 0; j < i; j++)699 edac_device_delete_instance(edac_dev, j);700 return err;701 }702 }703 704 return 0;705}706 707/*708 * edac_device_delete_instances(edac_dev);709 * unregister all the kobjects of the instances710 */711static void edac_device_delete_instances(struct edac_device_ctl_info *edac_dev)712{713 int i;714 715 /* iterate over creation of the instances */716 for (i = 0; i < edac_dev->nr_instances; i++)717 edac_device_delete_instance(edac_dev, i);718}719 720/* edac_dev sysfs ctor/dtor code */721 722/*723 * edac_device_add_main_sysfs_attributes724 * add some attributes to this instance's main kobject725 */726static int edac_device_add_main_sysfs_attributes(727 struct edac_device_ctl_info *edac_dev)728{729 struct edac_dev_sysfs_attribute *sysfs_attrib;730 int err = 0;731 732 sysfs_attrib = edac_dev->sysfs_attributes;733 if (sysfs_attrib) {734 /* iterate over the array and create an attribute for each735 * entry in the list736 */737 while (sysfs_attrib->attr.name != NULL) {738 err = sysfs_create_file(&edac_dev->kobj,739 (struct attribute*) sysfs_attrib);740 if (err)741 goto err_out;742 743 sysfs_attrib++;744 }745 }746 747err_out:748 return err;749}750 751/*752 * edac_device_remove_main_sysfs_attributes753 * remove any attributes to this instance's main kobject754 */755static void edac_device_remove_main_sysfs_attributes(756 struct edac_device_ctl_info *edac_dev)757{758 struct edac_dev_sysfs_attribute *sysfs_attrib;759 760 /* if there are main attributes, defined, remove them. First,761 * point to the start of the array and iterate over it762 * removing each attribute listed from this device's instance's kobject763 */764 sysfs_attrib = edac_dev->sysfs_attributes;765 if (sysfs_attrib) {766 while (sysfs_attrib->attr.name != NULL) {767 sysfs_remove_file(&edac_dev->kobj,768 (struct attribute *) sysfs_attrib);769 sysfs_attrib++;770 }771 }772}773 774/*775 * edac_device_create_sysfs() Constructor776 *777 * accept a created edac_device control structure778 * and 'export' it to sysfs. The 'main' kobj should already have been779 * created. 'instance' and 'block' kobjects should be registered780 * along with any 'block' attributes from the low driver. In addition,781 * the main attributes (if any) are connected to the main kobject of782 * the control structure.783 *784 * Return:785 * 0 Success786 * !0 Failure787 */788int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)789{790 int err;791 struct kobject *edac_kobj = &edac_dev->kobj;792 793 edac_dbg(0, "idx=%d\n", edac_dev->dev_idx);794 795 /* go create any main attributes callers wants */796 err = edac_device_add_main_sysfs_attributes(edac_dev);797 if (err) {798 edac_dbg(0, "failed to add sysfs attribs\n");799 goto err_out;800 }801 802 /* create a symlink from the edac device803 * to the platform 'device' being used for this804 */805 err = sysfs_create_link(edac_kobj,806 &edac_dev->dev->kobj, EDAC_DEVICE_SYMLINK);807 if (err) {808 edac_dbg(0, "sysfs_create_link() returned err= %d\n", err);809 goto err_remove_main_attribs;810 }811 812 /* Create the first level instance directories813 * In turn, the nested blocks beneath the instances will814 * be registered as well815 */816 err = edac_device_create_instances(edac_dev);817 if (err) {818 edac_dbg(0, "edac_device_create_instances() returned err= %d\n",819 err);820 goto err_remove_link;821 }822 823 824 edac_dbg(4, "create-instances done, idx=%d\n", edac_dev->dev_idx);825 826 return 0;827 828 /* Error unwind stack */829err_remove_link:830 /* remove the sym link */831 sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);832 833err_remove_main_attribs:834 edac_device_remove_main_sysfs_attributes(edac_dev);835 836err_out:837 return err;838}839 840/*841 * edac_device_remove_sysfs() destructor842 *843 * given an edac_device struct, tear down the kobject resources844 */845void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev)846{847 edac_dbg(0, "\n");848 849 /* remove any main attributes for this device */850 edac_device_remove_main_sysfs_attributes(edac_dev);851 852 /* remove the device sym link */853 sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);854 855 /* walk the instance/block kobject tree, deconstructing it */856 edac_device_delete_instances(edac_dev);857}858