diff options
Diffstat (limited to 'drivers/base/sys.c')
-rw-r--r-- | drivers/base/sys.c | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 358bb0be3c08..40fc14f03540 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -36,7 +36,7 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) | |||
36 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 36 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); |
37 | 37 | ||
38 | if (sysdev_attr->show) | 38 | if (sysdev_attr->show) |
39 | return sysdev_attr->show(sysdev, buffer); | 39 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); |
40 | return -EIO; | 40 | return -EIO; |
41 | } | 41 | } |
42 | 42 | ||
@@ -49,7 +49,7 @@ sysdev_store(struct kobject * kobj, struct attribute * attr, | |||
49 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 49 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); |
50 | 50 | ||
51 | if (sysdev_attr->store) | 51 | if (sysdev_attr->store) |
52 | return sysdev_attr->store(sysdev, buffer, count); | 52 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); |
53 | return -EIO; | 53 | return -EIO; |
54 | } | 54 | } |
55 | 55 | ||
@@ -130,8 +130,8 @@ static struct kset *system_kset; | |||
130 | 130 | ||
131 | int sysdev_class_register(struct sysdev_class * cls) | 131 | int sysdev_class_register(struct sysdev_class * cls) |
132 | { | 132 | { |
133 | pr_debug("Registering sysdev class '%s'\n", | 133 | pr_debug("Registering sysdev class '%s'\n", cls->name); |
134 | kobject_name(&cls->kset.kobj)); | 134 | |
135 | INIT_LIST_HEAD(&cls->drivers); | 135 | INIT_LIST_HEAD(&cls->drivers); |
136 | memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); | 136 | memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); |
137 | cls->kset.kobj.parent = &system_kset->kobj; | 137 | cls->kset.kobj.parent = &system_kset->kobj; |
@@ -241,7 +241,8 @@ int sysdev_register(struct sys_device * sysdev) | |||
241 | if (!cls) | 241 | if (!cls) |
242 | return -EINVAL; | 242 | return -EINVAL; |
243 | 243 | ||
244 | pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); | 244 | pr_debug("Registering sys device of class '%s'\n", |
245 | kobject_name(&cls->kset.kobj)); | ||
245 | 246 | ||
246 | /* initialize the kobject to 0, in case it had previously been used */ | 247 | /* initialize the kobject to 0, in case it had previously been used */ |
247 | memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); | 248 | memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); |
@@ -257,6 +258,9 @@ int sysdev_register(struct sys_device * sysdev) | |||
257 | if (!error) { | 258 | if (!error) { |
258 | struct sysdev_driver * drv; | 259 | struct sysdev_driver * drv; |
259 | 260 | ||
261 | pr_debug("Registering sys device '%s'\n", | ||
262 | kobject_name(&sysdev->kobj)); | ||
263 | |||
260 | mutex_lock(&sysdev_drivers_lock); | 264 | mutex_lock(&sysdev_drivers_lock); |
261 | /* Generic notification is implicit, because it's that | 265 | /* Generic notification is implicit, because it's that |
262 | * code that should have called us. | 266 | * code that should have called us. |
@@ -269,6 +273,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
269 | } | 273 | } |
270 | mutex_unlock(&sysdev_drivers_lock); | 274 | mutex_unlock(&sysdev_drivers_lock); |
271 | } | 275 | } |
276 | |||
272 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); | 277 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); |
273 | return error; | 278 | return error; |
274 | } | 279 | } |
@@ -474,3 +479,52 @@ int __init system_bus_init(void) | |||
474 | 479 | ||
475 | EXPORT_SYMBOL_GPL(sysdev_register); | 480 | EXPORT_SYMBOL_GPL(sysdev_register); |
476 | EXPORT_SYMBOL_GPL(sysdev_unregister); | 481 | EXPORT_SYMBOL_GPL(sysdev_unregister); |
482 | |||
483 | #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) | ||
484 | |||
485 | ssize_t sysdev_store_ulong(struct sys_device *sysdev, | ||
486 | struct sysdev_attribute *attr, | ||
487 | const char *buf, size_t size) | ||
488 | { | ||
489 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
490 | char *end; | ||
491 | unsigned long new = simple_strtoul(buf, &end, 0); | ||
492 | if (end == buf) | ||
493 | return -EINVAL; | ||
494 | *(unsigned long *)(ea->var) = new; | ||
495 | return end - buf; | ||
496 | } | ||
497 | EXPORT_SYMBOL_GPL(sysdev_store_ulong); | ||
498 | |||
499 | ssize_t sysdev_show_ulong(struct sys_device *sysdev, | ||
500 | struct sysdev_attribute *attr, | ||
501 | char *buf) | ||
502 | { | ||
503 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
504 | return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); | ||
505 | } | ||
506 | EXPORT_SYMBOL_GPL(sysdev_show_ulong); | ||
507 | |||
508 | ssize_t sysdev_store_int(struct sys_device *sysdev, | ||
509 | struct sysdev_attribute *attr, | ||
510 | const char *buf, size_t size) | ||
511 | { | ||
512 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
513 | char *end; | ||
514 | long new = simple_strtol(buf, &end, 0); | ||
515 | if (end == buf || new > INT_MAX || new < INT_MIN) | ||
516 | return -EINVAL; | ||
517 | *(int *)(ea->var) = new; | ||
518 | return end - buf; | ||
519 | } | ||
520 | EXPORT_SYMBOL_GPL(sysdev_store_int); | ||
521 | |||
522 | ssize_t sysdev_show_int(struct sys_device *sysdev, | ||
523 | struct sysdev_attribute *attr, | ||
524 | char *buf) | ||
525 | { | ||
526 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
527 | return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); | ||
528 | } | ||
529 | EXPORT_SYMBOL_GPL(sysdev_show_int); | ||
530 | |||