aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_mc_sysfs.c
diff options
context:
space:
mode:
authorDoug Thompson <dougthompson@xmission.com>2007-07-19 04:50:27 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:57 -0400
commit8096cfafbb7ad3cb1a286ae7e8086167f4ebb4b6 (patch)
tree27b859beffef019095db810244f93e10473ea06f /drivers/edac/edac_mc_sysfs.c
parentd45e7823baf655ced91c7987fb4ba9aae990ad6d (diff)
drivers/edac: fix edac_mc sysfs completion code
This patch refactors the 'releasing' of kobjects for the edac_mc type of device. The correct pattern of kobject release is followed. As internal kobjs are allocated they bump a ref count on the top level kobj. It in turn has a module ref count on the edac_core module. When internal kobjects are released, they dec the ref count on the top level kobj. When the top level kobj reaches zero, it decrements the ref count on the edac_core object, allow it to be unloaded, as all resources have all now been released. Cc: Alan Cox alan@lxorguk.ukuu.org.uk Signed-off-by: Doug Thompson <dougthompson@xmission.com> Acked-by: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/edac/edac_mc_sysfs.c')
-rw-r--r--drivers/edac/edac_mc_sysfs.c568
1 files changed, 355 insertions, 213 deletions
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 0843eaa10ec9..cd090b0677a7 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -10,10 +10,12 @@
10 */ 10 */
11 11
12#include <linux/ctype.h> 12#include <linux/ctype.h>
13#include <linux/bug.h>
13 14
14#include "edac_core.h" 15#include "edac_core.h"
15#include "edac_module.h" 16#include "edac_module.h"
16 17
18
17/* MC EDAC Controls, setable by module parameter, and sysfs */ 19/* MC EDAC Controls, setable by module parameter, and sysfs */
18static int edac_mc_log_ue = 1; 20static int edac_mc_log_ue = 1;
19static int edac_mc_log_ce = 1; 21static int edac_mc_log_ce = 1;
@@ -98,15 +100,7 @@ static const char *edac_caps[] = {
98 [EDAC_S16ECD16ED] = "S16ECD16ED" 100 [EDAC_S16ECD16ED] = "S16ECD16ED"
99}; 101};
100 102
101/* sysfs object:
102 * /sys/devices/system/edac/mc
103 */
104static struct kobject edac_memctrl_kobj;
105 103
106/* We use these to wait for the reference counts on edac_memctrl_kobj and
107 * edac_pci_kobj to reach 0.
108 */
109static struct completion edac_memctrl_kobj_complete;
110 104
111/* 105/*
112 * /sys/devices/system/edac/mc; 106 * /sys/devices/system/edac/mc;
@@ -128,153 +122,6 @@ static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count)
128 return count; 122 return count;
129} 123}
130 124
131struct memctrl_dev_attribute {
132 struct attribute attr;
133 void *value;
134 ssize_t(*show) (void *, char *);
135 ssize_t(*store) (void *, const char *, size_t);
136};
137
138/* Set of show/store abstract level functions for memory control object */
139static ssize_t memctrl_dev_show(struct kobject *kobj,
140 struct attribute *attr, char *buffer)
141{
142 struct memctrl_dev_attribute *memctrl_dev;
143 memctrl_dev = (struct memctrl_dev_attribute *)attr;
144
145 if (memctrl_dev->show)
146 return memctrl_dev->show(memctrl_dev->value, buffer);
147
148 return -EIO;
149}
150
151static ssize_t memctrl_dev_store(struct kobject *kobj, struct attribute *attr,
152 const char *buffer, size_t count)
153{
154 struct memctrl_dev_attribute *memctrl_dev;
155 memctrl_dev = (struct memctrl_dev_attribute *)attr;
156
157 if (memctrl_dev->store)
158 return memctrl_dev->store(memctrl_dev->value, buffer, count);
159
160 return -EIO;
161}
162
163static struct sysfs_ops memctrlfs_ops = {
164 .show = memctrl_dev_show,
165 .store = memctrl_dev_store
166};
167
168#define MEMCTRL_ATTR(_name,_mode,_show,_store) \
169static struct memctrl_dev_attribute attr_##_name = { \
170 .attr = {.name = __stringify(_name), .mode = _mode }, \
171 .value = &_name, \
172 .show = _show, \
173 .store = _store, \
174};
175
176#define MEMCTRL_STRING_ATTR(_name,_data,_mode,_show,_store) \
177static struct memctrl_dev_attribute attr_##_name = { \
178 .attr = {.name = __stringify(_name), .mode = _mode }, \
179 .value = _data, \
180 .show = _show, \
181 .store = _store, \
182};
183
184/* csrow<id> control files */
185MEMCTRL_ATTR(edac_mc_panic_on_ue,
186 S_IRUGO | S_IWUSR, memctrl_int_show, memctrl_int_store);
187
188MEMCTRL_ATTR(edac_mc_log_ue,
189 S_IRUGO | S_IWUSR, memctrl_int_show, memctrl_int_store);
190
191MEMCTRL_ATTR(edac_mc_log_ce,
192 S_IRUGO | S_IWUSR, memctrl_int_show, memctrl_int_store);
193
194MEMCTRL_ATTR(edac_mc_poll_msec,
195 S_IRUGO | S_IWUSR, memctrl_int_show, memctrl_int_store);
196
197/* Base Attributes of the memory ECC object */
198static struct memctrl_dev_attribute *memctrl_attr[] = {
199 &attr_edac_mc_panic_on_ue,
200 &attr_edac_mc_log_ue,
201 &attr_edac_mc_log_ce,
202 &attr_edac_mc_poll_msec,
203 NULL,
204};
205
206/* Main MC kobject release() function */
207static void edac_memctrl_master_release(struct kobject *kobj)
208{
209 debugf1("%s()\n", __func__);
210 complete(&edac_memctrl_kobj_complete);
211}
212
213static struct kobj_type ktype_memctrl = {
214 .release = edac_memctrl_master_release,
215 .sysfs_ops = &memctrlfs_ops,
216 .default_attrs = (struct attribute **)memctrl_attr,
217};
218
219/* Initialize the main sysfs entries for edac:
220 * /sys/devices/system/edac
221 *
222 * and children
223 *
224 * Return: 0 SUCCESS
225 * !0 FAILURE
226 */
227int edac_sysfs_memctrl_setup(void)
228{
229 int err = 0;
230 struct sysdev_class *edac_class;
231
232 debugf1("%s()\n", __func__);
233
234 /* get the /sys/devices/system/edac class reference */
235 edac_class = edac_get_edac_class();
236 if (edac_class == NULL) {
237 debugf1("%s() no edac_class error=%d\n", __func__, err);
238 return err;
239 }
240
241 /* Init the MC's kobject */
242 memset(&edac_memctrl_kobj, 0, sizeof(edac_memctrl_kobj));
243 edac_memctrl_kobj.parent = &edac_class->kset.kobj;
244 edac_memctrl_kobj.ktype = &ktype_memctrl;
245
246 /* generate sysfs "..../edac/mc" */
247 err = kobject_set_name(&edac_memctrl_kobj, "mc");
248 if (err) {
249 debugf1("%s() Failed to set name '.../edac/mc'\n", __func__);
250 return err;
251 }
252
253 /* FIXME: maybe new sysdev_create_subdir() */
254 err = kobject_register(&edac_memctrl_kobj);
255 if (err) {
256 debugf1("%s() Failed to register '.../edac/mc'\n", __func__);
257 return err;
258 }
259
260 debugf1("%s() Registered '.../edac/mc' kobject\n", __func__);
261 return 0;
262}
263
264/*
265 * MC teardown:
266 * the '..../edac/mc' kobject followed by '..../edac' itself
267 */
268void edac_sysfs_memctrl_teardown(void)
269{
270 debugf0("MC: " __FILE__ ": %s()\n", __func__);
271
272 /* Unregister the MC's kobject and wait for reference count to reach 0.
273 */
274 init_completion(&edac_memctrl_kobj_complete);
275 kobject_unregister(&edac_memctrl_kobj);
276 wait_for_completion(&edac_memctrl_kobj_complete);
277}
278 125
279/* EDAC sysfs CSROW data structures and methods 126/* EDAC sysfs CSROW data structures and methods
280 */ 127 */
@@ -486,10 +333,15 @@ static int edac_create_channel_files(struct kobject *kobj, int chan)
486/* No memory to release for this kobj */ 333/* No memory to release for this kobj */
487static void edac_csrow_instance_release(struct kobject *kobj) 334static void edac_csrow_instance_release(struct kobject *kobj)
488{ 335{
336 struct mem_ctl_info *mci;
489 struct csrow_info *cs; 337 struct csrow_info *cs;
490 338
339 debugf1("%s()\n", __func__);
340
491 cs = container_of(kobj, struct csrow_info, kobj); 341 cs = container_of(kobj, struct csrow_info, kobj);
492 complete(&cs->kobj_complete); 342 mci = cs->mci;
343
344 kobject_put(&mci->edac_mci_kobj);
493} 345}
494 346
495/* the kobj_type instance for a CSROW */ 347/* the kobj_type instance for a CSROW */
@@ -500,38 +352,61 @@ static struct kobj_type ktype_csrow = {
500}; 352};
501 353
502/* Create a CSROW object under specifed edac_mc_device */ 354/* Create a CSROW object under specifed edac_mc_device */
503static int edac_create_csrow_object(struct kobject *edac_mci_kobj, 355static int edac_create_csrow_object(struct mem_ctl_info *mci,
504 struct csrow_info *csrow, int index) 356 struct csrow_info *csrow, int index)
505{ 357{
506 int err = 0; 358 struct kobject *kobj_mci = &mci->edac_mci_kobj;
359 struct kobject *kobj;
507 int chan; 360 int chan;
508 361 int err;
509 memset(&csrow->kobj, 0, sizeof(csrow->kobj));
510 362
511 /* generate ..../edac/mc/mc<id>/csrow<index> */ 363 /* generate ..../edac/mc/mc<id>/csrow<index> */
512 364 memset(&csrow->kobj, 0, sizeof(csrow->kobj));
513 csrow->kobj.parent = edac_mci_kobj; 365 csrow->mci = mci; /* include container up link */
366 csrow->kobj.parent = kobj_mci;
514 csrow->kobj.ktype = &ktype_csrow; 367 csrow->kobj.ktype = &ktype_csrow;
515 368
516 /* name this instance of csrow<id> */ 369 /* name this instance of csrow<id> */
517 err = kobject_set_name(&csrow->kobj, "csrow%d", index); 370 err = kobject_set_name(&csrow->kobj, "csrow%d", index);
518 if (err) 371 if (err)
519 goto error_exit; 372 goto err_out;
373
374 /* bump the mci instance's kobject's ref count */
375 kobj = kobject_get(&mci->edac_mci_kobj);
376 if (!kobj) {
377 err = -ENODEV;
378 goto err_out;
379 }
520 380
521 /* Instanstiate the csrow object */ 381 /* Instanstiate the csrow object */
522 err = kobject_register(&csrow->kobj); 382 err = kobject_register(&csrow->kobj);
523 if (!err) { 383 if (err)
524 /* Create the dyanmic attribute files on this csrow, 384 goto err_release_top_kobj;
525 * namely, the DIMM labels and the channel ce_count 385
526 */ 386 /* At this point, to release a csrow kobj, one must
527 for (chan = 0; chan < csrow->nr_channels; chan++) { 387 * call the kobject_unregister and allow that tear down
528 err = edac_create_channel_files(&csrow->kobj, chan); 388 * to work the releasing
529 if (err) 389 */
530 break; 390
391 /* Create the dyanmic attribute files on this csrow,
392 * namely, the DIMM labels and the channel ce_count
393 */
394 for (chan = 0; chan < csrow->nr_channels; chan++) {
395 err = edac_create_channel_files(&csrow->kobj, chan);
396 if (err) {
397 /* special case the unregister here */
398 kobject_unregister(&csrow->kobj);
399 goto err_out;
531 } 400 }
532 } 401 }
533 402
534error_exit: 403 return 0;
404
405 /* error unwind stack */
406err_release_top_kobj:
407 kobject_put(&mci->edac_mci_kobj);
408
409err_out:
535 return err; 410 return err;
536} 411}
537 412
@@ -688,6 +563,7 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
688 return -EIO; 563 return -EIO;
689} 564}
690 565
566/* Intermediate show/store table */
691static struct sysfs_ops mci_ops = { 567static struct sysfs_ops mci_ops = {
692 .show = mcidev_show, 568 .show = mcidev_show,
693 .store = mcidev_store 569 .store = mcidev_store
@@ -729,32 +605,213 @@ static struct mcidev_sysfs_attribute *mci_attr[] = {
729 NULL 605 NULL
730}; 606};
731 607
608
732/* 609/*
733 * Release of a MC controlling instance 610 * Release of a MC controlling instance
611 *
612 * each MC control instance has the following resources upon entry:
613 * a) a ref count on the top memctl kobj
614 * b) a ref count on this module
615 *
616 * this function must decrement those ref counts and then
617 * issue a free on the instance's memory
734 */ 618 */
735static void edac_mci_instance_release(struct kobject *kobj) 619static void edac_mci_control_release(struct kobject *kobj)
736{ 620{
737 struct mem_ctl_info *mci; 621 struct mem_ctl_info *mci;
738 622
739 mci = to_mci(kobj); 623 mci = to_mci(kobj);
740 debugf0("%s() idx=%d\n", __func__, mci->mc_idx); 624
741 complete(&mci->kobj_complete); 625 debugf0("%s() mci instance idx=%d releasing\n", __func__, mci->mc_idx);
626
627 /* decrement the module ref count */
628 module_put(mci->owner);
629
630 /* free the mci instance memory here */
631 kfree(mci);
742} 632}
743 633
744static struct kobj_type ktype_mci = { 634static struct kobj_type ktype_mci = {
745 .release = edac_mci_instance_release, 635 .release = edac_mci_control_release,
746 .sysfs_ops = &mci_ops, 636 .sysfs_ops = &mci_ops,
747 .default_attrs = (struct attribute **)mci_attr, 637 .default_attrs = (struct attribute **)mci_attr,
748}; 638};
749 639
640/* show/store, tables, etc for the MC kset */
641
642
643struct memctrl_dev_attribute {
644 struct attribute attr;
645 void *value;
646 ssize_t(*show) (void *, char *);
647 ssize_t(*store) (void *, const char *, size_t);
648};
649
650/* Set of show/store abstract level functions for memory control object */
651static ssize_t memctrl_dev_show(struct kobject *kobj,
652 struct attribute *attr, char *buffer)
653{
654 struct memctrl_dev_attribute *memctrl_dev;
655 memctrl_dev = (struct memctrl_dev_attribute *)attr;
656
657 if (memctrl_dev->show)
658 return memctrl_dev->show(memctrl_dev->value, buffer);
659
660 return -EIO;
661}
662
663static ssize_t memctrl_dev_store(struct kobject *kobj, struct attribute *attr,
664 const char *buffer, size_t count)
665{
666 struct memctrl_dev_attribute *memctrl_dev;
667 memctrl_dev = (struct memctrl_dev_attribute *)attr;
668
669 if (memctrl_dev->store)
670 return memctrl_dev->store(memctrl_dev->value, buffer, count);
671
672 return -EIO;
673}
674
675static struct sysfs_ops memctrlfs_ops = {
676 .show = memctrl_dev_show,
677 .store = memctrl_dev_store
678};
679
680#define MEMCTRL_ATTR(_name, _mode, _show, _store) \
681static struct memctrl_dev_attribute attr_##_name = { \
682 .attr = {.name = __stringify(_name), .mode = _mode }, \
683 .value = &_name, \
684 .show = _show, \
685 .store = _store, \
686};
687
688#define MEMCTRL_STRING_ATTR(_name, _data, _mode, _show, _store) \
689static struct memctrl_dev_attribute attr_##_name = { \
690 .attr = {.name = __stringify(_name), .mode = _mode }, \
691 .value = _data, \
692 .show = _show, \
693 .store = _store, \
694};
695
696/* csrow<id> control files */
697MEMCTRL_ATTR(edac_mc_panic_on_ue,
698 S_IRUGO | S_IWUSR, memctrl_int_show, memctrl_int_store);
699
700MEMCTRL_ATTR(edac_mc_log_ue,
701 S_IRUGO | S_IWUSR, memctrl_int_show, memctrl_int_store);
702
703MEMCTRL_ATTR(edac_mc_log_ce,
704 S_IRUGO | S_IWUSR, memctrl_int_show, memctrl_int_store);
705
706MEMCTRL_ATTR(edac_mc_poll_msec,
707 S_IRUGO | S_IWUSR, memctrl_int_show, memctrl_int_store);
708
709/* Base Attributes of the memory ECC object */
710static struct memctrl_dev_attribute *memctrl_attr[] = {
711 &attr_edac_mc_panic_on_ue,
712 &attr_edac_mc_log_ue,
713 &attr_edac_mc_log_ce,
714 &attr_edac_mc_poll_msec,
715 NULL,
716};
717
718
719/* the ktype for the mc_kset internal kobj */
720static struct kobj_type ktype_mc_set_attribs = {
721 .sysfs_ops = &memctrlfs_ops,
722 .default_attrs = (struct attribute **)memctrl_attr,
723};
724
725/* EDAC memory controller sysfs kset:
726 * /sys/devices/system/edac/mc
727 */
728static struct kset mc_kset = {
729 .kobj = {.name = "mc", .ktype = &ktype_mc_set_attribs },
730 .ktype = &ktype_mci,
731};
732
733
734/*
735 * edac_mc_register_sysfs_main_kobj
736 *
737 * setups and registers the main kobject for each mci
738 */
739int edac_mc_register_sysfs_main_kobj(struct mem_ctl_info *mci)
740{
741 struct kobject *kobj_mci;
742 int err;
743
744 debugf1("%s()\n", __func__);
745
746 kobj_mci = &mci->edac_mci_kobj;
747
748 /* Init the mci's kobject */
749 memset(kobj_mci, 0, sizeof(*kobj_mci));
750
751 /* this instance become part of the mc_kset */
752 kobj_mci->kset = &mc_kset;
753
754 /* set the name of the mc<id> object */
755 err = kobject_set_name(kobj_mci, "mc%d", mci->mc_idx);
756 if (err)
757 goto fail_out;
758
759 /* Record which module 'owns' this control structure
760 * and bump the ref count of the module
761 */
762 mci->owner = THIS_MODULE;
763
764 /* bump ref count on this module */
765 if (!try_module_get(mci->owner)) {
766 err = -ENODEV;
767 goto fail_out;
768 }
769
770 /* register the mc<id> kobject to the mc_kset */
771 err = kobject_register(kobj_mci);
772 if (err) {
773 debugf1("%s()Failed to register '.../edac/mc%d'\n",
774 __func__, mci->mc_idx);
775 goto kobj_reg_fail;
776 }
777
778 /* At this point, to 'free' the control struct,
779 * edac_mc_unregister_sysfs_main_kobj() must be used
780 */
781
782 debugf1("%s() Registered '.../edac/mc%d' kobject\n",
783 __func__, mci->mc_idx);
784
785 return 0;
786
787 /* Error exit stack */
788
789kobj_reg_fail:
790 module_put(mci->owner);
791
792fail_out:
793 return err;
794}
795
796/*
797 * edac_mc_register_sysfs_main_kobj
798 *
799 * tears down and the main mci kobject from the mc_kset
800 */
801void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
802{
803 /* delete the kobj from the mc_kset */
804 kobject_unregister(&mci->edac_mci_kobj);
805}
806
750#define EDAC_DEVICE_SYMLINK "device" 807#define EDAC_DEVICE_SYMLINK "device"
751 808
752/* 809/*
753 * edac_create_driver_attributes 810 * edac_create_mci_instance_attributes
754 * create MC driver specific attributes at the topmost level 811 * create MC driver specific attributes at the topmost level
755 * directory of this mci instance. 812 * directory of this mci instance.
756 */ 813 */
757static int edac_create_driver_attributes(struct mem_ctl_info *mci) 814static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci)
758{ 815{
759 int err; 816 int err;
760 struct mcidev_sysfs_attribute *sysfs_attrib; 817 struct mcidev_sysfs_attribute *sysfs_attrib;
@@ -764,7 +821,7 @@ static int edac_create_driver_attributes(struct mem_ctl_info *mci)
764 */ 821 */
765 sysfs_attrib = mci->mc_driver_sysfs_attributes; 822 sysfs_attrib = mci->mc_driver_sysfs_attributes;
766 823
767 while (sysfs_attrib->attr.name != NULL) { 824 while (sysfs_attrib && sysfs_attrib->attr.name) {
768 err = sysfs_create_file(&mci->edac_mci_kobj, 825 err = sysfs_create_file(&mci->edac_mci_kobj,
769 (struct attribute*) sysfs_attrib); 826 (struct attribute*) sysfs_attrib);
770 if (err) { 827 if (err) {
@@ -778,6 +835,29 @@ static int edac_create_driver_attributes(struct mem_ctl_info *mci)
778} 835}
779 836
780/* 837/*
838 * edac_remove_mci_instance_attributes
839 * remove MC driver specific attributes at the topmost level
840 * directory of this mci instance.
841 */
842static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci)
843{
844 struct mcidev_sysfs_attribute *sysfs_attrib;
845
846 /* point to the start of the array and iterate over it
847 * adding each attribute listed to this mci instance's kobject
848 */
849 sysfs_attrib = mci->mc_driver_sysfs_attributes;
850
851 /* loop if there are attributes and until we hit a NULL entry */
852 while (sysfs_attrib && sysfs_attrib->attr.name) {
853 sysfs_remove_file(&mci->edac_mci_kobj,
854 (struct attribute *) sysfs_attrib);
855 sysfs_attrib++;
856 }
857}
858
859
860/*
781 * Create a new Memory Controller kobject instance, 861 * Create a new Memory Controller kobject instance,
782 * mc<id> under the 'mc' directory 862 * mc<id> under the 'mc' directory
783 * 863 *
@@ -790,51 +870,43 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
790 int i; 870 int i;
791 int err; 871 int err;
792 struct csrow_info *csrow; 872 struct csrow_info *csrow;
793 struct kobject *edac_mci_kobj = &mci->edac_mci_kobj; 873 struct kobject *kobj_mci = &mci->edac_mci_kobj;
794 874
795 debugf0("%s() idx=%d\n", __func__, mci->mc_idx); 875 debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
796 memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj));
797
798 /* set the name of the mc<id> object */
799 err = kobject_set_name(edac_mci_kobj, "mc%d", mci->mc_idx);
800 if (err)
801 return err;
802
803 /* link to our parent the '..../edac/mc' object */
804 edac_mci_kobj->parent = &edac_memctrl_kobj;
805 edac_mci_kobj->ktype = &ktype_mci;
806
807 /* register the mc<id> kobject */
808 err = kobject_register(edac_mci_kobj);
809 if (err)
810 return err;
811 876
812 /* create a symlink for the device */ 877 /* create a symlink for the device */
813 err = sysfs_create_link(edac_mci_kobj, &mci->dev->kobj, 878 err = sysfs_create_link(kobj_mci, &mci->dev->kobj,
814 EDAC_DEVICE_SYMLINK); 879 EDAC_DEVICE_SYMLINK);
815 if (err) 880 if (err) {
881 debugf1("%s() failure to create symlink\n", __func__);
816 goto fail0; 882 goto fail0;
883 }
817 884
818 /* If the low level driver desires some attributes, 885 /* If the low level driver desires some attributes,
819 * then create them now for the driver. 886 * then create them now for the driver.
820 */ 887 */
821 if (mci->mc_driver_sysfs_attributes) { 888 if (mci->mc_driver_sysfs_attributes) {
822 err = edac_create_driver_attributes(mci); 889 err = edac_create_mci_instance_attributes(mci);
823 if (err) 890 if (err) {
891 debugf1("%s() failure to create mci attributes\n",
892 __func__);
824 goto fail0; 893 goto fail0;
894 }
825 } 895 }
826 896
827 /* Make directories for each CSROW object 897 /* Make directories for each CSROW object under the mc<id> kobject
828 * under the mc<id> kobject
829 */ 898 */
830 for (i = 0; i < mci->nr_csrows; i++) { 899 for (i = 0; i < mci->nr_csrows; i++) {
831 csrow = &mci->csrows[i]; 900 csrow = &mci->csrows[i];
832 901
833 /* Only expose populated CSROWs */ 902 /* Only expose populated CSROWs */
834 if (csrow->nr_pages > 0) { 903 if (csrow->nr_pages > 0) {
835 err = edac_create_csrow_object(edac_mci_kobj, csrow, i); 904 err = edac_create_csrow_object(mci, csrow, i);
836 if (err) 905 if (err) {
906 debugf1("%s() failure: create csrow %d obj\n",
907 __func__, i);
837 goto fail1; 908 goto fail1;
909 }
838 } 910 }
839 } 911 }
840 912
@@ -844,16 +916,17 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
844fail1: 916fail1:
845 for (i--; i >= 0; i--) { 917 for (i--; i >= 0; i--) {
846 if (csrow->nr_pages > 0) { 918 if (csrow->nr_pages > 0) {
847 init_completion(&csrow->kobj_complete);
848 kobject_unregister(&mci->csrows[i].kobj); 919 kobject_unregister(&mci->csrows[i].kobj);
849 wait_for_completion(&csrow->kobj_complete);
850 } 920 }
851 } 921 }
852 922
923 /* remove the mci instance's attributes, if any */
924 edac_remove_mci_instance_attributes(mci);
925
926 /* remove the symlink */
927 sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK);
928
853fail0: 929fail0:
854 init_completion(&mci->kobj_complete);
855 kobject_unregister(edac_mci_kobj);
856 wait_for_completion(&mci->kobj_complete);
857 return err; 930 return err;
858} 931}
859 932
@@ -869,14 +942,83 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
869 /* remove all csrow kobjects */ 942 /* remove all csrow kobjects */
870 for (i = 0; i < mci->nr_csrows; i++) { 943 for (i = 0; i < mci->nr_csrows; i++) {
871 if (mci->csrows[i].nr_pages > 0) { 944 if (mci->csrows[i].nr_pages > 0) {
872 init_completion(&mci->csrows[i].kobj_complete); 945 debugf0("%s() unreg csrow-%d\n", __func__, i);
873 kobject_unregister(&mci->csrows[i].kobj); 946 kobject_unregister(&mci->csrows[i].kobj);
874 wait_for_completion(&mci->csrows[i].kobj_complete);
875 } 947 }
876 } 948 }
877 949
950 debugf0("%s() remove_link\n", __func__);
951
952 /* remove the symlink */
878 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); 953 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK);
879 init_completion(&mci->kobj_complete); 954
955 debugf0("%s() remove_mci_instance\n", __func__);
956
957 /* remove this mci instance's attribtes */
958 edac_remove_mci_instance_attributes(mci);
959
960 debugf0("%s() unregister this mci kobj\n", __func__);
961
962 /* unregister this instance's kobject */
880 kobject_unregister(&mci->edac_mci_kobj); 963 kobject_unregister(&mci->edac_mci_kobj);
881 wait_for_completion(&mci->kobj_complete);
882} 964}
965
966
967
968
969/*
970 * edac_setup_sysfs_mc_kset(void)
971 *
972 * Initialize the mc_kset for the 'mc' entry
973 * This requires creating the top 'mc' directory with a kset
974 * and its controls/attributes.
975 *
976 * To this 'mc' kset, instance 'mci' will be grouped as children.
977 *
978 * Return: 0 SUCCESS
979 * !0 FAILURE error code
980 */
981int edac_sysfs_setup_mc_kset(void)
982{
983 int err = 0;
984 struct sysdev_class *edac_class;
985
986 debugf1("%s()\n", __func__);
987
988 /* get the /sys/devices/system/edac class reference */
989 edac_class = edac_get_edac_class();
990 if (edac_class == NULL) {
991 debugf1("%s() no edac_class error=%d\n", __func__, err);
992 goto fail_out;
993 }
994
995 /* Init the MC's kobject */
996 mc_kset.kobj.parent = &edac_class->kset.kobj;
997
998 /* register the mc_kset */
999 err = kset_register(&mc_kset);
1000 if (err) {
1001 debugf1("%s() Failed to register '.../edac/mc'\n", __func__);
1002 goto fail_out;
1003 }
1004
1005 debugf1("%s() Registered '.../edac/mc' kobject\n", __func__);
1006
1007 return 0;
1008
1009
1010 /* error unwind stack */
1011fail_out:
1012 return err;
1013}
1014
1015/*
1016 * edac_sysfs_teardown_mc_kset
1017 *
1018 * deconstruct the mc_ket for memory controllers
1019 */
1020void edac_sysfs_teardown_mc_kset(void)
1021{
1022 kset_unregister(&mc_kset);
1023}
1024