diff options
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r-- | drivers/of/base.c | 111 |
1 files changed, 81 insertions, 30 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c index f71cda9ac09d..335d102586ac 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -415,6 +415,37 @@ int of_machine_is_compatible(const char *compat) } EXPORT_SYMBOL(of_machine_is_compatible); +static bool __of_device_is_status(const struct device_node *device, + const char * const*strings) +{ + const char *status; + int statlen; + + if (!device) + return false; + + status = __of_get_property(device, "status", &statlen); + if (status == NULL) + return false; + + if (statlen > 0) { + while (*strings) { + unsigned int len = strlen(*strings); + + if ((*strings)[len - 1] == '-') { + if (!strncmp(status, *strings, len)) + return true; + } else { + if (!strcmp(status, *strings)) + return true; + } + strings++; + } + } + + return false; +} + /** * __of_device_is_available - check if a device is available for use * @@ -425,22 +456,27 @@ EXPORT_SYMBOL(of_machine_is_compatible); */ static bool __of_device_is_available(const struct device_node *device) { - const char *status; - int statlen; + static const char * const ok[] = {"okay", "ok", NULL}; if (!device) return false; - status = __of_get_property(device, "status", &statlen); - if (status == NULL) - return true; + return !__of_get_property(device, "status", NULL) || + __of_device_is_status(device, ok); +} - if (statlen > 0) { - if (!strcmp(status, "okay") || !strcmp(status, "ok")) - return true; - } +/** + * __of_device_is_reserved - check if a device is reserved + * + * @device: Node to check for availability, with locks already held + * + * Return: True if the status property is set to "reserved", false otherwise + */ +static bool __of_device_is_reserved(const struct device_node *device) +{ + static const char * const reserved[] = {"reserved", NULL}; - return false; + return __of_device_is_status(device, reserved); } /** @@ -474,16 +510,9 @@ EXPORT_SYMBOL(of_device_is_available); */ static bool __of_device_is_fail(const struct device_node *device) { - const char *status; + static const char * const fail[] = {"fail", "fail-", NULL}; - if (!device) - return false; - - status = __of_get_property(device, "status", NULL); - if (status == NULL) - return false; - - return !strcmp(status, "fail") || !strncmp(status, "fail-", 5); + return __of_device_is_status(device, fail); } /** @@ -597,16 +626,9 @@ struct device_node *of_get_next_child(const struct device_node *node, } EXPORT_SYMBOL(of_get_next_child); -/** - * of_get_next_available_child - Find the next available child node - * @node: parent node - * @prev: previous child of the parent node, or NULL to get first - * - * This function is like of_get_next_child(), except that it - * automatically skips any disabled nodes (i.e. status = "disabled"). - */ -struct device_node *of_get_next_available_child(const struct device_node *node, - struct device_node *prev) +static struct device_node *of_get_next_status_child(const struct device_node *node, + struct device_node *prev, + bool (*checker)(const struct device_node *)) { struct device_node *next; unsigned long flags; @@ -617,7 +639,7 @@ struct device_node *of_get_next_available_child(const struct device_node *node, raw_spin_lock_irqsave(&devtree_lock, flags); next = prev ? prev->sibling : node->child; for (; next; next = next->sibling) { - if (!__of_device_is_available(next)) + if (!checker(next)) continue; if (of_node_get(next)) break; @@ -626,9 +648,38 @@ struct device_node *of_get_next_available_child(const struct device_node *node, raw_spin_unlock_irqrestore(&devtree_lock, flags); return next; } + +/** + * of_get_next_available_child - Find the next available child node + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * This function is like of_get_next_child(), except that it + * automatically skips any disabled nodes (i.e. status = "disabled"). + */ +struct device_node *of_get_next_available_child(const struct device_node *node, + struct device_node *prev) +{ + return of_get_next_status_child(node, prev, __of_device_is_available); +} EXPORT_SYMBOL(of_get_next_available_child); /** + * of_get_next_reserved_child - Find the next reserved child node + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * This function is like of_get_next_child(), except that it + * automatically skips any disabled nodes (i.e. status = "disabled"). + */ +struct device_node *of_get_next_reserved_child(const struct device_node *node, + struct device_node *prev) +{ + return of_get_next_status_child(node, prev, __of_device_is_reserved); +} +EXPORT_SYMBOL(of_get_next_reserved_child); + +/** * of_get_next_cpu_node - Iterate on cpu nodes * @prev: previous child of the /cpus node, or NULL to get first * |