aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/sys.c')
-rw-r--r--drivers/base/sys.c64
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
131int sysdev_class_register(struct sysdev_class * cls) 131int 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
475EXPORT_SYMBOL_GPL(sysdev_register); 480EXPORT_SYMBOL_GPL(sysdev_register);
476EXPORT_SYMBOL_GPL(sysdev_unregister); 481EXPORT_SYMBOL_GPL(sysdev_unregister);
482
483#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
484
485ssize_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}
497EXPORT_SYMBOL_GPL(sysdev_store_ulong);
498
499ssize_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}
506EXPORT_SYMBOL_GPL(sysdev_show_ulong);
507
508ssize_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}
520EXPORT_SYMBOL_GPL(sysdev_store_int);
521
522ssize_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}
529EXPORT_SYMBOL_GPL(sysdev_show_int);
530