diff options
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 7ecb1938e590..6bee6af8d8e1 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -166,13 +166,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, if (MAJOR(dev->devt)) { const char *tmp; const char *name; + mode_t mode = 0; add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); - name = device_get_nodename(dev, &tmp); + name = device_get_devnode(dev, &mode, &tmp); if (name) { add_uevent_var(env, "DEVNAME=%s", name); kfree(tmp); + if (mode) + add_uevent_var(env, "DEVMODE=%#o", mode & 0777); } } @@ -341,7 +344,7 @@ static void device_remove_attributes(struct device *dev, } static int device_add_groups(struct device *dev, - struct attribute_group **groups) + const struct attribute_group **groups) { int error = 0; int i; @@ -361,7 +364,7 @@ static int device_add_groups(struct device *dev, } static void device_remove_groups(struct device *dev, - struct attribute_group **groups) + const struct attribute_group **groups) { int i; @@ -843,6 +846,17 @@ static void device_remove_sys_dev_entry(struct device *dev) } } +int device_private_init(struct device *dev) +{ + dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); + if (!dev->p) + return -ENOMEM; + dev->p->device = dev; + klist_init(&dev->p->klist_children, klist_children_get, + klist_children_put); + return 0; +} + /** * device_add - add device to device hierarchy. * @dev: device. @@ -868,14 +882,11 @@ int device_add(struct device *dev) if (!dev) goto done; - dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); if (!dev->p) { - error = -ENOMEM; - goto done; + error = device_private_init(dev); + if (error) + goto done; } - dev->p->device = dev; - klist_init(&dev->p->klist_children, klist_children_get, - klist_children_put); /* * for statically allocated devices, which should all be converted @@ -921,6 +932,8 @@ int device_add(struct device *dev) error = device_create_sys_dev_entry(dev); if (error) goto devtattrError; + + devtmpfs_create_node(dev); } error = device_add_class_symlinks(dev); @@ -945,7 +958,7 @@ int device_add(struct device *dev) BUS_NOTIFY_ADD_DEVICE, dev); kobject_uevent(&dev->kobj, KOBJ_ADD); - bus_attach_device(dev); + bus_probe_device(dev); if (parent) klist_add_tail(&dev->p->knode_parent, &parent->p->klist_children); @@ -1067,6 +1080,7 @@ void device_del(struct device *dev) if (parent) klist_del(&dev->p->knode_parent); if (MAJOR(dev->devt)) { + devtmpfs_delete_node(dev); device_remove_sys_dev_entry(dev); device_remove_file(dev, &devt_attr); } @@ -1137,8 +1151,9 @@ static struct device *next_device(struct klist_iter *i) } /** - * device_get_nodename - path of device node file + * device_get_devnode - path of device node file * @dev: device + * @mode: returned file access mode * @tmp: possibly allocated string * * Return the relative path of a possible device node. @@ -1146,21 +1161,22 @@ static struct device *next_device(struct klist_iter *i) * a name. This memory is returned in tmp and needs to be * freed by the caller. */ -const char *device_get_nodename(struct device *dev, const char **tmp) +const char *device_get_devnode(struct device *dev, + mode_t *mode, const char **tmp) { char *s; *tmp = NULL; /* the device type may provide a specific name */ - if (dev->type && dev->type->nodename) - *tmp = dev->type->nodename(dev); + if (dev->type && dev->type->devnode) + *tmp = dev->type->devnode(dev, mode); if (*tmp) return *tmp; /* the class may provide a specific name */ - if (dev->class && dev->class->nodename) - *tmp = dev->class->nodename(dev); + if (dev->class && dev->class->devnode) + *tmp = dev->class->devnode(dev, mode); if (*tmp) return *tmp; |