drivers/edac: add edac_device class
[deliverable/linux.git] / drivers / edac / edac_device_sysfs.c
1 /*
2 * file for managing the edac_device class of devices for EDAC
3 *
4 * (C) 2007 SoftwareBitMaker(http://www.softwarebitmaker.com)
5 * This file may be distributed under the terms of the
6 * GNU General Public License.
7 *
8 * Written Doug Thompson <norsk5@xmission.com>
9 *
10 */
11
12 #include <linux/module.h>
13 #include <linux/sysdev.h>
14 #include <linux/ctype.h>
15
16 #include "edac_core.h"
17 #include "edac_module.h"
18
19
20 #define EDAC_DEVICE_SYMLINK "device"
21
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)
24
25 #ifdef DKT
26
27 static ssize_t edac_dev_ue_count_show(struct edac_device_ctl_info *edac_dev,
28 char *data)
29 {
30 return sprintf(data,"%d\n", edac_dev->ue_count);
31 }
32
33 static ssize_t edac_dev_ce_count_show(struct edac_device_ctl_info *edac_dev,
34 char *data)
35 {
36 return sprintf(data,"%d\n", edac_dev->ce_count);
37 }
38
39 static ssize_t edac_dev_seconds_show(struct edac_device_ctl_info *edac_dev,
40 char *data)
41 {
42 return sprintf(data,"%ld\n", (jiffies - edac_dev->start_time) / HZ);
43 }
44
45 static ssize_t edac_dev_ctl_name_show(struct edac_device_ctl_info *edac_dev,
46 char *data)
47 {
48 return sprintf(data,"%s\n", edac_dev->ctl_name);
49 }
50
51
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);
56 };
57
58
59 /* EDAC DEVICE show/store functions for top most object */
60 static ssize_t edacdev_show(struct kobject *kobj, struct attribute *attr,
61 char *buffer)
62 {
63 struct edac_device_ctl_info *edac_dev = to_edacdev(kobj);
64 struct edacdev_attribute * edacdev_attr = to_edacdev_attr(attr);
65
66 if (edacdev_attr->show)
67 return edacdev_attr->show(edac_dev, buffer);
68
69 return -EIO;
70 }
71
72 static ssize_t edacdev_store(struct kobject *kobj, struct attribute *attr,
73 const char *buffer, size_t count)
74 {
75 struct edac_device_ctl_info *edac_dev = to_edacdev(kobj);
76 struct edacdev_attribute * edacdev_attr = to_edacdev_attr(attr);
77
78 if (edacdev_attr->store)
79 return edacdev_attr->store(edac_dev, buffer, count);
80
81 return -EIO;
82 }
83
84 static struct sysfs_ops edac_dev_ops = {
85 .show = edacdev_show,
86 .store = edacdev_store
87 };
88
89 #define EDACDEV_ATTR(_name,_mode,_show,_store) \
90 static struct edacdev_attribute edac_dev_attr_##_name = { \
91 .attr = {.name = __stringify(_name), .mode = _mode }, \
92 .show = _show, \
93 .store = _store, \
94 };
95
96 /* default Control file */
97 EDACDEV_ATTR(reset_counters,S_IWUSR,NULL,edac_dev_reset_counters_store);
98
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);
104
105
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,
112 NULL
113 };
114
115 /*
116 * Release of a Edac Device controlling instance
117 */
118 static void edac_dev_instance_release(struct kobject *kobj)
119 {
120 struct edac_device_ctl_info *edac_dev;
121
122 edac_dev = to_edacdev(kobj);
123 debugf0("%s() idx=%d\n", __func__, edac_dev->dev_idx);
124 complete(&edac_dev->kobj_complete);
125 }
126
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,
131 };
132
133 #endif
134
135 /************************** edac_device sysfs code and data **************/
136
137 /*
138 * Set of edac_device_ctl_info attribute store/show functions
139 */
140
141 /* 'log_ue' */
142 static ssize_t edac_device_ctl_log_ue_show(
143 struct edac_device_ctl_info *ctl_info, char *data)
144 {
145 return sprintf(data,"%u\n", ctl_info->log_ue);
146 }
147
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)
151 {
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);
154
155 return count;
156 }
157
158 /* 'log_ce' */
159 static ssize_t edac_device_ctl_log_ce_show(
160 struct edac_device_ctl_info *ctl_info,char *data)
161 {
162 return sprintf(data,"%u\n", ctl_info->log_ce);
163 }
164
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)
168 {
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);
171
172 return count;
173 }
174
175
176 /* 'panic_on_ue' */
177 static ssize_t edac_device_ctl_panic_on_ue_show(
178 struct edac_device_ctl_info *ctl_info, char *data)
179 {
180 return sprintf(data,"%u\n", ctl_info->panic_on_ue);
181 }
182
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)
186 {
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);
189
190 return count;
191 }
192
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)
196 {
197 return sprintf(data,"%u\n", ctl_info->poll_msec);
198 }
199
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)
203 {
204 unsigned long value;
205
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
209 * and set a new one.
210 */
211 value = simple_strtoul(data,NULL,0);
212 edac_device_reset_delay_period(ctl_info,value);
213
214 return count;
215 }
216
217
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);
223 };
224
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)
227
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,
231 char *buffer)
232 {
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);
235
236 if (ctl_info_attr->show)
237 return ctl_info_attr->show(edac_dev,buffer);
238 return -EIO;
239 }
240
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)
245 {
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);
248
249 if (ctl_info_attr->store)
250 return ctl_info_attr->store(edac_dev, buffer, count);
251 return -EIO;
252 }
253
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
258 };
259
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 }, \
263 .show = _show, \
264 .store = _store, \
265 };
266
267
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);
281
282
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,
289 NULL,
290 };
291
292 /* Main DEVICE kobject release() function */
293 static void edac_device_ctrl_master_release(struct kobject *kobj)
294 {
295 struct edac_device_ctl_info *edac_dev;
296
297 edac_dev = to_edacdev(kobj);
298
299 debugf1("%s()\n", __func__);
300 complete(&edac_dev->kobj_complete);
301 }
302
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,
307 };
308
309
310 /**************** edac_device main kobj ctor/dtor code *********************/
311
312 /*
313 * edac_device_register_main_kobj
314 *
315 * perform the high level setup for the new edac_device instance
316 *
317 * Return: 0 SUCCESS
318 * !0 FAILURE
319 */
320 static int edac_device_register_main_kobj(
321 struct edac_device_ctl_info *edac_dev)
322 {
323 int err = 0;
324 struct sysdev_class *edac_class;
325
326 debugf1("%s()\n", __func__);
327
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);
332 return err;
333 }
334
335 /* Point to the 'edac_class' this instance 'reports' to */
336 edac_dev->edac_class = edac_class;
337
338 /* Init the devices's kobject */
339 memset(&edac_dev->kobj, 0, sizeof (struct kobject));
340 edac_dev->kobj.ktype = &ktype_device_ctrl;
341
342 /* set this new device under the edac_class kobject */
343 edac_dev->kobj.parent = &edac_class->kset.kobj;
344
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);
349 if (err)
350 return err;
351 err = kobject_register(&edac_dev->kobj);
352 if (err) {
353 debugf1("%s()Failed to register '.../edac/%s'\n",
354 __func__,edac_dev->name);
355 return err;
356 }
357
358 debugf1("%s() Registered '.../edac/%s' kobject\n",
359 __func__, edac_dev->name);
360
361 return 0;
362 }
363
364 /*
365 * edac_device_unregister_main_kobj:
366 * the '..../edac/<name>' kobject
367 */
368 static void edac_device_unregister_main_kobj(
369 struct edac_device_ctl_info *edac_dev)
370 {
371 debugf0("%s()\n", __func__);
372 debugf1("%s() name of kobject is: %s\n",
373 __func__, kobject_name(&edac_dev->kobj));
374
375 init_completion(&edac_dev->kobj_complete);
376
377 /*
378 * Unregister the edac device's kobject and
379 * wait for reference count to reach 0.
380 */
381 kobject_unregister(&edac_dev->kobj);
382 wait_for_completion(&edac_dev->kobj_complete);
383 }
384
385
386 /*************** edac_dev -> instance information ***********/
387
388 /*
389 * Set of low-level instance attribute show functions
390 */
391 static ssize_t instance_ue_count_show(
392 struct edac_device_instance *instance, char *data)
393 {
394 return sprintf(data,"%u\n", instance->counters.ue_count);
395 }
396
397 static ssize_t instance_ce_count_show(
398 struct edac_device_instance *instance, char *data)
399 {
400 return sprintf(data,"%u\n", instance->counters.ce_count);
401 }
402
403
404
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)
407
408 /* DEVICE instance kobject release() function */
409 static void edac_device_ctrl_instance_release(struct kobject *kobj)
410 {
411 struct edac_device_instance *instance;
412
413 debugf1("%s()\n", __func__);
414
415 instance = to_instance(kobj);
416 complete(&instance->kobj_complete);
417 }
418
419
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);
425 };
426
427
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,
431 char *buffer)
432 {
433 struct edac_device_instance *instance = to_instance(kobj);
434 struct instance_attribute *instance_attr = to_instance_attr(attr);
435
436 if (instance_attr->show)
437 return instance_attr->show(instance,buffer);
438 return -EIO;
439 }
440
441
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)
446 {
447 struct edac_device_instance *instance = to_instance(kobj);
448 struct instance_attribute *instance_attr = to_instance_attr(attr);
449
450 if (instance_attr->store)
451 return instance_attr->store(instance, buffer, count);
452 return -EIO;
453 }
454
455
456
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
461 };
462
463 #define INSTANCE_ATTR(_name,_mode,_show,_store) \
464 static struct instance_attribute attr_instance_##_name = { \
465 .attr = {.name = __stringify(_name), .mode = _mode }, \
466 .show = _show, \
467 .store = _store, \
468 };
469
470 /*
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
474 */
475 INSTANCE_ATTR(ce_count,S_IRUGO,instance_ce_count_show,NULL);
476 INSTANCE_ATTR(ue_count,S_IRUGO,instance_ue_count_show,NULL);
477
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,
482 NULL,
483 };
484
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,
490 };
491
492
493 /*************** edac_dev -> instance -> block information *********/
494
495 /*
496 * Set of low-level block attribute show functions
497 */
498 static ssize_t block_ue_count_show(
499 struct edac_device_block *block, char *data)
500 {
501 return sprintf(data,"%u\n", block->counters.ue_count);
502 }
503
504 static ssize_t block_ce_count_show(
505 struct edac_device_block *block, char *data)
506 {
507 return sprintf(data,"%u\n", block->counters.ce_count);
508 }
509
510
511
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)
514
515 /* DEVICE block kobject release() function */
516 static void edac_device_ctrl_block_release(struct kobject *kobj)
517 {
518 struct edac_device_block *block;
519
520 debugf1("%s()\n", __func__);
521
522 block = to_block(kobj);
523 complete(&block->kobj_complete);
524 }
525
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);
531 };
532
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,
536 char *buffer)
537 {
538 struct edac_device_block *block = to_block(kobj);
539 struct block_attribute *block_attr = to_block_attr(attr);
540
541 if (block_attr->show)
542 return block_attr->show(block,buffer);
543 return -EIO;
544 }
545
546
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)
551 {
552 struct edac_device_block *block = to_block(kobj);
553 struct block_attribute *block_attr = to_block_attr(attr);
554
555 if (block_attr->store)
556 return block_attr->store(block, buffer, count);
557 return -EIO;
558 }
559
560
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
565 };
566
567
568 #define BLOCK_ATTR(_name,_mode,_show,_store) \
569 static struct block_attribute attr_block_##_name = { \
570 .attr = {.name = __stringify(_name), .mode = _mode }, \
571 .show = _show, \
572 .store = _store, \
573 };
574
575 BLOCK_ATTR(ce_count,S_IRUGO,block_ce_count_show,NULL);
576 BLOCK_ATTR(ue_count,S_IRUGO,block_ue_count_show,NULL);
577
578
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,
583 NULL,
584 };
585
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,
591 };
592
593
594 /************** block ctor/dtor code ************/
595
596 /*
597 * edac_device_create_block
598 */
599 static int edac_device_create_block(
600 struct edac_device_ctl_info *edac_dev,
601 struct edac_device_instance *instance,
602 int idx)
603 {
604 int err;
605 struct edac_device_block *block;
606
607 block = &instance->blocks[idx];
608
609 debugf1("%s() Instance '%s' block[%d] '%s'\n",
610 __func__,instance->name, idx, block->name);
611
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;
616
617 err = kobject_set_name(&block->kobj,"%s",block->name);
618 if (err)
619 return err;
620
621 err = kobject_register(&block->kobj);
622 if (err) {
623 debugf1("%s()Failed to register instance '%s'\n",
624 __func__,block->name);
625 return err;
626 }
627
628 return 0;
629 }
630
631 /*
632 * edac_device_delete_block(edac_dev,j);
633 */
634 static void edac_device_delete_block(
635 struct edac_device_ctl_info *edac_dev,
636 struct edac_device_instance *instance,
637 int idx)
638 {
639 struct edac_device_block *block;
640
641 block = &instance->blocks[idx];
642
643 /* unregister this block's kobject */
644 init_completion(&block->kobj_complete);
645 kobject_unregister(&block->kobj);
646 wait_for_completion(&block->kobj_complete);
647 }
648
649 /************** instance ctor/dtor code ************/
650
651 /*
652 * edac_device_create_instance
653 * create just one instance of an edac_device 'instance'
654 */
655 static int edac_device_create_instance(
656 struct edac_device_ctl_info *edac_dev, int idx)
657 {
658 int i, j;
659 int err;
660 struct edac_device_instance *instance;
661
662 instance = &edac_dev->instances[idx];
663
664 /* Init the instance's kobject */
665 memset(&instance->kobj, 0, sizeof (struct kobject));
666
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;
670
671 err = kobject_set_name(&instance->kobj,"%s",instance->name);
672 if (err)
673 return err;
674
675 err = kobject_register(&instance->kobj);
676 if (err != 0) {
677 debugf2("%s() Failed to register instance '%s'\n",
678 __func__,instance->name);
679 return err;
680 }
681
682 debugf1("%s() now register '%d' blocks for instance %d\n",
683 __func__,instance->nr_blocks,idx);
684
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);
688 if (err) {
689 for (j = 0; j < i; j++) {
690 edac_device_delete_block(edac_dev,instance,j);
691 }
692 return err;
693 }
694 }
695
696 debugf1("%s() Registered instance %d '%s' kobject\n",
697 __func__, idx, instance->name);
698
699 return 0;
700 }
701
702 /*
703 * edac_device_remove_instance
704 * remove an edac_device instance
705 */
706 static void edac_device_delete_instance(
707 struct edac_device_ctl_info *edac_dev, int idx)
708 {
709 int i;
710 struct edac_device_instance *instance;
711
712 instance = &edac_dev->instances[idx];
713
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);
717 }
718
719 /* unregister this instance's kobject */
720 init_completion(&instance->kobj_complete);
721 kobject_unregister(&instance->kobj);
722 wait_for_completion(&instance->kobj_complete);
723 }
724
725 /*
726 * edac_device_create_instances
727 * create the first level of 'instances' for this device
728 * (ie 'cache' might have 'cache0', 'cache1', 'cache2', etc
729 */
730 static int edac_device_create_instances(struct edac_device_ctl_info *edac_dev)
731 {
732 int i, j;
733 int err;
734
735 debugf0("%s()\n", __func__);
736
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);
740 if (err) {
741 /* unwind previous instances on error */
742 for (j = 0; j < i; j++) {
743 edac_device_delete_instance(edac_dev,j);
744 }
745 return err;
746 }
747 }
748
749 return 0;
750 }
751
752 /*
753 * edac_device_delete_instances(edac_dev);
754 * unregister all the kobjects of the instances
755 */
756 static void edac_device_delete_instances(struct edac_device_ctl_info *edac_dev)
757 {
758 int i;
759
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);
763 }
764 }
765
766 /******************* edac_dev sysfs ctor/dtor code *************/
767
768 /*
769 * edac_device_create_sysfs() Constructor
770 *
771 * Create a new edac_device kobject instance,
772 *
773 * Return:
774 * 0 Success
775 * !0 Failure
776 */
777 int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)
778 {
779 int err;
780 struct kobject *edac_kobj=&edac_dev->kobj;
781
782 /* register this instance's main kobj with the edac class kobj */
783 err = edac_device_register_main_kobj(edac_dev);
784 if (err)
785 return err;
786
787 debugf0("%s() idx=%d\n", __func__, edac_dev->dev_idx);
788
789 /* create a symlink from the edac device
790 * to the platform 'device' being used for this
791 */
792 err = sysfs_create_link(edac_kobj,
793 &edac_dev->dev->kobj,
794 EDAC_DEVICE_SYMLINK);
795 if (err) {
796 debugf0("%s() sysfs_create_link() returned err= %d\n",
797 __func__, err);
798 return err;
799 }
800
801 debugf0("%s() calling create-instances, idx=%d\n",
802 __func__, edac_dev->dev_idx);
803
804 /* Create the first level instance directories */
805 err = edac_device_create_instances(edac_dev);
806 if (err) {
807 goto error0;
808 }
809
810 return 0;
811
812 /* Error unwind stack */
813
814 error0:
815 edac_device_unregister_main_kobj(edac_dev);
816
817 return err;
818 }
819
820 /*
821 * edac_device_remove_sysfs() destructor
822 *
823 * remove a edac_device instance
824 */
825 void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev)
826 {
827 debugf0("%s()\n", __func__);
828
829 edac_device_delete_instances(edac_dev);
830
831 /* remove the sym link */
832 sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);
833
834 /* unregister the instance's main kobj */
835 edac_device_unregister_main_kobj(edac_dev);
836 }
837
This page took 0.049183 seconds and 6 git commands to generate.