diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 22:36:42 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 22:36:42 -0400 |
| commit | b9da0571050c09863e59f94d0b8594a290d61b88 (patch) | |
| tree | 3632c4fee768db9a27a5c872bd42133692e2f3d0 /drivers/base | |
| parent | f8cae0f03f75adb54b1d48ddbc90f84a1f5de186 (diff) | |
| parent | 5abd935661e01289ba143c3b2c1ba300c65bcc5f (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: (31 commits)
driver core: Display error codes when class suspend fails
Driver core: Add section count to memory_block struct
Driver core: Add mutex for adding/removing memory blocks
Driver core: Move find_memory_block routine
hpilo: Despecificate driver from iLO generation
driver core: Convert link_mem_sections to use find_memory_block_hinted.
driver core: Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted.
kobject: Introduce kset_find_obj_hinted.
driver core: fix build for CONFIG_BLOCK not enabled
driver-core: base: change to new flag variable
sysfs: only access bin file vm_ops with the active lock
sysfs: Fail bin file mmap if vma close is implemented.
FW_LOADER: fix kconfig dependency warning on HOTPLUG
uio: Statically allocate uio_class and use class .dev_attrs.
uio: Support 2^MINOR_BITS minors
uio: Cleanup irq handling.
uio: Don't clear driver data
uio: Fix lack of locking in init_uio_class
SYSFS: Allow boot time switching between deprecated and modern sysfs layout
driver core: remove CONFIG_SYSFS_DEPRECATED_V2 but keep it for block devices
...
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/base/Makefile | 4 | ||||
| -rw-r--r-- | drivers/base/bus.c | 22 | ||||
| -rw-r--r-- | drivers/base/class.c | 23 | ||||
| -rw-r--r-- | drivers/base/core.c | 208 | ||||
| -rw-r--r-- | drivers/base/memory.c | 94 | ||||
| -rw-r--r-- | drivers/base/node.c | 8 | ||||
| -rw-r--r-- | drivers/base/platform.c | 80 | ||||
| -rw-r--r-- | drivers/base/sys.c | 8 |
9 files changed, 165 insertions, 283 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index ef38aff737eb..fd96345bc35c 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
| @@ -71,7 +71,6 @@ config PREVENT_FIRMWARE_BUILD | |||
| 71 | 71 | ||
| 72 | config FW_LOADER | 72 | config FW_LOADER |
| 73 | tristate "Userspace firmware loading support" if EMBEDDED | 73 | tristate "Userspace firmware loading support" if EMBEDDED |
| 74 | depends on HOTPLUG | ||
| 75 | default y | 74 | default y |
| 76 | ---help--- | 75 | ---help--- |
| 77 | This option is provided for the case where no in-kernel-tree modules | 76 | This option is provided for the case where no in-kernel-tree modules |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index c12c7f2f2a6f..5f51c3b4451e 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
| @@ -19,7 +19,5 @@ obj-$(CONFIG_MODULES) += module.o | |||
| 19 | endif | 19 | endif |
| 20 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o | 20 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o |
| 21 | 21 | ||
| 22 | ifeq ($(CONFIG_DEBUG_DRIVER),y) | 22 | ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG |
| 23 | EXTRA_CFLAGS += -DDEBUG | ||
| 24 | endif | ||
| 25 | 23 | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index eb1b7fa20dce..33c270a64db7 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
| @@ -440,22 +440,6 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev) | |||
| 440 | } | 440 | } |
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 444 | static int make_deprecated_bus_links(struct device *dev) | ||
| 445 | { | ||
| 446 | return sysfs_create_link(&dev->kobj, | ||
| 447 | &dev->bus->p->subsys.kobj, "bus"); | ||
| 448 | } | ||
| 449 | |||
| 450 | static void remove_deprecated_bus_links(struct device *dev) | ||
| 451 | { | ||
| 452 | sysfs_remove_link(&dev->kobj, "bus"); | ||
| 453 | } | ||
| 454 | #else | ||
| 455 | static inline int make_deprecated_bus_links(struct device *dev) { return 0; } | ||
| 456 | static inline void remove_deprecated_bus_links(struct device *dev) { } | ||
| 457 | #endif | ||
| 458 | |||
| 459 | /** | 443 | /** |
| 460 | * bus_add_device - add device to bus | 444 | * bus_add_device - add device to bus |
| 461 | * @dev: device being added | 445 | * @dev: device being added |
| @@ -482,15 +466,10 @@ int bus_add_device(struct device *dev) | |||
| 482 | &dev->bus->p->subsys.kobj, "subsystem"); | 466 | &dev->bus->p->subsys.kobj, "subsystem"); |
| 483 | if (error) | 467 | if (error) |
| 484 | goto out_subsys; | 468 | goto out_subsys; |
| 485 | error = make_deprecated_bus_links(dev); | ||
| 486 | if (error) | ||
| 487 | goto out_deprecated; | ||
| 488 | klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); | 469 | klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); |
| 489 | } | 470 | } |
| 490 | return 0; | 471 | return 0; |
| 491 | 472 | ||
| 492 | out_deprecated: | ||
| 493 | sysfs_remove_link(&dev->kobj, "subsystem"); | ||
| 494 | out_subsys: | 473 | out_subsys: |
| 495 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); | 474 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); |
| 496 | out_id: | 475 | out_id: |
| @@ -530,7 +509,6 @@ void bus_remove_device(struct device *dev) | |||
| 530 | { | 509 | { |
| 531 | if (dev->bus) { | 510 | if (dev->bus) { |
| 532 | sysfs_remove_link(&dev->kobj, "subsystem"); | 511 | sysfs_remove_link(&dev->kobj, "subsystem"); |
| 533 | remove_deprecated_bus_links(dev); | ||
| 534 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, | 512 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
| 535 | dev_name(dev)); | 513 | dev_name(dev)); |
| 536 | device_remove_attrs(dev->bus, dev); | 514 | device_remove_attrs(dev->bus, dev); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 8e231d05b400..9c63a5687d69 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
| @@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key) | |||
| 184 | if (!cls->dev_kobj) | 184 | if (!cls->dev_kobj) |
| 185 | cls->dev_kobj = sysfs_dev_char_kobj; | 185 | cls->dev_kobj = sysfs_dev_char_kobj; |
| 186 | 186 | ||
| 187 | #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) | 187 | #if defined(CONFIG_BLOCK) |
| 188 | /* let the block class directory show up in the root of sysfs */ | 188 | /* let the block class directory show up in the root of sysfs */ |
| 189 | if (cls != &block_class) | 189 | if (!sysfs_deprecated || cls != &block_class) |
| 190 | cp->class_subsys.kobj.kset = class_kset; | 190 | cp->class_subsys.kobj.kset = class_kset; |
| 191 | #else | 191 | #else |
| 192 | cp->class_subsys.kobj.kset = class_kset; | 192 | cp->class_subsys.kobj.kset = class_kset; |
| @@ -276,25 +276,6 @@ void class_destroy(struct class *cls) | |||
| 276 | class_unregister(cls); | 276 | class_unregister(cls); |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 280 | char *make_class_name(const char *name, struct kobject *kobj) | ||
| 281 | { | ||
| 282 | char *class_name; | ||
| 283 | int size; | ||
| 284 | |||
| 285 | size = strlen(name) + strlen(kobject_name(kobj)) + 2; | ||
| 286 | |||
| 287 | class_name = kmalloc(size, GFP_KERNEL); | ||
| 288 | if (!class_name) | ||
| 289 | return NULL; | ||
| 290 | |||
| 291 | strcpy(class_name, name); | ||
| 292 | strcat(class_name, ":"); | ||
| 293 | strcat(class_name, kobject_name(kobj)); | ||
| 294 | return class_name; | ||
| 295 | } | ||
| 296 | #endif | ||
| 297 | |||
| 298 | /** | 279 | /** |
| 299 | * class_dev_iter_init - initialize class device iterator | 280 | * class_dev_iter_init - initialize class device iterator |
| 300 | * @iter: class iterator to initialize | 281 | * @iter: class iterator to initialize |
diff --git a/drivers/base/core.c b/drivers/base/core.c index d1b2c9adc271..2cb49a93b1e6 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
| @@ -26,6 +26,19 @@ | |||
| 26 | #include "base.h" | 26 | #include "base.h" |
| 27 | #include "power/power.h" | 27 | #include "power/power.h" |
| 28 | 28 | ||
| 29 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 30 | #ifdef CONFIG_SYSFS_DEPRECATED_V2 | ||
| 31 | long sysfs_deprecated = 1; | ||
| 32 | #else | ||
| 33 | long sysfs_deprecated = 0; | ||
| 34 | #endif | ||
| 35 | static __init int sysfs_deprecated_setup(char *arg) | ||
| 36 | { | ||
| 37 | return strict_strtol(arg, 10, &sysfs_deprecated); | ||
| 38 | } | ||
| 39 | early_param("sysfs.deprecated", sysfs_deprecated_setup); | ||
| 40 | #endif | ||
| 41 | |||
| 29 | int (*platform_notify)(struct device *dev) = NULL; | 42 | int (*platform_notify)(struct device *dev) = NULL; |
| 30 | int (*platform_notify_remove)(struct device *dev) = NULL; | 43 | int (*platform_notify_remove)(struct device *dev) = NULL; |
| 31 | static struct kobject *dev_kobj; | 44 | static struct kobject *dev_kobj; |
| @@ -203,37 +216,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
| 203 | if (dev->driver) | 216 | if (dev->driver) |
| 204 | add_uevent_var(env, "DRIVER=%s", dev->driver->name); | 217 | add_uevent_var(env, "DRIVER=%s", dev->driver->name); |
| 205 | 218 | ||
| 206 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 207 | if (dev->class) { | ||
| 208 | struct device *parent = dev->parent; | ||
| 209 | |||
| 210 | /* find first bus device in parent chain */ | ||
| 211 | while (parent && !parent->bus) | ||
| 212 | parent = parent->parent; | ||
| 213 | if (parent && parent->bus) { | ||
| 214 | const char *path; | ||
| 215 | |||
| 216 | path = kobject_get_path(&parent->kobj, GFP_KERNEL); | ||
| 217 | if (path) { | ||
| 218 | add_uevent_var(env, "PHYSDEVPATH=%s", path); | ||
| 219 | kfree(path); | ||
| 220 | } | ||
| 221 | |||
| 222 | add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name); | ||
| 223 | |||
| 224 | if (parent->driver) | ||
| 225 | add_uevent_var(env, "PHYSDEVDRIVER=%s", | ||
| 226 | parent->driver->name); | ||
| 227 | } | ||
| 228 | } else if (dev->bus) { | ||
| 229 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); | ||
| 230 | |||
| 231 | if (dev->driver) | ||
| 232 | add_uevent_var(env, "PHYSDEVDRIVER=%s", | ||
| 233 | dev->driver->name); | ||
| 234 | } | ||
| 235 | #endif | ||
| 236 | |||
| 237 | /* have the bus specific function add its stuff */ | 219 | /* have the bus specific function add its stuff */ |
| 238 | if (dev->bus && dev->bus->uevent) { | 220 | if (dev->bus && dev->bus->uevent) { |
| 239 | retval = dev->bus->uevent(dev, env); | 221 | retval = dev->bus->uevent(dev, env); |
| @@ -578,24 +560,6 @@ void device_initialize(struct device *dev) | |||
| 578 | set_dev_node(dev, -1); | 560 | set_dev_node(dev, -1); |
| 579 | } | 561 | } |
| 580 | 562 | ||
| 581 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 582 | static struct kobject *get_device_parent(struct device *dev, | ||
| 583 | struct device *parent) | ||
| 584 | { | ||
| 585 | /* class devices without a parent live in /sys/class/<classname>/ */ | ||
| 586 | if (dev->class && (!parent || parent->class != dev->class)) | ||
| 587 | return &dev->class->p->class_subsys.kobj; | ||
| 588 | /* all other devices keep their parent */ | ||
| 589 | else if (parent) | ||
| 590 | return &parent->kobj; | ||
| 591 | |||
| 592 | return NULL; | ||
| 593 | } | ||
| 594 | |||
| 595 | static inline void cleanup_device_parent(struct device *dev) {} | ||
| 596 | static inline void cleanup_glue_dir(struct device *dev, | ||
| 597 | struct kobject *glue_dir) {} | ||
| 598 | #else | ||
| 599 | static struct kobject *virtual_device_parent(struct device *dev) | 563 | static struct kobject *virtual_device_parent(struct device *dev) |
| 600 | { | 564 | { |
| 601 | static struct kobject *virtual_dir = NULL; | 565 | static struct kobject *virtual_dir = NULL; |
| @@ -666,6 +630,15 @@ static struct kobject *get_device_parent(struct device *dev, | |||
| 666 | struct kobject *parent_kobj; | 630 | struct kobject *parent_kobj; |
| 667 | struct kobject *k; | 631 | struct kobject *k; |
| 668 | 632 | ||
| 633 | #ifdef CONFIG_BLOCK | ||
| 634 | /* block disks show up in /sys/block */ | ||
| 635 | if (sysfs_deprecated && dev->class == &block_class) { | ||
| 636 | if (parent && parent->class == &block_class) | ||
| 637 | return &parent->kobj; | ||
| 638 | return &block_class.p->class_subsys.kobj; | ||
| 639 | } | ||
| 640 | #endif | ||
| 641 | |||
| 669 | /* | 642 | /* |
| 670 | * If we have no parent, we live in "virtual". | 643 | * If we have no parent, we live in "virtual". |
| 671 | * Class-devices with a non class-device as parent, live | 644 | * Class-devices with a non class-device as parent, live |
| @@ -719,7 +692,6 @@ static void cleanup_device_parent(struct device *dev) | |||
| 719 | { | 692 | { |
| 720 | cleanup_glue_dir(dev, dev->kobj.parent); | 693 | cleanup_glue_dir(dev, dev->kobj.parent); |
| 721 | } | 694 | } |
| 722 | #endif | ||
| 723 | 695 | ||
| 724 | static void setup_parent(struct device *dev, struct device *parent) | 696 | static void setup_parent(struct device *dev, struct device *parent) |
| 725 | { | 697 | { |
| @@ -742,70 +714,29 @@ static int device_add_class_symlinks(struct device *dev) | |||
| 742 | if (error) | 714 | if (error) |
| 743 | goto out; | 715 | goto out; |
| 744 | 716 | ||
| 745 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 746 | /* stacked class devices need a symlink in the class directory */ | ||
| 747 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && | ||
| 748 | device_is_not_partition(dev)) { | ||
| 749 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, | ||
| 750 | &dev->kobj, dev_name(dev)); | ||
| 751 | if (error) | ||
| 752 | goto out_subsys; | ||
| 753 | } | ||
| 754 | |||
| 755 | if (dev->parent && device_is_not_partition(dev)) { | 717 | if (dev->parent && device_is_not_partition(dev)) { |
| 756 | struct device *parent = dev->parent; | 718 | error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, |
| 757 | char *class_name; | ||
| 758 | |||
| 759 | /* | ||
| 760 | * stacked class devices have the 'device' link | ||
| 761 | * pointing to the bus device instead of the parent | ||
| 762 | */ | ||
| 763 | while (parent->class && !parent->bus && parent->parent) | ||
| 764 | parent = parent->parent; | ||
| 765 | |||
| 766 | error = sysfs_create_link(&dev->kobj, | ||
| 767 | &parent->kobj, | ||
| 768 | "device"); | 719 | "device"); |
| 769 | if (error) | 720 | if (error) |
| 770 | goto out_busid; | 721 | goto out_subsys; |
| 771 | |||
| 772 | class_name = make_class_name(dev->class->name, | ||
| 773 | &dev->kobj); | ||
| 774 | if (class_name) | ||
| 775 | error = sysfs_create_link(&dev->parent->kobj, | ||
| 776 | &dev->kobj, class_name); | ||
| 777 | kfree(class_name); | ||
| 778 | if (error) | ||
| 779 | goto out_device; | ||
| 780 | } | 722 | } |
| 781 | return 0; | ||
| 782 | 723 | ||
| 783 | out_device: | 724 | #ifdef CONFIG_BLOCK |
| 784 | if (dev->parent && device_is_not_partition(dev)) | 725 | /* /sys/block has directories and does not need symlinks */ |
| 785 | sysfs_remove_link(&dev->kobj, "device"); | 726 | if (sysfs_deprecated && dev->class == &block_class) |
| 786 | out_busid: | 727 | return 0; |
| 787 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && | 728 | #endif |
| 788 | device_is_not_partition(dev)) | 729 | |
| 789 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, | ||
| 790 | dev_name(dev)); | ||
| 791 | #else | ||
| 792 | /* link in the class directory pointing to the device */ | 730 | /* link in the class directory pointing to the device */ |
| 793 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, | 731 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, |
| 794 | &dev->kobj, dev_name(dev)); | 732 | &dev->kobj, dev_name(dev)); |
| 795 | if (error) | 733 | if (error) |
| 796 | goto out_subsys; | 734 | goto out_device; |
| 797 | 735 | ||
| 798 | if (dev->parent && device_is_not_partition(dev)) { | ||
| 799 | error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, | ||
| 800 | "device"); | ||
| 801 | if (error) | ||
| 802 | goto out_busid; | ||
| 803 | } | ||
| 804 | return 0; | 736 | return 0; |
| 805 | 737 | ||
| 806 | out_busid: | 738 | out_device: |
| 807 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | 739 | sysfs_remove_link(&dev->kobj, "device"); |
| 808 | #endif | ||
| 809 | 740 | ||
| 810 | out_subsys: | 741 | out_subsys: |
| 811 | sysfs_remove_link(&dev->kobj, "subsystem"); | 742 | sysfs_remove_link(&dev->kobj, "subsystem"); |
| @@ -818,30 +749,14 @@ static void device_remove_class_symlinks(struct device *dev) | |||
| 818 | if (!dev->class) | 749 | if (!dev->class) |
| 819 | return; | 750 | return; |
| 820 | 751 | ||
| 821 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 822 | if (dev->parent && device_is_not_partition(dev)) { | ||
| 823 | char *class_name; | ||
| 824 | |||
| 825 | class_name = make_class_name(dev->class->name, &dev->kobj); | ||
| 826 | if (class_name) { | ||
| 827 | sysfs_remove_link(&dev->parent->kobj, class_name); | ||
| 828 | kfree(class_name); | ||
| 829 | } | ||
| 830 | sysfs_remove_link(&dev->kobj, "device"); | ||
| 831 | } | ||
| 832 | |||
| 833 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && | ||
| 834 | device_is_not_partition(dev)) | ||
| 835 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, | ||
| 836 | dev_name(dev)); | ||
| 837 | #else | ||
| 838 | if (dev->parent && device_is_not_partition(dev)) | 752 | if (dev->parent && device_is_not_partition(dev)) |
| 839 | sysfs_remove_link(&dev->kobj, "device"); | 753 | sysfs_remove_link(&dev->kobj, "device"); |
| 840 | |||
| 841 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | ||
| 842 | #endif | ||
| 843 | |||
| 844 | sysfs_remove_link(&dev->kobj, "subsystem"); | 754 | sysfs_remove_link(&dev->kobj, "subsystem"); |
| 755 | #ifdef CONFIG_BLOCK | ||
| 756 | if (sysfs_deprecated && dev->class == &block_class) | ||
| 757 | return; | ||
| 758 | #endif | ||
| 759 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | ||
| 845 | } | 760 | } |
| 846 | 761 | ||
| 847 | /** | 762 | /** |
| @@ -1613,41 +1528,23 @@ int device_rename(struct device *dev, const char *new_name) | |||
| 1613 | pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev), | 1528 | pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev), |
| 1614 | __func__, new_name); | 1529 | __func__, new_name); |
| 1615 | 1530 | ||
| 1616 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 1617 | if ((dev->class) && (dev->parent)) | ||
| 1618 | old_class_name = make_class_name(dev->class->name, &dev->kobj); | ||
| 1619 | #endif | ||
| 1620 | |||
| 1621 | old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); | 1531 | old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); |
| 1622 | if (!old_device_name) { | 1532 | if (!old_device_name) { |
| 1623 | error = -ENOMEM; | 1533 | error = -ENOMEM; |
| 1624 | goto out; | 1534 | goto out; |
| 1625 | } | 1535 | } |
| 1626 | 1536 | ||
| 1627 | #ifndef CONFIG_SYSFS_DEPRECATED | ||
| 1628 | if (dev->class) { | 1537 | if (dev->class) { |
| 1629 | error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, | 1538 | error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, |
| 1630 | &dev->kobj, old_device_name, new_name); | 1539 | &dev->kobj, old_device_name, new_name); |
| 1631 | if (error) | 1540 | if (error) |
| 1632 | goto out; | 1541 | goto out; |
| 1633 | } | 1542 | } |
| 1634 | #endif | 1543 | |
| 1635 | error = kobject_rename(&dev->kobj, new_name); | 1544 | error = kobject_rename(&dev->kobj, new_name); |
| 1636 | if (error) | 1545 | if (error) |
| 1637 | goto out; | 1546 | goto out; |
| 1638 | 1547 | ||
| 1639 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 1640 | if (old_class_name) { | ||
| 1641 | new_class_name = make_class_name(dev->class->name, &dev->kobj); | ||
| 1642 | if (new_class_name) { | ||
| 1643 | error = sysfs_rename_link(&dev->parent->kobj, | ||
| 1644 | &dev->kobj, | ||
| 1645 | old_class_name, | ||
| 1646 | new_class_name); | ||
| 1647 | } | ||
| 1648 | } | ||
| 1649 | #endif | ||
| 1650 | |||
| 1651 | out: | 1548 | out: |
| 1652 | put_device(dev); | 1549 | put_device(dev); |
| 1653 | 1550 | ||
| @@ -1664,40 +1561,13 @@ static int device_move_class_links(struct device *dev, | |||
| 1664 | struct device *new_parent) | 1561 | struct device *new_parent) |
| 1665 | { | 1562 | { |
| 1666 | int error = 0; | 1563 | int error = 0; |
| 1667 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
| 1668 | char *class_name; | ||
| 1669 | 1564 | ||
| 1670 | class_name = make_class_name(dev->class->name, &dev->kobj); | ||
| 1671 | if (!class_name) { | ||
| 1672 | error = -ENOMEM; | ||
| 1673 | goto out; | ||
| 1674 | } | ||
| 1675 | if (old_parent) { | ||
| 1676 | sysfs_remove_link(&dev->kobj, "device"); | ||
| 1677 | sysfs_remove_link(&old_parent->kobj, class_name); | ||
| 1678 | } | ||
| 1679 | if (new_parent) { | ||
| 1680 | error = sysfs_create_link(&dev->kobj, &new_parent->kobj, | ||
| 1681 | "device"); | ||
| 1682 | if (error) | ||
| 1683 | goto out; | ||
| 1684 | error = sysfs_create_link(&new_parent->kobj, &dev->kobj, | ||
| 1685 | class_name); | ||
| 1686 | if (error) | ||
| 1687 | sysfs_remove_link(&dev->kobj, "device"); | ||
| 1688 | } else | ||
| 1689 | error = 0; | ||
| 1690 | out: | ||
| 1691 | kfree(class_name); | ||
| 1692 | return error; | ||
| 1693 | #else | ||
| 1694 | if (old_parent) | 1565 | if (old_parent) |
| 1695 | sysfs_remove_link(&dev->kobj, "device"); | 1566 | sysfs_remove_link(&dev->kobj, "device"); |
| 1696 | if (new_parent) | 1567 | if (new_parent) |
| 1697 | error = sysfs_create_link(&dev->kobj, &new_parent->kobj, | 1568 | error = sysfs_create_link(&dev->kobj, &new_parent->kobj, |
| 1698 | "device"); | 1569 | "device"); |
| 1699 | return error; | 1570 | return error; |
| 1700 | #endif | ||
| 1701 | } | 1571 | } |
| 1702 | 1572 | ||
| 1703 | /** | 1573 | /** |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 933442f40321..cafeaaf0428f 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #include <asm/atomic.h> | 27 | #include <asm/atomic.h> |
| 28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
| 29 | 29 | ||
| 30 | static DEFINE_MUTEX(mem_sysfs_mutex); | ||
| 31 | |||
| 30 | #define MEMORY_CLASS_NAME "memory" | 32 | #define MEMORY_CLASS_NAME "memory" |
| 31 | 33 | ||
| 32 | static struct sysdev_class memory_sysdev_class = { | 34 | static struct sysdev_class memory_sysdev_class = { |
| @@ -435,6 +437,45 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn) | |||
| 435 | return 0; | 437 | return 0; |
| 436 | } | 438 | } |
| 437 | 439 | ||
| 440 | struct memory_block *find_memory_block_hinted(struct mem_section *section, | ||
| 441 | struct memory_block *hint) | ||
| 442 | { | ||
| 443 | struct kobject *kobj; | ||
| 444 | struct sys_device *sysdev; | ||
| 445 | struct memory_block *mem; | ||
| 446 | char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; | ||
| 447 | |||
| 448 | kobj = hint ? &hint->sysdev.kobj : NULL; | ||
| 449 | |||
| 450 | /* | ||
| 451 | * This only works because we know that section == sysdev->id | ||
| 452 | * slightly redundant with sysdev_register() | ||
| 453 | */ | ||
| 454 | sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section)); | ||
| 455 | |||
| 456 | kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj); | ||
| 457 | if (!kobj) | ||
| 458 | return NULL; | ||
| 459 | |||
| 460 | sysdev = container_of(kobj, struct sys_device, kobj); | ||
| 461 | mem = container_of(sysdev, struct memory_block, sysdev); | ||
| 462 | |||
| 463 | return mem; | ||
| 464 | } | ||
| 465 | |||
| 466 | /* | ||
| 467 | * For now, we have a linear search to go find the appropriate | ||
| 468 | * memory_block corresponding to a particular phys_index. If | ||
| 469 | * this gets to be a real problem, we can always use a radix | ||
| 470 | * tree or something here. | ||
| 471 | * | ||
| 472 | * This could be made generic for all sysdev classes. | ||
| 473 | */ | ||
| 474 | struct memory_block *find_memory_block(struct mem_section *section) | ||
| 475 | { | ||
| 476 | return find_memory_block_hinted(section, NULL); | ||
| 477 | } | ||
| 478 | |||
| 438 | static int add_memory_block(int nid, struct mem_section *section, | 479 | static int add_memory_block(int nid, struct mem_section *section, |
| 439 | unsigned long state, enum mem_add_context context) | 480 | unsigned long state, enum mem_add_context context) |
| 440 | { | 481 | { |
| @@ -445,8 +486,11 @@ static int add_memory_block(int nid, struct mem_section *section, | |||
| 445 | if (!mem) | 486 | if (!mem) |
| 446 | return -ENOMEM; | 487 | return -ENOMEM; |
| 447 | 488 | ||
| 489 | mutex_lock(&mem_sysfs_mutex); | ||
| 490 | |||
| 448 | mem->phys_index = __section_nr(section); | 491 | mem->phys_index = __section_nr(section); |
| 449 | mem->state = state; | 492 | mem->state = state; |
| 493 | mem->section_count++; | ||
| 450 | mutex_init(&mem->state_mutex); | 494 | mutex_init(&mem->state_mutex); |
| 451 | start_pfn = section_nr_to_pfn(mem->phys_index); | 495 | start_pfn = section_nr_to_pfn(mem->phys_index); |
| 452 | mem->phys_device = arch_get_memory_phys_device(start_pfn); | 496 | mem->phys_device = arch_get_memory_phys_device(start_pfn); |
| @@ -465,53 +509,29 @@ static int add_memory_block(int nid, struct mem_section *section, | |||
| 465 | ret = register_mem_sect_under_node(mem, nid); | 509 | ret = register_mem_sect_under_node(mem, nid); |
| 466 | } | 510 | } |
| 467 | 511 | ||
| 512 | mutex_unlock(&mem_sysfs_mutex); | ||
| 468 | return ret; | 513 | return ret; |
| 469 | } | 514 | } |
| 470 | 515 | ||
| 471 | /* | ||
| 472 | * For now, we have a linear search to go find the appropriate | ||
| 473 | * memory_block corresponding to a particular phys_index. If | ||
| 474 | * this gets to be a real problem, we can always use a radix | ||
| 475 | * tree or something here. | ||
| 476 | * | ||
| 477 | * This could be made generic for all sysdev classes. | ||
| 478 | */ | ||
| 479 | struct memory_block *find_memory_block(struct mem_section *section) | ||
| 480 | { | ||
| 481 | struct kobject *kobj; | ||
| 482 | struct sys_device *sysdev; | ||
| 483 | struct memory_block *mem; | ||
| 484 | char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; | ||
| 485 | |||
| 486 | /* | ||
| 487 | * This only works because we know that section == sysdev->id | ||
| 488 | * slightly redundant with sysdev_register() | ||
| 489 | */ | ||
| 490 | sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section)); | ||
| 491 | |||
| 492 | kobj = kset_find_obj(&memory_sysdev_class.kset, name); | ||
| 493 | if (!kobj) | ||
| 494 | return NULL; | ||
| 495 | |||
| 496 | sysdev = container_of(kobj, struct sys_device, kobj); | ||
| 497 | mem = container_of(sysdev, struct memory_block, sysdev); | ||
| 498 | |||
| 499 | return mem; | ||
| 500 | } | ||
| 501 | |||
| 502 | int remove_memory_block(unsigned long node_id, struct mem_section *section, | 516 | int remove_memory_block(unsigned long node_id, struct mem_section *section, |
| 503 | int phys_device) | 517 | int phys_device) |
| 504 | { | 518 | { |
| 505 | struct memory_block *mem; | 519 | struct memory_block *mem; |
| 506 | 520 | ||
| 521 | mutex_lock(&mem_sysfs_mutex); | ||
| 507 | mem = find_memory_block(section); | 522 | mem = find_memory_block(section); |
| 508 | unregister_mem_sect_under_nodes(mem); | ||
| 509 | mem_remove_simple_file(mem, phys_index); | ||
| 510 | mem_remove_simple_file(mem, state); | ||
| 511 | mem_remove_simple_file(mem, phys_device); | ||
| 512 | mem_remove_simple_file(mem, removable); | ||
| 513 | unregister_memory(mem, section); | ||
| 514 | 523 | ||
| 524 | mem->section_count--; | ||
| 525 | if (mem->section_count == 0) { | ||
| 526 | unregister_mem_sect_under_nodes(mem); | ||
| 527 | mem_remove_simple_file(mem, phys_index); | ||
| 528 | mem_remove_simple_file(mem, state); | ||
| 529 | mem_remove_simple_file(mem, phys_device); | ||
| 530 | mem_remove_simple_file(mem, removable); | ||
| 531 | unregister_memory(mem, section); | ||
| 532 | } | ||
| 533 | |||
| 534 | mutex_unlock(&mem_sysfs_mutex); | ||
| 515 | return 0; | 535 | return 0; |
| 516 | } | 536 | } |
| 517 | 537 | ||
diff --git a/drivers/base/node.c b/drivers/base/node.c index 2872e86837b2..ee53558b452f 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
| @@ -409,25 +409,27 @@ static int link_mem_sections(int nid) | |||
| 409 | unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; | 409 | unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; |
| 410 | unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; | 410 | unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; |
| 411 | unsigned long pfn; | 411 | unsigned long pfn; |
| 412 | struct memory_block *mem_blk = NULL; | ||
| 412 | int err = 0; | 413 | int err = 0; |
| 413 | 414 | ||
| 414 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { | 415 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { |
| 415 | unsigned long section_nr = pfn_to_section_nr(pfn); | 416 | unsigned long section_nr = pfn_to_section_nr(pfn); |
| 416 | struct mem_section *mem_sect; | 417 | struct mem_section *mem_sect; |
| 417 | struct memory_block *mem_blk; | ||
| 418 | int ret; | 418 | int ret; |
| 419 | 419 | ||
| 420 | if (!present_section_nr(section_nr)) | 420 | if (!present_section_nr(section_nr)) |
| 421 | continue; | 421 | continue; |
| 422 | mem_sect = __nr_to_section(section_nr); | 422 | mem_sect = __nr_to_section(section_nr); |
| 423 | mem_blk = find_memory_block(mem_sect); | 423 | mem_blk = find_memory_block_hinted(mem_sect, mem_blk); |
| 424 | ret = register_mem_sect_under_node(mem_blk, nid); | 424 | ret = register_mem_sect_under_node(mem_blk, nid); |
| 425 | if (!err) | 425 | if (!err) |
| 426 | err = ret; | 426 | err = ret; |
| 427 | 427 | ||
| 428 | /* discard ref obtained in find_memory_block() */ | 428 | /* discard ref obtained in find_memory_block() */ |
| 429 | kobject_put(&mem_blk->sysdev.kobj); | ||
| 430 | } | 429 | } |
| 430 | |||
| 431 | if (mem_blk) | ||
| 432 | kobject_put(&mem_blk->sysdev.kobj); | ||
| 431 | return err; | 433 | return err; |
| 432 | } | 434 | } |
| 433 | 435 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c6c933f58102..3966e62ad019 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -192,6 +192,9 @@ int platform_device_add_resources(struct platform_device *pdev, | |||
| 192 | { | 192 | { |
| 193 | struct resource *r; | 193 | struct resource *r; |
| 194 | 194 | ||
| 195 | if (!res) | ||
| 196 | return 0; | ||
| 197 | |||
| 195 | r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); | 198 | r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); |
| 196 | if (r) { | 199 | if (r) { |
| 197 | pdev->resource = r; | 200 | pdev->resource = r; |
| @@ -215,8 +218,12 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources); | |||
| 215 | int platform_device_add_data(struct platform_device *pdev, const void *data, | 218 | int platform_device_add_data(struct platform_device *pdev, const void *data, |
| 216 | size_t size) | 219 | size_t size) |
| 217 | { | 220 | { |
| 218 | void *d = kmemdup(data, size, GFP_KERNEL); | 221 | void *d; |
| 222 | |||
| 223 | if (!data) | ||
| 224 | return 0; | ||
| 219 | 225 | ||
| 226 | d = kmemdup(data, size, GFP_KERNEL); | ||
| 220 | if (d) { | 227 | if (d) { |
| 221 | pdev->dev.platform_data = d; | 228 | pdev->dev.platform_data = d; |
| 222 | return 0; | 229 | return 0; |
| @@ -373,17 +380,13 @@ struct platform_device *__init_or_module platform_device_register_resndata( | |||
| 373 | 380 | ||
| 374 | pdev->dev.parent = parent; | 381 | pdev->dev.parent = parent; |
| 375 | 382 | ||
| 376 | if (res) { | 383 | ret = platform_device_add_resources(pdev, res, num); |
| 377 | ret = platform_device_add_resources(pdev, res, num); | 384 | if (ret) |
| 378 | if (ret) | 385 | goto err; |
| 379 | goto err; | ||
| 380 | } | ||
| 381 | 386 | ||
| 382 | if (data) { | 387 | ret = platform_device_add_data(pdev, data, size); |
| 383 | ret = platform_device_add_data(pdev, data, size); | 388 | if (ret) |
| 384 | if (ret) | 389 | goto err; |
| 385 | goto err; | ||
| 386 | } | ||
| 387 | 390 | ||
| 388 | ret = platform_device_add(pdev); | 391 | ret = platform_device_add(pdev); |
| 389 | if (ret) { | 392 | if (ret) { |
| @@ -488,12 +491,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, | |||
| 488 | * if the probe was successful, and make sure any forced probes of | 491 | * if the probe was successful, and make sure any forced probes of |
| 489 | * new devices fail. | 492 | * new devices fail. |
| 490 | */ | 493 | */ |
| 491 | spin_lock(&platform_bus_type.p->klist_drivers.k_lock); | 494 | spin_lock(&drv->driver.bus->p->klist_drivers.k_lock); |
| 492 | drv->probe = NULL; | 495 | drv->probe = NULL; |
| 493 | if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) | 496 | if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) |
| 494 | retval = -ENODEV; | 497 | retval = -ENODEV; |
| 495 | drv->driver.probe = platform_drv_probe_fail; | 498 | drv->driver.probe = platform_drv_probe_fail; |
| 496 | spin_unlock(&platform_bus_type.p->klist_drivers.k_lock); | 499 | spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock); |
| 497 | 500 | ||
| 498 | if (code != retval) | 501 | if (code != retval) |
| 499 | platform_driver_unregister(drv); | 502 | platform_driver_unregister(drv); |
| @@ -530,17 +533,13 @@ struct platform_device * __init_or_module platform_create_bundle( | |||
| 530 | goto err_out; | 533 | goto err_out; |
| 531 | } | 534 | } |
| 532 | 535 | ||
| 533 | if (res) { | 536 | error = platform_device_add_resources(pdev, res, n_res); |
| 534 | error = platform_device_add_resources(pdev, res, n_res); | 537 | if (error) |
| 535 | if (error) | 538 | goto err_pdev_put; |
| 536 | goto err_pdev_put; | ||
| 537 | } | ||
| 538 | 539 | ||
| 539 | if (data) { | 540 | error = platform_device_add_data(pdev, data, size); |
| 540 | error = platform_device_add_data(pdev, data, size); | 541 | if (error) |
| 541 | if (error) | 542 | goto err_pdev_put; |
| 542 | goto err_pdev_put; | ||
| 543 | } | ||
| 544 | 543 | ||
| 545 | error = platform_device_add(pdev); | 544 | error = platform_device_add(pdev); |
| 546 | if (error) | 545 | if (error) |
| @@ -976,6 +975,41 @@ struct bus_type platform_bus_type = { | |||
| 976 | }; | 975 | }; |
| 977 | EXPORT_SYMBOL_GPL(platform_bus_type); | 976 | EXPORT_SYMBOL_GPL(platform_bus_type); |
| 978 | 977 | ||
| 978 | /** | ||
| 979 | * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops | ||
| 980 | * | ||
| 981 | * This function can be used by platform code to get the current | ||
| 982 | * set of dev_pm_ops functions used by the platform_bus_type. | ||
| 983 | */ | ||
| 984 | const struct dev_pm_ops * __init platform_bus_get_pm_ops(void) | ||
| 985 | { | ||
| 986 | return platform_bus_type.pm; | ||
| 987 | } | ||
| 988 | |||
| 989 | /** | ||
| 990 | * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type | ||
| 991 | * | ||
| 992 | * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type | ||
| 993 | * | ||
| 994 | * Platform code can override the dev_pm_ops methods of | ||
| 995 | * platform_bus_type by using this function. It is expected that | ||
| 996 | * platform code will first do a platform_bus_get_pm_ops(), then | ||
| 997 | * kmemdup it, then customize selected methods and pass a pointer to | ||
| 998 | * the new struct dev_pm_ops to this function. | ||
| 999 | * | ||
| 1000 | * Since platform-specific code is customizing methods for *all* | ||
| 1001 | * devices (not just platform-specific devices) it is expected that | ||
| 1002 | * any custom overrides of these functions will keep existing behavior | ||
| 1003 | * and simply extend it. For example, any customization of the | ||
| 1004 | * runtime PM methods should continue to call the pm_generic_* | ||
| 1005 | * functions as the default ones do in addition to the | ||
| 1006 | * platform-specific behavior. | ||
| 1007 | */ | ||
| 1008 | void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm) | ||
| 1009 | { | ||
| 1010 | platform_bus_type.pm = pm; | ||
| 1011 | } | ||
| 1012 | |||
| 979 | int __init platform_bus_init(void) | 1013 | int __init platform_bus_init(void) |
| 980 | { | 1014 | { |
| 981 | int error; | 1015 | int error; |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 9354dc10a363..1667aaf4fde6 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
| @@ -432,13 +432,13 @@ int sysdev_suspend(pm_message_t state) | |||
| 432 | /* resume current sysdev */ | 432 | /* resume current sysdev */ |
| 433 | cls_driver: | 433 | cls_driver: |
| 434 | drv = NULL; | 434 | drv = NULL; |
| 435 | printk(KERN_ERR "Class suspend failed for %s\n", | 435 | printk(KERN_ERR "Class suspend failed for %s: %d\n", |
| 436 | kobject_name(&sysdev->kobj)); | 436 | kobject_name(&sysdev->kobj), ret); |
| 437 | 437 | ||
| 438 | aux_driver: | 438 | aux_driver: |
| 439 | if (drv) | 439 | if (drv) |
| 440 | printk(KERN_ERR "Class driver suspend failed for %s\n", | 440 | printk(KERN_ERR "Class driver suspend failed for %s: %d\n", |
| 441 | kobject_name(&sysdev->kobj)); | 441 | kobject_name(&sysdev->kobj), ret); |
| 442 | list_for_each_entry(err_drv, &cls->drivers, entry) { | 442 | list_for_each_entry(err_drv, &cls->drivers, entry) { |
| 443 | if (err_drv == drv) | 443 | if (err_drv == drv) |
| 444 | break; | 444 | break; |
