aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 5c91d0d81e7..f1228f25efe 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -94,6 +94,8 @@ static void device_release(struct kobject * kobj)
94 94
95 if (dev->release) 95 if (dev->release)
96 dev->release(dev); 96 dev->release(dev);
97 else if (dev->class && dev->class->dev_release)
98 dev->class->dev_release(dev);
97 else { 99 else {
98 printk(KERN_ERR "Device '%s' does not have a release() function, " 100 printk(KERN_ERR "Device '%s' does not have a release() function, "
99 "it is broken and must be fixed.\n", 101 "it is broken and must be fixed.\n",
@@ -183,6 +185,15 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
183 } 185 }
184 } 186 }
185 187
188 if (dev->class && dev->class->dev_uevent) {
189 /* have the class specific function add its stuff */
190 retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
191 if (retval) {
192 pr_debug("%s - dev_uevent() returned %d\n",
193 __FUNCTION__, retval);
194 }
195 }
196
186 return retval; 197 return retval;
187} 198}
188 199
@@ -228,6 +239,43 @@ static void device_remove_groups(struct device *dev)
228 } 239 }
229} 240}
230 241
242static int device_add_attrs(struct device *dev)
243{
244 struct class *class = dev->class;
245 int error = 0;
246 int i;
247
248 if (!class)
249 return 0;
250
251 if (class->dev_attrs) {
252 for (i = 0; attr_name(class->dev_attrs[i]); i++) {
253 error = device_create_file(dev, &class->dev_attrs[i]);
254 if (error)
255 break;
256 }
257 }
258 if (error)
259 while (--i >= 0)
260 device_remove_file(dev, &class->dev_attrs[i]);
261 return error;
262}
263
264static void device_remove_attrs(struct device *dev)
265{
266 struct class *class = dev->class;
267 int i;
268
269 if (!class)
270 return;
271
272 if (class->dev_attrs) {
273 for (i = 0; attr_name(class->dev_attrs[i]); i++)
274 device_remove_file(dev, &class->dev_attrs[i]);
275 }
276}
277
278
231static ssize_t show_dev(struct device *dev, struct device_attribute *attr, 279static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
232 char *buf) 280 char *buf)
233{ 281{
@@ -382,6 +430,8 @@ int device_add(struct device *dev)
382 } 430 }
383 } 431 }
384 432
433 if ((error = device_add_attrs(dev)))
434 goto AttrsError;
385 if ((error = device_add_groups(dev))) 435 if ((error = device_add_groups(dev)))
386 goto GroupError; 436 goto GroupError;
387 if ((error = device_pm_add(dev))) 437 if ((error = device_pm_add(dev)))
@@ -412,6 +462,8 @@ int device_add(struct device *dev)
412 PMError: 462 PMError:
413 device_remove_groups(dev); 463 device_remove_groups(dev);
414 GroupError: 464 GroupError:
465 device_remove_attrs(dev);
466 AttrsError:
415 if (dev->devt_attr) { 467 if (dev->devt_attr) {
416 device_remove_file(dev, dev->devt_attr); 468 device_remove_file(dev, dev->devt_attr);
417 kfree(dev->devt_attr); 469 kfree(dev->devt_attr);
@@ -509,6 +561,7 @@ void device_del(struct device * dev)
509 } 561 }
510 device_remove_file(dev, &dev->uevent_attr); 562 device_remove_file(dev, &dev->uevent_attr);
511 device_remove_groups(dev); 563 device_remove_groups(dev);
564 device_remove_attrs(dev);
512 565
513 /* Notify the platform of the removal, in case they 566 /* Notify the platform of the removal, in case they
514 * need to do anything... 567 * need to do anything...