1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/string.h> 3 #include <linux/err.h> 4 #include <linux/slab.h> 5 #include <linux/of.h> 6 7 #include "of_helpers.h" 8 9 /** 10 * pseries_of_derive_parent - basically like dirname(1) 11 * @path: the full_name of a node to be added to the tree 12 * 13 * Returns the node which should be the parent of the node 14 * described by path. E.g., for path = "/foo/bar", returns 15 * the node with full_name = "/foo". 16 */ 17 struct device_node *pseries_of_derive_parent(const char *path) 18 { 19 struct device_node *parent; 20 char *parent_path = "/"; 21 const char *tail; 22 23 /* We do not want the trailing '/' character */ 24 tail = kbasename(path) - 1; 25 26 /* reject if path is "/" */ 27 if (!strcmp(path, "/")) 28 return ERR_PTR(-EINVAL); 29 30 if (tail > path) { 31 parent_path = kstrndup(path, tail - path, GFP_KERNEL); 32 if (!parent_path) 33 return ERR_PTR(-ENOMEM); 34 } 35 parent = of_find_node_by_path(parent_path); 36 if (strcmp(parent_path, "/")) 37 kfree(parent_path); 38 return parent ? parent : ERR_PTR(-EINVAL); 39 } 40