| From 180df901a3af5c0e3f41816855c125be58867d07 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| drivers/of/base.c | 60 +++++++++++++++++++++++++++++++--------------------- |
| 1 files changed, 36 insertions(+), 24 deletions(-) |
| |
| diff --git a/drivers/of/base.c b/drivers/of/base.c |
| index a05713e..075e75b 100644 |
| --- a/drivers/of/base.c |
| +++ b/drivers/of/base.c |
| @@ -162,10 +162,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; |
| } |
| @@ -248,11 +249,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); |
| @@ -314,13 +316,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); |
| @@ -339,14 +342,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; |
| } |
| |
| @@ -362,14 +366,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); |
| @@ -384,14 +389,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); |
| @@ -411,15 +417,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); |
| @@ -440,15 +447,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); |
| @@ -471,8 +479,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 |
| @@ -483,7 +492,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); |
| @@ -505,8 +514,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) { |
| @@ -518,7 +528,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); |
| @@ -556,10 +566,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); |
| @@ -580,15 +591,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.0.4 |
| |