| #include <linux/string.h> |
| #include <linux/err.h> |
| #include <linux/slab.h> |
| #include <linux/of.h> |
| |
| #include "of_helpers.h" |
| |
| /** |
| * pseries_of_derive_parent - basically like dirname(1) |
| * @path: the full_name of a node to be added to the tree |
| * |
| * Returns the node which should be the parent of the node |
| * described by path. E.g., for path = "/foo/bar", returns |
| * the node with full_name = "/foo". |
| */ |
| struct device_node *pseries_of_derive_parent(const char *path) |
| { |
| struct device_node *parent; |
| char *parent_path = "/"; |
| const char *tail; |
| |
| /* We do not want the trailing '/' character */ |
| tail = kbasename(path) - 1; |
| |
| /* reject if path is "/" */ |
| if (!strcmp(path, "/")) |
| return ERR_PTR(-EINVAL); |
| |
| if (tail > path) { |
| parent_path = kstrndup(path, tail - path, GFP_KERNEL); |
| if (!parent_path) |
| return ERR_PTR(-ENOMEM); |
| } |
| parent = of_find_node_by_path(parent_path); |
| if (strcmp(parent_path, "/")) |
| kfree(parent_path); |
| return parent ? parent : ERR_PTR(-EINVAL); |
| } |