summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorSaravana Kannan <saravanak@google.com>2020-05-21 12:18:00 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-07-10 15:24:56 +0200
commitda6d647598a6d182eb6a0344a7b14ae005244399 (patch)
tree88dcad2df2466fa911d88dcad5669b7c72d5b016 /drivers/base
parent8fd456ec0cf03875908d6b67c1cd20cf0a7b4474 (diff)
driver core: Add waiting_for_supplier sysfs file for devices
This would be useful to check if a device is not probing because it's waiting for a supplier to be added and then linked to before it can probe. To reduce sysfs clutter, this file is added only if it can ever be 1. So, if fw_devlink is disabled or set to permissive, this file is not added. Also, this file is removed once the device probes as it's no longer relevant. Signed-off-by: Saravana Kannan <saravanak@google.com> Link: https://lore.kernel.org/r/20200521191800.136035-4-saravanak@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index ca6403343515..5373ddd029f6 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1041,6 +1041,22 @@ static void device_link_drop_managed(struct device_link *link)
kref_put(&link->kref, __device_link_del);
}
+static ssize_t waiting_for_supplier_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ bool val;
+
+ device_lock(dev);
+ mutex_lock(&wfs_lock);
+ val = !list_empty(&dev->links.needs_suppliers)
+ && dev->links.need_for_probe;
+ mutex_unlock(&wfs_lock);
+ device_unlock(dev);
+ return sprintf(buf, "%u\n", val);
+}
+static DEVICE_ATTR_RO(waiting_for_supplier);
+
/**
* device_links_driver_bound - Update device links after probing its driver.
* @dev: Device to update the links for.
@@ -1065,6 +1081,7 @@ void device_links_driver_bound(struct device *dev)
mutex_lock(&wfs_lock);
list_del_init(&dev->links.needs_suppliers);
mutex_unlock(&wfs_lock);
+ device_remove_file(dev, &dev_attr_waiting_for_supplier);
device_links_write_lock();
@@ -2144,8 +2161,16 @@ static int device_add_attrs(struct device *dev)
goto err_remove_dev_groups;
}
+ if (fw_devlink_flags && !fw_devlink_is_permissive()) {
+ error = device_create_file(dev, &dev_attr_waiting_for_supplier);
+ if (error)
+ goto err_remove_dev_online;
+ }
+
return 0;
+ err_remove_dev_online:
+ device_remove_file(dev, &dev_attr_online);
err_remove_dev_groups:
device_remove_groups(dev, dev->groups);
err_remove_type_groups:
@@ -2163,6 +2188,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_waiting_for_supplier);
device_remove_file(dev, &dev_attr_online);
device_remove_groups(dev, dev->groups);