Skip to content

Commit

Permalink
driver core: Add deferred_probe attribute to devices in sysfs
Browse files Browse the repository at this point in the history
It is sometimes useful to know that a device is on the deferred probe
list rather than, say, not having a driver available.  Expose this
information to user-space.

Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Ben Hutchings authored and Greg Kroah-Hartman committed Nov 10, 2016
1 parent baa8809 commit 6751667
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Documentation/ABI/testing/sysfs-devices-deferred_probe
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
What: /sys/devices/.../deferred_probe
Date: August 2016
Contact: Ben Hutchings <ben.hutchings@codethink.co.uk>
Description:
The /sys/devices/.../deferred_probe attribute is
present for all devices. If a driver detects during
probing a device that a related device is not yet
ready, it may defer probing of the first device. The
kernel will retry probing the first device after any
other device is successfully probed. This attribute
reads as 1 if probing of this device is currently
deferred, or 0 otherwise.
2 changes: 2 additions & 0 deletions drivers/base/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ extern void device_unblock_probing(void);
extern struct kset *devices_kset;
extern void devices_kset_move_last(struct device *dev);

extern struct device_attribute dev_attr_deferred_probe;

#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
extern void module_add_driver(struct module *mod, struct device_driver *drv);
extern void module_remove_driver(struct device_driver *drv);
Expand Down
7 changes: 7 additions & 0 deletions drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1060,8 +1060,14 @@ static int device_add_attrs(struct device *dev)
goto err_remove_dev_groups;
}

error = device_create_file(dev, &dev_attr_deferred_probe);
if (error)
goto err_remove_online;

return 0;

err_remove_online:
device_remove_file(dev, &dev_attr_online);
err_remove_dev_groups:
device_remove_groups(dev, dev->groups);
err_remove_type_groups:
Expand All @@ -1079,6 +1085,7 @@ static void device_remove_attrs(struct device *dev)
struct class *class = dev->class;
const struct device_type *type = dev->type;

device_remove_file(dev, &dev_attr_deferred_probe);
device_remove_file(dev, &dev_attr_online);
device_remove_groups(dev, dev->groups);

Expand Down
13 changes: 13 additions & 0 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ static LIST_HEAD(deferred_probe_pending_list);
static LIST_HEAD(deferred_probe_active_list);
static atomic_t deferred_trigger_count = ATOMIC_INIT(0);

static ssize_t deferred_probe_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
bool value;

mutex_lock(&deferred_probe_mutex);
value = !list_empty(&dev->p->deferred_probe);
mutex_unlock(&deferred_probe_mutex);

return sprintf(buf, "%d\n", value);
}
DEVICE_ATTR_RO(deferred_probe);

/*
* In some cases, like suspend to RAM or hibernation, It might be reasonable
* to prohibit probing of devices as it could be unsafe.
Expand Down

0 comments on commit 6751667

Please sign in to comment.