| From 62b3bbbe113631dee7b373e7032e8aba45257203 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Thu, 13 Aug 2009 18:03:01 +0200 |
| Subject: [PATCH] OF: devtree_lock needs to be taken irqsave |
| |
| commit a87f354dbe174dc43a93844f2d3bc7dd990ffb32 in tip. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| |
| diff --git a/drivers/of/base.c b/drivers/of/base.c |
| index eeead4e..ef64f7c 100644 |
| --- a/drivers/of/base.c |
| +++ b/drivers/of/base.c |
| @@ -84,10 +84,11 @@ struct property *of_find_property(const struct device_node *np, |
| int *lenp) |
| { |
| struct property *pp; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| pp = __of_find_property(np, name, lenp); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| |
| return pp; |
| } |
| @@ -170,11 +171,12 @@ static int __of_device_is_compatible(const struct device_node *device, |
| int of_device_is_compatible(const struct device_node *device, |
| const char *compat) |
| { |
| + unsigned long flags; |
| int res; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| res = __of_device_is_compatible(device, compat); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return res; |
| } |
| EXPORT_SYMBOL(of_device_is_compatible); |
| @@ -215,13 +217,14 @@ EXPORT_SYMBOL(of_device_is_available); |
| struct device_node *of_get_parent(const struct device_node *node) |
| { |
| struct device_node *np; |
| + unsigned long flags; |
| |
| if (!node) |
| return NULL; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| np = of_node_get(node->parent); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return np; |
| } |
| EXPORT_SYMBOL(of_get_parent); |
| @@ -240,14 +243,15 @@ EXPORT_SYMBOL(of_get_parent); |
| struct device_node *of_get_next_parent(struct device_node *node) |
| { |
| struct device_node *parent; |
| + unsigned long flags; |
| |
| if (!node) |
| return NULL; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| parent = of_node_get(node->parent); |
| of_node_put(node); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return parent; |
| } |
| |
| @@ -263,14 +267,15 @@ struct device_node *of_get_next_child(const struct device_node *node, |
| struct device_node *prev) |
| { |
| struct device_node *next; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| next = prev ? prev->sibling : node->child; |
| for (; next; next = next->sibling) |
| if (of_node_get(next)) |
| break; |
| of_node_put(prev); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return next; |
| } |
| EXPORT_SYMBOL(of_get_next_child); |
| @@ -285,14 +290,15 @@ EXPORT_SYMBOL(of_get_next_child); |
| struct device_node *of_find_node_by_path(const char *path) |
| { |
| struct device_node *np = allnodes; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| for (; np; np = np->allnext) { |
| if (np->full_name && (of_node_cmp(np->full_name, path) == 0) |
| && of_node_get(np)) |
| break; |
| } |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return np; |
| } |
| EXPORT_SYMBOL(of_find_node_by_path); |
| @@ -312,15 +318,16 @@ struct device_node *of_find_node_by_name(struct device_node *from, |
| const char *name) |
| { |
| struct device_node *np; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| np = from ? from->allnext : allnodes; |
| for (; np; np = np->allnext) |
| if (np->name && (of_node_cmp(np->name, name) == 0) |
| && of_node_get(np)) |
| break; |
| of_node_put(from); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return np; |
| } |
| EXPORT_SYMBOL(of_find_node_by_name); |
| @@ -341,15 +348,16 @@ struct device_node *of_find_node_by_type(struct device_node *from, |
| const char *type) |
| { |
| struct device_node *np; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| np = from ? from->allnext : allnodes; |
| for (; np; np = np->allnext) |
| if (np->type && (of_node_cmp(np->type, type) == 0) |
| && of_node_get(np)) |
| break; |
| of_node_put(from); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return np; |
| } |
| EXPORT_SYMBOL(of_find_node_by_type); |
| @@ -372,8 +380,9 @@ struct device_node *of_find_compatible_node(struct device_node *from, |
| const char *type, const char *compatible) |
| { |
| struct device_node *np; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| np = from ? from->allnext : allnodes; |
| for (; np; np = np->allnext) { |
| if (type |
| @@ -384,7 +393,7 @@ struct device_node *of_find_compatible_node(struct device_node *from, |
| break; |
| } |
| of_node_put(from); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return np; |
| } |
| EXPORT_SYMBOL(of_find_compatible_node); |
| @@ -406,8 +415,9 @@ struct device_node *of_find_node_with_property(struct device_node *from, |
| { |
| struct device_node *np; |
| struct property *pp; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| np = from ? from->allnext : allnodes; |
| for (; np; np = np->allnext) { |
| for (pp = np->properties; pp != 0; pp = pp->next) { |
| @@ -419,7 +429,7 @@ struct device_node *of_find_node_with_property(struct device_node *from, |
| } |
| out: |
| of_node_put(from); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return np; |
| } |
| EXPORT_SYMBOL(of_find_node_with_property); |
| @@ -457,10 +467,11 @@ 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; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| match = __of_match_node(matches, node); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return match; |
| } |
| EXPORT_SYMBOL(of_match_node); |
| @@ -481,15 +492,16 @@ struct device_node *of_find_matching_node(struct device_node *from, |
| const struct of_device_id *matches) |
| { |
| struct device_node *np; |
| + unsigned long flags; |
| |
| - raw_spin_lock(&devtree_lock); |
| + raw_spin_lock_irqsave(&devtree_lock, flags); |
| np = from ? from->allnext : allnodes; |
| for (; np; np = np->allnext) { |
| if (__of_match_node(matches, np) && of_node_get(np)) |
| break; |
| } |
| of_node_put(from); |
| - raw_spin_unlock(&devtree_lock); |
| + raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| return np; |
| } |
| EXPORT_SYMBOL(of_find_matching_node); |
| -- |
| 1.7.1.1 |
| |