Re: [PATCH v3 3/8] component: add support for component match array

2014-07-04 Thread Sachin Kamat
Hi Russell

 Add support for generating a set of component matches at master probe
 time, and submitting them to the component layer.  This allows the
 component layer to perform the matches internally without needing to
 call into the master driver, and allows for further restructuring of
 the component helper.

 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
 ---

[snip]

 +int component_master_add_with_match(struct device *dev,
 +   const struct component_master_ops *ops,
 +   struct component_match *match)
  {
 struct master *master;
 int ret;

 +   if (ops-add_components  match)
 +   return -EINVAL;
 +
 +   /* Reallocate the match array for its true size */
 +   match = component_match_realloc(dev, match, match-num);

   ^
This gives a NULL pointer dereference error when match is NULL (as passed
by component_master_add() below). Observed this while testing linux-next
kernel (next-20140704) on Exynos based board with DRM enabled.


 +   if (IS_ERR(match))
 +   return PTR_ERR(match);
 +
 master = kzalloc(sizeof(*master), GFP_KERNEL);
 if (!master)
 return -ENOMEM;

 master-dev = dev;
 master-ops = ops;
 +   master-match = match;
 INIT_LIST_HEAD(master-components);

 /* Add to the list of available masters. */
 @@ -215,6 +322,13 @@ int component_master_add(struct device *dev,

 return ret  0 ? ret : 0;
  }
 +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);


-- 
Regards,
Sachin.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 3/8] component: add support for component match array

2014-07-04 Thread Russell King - ARM Linux
On Fri, Jul 04, 2014 at 04:17:35PM +0530, Sachin Kamat wrote:
 Hi Russell
 
  +int component_master_add_with_match(struct device *dev,
  +   const struct component_master_ops *ops,
  +   struct component_match *match)
   {
  struct master *master;
  int ret;
 
  +   if (ops-add_components  match)
  +   return -EINVAL;
  +
  +   /* Reallocate the match array for its true size */
  +   match = component_match_realloc(dev, match, match-num);
 
^
 This gives a NULL pointer dereference error when match is NULL (as passed
 by component_master_add() below). Observed this while testing linux-next
 kernel (next-20140704) on Exynos based board with DRM enabled.

Thanks for your report.  Please verify that the patch below resolves it
for you.  Thanks.

 drivers/base/component.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index b4236daed4fa..f748430bb654 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -293,10 +293,12 @@ int component_master_add_with_match(struct device *dev,
if (ops-add_components  match)
return -EINVAL;
 
-   /* Reallocate the match array for its true size */
-   match = component_match_realloc(dev, match, match-num);
-   if (IS_ERR(match))
-   return PTR_ERR(match);
+   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);
+   }
 
master = kzalloc(sizeof(*master), GFP_KERNEL);
if (!master)


-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 3/8] component: add support for component match array

2014-07-04 Thread Sachin Kamat
On Fri, Jul 4, 2014 at 4:22 PM, Russell King - ARM Linux
li...@arm.linux.org.uk wrote:
 On Fri, Jul 04, 2014 at 04:17:35PM +0530, Sachin Kamat wrote:
 Hi Russell

  +int component_master_add_with_match(struct device *dev,
  +   const struct component_master_ops *ops,
  +   struct component_match *match)
   {
  struct master *master;
  int ret;
 
  +   if (ops-add_components  match)
  +   return -EINVAL;
  +
  +   /* Reallocate the match array for its true size */
  +   match = component_match_realloc(dev, match, match-num);

^
 This gives a NULL pointer dereference error when match is NULL (as passed
 by component_master_add() below). Observed this while testing linux-next
 kernel (next-20140704) on Exynos based board with DRM enabled.

 Thanks for your report.  Please verify that the patch below resolves it
 for you.  Thanks.

Yes, the below patch fixes the crash. Thanks for the fix.



  drivers/base/component.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

 diff --git a/drivers/base/component.c b/drivers/base/component.c
 index b4236daed4fa..f748430bb654 100644
 --- a/drivers/base/component.c
 +++ b/drivers/base/component.c
 @@ -293,10 +293,12 @@ int component_master_add_with_match(struct device *dev,
 if (ops-add_components  match)
 return -EINVAL;

 -   /* Reallocate the match array for its true size */
 -   match = component_match_realloc(dev, match, match-num);
 -   if (IS_ERR(match))
 -   return PTR_ERR(match);
 +   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);
 +   }

 master = kzalloc(sizeof(*master), GFP_KERNEL);
 if (!master)


 --
 FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
 improving, and getting towards what was expected from it.



-- 
Regards,
Sachin.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 3/8] component: add support for component match array

2014-07-04 Thread Russell King - ARM Linux
On Fri, Jul 04, 2014 at 05:00:36PM +0530, Sachin Kamat wrote:
 On Fri, Jul 4, 2014 at 4:22 PM, Russell King - ARM Linux
 li...@arm.linux.org.uk wrote:
  On Fri, Jul 04, 2014 at 04:17:35PM +0530, Sachin Kamat wrote:
  Hi Russell
 
   +int component_master_add_with_match(struct device *dev,
   +   const struct component_master_ops *ops,
   +   struct component_match *match)
{
   struct master *master;
   int ret;
  
   +   if (ops-add_components  match)
   +   return -EINVAL;
   +
   +   /* Reallocate the match array for its true size */
   +   match = component_match_realloc(dev, match, match-num);
 
 ^
  This gives a NULL pointer dereference error when match is NULL (as passed
  by component_master_add() below). Observed this while testing linux-next
  kernel (next-20140704) on Exynos based board with DRM enabled.
 
  Thanks for your report.  Please verify that the patch below resolves it
  for you.  Thanks.
 
 Yes, the below patch fixes the crash. Thanks for the fix.

Thanks.  I'll add a tested-by and reported-by for your address when
committing this patch.  Let me know if you want something different.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 3/8] component: add support for component match array

