2 * file for managing the edac_device class of devices for EDAC
4 * (C) 2007 SoftwareBitMaker(http://www.softwarebitmaker.com)
5 * This file may be distributed under the terms of the
6 * GNU General Public License.
8 * Written Doug Thompson <norsk5@xmission.com>
12 #include <linux/module.h>
13 #include <linux/sysdev.h>
14 #include <linux/ctype.h>
16 #include "edac_core.h"
17 #include "edac_module.h"
20 #define EDAC_DEVICE_SYMLINK "device"
22 #define to_edacdev(k) container_of(k, struct edac_device_ctl_info, kobj)
23 #define to_edacdev_attr(a) container_of(a, struct edacdev_attribute, attr)
27 static ssize_t
edac_dev_ue_count_show(struct edac_device_ctl_info
*edac_dev
,
30 return sprintf(data
,"%d\n", edac_dev
->ue_count
);
33 static ssize_t
edac_dev_ce_count_show(struct edac_device_ctl_info
*edac_dev
,
36 return sprintf(data
,"%d\n", edac_dev
->ce_count
);
39 static ssize_t
edac_dev_seconds_show(struct edac_device_ctl_info
*edac_dev
,
42 return sprintf(data
,"%ld\n", (jiffies
- edac_dev
->start_time
) / HZ
);
45 static ssize_t
edac_dev_ctl_name_show(struct edac_device_ctl_info
*edac_dev
,
48 return sprintf(data
,"%s\n", edac_dev
->ctl_name
);
52 struct edacdev_attribute
{
53 struct attribute attr
;
54 ssize_t (*show
)(struct edac_device_ctl_info
*,char *);
55 ssize_t (*store
)(struct edac_device_ctl_info
*, const char *,size_t);
59 /* EDAC DEVICE show/store functions for top most object */
60 static ssize_t
edacdev_show(struct kobject
*kobj
, struct attribute
*attr
,
63 struct edac_device_ctl_info
*edac_dev
= to_edacdev(kobj
);
64 struct edacdev_attribute
* edacdev_attr
= to_edacdev_attr(attr
);
66 if (edacdev_attr
->show
)
67 return edacdev_attr
->show(edac_dev
, buffer
);
72 static ssize_t
edacdev_store(struct kobject
*kobj
, struct attribute
*attr
,
73 const char *buffer
, size_t count
)
75 struct edac_device_ctl_info
*edac_dev
= to_edacdev(kobj
);
76 struct edacdev_attribute
* edacdev_attr
= to_edacdev_attr(attr
);
78 if (edacdev_attr
->store
)
79 return edacdev_attr
->store(edac_dev
, buffer
, count
);
84 static struct sysfs_ops edac_dev_ops
= {
86 .store
= edacdev_store
89 #define EDACDEV_ATTR(_name,_mode,_show,_store) \
90 static struct edacdev_attribute edac_dev_attr_##_name = { \
91 .attr = {.name = __stringify(_name), .mode = _mode }, \
96 /* default Control file */
97 EDACDEV_ATTR(reset_counters
,S_IWUSR
,NULL
,edac_dev_reset_counters_store
);
99 /* default Attribute files */
100 EDACDEV_ATTR(mc_name
,S_IRUGO
,edac_dev_ctl_name_show
,NULL
);
101 EDACDEV_ATTR(seconds_since_reset
,S_IRUGO
,edac_dev_seconds_show
,NULL
);
102 EDACDEV_ATTR(ue_count
,S_IRUGO
,edac_dev_ue_count_show
,NULL
);
103 EDACDEV_ATTR(ce_count
,S_IRUGO
,edac_dev_ce_count_show
,NULL
);
106 static struct edacdev_attribute
*edacdev_attr
[] = {
107 &edacdev_attr_reset_counters
,
108 &edacdev_attr_mc_name
,
109 &edacdev_attr_seconds_since_reset
,
110 &edacdev_attr_ue_count
,
111 &edacdev_attr_ce_count
,
116 * Release of a Edac Device controlling instance
118 static void edac_dev_instance_release(struct kobject
*kobj
)
120 struct edac_device_ctl_info
*edac_dev
;
122 edac_dev
= to_edacdev(kobj
);
123 debugf0("%s() idx=%d\n", __func__
, edac_dev
->dev_idx
);
124 complete(&edac_dev
->kobj_complete
);
127 static struct kobj_type ktype_device
= {
128 .release
= edac_dev_instance_release
,
129 .sysfs_ops
= &edacdev_ops
,
130 .default_attrs
= (struct attribute
**) edacdev_attr
,
135 /************************** edac_device sysfs code and data **************/
138 * Set of edac_device_ctl_info attribute store/show functions
142 static ssize_t
edac_device_ctl_log_ue_show(
143 struct edac_device_ctl_info
*ctl_info
, char *data
)
145 return sprintf(data
,"%u\n", ctl_info
->log_ue
);
148 static ssize_t
edac_device_ctl_log_ue_store(
149 struct edac_device_ctl_info
*ctl_info
,
150 const char *data
,size_t count
)
152 /* if parameter is zero, turn off flag, if non-zero turn on flag */
153 ctl_info
->log_ue
= (simple_strtoul(data
,NULL
,0) != 0);
159 static ssize_t
edac_device_ctl_log_ce_show(
160 struct edac_device_ctl_info
*ctl_info
,char *data
)
162 return sprintf(data
,"%u\n", ctl_info
->log_ce
);
165 static ssize_t
edac_device_ctl_log_ce_store(
166 struct edac_device_ctl_info
*ctl_info
,
167 const char *data
,size_t count
)
169 /* if parameter is zero, turn off flag, if non-zero turn on flag */
170 ctl_info
->log_ce
= (simple_strtoul(data
,NULL
,0) != 0);
177 static ssize_t
edac_device_ctl_panic_on_ue_show(
178 struct edac_device_ctl_info
*ctl_info
, char *data
)
180 return sprintf(data
,"%u\n", ctl_info
->panic_on_ue
);
183 static ssize_t
edac_device_ctl_panic_on_ue_store(
184 struct edac_device_ctl_info
*ctl_info
,
185 const char *data
,size_t count
)
187 /* if parameter is zero, turn off flag, if non-zero turn on flag */
188 ctl_info
->panic_on_ue
= (simple_strtoul(data
,NULL
,0) != 0);
193 /* 'poll_msec' show and store functions*/
194 static ssize_t
edac_device_ctl_poll_msec_show(
195 struct edac_device_ctl_info
*ctl_info
, char *data
)
197 return sprintf(data
,"%u\n", ctl_info
->poll_msec
);
200 static ssize_t
edac_device_ctl_poll_msec_store(
201 struct edac_device_ctl_info
*ctl_info
,
202 const char *data
,size_t count
)
206 /* get the value and enforce that it is non-zero, must be at least
207 * one millisecond for the delay period, between scans
208 * Then cancel last outstanding delay for the work request
211 value
= simple_strtoul(data
,NULL
,0);
212 edac_device_reset_delay_period(ctl_info
,value
);
218 /* edac_device_ctl_info specific attribute structure */
219 struct ctl_info_attribute
{
220 struct attribute attr
;
221 ssize_t (*show
)(struct edac_device_ctl_info
*,char *);
222 ssize_t (*store
)(struct edac_device_ctl_info
*,const char *,size_t);
225 #define to_ctl_info(k) container_of(k, struct edac_device_ctl_info, kobj)
226 #define to_ctl_info_attr(a) container_of(a,struct ctl_info_attribute,attr)
228 /* Function to 'show' fields from the edac_dev 'ctl_info' structure */
229 static ssize_t
edac_dev_ctl_info_show(struct kobject
*kobj
,
230 struct attribute
*attr
,
233 struct edac_device_ctl_info
*edac_dev
= to_ctl_info(kobj
);
234 struct ctl_info_attribute
*ctl_info_attr
= to_ctl_info_attr(attr
);
236 if (ctl_info_attr
->show
)
237 return ctl_info_attr
->show(edac_dev
,buffer
);
241 /* Function to 'store' fields into the edac_dev 'ctl_info' structure */
242 static ssize_t
edac_dev_ctl_info_store(struct kobject
*kobj
,
243 struct attribute
*attr
,
244 const char *buffer
, size_t count
)
246 struct edac_device_ctl_info
*edac_dev
= to_ctl_info(kobj
);
247 struct ctl_info_attribute
*ctl_info_attr
= to_ctl_info_attr(attr
);
249 if (ctl_info_attr
->store
)
250 return ctl_info_attr
->store(edac_dev
, buffer
, count
);
254 /* edac_dev file operations for an 'ctl_info' */
255 static struct sysfs_ops device_ctl_info_ops
= {
256 .show
= edac_dev_ctl_info_show
,
257 .store
= edac_dev_ctl_info_store
260 #define CTL_INFO_ATTR(_name,_mode,_show,_store) \
261 static struct ctl_info_attribute attr_ctl_info_##_name = { \
262 .attr = {.name = __stringify(_name), .mode = _mode }, \
268 /* Declare the various ctl_info attributes here and their respective ops */
269 CTL_INFO_ATTR(log_ue
,S_IRUGO
|S_IWUSR
,
270 edac_device_ctl_log_ue_show
,
271 edac_device_ctl_log_ue_store
);
272 CTL_INFO_ATTR(log_ce
,S_IRUGO
|S_IWUSR
,
273 edac_device_ctl_log_ce_show
,
274 edac_device_ctl_log_ce_store
);
275 CTL_INFO_ATTR(panic_on_ue
,S_IRUGO
|S_IWUSR
,
276 edac_device_ctl_panic_on_ue_show
,
277 edac_device_ctl_panic_on_ue_store
);
278 CTL_INFO_ATTR(poll_msec
,S_IRUGO
|S_IWUSR
,
279 edac_device_ctl_poll_msec_show
,
280 edac_device_ctl_poll_msec_store
);
283 /* Base Attributes of the EDAC_DEVICE ECC object */
284 static struct ctl_info_attribute
*device_ctrl_attr
[] = {
285 &attr_ctl_info_panic_on_ue
,
286 &attr_ctl_info_log_ue
,
287 &attr_ctl_info_log_ce
,
288 &attr_ctl_info_poll_msec
,
292 /* Main DEVICE kobject release() function */
293 static void edac_device_ctrl_master_release(struct kobject
*kobj
)
295 struct edac_device_ctl_info
*edac_dev
;
297 edac_dev
= to_edacdev(kobj
);
299 debugf1("%s()\n", __func__
);
300 complete(&edac_dev
->kobj_complete
);
303 static struct kobj_type ktype_device_ctrl
= {
304 .release
= edac_device_ctrl_master_release
,
305 .sysfs_ops
= &device_ctl_info_ops
,
306 .default_attrs
= (struct attribute
**) device_ctrl_attr
,
310 /**************** edac_device main kobj ctor/dtor code *********************/
313 * edac_device_register_main_kobj
315 * perform the high level setup for the new edac_device instance
320 static int edac_device_register_main_kobj(
321 struct edac_device_ctl_info
*edac_dev
)
324 struct sysdev_class
*edac_class
;
326 debugf1("%s()\n", __func__
);
328 /* get the /sys/devices/system/edac reference */
329 edac_class
= edac_get_edac_class();
330 if (edac_class
== NULL
) {
331 debugf1("%s() no edac_class error=%d\n", __func__
, err
);
335 /* Point to the 'edac_class' this instance 'reports' to */
336 edac_dev
->edac_class
= edac_class
;
338 /* Init the devices's kobject */
339 memset(&edac_dev
->kobj
, 0, sizeof (struct kobject
));
340 edac_dev
->kobj
.ktype
= &ktype_device_ctrl
;
342 /* set this new device under the edac_class kobject */
343 edac_dev
->kobj
.parent
= &edac_class
->kset
.kobj
;
345 /* generate sysfs "..../edac/<name>" */
346 debugf1("%s() set name of kobject to: %s\n",
347 __func__
, edac_dev
->name
);
348 err
= kobject_set_name(&edac_dev
->kobj
,"%s",edac_dev
->name
);
351 err
= kobject_register(&edac_dev
->kobj
);
353 debugf1("%s()Failed to register '.../edac/%s'\n",
354 __func__
,edac_dev
->name
);
358 debugf1("%s() Registered '.../edac/%s' kobject\n",
359 __func__
, edac_dev
->name
);
365 * edac_device_unregister_main_kobj:
366 * the '..../edac/<name>' kobject
368 static void edac_device_unregister_main_kobj(
369 struct edac_device_ctl_info
*edac_dev
)
371 debugf0("%s()\n", __func__
);
372 debugf1("%s() name of kobject is: %s\n",
373 __func__
, kobject_name(&edac_dev
->kobj
));
375 init_completion(&edac_dev
->kobj_complete
);
378 * Unregister the edac device's kobject and
379 * wait for reference count to reach 0.
381 kobject_unregister(&edac_dev
->kobj
);
382 wait_for_completion(&edac_dev
->kobj_complete
);
386 /*************** edac_dev -> instance information ***********/
389 * Set of low-level instance attribute show functions
391 static ssize_t
instance_ue_count_show(
392 struct edac_device_instance
*instance
, char *data
)
394 return sprintf(data
,"%u\n", instance
->counters
.ue_count
);
397 static ssize_t
instance_ce_count_show(
398 struct edac_device_instance
*instance
, char *data
)
400 return sprintf(data
,"%u\n", instance
->counters
.ce_count
);
405 #define to_instance(k) container_of(k, struct edac_device_instance, kobj)
406 #define to_instance_attr(a) container_of(a,struct instance_attribute,attr)
408 /* DEVICE instance kobject release() function */
409 static void edac_device_ctrl_instance_release(struct kobject
*kobj
)
411 struct edac_device_instance
*instance
;
413 debugf1("%s()\n", __func__
);
415 instance
= to_instance(kobj
);
416 complete(&instance
->kobj_complete
);
420 /* instance specific attribute structure */
421 struct instance_attribute
{
422 struct attribute attr
;
423 ssize_t (*show
)(struct edac_device_instance
*,char *);
424 ssize_t (*store
)(struct edac_device_instance
*,const char *,size_t);
428 /* Function to 'show' fields from the edac_dev 'instance' structure */
429 static ssize_t
edac_dev_instance_show(struct kobject
*kobj
,
430 struct attribute
*attr
,
433 struct edac_device_instance
*instance
= to_instance(kobj
);
434 struct instance_attribute
*instance_attr
= to_instance_attr(attr
);
436 if (instance_attr
->show
)
437 return instance_attr
->show(instance
,buffer
);
442 /* Function to 'store' fields into the edac_dev 'instance' structure */
443 static ssize_t
edac_dev_instance_store(struct kobject
*kobj
,
444 struct attribute
*attr
,
445 const char *buffer
, size_t count
)
447 struct edac_device_instance
*instance
= to_instance(kobj
);
448 struct instance_attribute
*instance_attr
= to_instance_attr(attr
);
450 if (instance_attr
->store
)
451 return instance_attr
->store(instance
, buffer
, count
);
457 /* edac_dev file operations for an 'instance' */
458 static struct sysfs_ops device_instance_ops
= {
459 .show
= edac_dev_instance_show
,
460 .store
= edac_dev_instance_store
463 #define INSTANCE_ATTR(_name,_mode,_show,_store) \
464 static struct instance_attribute attr_instance_##_name = { \
465 .attr = {.name = __stringify(_name), .mode = _mode }, \
471 * Define attributes visible for the edac_device instance object
472 * Each contains a pointer to a show and an optional set
473 * function pointer that does the low level output/input
475 INSTANCE_ATTR(ce_count
,S_IRUGO
,instance_ce_count_show
,NULL
);
476 INSTANCE_ATTR(ue_count
,S_IRUGO
,instance_ue_count_show
,NULL
);
478 /* list of edac_dev 'instance' attributes */
479 static struct instance_attribute
*device_instance_attr
[] = {
480 &attr_instance_ce_count
,
481 &attr_instance_ue_count
,
485 /* The 'ktype' for each edac_dev 'instance' */
486 static struct kobj_type ktype_instance_ctrl
= {
487 .release
= edac_device_ctrl_instance_release
,
488 .sysfs_ops
= &device_instance_ops
,
489 .default_attrs
= (struct attribute
**) device_instance_attr
,
493 /*************** edac_dev -> instance -> block information *********/
496 * Set of low-level block attribute show functions
498 static ssize_t
block_ue_count_show(
499 struct edac_device_block
*block
, char *data
)
501 return sprintf(data
,"%u\n", block
->counters
.ue_count
);
504 static ssize_t
block_ce_count_show(
505 struct edac_device_block
*block
, char *data
)
507 return sprintf(data
,"%u\n", block
->counters
.ce_count
);
512 #define to_block(k) container_of(k, struct edac_device_block, kobj)
513 #define to_block_attr(a) container_of(a,struct block_attribute,attr)
515 /* DEVICE block kobject release() function */
516 static void edac_device_ctrl_block_release(struct kobject
*kobj
)
518 struct edac_device_block
*block
;
520 debugf1("%s()\n", __func__
);
522 block
= to_block(kobj
);
523 complete(&block
->kobj_complete
);
526 /* block specific attribute structure */
527 struct block_attribute
{
528 struct attribute attr
;
529 ssize_t (*show
)(struct edac_device_block
*,char *);
530 ssize_t (*store
)(struct edac_device_block
*,const char *,size_t);
533 /* Function to 'show' fields from the edac_dev 'block' structure */
534 static ssize_t
edac_dev_block_show(struct kobject
*kobj
,
535 struct attribute
*attr
,
538 struct edac_device_block
*block
= to_block(kobj
);
539 struct block_attribute
*block_attr
= to_block_attr(attr
);
541 if (block_attr
->show
)
542 return block_attr
->show(block
,buffer
);
547 /* Function to 'store' fields into the edac_dev 'block' structure */
548 static ssize_t
edac_dev_block_store(struct kobject
*kobj
,
549 struct attribute
*attr
,
550 const char *buffer
, size_t count
)
552 struct edac_device_block
*block
= to_block(kobj
);
553 struct block_attribute
*block_attr
= to_block_attr(attr
);
555 if (block_attr
->store
)
556 return block_attr
->store(block
, buffer
, count
);
561 /* edac_dev file operations for a 'block' */
562 static struct sysfs_ops device_block_ops
= {
563 .show
= edac_dev_block_show
,
564 .store
= edac_dev_block_store
568 #define BLOCK_ATTR(_name,_mode,_show,_store) \
569 static struct block_attribute attr_block_##_name = { \
570 .attr = {.name = __stringify(_name), .mode = _mode }, \
575 BLOCK_ATTR(ce_count
,S_IRUGO
,block_ce_count_show
,NULL
);
576 BLOCK_ATTR(ue_count
,S_IRUGO
,block_ue_count_show
,NULL
);
579 /* list of edac_dev 'block' attributes */
580 static struct block_attribute
*device_block_attr
[] = {
581 &attr_block_ce_count
,
582 &attr_block_ue_count
,
586 /* The 'ktype' for each edac_dev 'block' */
587 static struct kobj_type ktype_block_ctrl
= {
588 .release
= edac_device_ctrl_block_release
,
589 .sysfs_ops
= &device_block_ops
,
590 .default_attrs
= (struct attribute
**) device_block_attr
,
594 /************** block ctor/dtor code ************/
597 * edac_device_create_block
599 static int edac_device_create_block(
600 struct edac_device_ctl_info
*edac_dev
,
601 struct edac_device_instance
*instance
,
605 struct edac_device_block
*block
;
607 block
= &instance
->blocks
[idx
];
609 debugf1("%s() Instance '%s' block[%d] '%s'\n",
610 __func__
,instance
->name
, idx
, block
->name
);
612 /* init this block's kobject */
613 memset(&block
->kobj
, 0, sizeof (struct kobject
));
614 block
->kobj
.parent
= &instance
->kobj
;
615 block
->kobj
.ktype
= &ktype_block_ctrl
;
617 err
= kobject_set_name(&block
->kobj
,"%s",block
->name
);
621 err
= kobject_register(&block
->kobj
);
623 debugf1("%s()Failed to register instance '%s'\n",
624 __func__
,block
->name
);
632 * edac_device_delete_block(edac_dev,j);
634 static void edac_device_delete_block(
635 struct edac_device_ctl_info
*edac_dev
,
636 struct edac_device_instance
*instance
,
639 struct edac_device_block
*block
;
641 block
= &instance
->blocks
[idx
];
643 /* unregister this block's kobject */
644 init_completion(&block
->kobj_complete
);
645 kobject_unregister(&block
->kobj
);
646 wait_for_completion(&block
->kobj_complete
);
649 /************** instance ctor/dtor code ************/
652 * edac_device_create_instance
653 * create just one instance of an edac_device 'instance'
655 static int edac_device_create_instance(
656 struct edac_device_ctl_info
*edac_dev
, int idx
)
660 struct edac_device_instance
*instance
;
662 instance
= &edac_dev
->instances
[idx
];
664 /* Init the instance's kobject */
665 memset(&instance
->kobj
, 0, sizeof (struct kobject
));
667 /* set this new device under the edac_device main kobject */
668 instance
->kobj
.parent
= &edac_dev
->kobj
;
669 instance
->kobj
.ktype
= &ktype_instance_ctrl
;
671 err
= kobject_set_name(&instance
->kobj
,"%s",instance
->name
);
675 err
= kobject_register(&instance
->kobj
);
677 debugf2("%s() Failed to register instance '%s'\n",
678 __func__
,instance
->name
);
682 debugf1("%s() now register '%d' blocks for instance %d\n",
683 __func__
,instance
->nr_blocks
,idx
);
685 /* register all blocks of this instance */
686 for (i
= 0; i
< instance
->nr_blocks
; i
++ ) {
687 err
= edac_device_create_block(edac_dev
,instance
,i
);
689 for (j
= 0; j
< i
; j
++) {
690 edac_device_delete_block(edac_dev
,instance
,j
);
696 debugf1("%s() Registered instance %d '%s' kobject\n",
697 __func__
, idx
, instance
->name
);
703 * edac_device_remove_instance
704 * remove an edac_device instance
706 static void edac_device_delete_instance(
707 struct edac_device_ctl_info
*edac_dev
, int idx
)
710 struct edac_device_instance
*instance
;
712 instance
= &edac_dev
->instances
[idx
];
714 /* unregister all blocks in this instance */
715 for (i
= 0; i
< instance
->nr_blocks
; i
++) {
716 edac_device_delete_block(edac_dev
,instance
,i
);
719 /* unregister this instance's kobject */
720 init_completion(&instance
->kobj_complete
);
721 kobject_unregister(&instance
->kobj
);
722 wait_for_completion(&instance
->kobj_complete
);
726 * edac_device_create_instances
727 * create the first level of 'instances' for this device
728 * (ie 'cache' might have 'cache0', 'cache1', 'cache2', etc
730 static int edac_device_create_instances(struct edac_device_ctl_info
*edac_dev
)
735 debugf0("%s()\n", __func__
);
737 /* iterate over creation of the instances */
738 for (i
= 0; i
< edac_dev
->nr_instances
; i
++ ) {
739 err
= edac_device_create_instance(edac_dev
,i
);
741 /* unwind previous instances on error */
742 for (j
= 0; j
< i
; j
++) {
743 edac_device_delete_instance(edac_dev
,j
);
753 * edac_device_delete_instances(edac_dev);
754 * unregister all the kobjects of the instances
756 static void edac_device_delete_instances(struct edac_device_ctl_info
*edac_dev
)
760 /* iterate over creation of the instances */
761 for (i
= 0; i
< edac_dev
->nr_instances
; i
++ ) {
762 edac_device_delete_instance(edac_dev
,i
);
766 /******************* edac_dev sysfs ctor/dtor code *************/
769 * edac_device_create_sysfs() Constructor
771 * Create a new edac_device kobject instance,
777 int edac_device_create_sysfs(struct edac_device_ctl_info
*edac_dev
)
780 struct kobject
*edac_kobj
=&edac_dev
->kobj
;
782 /* register this instance's main kobj with the edac class kobj */
783 err
= edac_device_register_main_kobj(edac_dev
);
787 debugf0("%s() idx=%d\n", __func__
, edac_dev
->dev_idx
);
789 /* create a symlink from the edac device
790 * to the platform 'device' being used for this
792 err
= sysfs_create_link(edac_kobj
,
793 &edac_dev
->dev
->kobj
,
794 EDAC_DEVICE_SYMLINK
);
796 debugf0("%s() sysfs_create_link() returned err= %d\n",
801 debugf0("%s() calling create-instances, idx=%d\n",
802 __func__
, edac_dev
->dev_idx
);
804 /* Create the first level instance directories */
805 err
= edac_device_create_instances(edac_dev
);
812 /* Error unwind stack */
815 edac_device_unregister_main_kobj(edac_dev
);
821 * edac_device_remove_sysfs() destructor
823 * remove a edac_device instance
825 void edac_device_remove_sysfs(struct edac_device_ctl_info
*edac_dev
)
827 debugf0("%s()\n", __func__
);
829 edac_device_delete_instances(edac_dev
);
831 /* remove the sym link */
832 sysfs_remove_link(&edac_dev
->kobj
, EDAC_DEVICE_SYMLINK
);
834 /* unregister the instance's main kobj */
835 edac_device_unregister_main_kobj(edac_dev
);