edac_device_sysfs.c 23.6 KB
Newer Older
1 2 3
/*
 * file for managing the edac_device class of devices for EDAC
 *
4 5
 * (C) 2007 SoftwareBitMaker (http://www.softwarebitmaker.com)
 *
6 7 8 9 10 11 12 13
 * This file may be distributed under the terms of the
 * GNU General Public License.
 *
 * Written Doug Thompson <norsk5@xmission.com>
 *
 */

#include <linux/ctype.h>
14
#include <linux/module.h>
15
#include <linux/slab.h>
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

#include "edac_core.h"
#include "edac_module.h"

#define EDAC_DEVICE_SYMLINK	"device"

#define to_edacdev(k) container_of(k, struct edac_device_ctl_info, kobj)
#define to_edacdev_attr(a) container_of(a, struct edacdev_attribute, attr)


/*
 * Set of edac_device_ctl_info attribute store/show functions
 */

/* 'log_ue' */
31
static ssize_t edac_device_ctl_log_ue_show(struct edac_device_ctl_info
32
					*ctl_info, char *data)
33
{
34
	return sprintf(data, "%u\n", ctl_info->log_ue);
35 36
}

37
static ssize_t edac_device_ctl_log_ue_store(struct edac_device_ctl_info
38 39
					*ctl_info, const char *data,
					size_t count)
40 41
{
	/* if parameter is zero, turn off flag, if non-zero turn on flag */
42
	ctl_info->log_ue = (simple_strtoul(data, NULL, 0) != 0);
43

44
	return count;
45 46 47
}

/* 'log_ce' */
48
static ssize_t edac_device_ctl_log_ce_show(struct edac_device_ctl_info
49
					*ctl_info, char *data)
50
{
51
	return sprintf(data, "%u\n", ctl_info->log_ce);
52 53
}

54
static ssize_t edac_device_ctl_log_ce_store(struct edac_device_ctl_info
55 56
					*ctl_info, const char *data,
					size_t count)
57 58
{
	/* if parameter is zero, turn off flag, if non-zero turn on flag */
59
	ctl_info->log_ce = (simple_strtoul(data, NULL, 0) != 0);
60

61
	return count;
62 63 64
}

/* 'panic_on_ue' */
65 66
static ssize_t edac_device_ctl_panic_on_ue_show(struct edac_device_ctl_info
						*ctl_info, char *data)
67
{
68
	return sprintf(data, "%u\n", ctl_info->panic_on_ue);
69 70
}

71 72 73
static ssize_t edac_device_ctl_panic_on_ue_store(struct edac_device_ctl_info
						 *ctl_info, const char *data,
						 size_t count)
74 75
{
	/* if parameter is zero, turn off flag, if non-zero turn on flag */
76
	ctl_info->panic_on_ue = (simple_strtoul(data, NULL, 0) != 0);
77 78 79 80 81

	return count;
}

/* 'poll_msec' show and store functions*/
82
static ssize_t edac_device_ctl_poll_msec_show(struct edac_device_ctl_info
83
					*ctl_info, char *data)
84
{
85
	return sprintf(data, "%u\n", ctl_info->poll_msec);
86 87
}

88
static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info
89 90
					*ctl_info, const char *data,
					size_t count)
91 92 93 94 95 96 97 98
{
	unsigned long value;

	/* get the value and enforce that it is non-zero, must be at least
	 * one millisecond for the delay period, between scans
	 * Then cancel last outstanding delay for the work request
	 * and set a new one.
	 */
99 100
	value = simple_strtoul(data, NULL, 0);
	edac_device_reset_delay_period(ctl_info, value);
101

102
	return count;
103 104 105 106
}

/* edac_device_ctl_info specific attribute structure */
struct ctl_info_attribute {
107
	struct attribute attr;
108 109
	ssize_t(*show) (struct edac_device_ctl_info *, char *);
	ssize_t(*store) (struct edac_device_ctl_info *, const char *, size_t);
110 111 112 113 114 115 116
};

