On 01/25/2013 12:21 PM, Paul Gortmaker wrote:
> From: Thomas Gleixner <t...@linutronix.de>
> 
> There is no real reason to use a rwlock for devtree_lock. It even
> could be a mutex, but unfortunately it's locked from cpu hotplug
> paths which can't schedule :(
> 
> So it needs to become a raw lock on rt as well.  The devtree_lock would
> be the only user of a raw_rw_lock, so we are better off cleaning up the
> recursive locking paths which allows us to convert devtree_lock to a
> read_lock.
> 
> Here we do the standard thing of introducing __foo() as the "raw"
> version of foo(), so that we can take better control of the locking.
> The "raw" versions are not exported and are for internal use within
> the file itself.
> 
> Signed-off-by: Thomas Gleixner <t...@linutronix.de>
> Signed-off-by: Paul Gortmaker <paul.gortma...@windriver.com>
> ---

Applied for 3.9.

Rob

> 
> [This has been living in the RT tree for several releases, and I've
>  put it on top of 3.8-rc4 mainline and tested it independently there
>  on a ppc sbc8548 board as well.  So it would be nice to get this in 3.9]
> 
>  drivers/of/base.c | 91 
> ++++++++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 70 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 2390ddb..21195a1 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -164,16 +164,14 @@ void of_node_put(struct device_node *node)
>  EXPORT_SYMBOL(of_node_put);
>  #endif /* CONFIG_OF_DYNAMIC */
>  
> -struct property *of_find_property(const struct device_node *np,
> -                               const char *name,
> -                               int *lenp)
> +static struct property *__of_find_property(const struct device_node *np,
> +                                        const char *name, int *lenp)
>  {
>       struct property *pp;
>  
>       if (!np)
>               return NULL;
>  
> -     read_lock(&devtree_lock);
>       for (pp = np->properties; pp; pp = pp->next) {
>               if (of_prop_cmp(pp->name, name) == 0) {
>                       if (lenp)
> @@ -181,6 +179,18 @@ struct property *of_find_property(const struct 
> device_node *np,
>                       break;
>               }
>       }
> +
> +     return pp;
> +}
> +
> +struct property *of_find_property(const struct device_node *np,
> +                               const char *name,
> +                               int *lenp)
> +{
> +     struct property *pp;
> +
> +     read_lock(&devtree_lock);
> +     pp = __of_find_property(np, name, lenp);
>       read_unlock(&devtree_lock);
>  
>       return pp;
> @@ -214,8 +224,20 @@ EXPORT_SYMBOL(of_find_all_nodes);
>   * Find a property with a given name for a given node
>   * and return the value.
>   */
> +static const void *__of_get_property(const struct device_node *np,
> +                                  const char *name, int *lenp)
> +{
> +     struct property *pp = __of_find_property(np, name, lenp);
> +
> +     return pp ? pp->value : NULL;
> +}
> +
> +/*
> + * Find a property with a given name for a given node
> + * and return the value.
> + */
>  const void *of_get_property(const struct device_node *np, const char *name,
> -                      int *lenp)
> +                         int *lenp)
>  {
>       struct property *pp = of_find_property(np, name, lenp);
>  
> @@ -226,13 +248,13 @@ EXPORT_SYMBOL(of_get_property);
>  /** Checks if the given "compat" string matches one of the strings in
>   * the device's "compatible" property
>   */
> -int of_device_is_compatible(const struct device_node *device,
> -             const char *compat)
> +static int __of_device_is_compatible(const struct device_node *device,
> +                                  const char *compat)
>  {
>       const char* cp;
>       int cplen, l;
>  
> -     cp = of_get_property(device, "compatible", &cplen);
> +     cp = __of_get_property(device, "compatible", &cplen);
>       if (cp == NULL)
>               return 0;
>       while (cplen > 0) {
> @@ -245,6 +267,20 @@ int of_device_is_compatible(const struct device_node 
> *device,
>  
>       return 0;
>  }
> +
> +/** Checks if the given "compat" string matches one of the strings in
> + * the device's "compatible" property
> + */
> +int of_device_is_compatible(const struct device_node *device,
> +             const char *compat)
> +{
> +     int res;
> +
> +     read_lock(&devtree_lock);
> +     res = __of_device_is_compatible(device, compat);
> +     read_unlock(&devtree_lock);
> +     return res;
> +}
>  EXPORT_SYMBOL(of_device_is_compatible);
>  
>  /**
> @@ -518,7 +554,8 @@ struct device_node *of_find_compatible_node(struct 
> device_node *from,
>               if (type
>                   && !(np->type && (of_node_cmp(np->type, type) == 0)))
>                       continue;
> -             if (of_device_is_compatible(np, compatible) && of_node_get(np))
> +             if (__of_device_is_compatible(np, compatible) &&
> +                 of_node_get(np))
>                       break;
>       }
>       of_node_put(from);
> @@ -562,15 +599,9 @@ out:
>  }
>  EXPORT_SYMBOL(of_find_node_with_property);
>  
> -/**
> - * of_match_node - Tell if an device_node has a matching of_match structure
> - *   @matches:       array of of device match structures to search in
> - *   @node:          the of device structure to match against
> - *
> - *   Low level utility function used by device matching.
> - */
> -const struct of_device_id *of_match_node(const struct of_device_id *matches,
> -                                      const struct device_node *node)
> +static
> +const struct of_device_id *__of_match_node(const struct of_device_id 
> *matches,
> +                                        const struct device_node *node)
>  {
>       if (!matches)
>               return NULL;
> @@ -584,14 +615,32 @@ const struct of_device_id *of_match_node(const struct 
> of_device_id *matches,
>                       match &= node->type
>                               && !strcmp(matches->type, node->type);
>               if (matches->compatible[0])
> -                     match &= of_device_is_compatible(node,
> -                                             matches->compatible);
> +                     match &= __of_device_is_compatible(node,
> +                                                        matches->compatible);
>               if (match)
>                       return matches;
>               matches++;
>       }
>       return NULL;
>  }
> +
> +/**
> + * of_match_node - Tell if an device_node has a matching of_match structure
> + *   @matches:       array of of device match structures to search in
> + *   @node:          the of device structure to match against
> + *
> + *   Low level utility function used by device matching.
> + */
> +const struct of_device_id *of_match_node(const struct of_device_id *matches,
> +                                      const struct device_node *node)
> +{
> +     const struct of_device_id *match;
> +
> +     read_lock(&devtree_lock);
> +     match = __of_match_node(matches, node);
> +     read_unlock(&devtree_lock);
> +     return match;
> +}
>  EXPORT_SYMBOL(of_match_node);
>  
>  /**
> @@ -619,7 +668,7 @@ struct device_node 
> *of_find_matching_node_and_match(struct device_node *from,
>       read_lock(&devtree_lock);
>       np = from ? from->allnext : of_allnodes;
>       for (; np; np = np->allnext) {
> -             if (of_match_node(matches, np) && of_node_get(np)) {
> +             if (__of_match_node(matches, np) && of_node_get(np)) {
>                       if (match)
>                               *match = matches;
>                       break;
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to