All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Component helper updates
@ 2015-11-23 16:02 ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2015-11-23 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

Greg,

These four patches update the component helper by:
* Removing the legacy matching code with the .add_components method
  in the master's operation structure.  Nothing in -rc1 appears to be
  using the legacy functions or method, according to my git greps.

* A slight code reorganisation which results in slightly easier to read
  code.

* Switch to tracking components via an array rather than a list, which
  allows us to keep the matching and matched components together, and
  more importantly allows us to reduce the amount of matching - with
  this structure, we can incrementally add the component devices as
  they become available, rather than re-running the list of matches
  each time something changes.

* Fix the lack of match release functionality, which Liviu Dudau
  reminded me was missing.  This allows people who want to pass
  device_node structures in to (correctly) retain the reference to the
  node, and drop the node when the need to do matches is no longer
  required.

The first three patches have been well tested over the last year as I've
had them in my tree that long.  I hadn't considered them important enough
to send as they're only removing and cleaning up functionality.  However,
with the need to fix something, it now makes sense to get them merged.

The last patch has been tested with etnaviv DRM to prove that the match
release works by unloading the module.  On unload, the release function
is correctly called.

This is intended for the next merge window.  Please apply.

 drivers/base/component.c  | 281 ++++++++++++++++++++++++----------------------
 include/linux/component.h |  33 ++++--
 2 files changed, 167 insertions(+), 147 deletions(-)

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 0/4] Component helper updates
@ 2015-11-23 16:02 ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2015-11-23 16:02 UTC (permalink / raw)
  To: gregkh; +Cc: dri-devel, linux-arm-kernel

Greg,

These four patches update the component helper by:
* Removing the legacy matching code with the .add_components method
  in the master's operation structure.  Nothing in -rc1 appears to be
  using the legacy functions or method, according to my git greps.

* A slight code reorganisation which results in slightly easier to read
  code.

* Switch to tracking components via an array rather than a list, which
  allows us to keep the matching and matched components together, and
  more importantly allows us to reduce the amount of matching - with
  this structure, we can incrementally add the component devices as
  they become available, rather than re-running the list of matches
  each time something changes.

* Fix the lack of match release functionality, which Liviu Dudau
  reminded me was missing.  This allows people who want to pass
  device_node structures in to (correctly) retain the reference to the
  node, and drop the node when the need to do matches is no longer
  required.

The first three patches have been well tested over the last year as I've
had them in my tree that long.  I hadn't considered them important enough
to send as they're only removing and cleaning up functionality.  However,
with the need to fix something, it now makes sense to get them merged.

The last patch has been tested with etnaviv DRM to prove that the match
release works by unloading the module.  On unload, the release function
is correctly called.

This is intended for the next merge window.  Please apply.

 drivers/base/component.c  | 281 ++++++++++++++++++++++++----------------------
 include/linux/component.h |  33 ++++--
 2 files changed, 167 insertions(+), 147 deletions(-)

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/4] component: remove old add_components method
  2015-11-23 16:02 ` Russell King - ARM Linux
@ 2015-11-23 16:02   ` Russell King
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King @ 2015-11-23 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

Now that drivers create an array of component matches at probe time, we
can retire the old methods.  This involves removing the add_components
master method, and removing component_master_add_child() from public
view.  We also remove component_add_master() as that interface is no
longer useful.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c  | 31 +++++--------------------------
 include/linux/component.h |  5 -----
 2 files changed, 5 insertions(+), 31 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index f748430bb654..2ca22738ae92 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -84,7 +84,7 @@ static void component_detach_master(struct master *master, struct component *c)
  * 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,
