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(-)
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 *,
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
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
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;
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);
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
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
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
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
dri-devel@lists.freedesktop.org