diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-12-01 09:56:43 +0000 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-12-01 09:56:43 +0000 |
commit | bd3c97a7c718bfb9f1e4f31c16c383a5c6f815eb (patch) | |
tree | 3f56594e813c6f35cbacbdb3e137ba5bfd0b3069 /drivers/base | |
parent | 6c33cafc794d07c9254c160789120a0e98c088c9 (diff) | |
parent | 0215ffb08ce99e2bb59eca114a99499a4d06e704 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/Kconfig | 4 | ||||
-rw-r--r-- | drivers/base/core.c | 4 | ||||
-rw-r--r-- | drivers/base/dd.c | 30 |
3 files changed, 35 insertions, 3 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 0b4e2243693..1429f3a2629 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -37,8 +37,8 @@ config DEBUG_DRIVER If you are unsure about this, say N here. -endmenu - config SYS_HYPERVISOR bool default n + +endmenu diff --git a/drivers/base/core.c b/drivers/base/core.c index 68ad11af22b..002fde46d38 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -591,8 +591,10 @@ void device_del(struct device * dev) if (parent) klist_del(&dev->knode_parent); - if (dev->devt_attr) + if (dev->devt_attr) { device_remove_file(dev, dev->devt_attr); + kfree(dev->devt_attr); + } if (dev->class) { sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index db01b95a47a..c5d6bb4290a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -18,6 +18,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/kthread.h> +#include <linux/wait.h> #include "base.h" #include "power/power.h" @@ -70,6 +71,8 @@ struct stupid_thread_structure { }; static atomic_t probe_count = ATOMIC_INIT(0); +static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); + static int really_probe(void *void_data) { struct stupid_thread_structure *data = void_data; @@ -121,6 +124,7 @@ probe_failed: done: kfree(data); atomic_dec(&probe_count); + wake_up(&probe_waitqueue); return ret; } @@ -337,6 +341,32 @@ void driver_detach(struct device_driver * drv) } } +#ifdef CONFIG_PCI_MULTITHREAD_PROBE +static int __init wait_for_probes(void) +{ + DEFINE_WAIT(wait); + + printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__, + atomic_read(&probe_count)); + if (!atomic_read(&probe_count)) + return 0; + while (atomic_read(&probe_count)) { + prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE); + if (atomic_read(&probe_count)) + schedule(); + } + finish_wait(&probe_waitqueue, &wait); + return 0; +} + +core_initcall_sync(wait_for_probes); +postcore_initcall_sync(wait_for_probes); +arch_initcall_sync(wait_for_probes); +subsys_initcall_sync(wait_for_probes); +fs_initcall_sync(wait_for_probes); +device_initcall_sync(wait_for_probes); +late_initcall_sync(wait_for_probes); +#endif EXPORT_SYMBOL_GPL(device_bind_driver); EXPORT_SYMBOL_GPL(device_release_driver); |