diff options
Diffstat (limited to 'drivers/base/class.c')
| -rw-r--r-- | drivers/base/class.c | 67 |
1 files changed, 29 insertions, 38 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index 05d9df90f621..2526c57d924e 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -183,6 +183,17 @@ int class_register(const struct class *cls) pr_debug("device class '%s': registering\n", cls->name); + if (cls->ns_type && !cls->namespace) { + pr_err("%s: class '%s' does not have namespace\n", + __func__, cls->name); + return -EINVAL; + } + if (!cls->ns_type && cls->namespace) { + pr_err("%s: class '%s' does not have ns_type\n", + __func__, cls->name); + return -EINVAL; + } + cp = kzalloc(sizeof(*cp), GFP_KERNEL); if (!cp) return -ENOMEM; @@ -193,10 +204,8 @@ int class_register(const struct class *cls) lockdep_register_key(key); __mutex_init(&cp->mutex, "subsys mutex", key); error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); - if (error) { - kfree(cp); - return error; - } + if (error) + goto err_out; cp->subsys.kobj.kset = class_kset; cp->subsys.kobj.ktype = &class_ktype; @@ -215,6 +224,7 @@ int class_register(const struct class *cls) return 0; err_out: + lockdep_unregister_key(key); kfree(cp); return error; } @@ -313,8 +323,12 @@ void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, struct subsys_private *sp = class_to_subsys(class); struct klist_node *start_knode = NULL; - if (!sp) + memset(iter, 0, sizeof(*iter)); + if (!sp) { + pr_crit("%s: class %p was not registered yet\n", + __func__, class); return; + } if (start) start_knode = &start->p->knode_class; @@ -341,6 +355,9 @@ struct device *class_dev_iter_next(struct class_dev_iter *iter) struct klist_node *knode; struct device *dev; + if (!iter->sp) + return NULL; + while (1) { knode = klist_next(&iter->ki); if (!knode) @@ -385,7 +402,7 @@ EXPORT_SYMBOL_GPL(class_dev_iter_exit); * code. There's no locking restriction. */ int class_for_each_device(const struct class *class, const struct device *start, - void *data, int (*fn)(struct device *, void *)) + void *data, device_iter_t fn) { struct subsys_private *sp = class_to_subsys(class); struct class_dev_iter iter; @@ -395,7 +412,7 @@ int class_for_each_device(const struct class *class, const struct device *start, if (!class) return -EINVAL; if (!sp) { - WARN(1, "%s called for class '%s' before it was initialized", + WARN(1, "%s called for class '%s' before it was registered", __func__, class->name); return -EINVAL; } @@ -434,8 +451,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device); * code. There's no locking restriction. */ struct device *class_find_device(const struct class *class, const struct device *start, - const void *data, - int (*match)(struct device *, const void *)) + const void *data, device_match_t match) { struct subsys_private *sp = class_to_subsys(class); struct class_dev_iter iter; @@ -444,7 +460,7 @@ struct device *class_find_device(const struct class *class, const struct device if (!class) return NULL; if (!sp) { - WARN(1, "%s called for class '%s' before it was initialized", + WARN(1, "%s called for class '%s' before it was registered", __func__, class->name); return NULL; } @@ -585,30 +601,10 @@ EXPORT_SYMBOL_GPL(class_compat_unregister); * a bus device * @cls: the compatibility class * @dev: the target bus device - * @device_link: an optional device to which a "device" link should be created */ -int class_compat_create_link(struct class_compat *cls, struct device *dev, - struct device *device_link) +int class_compat_create_link(struct class_compat *cls, struct device *dev) { - int error; - - error = sysfs_create_link(cls->kobj, &dev->kobj, dev_name(dev)); - if (error) - return error; - - /* - * Optionally add a "device" link (typically to the parent), as a - * class device would have one and we want to provide as much - * backwards compatibility as possible. - */ - if (device_link) { - error = sysfs_create_link(&dev->kobj, &device_link->kobj, - "device"); - if (error) - sysfs_remove_link(cls->kobj, dev_name(dev)); - } - - return error; + return sysfs_create_link(cls->kobj, &dev->kobj, dev_name(dev)); } EXPORT_SYMBOL_GPL(class_compat_create_link); @@ -617,14 +613,9 @@ EXPORT_SYMBOL_GPL(class_compat_create_link); * a bus device * @cls: the compatibility class * @dev: the target bus device - * @device_link: an optional device to which a "device" link was previously - * created */ -void class_compat_remove_link(struct class_compat *cls, struct device *dev, - struct device *device_link) +void class_compat_remove_link(struct class_compat *cls, struct device *dev) { - if (device_link) - sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(cls->kobj, dev_name(dev)); } EXPORT_SYMBOL_GPL(class_compat_remove_link); |
