aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/dd.c55
-rw-r--r--drivers/pinctrl/devicetree.c7
-rw-r--r--include/linux/device.h1
3 files changed, 51 insertions, 12 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0df9b4461766..994a90747420 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -235,6 +235,19 @@ static int __init deferred_probe_timeout_setup(char *str)
235} 235}
236__setup("deferred_probe_timeout=", deferred_probe_timeout_setup); 236__setup("deferred_probe_timeout=", deferred_probe_timeout_setup);
237 237
238static int __driver_deferred_probe_check_state(struct device *dev)
239{
240 if (!initcalls_done)
241 return -EPROBE_DEFER;
242
243 if (!deferred_probe_timeout) {
244 dev_WARN(dev, "deferred probe timeout, ignoring dependency");
245 return -ETIMEDOUT;
246 }
247
248 return 0;
249}
250
238/** 251/**
239 * driver_deferred_probe_check_state() - Check deferred probe state 252 * driver_deferred_probe_check_state() - Check deferred probe state
240 * @dev: device to check 253 * @dev: device to check
@@ -248,14 +261,40 @@ __setup("deferred_probe_timeout=", deferred_probe_timeout_setup);
248 */ 261 */
249int driver_deferred_probe_check_state(struct device *dev) 262int driver_deferred_probe_check_state(struct device *dev)
250{ 263{
251 if (initcalls_done) { 264 int ret;
252 if (!deferred_probe_timeout) { 265
253 dev_WARN(dev, "deferred probe timeout, ignoring dependency"); 266 ret = __driver_deferred_probe_check_state(dev);
254 return -ETIMEDOUT; 267 if (ret < 0)
255 } 268 return ret;
256 dev_warn(dev, "ignoring dependency for device, assuming no driver"); 269
257 return -ENODEV; 270 dev_warn(dev, "ignoring dependency for device, assuming no driver");
258 } 271
272 return -ENODEV;
273}
274
275/**
276 * driver_deferred_probe_check_state_continue() - check deferred probe state
277 * @dev: device to check
278 *
279 * Returns -ETIMEDOUT if deferred probe debug timeout has expired, or
280 * -EPROBE_DEFER otherwise.
281 *
282 * Drivers or subsystems can opt-in to calling this function instead of
283 * directly returning -EPROBE_DEFER.
284 *
285 * This is similar to driver_deferred_probe_check_state(), but it allows the
286 * subsystem to keep deferring probe after built-in drivers have had a chance
287 * to probe. One scenario where that is useful is if built-in drivers rely on
288 * resources that are provided by modular drivers.
289 */
290int driver_deferred_probe_check_state_continue(struct device *dev)
291{
292 int ret;
293
294 ret = __driver_deferred_probe_check_state(dev);
295 if (ret < 0)
296 return ret;
297
259 return -EPROBE_DEFER; 298 return -EPROBE_DEFER;
260} 299}
261 300
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index f7e354f85518..88ddbb2e30de 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -112,12 +112,11 @@ static int dt_to_map_one_config(struct pinctrl *p,
112 np_pctldev = of_get_next_parent(np_pctldev); 112 np_pctldev = of_get_next_parent(np_pctldev);
113 if (!np_pctldev || of_node_is_root(np_pctldev)) { 113 if (!np_pctldev || of_node_is_root(np_pctldev)) {
114 of_node_put(np_pctldev); 114 of_node_put(np_pctldev);
115 ret = driver_deferred_probe_check_state(p->dev);
116 /* keep deferring if modules are enabled unless we've timed out */ 115 /* keep deferring if modules are enabled unless we've timed out */
117 if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret == -ENODEV) 116 if (IS_ENABLED(CONFIG_MODULES) && !allow_default)
118 ret = -EPROBE_DEFER; 117 return driver_deferred_probe_check_state_continue(p->dev);
119 118
120 return ret; 119 return driver_deferred_probe_check_state(p->dev);
121 } 120 }
122 /* If we're creating a hog we can use the passed pctldev */ 121 /* If we're creating a hog we can use the passed pctldev */
123 if (hog_pctldev && (np_pctldev == p->dev->of_node)) { 122 if (hog_pctldev && (np_pctldev == p->dev->of_node)) {
diff --git a/include/linux/device.h b/include/linux/device.h
index 709308560d32..ef61e2d50ecc 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -343,6 +343,7 @@ struct device *driver_find_device(struct device_driver *drv,
343 343
344void driver_deferred_probe_add(struct device *dev); 344void driver_deferred_probe_add(struct device *dev);
345int driver_deferred_probe_check_state(struct device *dev); 345int driver_deferred_probe_check_state(struct device *dev);
346int driver_deferred_probe_check_state_continue(struct device *dev);
346 347
347/** 348/**
348 * struct subsys_interface - interfaces to device functions 349 * struct subsys_interface - interfaces to device functions