#define to_ctl_info(k) container_of(k, struct edac_device_ctl_info, kobj)
#define to_ctl_info_attr(a) container_of(a,struct ctl_info_attribute,attr)

/* Function to 'show' fields from the edac_dev 'ctl_info' structure */
static ssize_t edac_dev_ctl_info_show(struct kobject *kobj,
117
				struct attribute *attr, char *buffer)
118
{
119 120
	struct edac_device_ctl_info *edac_dev = to_ctl_info(kobj);
	struct ctl_info_attribute *ctl_info_attr = to_ctl_info_attr(attr);
121

122 123 124
	if (ctl_info_attr->show)
		return ctl_info_attr->show(edac_dev, buffer);
	return -EIO;
125 126 127 128
}

/* Function to 'store' fields into the edac_dev 'ctl_info' structure */
static ssize_t edac_dev_ctl_info_store(struct kobject *kobj,
129 130
				struct attribute *attr,
				const char *buffer, size_t count)
131
{
132 133
	struct edac_device_ctl_info *edac_dev = to_ctl_info(kobj);
	struct ctl_info_attribute *ctl_info_attr = to_ctl_info_attr(attr);
134

135 136 137
	if (ctl_info_attr->store)
		return ctl_info_attr->store(edac_dev, buffer, count);
	return -EIO;
138 139 140
}

/* edac_dev file operations for an 'ctl_info' */
141
static const struct sysfs_ops device_ctl_info_ops = {
142 143
	.show = edac_dev_ctl_info_show,
	.store = edac_dev_ctl_info_store
144 145 146 147
};

#define CTL_INFO_ATTR(_name,_mode,_show,_store)        \
static struct ctl_info_attribute attr_ctl_info_##_name = {      \
148 149 150
	.attr = {.name = __stringify(_name), .mode = _mode },   \
	.show   = _show,                                        \
	.store  = _store,                                       \
151 152 153
};

/* Declare the various ctl_info attributes here and their respective ops */
154
CTL_INFO_ATTR(log_ue, S_IRUGO | S_IWUSR,
155
	edac_device_ctl_log_ue_show, edac_device_ctl_log_ue_store);
156
CTL_INFO_ATTR(log_ce, S_IRUGO | S_IWUSR,
157
	edac_device_ctl_log_ce_show, edac_device_ctl_log_ce_store);
158
CTL_INFO_ATTR(panic_on_ue, S_IRUGO | S_IWUSR,
159 160
	edac_device_ctl_panic_on_ue_show,
	edac_device_ctl_panic_on_ue_store);
161
CTL_INFO_ATTR(poll_msec, S_IRUGO | S_IWUSR,
162
	edac_device_ctl_poll_msec_show, edac_device_ctl_poll_msec_store);
163 164 165 166 167 168 169 170 171 172

/* Base Attributes of the EDAC_DEVICE ECC object */
static struct ctl_info_attribute *device_ctrl_attr[] = {
	&attr_ctl_info_panic_on_ue,
	&attr_ctl_info_log_ue,
	&attr_ctl_info_log_ce,
	&attr_ctl_info_poll_msec,
	NULL,
};

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
/*
 * edac_device_ctrl_master_release
 *
 *	called when the reference count for the 'main' kobj
 *	for a edac_device control struct reaches zero
 *
 *	Reference count model:
 *		One 'main' kobject for each control structure allocated.
 *		That main kobj is initially set to one AND
 *		the reference count for the EDAC 'core' module is
 *		bumped by one, thus added 'keep in memory' dependency.
 *
 *		Each new internal kobj (in instances and blocks) then
 *		bumps the 'main' kobject.
 *
 *		When they are released their release functions decrement
 *		the 'main' kobj.
 *
 *		When the main kobj reaches zero (0) then THIS function
 *		is called which then decrements the EDAC 'core' module.
 *		When the module reference count reaches zero then the
 *		module no longer has dependency on keeping the release
 *		function code in memory and module can be unloaded.
 *
 *		This will support several control objects as well, each
 *		with its own 'main' kobj.
 */
