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