Blob Blame History Raw
From 7190450511e91143bf1e610c91d57e1c7899ffa7 Mon Sep 17 00:00:00 2001
From: Hannes Reinecke <hare@suse.de>
Date: Wed, 8 Jan 2020 15:59:05 +0100
Subject: [PATCH] drivers/base: implement dev_enable_async_probe()
Patch-Mainline: never, SLE15-SP2 specific
References: jsc#SLE-11117,bsc#1156954

Implement dev_enable_async_probe() to selectively enable asynchronous
probing for individual devices.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/base/base.h    |  1 +
 drivers/base/core.c    | 11 +++++++++++
 drivers/base/dd.c      |  6 +++++-
 include/linux/device.h |  1 +
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index b405436ee28e..5b077f6776f8 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -84,6 +84,7 @@ struct device_private {
 	struct device_driver *async_driver;
 	struct device *device;
 	u8 dead:1;
+	u8 async_probe_enabled:1;
 };
 #define to_device_private_parent(obj)	\
 	container_of(obj, struct device_private, knode_parent)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0ae6fcf50f8d..7d3f0d7c6a64 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3442,3 +3442,14 @@ int device_match_fwnode(struct device *dev, const void *fwnode)
 	return dev_fwnode(dev) == fwnode;
 }
 EXPORT_SYMBOL_GPL(device_match_fwnode);
+
+void dev_enable_async_probe(struct device *dev, bool enabled)
+{
+	if (!dev->p) {
+		if (device_private_init(dev))
+			return;
+	}
+	if (dev->p)
+		dev->p->async_probe_enabled = enabled;
+}
+EXPORT_SYMBOL_GPL(dev_enable_async_probe);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 994a90747420..9d51111bdd02 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -807,6 +807,9 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
 
 	async_allowed = driver_allows_async_probing(drv);
 
+	if (async_allowed)
+		async_allowed = dev->p->async_probe_enabled;
+
 	if (async_allowed)
 		data->have_async = true;
 
@@ -1038,7 +1041,8 @@ static int __driver_attach(struct device *dev, void *data)
 		return ret;
 	} /* ret > 0 means positive match */
 
-	if (driver_allows_async_probing(drv)) {
+	if (dev->p && dev->p->async_probe_enabled &&
+	    driver_allows_async_probing(drv)) {
 		/*
 		 * Instead of probing the device synchronously we will
 		 * probe it asynchronously to allow for more parallelism.
diff --git a/include/linux/device.h b/include/linux/device.h
index 13c86b0e1bcf..4484397709c0 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1390,6 +1390,7 @@ extern int device_move(struct device *dev, struct device *new_parent,
 extern const char *device_get_devnode(struct device *dev,
 				      umode_t *mode, kuid_t *uid, kgid_t *gid,
 				      const char **tmp);
+extern void dev_enable_async_probe(struct device *dev, bool enabled);
 
 static inline bool device_supports_offline(struct device *dev)
 {
-- 
2.16.4