200 201
static void edac_device_ctrl_master_release(struct kobject *kobj)
{
202
	struct edac_device_ctl_info *edac_dev = to_edacdev(kobj);
203

204
	debugf4("%s() control index=%d\n", __func__, edac_dev->dev_idx);
205

206 207 208 209 210 211 212
	/* decrement the EDAC CORE module ref count */
	module_put(edac_dev->owner);

	/* free the control struct containing the 'main' kobj
	 * passed in to this routine
	 */
	kfree(edac_dev);
213 214
}

215
/* ktype for the main (master) kobject */
216 217 218
static struct kobj_type ktype_device_ctrl = {
	.release = edac_device_ctrl_master_release,
	.sysfs_ops = &device_ctl_info_ops,
219
	.default_attrs = (struct attribute **)device_ctrl_attr,
220 221 222
};

/*
223
 * edac_device_register_sysfs_main_kobj
224 225 226 227 228 229
 *
 *	perform the high level setup for the new edac_device instance
 *
 * Return:  0 SUCCESS
 *         !0 FAILURE
 */
230
int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
231 232
{
	struct sysdev_class *edac_class;
233
	int err;
234 235 236

	debugf1("%s()\n", __func__);

237 238 239
	/* get the /sys/devices/system/edac reference */
	edac_class = edac_get_edac_class();
	if (edac_class == NULL) {
240 241 242
		debugf1("%s() no edac_class error\n", __func__);
		err = -ENODEV;
		goto err_out;
243
	}
244 245 246 247 248

	/* Point to the 'edac_class' this instance 'reports' to */
	edac_dev->edac_class = edac_class;

	/* Init the devices's kobject */
249
	memset(&edac_dev->kobj, 0, sizeof(struct kobject));
250 251 252 253 254 255 256 257 258 259 260 261

	/* Record which module 'owns' this control structure
	 * and bump the ref count of the module
	 */
	edac_dev->owner = THIS_MODULE;

	if (!try_module_get(edac_dev->owner)) {
		err = -ENODEV;
		goto err_out;
	}

	/* register */
262 263 264
	err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl,
				   &edac_class->kset.kobj,
				   "%s", edac_dev->name);
265 266
	if (err) {
		debugf1("%s()Failed to register '.../edac/%s'\n",
267
			__func__, edac_dev->name);
268
		goto err_kobj_reg;
269
	}
270
	kobject_uevent(&edac_dev->kobj, KOBJ_ADD);
271

272 273 274 275
	/* At this point, to 'free' the control struct,
	 * edac_device_unregister_sysfs_main_kobj() must be used
	 */

276
	debugf4("%s() Registered '.../edac/%s' kobject\n",
277 278 279
		__func__, edac_dev->name);

	return 0;
280 281 282 283 284 285 286

	/* Error exit stack */
err_kobj_reg:
	module_put(edac_dev->owner);

err_out:
	return err;
287 288 289
}

/*
290
 * edac_device_unregister_sysfs_main_kobj:
291 292
 *	the '..../edac/<name>' kobject
 */
293 294
void edac_device_unregister_sysfs_main_kobj(
					struct edac_device_ctl_info *edac_dev)
295 296
{
	debugf0("%s()\n", __func__);
297
	debugf4("%s() name of kobject is: %s\n",
298 299 300 301
		__func__, kobject_name(&edac_dev->kobj));

	/*
	 * Unregister the edac device's kobject and
302 303 304 305
	 * allow for reference count to reach 0 at which point
	 * the callback will be called to:
	 *   a) module_put() this module
	 *   b) 'kfree' the memory
306
	 */
307
	kobject_put(&edac_dev->kobj);
308 309
}

