aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/dd.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index c17fefc77345..ad44b40fe284 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -20,6 +20,7 @@
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/dma-mapping.h> 22#include <linux/dma-mapping.h>
23#include <linux/init.h>
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/kthread.h> 25#include <linux/kthread.h>
25#include <linux/wait.h> 26#include <linux/wait.h>
@@ -53,6 +54,7 @@ static DEFINE_MUTEX(deferred_probe_mutex);
53static LIST_HEAD(deferred_probe_pending_list); 54static LIST_HEAD(deferred_probe_pending_list);
54static LIST_HEAD(deferred_probe_active_list); 55static LIST_HEAD(deferred_probe_active_list);
55static atomic_t deferred_trigger_count = ATOMIC_INIT(0); 56static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
57static bool initcalls_done;
56 58
57/* 59/*
58 * In some cases, like suspend to RAM or hibernation, It might be reasonable 60 * In some cases, like suspend to RAM or hibernation, It might be reasonable
@@ -62,6 +64,26 @@ static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
62static bool defer_all_probes; 64static bool defer_all_probes;
63 65
64/* 66/*
67 * For initcall_debug, show the deferred probes executed in late_initcall
68 * processing.
69 */
70static void deferred_probe_debug(struct device *dev)
71{
72 ktime_t calltime, delta, rettime;
73 unsigned long long duration;
74
75 printk(KERN_DEBUG "deferred probe %s @ %i\n", dev_name(dev),
76 task_pid_nr(current));
77 calltime = ktime_get();
78 bus_probe_device(dev);
79 rettime = ktime_get();
80 delta = ktime_sub(rettime, calltime);
81 duration = (unsigned long long) ktime_to_ns(delta) >> 10;
82 printk(KERN_DEBUG "deferred probe %s returned after %lld usecs\n",
83 dev_name(dev), duration);
84}
85
86/*
65 * deferred_probe_work_func() - Retry probing devices in the active list. 87 * deferred_probe_work_func() - Retry probing devices in the active list.
66 */ 88 */
67static void deferred_probe_work_func(struct work_struct *work) 89static void deferred_probe_work_func(struct work_struct *work)
@@ -106,7 +128,10 @@ static void deferred_probe_work_func(struct work_struct *work)
106 device_pm_unlock(); 128 device_pm_unlock();
107 129
108 dev_dbg(dev, "Retrying from deferred list\n"); 130 dev_dbg(dev, "Retrying from deferred list\n");
109 bus_probe_device(dev); 131 if (initcall_debug && !initcalls_done)
132 deferred_probe_debug(dev);
133 else
134 bus_probe_device(dev);
110 135
111 mutex_lock(&deferred_probe_mutex); 136 mutex_lock(&deferred_probe_mutex);
112 137
@@ -215,6 +240,7 @@ static int deferred_probe_initcall(void)
215 driver_deferred_probe_trigger(); 240 driver_deferred_probe_trigger();
216 /* Sort as many dependencies as possible before exiting initcalls */ 241 /* Sort as many dependencies as possible before exiting initcalls */
217 flush_work(&deferred_probe_work); 242 flush_work(&deferred_probe_work);
243 initcalls_done = true;
218 return 0; 244 return 0;
219} 245}
220late_initcall(deferred_probe_initcall); 246late_initcall(deferred_probe_initcall);