diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-16 15:40:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-16 15:40:26 -0400 |
commit | c813b4e16ead3c3df98ac84419d4df2adf33fe01 (patch) | |
tree | 2ca4a5b6966d833b6149e3dda7a4e85d1255779c /drivers/base | |
parent | c8d8a2321f9c4ee18fbcc399fdc2a77e580a03b9 (diff) | |
parent | 02683ffdf655b4ae15245376ba6fea6d9e5829a6 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (46 commits)
UIO: Fix mapping of logical and virtual memory
UIO: add automata sercos3 pci card support
UIO: Change driver name of uio_pdrv
UIO: Add alignment warnings for uio-mem
Driver core: add bus_sort_breadthfirst() function
NET: convert the phy_device file to use bus_find_device_by_name
kobject: Cleanup kobject_rename and !CONFIG_SYSFS
kobject: Fix kobject_rename and !CONFIG_SYSFS
sysfs: Make dir and name args to sysfs_notify() const
platform: add new device registration helper
sysfs: use ilookup5() instead of ilookup5_nowait()
PNP: create device attributes via default device attributes
Driver core: make bus_find_device_by_name() more robust
usb: turn dev_warn+WARN_ON combos into dev_WARN
debug: use dev_WARN() rather than WARN_ON() in device_pm_add()
debug: Introduce a dev_WARN() function
sysfs: fix deadlock
device model: Do a quickcheck for driver binding before doing an expensive check
Driver core: Fix cleanup in device_create_vargs().
Driver core: Clarify device cleanup.
...
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/bus.c | 54 | ||||
-rw-r--r-- | drivers/base/core.c | 30 | ||||
-rw-r--r-- | drivers/base/dd.c | 3 | ||||
-rw-r--r-- | drivers/base/platform.c | 49 | ||||
-rw-r--r-- | drivers/base/power/main.c | 2 |
5 files changed, 127 insertions, 11 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index ef522ae55480..5aee1c0169ea 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -333,9 +333,7 @@ static int match_name(struct device *dev, void *data) | |||
333 | { | 333 | { |
334 | const char *name = data; | 334 | const char *name = data; |
335 | 335 | ||
336 | if (strcmp(name, dev->bus_id) == 0) | 336 | return sysfs_streq(name, dev->bus_id); |
337 | return 1; | ||
338 | return 0; | ||
339 | } | 337 | } |
340 | 338 | ||
341 | /** | 339 | /** |
@@ -982,6 +980,56 @@ struct klist *bus_get_device_klist(struct bus_type *bus) | |||
982 | } | 980 | } |
983 | EXPORT_SYMBOL_GPL(bus_get_device_klist); | 981 | EXPORT_SYMBOL_GPL(bus_get_device_klist); |
984 | 982 | ||
983 | /* | ||
984 | * Yes, this forcably breaks the klist abstraction temporarily. It | ||
985 | * just wants to sort the klist, not change reference counts and | ||
986 | * take/drop locks rapidly in the process. It does all this while | ||
987 | * holding the lock for the list, so objects can't otherwise be | ||
988 | * added/removed while we're swizzling. | ||
989 | */ | ||
990 | static void device_insertion_sort_klist(struct device *a, struct list_head *list, | ||
991 | int (*compare)(const struct device *a, | ||
992 | const struct device *b)) | ||
993 | { | ||
994 | struct list_head *pos; | ||
995 | struct klist_node *n; | ||
996 | struct device *b; | ||
997 | |||
998 | list_for_each(pos, list) { | ||
999 | n = container_of(pos, struct klist_node, n_node); | ||
1000 | b = container_of(n, struct device, knode_bus); | ||
1001 | if (compare(a, b) <= 0) { | ||
1002 | list_move_tail(&a->knode_bus.n_node, | ||
1003 | &b->knode_bus.n_node); | ||
1004 | return; | ||
1005 | } | ||
1006 | } | ||
1007 | list_move_tail(&a->knode_bus.n_node, list); | ||
1008 | } | ||
1009 | |||
1010 | void bus_sort_breadthfirst(struct bus_type *bus, | ||
1011 | int (*compare)(const struct device *a, | ||
1012 | const struct device *b)) | ||
1013 | { | ||
1014 | LIST_HEAD(sorted_devices); | ||
1015 | struct list_head *pos, *tmp; | ||
1016 | struct klist_node *n; | ||
1017 | struct device *dev; | ||
1018 | struct klist *device_klist; | ||
1019 | |||
1020 | device_klist = bus_get_device_klist(bus); | ||
1021 | |||
1022 | spin_lock(&device_klist->k_lock); | ||
1023 | list_for_each_safe(pos, tmp, &device_klist->k_list) { | ||
1024 | n = container_of(pos, struct klist_node, n_node); | ||
1025 | dev = container_of(n, struct device, knode_bus); | ||
1026 | device_insertion_sort_klist(dev, &sorted_devices, compare); | ||
1027 | } | ||
1028 | list_splice(&sorted_devices, &device_klist->k_list); | ||
1029 | spin_unlock(&device_klist->k_lock); | ||
1030 | } | ||
1031 | EXPORT_SYMBOL_GPL(bus_sort_breadthfirst); | ||
1032 | |||
985 | int __init buses_init(void) | 1033 | int __init buses_init(void) |
986 | { | 1034 | { |
987 | bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); | 1035 | bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index b98cb1416a2d..8c2cc2648f5a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -523,11 +523,16 @@ static void klist_children_put(struct klist_node *n) | |||
523 | * device_initialize - init device structure. | 523 | * device_initialize - init device structure. |
524 | * @dev: device. | 524 | * @dev: device. |
525 | * | 525 | * |
526 | * This prepares the device for use by other layers, | 526 | * This prepares the device for use by other layers by initializing |
527 | * including adding it to the device hierarchy. | 527 | * its fields. |
528 | * It is the first half of device_register(), if called by | 528 | * It is the first half of device_register(), if called by |
529 | * that, though it can also be called separately, so one | 529 | * that function, though it can also be called separately, so one |
530 | * may use @dev's fields (e.g. the refcount). | 530 | * may use @dev's fields. In particular, get_device()/put_device() |
531 | * may be used for reference counting of @dev after calling this | ||
532 | * function. | ||
533 | * | ||
534 | * NOTE: Use put_device() to give up your reference instead of freeing | ||
535 | * @dev directly once you have called this function. | ||
531 | */ | 536 | */ |
532 | void device_initialize(struct device *dev) | 537 | void device_initialize(struct device *dev) |
533 | { | 538 | { |
@@ -835,9 +840,13 @@ static void device_remove_sys_dev_entry(struct device *dev) | |||
835 | * This is part 2 of device_register(), though may be called | 840 | * This is part 2 of device_register(), though may be called |
836 | * separately _iff_ device_initialize() has been called separately. | 841 | * separately _iff_ device_initialize() has been called separately. |
837 | * | 842 | * |
838 | * This adds it to the kobject hierarchy via kobject_add(), adds it | 843 | * This adds @dev to the kobject hierarchy via kobject_add(), adds it |
839 | * to the global and sibling lists for the device, then | 844 | * to the global and sibling lists for the device, then |
840 | * adds it to the other relevant subsystems of the driver model. | 845 | * adds it to the other relevant subsystems of the driver model. |
846 | * | ||
847 | * NOTE: _Never_ directly free @dev after calling this function, even | ||
848 | * if it returned an error! Always use put_device() to give up your | ||
849 | * reference instead. | ||
841 | */ | 850 | */ |
842 | int device_add(struct device *dev) | 851 | int device_add(struct device *dev) |
843 | { | 852 | { |
@@ -965,6 +974,10 @@ done: | |||
965 | * I.e. you should only call the two helpers separately if | 974 | * I.e. you should only call the two helpers separately if |
966 | * have a clearly defined need to use and refcount the device | 975 | * have a clearly defined need to use and refcount the device |
967 | * before it is added to the hierarchy. | 976 | * before it is added to the hierarchy. |
977 | * | ||
978 | * NOTE: _Never_ directly free @dev after calling this function, even | ||
979 | * if it returned an error! Always use put_device() to give up the | ||
980 | * reference initialized in this function instead. | ||
968 | */ | 981 | */ |
969 | int device_register(struct device *dev) | 982 | int device_register(struct device *dev) |
970 | { | 983 | { |
@@ -1243,7 +1256,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent, | |||
1243 | return dev; | 1256 | return dev; |
1244 | 1257 | ||
1245 | error: | 1258 | error: |
1246 | kfree(dev); | 1259 | put_device(dev); |
1247 | return ERR_PTR(retval); | 1260 | return ERR_PTR(retval); |
1248 | } | 1261 | } |
1249 | EXPORT_SYMBOL_GPL(device_create_vargs); | 1262 | EXPORT_SYMBOL_GPL(device_create_vargs); |
@@ -1314,6 +1327,11 @@ EXPORT_SYMBOL_GPL(device_destroy); | |||
1314 | * device_rename - renames a device | 1327 | * device_rename - renames a device |
1315 | * @dev: the pointer to the struct device to be renamed | 1328 | * @dev: the pointer to the struct device to be renamed |
1316 | * @new_name: the new name of the device | 1329 | * @new_name: the new name of the device |
1330 | * | ||
1331 | * It is the responsibility of the caller to provide mutual | ||
1332 | * exclusion between two different calls of device_rename | ||
1333 | * on the same device to ensure that new_name is valid and | ||
1334 | * won't conflict with other devices. | ||
1317 | */ | 1335 | */ |
1318 | int device_rename(struct device *dev, char *new_name) | 1336 | int device_rename(struct device *dev, char *new_name) |
1319 | { | 1337 | { |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 3ac443b2ac08..20febc00a525 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -257,6 +257,9 @@ static int __driver_attach(struct device *dev, void *data) | |||
257 | * is an error. | 257 | * is an error. |
258 | */ | 258 | */ |
259 | 259 | ||
260 | if (drv->bus->match && !drv->bus->match(dev, drv)) | ||
261 | return 0; | ||
262 | |||
260 | if (dev->parent) /* Needed for USB */ | 263 | if (dev->parent) /* Needed for USB */ |
261 | down(&dev->parent->sem); | 264 | down(&dev->parent->sem); |
262 | down(&dev->sem); | 265 | down(&dev->sem); |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 66b710c28812..dfcbfe504867 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -394,6 +394,53 @@ error: | |||
394 | } | 394 | } |
395 | EXPORT_SYMBOL_GPL(platform_device_register_simple); | 395 | EXPORT_SYMBOL_GPL(platform_device_register_simple); |
396 | 396 | ||
397 | /** | ||
398 | * platform_device_register_data | ||
399 | * @parent: parent device for the device we're adding | ||
400 | * @name: base name of the device we're adding | ||
401 | * @id: instance id | ||
402 | * @data: platform specific data for this platform device | ||
403 | * @size: size of platform specific data | ||
404 | * | ||
405 | * This function creates a simple platform device that requires minimal | ||
406 | * resource and memory management. Canned release function freeing memory | ||
407 | * allocated for the device allows drivers using such devices to be | ||
408 | * unloaded without waiting for the last reference to the device to be | ||
409 | * dropped. | ||
410 | */ | ||
411 | struct platform_device *platform_device_register_data( | ||
412 | struct device *parent, | ||
413 | const char *name, int id, | ||
414 | const void *data, size_t size) | ||
415 | { | ||
416 | struct platform_device *pdev; | ||
417 | int retval; | ||
418 | |||
419 | pdev = platform_device_alloc(name, id); | ||
420 | if (!pdev) { | ||
421 | retval = -ENOMEM; | ||
422 | goto error; | ||
423 | } | ||
424 | |||
425 | pdev->dev.parent = parent; | ||
426 | |||
427 | if (size) { | ||
428 | retval = platform_device_add_data(pdev, data, size); | ||
429 | if (retval) | ||
430 | goto error; | ||
431 | } | ||
432 | |||
433 | retval = platform_device_add(pdev); | ||
434 | if (retval) | ||
435 | goto error; | ||
436 | |||
437 | return pdev; | ||
438 | |||
439 | error: | ||
440 | platform_device_put(pdev); | ||
441 | return ERR_PTR(retval); | ||
442 | } | ||
443 | |||
397 | static int platform_drv_probe(struct device *_dev) | 444 | static int platform_drv_probe(struct device *_dev) |
398 | { | 445 | { |
399 | struct platform_driver *drv = to_platform_driver(_dev->driver); | 446 | struct platform_driver *drv = to_platform_driver(_dev->driver); |
@@ -865,7 +912,7 @@ static int platform_pm_restore_noirq(struct device *dev) | |||
865 | 912 | ||
866 | #endif /* !CONFIG_HIBERNATION */ | 913 | #endif /* !CONFIG_HIBERNATION */ |
867 | 914 | ||
868 | struct pm_ext_ops platform_pm_ops = { | 915 | static struct pm_ext_ops platform_pm_ops = { |
869 | .base = { | 916 | .base = { |
870 | .prepare = platform_pm_prepare, | 917 | .prepare = platform_pm_prepare, |
871 | .complete = platform_pm_complete, | 918 | .complete = platform_pm_complete, |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 03bde7524bc3..692c20ba5144 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -83,7 +83,7 @@ void device_pm_add(struct device *dev) | |||
83 | * transition is in progress in order to avoid leaving them | 83 | * transition is in progress in order to avoid leaving them |
84 | * unhandled down the road | 84 | * unhandled down the road |
85 | */ | 85 | */ |
86 | WARN_ON(true); | 86 | dev_WARN(dev, "Parentless device registered during a PM transaction\n"); |
87 | } | 87 | } |
88 | 88 | ||
89 | list_add_tail(&dev->power.entry, &dpm_list); | 89 | list_add_tail(&dev->power.entry, &dpm_list); |