310
/* edac_dev -> instance information */
311 312 313 314

/*
 * Set of low-level instance attribute show functions
 */
315
static ssize_t instance_ue_count_show(struct edac_device_instance *instance,
316
				char *data)
317
{
318
	return sprintf(data, "%u\n", instance->counters.ue_count);
319 320
}

321
static ssize_t instance_ce_count_show(struct edac_device_instance *instance,
322
				char *data)
323
{
324
	return sprintf(data, "%u\n", instance->counters.ce_count);
325 326 327 328 329 330 331 332 333 334 335 336
}

#define to_instance(k) container_of(k, struct edac_device_instance, kobj)
#define to_instance_attr(a) container_of(a,struct instance_attribute,attr)

/* DEVICE instance kobject release() function */
static void edac_device_ctrl_instance_release(struct kobject *kobj)
{
	struct edac_device_instance *instance;

	debugf1("%s()\n", __func__);

337 338 339
	/* map from this kobj to the main control struct
	 * and then dec the main kobj count
	 */
340
	instance = to_instance(kobj);
341
	kobject_put(&instance->ctl->kobj);
342 343 344 345
}

/* instance specific attribute structure */
struct instance_attribute {
346
	struct attribute attr;
347 348
	ssize_t(*show) (struct edac_device_instance *, char *);
	ssize_t(*store) (struct edac_device_instance *, const char *, size_t);
349 350 351 352
};

/* Function to 'show' fields from the edac_dev 'instance' structure */
static ssize_t edac_dev_instance_show(struct kobject *kobj,
353
				struct attribute *attr, char *buffer)
354
{
355 356
	struct edac_device_instance *instance = to_instance(kobj);
	struct instance_attribute *instance_attr = to_instance_attr(attr);
357

358 359 360
	if (instance_attr->show)
		return instance_attr->show(instance, buffer);
	return -EIO;
361 362 363 364
}

/* Function to 'store' fields into the edac_dev 'instance' structure */
static ssize_t edac_dev_instance_store(struct kobject *kobj,
365 366
				struct attribute *attr,
				const char *buffer, size_t count)
367
{
368 369
	struct edac_device_instance *instance = to_instance(kobj);
	struct instance_attribute *instance_attr = to_instance_attr(attr);
370

371 372 373
	if (instance_attr->store)
		return instance_attr->store(instance, buffer, count);
	return -EIO;
374 375 376
}

/* edac_dev file operations for an 'instance' */
377
static const struct sysfs_ops device_instance_ops = {
378 379
	.show = edac_dev_instance_show,
	.store = edac_dev_instance_store
380 381 382 383
};

#define INSTANCE_ATTR(_name,_mode,_show,_store)        \
static struct instance_attribute attr_instance_##_name = {      \
384 385 386
	.attr = {.name = __stringify(_name), .mode = _mode },   \
	.show   = _show,                                        \
	.store  = _store,                                       \
387 388 389 390 391 392 393
};

/*
 * Define attributes visible for the edac_device instance object
 *	Each contains a pointer to a show and an optional set
 *	function pointer that does the low level output/input
 */
394 395
INSTANCE_ATTR(ce_count, S_IRUGO, instance_ce_count_show, NULL);
INSTANCE_ATTR(ue_count, S_IRUGO, instance_ue_count_show, NULL);
396 397 398 399 400 401 402 403 404 405 406 407

/* list of edac_dev 'instance' attributes */
static struct instance_attribute *device_instance_attr[] = {
	&attr_instance_ce_count,
	&attr_instance_ue_count,
	NULL,
};

/* The 'ktype' for each edac_dev 'instance' */
static struct kobj_type ktype_instance_ctrl = {
	.release = edac_device_ctrl_instance_release,
	.sysfs_ops = &device_instance_ops,
408
	.default_attrs = (struct attribute **)device_instance_attr,
409 410
};

411
/* edac_dev -> instance -> block information */
412