2014-07-04 Thread Sachin Kamat
On Fri, Jul 4, 2014 at 5:55 PM, Russell King - ARM Linux
li...@arm.linux.org.uk wrote:
 On Fri, Jul 04, 2014 at 05:00:36PM +0530, Sachin Kamat wrote:
 On Fri, Jul 4, 2014 at 4:22 PM, Russell King - ARM Linux
 li...@arm.linux.org.uk wrote:
  On Fri, Jul 04, 2014 at 04:17:35PM +0530, Sachin Kamat wrote:
  Hi Russell
 
   +int component_master_add_with_match(struct device *dev,
   +   const struct component_master_ops *ops,
   +   struct component_match *match)
{
   struct master *master;
   int ret;
  
   +   if (ops-add_components  match)
   +   return -EINVAL;
   +
   +   /* Reallocate the match array for its true size */
   +   match = component_match_realloc(dev, match, match-num);
 
 ^
  This gives a NULL pointer dereference error when match is NULL (as passed
  by component_master_add() below). Observed this while testing linux-next
  kernel (next-20140704) on Exynos based board with DRM enabled.
 
  Thanks for your report.  Please verify that the patch below resolves it
  for you.  Thanks.

 Yes, the below patch fixes the crash. Thanks for the fix.

 Thanks.  I'll add a tested-by and reported-by for your address when
 committing this patch.  Let me know if you want something different.

Thanks. Please use the following for the tags:

Sachin Kamat sachin.ka...@samsung.com

-- 
Regards,
Sachin.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 3/8] component: add support for component match array

2014-07-01 Thread Russell King
Add support for generating a set of component matches at master probe
time, and submitting them to the component layer.  This allows the
component layer to perform the matches internally without needing to
call into the master driver, and allows for further restructuring of
the component helper.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
This patch is destined for Greg's driver and staging trees, and David's DRM
tree.

 drivers/base/component.c  | 120 --
 include/linux/component.h |   7 +++
 2 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 55813e91bf0d..b4236daed4fa 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -18,6 +18,15 @@
 #include linux/mutex.h
 #include linux/slab.h
 
+struct component_match {
+   size_t alloc;
+   size_t num;
+   struct {
+   void *data;
+   int (*fn)(struct device *, void *);
+   } compare[0];
+};
+
 struct master {
struct list_head node;
struct list_head components;
@@ -25,6 +34,7 @@ struct master {
 
const struct component_master_ops *ops;
struct device *dev;
+   struct component_match *match;
 };
 
 struct component {
@@ -96,6 +106,34 @@ int component_master_add_child(struct master *master,
 }
 EXPORT_SYMBOL_GPL(component_master_add_child);
 
+static int find_components(struct master *master)
+{
+   struct component_match *match = master-match;
+   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.
+*/
+   for (i = 0; i  match-num; i++) {
+   ret = component_master_add_child(master,
+match-compare[i].fn,
+match-compare[i].data);
+   if (ret)
+   break;
+   }
+   return ret;
+}
+
 /* Detach all attached components from this master */
 static void master_remove_components(struct master *master)
 {
@@ -128,7 +166,7 @@ static int try_to_bring_up_master(struct master *master,
 * Search the list of components, looking for components that
 * belong to this master, and attach them to the master.
 */
-   if (master-ops-add_components(master-dev, master)) {
+   if (find_components(master)) {
/* Failed to find all components */
ret = 0;
goto out;
@@ -186,18 +224,87 @@ static void take_down_master(struct master *master)
master_remove_components(master);
 }
 
-int component_master_add(struct device *dev,
-   const struct component_master_ops *ops)
+static size_t component_match_size(size_t num)
+{
+   return offsetof(struct component_match, compare[num]);
+}
+
+static struct component_match *component_match_realloc(struct device *dev,
+   struct component_match *match, size_t num)
+{
+   struct component_match *new;
+
+   if (match  match-alloc == num)
+   return match;
+
+   new = devm_kmalloc(dev, component_match_size(num), GFP_KERNEL);
+   if (!new)
+   return ERR_PTR(-ENOMEM);
+
+   if (match) {
+   memcpy(new, match, component_match_size(min(match-num, num)));
+   devm_kfree(dev, match);
+   } else {
+   new-num = 0;
+   }
+
+   new-alloc = num;
+
+   return new;
+}
+
+/*
+ * Add a component to be matched.
+ *
+ * The match array is first created or extended if necessary.
+ */
+void component_match_add(struct device *dev, struct component_match **matchptr,
+   int (*compare)(struct device *, void *), void *compare_data)
+{
+   struct component_match *match = *matchptr;
+
+   if (IS_ERR(match))
+   return;
+
+   if (!match || match-num == match-alloc) {
+   size_t new_size = match ? match-alloc + 16 : 15;
+
+   match = component_match_realloc(dev, match, new_size);
+
+   *matchptr = match;
+
+   if (IS_ERR(match))
+   return;
+   }
+
+   match-compare[match-num].fn = compare;
+   match-compare[match-num].data = compare_data;
+   match-num++;
+}
+EXPORT_SYMBOL(component_match_add);
+
+int component_master_add_with_match(struct device *dev,
+   const struct component_master_ops *ops,
+   struct component_match *match)
 {
struct master *master;
int ret;
 
+   if (ops-add_components  match)
+   return -EINVAL;
+
+   /* Reallocate the match array for its