Skip to content

Commit d090b70

Browse files
Andrzej Hajdagregkh
authored andcommitted
driver core: add deferring probe reason to devices_deferred property
/sys/kernel/debug/devices_deferred property contains list of deferred devices. This list does not contain reason why the driver deferred probe, the patch improves it. The natural place to set the reason is dev_err_probe function introduced recently, ie. if dev_err_probe will be called with -EPROBE_DEFER instead of printk the message will be attached to a deferred device and printed when user reads devices_deferred property. Signed-off-by: Andrzej Hajda <[email protected]> Reviewed-by: Mark Brown <[email protected]> Reviewed-by: Javier Martinez Canillas <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Reviewed-by: Rafael J. Wysocki <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a787e54 commit d090b70

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

drivers/base/base.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct device_private {
9393
struct klist_node knode_class;
9494
struct list_head deferred_probe;
9595
struct device_driver *async_driver;
96+
char *deferred_probe_reason;
9697
struct device *device;
9798
u8 dead:1;
9899
};
@@ -134,6 +135,8 @@ extern void device_release_driver_internal(struct device *dev,
134135
extern void driver_detach(struct device_driver *drv);
135136
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
136137
extern void driver_deferred_probe_del(struct device *dev);
138+
extern void device_set_deferred_probe_reason(const struct device *dev,
139+
struct va_format *vaf);
137140
static inline int driver_match_device(struct device_driver *drv,
138141
struct device *dev)
139142
{

drivers/base/core.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4213,6 +4213,8 @@ define_dev_printk_level(_dev_info, KERN_INFO);
42134213
* This helper implements common pattern present in probe functions for error
42144214
* checking: print debug or error message depending if the error value is
42154215
* -EPROBE_DEFER and propagate error upwards.
4216+
* In case of -EPROBE_DEFER it sets also defer probe reason, which can be
4217+
* checked later by reading devices_deferred debugfs attribute.
42164218
* It replaces code sequence:
42174219
* if (err != -EPROBE_DEFER)
42184220
* dev_err(dev, ...);
@@ -4234,10 +4236,12 @@ int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
42344236
vaf.fmt = fmt;
42354237
vaf.va = &args;
42364238

4237-
if (err != -EPROBE_DEFER)
4239+
if (err != -EPROBE_DEFER) {
42384240
dev_err(dev, "error %d: %pV", err, &vaf);
4239-
else
4241+
} else {
4242+
device_set_deferred_probe_reason(dev, &vaf);
42404243
dev_dbg(dev, "error %d: %pV", err, &vaf);
4244+
}
42414245

42424246
va_end(args);
42434247

drivers/base/dd.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <linux/async.h>
2828
#include <linux/pm_runtime.h>
2929
#include <linux/pinctrl/devinfo.h>
30+
#include <linux/slab.h>
3031

3132
#include "base.h"
3233
#include "power/power.h"
@@ -136,6 +137,8 @@ void driver_deferred_probe_del(struct device *dev)
136137
if (!list_empty(&dev->p->deferred_probe)) {
137138
dev_dbg(dev, "Removed from deferred list\n");
138139
list_del_init(&dev->p->deferred_probe);
140+
kfree(dev->p->deferred_probe_reason);
141+
dev->p->deferred_probe_reason = NULL;
139142
}
140143
mutex_unlock(&deferred_probe_mutex);
141144
}
@@ -206,6 +209,23 @@ void device_unblock_probing(void)
206209
driver_deferred_probe_trigger();
207210
}
208211

212+
/**
213+
* device_set_deferred_probe_reason() - Set defer probe reason message for device
214+
* @dev: the pointer to the struct device
215+
* @vaf: the pointer to va_format structure with message
216+
*/
217+
void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf)
218+
{
219+
const char *drv = dev_driver_string(dev);
220+
221+
mutex_lock(&deferred_probe_mutex);
222+
223+
kfree(dev->p->deferred_probe_reason);
224+
dev->p->deferred_probe_reason = kasprintf(GFP_KERNEL, "%s: %pV", drv, vaf);
225+
226+
mutex_unlock(&deferred_probe_mutex);
227+
}
228+
209229
/*
210230
* deferred_devs_show() - Show the devices in the deferred probe pending list.
211231
*/
@@ -216,7 +236,8 @@ static int deferred_devs_show(struct seq_file *s, void *data)
216236
mutex_lock(&deferred_probe_mutex);
217237

218238
list_for_each_entry(curr, &deferred_probe_pending_list, deferred_probe)
219-
seq_printf(s, "%s\n", dev_name(curr->device));
239+
seq_printf(s, "%s\t%s", dev_name(curr->device),
240+
curr->device->p->deferred_probe_reason ?: "\n");
220241

221242
mutex_unlock(&deferred_probe_mutex);
222243

0 commit comments

Comments
 (0)