summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-04-18 21:16:22 +0200
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-07-03 12:32:40 +0200
commitfcbcebce7159c928692dc6a5e88869f6e44438b9 (patch)
treeabc91266771d81fe0401da0febbaeba59dd425f8
parentcomponent: fix missed cleanup in case of devres failure (diff)
downloadlinux-fcbcebce7159c928692dc6a5e88869f6e44438b9.tar.xz
linux-fcbcebce7159c928692dc6a5e88869f6e44438b9.zip
component: ignore multiple additions of the same component
Permit masters to call component_master_add_child() and match the same child multiple times. This may happen if there's multiple connections to a single component device from other devices. In such scenarios, we should not return a failure, but instead ignore the attempt. Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/base/component.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c
index d0ebd4431736..55813e91bf0d 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -69,6 +69,11 @@ static void component_detach_master(struct master *master, struct component *c)
c->master = NULL;
}
+/*
+ * Add a component to a master, finding the component via the compare
+ * function and compare data. This is safe to call for duplicate matches
+ * and will not result in the same component being added multiple times.
+ */
int component_master_add_child(struct master *master,
int (*compare)(struct device *, void *), void *compare_data)
{
@@ -76,11 +81,12 @@ int component_master_add_child(struct master *master,
int ret = -ENXIO;
list_for_each_entry(c, &component_list, node) {
- if (c->master)
+ if (c->master && c->master != master)
continue;
if (compare(c->dev, compare_data)) {
- component_attach_master(master, c);
+ if (!c->master)
+ component_attach_master(master, c);
ret = 0;
break;
}