summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/core.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index f24eb2daad00..a4d6f9b93088 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -221,12 +221,29 @@ struct device_link *device_link_add(struct device *consumer,
goto out;
}
- list_for_each_entry(link, &supplier->links.consumers, s_node)
- if (link->consumer == consumer) {
- kref_get(&link->kref);
+ list_for_each_entry(link, &supplier->links.consumers, s_node) {
+ if (link->consumer != consumer)
+ continue;
+
+ /*
+ * Don't return a stateless link if the caller wants a stateful
+ * one and vice versa.
+ */
+ if (WARN_ON((flags & DL_FLAG_STATELESS) != (link->flags & DL_FLAG_STATELESS))) {
+ link = NULL;
goto out;
}
+ if (flags & DL_FLAG_AUTOREMOVE_CONSUMER)
+ link->flags |= DL_FLAG_AUTOREMOVE_CONSUMER;
+
+ if (flags & DL_FLAG_AUTOREMOVE_SUPPLIER)
+ link->flags |= DL_FLAG_AUTOREMOVE_SUPPLIER;
+
+ kref_get(&link->kref);
+ goto out;
+ }
+
link = kzalloc(sizeof(*link), GFP_KERNEL);
if (!link)
goto out;