Path: blob/master/arch/powerpc/platforms/pseries/of_helpers.c
26481 views
// SPDX-License-Identifier: GPL-2.01#include <linux/string.h>2#include <linux/err.h>3#include <linux/slab.h>4#include <linux/of.h>5#include <asm/prom.h>67#include "of_helpers.h"89/**10* pseries_of_derive_parent - basically like dirname(1)11* @path: the full_name of a node to be added to the tree12*13* Returns the node which should be the parent of the node14* described by path. E.g., for path = "/foo/bar", returns15* the node with full_name = "/foo".16*/17struct device_node *pseries_of_derive_parent(const char *path)18{19struct device_node *parent;20char *parent_path = "/";21const char *tail;2223/* We do not want the trailing '/' character */24tail = kbasename(path) - 1;2526/* reject if path is "/" */27if (!strcmp(path, "/"))28return ERR_PTR(-EINVAL);2930if (tail > path) {31parent_path = kstrndup(path, tail - path, GFP_KERNEL);32if (!parent_path)33return ERR_PTR(-ENOMEM);34}35parent = of_find_node_by_path(parent_path);36if (strcmp(parent_path, "/"))37kfree(parent_path);38return parent ? parent : ERR_PTR(-EINVAL);39}404142/* Helper Routines to convert between drc_index to cpu numbers */4344int of_read_drc_info_cell(struct property **prop, const __be32 **curval,45struct of_drc_info *data)46{47const char *p = (char *)(*curval);48const __be32 *p2;4950if (!data)51return -EINVAL;5253/* Get drc-type:encode-string */54data->drc_type = (char *)p;55p = of_prop_next_string(*prop, p);56if (!p)57return -EINVAL;5859/* Get drc-name-prefix:encode-string */60data->drc_name_prefix = (char *)p;61p = of_prop_next_string(*prop, p);62if (!p)63return -EINVAL;6465/* Get drc-index-start:encode-int */66p2 = (const __be32 *)p;67data->drc_index_start = be32_to_cpu(*p2);6869/* Get drc-name-suffix-start:encode-int */70p2 = of_prop_next_u32(*prop, p2, &data->drc_name_suffix_start);71if (!p2)72return -EINVAL;7374/* Get number-sequential-elements:encode-int */75p2 = of_prop_next_u32(*prop, p2, &data->num_sequential_elems);76if (!p2)77return -EINVAL;7879/* Get sequential-increment:encode-int */80p2 = of_prop_next_u32(*prop, p2, &data->sequential_inc);81if (!p2)82return -EINVAL;8384/* Get drc-power-domain:encode-int */85p2 = of_prop_next_u32(*prop, p2, &data->drc_power_domain);86if (!p2)87return -EINVAL;8889/* Should now know end of current entry */90(*curval) = (void *)(++p2);91data->last_drc_index = data->drc_index_start +92((data->num_sequential_elems - 1) * data->sequential_inc);9394return 0;95}96EXPORT_SYMBOL(of_read_drc_info_cell);979899