aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/Kconfig1
-rw-r--r--drivers/base/Makefile4
-rw-r--r--drivers/base/bus.c22
-rw-r--r--drivers/base/class.c23
-rw-r--r--drivers/base/core.c208
-rw-r--r--drivers/base/memory.c94
-rw-r--r--drivers/base/node.c8
-rw-r--r--drivers/base/platform.c80
-rw-r--r--drivers/base/sys.c8
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
72config FW_LOADER 72config 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
19endif 19endif
20obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o 20obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
21 21
22ifeq ($(CONFIG_DEBUG_DRIVER),y) 22ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
23EXTRA_CFLAGS += -DDEBUG
24endif
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
444static 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
450static void remove_deprecated_bus_links(struct device *dev)
451{
452 sysfs_remove_link(&dev->kobj, "bus");
453}
454#else
455static inline int make_deprecated_bus_links(struct device *dev) { return 0; }
456static 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
492out_deprecated:
493 sysfs_remove_link(&dev->kobj, "subsystem");
494out_subsys: 473out_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));
496out_id: 475out_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
280char *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
31long sysfs_deprecated = 1;
32#else
33long sysfs_deprecated = 0;
34#endif
35static __init int sysfs_deprecated_setup(char *arg)
36{
37 return strict_strtol(arg, 10, &sysfs_deprecated);
38}
39early_param("sysfs.deprecated", sysfs_deprecated_setup);
40#endif
41
29int (*platform_notify)(struct device *dev) = NULL; 42int (*platform_notify)(struct device *dev) = NULL;
30int (*platform_notify_remove)(struct device *dev) = NULL; 43int (*platform_notify_remove)(struct device *dev) = NULL;
31static struct kobject *dev_kobj; 44static 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
582static 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
595static inline void cleanup_device_parent(struct device *dev) {}
596static inline void cleanup_glue_dir(struct device *dev,
597 struct kobject *glue_dir) {}
598#else
599static struct kobject *virtual_device_parent(struct device *dev) 563static 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
724static void setup_parent(struct device *dev, struct device *parent) 696static 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
783out_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)
786out_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
806out_busid: 738out_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
810out_subsys: 741out_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
1651out: 1548out:
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;
1690out:
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
30static DEFINE_MUTEX(mem_sysfs_mutex);
31
30#define MEMORY_CLASS_NAME "memory" 32#define MEMORY_CLASS_NAME "memory"
31 33
32static struct sysdev_class memory_sysdev_class = { 34static 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
440struct 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 */
474struct memory_block *find_memory_block(struct mem_section *section)
475{
476 return find_memory_block_hinted(section, NULL);
477}
478
438static int add_memory_block(int nid, struct mem_section *section, 479static 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 */
479struct 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
502int remove_memory_block(unsigned long node_id, struct mem_section *section, 516int 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);
215int platform_device_add_data(struct platform_device *pdev, const void *data, 218int 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};
977EXPORT_SYMBOL_GPL(platform_bus_type); 976EXPORT_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 */
984const 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 */
1008void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
1009{
1010 platform_bus_type.pm = pm;
1011}
1012
979int __init platform_bus_init(void) 1013int __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 */
433cls_driver: 433cls_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
438aux_driver: 438aux_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;