413 414 415 416
#define to_block(k) container_of(k, struct edac_device_block, kobj)
#define to_block_attr(a) \
	container_of(a, struct edac_dev_sysfs_block_attribute, attr)

417 418 419
/*
 * Set of low-level block attribute show functions
 */
420 421
static ssize_t block_ue_count_show(struct kobject *kobj,
					struct attribute *attr, char *data)
422
{
423 424
	struct edac_device_block *block = to_block(kobj);

425
	return sprintf(data, "%u\n", block->counters.ue_count);
426 427
}

428 429
static ssize_t block_ce_count_show(struct kobject *kobj,
					struct attribute *attr, char *data)
430
{
431 432
	struct edac_device_block *block = to_block(kobj);

433
	return sprintf(data, "%u\n", block->counters.ce_count);
434 435 436 437 438 439 440 441 442
}

/* DEVICE block kobject release() function */
static void edac_device_ctrl_block_release(struct kobject *kobj)
{
	struct edac_device_block *block;

	debugf1("%s()\n", __func__);

443
	/* get the container of the kobj */
444
	block = to_block(kobj);
445 446 447 448 449

	/* map from 'block kobj' to 'block->instance->controller->main_kobj'
	 * now 'release' the block kobject
	 */
	kobject_put(&block->instance->ctl->kobj);
450 451 452 453 454
}


/* Function to 'show' fields from the edac_dev 'block' structure */
static ssize_t edac_dev_block_show(struct kobject *kobj,
455
				struct attribute *attr, char *buffer)
456
{
457 458
	struct edac_dev_sysfs_block_attribute *block_attr =
						to_block_attr(attr);
459

460
	if (block_attr->show)
461
		return block_attr->show(kobj, attr, buffer);
462
	return -EIO;
463 464 465 466
}

/* Function to 'store' fields into the edac_dev 'block' structure */
static ssize_t edac_dev_block_store(struct kobject *kobj,
467 468
				struct attribute *attr,
				const char *buffer, size_t count)
469
{
470 471 472
	struct edac_dev_sysfs_block_attribute *block_attr;

	block_attr = to_block_attr(attr);
473

474
	if (block_attr->store)
475
		return block_attr->store(kobj, attr, buffer, count);
476
	return -EIO;
477 478 479
}

/* edac_dev file operations for a 'block' */
480
static const struct sysfs_ops device_block_ops = {
481 482
	.show = edac_dev_block_show,
	.store = edac_dev_block_store
483 484 485
};

#define BLOCK_ATTR(_name,_mode,_show,_store)        \
486
static struct edac_dev_sysfs_block_attribute attr_block_##_name = {	\
487 488 489
	.attr = {.name = __stringify(_name), .mode = _mode },   \
	.show   = _show,                                        \
	.store  = _store,                                       \
490 491
};

492 493
BLOCK_ATTR(ce_count, S_IRUGO, block_ce_count_show, NULL);
BLOCK_ATTR(ue_count, S_IRUGO, block_ue_count_show, NULL);
494 495

/* list of edac_dev 'block' attributes */
496
static struct edac_dev_sysfs_block_attribute *device_block_attr[] = {
497 498 499 500 501 502 503 504 505
	&attr_block_ce_count,
	&attr_block_ue_count,
	NULL,
};

/* The 'ktype' for each edac_dev 'block' */
static struct kobj_type ktype_block_ctrl = {
	.release = edac_device_ctrl_block_release,
	.sysfs_ops = &device_block_ops,
506
	.default_attrs = (struct attribute **)device_block_attr,
507 508
};

509
/* block ctor/dtor  code */
510 511 512 513

/*
 * edac_device_create_block
 */
514
static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
515
				struct edac_device_instance *instance,
516
				struct edac_device_block *block)