+static int component_master_add_child(struct master *master,
 	int (*compare)(struct device *, void *), void *compare_data)
 {
 	struct component *c;
@@ -104,7 +104,6 @@ int component_master_add_child(struct master *master,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(component_master_add_child);
 
 static int find_components(struct master *master)
 {
@@ -112,14 +111,6 @@ static int find_components(struct master *master)
 	size_t i;
 	int ret = 0;
 
-	if (!match) {
-		/*
-		 * Search the list of components, looking for components that
-		 * belong to this master, and attach them to the master.
-		 */
-		return master->ops->add_components(master->dev, master);
-	}
-
 	/*
 	 * Scan the array of match functions and attach
 	 * any components which are found to this master.
@@ -290,15 +281,10 @@ int component_master_add_with_match(struct device *dev,
 	struct master *master;
 	int ret;
 
-	if (ops->add_components && match)
-		return -EINVAL;
-
-	if (match) {
-		/* Reallocate the match array for its true size */
-		match = component_match_realloc(dev, match, match->num);
-		if (IS_ERR(match))
-			return PTR_ERR(match);
-	}
+	/* Reallocate the match array for its true size */
+	match = component_match_realloc(dev, match, match->num);
+	if (IS_ERR(match))
+		return PTR_ERR(match);
 
 	master = kzalloc(sizeof(*master), GFP_KERNEL);
 	if (!master)
@@ -326,13 +312,6 @@ int component_master_add_with_match(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(component_master_add_with_match);
 
-int component_master_add(struct device *dev,
-	const struct component_master_ops *ops)
-{
-	return component_master_add_with_match(dev, ops, NULL);
-}
-EXPORT_SYMBOL_GPL(component_master_add);
-
 void component_master_del(struct device *dev,
 	const struct component_master_ops *ops)
 {
diff --git a/include/linux/component.h b/include/linux/component.h
index c00dcc302611..71c434a6a5ee 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -17,18 +17,13 @@ void component_unbind_all(struct device *, void *);
 struct master;
 
 struct component_master_ops {
-	int (*add_components)(struct device *, struct master *);
 	int (*bind)(struct device *);
 	void (*unbind)(struct device *);
 };
 
-int component_master_add(struct device *, const struct component_master_ops *);
 void component_master_del(struct device *,
 	const struct component_master_ops *);
 
-int component_master_add_child(struct master *master,
-	int (*compare)(struct device *, void *), void *compare_data);
-
 struct component_match;
 
 int component_master_add_with_match(struct device *,
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 1/4] component: remove old add_components method
@ 2015-11-23 16:02   ` Russell King
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King @ 2015-11-23 16:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: dri-devel, linux-arm-kernel

Now that drivers create an array of component matches at probe time, we
can retire the old methods.  This involves removing the add_components
master method, and removing component_master_add_child() from public
view.  We also remove component_add_master() as that interface is no
longer useful.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c  | 31 +++++--------------------------
 include/linux/component.h |  5 -----
 2 files changed, 5 insertions(+), 31 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index f748430bb654..2ca22738ae92 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -84,7 +84,7 @@ static void component_detach_master(struct master *master, struct component *c)
  * 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,
+static int component_master_add_child(struct master *master,
 	int (*compare)(struct device *, void *), void *compare_data)
 {
 	struct component *c;
@@ -104,7 +104,6 @@ int component_master_add_child(struct master *master,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(component_master_add_child);
 
 static int find_components(struct master *master)
 {
@@ -112,14 +111,6 @@ static int find_components(struct master *master)
 	size_t i;
 	int ret = 0;
 
-	if (!match) {
-		/*
-		 * Search the list of components, looking for components that
-		 * belong to this master, and attach them to the master.
-		 */
-		return master->ops->add_components(master->dev, master);
-	}
-
 	/*
 	 * Scan the array of match functions and attach
 	 * any components which are found to this master.
@@ -290,15 +281,10 @@ int component_master_add_with_match(struct device *dev,
 	struct master *master;
 	int ret;
 
-	if (ops->add_components && match)
-		return -EINVAL;
-
-	if (match) {
-		/* Reallocate the match array for its true size */
-		match = component_match_realloc(dev, match, match->num);
-		if (IS_ERR(match))
-			return PTR_ERR(match);
-	}
+	/* Reallocate the match array for its true size */
+	match = component_match_realloc(dev, match, match->num);
+	if (IS_ERR(match))
+		return PTR_ERR(match);
 
 	master = kzalloc(sizeof(*master), GFP_KERNEL);
 	if (!master)
@@ -326,13 +312,6 @@ int component_master_add_with_match(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(component_master_add_with_match);
 
-int component_master_add(struct device *dev,
-	const struct component_master_ops *ops)
-{
-	return component_master_add_with_match(dev, ops, NULL);
-}
-EXPORT_SYMBOL_GPL(component_master_add);
-
 void component_master_del(struct device *dev,
 	const struct component_master_ops *ops)
 {
diff --git a/include/linux/component.h b/include/linux/component.h
index c00dcc302611..71c434a6a5ee 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -17,18 +17,13 @@ void component_unbind_all(struct device *, void *);
 struct master;
 
 struct component_master_ops {
-	int (*add_components)(struct device *, struct master *);
 	int (*bind)(struct device *);
 	void (*unbind)(struct device *);
 };
 
-int component_master_add(struct device *, const struct component_master_ops *);
 void component_master_del(struct device *,
 	const struct component_master_ops *);
 
-int component_master_add_child(struct master *master,
-	int (*compare)(struct device *, void *), void *compare_data);
-
 struct component_match;
 
 int component_master_add_with_match(struct device *,
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/4] component: move check for unbound master into try_to_bring_up_masters()
  2015-11-23 16:02 ` Russell King - ARM Linux
@ 2015-11-23 16:02   ` Russell King
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King @ 2015-11-23 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

Clean up the code a little; we don't need to check that the master is
unbound for every invocation of try_to_bring_up_master(), so let's move
it to where it's really needed - try_to_bring_up_masters(), where we may
encounter already bound masters.

Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 2ca22738ae92..cd70b68d9780 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -150,13 +150,6 @@ static int try_to_bring_up_master(struct master *master,
 {
 	int ret;
 
-	if (master->bound)
-		return 0;
-
-	/*
-	 * Search the list of components, looking for components that
-	 * belong to this master, and attach them to the master.
-	 */
 	if (find_components(master)) {
 		/* Failed to find all components */
 		ret = 0;
@@ -196,9 +189,11 @@ static int try_to_bring_up_masters(struct component *component)
 	int ret = 0;
 
 	list_for_each_entry(m, &masters, node) {
-		ret = try_to_bring_up_master(m, component);
-		if (ret != 0)
-			break;
+		if (!m->bound) {
+			ret = try_to_bring_up_master(m, component);
+			if (ret != 0)
+				break;
+		}
 	}
 
 	return ret;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/4] component: move check for unbound master into try_to_bring_up_masters()
@ 2015-11-23 16:02   ` Russell King
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King @ 2015-11-23 16:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: dri-devel, linux-arm-kernel

Clean up the code a little; we don't need to check that the master is
unbound for every invocation of try_to_bring_up_master(), so let's move
it to where it's really needed - try_to_bring_up_masters(), where we may
encounter already bound masters.

Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 2ca22738ae92..cd70b68d9780 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -150,13 +150,6 @@ static int try_to_bring_up_master(struct master *master,
 {
 	int ret;
 
-	if (master->bound)
-		return 0;
-
-	/*
-	 * Search the list of components, looking for components that
-	 * belong to this master, and attach them to the master.
-	 */
 	if (find_components(master)) {
 		/* Failed to find all components */
 		ret = 0;
@@ -196,9 +189,11 @@ static int try_to_bring_up_masters(struct component *component)
 	int ret = 0;
 
 	list_for_each_entry(m, &masters, node) {
-		ret = try_to_bring_up_master(m, component);
-		if (ret != 0)
-			break;
+		if (!m->bound) {
+			ret = try_to_bring_up_master(m, component);
+			if (ret != 0)
+				break;
+		}
 	}
 
 	return ret;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/4] component: track components via array rather than list
  2015-11-23 16:02 ` Russell King - ARM Linux
@ 2015-11-23 16:02   ` Russell King
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King @ 2015-11-23 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

Since we now have an array which defines each component, maintain the
components to be bound in the array rather than a separate list.  We
also need duplicate tracking so we can eliminate multiple bind calls
for the same component: we preserve the list-based component order in
that the first match which adds the component determines its position.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c | 154 ++++++++++++++++++++++++-----------------------
 1 file changed, 80 insertions(+), 74 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index cd70b68d9780..d99b06b341fb 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -18,18 +18,21 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 
+struct component;
+
 struct component_match {
 	size_t alloc;
 	size_t num;
 	struct {
 		void *data;
 		int (*fn)(struct device *, void *);
+		struct component *component;
+		bool duplicate;
 	} compare[0];
 };
 
 struct master {
 	struct list_head node;
-	struct list_head components;
 	bool bound;
 
 	const struct component_master_ops *ops;
@@ -39,7 +42,6 @@ struct master {
 
 struct component {
 	struct list_head node;
-	struct list_head master_node;
 	struct master *master;
 	bool bound;
 
@@ -63,46 +65,20 @@ static struct master *__master_find(struct device *dev,
 	return NULL;
 }
 
-/* Attach an unattached component to a master. */
-static void component_attach_master(struct master *master, struct component *c)
-{
-	c->master = master;
-
-	list_add_tail(&c->master_node, &master->components);
-}
-
-/* Detach a component from a master. */
-static void component_detach_master(struct master *master, struct component *c)
-{
-	list_del(&c->master_node);
-
-	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.
- */
-static int component_master_add_child(struct master *master,
+static struct component *find_component(struct master *master,
 	int (*compare)(struct device *, void *), void *compare_data)
 {
 	struct component *c;
-	int ret = -ENXIO;
 
 	list_for_each_entry(c, &component_list, node) {
 		if (c->master && c->master != master)
 			continue;
 
-		if (compare(c->dev, compare_data)) {
-			if (!c->master)
-				component_attach_master(master, c);
-			ret = 0;
-			break;
-		}
+		if (compare(c->dev, compare_data))
+			return c;
 	}
 
-	return ret;
+	return NULL;
 }
 
 static int find_components(struct master *master)
@@ -116,26 +92,39 @@ static int find_components(struct master *master)
 	 * any components which are found to this master.
 	 */
 	for (i = 0; i < match->num; i++) {
-		ret = component_master_add_child(master,
-						 match->compare[i].fn,
-						 match->compare[i].data);
-		if (ret)
+		struct component *c;
+
+		dev_dbg(master->dev, "Looking for component %zu\n", i);
+
+		if (match->compare[i].component)
+			continue;
+
+		c = find_component(master, match->compare[i].fn,
+				   match->compare[i].data);
+		if (!c) {
+			ret = -ENXIO;
 			break;
+		}
+
+		dev_dbg(master->dev, "found component %s, duplicate %u\n", dev_name(c->dev), !!c->master);
+
+		/* Attach this component to the master */
+		match->compare[i].duplicate = !!c->master;
+		match->compare[i].component = c;
+		c->master = master;
 	}
 	return ret;
 }
 
-/* Detach all attached components from this master */
-static void master_remove_components(struct master *master)
+/* Detach component from associated master */
+static void remove_component(struct master *master, struct component *c)
 {
-	while (!list_empty(&master->components)) {
-		struct component *c = list_first_entry(&master->components,
-					struct component, master_node);
-
-		WARN_ON(c->master != master);
+	size_t i;
 
-		component_detach_master(master, c);
-	}
+	/* Detach the component from this master. */
+	for (i = 0; i < master->match->num; i++)
+		if (master->match->compare[i].component == c)
+			master->match->compare[i].component = NULL;
 }
 
 /*
@@ -150,37 +139,32 @@ static int try_to_bring_up_master(struct master *master,
 {
 	int ret;
 
+	dev_dbg(master->dev, "trying to bring up master\n");
+
 	if (find_components(master)) {
-		/* Failed to find all components */
-		ret = 0;
-		goto out;
+		dev_dbg(master->dev, "master has incomplete components\n");
+		return 0;
 	}
 
 	if (component && component->master != master) {
-		ret = 0;
-		goto out;
+		dev_dbg(master->dev, "master is not for this component (%s)\n",
+			dev_name(component->dev));
+		return 0;
 	}
 
-	if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!devres_open_group(master->dev, NULL, GFP_KERNEL))
+		return -ENOMEM;
 
 	/* Found all components */
 	ret = master->ops->bind(master->dev);
 	if (ret < 0) {
 		devres_release_group(master->dev, NULL);
 		dev_info(master->dev, "master bind failed: %d\n", ret);
-		goto out;
+		return ret;
 	}
 
 	master->bound = true;
 	return 1;
-
-out:
-	master_remove_components(master);
-
-	return ret;
 }
 
 static int try_to_bring_up_masters(struct component *component)
@@ -206,8 +190,6 @@ static void take_down_master(struct master *master)
 		devres_release_group(master->dev, NULL);
 		master->bound = false;
 	}
-
-	master_remove_components(master);
 }
 
 static size_t component_match_size(size_t num)
@@ -265,6 +247,7 @@ void component_match_add(struct device *dev, struct component_match **matchptr,
 
 	match->compare[match->num].fn = compare;
 	match->compare[match->num].data = compare_data;
+	match->compare[match->num].component = NULL;
 	match->num++;
 }
 EXPORT_SYMBOL(component_match_add);
@@ -288,7 +271,6 @@ int component_master_add_with_match(struct device *dev,
 	master->dev = dev;
 	master->ops = ops;
 	master->match = match;
-	INIT_LIST_HEAD(&master->components);
 
 	/* Add to the list of available masters. */
 	mutex_lock(&component_mutex);
@@ -311,13 +293,24 @@ void component_master_del(struct device *dev,
 	const struct component_master_ops *ops)
 {
 	struct master *master;
+	int i;
 
 	mutex_lock(&component_mutex);
 	master = __master_find(dev, ops);
 	if (master) {
+		struct component_match *match = master->match;
+
 		take_down_master(master);
 
 		list_del(&master->node);
+
+		if (match) {
+			for (i = 0; i < match->num; i++) {
+				struct component *c = match->compare[i].component;
+				if (c)
+					c->master = NULL;
+			}
+		}
 		kfree(master);
 	}
 	mutex_unlock(&component_mutex);
@@ -340,6 +333,7 @@ void component_unbind_all(struct device *master_dev, void *data)
 {
 	struct master *master;
 	struct component *c;
+	size_t i;
 
 	WARN_ON(!mutex_is_locked(&component_mutex));
 
@@ -347,8 +341,12 @@ void component_unbind_all(struct device *master_dev, void *data)
 	if (!master)
 		return;
 
-	list_for_each_entry_reverse(c, &master->components, master_node)
-		component_unbind(c, master, data);
+	/* Unbind components in reverse order */
+	for (i = master->match->num; i--; )
+		if (!master->match->compare[i].duplicate) {
+			c = master->match->compare[i].component;
+			component_unbind(c, master, data);
+		}
 }
 EXPORT_SYMBOL_GPL(component_unbind_all);
 
@@ -408,6 +406,7 @@ int component_bind_all(struct device *master_dev, void *data)
 {
 	struct master *master;
 	struct component *c;
+	size_t i;
 	int ret = 0;
 
 	WARN_ON(!mutex_is_locked(&component_mutex));
@@ -416,16 +415,21 @@ int component_bind_all(struct device *master_dev, void *data)
 	if (!master)
 		return -EINVAL;
 
-	list_for_each_entry(c, &master->components, master_node) {
-		ret = component_bind(c, master, data);
-		if (ret)
-			break;
-	}
+	/* Bind components in match order */
+	for (i = 0; i < master->match->num; i++)
+		if (!master->match->compare[i].duplicate) {
+			c = master->match->compare[i].component;
+			ret = component_bind(c, master, data);
+			if (ret)
+				break;
+		}
 
 	if (ret != 0) {
-		list_for_each_entry_continue_reverse(c, &master->components,
-						     master_node)
-			component_unbind(c, master, data);
+		for (; i--; )
+			if (!master->match->compare[i].duplicate) {
+				c = master->match->compare[i].component;
+				component_unbind(c, master, data);
+			}
 	}
 
 	return ret;
@@ -473,8 +477,10 @@ void component_del(struct device *dev, const struct component_ops *ops)
 			break;
 		}
 
-	if (component && component->master)
+	if (component && component->master) {
 		take_down_master(component->master);
+		remove_component(component->master, component);
+	}
 
 	mutex_unlock(&component_mutex);
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/4] component: track components via array rather than list
@ 2015-11-23 16:02   ` Russell King
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King @ 2015-11-23 16:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: dri-devel, linux-arm-kernel

Since we now have an array which defines each component, maintain the
components to be bound in the array rather than a separate list.  We
also need duplicate tracking so we can eliminate multiple bind calls
for the same component: we preserve the list-based component order in
that the first match which adds the component determines its position.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c | 154 ++++++++++++++++++++++++-----------------------
 1 file changed, 80 insertions(+), 74 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index cd70b68d9780..d99b06b341fb 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -18,18 +18,21 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 
+struct component;
+
 struct component_match {
 	size_t alloc;
 	size_t num;
 	struct {
 		void *data;
 		int (*fn)(struct device *, void *);
+		struct component *component;
+		bool duplicate;
 	} compare[0];
 };
 
 struct master {
 	struct list_head node;
-	struct list_head components;
 	bool bound;
 
 	const struct component_master_ops *ops;
@@ -39,7 +42,6 @@ struct master {
 
 struct component {
 	struct list_head node;
-	struct list_head master_node;
 	struct master *master;
 	bool bound;
 
@@ -63,46 +65,20 @@ static struct master *__master_find(struct device *dev,
 	return NULL;
 }
 
-/* Attach an unattached component to a master. */
-static void component_attach_master(struct master *master, struct component *c)
-{
-	c->master = master;
-
-	list_add_tail(&c->master_node, &master->components);
-}
-
-/* Detach a component from a master. */
-static void component_detach_master(struct master *master, struct component *c)
-{
-	list_del(&c->master_node);
-
-	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.
- */
-static int component_master_add_child(struct master *master,
+static struct component *find_component(struct master *master,
 	int (*compare)(struct device *, void *), void *compare_data)
 {
 	struct component *c;
-	int ret = -ENXIO;
 
 	list_for_each_entry(c, &component_list, node) {
 		if (c->master && c->master != master)
 			continue;
 
-		if (compare(c->dev, compare_data)) {
-			if (!c->master)
-				component_attach_master(master, c);
-			ret = 0;
-			break;
-		}
+		if (compare(c->dev, compare_data))
+			return c;
 	}
 
-	return ret;
+	return NULL;
 }
 
 static int find_components(struct master *master)
@@ -116,26 +92,39 @@ static int find_components(struct master *master)
 	 * any components which are found to this master.
 	 */
 	for (i = 0; i < match->num; i++) {
-		ret = component_master_add_child(master,
-						 match->compare[i].fn,
-						 match->compare[i].data);
-		if (ret)
+		struct component *c;
+
+		dev_dbg(master->dev, "Looking for component %zu\n", i);
+
+		if (match->compare[i].component)
+			continue;
+
+		c = find_component(master, match->compare[i].fn,
+				   match->compare[i].data);
+		if (!c) {
+			ret = -ENXIO;
 			break;
+		}
+
+		dev_dbg(master->dev, "found component %s, duplicate %u\n", dev_name(c->dev), !!c->master);
+
+		/* Attach this component to the master */
+		match->compare[i].duplicate = !!c->master;
+		match->compare[i].component = c;
+		c->master = master;
 	}
 	return ret;
 }
 
-/* Detach all attached components from this master */
-static void master_remove_components(struct master *master)
+/* Detach component from associated master */
+static void remove_component(struct master *master, struct component *c)
 {
-	while (!list_empty(&master->components)) {
-		struct component *c = list_first_entry(&master->components,
-					struct component, master_node);
-
-		WARN_ON(c->master != master);
+	size_t i;
 
-		component_detach_master(master, c);
-	}
+	/* Detach the component from this master. */
+	for (i = 0; i < master->match->num; i++)
+		if (master->match->compare[i].component == c)
+			master->match->compare[i].component = NULL;
 }
 
 /*
@@ -150,37 +139,32 @@ static int try_to_bring_up_master(struct master *master,
 {
 	int ret;
 
+	dev_dbg(master->dev, "trying to bring up master\n");
+
 	if (find_components(master)) {
-		/* Failed to find all components */
-		ret = 0;
-		goto out;
+		dev_dbg(master->dev, "master has incomplete components\n");
+		return 0;
 	}
 
 	if (component && component->master != master) {
-		ret = 0;
-		goto out;
+		dev_dbg(master->dev, "master is not for this component (%s)\n",
+			dev_name(component->dev));
+		return 0;
 	}
 
-	if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!devres_open_group(master->dev, NULL, GFP_KERNEL))
+		return -ENOMEM;
 
 	/* Found all components */
 	ret = master->ops->bind(master->dev);
 	if (ret < 0) {
 		devres_release_group(master->dev, NULL);
 		dev_info(master->dev, "master bind failed: %d\n", ret);
-		goto out;
+		return ret;
 	}
 
 	master->bound = true;
 	return 1;
-
-out:
-	master_remove_components(master);
-
-	return ret;
 }
 
 static int try_to_bring_up_masters(struct component *component)
@@ -206,8 +190,6 @@ static void take_down_master(struct master *master)
 		devres_release_group(master->dev, NULL);
 		master->bound = false;
 	}
-
-	master_remove_components(master);
 }
 
 static size_t component_match_size(size_t num)
@@ -265,6 +247,7 @@ void component_match_add(struct device *dev, struct component_match **matchptr,
 
 	match->compare[match->num].fn = compare;
 	match->compare[match->num].data = compare_data;
+	match->compare[match->num].component = NULL;
 	match->num++;
 }
 EXPORT_SYMBOL(component_match_add);
@@ -288,7 +271,6 @@ int component_master_add_with_match(struct device *dev,
 	master->dev = dev;
 	master->ops = ops;
 	master->match = match;
-	INIT_LIST_HEAD(&master->components);
 
 	/* Add to the list of available masters. */
 	mutex_lock(&component_mutex);
@@ -311,13 +293,24 @@ void component_master_del(struct device *dev,
 	const struct component_master_ops *ops)
 {
 	struct master *master;
+	int i;
 
 	mutex_lock(&component_mutex);
 	master = __master_find(dev, ops);
 	if (master) {
+		struct component_match *match = master->match;
+
 		take_down_master(master);
 
 		list_del(&master->node);
+
+		if (match) {
+			for (i = 0; i < match->num; i++) {
+				struct component *c = match->compare[i].component;
+				if (c)
+					c->master = NULL;
+			}
+		}
 		kfree(master);
 	}
 	mutex_unlock(&component_mutex);
@@ -340,6 +333,7 @@ void component_unbind_all(struct device *master_dev, void *data)
 {
 	struct master *master;
 	struct component *c;
+	size_t i;
 
 	WARN_ON(!mutex_is_locked(&component_mutex));
 
@@ -347,8 +341,12 @@ void component_unbind_all(struct device *master_dev, void *data)
 	if (!master)
 		return;
 
-	list_for_each_entry_reverse(c, &master->components, master_node)
-		component_unbind(c, master, data);
+	/* Unbind components in reverse order */
+	for (i = master->match->num; i--; )
+		if (!master->match->compare[i].duplicate) {
+			c = master->match->compare[i].component;
+			component_unbind(c, master, data);
+		}
 }
 EXPORT_SYMBOL_GPL(component_unbind_all);
 
@@ -408,6 +406,7 @@ int component_bind_all(struct device *master_dev, void *data)
 {
 	struct master *master;
 	struct component *c;
+	size_t i;
 	int ret = 0;
 
 	WARN_ON(!mutex_is_locked(&component_mutex));
@@ -416,16 +415,21 @@ int component_bind_all(struct device *master_dev, void *data)
 	if (!master)
 		return -EINVAL;
 
-	list_for_each_entry(c, &master->components, master_node) {
-		ret = component_bind(c, master, data);
-		if (ret)
-			break;
-	}
+	/* Bind components in match order */
+	for (i = 0; i < master->match->num; i++)
+		if (!master->match->compare[i].duplicate) {
+			c = master->match->compare[i].component;
+			ret = component_bind(c, master, data);
+			if (ret)
+				break;
+		}
 
 	if (ret != 0) {
-		list_for_each_entry_continue_reverse(c, &master->components,
-						     master_node)
-			component_unbind(c, master, data);
+		for (; i--; )
+			if (!master->match->compare[i].duplicate) {
+				c = master->match->compare[i].component;
+				component_unbind(c, master, data);
+			}
 	}
 
 	return ret;
@@ -473,8 +477,10 @@ void component_del(struct device *dev, const struct component_ops *ops)
 			break;
 		}
 
-	if (component && component->master)
+	if (component && component->master) {
 		take_down_master(component->master);
+		remove_component(component->master, component);
+	}
 
 	mutex_unlock(&component_mutex);
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/4] component: add support for releasing match data
  2015-11-23 16:02 ` Russell King - ARM Linux
@ 2015-11-23 16:02   ` Russell King
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King @ 2015-11-23 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

The component helper treats the void match data pointer as an opaque
object which needs no further management.  When device nodes being
passed, this is not true: the caller should pass its refcount to the
component helper, and there should be a way to drop the refcount when
the matching information is destroyed.

This patch provides a per-match release method in addition to the match
method to solve this issue.  Rather than using component_match_add(),
users should use component_match_add_release() which takes an additional
function pointer for releasing this reference.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c  | 101 ++++++++++++++++++++++++++++++----------------
 include/linux/component.h |  28 +++++++++----
 2 files changed, 87 insertions(+), 42 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index d99b06b341fb..89f5cf68d80a 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -20,15 +20,18 @@
 
 struct component;
 
+struct component_match_array {
+	void *data;
+	int (*compare)(struct device *, void *);
+	void (*release)(struct device *, void *);
+	struct component *component;
+	bool duplicate;
+};
+
 struct component_match {
 	size_t alloc;
 	size_t num;
-	struct {
-		void *data;
-		int (*fn)(struct device *, void *);
-		struct component *component;
-		bool duplicate;
-	} compare[0];
+	struct component_match_array *compare;
 };
 
 struct master {
@@ -92,6 +95,7 @@ static int find_components(struct master *master)
 	 * any components which are found to this master.
 	 */
 	for (i = 0; i < match->num; i++) {
+		struct component_match_array *mc = &match->compare[i];
 		struct component *c;
 
 		dev_dbg(master->dev, "Looking for component %zu\n", i);
@@ -99,8 +103,7 @@ static int find_components(struct master *master)
 		if (match->compare[i].component)
 			continue;
 
-		c = find_component(master, match->compare[i].fn,
-				   match->compare[i].data);
+		c = find_component(master, mc->compare, mc->data);
 		if (!c) {
 			ret = -ENXIO;
 			break;
@@ -192,41 +195,55 @@ static void take_down_master(struct master *master)
 	}
 }
 
-static size_t component_match_size(size_t num)
+static void component_match_release(struct device *master,
+	struct component_match *match)
+{
+	unsigned int i;
+
+	for (i = 0; i < match->num; i++) {
+		struct component_match_array *mc = &match->compare[i];
+
+		if (mc->release)
+			mc->release(master, mc->data);
+	}
+}
+
+static void devm_component_match_release(struct device *dev, void *res)
 {
-	return offsetof(struct component_match, compare[num]);
+	component_match_release(dev, res);
 }
 
-static struct component_match *component_match_realloc(struct device *dev,
+static int component_match_realloc(struct device *dev,
 	struct component_match *match, size_t num)
 {
-	struct component_match *new;
+	struct component_match_array *new;
 
-	if (match && match->alloc == num)
-		return match;
+	if (match->alloc == num)
+		return 0;
 
-	new = devm_kmalloc(dev, component_match_size(num), GFP_KERNEL);
+	new = devm_kmalloc_array(dev, num, sizeof(*new), GFP_KERNEL);
 	if (!new)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
-	if (match) {
-		memcpy(new, match, component_match_size(min(match->num, num)));
-		devm_kfree(dev, match);
-	} else {
-		new->num = 0;
+	if (match->compare) {
+		memcpy(new, match->compare, sizeof(*new) *
+					    min(match->num, num));
+		devm_kfree(dev, match->compare);
 	}
+	match->compare = new;
+	match->alloc = num;
 
-	new->alloc = num;
-
-	return new;
+	return 0;
 }
 
 /*
- * Add a component to be matched.
+ * Add a component to be matched, with a release function.
  *
  * The match array is first created or extended if necessary.
  */
-void component_match_add(struct device *dev, struct component_match **matchptr,
+void component_match_add_release(struct device *master,
+	struct component_match **matchptr,
+	void (*release)(struct device *, void *),
 	int (*compare)(struct device *, void *), void *compare_data)
 {
 	struct component_match *match = *matchptr;
@@ -234,23 +251,37 @@ void component_match_add(struct device *dev, struct component_match **matchptr,
 	if (IS_ERR(match))
 		return;
 
-	if (!match || match->num == match->alloc) {
-		size_t new_size = match ? match->alloc + 16 : 15;
+	if (!match) {
+		match = devres_alloc(devm_component_match_release,
+				     sizeof(*match), GFP_KERNEL);
+		if (!match) {
+			*matchptr = ERR_PTR(-ENOMEM);
+			return;
+		}
 
-		match = component_match_realloc(dev, match, new_size);
+		devres_add(master, match);
 
 		*matchptr = match;
+	}
+
+	if (match->num == match->alloc) {
+		size_t new_size = match ? match->alloc + 16 : 15;
+		int ret;
 
-		if (IS_ERR(match))
+		ret = component_match_realloc(master, match, new_size);
+		if (ret) {
+			*matchptr = ERR_PTR(ret);
 			return;
+		}
 	}
 
-	match->compare[match->num].fn = compare;
+	match->compare[match->num].compare = compare;
+	match->compare[match->num].release = release;
 	match->compare[match->num].data = compare_data;
 	match->compare[match->num].component = NULL;
 	match->num++;
 }
-EXPORT_SYMBOL(component_match_add);
+EXPORT_SYMBOL(component_match_add_release);
 
 int component_master_add_with_match(struct device *dev,
 	const struct component_master_ops *ops,
@@ -260,9 +291,9 @@ int component_master_add_with_match(struct device *dev,
 	int ret;
 
 	/* Reallocate the match array for its true size */
-	match = component_match_realloc(dev, match, match->num);
-	if (IS_ERR(match))
-		return PTR_ERR(match);
+	ret = component_match_realloc(dev, match, match->num);
+	if (ret)
+		return ret;
 
 	master = kzalloc(sizeof(*master), GFP_KERNEL);
 	if (!master)
diff --git a/include/linux/component.h b/include/linux/component.h
index 71c434a6a5ee..a559eebc0e0f 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -1,24 +1,28 @@
 #ifndef COMPONENT_H
 #define COMPONENT_H
 
+#include <linux/stddef.h>
+
 struct device;
 
 struct component_ops {
-	int (*bind)(struct device *, struct device *, void *);
-	void (*unbind)(struct device *, struct device *, void *);
+	int (*bind)(struct device *comp, struct device *master,
+		    void *master_data);
+	void (*unbind)(struct device *comp, struct device *master,
+		       void *master_data);
 };
 
 int component_add(struct device *, const struct component_ops *);
 void component_del(struct device *, const struct component_ops *);
 
-int component_bind_all(struct device *, void *);
-void component_unbind_all(struct device *, void *);
+int component_bind_all(struct device *master, void *master_data);
+void component_unbind_all(struct device *master, void *master_data);
 
 struct master;
 
 struct component_master_ops {
-	int (*bind)(struct device *);
-	void (*unbind)(struct device *);
+	int (*bind)(struct device *master);
+	void (*unbind)(struct device *master);
 };
 
 void component_master_del(struct device *,
@@ -28,7 +32,17 @@ struct component_match;
 
 int component_master_add_with_match(struct device *,
 	const struct component_master_ops *, struct component_match *);
-void component_match_add(struct device *, struct component_match **,
+void component_match_add_release(struct device *master,
+	struct component_match **matchptr,
+	void (*release)(struct device *, void *),
 	int (*compare)(struct device *, void *), void *compare_data);
 
+static inline void component_match_add(struct device *master,
+	struct component_match **matchptr,
+	int (*compare)(struct device *, void *), void *compare_data)
+{
+	component_match_add_release(master, matchptr, NULL, compare,
+				    compare_data);
+}
+
 #endif
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/4] component: add support for releasing match data
@ 2015-11-23 16:02   ` Russell King
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King @ 2015-11-23 16:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: dri-devel, linux-arm-kernel

The component helper treats the void match data pointer as an opaque
object which needs no further management.  When device nodes being
passed, this is not true: the caller should pass its refcount to the
component helper, and there should be a way to drop the refcount when
the matching information is destroyed.

This patch provides a per-match release method in addition to the match
method to solve this issue.  Rather than using component_match_add(),
users should use component_match_add_release() which takes an additional
function pointer for releasing this reference.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c  | 101 ++++++++++++++++++++++++++++++----------------
 include/linux/component.h |  28 +++++++++----
 2 files changed, 87 insertions(+), 42 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index d99b06b341fb..89f5cf68d80a 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -20,15 +20,18 @@
 
 struct component;
 
+struct component_match_array {
+	void *data;
+	int (*compare)(struct device *, void *);
+	void (*release)(struct device *, void *);
+	struct component *component;
+	bool duplicate;
+};
+
 struct component_match {
 	size_t alloc;
 	size_t num;
-	struct {
-		void *data;
-		int (*fn)(struct device *, void *);
-		struct component *component;
-		bool duplicate;
-	} compare[0];
+	struct component_match_array *compare;
 };
 
 struct master {
@@ -92,6 +95,7 @@ static int find_components(struct master *master)
 	 * any components which are found to this master.
 	 */
 	for (i = 0; i < match->num; i++) {
+		struct component_match_array *mc = &match->compare[i];
 		struct component *c;
 
 		dev_dbg(master->dev, "Looking for component %zu\n", i);
@@ -99,8 +103,7 @@ static int find_components(struct master *master)
 		if (match->compare[i].component)
 			continue;
 
-		c = find_component(master, match->compare[i].fn,
-				   match->compare[i].data);
+		c = find_component(master, mc->compare, mc->data);
 		if (!c) {
 			ret = -ENXIO;
 			break;
@@ -192,41 +195,55 @@ static void take_down_master(struct master *master)
 	}
 }
 
-static size_t component_match_size(size_t num)
+static void component_match_release(struct device *master,
+	struct component_match *match)
+{
+	unsigned int i;
+
+	for (i = 0; i < match->num; i++) {
+		struct component_match_array *mc = &match->compare[i];
+
+		if (mc->release)
+			mc->release(master, mc->data);
+	}
+}
+
+static void devm_component_match_release(struct device *dev, void *res)
 {
-	return offsetof(struct component_match, compare[num]);
+	component_match_release(dev, res);
 }
 
-static struct component_match *component_match_realloc(struct device *dev,
+static int component_match_realloc(struct device *dev,
 	struct component_match *match, size_t num)
 {
-	struct component_match *new;
+	struct component_match_array *new;
 
-	if (match && match->alloc == num)
-		return match;
+	if (match->alloc == num)
+		return 0;
 
-	new = devm_kmalloc(dev, component_match_size(num), GFP_KERNEL);
+	new = devm_kmalloc_array(dev, num, sizeof(*new), GFP_KERNEL);
 	if (!new)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
-	if (match) {
-		memcpy(new, match, component_match_size(min(match->num, num)));
-		devm_kfree(dev, match);
-	} else {
-		new->num = 0;
+	if (match->compare) {
+		memcpy(new, match->compare, sizeof(*new) *
+					    min(match->num, num));
+		devm_kfree(dev, match->compare);
 	}
+	match->compare = new;
+	match->alloc = num;
 
-	new->alloc = num;
-
-	return new;
+	return 0;
 }
 
 /*
- * Add a component to be matched.
+ * Add a component to be matched, with a release function.
  *
  * The match array is first created or extended if necessary.
  */
-void component_match_add(struct device *dev, struct component_match **matchptr,
+void component_match_add_release(struct device *master,
+	struct component_match **matchptr,
+	void (*release)(struct device *, void *),
 	int (*compare)(struct device *, void *), void *compare_data)
 {
 	struct component_match *match = *matchptr;
@@ -234,23 +251,37 @@ void component_match_add(struct device *dev, struct component_match **matchptr,
 	if (IS_ERR(match))
 		return;
 
-	if (!match || match->num == match->alloc) {
-		size_t new_size = match ? match->alloc + 16 : 15;
+	if (!match) {
+		match = devres_alloc(devm_component_match_release,
+				     sizeof(*match), GFP_KERNEL);
+		if (!match) {
+			*matchptr = ERR_PTR(-ENOMEM);
+			return;
+		}
 
-		match = component_match_realloc(dev, match, new_size);
+		devres_add(master, match);
 
 		*matchptr = match;
+	}
+
+	if (match->num == match->alloc) {
+		size_t new_size = match ? match->alloc + 16 : 15;
+		int ret;
 
-		if (IS_ERR(match))
+		ret = component_match_realloc(master, match, new_size);
+		if (ret) {
+			*matchptr = ERR_PTR(ret);
 			return;
+		}
 	}
 
-	match->compare[match->num].fn = compare;
+	match->compare[match->num].compare = compare;
+	match->compare[match->num].release = release;
 	match->compare[match->num].data = compare_data;
 	match->compare[match->num].component = NULL;
 	match->num++;
 }
-EXPORT_SYMBOL(component_match_add);
+EXPORT_SYMBOL(component_match_add_release);
 
 int component_master_add_with_match(struct device *dev,
 	const struct component_master_ops *ops,
@@ -260,9 +291,9 @@ int component_master_add_with_match(struct device *dev,
 	int ret;
 
 	/* Reallocate the match array for its true size */
-	match = component_match_realloc(dev, match, match->num);
-	if (IS_ERR(match))
-		return PTR_ERR(match);
+	ret = component_match_realloc(dev, match, match->num);
+	if (ret)
+		return ret;
 
 	master = kzalloc(sizeof(*master), GFP_KERNEL);
 	if (!master)
diff --git a/include/linux/component.h b/include/linux/component.h
index 71c434a6a5ee..a559eebc0e0f 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -1,24 +1,28 @@
 #ifndef COMPONENT_H
 #define COMPONENT_H
 
+#include <linux/stddef.h>
+
 struct device;
 
 struct component_ops {
-	int (*bind)(struct device *, struct device *, void *);
-	void (*unbind)(struct device *, struct device *, void *);
+	int (*bind)(struct device *comp, struct device *master,
+		    void *master_data);
+	void (*unbind)(struct device *comp, struct device *master,
+		       void *master_data);
 };
 
 int component_add(struct device *, const struct component_ops *);
 void component_del(struct device *, const struct component_ops *);
 
-int component_bind_all(struct device *, void *);
-void component_unbind_all(struct device *, void *);
+int component_bind_all(struct device *master, void *master_data);
+void component_unbind_all(struct device *master, void *master_data);
 
 struct master;
 
 struct component_master_ops {
-	int (*bind)(struct device *);
-	void (*unbind)(struct device *);
+	int (*bind)(struct device *master);
+	void (*unbind)(struct device *master);
 };
 
 void component_master_del(struct device *,
@@ -28,7 +32,17 @@ struct component_match;
 
 int component_master_add_with_match(struct device *,
 	const struct component_master_ops *, struct component_match *);
-void component_match_add(struct device *, struct component_match **,
+void component_match_add_release(struct device *master,
+	struct component_match **matchptr,
+	void (*release)(struct device *, void *),
 	int (*compare)(struct device *, void *), void *compare_data);
 
+static inline void component_match_add(struct device *master,
+	struct component_match **matchptr,
+	int (*compare)(struct device *, void *), void *compare_data)
+{
+	component_match_add_release(master, matchptr, NULL, compare,
+				    compare_data);
+}
+
 #endif
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 1/4] component: remove old add_components method
  2015-11-23 16:02   ` Russell King
@ 2015-11-23 23:26     ` Andrew Lunn
  -1 siblings, 0 replies; 20+ messages in thread
From: Andrew Lunn @ 2015-11-23 23:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 23, 2015 at 04:02:37PM +0000, Russell King wrote:
> Now that drivers create an array of component matches at probe time, we
> can retire the old methods.  This involves removing the add_components
> master method

Hi Russell

Ack for removing this. I'm using components while restructing DSA, and
it seems odd that if i don't have any optional matches this method
gets called, but if i do have matches, it does not...

     Andrew

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/4] component: remove old add_components method
@ 2015-11-23 23:26     ` Andrew Lunn
  0 siblings, 0 replies; 20+ messages in thread
From: Andrew Lunn @ 2015-11-23 23:26 UTC (permalink / raw)
  To: Russell King; +Cc: Greg Kroah-Hartman, linux-arm-kernel, dri-devel

On Mon, Nov 23, 2015 at 04:02:37PM +0000, Russell King wrote:
> Now that drivers create an array of component matches at probe time, we
> can retire the old methods.  This involves removing the add_components
> master method

Hi Russell

Ack for removing this. I'm using components while restructing DSA, and
it seems odd that if i don't have any optional matches this method
gets called, but if i do have matches, it does not...

     Andrew

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 0/4] Component helper updates
  2015-11-23 16:02 ` Russell King - ARM Linux
@ 2015-11-23 23:38   ` Andrew Lunn
  -1 siblings, 0 replies; 20+ messages in thread
From: Andrew Lunn @ 2015-11-23 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 23, 2015 at 04:02:11PM +0000, Russell King - ARM Linux wrote:
> Greg,
> 
> These four patches update the component helper by:

Hi Russell

Is there any documentation for the component helper, in particular,
when devm_ can be used?

It seems like slaves should only do a component_add() in their probe
function, and then do resource allocation using devm_* in the bind
callback?

It seems like a master device can however use devm_ in its probe
function?

Thanks
	Andrew

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Component helper updates
@ 2015-11-23 23:38   ` Andrew Lunn
  0 siblings, 0 replies; 20+ messages in thread
From: Andrew Lunn @ 2015-11-23 23:38 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, gregkh, dri-devel

On Mon, Nov 23, 2015 at 04:02:11PM +0000, Russell King - ARM Linux wrote:
> Greg,
> 
> These four patches update the component helper by:

Hi Russell

Is there any documentation for the component helper, in particular,
when devm_ can be used?

It seems like slaves should only do a component_add() in their probe
function, and then do resource allocation using devm_* in the bind
callback?

It seems like a master device can however use devm_ in its probe
function?

Thanks
	Andrew

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 0/4] Component helper updates
  2015-11-23 16:02 ` Russell King - ARM Linux
@ 2015-12-07 15:01   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2015-12-07 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

Given the lack of interest in these patches, I've put these into my
"for-next" branch so that they can get some exposure in linux-next.

On Mon, Nov 23, 2015 at 04:02:11PM +0000, Russell King - ARM Linux wrote:
> Greg,
> 
> These four patches update the component helper by:
> * Removing the legacy matching code with the .add_components method
>   in the master's operation structure.  Nothing in -rc1 appears to be
>   using the legacy functions or method, according to my git greps.
> 
> * A slight code reorganisation which results in slightly easier to read
>   code.
> 
> * Switch to tracking components via an array rather than a list, which
>   allows us to keep the matching and matched components together, and
>   more importantly allows us to reduce the amount of matching - with
>   this structure, we can incrementally add the component devices as
>   they become available, rather than re-running the list of matches
>   each time something changes.
> 
> * Fix the lack of match release functionality, which Liviu Dudau
>   reminded me was missing.  This allows people who want to pass
>   device_node structures in to (correctly) retain the reference to the
>   node, and drop the node when the need to do matches is no longer
>   required.
> 
> The first three patches have been well tested over the last year as I've
> had them in my tree that long.  I hadn't considered them important enough
> to send as they're only removing and cleaning up functionality.  However,
> with the need to fix something, it now makes sense to get them merged.
> 
> The last patch has been tested with etnaviv DRM to prove that the match
> release works by unloading the module.  On unload, the release function
> is correctly called.
> 
> This is intended for the next merge window.  Please apply.
> 
>  drivers/base/component.c  | 281 ++++++++++++++++++++++++----------------------
>  include/linux/component.h |  33 ++++--
>  2 files changed, 167 insertions(+), 147 deletions(-)
> 
> -- 
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Component helper updates
@ 2015-12-07 15:01   ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2015-12-07 15:01 UTC (permalink / raw)
  To: gregkh; +Cc: linux-arm-kernel, dri-devel

Given the lack of interest in these patches, I've put these into my
"for-next" branch so that they can get some exposure in linux-next.

On Mon, Nov 23, 2015 at 04:02:11PM +0000, Russell King - ARM Linux wrote:
> Greg,
> 
> These four patches update the component helper by:
> * Removing the legacy matching code with the .add_components method
>   in the master's operation structure.  Nothing in -rc1 appears to be
>   using the legacy functions or method, according to my git greps.
> 
> * A slight code reorganisation which results in slightly easier to read
>   code.
> 
> * Switch to tracking components via an array rather than a list, which
>   allows us to keep the matching and matched components together, and
>   more importantly allows us to reduce the amount of matching - with
>   this structure, we can incrementally add the component devices as
>   they become available, rather than re-running the list of matches
>   each time something changes.
> 
> * Fix the lack of match release functionality, which Liviu Dudau
>   reminded me was missing.  This allows people who want to pass
>   device_node structures in to (correctly) retain the reference to the
>   node, and drop the node when the need to do matches is no longer
>   required.
> 
> The first three patches have been well tested over the last year as I've
> had them in my tree that long.  I hadn't considered them important enough
> to send as they're only removing and cleaning up functionality.  However,
> with the need to fix something, it now makes sense to get them merged.
> 
> The last patch has been tested with etnaviv DRM to prove that the match
> release works by unloading the module.  On unload, the release function
> is correctly called.
> 
> This is intended for the next merge window.  Please apply.
> 
>  drivers/base/component.c  | 281 ++++++++++++++++++++++++----------------------
>  include/linux/component.h |  33 ++++--
>  2 files changed, 167 insertions(+), 147 deletions(-)
> 
> -- 
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/4] component: remove old add_components method
  2015-11-23 16:02   ` Russell King
@ 2015-12-07 17:06     ` Andrew Lunn
  -1 siblings, 0 replies; 20+ messages in thread
From: Andrew Lunn @ 2015-12-07 17:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 23, 2015 at 04:02:37PM +0000, Russell King wrote:
> Now that drivers create an array of component matches at probe time, we
> can retire the old methods.  This involves removing the add_components
> master method, and removing component_master_add_child() from public
> view.  We also remove component_add_master() as that interface is no
> longer useful.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

I've been using this patch for a couple of weeks

Tested-by: Andrew Lunn <andrew@lunn.ch>

	   Andrew

> ---
>  drivers/base/component.c  | 31 +++++--------------------------
>  include/linux/component.h |  5 -----
>  2 files changed, 5 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/base/component.c b/drivers/base/component.c
> index f748430bb654..2ca22738ae92 100644
> --- a/drivers/base/component.c
> +++ b/drivers/base/component.c
> @@ -84,7 +84,7 @@ static void component_detach_master(struct master *master, struct component *c)
>   * 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,
> +static int component_master_add_child(struct master *master,
>  	int (*compare)(struct device *, void *), void *compare_data)
>  {
>  	struct component *c;
> @@ -104,7 +104,6 @@ int component_master_add_child(struct master *master,
>  
>  	return ret;
>  }
> -EXPORT_SYMBOL_GPL(component_master_add_child);
>  
>  static int find_components(struct master *master)
>  {
> @@ -112,14 +111,6 @@ static int find_components(struct master *master)
>  	size_t i;
>  	int ret = 0;
>  
> -	if (!match) {
> -		/*
> -		 * Search the list of components, looking for components that
> -		 * belong to this master, and attach them to the master.
> -		 */
> -		return master->ops->add_components(master->dev, master);
> -	}
> -
>  	/*
>  	 * Scan the array of match functions and attach
>  	 * any components which are found to this master.
> @@ -290,15 +281,10 @@ int component_master_add_with_match(struct device *dev,
>  	struct master *master;
>  	int ret;
>  
> -	if (ops->add_components && match)
> -		return -EINVAL;
> -
> -	if (match) {
> -		/* Reallocate the match array for its true size */
> -		match = component_match_realloc(dev, match, match->num);
> -		if (IS_ERR(match))
> -			return PTR_ERR(match);
> -	}
> +	/* Reallocate the match array for its true size */
> +	match = component_match_realloc(dev, match, match->num);
> +	if (IS_ERR(match))
> +		return PTR_ERR(match);
>  
>  	master = kzalloc(sizeof(*master), GFP_KERNEL);
>  	if (!master)
> @@ -326,13 +312,6 @@ int component_master_add_with_match(struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(component_master_add_with_match);
>  
> -int component_master_add(struct device *dev,
> -	const struct component_master_ops *ops)
> -{
> -	return component_master_add_with_match(dev, ops, NULL);
> -}
> -EXPORT_SYMBOL_GPL(component_master_add);
> -
>  void component_master_del(struct device *dev,
>  	const struct component_master_ops *ops)
>  {
> diff --git a/include/linux/component.h b/include/linux/component.h
> index c00dcc302611..71c434a6a5ee 100644
> --- a/include/linux/component.h
> +++ b/include/linux/component.h
> @@ -17,18 +17,13 @@ void component_unbind_all(struct device *, void *);
>  struct master;
>  
>  struct component_master_ops {
> -	int (*add_components)(struct device *, struct master *);
>  	int (*bind)(struct device *);
>  	void (*unbind)(struct device *);
>  };
>  
> -int component_master_add(struct device *, const struct component_master_ops *);
>  void component_master_del(struct device *,
>  	const struct component_master_ops *);
>  
> -int component_master_add_child(struct master *master,
> -	int (*compare)(struct device *, void *), void *compare_data);
> -
>  struct component_match;
>  
>  int component_master_add_with_match(struct device *,
> -- 
> 2.1.0
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/4] component: remove old add_components method
@ 2015-12-07 17:06     ` Andrew Lunn
  0 siblings, 0 replies; 20+ messages in thread
From: Andrew Lunn @ 2015-12-07 17:06 UTC (permalink / raw)
  To: Russell King; +Cc: Greg Kroah-Hartman, linux-arm-kernel, dri-devel

On Mon, Nov 23, 2015 at 04:02:37PM +0000, Russell King wrote:
> Now that drivers create an array of component matches at probe time, we
> can retire the old methods.  This involves removing the add_components
> master method, and removing component_master_add_child() from public
> view.  We also remove component_add_master() as that interface is no
> longer useful.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

I've been using this patch for a couple of weeks

Tested-by: Andrew Lunn <andrew@lunn.ch>

	   Andrew

> ---
>  drivers/base/component.c  | 31 +++++--------------------------
>  include/linux/component.h |  5 -----
>  2 files changed, 5 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/base/component.c b/drivers/base/component.c
> index f748430bb654..2ca22738ae92 100644
> --- a/drivers/base/component.c
> +++ b/drivers/base/component.c
> @@ -84,7 +84,7 @@ static void component_detach_master(struct master *master, struct component *c)
>   * 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,
> +static int component_master_add_child(struct master *master,
>  	int (*compare)(struct device *, void *), void *compare_data)
>  {
>  	struct component *c;
> @@ -104,7 +104,6 @@ int component_master_add_child(struct master *master,
>  
>  	return ret;
>  }
> -EXPORT_SYMBOL_GPL(component_master_add_child);
>  
>  static int find_components(struct master *master)
>  {
> @@ -112,14 +111,6 @@ static int find_components(struct master *master)
>  	size_t i;
>  	int ret = 0;
>  
> -	if (!match) {
> -		/*
> -		 * Search the list of components, looking for components that
> -		 * belong to this master, and attach them to the master.
> -		 */
> -		return master->ops->add_components(master->dev, master);
> -	}
> -
>  	/*
>  	 * Scan the array of match functions and attach
>  	 * any components which are found to this master.
> @@ -290,15 +281,10 @@ int component_master_add_with_match(struct device *dev,
>  	struct master *master;
>  	int ret;
>  
> -	if (ops->add_components && match)
> -		return -EINVAL;
> -
> -	if (match) {
> -		/* Reallocate the match array for its true size */
> -		match = component_match_realloc(dev, match, match->num);
> -		if (IS_ERR(match))
> -			return PTR_ERR(match);
> -	}
> +	/* Reallocate the match array for its true size */
> +	match = component_match_realloc(dev, match, match->num);
> +	if (IS_ERR(match))
> +		return PTR_ERR(match);
>  
>  	master = kzalloc(sizeof(*master), GFP_KERNEL);
>  	if (!master)
> @@ -326,13 +312,6 @@ int component_master_add_with_match(struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(component_master_add_with_match);
>  
> -int component_master_add(struct device *dev,
> -	const struct component_master_ops *ops)
> -{
> -	return component_master_add_with_match(dev, ops, NULL);
> -}
> -EXPORT_SYMBOL_GPL(component_master_add);
> -
>  void component_master_del(struct device *dev,
>  	const struct component_master_ops *ops)
>  {
> diff --git a/include/linux/component.h b/include/linux/component.h
> index c00dcc302611..71c434a6a5ee 100644
> --- a/include/linux/component.h
> +++ b/include/linux/component.h
> @@ -17,18 +17,13 @@ void component_unbind_all(struct device *, void *);
>  struct master;
>  
>  struct component_master_ops {
> -	int (*add_components)(struct device *, struct master *);
>  	int (*bind)(struct device *);
>  	void (*unbind)(struct device *);
>  };
>  
> -int component_master_add(struct device *, const struct component_master_ops *);
>  void component_master_del(struct device *,
>  	const struct component_master_ops *);
>  
> -int component_master_add_child(struct master *master,
> -	int (*compare)(struct device *, void *), void *compare_data);
> -
>  struct component_match;
>  
>  int component_master_add_with_match(struct device *,
> -- 
> 2.1.0
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 0/4] Component helper updates
  2015-12-07 15:01   ` Russell King - ARM Linux
@ 2016-01-04 17:25     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2016-01-04 17:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 07, 2015 at 03:01:43PM +0000, Russell King - ARM Linux wrote:
> Given the lack of interest in these patches, I've put these into my
> "for-next" branch so that they can get some exposure in linux-next.

These have been in for-next, and no one's reported any issues.
I've now queued these into my for-linus branch in preparation to
merging during the next merge window.

> On Mon, Nov 23, 2015 at 04:02:11PM +0000, Russell King - ARM Linux wrote:
> > Greg,
> > 
> > These four patches update the component helper by:
> > * Removing the legacy matching code with the .add_components method
> >   in the master's operation structure.  Nothing in -rc1 appears to be
> >   using the legacy functions or method, according to my git greps.
> > 
> > * A slight code reorganisation which results in slightly easier to read
> >   code.
> > 
> > * Switch to tracking components via an array rather than a list, which
> >   allows us to keep the matching and matched components together, and
> >   more importantly allows us to reduce the amount of matching - with
> >   this structure, we can incrementally add the component devices as
> >   they become available, rather than re-running the list of matches
> >   each time something changes.
> > 
> > * Fix the lack of match release functionality, which Liviu Dudau
> >   reminded me was missing.  This allows people who want to pass
> >   device_node structures in to (correctly) retain the reference to the
> >   node, and drop the node when the need to do matches is no longer
> >   required.
> > 
> > The first three patches have been well tested over the last year as I've
> > had them in my tree that long.  I hadn't considered them important enough
> > to send as they're only removing and cleaning up functionality.  However,
> > with the need to fix something, it now makes sense to get them merged.
> > 
> > The last patch has been tested with etnaviv DRM to prove that the match
> > release works by unloading the module.  On unload, the release function
> > is correctly called.
> > 
> > This is intended for the next merge window.  Please apply.
> > 
> >  drivers/base/component.c  | 281 ++++++++++++++++++++++++----------------------
> >  include/linux/component.h |  33 ++++--
> >  2 files changed, 167 insertions(+), 147 deletions(-)
> > 
> > -- 
> > FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> > according to speedtest.net.
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> -- 
> RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Component helper updates
@ 2016-01-04 17:25     ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2016-01-04 17:25 UTC (permalink / raw)
  To: gregkh; +Cc: dri-devel, linux-arm-kernel

On Mon, Dec 07, 2015 at 03:01:43PM +0000, Russell King - ARM Linux wrote:
> Given the lack of interest in these patches, I've put these into my
> "for-next" branch so that they can get some exposure in linux-next.

These have been in for-next, and no one's reported any issues.
I've now queued these into my for-linus branch in preparation to
merging during the next merge window.

> On Mon, Nov 23, 2015 at 04:02:11PM +0000, Russell King - ARM Linux wrote:
> > Greg,
> > 
> > These four patches update the component helper by:
> > * Removing the legacy matching code with the .add_components method
> >   in the master's operation structure.  Nothing in -rc1 appears to be
> >   using the legacy functions or method, according to my git greps.
> > 
> > * A slight code reorganisation which results in slightly easier to read
> >   code.
> > 
> > * Switch to tracking components via an array rather than a list, which
> >   allows us to keep the matching and matched components together, and
> >   more importantly allows us to reduce the amount of matching - with
> >   this structure, we can incrementally add the component devices as
> >   they become available, rather than re-running the list of matches
> >   each time something changes.
> > 
> > * Fix the lack of match release functionality, which Liviu Dudau
> >   reminded me was missing.  This allows people who want to pass
> >   device_node structures in to (correctly) retain the reference to the
> >   node, and drop the node when the need to do matches is no longer
> >   required.
> > 
> > The first three patches have been well tested over the last year as I've
> > had them in my tree that long.  I hadn't considered them important enough
> > to send as they're only removing and cleaning up functionality.  However,
> > with the need to fix something, it now makes sense to get them merged.
> > 
> > The last patch has been tested with etnaviv DRM to prove that the match
> > release works by unloading the module.  On unload, the release function
> > is correctly called.
> > 
> > This is intended for the next merge window.  Please apply.
> > 
> >  drivers/base/component.c  | 281 ++++++++++++++++++++++++----------------------
> >  include/linux/component.h |  33 ++++--
> >  2 files changed, 167 insertions(+), 147 deletions(-)
> > 
> > -- 
> > FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> > according to speedtest.net.
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> -- 
> RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2016-01-04 17:25 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-23 16:02 [PATCH 0/4] Component helper updates Russell King - ARM Linux
2015-11-23 16:02 ` Russell King - ARM Linux
2015-11-23 16:02 ` [PATCH 1/4] component: remove old add_components method Russell King
2015-11-23 16:02   ` Russell King
2015-11-23 23:26   ` Andrew Lunn
2015-11-23 23:26     ` Andrew Lunn
2015-12-07 17:06   ` Andrew Lunn
2015-12-07 17:06     ` Andrew Lunn
2015-11-23 16:02 ` [PATCH 2/4] component: move check for unbound master into try_to_bring_up_masters() Russell King
2015-11-23 16:02   ` Russell King
2015-11-23 16:02 ` [PATCH 3/4] component: track components via array rather than list Russell King
2015-11-23 16:02   ` Russell King
2015-11-23 16:02 ` [PATCH 4/4] component: add support for releasing match data Russell King
2015-11-23 16:02   ` Russell King
2015-11-23 23:38 ` [PATCH 0/4] Component helper updates Andrew Lunn
2015-11-23 23:38   ` Andrew Lunn
2015-12-07 15:01 ` Russell King - ARM Linux
2015-12-07 15:01   ` Russell King - ARM Linux
2016-01-04 17:25   ` Russell King - ARM Linux
2016-01-04 17:25     ` Russell King - ARM Linux

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.