diff options
author | Scott Wood <scottwood@freescale.com> | 2013-10-29 19:50:27 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2013-10-29 19:50:37 (GMT) |
commit | d0ebef8230e267ec47d4d4a65fe3262e2ebb8026 (patch) | |
tree | 24b8bb342576f543dac42d59821c4feb7ce07453 /drivers/of | |
parent | 041f2bc64a985b30328de4cb596f04fd913a85de (diff) | |
download | linux-fsl-qoriq-d0ebef8230e267ec47d4d4a65fe3262e2ebb8026.tar.xz |
Revert to v3.8 (no RT, no stable)
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/base.c | 211 |
1 files changed, 65 insertions, 146 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c index ec2fd1f..2390ddb 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -55,7 +55,7 @@ static DEFINE_MUTEX(of_aliases_mutex); /* use when traversing tree through the allnext, child, sibling, * or parent members of struct device_node. */ -DEFINE_RAW_SPINLOCK(devtree_lock); +DEFINE_RWLOCK(devtree_lock); int of_n_addr_cells(struct device_node *np) { @@ -164,14 +164,16 @@ void of_node_put(struct device_node *node) EXPORT_SYMBOL(of_node_put); #endif /* CONFIG_OF_DYNAMIC */ -static struct property *__of_find_property(const struct device_node *np, - const char *name, int *lenp) +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) @@ -179,20 +181,7 @@ static 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; - unsigned long flags; - - raw_spin_lock_irqsave(&devtree_lock, flags); - pp = __of_find_property(np, name, lenp); - raw_spin_unlock_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return pp; } @@ -210,13 +199,13 @@ struct device_node *of_find_all_nodes(struct device_node *prev) { struct device_node *np; - raw_spin_lock(&devtree_lock); + read_lock(&devtree_lock); np = prev ? prev->allnext : of_allnodes; for (; np != NULL; np = np->allnext) if (of_node_get(np)) break; of_node_put(prev); - raw_spin_unlock(&devtree_lock); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_find_all_nodes); @@ -225,20 +214,8 @@ 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); @@ -249,13 +226,13 @@ EXPORT_SYMBOL(of_get_property); /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ -static int __of_device_is_compatible(const struct device_node *device, - const char *compat) +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) { @@ -268,21 +245,6 @@ static 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) -{ - unsigned long flags; - int res; - - raw_spin_lock_irqsave(&devtree_lock, flags); - res = __of_device_is_compatible(device, compat); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - return res; -} EXPORT_SYMBOL(of_device_is_compatible); /** @@ -307,19 +269,19 @@ int of_machine_is_compatible(const char *compat) EXPORT_SYMBOL(of_machine_is_compatible); /** - * __of_device_is_available - check if a device is available for use + * of_device_is_available - check if a device is available for use * - * @device: Node to check for availability, with locks already held + * @device: Node to check for availability * * Returns 1 if the status property is absent or set to "okay" or "ok", * 0 otherwise */ -static int __of_device_is_available(const struct device_node *device) +int of_device_is_available(const struct device_node *device) { const char *status; int statlen; - status = __of_get_property(device, "status", &statlen); + status = of_get_property(device, "status", &statlen); if (status == NULL) return 1; @@ -330,26 +292,6 @@ static int __of_device_is_available(const struct device_node *device) return 0; } - -/** - * of_device_is_available - check if a device is available for use - * - * @device: Node to check for availability - * - * Returns 1 if the status property is absent or set to "okay" or "ok", - * 0 otherwise - */ -int of_device_is_available(const struct device_node *device) -{ - unsigned long flags; - int res; - - raw_spin_lock_irqsave(&devtree_lock, flags); - res = __of_device_is_available(device); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - return res; - -} EXPORT_SYMBOL(of_device_is_available); /** @@ -362,14 +304,13 @@ 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_irqsave(&devtree_lock, flags); + read_lock(&devtree_lock); np = of_node_get(node->parent); - raw_spin_unlock_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_get_parent); @@ -388,15 +329,14 @@ 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_irqsave(&devtree_lock, flags); + read_lock(&devtree_lock); parent = of_node_get(node->parent); of_node_put(node); - raw_spin_unlock_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return parent; } @@ -412,15 +352,14 @@ 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_irqsave(&devtree_lock, flags); + read_lock(&devtree_lock); next = prev ? prev->sibling : node->child; for (; next; next = next->sibling) if (of_node_get(next)) break; of_node_put(prev); - raw_spin_unlock_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return next; } EXPORT_SYMBOL(of_get_next_child); @@ -438,16 +377,16 @@ struct device_node *of_get_next_available_child(const struct device_node *node, { struct device_node *next; - raw_spin_lock(&devtree_lock); + read_lock(&devtree_lock); next = prev ? prev->sibling : node->child; for (; next; next = next->sibling) { - if (!__of_device_is_available(next)) + if (!of_device_is_available(next)) continue; if (of_node_get(next)) break; } of_node_put(prev); - raw_spin_unlock(&devtree_lock); + read_unlock(&devtree_lock); return next; } EXPORT_SYMBOL(of_get_next_available_child); @@ -485,15 +424,14 @@ EXPORT_SYMBOL(of_get_child_by_name); struct device_node *of_find_node_by_path(const char *path) { struct device_node *np = of_allnodes; - unsigned long flags; - raw_spin_lock_irqsave(&devtree_lock, flags); + read_lock(&devtree_lock); 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_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_find_node_by_path); @@ -513,16 +451,15 @@ 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_irqsave(&devtree_lock, flags); + read_lock(&devtree_lock); np = from ? from->allnext : of_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_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_find_node_by_name); @@ -543,16 +480,15 @@ 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_irqsave(&devtree_lock, flags); + read_lock(&devtree_lock); np = from ? from->allnext : of_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_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_find_node_by_type); @@ -575,20 +511,18 @@ 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_irqsave(&devtree_lock, flags); + read_lock(&devtree_lock); np = from ? from->allnext : of_allnodes; for (; np; np = np->allnext) { 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); - raw_spin_unlock_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_find_compatible_node); @@ -610,9 +544,8 @@ 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_irqsave(&devtree_lock, flags); + read_lock(&devtree_lock); np = from ? from->allnext : of_allnodes; for (; np; np = np->allnext) { for (pp = np->properties; pp; pp = pp->next) { @@ -624,14 +557,20 @@ struct device_node *of_find_node_with_property(struct device_node *from, } out: of_node_put(from); - raw_spin_unlock_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_find_node_with_property); -static -const struct of_device_id *__of_match_node(const struct of_device_id *matches, - const struct device_node *node) +/** + * 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) { if (!matches) return NULL; @@ -645,33 +584,14 @@ 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; - unsigned long flags; - - raw_spin_lock_irqsave(&devtree_lock, flags); - match = __of_match_node(matches, node); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - return match; -} EXPORT_SYMBOL(of_match_node); /** @@ -692,22 +612,21 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from, const struct of_device_id **match) { struct device_node *np; - unsigned long flags; if (match) *match = NULL; - raw_spin_lock_irqsave(&devtree_lock, flags); + 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; } } of_node_put(from); - raw_spin_unlock_irqrestore(&devtree_lock, flags); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_find_matching_node_and_match); @@ -750,12 +669,12 @@ struct device_node *of_find_node_by_phandle(phandle handle) { struct device_node *np; - raw_spin_lock(&devtree_lock); + read_lock(&devtree_lock); for (np = of_allnodes; np; np = np->allnext) if (np->phandle == handle) break; of_node_get(np); - raw_spin_unlock(&devtree_lock); + read_unlock(&devtree_lock); return np; } EXPORT_SYMBOL(of_find_node_by_phandle); @@ -1227,18 +1146,18 @@ int of_add_property(struct device_node *np, struct property *prop) return rc; prop->next = NULL; - raw_spin_lock_irqsave(&devtree_lock, flags); + write_lock_irqsave(&devtree_lock, flags); next = &np->properties; while (*next) { if (strcmp(prop->name, (*next)->name) == 0) { /* duplicate ! don't insert it */ - raw_spin_unlock_irqrestore(&devtree_lock, flags); + write_unlock_irqrestore(&devtree_lock, flags); return -1; } next = &(*next)->next; } *next = prop; - raw_spin_unlock_irqrestore(&devtree_lock, flags); + write_unlock_irqrestore(&devtree_lock, flags); #ifdef CONFIG_PROC_DEVICETREE /* try to add to proc as well if it was initialized */ @@ -1268,7 +1187,7 @@ int of_remove_property(struct device_node *np, struct property *prop) if (rc) return rc; - raw_spin_lock_irqsave(&devtree_lock, flags); + write_lock_irqsave(&devtree_lock, flags); next = &np->properties; while (*next) { if (*next == prop) { @@ -1281,7 +1200,7 @@ int of_remove_property(struct device_node *np, struct property *prop) } next = &(*next)->next; } - raw_spin_unlock_irqrestore(&devtree_lock, flags); + write_unlock_irqrestore(&devtree_lock, flags); if (!found) return -ENODEV; @@ -1321,7 +1240,7 @@ int of_update_property(struct device_node *np, struct property *newprop) if (!oldprop) return of_add_property(np, newprop); - raw_spin_lock_irqsave(&devtree_lock, flags); + write_lock_irqsave(&devtree_lock, flags); next = &np->properties; while (*next) { if (*next == oldprop) { @@ -1335,7 +1254,7 @@ int of_update_property(struct device_node *np, struct property *newprop) } next = &(*next)->next; } - raw_spin_unlock_irqrestore(&devtree_lock, flags); + write_unlock_irqrestore(&devtree_lock, flags); if (!found) return -ENODEV; @@ -1408,12 +1327,12 @@ int of_attach_node(struct device_node *np) if (rc) return rc; - raw_spin_lock_irqsave(&devtree_lock, flags); + write_lock_irqsave(&devtree_lock, flags); np->sibling = np->parent->child; np->allnext = of_allnodes; np->parent->child = np; of_allnodes = np; - raw_spin_unlock_irqrestore(&devtree_lock, flags); + write_unlock_irqrestore(&devtree_lock, flags); of_add_proc_dt_entry(np); return 0; @@ -1456,17 +1375,17 @@ int of_detach_node(struct device_node *np) if (rc) return rc; - raw_spin_lock_irqsave(&devtree_lock, flags); + write_lock_irqsave(&devtree_lock, flags); if (of_node_check_flag(np, OF_DETACHED)) { /* someone already detached it */ - raw_spin_unlock_irqrestore(&devtree_lock, flags); + write_unlock_irqrestore(&devtree_lock, flags); return rc; } parent = np->parent; if (!parent) { - raw_spin_unlock_irqrestore(&devtree_lock, flags); + write_unlock_irqrestore(&devtree_lock, flags); return rc; } @@ -1493,7 +1412,7 @@ int of_detach_node(struct device_node *np) } of_node_set_flag(np, OF_DETACHED); - raw_spin_unlock_irqrestore(&devtree_lock, flags); + write_unlock_irqrestore(&devtree_lock, flags); of_remove_proc_dt_entry(np); return rc; |