517
{
518
	int i;
519
	int err;
520
	struct edac_dev_sysfs_block_attribute *sysfs_attrib;
521
	struct kobject *main_kobj;
522

523 524 525 526
	debugf4("%s() Instance '%s' inst_p=%p  block '%s'  block_p=%p\n",
		__func__, instance->name, instance, block->name, block);
	debugf4("%s() block kobj=%p  block kobj->parent=%p\n",
		__func__, &block->kobj, &block->kobj.parent);
527 528

	/* init this block's kobject */
529
	memset(&block->kobj, 0, sizeof(struct kobject));
530

531 532 533 534 535 536 537 538 539 540
	/* bump the main kobject's reference count for this controller
	 * and this instance is dependant on the main
	 */
	main_kobj = kobject_get(&edac_dev->kobj);
	if (!main_kobj) {
		err = -ENODEV;
		goto err_out;
	}

	/* Add this block's kobject */
541 542 543
	err = kobject_init_and_add(&block->kobj, &ktype_block_ctrl,
				   &instance->kobj,
				   "%s", block->name);
544
	if (err) {
545
		debugf1("%s() Failed to register instance '%s'\n",
546
			__func__, block->name);
547 548 549
		kobject_put(main_kobj);
		err = -ENODEV;
		goto err_out;
550 551
	}

552 553 554 555
	/* If there are driver level block attributes, then added them
	 * to the block kobject
	 */
	sysfs_attrib = block->block_attributes;
556 557 558 559 560 561 562 563 564 565
	if (sysfs_attrib && block->nr_attribs) {
		for (i = 0; i < block->nr_attribs; i++, sysfs_attrib++) {

			debugf4("%s() creating block attrib='%s' "
				"attrib->%p to kobj=%p\n",
				__func__,
				sysfs_attrib->attr.name,
				sysfs_attrib, &block->kobj);

			/* Create each block_attribute file */
566
			err = sysfs_create_file(&block->kobj,
567
				&sysfs_attrib->attr);
568 569 570 571
			if (err)
				goto err_on_attrib;
		}
	}
572
	kobject_uevent(&block->kobj, KOBJ_ADD);
573

574
	return 0;
575

576
	/* Error unwind stack */
577
err_on_attrib:
578
	kobject_put(&block->kobj);
579

580
err_out:
581
	return err;
582 583 584
}

/*
585
 * edac_device_delete_block(edac_dev,block);
586
 */
587
static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev,
588
				struct edac_device_block *block)
589
{
590 591
	struct edac_dev_sysfs_block_attribute *sysfs_attrib;
	int i;
592

593 594 595 596 597
	/* if this block has 'attributes' then we need to iterate over the list
	 * and 'remove' the attributes on this block
	 */
	sysfs_attrib = block->block_attributes;
	if (sysfs_attrib && block->nr_attribs) {
598 599 600
		for (i = 0; i < block->nr_attribs; i++, sysfs_attrib++) {

			/* remove each block_attrib file */
601 602 603 604
			sysfs_remove_file(&block->kobj,
				(struct attribute *) sysfs_attrib);
		}
	}
605

606 607 608
	/* unregister this block's kobject, SEE:
	 *	edac_device_ctrl_block_release() callback operation
	 */
609
	kobject_put(&block->kobj);
610 611
}

612
/* instance ctor/dtor code */
613 614 615 616 617

/*
 * edac_device_create_instance
 *	create just one instance of an edac_device 'instance'
 */
618
static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
619
				int idx)
