aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2012-03-05 10:47:41 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-08 14:53:13 -0500
commitd1c3414c2a9d10ef7f0f7665f5d2947cd088c093 (patch)
treebd33518d50f23adc2e55e7b4c99b6b1753a41a03 /drivers/base/core.c
parentfef37e9a47b9927ce2817fe1a0fa8cf40f6eefb6 (diff)
drivercore: Add driver probe deferral mechanism
Allow drivers to report at probe time that they cannot get all the resources required by the device, and should be retried at a later time. This should completely solve the problem of getting devices initialized in the right order. Right now this is mostly handled by mucking about with initcall ordering which is a complete hack, and doesn't even remotely handle the case where device drivers are in modules. This approach completely sidesteps the issues by allowing driver registration to occur in any order, and any driver can request to be retried after a few more other drivers get probed. v4: - Integrate Manjunath's addition of a separate workqueue - Change -EAGAIN to -EPROBE_DEFER for drivers to trigger deferral - Update comment blocks to reflect how the code really works v3: - Hold off workqueue scheduling until late_initcall so that the bulk of driver probes are complete before we start retrying deferred devices. - Tested with simple use cases. Still needs more testing though. Using it to get rid of the gpio early_initcall madness, or to replace the ASoC internal probe deferral code would be ideal. v2: - added locking so it should no longer be utterly broken in that regard - remove device from deferred list at device_del time. - Still completely untested with any real use case, but has been boot tested. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Dilan Lee <dilee@nvidia.com> Cc: Manjunath GKondaiah <manjunath.gkondaiah@linaro.org> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Tony Lindgren <tony@atomide.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: David Daney <david.daney@cavium.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 74dda4f697f9..d4ff7adce38c 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -644,6 +644,7 @@ void device_initialize(struct device *dev)
644{ 644{
645 dev->kobj.kset = devices_kset; 645 dev->kobj.kset = devices_kset;
646 kobject_init(&dev->kobj, &device_ktype); 646 kobject_init(&dev->kobj, &device_ktype);
647 INIT_LIST_HEAD(&dev->deferred_probe);
647 INIT_LIST_HEAD(&dev->dma_pools); 648 INIT_LIST_HEAD(&dev->dma_pools);
648 mutex_init(&dev->mutex); 649 mutex_init(&dev->mutex);
649 lockdep_set_novalidate_class(&dev->mutex); 650 lockdep_set_novalidate_class(&dev->mutex);
@@ -1188,6 +1189,7 @@ void device_del(struct device *dev)
1188 device_remove_file(dev, &uevent_attr); 1189 device_remove_file(dev, &uevent_attr);
1189 device_remove_attrs(dev); 1190 device_remove_attrs(dev);
1190 bus_remove_device(dev); 1191 bus_remove_device(dev);
1192 driver_deferred_probe_del(dev);
1191 1193
1192 /* 1194 /*
1193 * Some platform devices are driven without driver attached 1195 * Some platform devices are driven without driver attached