diff options
-rw-r--r-- | drivers/base/core.c | 53 | ||||
-rw-r--r-- | include/linux/device.h | 4 |
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 5c91d0d81e78..f1228f25efe0 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -94,6 +94,8 @@ static void device_release(struct kobject * kobj) if (dev->release) dev->release(dev); + else if (dev->class && dev->class->dev_release) + dev->class->dev_release(dev); else { printk(KERN_ERR "Device '%s' does not have a release() function, " "it is broken and must be fixed.\n", @@ -183,6 +185,15 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, } } + if (dev->class && dev->class->dev_uevent) { + /* have the class specific function add its stuff */ + retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); + if (retval) { + pr_debug("%s - dev_uevent() returned %d\n", + __FUNCTION__, retval); + } + } + return retval; } @@ -228,6 +239,43 @@ static void device_remove_groups(struct device *dev) } } +static int device_add_attrs(struct device *dev) +{ + struct class *class = dev->class; + int error = 0; + int i; + + if (!class) + return 0; + + if (class->dev_attrs) { + for (i = 0; attr_name(class->dev_attrs[i]); i++) { + error = device_create_file(dev, &class->dev_attrs[i]); + if (error) + break; + } + } + if (error) + while (--i >= 0) + device_remove_file(dev, &class->dev_attrs[i]); + return error; +} + +static void device_remove_attrs(struct device *dev) +{ + struct class *class = dev->class; + int i; + + if (!class) + return; + + if (class->dev_attrs) { + for (i = 0; attr_name(class->dev_attrs[i]); i++) + device_remove_file(dev, &class->dev_attrs[i]); + } +} + + static ssize_t show_dev(struct device *dev, struct device_attribute *attr, char *buf) { @@ -382,6 +430,8 @@ int device_add(struct device *dev) } } + if ((error = device_add_attrs(dev))) + goto AttrsError; if ((error = device_add_groups(dev))) goto GroupError; if ((error = device_pm_add(dev))) @@ -412,6 +462,8 @@ int device_add(struct device *dev) PMError: device_remove_groups(dev); GroupError: + device_remove_attrs(dev); + AttrsError: if (dev->devt_attr) { device_remove_file(dev, dev->devt_attr); kfree(dev->devt_attr); @@ -509,6 +561,7 @@ void device_del(struct device * dev) } device_remove_file(dev, &dev->uevent_attr); device_remove_groups(dev); + device_remove_attrs(dev); /* Notify the platform of the removal, in case they * need to do anything... diff --git a/include/linux/device.h b/include/linux/device.h index 994d3ebd53f4..3122bd25ce42 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -151,12 +151,16 @@ struct class { struct class_attribute * class_attrs; struct class_device_attribute * class_dev_attrs; + struct device_attribute * dev_attrs; int (*uevent)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size); + int (*dev_uevent)(struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size); void (*release)(struct class_device *dev); void (*class_release)(struct class *class); + void (*dev_release)(struct device *dev); int (*suspend)(struct device *, pm_message_t state); int (*resume)(struct device *); |