620 621 622 623
{
	int i, j;
	int err;
	struct edac_device_instance *instance;
624
	struct kobject *main_kobj;
625 626 627 628

	instance = &edac_dev->instances[idx];

	/* Init the instance's kobject */
629
	memset(&instance->kobj, 0, sizeof(struct kobject));
630

631
	instance->ctl = edac_dev;
632

633 634 635 636 637 638 639 640
	/* bump the main kobject's reference count for this controller
	 * and this instance is dependant on the main
	 */
	main_kobj = kobject_get(&edac_dev->kobj);
	if (!main_kobj) {
		err = -ENODEV;
		goto err_out;
	}
641

642 643 644
	/* Formally register this instance's kobject under the edac_device */
	err = kobject_init_and_add(&instance->kobj, &ktype_instance_ctrl,
				   &edac_dev->kobj, "%s", instance->name);
645 646
	if (err != 0) {
		debugf2("%s() Failed to register instance '%s'\n",
647
			__func__, instance->name);
648 649
		kobject_put(main_kobj);
		goto err_out;
650 651
	}

652
	debugf4("%s() now register '%d' blocks for instance %d\n",
653
		__func__, instance->nr_blocks, idx);
654 655

	/* register all blocks of this instance */
656
	for (i = 0; i < instance->nr_blocks; i++) {
657 658
		err = edac_device_create_block(edac_dev, instance,
						&instance->blocks[i]);
659
		if (err) {
660
			/* If any fail, remove all previous ones */
661
			for (j = 0; j < i; j++)
662 663 664
				edac_device_delete_block(edac_dev,
							&instance->blocks[j]);
			goto err_release_instance_kobj;
665 666
		}
	}
667
	kobject_uevent(&instance->kobj, KOBJ_ADD);
668

669
	debugf4("%s() Registered instance %d '%s' kobject\n",
670 671 672
		__func__, idx, instance->name);

	return 0;
673 674 675

	/* error unwind stack */
err_release_instance_kobj:
676
	kobject_put(&instance->kobj);
677 678 679

err_out:
	return err;
680 681 682 683 684 685
}

/*
 * edac_device_remove_instance
 *	remove an edac_device instance
 */
686 687
static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev,
					int idx)
688 689
{
	struct edac_device_instance *instance;
690
	int i;
691 692 693 694

	instance = &edac_dev->instances[idx];

	/* unregister all blocks in this instance */
695
	for (i = 0; i < instance->nr_blocks; i++)
696
		edac_device_delete_block(edac_dev, &instance->blocks[i]);
697

698 699 700
	/* unregister this instance's kobject, SEE:
	 *	edac_device_ctrl_instance_release() for callback operation
	 */
701
	kobject_put(&instance->kobj);
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
}

/*
 * edac_device_create_instances
 *	create the first level of 'instances' for this device
 *	(ie  'cache' might have 'cache0', 'cache1', 'cache2', etc
 */
static int edac_device_create_instances(struct edac_device_ctl_info *edac_dev)
{
	int i, j;
	int err;

	debugf0("%s()\n", __func__);

	/* iterate over creation of the instances */
717 718
	for (i = 0; i < edac_dev->nr_instances; i++) {
		err = edac_device_create_instance(edac_dev, i);
719 720
		if (err) {
			/* unwind previous instances on error */
721
			for (j = 0; j < i; j++)
722
				edac_device_delete_instance(edac_dev, j);
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
			return err;
		}
	}

	return 0;
}

/*
 * edac_device_delete_instances(edac_dev);
 *	unregister all the kobjects of the instances
 */
static void edac_device_delete_instances(struct edac_device_ctl_info *edac_dev)
{
	int i;

	/* iterate over creation of the instances */
739
	for (i = 0; i < edac_dev->nr_instances; i++)
740
		edac_device_delete_instance(edac_dev, i);
741 742
}

743
/* edac_dev sysfs ctor/dtor  code */
744

745
/*
746
 * edac_device_add_main_sysfs_attributes
747 748
 *	add some attributes to this instance's main kobject
 */
749
static int edac_device_add_main_sysfs_attributes(
750 751
			struct edac_device_ctl_info *edac_dev)
{
752
	struct edac_dev_sysfs_attribute *sysfs_attrib;
753
	int err = 0;
754 755

