^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Procedures for creating, accessing and interpreting the device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Paul Mackerras August 1996.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1996-2005 Paul Mackerras.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * {engebret|bergner}@us.ibm.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Grant Likely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define pr_fmt(fmt) "OF: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "of_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) LIST_HEAD(aliases_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct device_node *of_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) EXPORT_SYMBOL(of_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct device_node *of_chosen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct device_node *of_aliases;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct device_node *of_stdout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static const char *of_stdout_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct kset *of_kset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Used to protect the of_aliases, to hold off addition of nodes to sysfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * This mutex must be held whenever modifications are being made to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * device tree. The of_{attach,detach}_node() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * of_{add,remove,update}_property() helpers make sure this happens.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) DEFINE_MUTEX(of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* use when traversing tree through the child, sibling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * or parent members of struct device_node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) DEFINE_RAW_SPINLOCK(devtree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) bool of_node_name_eq(const struct device_node *np, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) const char *node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) node_name = kbasename(np->full_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) len = strchrnul(node_name, '@') - node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return (strlen(name) == len) && (strncmp(node_name, name, len) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) EXPORT_SYMBOL(of_node_name_eq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bool of_node_name_prefix(const struct device_node *np, const char *prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return strncmp(kbasename(np->full_name), prefix, strlen(prefix)) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) EXPORT_SYMBOL(of_node_name_prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static bool __of_node_is_type(const struct device_node *np, const char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const char *match = __of_get_property(np, "device_type", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return np && match && type && !strcmp(match, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int of_bus_n_addr_cells(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u32 cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) for (; np; np = np->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (!of_property_read_u32(np, "#address-cells", &cells))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* No #address-cells property for the root node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int of_n_addr_cells(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (np->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) np = np->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return of_bus_n_addr_cells(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) EXPORT_SYMBOL(of_n_addr_cells);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int of_bus_n_size_cells(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u32 cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) for (; np; np = np->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!of_property_read_u32(np, "#size-cells", &cells))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* No #size-cells property for the root node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int of_n_size_cells(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (np->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) np = np->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return of_bus_n_size_cells(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) EXPORT_SYMBOL(of_n_size_cells);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int __weak of_node_to_nid(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return NUMA_NO_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define OF_PHANDLE_CACHE_BITS 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define OF_PHANDLE_CACHE_SZ BIT(OF_PHANDLE_CACHE_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static struct device_node *phandle_cache[OF_PHANDLE_CACHE_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static u32 of_phandle_cache_hash(phandle handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return hash_32(handle, OF_PHANDLE_CACHE_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Caller must hold devtree_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) void __of_phandle_cache_inv_entry(phandle handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u32 handle_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) handle_hash = of_phandle_cache_hash(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) np = phandle_cache[handle_hash];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (np && handle == np->phandle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) phandle_cache[handle_hash] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) void __init of_core_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Create the kset, and register existing nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mutex_lock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (!of_kset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mutex_unlock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) pr_err("failed to register existing nodes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) for_each_of_allnodes(np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) __of_attach_node_sysfs(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (np->phandle && !phandle_cache[of_phandle_cache_hash(np->phandle)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) phandle_cache[of_phandle_cache_hash(np->phandle)] = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) mutex_unlock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Symlink in /proc as required by userspace ABI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (of_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static struct property *__of_find_property(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) const char *name, int *lenp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct property *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) for (pp = np->properties; pp; pp = pp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (of_prop_cmp(pp->name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (lenp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *lenp = pp->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct property *of_find_property(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int *lenp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct property *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pp = __of_find_property(np, name, lenp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) EXPORT_SYMBOL(of_find_property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct device_node *__of_find_all_nodes(struct device_node *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (!prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) np = of_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) } else if (prev->child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) np = prev->child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Walk back up looking for a sibling, or the end of the structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) np = prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) while (np->parent && !np->sibling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) np = np->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) np = np->sibling; /* Might be null at the end of the tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * of_find_all_nodes - Get next node in global list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * @prev: Previous node or NULL to start iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * of_node_put() will be called on it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct device_node *of_find_all_nodes(struct device_node *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) np = __of_find_all_nodes(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) of_node_get(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) of_node_put(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) EXPORT_SYMBOL(of_find_all_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * Find a property with a given name for a given node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * and return the value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) const void *__of_get_property(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) const char *name, int *lenp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct property *pp = __of_find_property(np, name, lenp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return pp ? pp->value : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Find a property with a given name for a given node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * and return the value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) const void *of_get_property(const struct device_node *np, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int *lenp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct property *pp = of_find_property(np, name, lenp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return pp ? pp->value : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) EXPORT_SYMBOL(of_get_property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * arch_match_cpu_phys_id - Match the given logical CPU and physical id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * @cpu: logical cpu index of a core/thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @phys_id: physical identifier of a core/thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * CPU logical to physical index mapping is architecture specific.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * However this __weak function provides a default match of physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * id to logical cpu index. phys_id provided here is usually values read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * from the device tree which must match the hardware internal registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * Returns true if the physical identifier and the logical cpu index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * correspond to the same core/thread, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return (u32)phys_id == cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Checks if the given "prop_name" property holds the physical id of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * NULL, local thread number within the core is returned in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static bool __of_find_n_match_cpu_property(struct device_node *cpun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) const char *prop_name, int cpu, unsigned int *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) const __be32 *cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int ac, prop_len, tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) u64 hwid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ac = of_n_addr_cells(cpun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) cell = of_get_property(cpun, prop_name, &prop_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!cell && !ac && arch_match_cpu_phys_id(cpu, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (!cell || !ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) prop_len /= sizeof(*cell) * ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) for (tid = 0; tid < prop_len; tid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) hwid = of_read_number(cell, ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (arch_match_cpu_phys_id(cpu, hwid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) *thread = tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) cell += ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * arch_find_n_match_cpu_physical_id - See if the given device node is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * for the cpu corresponding to logical cpu 'cpu'. Return true if so,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * else false. If 'thread' is non-NULL, the local thread number within the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * core is returned in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int cpu, unsigned int *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* Check for non-standard "ibm,ppc-interrupt-server#s" property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * for thread ids on PowerPC. If it doesn't exist fallback to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * standard "reg" property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (IS_ENABLED(CONFIG_PPC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) __of_find_n_match_cpu_property(cpun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) "ibm,ppc-interrupt-server#s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) cpu, thread))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return __of_find_n_match_cpu_property(cpun, "reg", cpu, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * of_get_cpu_node - Get device node associated with the given logical CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * @cpu: CPU number(logical index) for which device node is required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * @thread: if not NULL, local thread number within the physical core is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * The main purpose of this function is to retrieve the device node for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * given logical CPU index. It should be used to initialize the of_node in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * cpu device. Once of_node in cpu device is populated, all the further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * references can use that instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * CPU logical to physical index mapping is architecture specific and is built
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * before booting secondary cores. This function uses arch_match_cpu_phys_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * which can be overridden by architecture specific implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Returns a node pointer for the logical cpu with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * of_node_put() on it when done. Returns NULL if not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct device_node *cpun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) for_each_of_cpu_node(cpun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return cpun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) EXPORT_SYMBOL(of_get_cpu_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * of_cpu_node_to_id: Get the logical CPU number for a given device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * @cpu_node: Pointer to the device_node for CPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * Returns the logical CPU number of the given CPU device_node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * Returns -ENODEV if the CPU is not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) int of_cpu_node_to_id(struct device_node *cpu_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) np = of_cpu_device_node_get(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) found = (cpu_node == np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) EXPORT_SYMBOL(of_cpu_node_to_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * of_get_cpu_state_node - Get CPU's idle state node at the given index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * @cpu_node: The device node for the CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * @index: The index in the list of the idle states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * Two generic methods can be used to describe a CPU's idle states, either via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * a flattened description through the "cpu-idle-states" binding or via the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * hierarchical layout, using the "power-domains" and the "domain-idle-states"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * bindings. This function check for both and returns the idle state node for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * the requested index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * In case an idle state node is found at @index, the refcount is incremented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * for it, so call of_node_put() on it when done. Returns NULL if not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct of_phandle_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) err = of_parse_phandle_with_args(cpu_node, "power-domains",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) "#power-domain-cells", 0, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct device_node *state_node =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) of_parse_phandle(args.np, "domain-idle-states", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) of_node_put(args.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (state_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return state_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return of_parse_phandle(cpu_node, "cpu-idle-states", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) EXPORT_SYMBOL(of_get_cpu_state_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * __of_device_is_compatible() - Check if the node matches given constraints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * @device: pointer to node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * @compat: required compatible string, NULL or "" for any match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * @type: required device_type value, NULL or "" for any match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * @name: required node name, NULL or "" for any match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * Checks if the given @compat, @type and @name strings match the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * properties of the given @device. A constraints can be skipped by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * passing NULL or an empty string as the constraint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * Returns 0 for no match, and a positive integer on match. The return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * value is a relative score with larger values indicating better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * matches. The score is weighted for the most specific compatible value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * to get the highest score. Matching type is next, followed by matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * name. Practically speaking, this results in the following priority
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * order for matches:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * 1. specific compatible && type && name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * 2. specific compatible && type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * 3. specific compatible && name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * 4. specific compatible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * 5. general compatible && type && name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * 6. general compatible && type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * 7. general compatible && name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * 8. general compatible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * 9. type && name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * 10. type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * 11. name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int __of_device_is_compatible(const struct device_node *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) const char *compat, const char *type, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) const char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int index = 0, score = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Compatible match has highest priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (compat && compat[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) prop = __of_find_property(device, "compatible", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) for (cp = of_prop_next_string(prop, NULL); cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) cp = of_prop_next_string(prop, cp), index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) score = INT_MAX/2 - (index << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!score)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* Matching type is better than matching name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (type && type[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (!__of_node_is_type(device, type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) score += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Matching name is a bit better than not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (name && name[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!of_node_name_eq(device, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) score++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return score;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /** Checks if the given "compat" string matches one of the strings in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * the device's "compatible" property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int of_device_is_compatible(const struct device_node *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) const char *compat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) res = __of_device_is_compatible(device, compat, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) EXPORT_SYMBOL(of_device_is_compatible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /** Checks if the device is compatible with any of the entries in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * a NULL terminated array of strings. Returns the best match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * score or 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int of_device_compatible_match(struct device_node *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) const char *const *compat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) unsigned int tmp, score = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (!compat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) while (*compat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) tmp = of_device_is_compatible(device, *compat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (tmp > score)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) score = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) compat++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return score;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * of_machine_is_compatible - Test root of device tree for a given compatible value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * @compat: compatible string to look for in root node's compatible property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * Returns a positive integer if the root node has the given value in its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * compatible property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int of_machine_is_compatible(const char *compat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct device_node *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) root = of_find_node_by_path("/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) rc = of_device_is_compatible(root, compat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) of_node_put(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) EXPORT_SYMBOL(of_machine_is_compatible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * __of_device_is_available - check if a device is available for use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * @device: Node to check for availability, with locks already held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * Returns true if the status property is absent or set to "okay" or "ok",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static bool __of_device_is_available(const struct device_node *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) const char *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int statlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (!device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) status = __of_get_property(device, "status", &statlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (status == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (statlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (!strcmp(status, "okay") || !strcmp(status, "ok"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * of_device_is_available - check if a device is available for use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * @device: Node to check for availability
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * Returns true if the status property is absent or set to "okay" or "ok",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) bool of_device_is_available(const struct device_node *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) bool res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) res = __of_device_is_available(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) EXPORT_SYMBOL(of_device_is_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * of_device_is_big_endian - check if a device has BE registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * @device: Node to check for endianness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * Returns true if the device has a "big-endian" property, or if the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * was compiled for BE *and* the device has a "native-endian" property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * Returns false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * Callers would nominally use ioread32be/iowrite32be if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * of_device_is_big_endian() == true, or readl/writel otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) bool of_device_is_big_endian(const struct device_node *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (of_property_read_bool(device, "big-endian"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) of_property_read_bool(device, "native-endian"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) EXPORT_SYMBOL(of_device_is_big_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * of_get_parent - Get a node's parent if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * @node: Node to get parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct device_node *of_get_parent(const struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) np = of_node_get(node->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) EXPORT_SYMBOL(of_get_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * of_get_next_parent - Iterate to a node's parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * @node: Node to get parent of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * This is like of_get_parent() except that it drops the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * refcount on the passed node, making it suitable for iterating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * through a node's parents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct device_node *of_get_next_parent(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct device_node *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) parent = of_node_get(node->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) EXPORT_SYMBOL(of_get_next_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static struct device_node *__of_get_next_child(const struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct device_node *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct device_node *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) next = prev ? prev->sibling : node->child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) for (; next; next = next->sibling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (of_node_get(next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) of_node_put(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) #define __for_each_child_of_node(parent, child) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) for (child = __of_get_next_child(parent, NULL); child != NULL; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) child = __of_get_next_child(parent, child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * of_get_next_child - Iterate a node childs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * @node: parent node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * @prev: previous child of the parent node, or NULL to get first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * Returns a node pointer with refcount incremented, use of_node_put() on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * it when done. Returns NULL when prev is the last child. Decrements the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * refcount of prev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct device_node *of_get_next_child(const struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct device_node *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct device_node *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) next = __of_get_next_child(node, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) EXPORT_SYMBOL(of_get_next_child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * of_get_next_available_child - Find the next available child node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * @node: parent node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * @prev: previous child of the parent node, or NULL to get first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * This function is like of_get_next_child(), except that it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * automatically skips any disabled nodes (i.e. status = "disabled").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct device_node *of_get_next_available_child(const struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct device_node *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct device_node *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) next = prev ? prev->sibling : node->child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) for (; next; next = next->sibling) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (!__of_device_is_available(next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (of_node_get(next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) of_node_put(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) EXPORT_SYMBOL(of_get_next_available_child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * of_get_next_cpu_node - Iterate on cpu nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * @prev: previous child of the /cpus node, or NULL to get first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * Returns a cpu node pointer with refcount incremented, use of_node_put()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * on it when done. Returns NULL when prev is the last child. Decrements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * the refcount of prev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct device_node *of_get_next_cpu_node(struct device_node *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct device_node *next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) node = of_find_node_by_path("/cpus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) next = prev->sibling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) else if (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) next = node->child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) for (; next; next = next->sibling) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!(of_node_name_eq(next, "cpu") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) __of_node_is_type(next, "cpu")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (of_node_get(next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) of_node_put(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) EXPORT_SYMBOL(of_get_next_cpu_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * of_get_compatible_child - Find compatible child node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * @parent: parent node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * @compatible: compatible string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * Lookup child node whose compatible property contains the given compatible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * Returns a node pointer with refcount incremented, use of_node_put() on it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * when done; or NULL if not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct device_node *of_get_compatible_child(const struct device_node *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) const char *compatible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) for_each_child_of_node(parent, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (of_device_is_compatible(child, compatible))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) EXPORT_SYMBOL(of_get_compatible_child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * of_get_child_by_name - Find the child node by name for a given parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * @node: parent node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * @name: child name to look for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * This function looks for child node for given matching name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * Returns a node pointer if found, with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * Returns NULL if node is not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct device_node *of_get_child_by_name(const struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) for_each_child_of_node(node, child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (of_node_name_eq(child, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) EXPORT_SYMBOL(of_get_child_by_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct device_node *__of_find_node_by_path(struct device_node *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) const char *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) len = strcspn(path, "/:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) __for_each_child_of_node(parent, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) const char *name = kbasename(child->full_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (strncmp(path, name, len) == 0 && (strlen(name) == len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct device_node *__of_find_node_by_full_path(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) const char *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) const char *separator = strchr(path, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) while (node && *path == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct device_node *tmp = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) path++; /* Increment past '/' delimiter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) node = __of_find_node_by_path(node, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) of_node_put(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) path = strchrnul(path, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (separator && separator < path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * of_find_node_opts_by_path - Find a node matching a full OF path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * @path: Either the full path to match, or if the path does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * start with '/', the name of a property of the /aliases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * node (an alias). In the case of an alias, the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * matching the alias' value will be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * @opts: Address of a pointer into which to store the start of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * an options string appended to the end of the path with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * a ':' separator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * Valid paths:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * /foo/bar Full path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * foo Valid alias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * foo/bar Valid alias + relative path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) struct device_node *of_find_node_opts_by_path(const char *path, const char **opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct device_node *np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct property *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) const char *separator = strchr(path, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) *opts = separator ? separator + 1 : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (strcmp(path, "/") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return of_node_get(of_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* The path could begin with an alias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (*path != '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) const char *p = separator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) p = strchrnul(path, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) len = p - path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) /* of_aliases must not be NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (!of_aliases)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) for_each_property_of_node(of_aliases, pp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) np = of_find_node_by_path(pp->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) path = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /* Step down the tree matching path components */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) np = of_node_get(of_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) np = __of_find_node_by_full_path(np, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) EXPORT_SYMBOL(of_find_node_opts_by_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * of_find_node_by_name - Find a node by its "name" property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * @from: The node to start searching from or NULL; the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * you pass will not be searched, only the next one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * will. Typically, you pass what the previous call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * returned. of_node_put() will be called on @from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * @name: The name string to match against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) struct device_node *of_find_node_by_name(struct device_node *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) for_each_of_allnodes_from(from, np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (of_node_name_eq(np, name) && of_node_get(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) of_node_put(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) EXPORT_SYMBOL(of_find_node_by_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * of_find_node_by_type - Find a node by its "device_type" property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * @from: The node to start searching from, or NULL to start searching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * the entire device tree. The node you pass will not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * searched, only the next one will; typically, you pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * what the previous call returned. of_node_put() will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * called on from for you.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * @type: The type string to match against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct device_node *of_find_node_by_type(struct device_node *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) const char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) for_each_of_allnodes_from(from, np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (__of_node_is_type(np, type) && of_node_get(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) of_node_put(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) EXPORT_SYMBOL(of_find_node_by_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * of_find_compatible_node - Find a node based on type and one of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * tokens in its "compatible" property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * @from: The node to start searching from or NULL, the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) * you pass will not be searched, only the next one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * will; typically, you pass what the previous call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * returned. of_node_put() will be called on it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * @type: The type string to match "device_type" or NULL to ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * @compatible: The string to match to one of the tokens in the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * "compatible" list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct device_node *of_find_compatible_node(struct device_node *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) const char *type, const char *compatible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) for_each_of_allnodes_from(from, np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (__of_device_is_compatible(np, compatible, type, NULL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) of_node_get(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) of_node_put(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) EXPORT_SYMBOL(of_find_compatible_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * of_find_node_with_property - Find a node which has a property with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * the given name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * @from: The node to start searching from or NULL, the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) * you pass will not be searched, only the next one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * will; typically, you pass what the previous call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * returned. of_node_put() will be called on it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * @prop_name: The name of the property to look for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct device_node *of_find_node_with_property(struct device_node *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) const char *prop_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct property *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) for_each_of_allnodes_from(from, np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) for (pp = np->properties; pp; pp = pp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (of_prop_cmp(pp->name, prop_name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) of_node_get(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) of_node_put(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) EXPORT_SYMBOL(of_find_node_with_property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) const struct of_device_id *__of_match_node(const struct of_device_id *matches,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) const struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) const struct of_device_id *best_match = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) int score, best_score = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!matches)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) score = __of_device_is_compatible(node, matches->compatible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) matches->type, matches->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (score > best_score) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) best_match = matches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) best_score = score;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return best_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * of_match_node - Tell if a device_node has a matching of_match structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * @matches: array of of device match structures to search in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * @node: the of device structure to match against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) * Low level utility function used by device matching.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) const struct of_device_id *of_match_node(const struct of_device_id *matches,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) const struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) match = __of_match_node(matches, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) EXPORT_SYMBOL(of_match_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * of_find_matching_node_and_match - Find a node based on an of_device_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * match table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * @from: The node to start searching from or NULL, the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * you pass will not be searched, only the next one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * will; typically, you pass what the previous call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * returned. of_node_put() will be called on it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * @matches: array of of device match structures to search in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) * @match Updated to point at the matches entry which matched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct device_node *of_find_matching_node_and_match(struct device_node *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) const struct of_device_id *matches,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) const struct of_device_id **match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) const struct of_device_id *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) *match = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) for_each_of_allnodes_from(from, np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) m = __of_match_node(matches, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (m && of_node_get(np)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) *match = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) of_node_put(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) EXPORT_SYMBOL(of_find_matching_node_and_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) * of_modalias_node - Lookup appropriate modalias for a device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) * @node: pointer to a device tree node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) * @modalias: Pointer to buffer that modalias value will be copied into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) * @len: Length of modalias value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) * Based on the value of the compatible property, this routine will attempt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * to choose an appropriate modalias value for a particular device tree node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * It does this by stripping the manufacturer prefix (as delimited by a ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * from the first entry in the compatible list property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * This routine returns 0 on success, <0 on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) int of_modalias_node(struct device_node *node, char *modalias, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) const char *compatible, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) int cplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) compatible = of_get_property(node, "compatible", &cplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (!compatible || strlen(compatible) > cplen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) p = strchr(compatible, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) strlcpy(modalias, p ? p + 1 : compatible, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) EXPORT_SYMBOL_GPL(of_modalias_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * of_find_node_by_phandle - Find a node given a phandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) * @handle: phandle of the node to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct device_node *of_find_node_by_phandle(phandle handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct device_node *np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) u32 handle_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (!handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) handle_hash = of_phandle_cache_hash(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (phandle_cache[handle_hash] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) handle == phandle_cache[handle_hash]->phandle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) np = phandle_cache[handle_hash];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) for_each_of_allnodes(np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (np->phandle == handle &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) !of_node_check_flag(np, OF_DETACHED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) phandle_cache[handle_hash] = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) of_node_get(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) EXPORT_SYMBOL(of_find_node_by_phandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) printk("%s %pOF", msg, args->np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) for (i = 0; i < args->args_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) const char delim = i ? ',' : ':';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) pr_cont("%c%08x", delim, args->args[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) int of_phandle_iterator_init(struct of_phandle_iterator *it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) const char *list_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) const char *cells_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) int cell_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) const __be32 *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) memset(it, 0, sizeof(*it));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) * one of cell_count or cells_name must be provided to determine the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) * argument length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (cell_count < 0 && !cells_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) list = of_get_property(np, list_name, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (!list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) it->cells_name = cells_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) it->cell_count = cell_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) it->parent = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) it->list_end = list + size / sizeof(*list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) it->phandle_end = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) it->cur = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) EXPORT_SYMBOL_GPL(of_phandle_iterator_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) int of_phandle_iterator_next(struct of_phandle_iterator *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) uint32_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (it->node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) of_node_put(it->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) it->node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (!it->cur || it->phandle_end >= it->list_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) it->cur = it->phandle_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) /* If phandle is 0, then it is an empty entry with no arguments. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) it->phandle = be32_to_cpup(it->cur++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (it->phandle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * Find the provider node and parse the #*-cells property to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * determine the argument length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) it->node = of_find_node_by_phandle(it->phandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (it->cells_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (!it->node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) pr_err("%pOF: could not find phandle\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) it->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (of_property_read_u32(it->node, it->cells_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) &count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) * If both cell_count and cells_name is given,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * fall back to cell_count in absence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * of the cells_name property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (it->cell_count >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) count = it->cell_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) pr_err("%pOF: could not get %s for %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) it->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) it->cells_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) it->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) count = it->cell_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * Make sure that the arguments actually fit in the remaining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * property data length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (it->cur + count > it->list_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) if (it->cells_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) pr_err("%pOF: %s = %d found %td\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) it->parent, it->cells_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) count, it->list_end - it->cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) pr_err("%pOF: phandle %s needs %d, found %td\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) it->parent, of_node_full_name(it->node),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) count, it->list_end - it->cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) it->phandle_end = it->cur + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) it->cur_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (it->node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) of_node_put(it->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) it->node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) EXPORT_SYMBOL_GPL(of_phandle_iterator_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) int of_phandle_iterator_args(struct of_phandle_iterator *it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) uint32_t *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) int i, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) count = it->cur_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (WARN_ON(size < count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) count = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) for (i = 0; i < count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) args[i] = be32_to_cpup(it->cur++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static int __of_parse_phandle_with_args(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) const char *list_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) const char *cells_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) int cell_count, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) struct of_phandle_args *out_args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) struct of_phandle_iterator it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) int rc, cur_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) /* Loop over the phandles until all the requested entry is found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) of_for_each_phandle(&it, rc, np, list_name, cells_name, cell_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * All of the error cases bail out of the loop, so at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * this point, the parsing is successful. If the requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) * index matches, then fill the out_args structure and return,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) * or return -ENOENT for an empty entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (cur_index == index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (!it.phandle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (out_args) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) c = of_phandle_iterator_args(&it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) out_args->args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) MAX_PHANDLE_ARGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) out_args->np = it.node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) out_args->args_count = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) of_node_put(it.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) /* Found it! return success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) cur_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) * Unlock node before returning result; will be one of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) * -ENOENT : index is for empty phandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) * -EINVAL : parsing error on data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) of_node_put(it.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) * of_parse_phandle - Resolve a phandle property to a device_node pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) * @np: Pointer to device node holding phandle property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) * @phandle_name: Name of property holding a phandle value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) * @index: For properties holding a table of phandles, this is the index into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) * the table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * Returns the device_node pointer with refcount incremented. Use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * of_node_put() on it when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) struct device_node *of_parse_phandle(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) const char *phandle_name, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) struct of_phandle_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) index, &args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return args.np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) EXPORT_SYMBOL(of_parse_phandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) * @np: pointer to a device tree node containing a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * @list_name: property name that contains a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * @cells_name: property name that specifies phandles' arguments count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * @index: index of a phandle to parse out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) * @out_args: optional pointer to output arguments structure (will be filled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * This function is useful to parse lists of phandles and their arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * Returns 0 on success and fills out_args, on error returns appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) * errno value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) * Caller is responsible to call of_node_put() on the returned out_args->np
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * Example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) * phandle1: node1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * #list-cells = <2>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) * phandle2: node2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) * #list-cells = <1>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) * node3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) * list = <&phandle1 1 2 &phandle2 3>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) * To get a device_node of the `node2' node you may call this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) const char *cells_name, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) struct of_phandle_args *out_args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) int cell_count = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /* If cells_name is NULL we assume a cell count of 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (!cells_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) cell_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) return __of_parse_phandle_with_args(np, list_name, cells_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) cell_count, index, out_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) EXPORT_SYMBOL(of_parse_phandle_with_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) * of_parse_phandle_with_args_map() - Find a node pointed by phandle in a list and remap it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) * @np: pointer to a device tree node containing a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * @list_name: property name that contains a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * @stem_name: stem of property names that specify phandles' arguments count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * @index: index of a phandle to parse out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * @out_args: optional pointer to output arguments structure (will be filled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * This function is useful to parse lists of phandles and their arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) * Returns 0 on success and fills out_args, on error returns appropriate errno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * value. The difference between this function and of_parse_phandle_with_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) * is that this API remaps a phandle if the node the phandle points to has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) * a <@stem_name>-map property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * Caller is responsible to call of_node_put() on the returned out_args->np
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) * pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) * Example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) * phandle1: node1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * #list-cells = <2>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) * phandle2: node2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) * #list-cells = <1>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) * phandle3: node3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) * #list-cells = <1>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * list-map = <0 &phandle2 3>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * <1 &phandle2 2>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) * <2 &phandle1 5 1>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) * list-map-mask = <0x3>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) * };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) * node4 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) * list = <&phandle1 1 2 &phandle3 0>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) * To get a device_node of the `node2' node you may call this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) * of_parse_phandle_with_args(node4, "list", "list", 1, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) int of_parse_phandle_with_args_map(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) const char *list_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) const char *stem_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) int index, struct of_phandle_args *out_args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) char *cells_name, *map_name = NULL, *mask_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) char *pass_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) struct device_node *cur, *new = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) const __be32 *map, *mask, *pass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static const __be32 dummy_mask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static const __be32 dummy_pass[] = { [0 ... MAX_PHANDLE_ARGS] = 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) __be32 initial_match_array[MAX_PHANDLE_ARGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) const __be32 *match_array = initial_match_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) int i, ret, map_len, match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) u32 list_size, new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) cells_name = kasprintf(GFP_KERNEL, "#%s-cells", stem_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (!cells_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) map_name = kasprintf(GFP_KERNEL, "%s-map", stem_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (!map_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) mask_name = kasprintf(GFP_KERNEL, "%s-map-mask", stem_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (!mask_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) pass_name = kasprintf(GFP_KERNEL, "%s-map-pass-thru", stem_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (!pass_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) ret = __of_parse_phandle_with_args(np, list_name, cells_name, -1, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) out_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /* Get the #<list>-cells property */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) cur = out_args->np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) ret = of_property_read_u32(cur, cells_name, &list_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) goto put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /* Precalculate the match array - this simplifies match loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) for (i = 0; i < list_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) initial_match_array[i] = cpu_to_be32(out_args->args[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) while (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* Get the <list>-map property */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) map = of_get_property(cur, map_name, &map_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (!map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) map_len /= sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) /* Get the <list>-map-mask property (optional) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) mask = of_get_property(cur, mask_name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (!mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) mask = dummy_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /* Iterate through <list>-map property */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) match = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) while (map_len > (list_size + 1) && !match) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) /* Compare specifiers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) match = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) for (i = 0; i < list_size; i++, map_len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) match &= !((match_array[i] ^ *map++) & mask[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) of_node_put(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) new = of_find_node_by_phandle(be32_to_cpup(map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) map++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) map_len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) /* Check if not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) goto put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (!of_device_is_available(new))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) match = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) ret = of_property_read_u32(new, cells_name, &new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) goto put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) /* Check for malformed properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (WARN_ON(new_size > MAX_PHANDLE_ARGS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) goto put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (map_len < new_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) goto put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) /* Move forward by new node's #<list>-cells amount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) map += new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) map_len -= new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) goto put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /* Get the <list>-map-pass-thru property (optional) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) pass = of_get_property(cur, pass_name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (!pass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) pass = dummy_pass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) * Successfully parsed a <list>-map translation; copy new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) * specifier into the out_args structure, keeping the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) * bits specified in <list>-map-pass-thru.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) match_array = map - new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) for (i = 0; i < new_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) __be32 val = *(map - new_size + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (i < list_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) val &= ~pass[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) val |= cpu_to_be32(out_args->args[i]) & pass[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) out_args->args[i] = be32_to_cpu(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) out_args->args_count = list_size = new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) /* Iterate again with new provider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) out_args->np = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) of_node_put(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) cur = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) of_node_put(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) of_node_put(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) kfree(mask_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) kfree(map_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) kfree(cells_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) kfree(pass_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) EXPORT_SYMBOL(of_parse_phandle_with_args_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) * @np: pointer to a device tree node containing a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) * @list_name: property name that contains a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) * @cell_count: number of argument cells following the phandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) * @index: index of a phandle to parse out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) * @out_args: optional pointer to output arguments structure (will be filled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) * This function is useful to parse lists of phandles and their arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) * Returns 0 on success and fills out_args, on error returns appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) * errno value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * Caller is responsible to call of_node_put() on the returned out_args->np
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) * pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) * Example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * phandle1: node1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) * phandle2: node2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) * node3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) * list = <&phandle1 0 2 &phandle2 2 3>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) * To get a device_node of the `node2' node you may call this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) int of_parse_phandle_with_fixed_args(const struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) const char *list_name, int cell_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) int index, struct of_phandle_args *out_args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) index, out_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) * of_count_phandle_with_args() - Find the number of phandles references in a property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) * @np: pointer to a device tree node containing a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) * @list_name: property name that contains a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) * @cells_name: property name that specifies phandles' arguments count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) * Returns the number of phandle + argument tuples within a property. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) * is a typical pattern to encode a list of phandle and variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) * arguments into a single property. The number of arguments is encoded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) * by a property in the phandle-target node. For example, a gpios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) * property would contain a list of GPIO specifies consisting of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) * phandle and 1 or more arguments. The number of arguments are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) * determined by the #gpio-cells property in the node pointed to by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) * phandle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) const char *cells_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) struct of_phandle_iterator it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) int rc, cur_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) * If cells_name is NULL we assume a cell count of 0. This makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) * counting the phandles trivial as each 32bit word in the list is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) * phandle and no arguments are to consider. So we don't iterate through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) * the list but just use the length to determine the phandle count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (!cells_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) const __be32 *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) list = of_get_property(np, list_name, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) if (!list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) return size / sizeof(*list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) rc = of_phandle_iterator_init(&it, np, list_name, cells_name, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) while ((rc = of_phandle_iterator_next(&it)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) cur_index += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) if (rc != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) return cur_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) EXPORT_SYMBOL(of_count_phandle_with_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) * __of_add_property - Add a property to a node without lock operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) int __of_add_property(struct device_node *np, struct property *prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) struct property **next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) prop->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) next = &np->properties;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) while (*next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (strcmp(prop->name, (*next)->name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) /* duplicate ! don't insert it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) next = &(*next)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) *next = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) * of_add_property - Add a property to a node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) int of_add_property(struct device_node *np, struct property *prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) mutex_lock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) rc = __of_add_property(np, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) __of_add_property_sysfs(np, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) mutex_unlock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) EXPORT_SYMBOL_GPL(of_add_property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) int __of_remove_property(struct device_node *np, struct property *prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) struct property **next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) for (next = &np->properties; *next; next = &(*next)->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) if (*next == prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (*next == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) /* found the node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) *next = prop->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) prop->next = np->deadprops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) np->deadprops = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) * of_remove_property - Remove a property from a node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) * Note that we don't actually remove it, since we have given out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) * who-knows-how-many pointers to the data using get-property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) * Instead we just move the property to the "dead properties"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) * list, so it won't be found any more.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) int of_remove_property(struct device_node *np, struct property *prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) mutex_lock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) rc = __of_remove_property(np, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) __of_remove_property_sysfs(np, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) mutex_unlock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) EXPORT_SYMBOL_GPL(of_remove_property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) int __of_update_property(struct device_node *np, struct property *newprop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) struct property **oldpropp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) struct property **next, *oldprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) for (next = &np->properties; *next; next = &(*next)->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) if (of_prop_cmp((*next)->name, newprop->name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) *oldpropp = oldprop = *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (oldprop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) /* replace the node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) newprop->next = oldprop->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) *next = newprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) oldprop->next = np->deadprops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) np->deadprops = oldprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) /* new node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) newprop->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) *next = newprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) * of_update_property - Update a property in a node, if the property does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) * not exist, add it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) * Note that we don't actually remove it, since we have given out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) * who-knows-how-many pointers to the data using get-property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) * Instead we just move the property to the "dead properties" list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) * and add the new property to the property list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) int of_update_property(struct device_node *np, struct property *newprop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) struct property *oldprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) if (!newprop->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) mutex_lock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) raw_spin_lock_irqsave(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) rc = __of_update_property(np, newprop, &oldprop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) raw_spin_unlock_irqrestore(&devtree_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) __of_update_property_sysfs(np, newprop, oldprop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) mutex_unlock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) static void of_alias_add(struct alias_prop *ap, struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) int id, const char *stem, int stem_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) ap->np = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) ap->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) strncpy(ap->stem, stem, stem_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) ap->stem[stem_len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) list_add_tail(&ap->link, &aliases_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) pr_debug("adding DT alias:%s: stem=%s id=%i node=%pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) ap->alias, ap->stem, ap->id, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) * of_alias_scan - Scan all properties of the 'aliases' node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) * The function scans all the properties of the 'aliases' node and populates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) * the global lookup table with the properties. It returns the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) * number of alias properties found, or an error code in case of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) * @dt_alloc: An allocator that provides a virtual address to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) * for storing the resulting tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) struct property *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) of_aliases = of_find_node_by_path("/aliases");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) of_chosen = of_find_node_by_path("/chosen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (of_chosen == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) of_chosen = of_find_node_by_path("/chosen@0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (of_chosen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /* linux,stdout-path and /aliases/stdout are for legacy compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) const char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (of_property_read_string(of_chosen, "stdout-path", &name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) of_property_read_string(of_chosen, "linux,stdout-path",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) &name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (IS_ENABLED(CONFIG_PPC) && !name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) of_property_read_string(of_aliases, "stdout", &name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) of_stdout = of_find_node_opts_by_path(name, &of_stdout_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (!of_aliases)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) for_each_property_of_node(of_aliases, pp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) const char *start = pp->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) const char *end = start + strlen(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) struct alias_prop *ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) int id, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) /* Skip those we do not want to proceed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (!strcmp(pp->name, "name") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) !strcmp(pp->name, "phandle") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) !strcmp(pp->name, "linux,phandle"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) np = of_find_node_by_path(pp->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) /* walk the alias backwards to extract the id and work out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) * the 'stem' string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) while (isdigit(*(end-1)) && end > start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) end--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) len = end - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (kstrtoint(end, 10, &id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) /* Allocate an alias_prop with enough space for the stem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) ap = dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) if (!ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) memset(ap, 0, sizeof(*ap) + len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) ap->alias = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) of_alias_add(ap, np, id, start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) * of_alias_get_id - Get alias id for the given device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) * @np: Pointer to the given device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) * @stem: Alias stem of the given device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) * The function travels the lookup table to get the alias id for the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) * device_node and alias stem. It returns the alias id if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) int of_alias_get_id(struct device_node *np, const char *stem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) struct alias_prop *app;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) int id = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) mutex_lock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) list_for_each_entry(app, &aliases_lookup, link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) if (strcmp(app->stem, stem) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) if (np == app->np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) id = app->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) mutex_unlock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) EXPORT_SYMBOL_GPL(of_alias_get_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) * of_alias_get_alias_list - Get alias list for the given device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) * @matches: Array of OF device match structures to search in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) * @stem: Alias stem of the given device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * @bitmap: Bitmap field pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * @nbits: Maximum number of alias IDs which can be recorded in bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * The function travels the lookup table to record alias ids for the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) * device match structures and alias stem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * Return: 0 or -ENOSYS when !CONFIG_OF or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) * -EOVERFLOW if alias ID is greater then allocated nbits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) int of_alias_get_alias_list(const struct of_device_id *matches,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) const char *stem, unsigned long *bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) unsigned int nbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) struct alias_prop *app;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) /* Zero bitmap field to make sure that all the time it is clean */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) bitmap_zero(bitmap, nbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) mutex_lock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) pr_debug("%s: Looking for stem: %s\n", __func__, stem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) list_for_each_entry(app, &aliases_lookup, link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) pr_debug("%s: stem: %s, id: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) __func__, app->stem, app->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) if (strcmp(app->stem, stem) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) pr_debug("%s: stem comparison didn't pass %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) __func__, app->stem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) if (of_match_node(matches, app->np)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) pr_debug("%s: Allocated ID %d\n", __func__, app->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) if (app->id >= nbits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) pr_warn("%s: ID %d >= than bitmap field %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) __func__, app->id, nbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) ret = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) set_bit(app->id, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) mutex_unlock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) EXPORT_SYMBOL_GPL(of_alias_get_alias_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) * of_alias_get_highest_id - Get highest alias id for the given stem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) * @stem: Alias stem to be examined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) * The function travels the lookup table to get the highest alias id for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) * given alias stem. It returns the alias id if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) int of_alias_get_highest_id(const char *stem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) struct alias_prop *app;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) int id = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) mutex_lock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) list_for_each_entry(app, &aliases_lookup, link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) if (strcmp(app->stem, stem) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (app->id > id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) id = app->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) mutex_unlock(&of_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) * of_console_check() - Test and setup console for DT setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) * @dn - Pointer to device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) * @name - Name to use for preferred console without index. ex. "ttyS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) * @index - Index to use for preferred console.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) * Check if the given device node matches the stdout-path property in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) * /chosen node. If it does then register it as the preferred console and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) * TRUE. Otherwise return FALSE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) bool of_console_check(struct device_node *dn, char *name, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) if (!dn || dn != of_stdout || console_set_on_cmdline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) * XXX: cast `options' to char pointer to suppress complication
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) * warnings: printk, UART and console drivers expect char pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) return !add_preferred_console(name, index, (char *)of_stdout_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) EXPORT_SYMBOL_GPL(of_console_check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) * of_find_next_cache_node - Find a node's subsidiary cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) * @np: node of type "cpu" or "cache"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) * Returns a node pointer with refcount incremented, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) * of_node_put() on it when done. Caller should hold a reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) * to np.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) struct device_node *of_find_next_cache_node(const struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) struct device_node *child, *cache_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) cache_node = of_parse_phandle(np, "l2-cache", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if (!cache_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) cache_node = of_parse_phandle(np, "next-level-cache", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) if (cache_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) return cache_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) /* OF on pmac has nodes instead of properties named "l2-cache"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) * beneath CPU nodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) if (IS_ENABLED(CONFIG_PPC_PMAC) && of_node_is_type(np, "cpu"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) for_each_child_of_node(np, child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) if (of_node_is_type(child, "cache"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) return child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) * of_find_last_cache_level - Find the level at which the last cache is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) * present for the given logical cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) * @cpu: cpu number(logical index) for which the last cache level is needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) * Returns the the level at which the last cache is present. It is exactly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) * same as the total number of cache levels for the given logical cpu.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) int of_find_last_cache_level(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) u32 cache_level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) struct device_node *prev = NULL, *np = of_cpu_device_node_get(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) while (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) prev = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) np = of_find_next_cache_node(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) of_property_read_u32(prev, "cache-level", &cache_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) return cache_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) * of_map_id - Translate an ID through a downstream mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) * @np: root complex device node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) * @id: device ID to map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) * @map_name: property name of the map to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) * @map_mask_name: optional property name of the mask to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) * @target: optional pointer to a target device node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) * @id_out: optional pointer to receive the translated ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) * Given a device ID, look up the appropriate implementation-defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) * platform ID and/or the target device which receives transactions on that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) * @id_out may be NULL if only the other is required. If @target points to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * a non-NULL device node pointer, only entries targeting that node will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) * matched; if it points to a NULL value, it will receive the device node of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) * the first matching target phandle, with a reference held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * Return: 0 on success or a standard error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) int of_map_id(struct device_node *np, u32 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) const char *map_name, const char *map_mask_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) struct device_node **target, u32 *id_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) u32 map_mask, masked_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) int map_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) const __be32 *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if (!np || !map_name || (!target && !id_out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) map = of_get_property(np, map_name, &map_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (!map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) if (target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) /* Otherwise, no map implies no translation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) *id_out = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) if (!map_len || map_len % (4 * sizeof(*map))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) pr_err("%pOF: Error: Bad %s length: %d\n", np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) map_name, map_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) /* The default is to select all bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) map_mask = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) * Can be overridden by "{iommu,msi}-map-mask" property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) * If of_property_read_u32() fails, the default is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) if (map_mask_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) of_property_read_u32(np, map_mask_name, &map_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) masked_id = map_mask & id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) struct device_node *phandle_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) u32 id_base = be32_to_cpup(map + 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) u32 phandle = be32_to_cpup(map + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) u32 out_base = be32_to_cpup(map + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) u32 id_len = be32_to_cpup(map + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) if (id_base & ~map_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) np, map_name, map_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) map_mask, id_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) if (masked_id < id_base || masked_id >= id_base + id_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) phandle_node = of_find_node_by_phandle(phandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) if (!phandle_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) if (target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) if (*target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) of_node_put(phandle_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) *target = phandle_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if (*target != phandle_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) if (id_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) *id_out = masked_id - id_base + out_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) np, map_name, map_mask, id_base, out_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) id_len, id, masked_id - id_base + out_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) pr_info("%pOF: no %s translation for id 0x%x on %pOF\n", np, map_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) id, target && *target ? *target : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) /* Bypasses translation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) if (id_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) *id_out = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) EXPORT_SYMBOL_GPL(of_map_id);