aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c261
1 files changed, 226 insertions, 35 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 27c2176895d..b224bb43ff6 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3,12 +3,13 @@
3 * 3 *
4 * Copyright (c) 2002-3 Patrick Mochel 4 * Copyright (c) 2002-3 Patrick Mochel
5 * Copyright (c) 2002-3 Open Source Development Labs 5 * Copyright (c) 2002-3 Open Source Development Labs
6 * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de>
7 * Copyright (c) 2006 Novell, Inc.
6 * 8 *
7 * This file is released under the GPLv2 9 * This file is released under the GPLv2
8 * 10 *
9 */ 11 */
10 12
11#include <linux/config.h>
12#include <linux/device.h> 13#include <linux/device.h>
13#include <linux/err.h> 14#include <linux/err.h>
14#include <linux/init.h> 15#include <linux/init.h>
@@ -93,6 +94,8 @@ static void device_release(struct kobject * kobj)
93 94
94 if (dev->release) 95 if (dev->release)
95 dev->release(dev); 96 dev->release(dev);
97 else if (dev->class && dev->class->dev_release)
98 dev->class->dev_release(dev);
96 else { 99 else {
97 printk(KERN_ERR "Device '%s' does not have a release() function, " 100 printk(KERN_ERR "Device '%s' does not have a release() function, "
98 "it is broken and must be fixed.\n", 101 "it is broken and must be fixed.\n",
@@ -150,17 +153,21 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
150 "MINOR=%u", MINOR(dev->devt)); 153 "MINOR=%u", MINOR(dev->devt));
151 } 154 }
152 155
153 /* add bus name of physical device */ 156 /* add bus name (same as SUBSYSTEM, deprecated) */
154 if (dev->bus) 157 if (dev->bus)
155 add_uevent_var(envp, num_envp, &i, 158 add_uevent_var(envp, num_envp, &i,
156 buffer, buffer_size, &length, 159 buffer, buffer_size, &length,
157 "PHYSDEVBUS=%s", dev->bus->name); 160 "PHYSDEVBUS=%s", dev->bus->name);
158 161
159 /* add driver name of physical device */ 162 /* add driver name (PHYSDEV* values are deprecated)*/
160 if (dev->driver) 163 if (dev->driver) {
164 add_uevent_var(envp, num_envp, &i,
165 buffer, buffer_size, &length,
166 "DRIVER=%s", dev->driver->name);
161 add_uevent_var(envp, num_envp, &i, 167 add_uevent_var(envp, num_envp, &i,
162 buffer, buffer_size, &length, 168 buffer, buffer_size, &length,
163 "PHYSDEVDRIVER=%s", dev->driver->name); 169 "PHYSDEVDRIVER=%s", dev->driver->name);
170 }
164 171
165 /* terminate, set to next free slot, shrink available space */ 172 /* terminate, set to next free slot, shrink available space */
166 envp[i] = NULL; 173 envp[i] = NULL;
@@ -178,6 +185,15 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
178 } 185 }
179 } 186 }
180 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
181 return retval; 197 return retval;
182} 198}
183 199
@@ -194,6 +210,72 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
194 return count; 210 return count;
195} 211}
196 212
213static int device_add_groups(struct device *dev)
214{
215 int i;
216 int error = 0;
217
218 if (dev->groups) {
219 for (i = 0; dev->groups[i]; i++) {
220 error = sysfs_create_group(&dev->kobj, dev->groups[i]);
221 if (error) {
222 while (--i >= 0)
223 sysfs_remove_group(&dev->kobj, dev->groups[i]);
224 goto out;
225 }
226 }
227 }
228out:
229 return error;
230}
231
232static void device_remove_groups(struct device *dev)
233{
234 int i;
235 if (dev->groups) {
236 for (i = 0; dev->groups[i]; i++) {
237 sysfs_remove_group(&dev->kobj, dev->groups[i]);
238 }
239 }
240}
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
197static ssize_t show_dev(struct device *dev, struct device_attribute *attr, 279static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
198 char *buf) 280 char *buf)
199{ 281{
@@ -237,6 +319,32 @@ void device_remove_file(struct device * dev, struct device_attribute * attr)
237 } 319 }
238} 320}
239 321
322/**
323 * device_create_bin_file - create sysfs binary attribute file for device.
324 * @dev: device.
325 * @attr: device binary attribute descriptor.
326 */
327int device_create_bin_file(struct device *dev, struct bin_attribute *attr)
328{
329 int error = -EINVAL;
330 if (dev)
331 error = sysfs_create_bin_file(&dev->kobj, attr);
332 return error;
333}
334EXPORT_SYMBOL_GPL(device_create_bin_file);
335
336/**
337 * device_remove_bin_file - remove sysfs binary attribute file
338 * @dev: device.
339 * @attr: device binary attribute descriptor.
340 */
341void device_remove_bin_file(struct device *dev, struct bin_attribute *attr)
342{
343 if (dev)
344 sysfs_remove_bin_file(&dev->kobj, attr);
345}
346EXPORT_SYMBOL_GPL(device_remove_bin_file);
347
240static void klist_children_get(struct klist_node *n) 348static void klist_children_get(struct klist_node *n)
241{ 349{
242 struct device *dev = container_of(n, struct device, knode_parent); 350 struct device *dev = container_of(n, struct device, knode_parent);
@@ -290,12 +398,20 @@ int device_add(struct device *dev)
290{ 398{
291 struct device *parent = NULL; 399 struct device *parent = NULL;
292 char *class_name = NULL; 400 char *class_name = NULL;
401 struct class_interface *class_intf;
293 int error = -EINVAL; 402 int error = -EINVAL;
294 403
295 dev = get_device(dev); 404 dev = get_device(dev);
296 if (!dev || !strlen(dev->bus_id)) 405 if (!dev || !strlen(dev->bus_id))
297 goto Error; 406 goto Error;
298 407
408 /* if this is a class device, and has no parent, create one */
409 if ((dev->class) && (dev->parent == NULL)) {
410 error = virtual_device_parent(dev);
411 if (error)
412 goto Error;
413 }
414
299 parent = get_device(dev->parent); 415 parent = get_device(dev->parent);
300 416
301 pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); 417 pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
@@ -308,6 +424,10 @@ int device_add(struct device *dev)
308 if ((error = kobject_add(&dev->kobj))) 424 if ((error = kobject_add(&dev->kobj)))
309 goto Error; 425 goto Error;
310 426
427 /* notify platform of device entry */
428 if (platform_notify)
429 platform_notify(dev);
430
311 dev->uevent_attr.attr.name = "uevent"; 431 dev->uevent_attr.attr.name = "uevent";
312 dev->uevent_attr.attr.mode = S_IWUSR; 432 dev->uevent_attr.attr.mode = S_IWUSR;
313 if (dev->driver) 433 if (dev->driver)
@@ -341,12 +461,17 @@ int device_add(struct device *dev)
341 "subsystem"); 461 "subsystem");
342 sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, 462 sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
343 dev->bus_id); 463 dev->bus_id);
344 464 if (parent) {
345 sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); 465 sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
346 class_name = make_class_name(dev->class->name, &dev->kobj); 466 class_name = make_class_name(dev->class->name, &dev->kobj);
347 sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); 467 sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
468 }
348 } 469 }
349 470
471 if ((error = device_add_attrs(dev)))
472 goto AttrsError;
473 if ((error = device_add_groups(dev)))
474 goto GroupError;
350 if ((error = device_pm_add(dev))) 475 if ((error = device_pm_add(dev)))
351 goto PMError; 476 goto PMError;
352 if ((error = bus_add_device(dev))) 477 if ((error = bus_add_device(dev)))
@@ -357,15 +482,16 @@ int device_add(struct device *dev)
357 klist_add_tail(&dev->knode_parent, &parent->klist_children); 482 klist_add_tail(&dev->knode_parent, &parent->klist_children);
358 483
359 if (dev->class) { 484 if (dev->class) {
360 /* tie the class to the device */
361 down(&dev->class->sem); 485 down(&dev->class->sem);
486 /* tie the class to the device */
362 list_add_tail(&dev->node, &dev->class->devices); 487 list_add_tail(&dev->node, &dev->class->devices);
488
489 /* notify any interfaces that the device is here */
490 list_for_each_entry(class_intf, &dev->class->interfaces, node)
491 if (class_intf->add_dev)
492 class_intf->add_dev(dev, class_intf);
363 up(&dev->class->sem); 493 up(&dev->class->sem);
364 } 494 }
365
366 /* notify platform of device entry */
367 if (platform_notify)
368 platform_notify(dev);
369 Done: 495 Done:
370 kfree(class_name); 496 kfree(class_name);
371 put_device(dev); 497 put_device(dev);
@@ -373,6 +499,10 @@ int device_add(struct device *dev)
373 BusError: 499 BusError:
374 device_pm_remove(dev); 500 device_pm_remove(dev);
375 PMError: 501 PMError:
502 device_remove_groups(dev);
503 GroupError:
504 device_remove_attrs(dev);
505 AttrsError:
376 if (dev->devt_attr) { 506 if (dev->devt_attr) {
377 device_remove_file(dev, dev->devt_attr); 507 device_remove_file(dev, dev->devt_attr);
378 kfree(dev->devt_attr); 508 kfree(dev->devt_attr);
@@ -450,6 +580,7 @@ void device_del(struct device * dev)
450{ 580{
451 struct device * parent = dev->parent; 581 struct device * parent = dev->parent;
452 char *class_name = NULL; 582 char *class_name = NULL;
583 struct class_interface *class_intf;
453 584
454 if (parent) 585 if (parent)
455 klist_del(&dev->knode_parent); 586 klist_del(&dev->knode_parent);
@@ -459,14 +590,23 @@ void device_del(struct device * dev)
459 sysfs_remove_link(&dev->kobj, "subsystem"); 590 sysfs_remove_link(&dev->kobj, "subsystem");
460 sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); 591 sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id);
461 class_name = make_class_name(dev->class->name, &dev->kobj); 592 class_name = make_class_name(dev->class->name, &dev->kobj);
462 sysfs_remove_link(&dev->kobj, "device"); 593 if (parent) {
463 sysfs_remove_link(&dev->parent->kobj, class_name); 594 sysfs_remove_link(&dev->kobj, "device");
595 sysfs_remove_link(&dev->parent->kobj, class_name);
596 }
464 kfree(class_name); 597 kfree(class_name);
465 down(&dev->class->sem); 598 down(&dev->class->sem);
599 /* notify any interfaces that the device is now gone */
600 list_for_each_entry(class_intf, &dev->class->interfaces, node)
601 if (class_intf->remove_dev)
602 class_intf->remove_dev(dev, class_intf);
603 /* remove the device from the class list */
466 list_del_init(&dev->node); 604 list_del_init(&dev->node);
467 up(&dev->class->sem); 605 up(&dev->class->sem);
468 } 606 }
469 device_remove_file(dev, &dev->uevent_attr); 607 device_remove_file(dev, &dev->uevent_attr);
608 device_remove_groups(dev);
609 device_remove_attrs(dev);
470 610
471 /* Notify the platform of the removal, in case they 611 /* Notify the platform of the removal, in case they
472 * need to do anything... 612 * need to do anything...
@@ -560,27 +700,27 @@ static void device_create_release(struct device *dev)
560 700
561/** 701/**
562 * device_create - creates a device and registers it with sysfs 702 * device_create - creates a device and registers it with sysfs
563 * @cs: pointer to the struct class that this device should be registered to. 703 * @class: pointer to the struct class that this device should be registered to
564 * @parent: pointer to the parent struct device of this new device, if any. 704 * @parent: pointer to the parent struct device of this new device, if any
565 * @dev: the dev_t for the char device to be added. 705 * @devt: the dev_t for the char device to be added
566 * @fmt: string for the class device's name 706 * @fmt: string for the device's name
707 *
708 * This function can be used by char device classes. A struct device
709 * will be created in sysfs, registered to the specified class.
567 * 710 *
568 * This function can be used by char device classes. A struct
569 * device will be created in sysfs, registered to the specified
570 * class.
571 * A "dev" file will be created, showing the dev_t for the device, if 711 * A "dev" file will be created, showing the dev_t for the device, if
572 * the dev_t is not 0,0. 712 * the dev_t is not 0,0.
573 * If a pointer to a parent struct device is passed in, the newly 713 * If a pointer to a parent struct device is passed in, the newly created
574 * created struct device will be a child of that device in sysfs. The 714 * struct device will be a child of that device in sysfs.
575 * pointer to the struct device will be returned from the call. Any 715 * The pointer to the struct device will be returned from the call.
576 * further sysfs files that might be required can be created using this 716 * Any further sysfs files that might be required can be created using this
577 * pointer. 717 * pointer.
578 * 718 *
579 * Note: the struct class passed to this function must have previously 719 * Note: the struct class passed to this function must have previously
580 * been created with a call to class_create(). 720 * been created with a call to class_create().
581 */ 721 */
582struct device *device_create(struct class *class, struct device *parent, 722struct device *device_create(struct class *class, struct device *parent,
583 dev_t devt, char *fmt, ...) 723 dev_t devt, const char *fmt, ...)
584{ 724{
585 va_list args; 725 va_list args;
586 struct device *dev = NULL; 726 struct device *dev = NULL;
@@ -588,10 +728,6 @@ struct device *device_create(struct class *class, struct device *parent,
588 728
589 if (class == NULL || IS_ERR(class)) 729 if (class == NULL || IS_ERR(class))
590 goto error; 730 goto error;
591 if (parent == NULL) {
592 printk(KERN_WARNING "%s does not work yet for NULL parents\n", __FUNCTION__);
593 goto error;
594 }
595 731
596 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 732 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
597 if (!dev) { 733 if (!dev) {
@@ -621,11 +757,11 @@ EXPORT_SYMBOL_GPL(device_create);
621 757
622/** 758/**
623 * device_destroy - removes a device that was created with device_create() 759 * device_destroy - removes a device that was created with device_create()
624 * @class: the pointer to the struct class that this device was registered * with. 760 * @class: pointer to the struct class that this device was registered with
625 * @dev: the dev_t of the device that was previously registered. 761 * @devt: the dev_t of the device that was previously registered
626 * 762 *
627 * This call unregisters and cleans up a class device that was created with a 763 * This call unregisters and cleans up a device that was created with a
628 * call to class_device_create() 764 * call to device_create().
629 */ 765 */
630void device_destroy(struct class *class, dev_t devt) 766void device_destroy(struct class *class, dev_t devt)
631{ 767{
@@ -645,3 +781,58 @@ void device_destroy(struct class *class, dev_t devt)
645 device_unregister(dev); 781 device_unregister(dev);
646} 782}
647EXPORT_SYMBOL_GPL(device_destroy); 783EXPORT_SYMBOL_GPL(device_destroy);
784
785/**
786 * device_rename - renames a device
787 * @dev: the pointer to the struct device to be renamed
788 * @new_name: the new name of the device
789 */
790int device_rename(struct device *dev, char *new_name)
791{
792 char *old_class_name = NULL;
793 char *new_class_name = NULL;
794 char *old_symlink_name = NULL;
795 int error;
796
797 dev = get_device(dev);
798 if (!dev)
799 return -EINVAL;
800
801 pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name);
802
803 if ((dev->class) && (dev->parent))
804 old_class_name = make_class_name(dev->class->name, &dev->kobj);
805
806 if (dev->class) {
807 old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
808 if (!old_symlink_name)
809 return -ENOMEM;
810 strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
811 }
812
813 strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
814
815 error = kobject_rename(&dev->kobj, new_name);
816
817 if (old_class_name) {
818 new_class_name = make_class_name(dev->class->name, &dev->kobj);
819 if (new_class_name) {
820 sysfs_create_link(&dev->parent->kobj, &dev->kobj,
821 new_class_name);
822 sysfs_remove_link(&dev->parent->kobj, old_class_name);
823 }
824 }
825 if (dev->class) {
826 sysfs_remove_link(&dev->class->subsys.kset.kobj,
827 old_symlink_name);
828 sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
829 dev->bus_id);
830 }
831 put_device(dev);
832
833 kfree(old_class_name);
834 kfree(new_class_name);
835 kfree(old_symlink_name);
836
837 return error;
838}