	sysfs_attrib = edac_dev->sysfs_attributes;
756 757 758 759 760 761
	if (sysfs_attrib) {
		/* iterate over the array and create an attribute for each
		 * entry in the list
		 */
		while (sysfs_attrib->attr.name != NULL) {
			err = sysfs_create_file(&edac_dev->kobj,
762
				(struct attribute*) sysfs_attrib);
763 764
			if (err)
				goto err_out;
765

766 767
			sysfs_attrib++;
		}
768
	}
769

770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
err_out:
	return err;
}

/*
 * edac_device_remove_main_sysfs_attributes
 *	remove any attributes to this instance's main kobject
 */
static void edac_device_remove_main_sysfs_attributes(
			struct edac_device_ctl_info *edac_dev)
{
	struct edac_dev_sysfs_attribute *sysfs_attrib;

	/* if there are main attributes, defined, remove them. First,
	 * point to the start of the array and iterate over it
	 * removing each attribute listed from this device's instance's kobject
	 */
	sysfs_attrib = edac_dev->sysfs_attributes;
	if (sysfs_attrib) {
		while (sysfs_attrib->attr.name != NULL) {
			sysfs_remove_file(&edac_dev->kobj,
					(struct attribute *) sysfs_attrib);
			sysfs_attrib++;
		}
	}
795 796
}

797 798 799
/*
 * edac_device_create_sysfs() Constructor
 *
800 801 802 803 804 805
 * accept a created edac_device control structure
 * and 'export' it to sysfs. The 'main' kobj should already have been
 * created. 'instance' and 'block' kobjects should be registered
 * along with any 'block' attributes from the low driver. In addition,
 * the main attributes (if any) are connected to the main kobject of
 * the control structure.
806 807 808 809 810 811 812 813
 *
 * Return:
 *	0	Success
 *	!0	Failure
 */
int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)
{
	int err;
814
	struct kobject *edac_kobj = &edac_dev->kobj;
815 816 817

	debugf0("%s() idx=%d\n", __func__, edac_dev->dev_idx);

818 819 820 821 822
	/*  go create any main attributes callers wants */
	err = edac_device_add_main_sysfs_attributes(edac_dev);
	if (err) {
		debugf0("%s() failed to add sysfs attribs\n", __func__);
		goto err_out;
823 824
	}

825 826 827 828
	/* create a symlink from the edac device
	 * to the platform 'device' being used for this
	 */
	err = sysfs_create_link(edac_kobj,
829
				&edac_dev->dev->kobj, EDAC_DEVICE_SYMLINK);
830 831 832
	if (err) {
		debugf0("%s() sysfs_create_link() returned err= %d\n",
			__func__, err);
833
		goto err_remove_main_attribs;
834 835
	}

836 837 838 839
	/* Create the first level instance directories
	 * In turn, the nested blocks beneath the instances will
	 * be registered as well
	 */
840
	err = edac_device_create_instances(edac_dev);
841 842 843
	if (err) {
		debugf0("%s() edac_device_create_instances() "
			"returned err= %d\n", __func__, err);
844
		goto err_remove_link;
845 846 847
	}


848
	debugf4("%s() create-instances done, idx=%d\n",
849
		__func__, edac_dev->dev_idx);
850 851 852 853

	return 0;

	/* Error unwind stack */
854 855 856
err_remove_link:
	/* remove the sym link */
	sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);
857

858 859
err_remove_main_attribs:
	edac_device_remove_main_sysfs_attributes(edac_dev);
860

861
err_out:
862 863 864 865 866 867
	return err;
}

/*
 * edac_device_remove_sysfs() destructor
 *
868
 * given an edac_device struct, tear down the kobject resources
869 870 871 872 873
 */
void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev)
{
	debugf0("%s()\n", __func__);

874 875
	/* remove any main attributes for this device */
	edac_device_remove_main_sysfs_attributes(edac_dev);
876

877
	/* remove the device sym link */
878 879
	sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);

880 881
	/* walk the instance/block kobject tree, deconstructing it */
	edac_device_delete_instances(edac_dev);
882
}