* [PATCH 1/4] component: remove old add_components method
2015-11-23 16:02 [PATCH 0/4] Component helper updates Russell King - ARM Linux
@ 2015-11-23 16:02 ` Russell King
2015-11-23 23:26 ` 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
` (4 subsequent siblings)
5 siblings, 2 replies; 10+ 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] 10+ messages in thread* Re: [PATCH 1/4] component: remove old add_components method
2015-11-23 16:02 ` [PATCH 1/4] component: remove old add_components method Russell King
@ 2015-11-23 23:26 ` Andrew Lunn
2015-12-07 17:06 ` Andrew Lunn
1 sibling, 0 replies; 10+ 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] 10+ messages in thread* Re: [PATCH 1/4] component: remove old add_components method
2015-11-23 16:02 ` [PATCH 1/4] component: remove old add_components method Russell King
2015-11-23 23:26 ` Andrew Lunn
@ 2015-12-07 17:06 ` Andrew Lunn
1 sibling, 0 replies; 10+ 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] 10+ messages in thread
* [PATCH 2/4] component: move check for unbound master into try_to_bring_up_masters()
2015-11-23 16:02 [PATCH 0/4] Component helper updates 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 16:02 ` [PATCH 3/4] component: track components via array rather than list Russell King
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ 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] 10+ messages in thread* [PATCH 3/4] component: track components via array rather than list
2015-11-23 16:02 [PATCH 0/4] Component helper updates 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 ` [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 4/4] component: add support for releasing match data Russell King
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ 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] 10+ messages in thread* [PATCH 4/4] component: add support for releasing match data
2015-11-23 16:02 [PATCH 0/4] Component helper updates Russell King - ARM Linux
` (2 preceding siblings ...)
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 23:38 ` [PATCH 0/4] Component helper updates Andrew Lunn
2015-12-07 15:01 ` Russell King - ARM Linux
5 siblings, 0 replies; 10+ 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] 10+ messages in thread* Re: [PATCH 0/4] Component helper updates
2015-11-23 16:02 [PATCH 0/4] Component helper updates Russell King - ARM Linux
` (3 preceding siblings ...)
2015-11-23 16:02 ` [PATCH 4/4] component: add support for releasing match data Russell King
@ 2015-11-23 23:38 ` Andrew Lunn
2015-12-07 15:01 ` Russell King - ARM Linux
5 siblings, 0 replies; 10+ 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] 10+ messages in thread* Re: [PATCH 0/4] Component helper updates
2015-11-23 16:02 [PATCH 0/4] Component helper updates Russell King - ARM Linux
` (4 preceding siblings ...)
2015-11-23 23:38 ` [PATCH 0/4] Component helper updates Andrew Lunn
@ 2015-12-07 15:01 ` Russell King - ARM Linux
2016-01-04 17:25 ` Russell King - ARM Linux
5 siblings, 1 reply; 10+ 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] 10+ messages in thread* Re: [PATCH 0/4] Component helper updates
2015-12-07 15:01 ` Russell King - ARM Linux
@ 2016-01-04 17:25 ` Russell King - ARM Linux
0 siblings, 0 replies; 10+ 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] 10+ messages in thread