linux/arch/sparc/prom/tree_64.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * tree.c: Basic device tree traversal/scanning for the Linux
   4 *         prom library.
   5 *
   6 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
   7 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
   8 */
   9
  10#include <linux/string.h>
  11#include <linux/types.h>
  12#include <linux/kernel.h>
  13#include <linux/sched.h>
  14#include <linux/module.h>
  15
  16#include <asm/openprom.h>
  17#include <asm/oplib.h>
  18#include <asm/ldc.h>
  19
  20static phandle prom_node_to_node(const char *type, phandle node)
  21{
  22        unsigned long args[5];
  23
  24        args[0] = (unsigned long) type;
  25        args[1] = 1;
  26        args[2] = 1;
  27        args[3] = (unsigned int) node;
  28        args[4] = (unsigned long) -1;
  29
  30        p1275_cmd_direct(args);
  31
  32        return (phandle) args[4];
  33}
  34
  35/* Return the child of node 'node' or zero if no this node has no
  36 * direct descendent.
  37 */
  38inline phandle __prom_getchild(phandle node)
  39{
  40        return prom_node_to_node("child", node);
  41}
  42
  43phandle prom_getchild(phandle node)
  44{
  45        phandle cnode;
  46
  47        if ((s32)node == -1)
  48                return 0;
  49        cnode = __prom_getchild(node);
  50        if ((s32)cnode == -1)
  51                return 0;
  52        return cnode;
  53}
  54EXPORT_SYMBOL(prom_getchild);
  55
  56inline phandle prom_getparent(phandle node)
  57{
  58        phandle cnode;
  59
  60        if ((s32)node == -1)
  61                return 0;
  62        cnode = prom_node_to_node("parent", node);
  63        if ((s32)cnode == -1)
  64                return 0;
  65        return cnode;
  66}
  67
  68/* Return the next sibling of node 'node' or zero if no more siblings
  69 * at this level of depth in the tree.
  70 */
  71inline phandle __prom_getsibling(phandle node)
  72{
  73        return prom_node_to_node(prom_peer_name, node);
  74}
  75
  76phandle prom_getsibling(phandle node)
  77{
  78        phandle sibnode;
  79
  80        if ((s32)node == -1)
  81                return 0;
  82        sibnode = __prom_getsibling(node);
  83        if ((s32)sibnode == -1)
  84                return 0;
  85
  86        return sibnode;
  87}
  88EXPORT_SYMBOL(prom_getsibling);
  89
  90/* Return the length in bytes of property 'prop' at node 'node'.
  91 * Return -1 on error.
  92 */
  93int prom_getproplen(phandle node, const char *prop)
  94{
  95        unsigned long args[6];
  96
  97        if (!node || !prop)
  98                return -1;
  99
 100        args[0] = (unsigned long) "getproplen";
 101        args[1] = 2;
 102        args[2] = 1;
 103        args[3] = (unsigned int) node;
 104        args[4] = (unsigned long) prop;
 105        args[5] = (unsigned long) -1;
 106
 107        p1275_cmd_direct(args);
 108
 109        return (int) args[5];
 110}
 111EXPORT_SYMBOL(prom_getproplen);
 112
 113/* Acquire a property 'prop' at node 'node' and place it in
 114 * 'buffer' which has a size of 'bufsize'.  If the acquisition
 115 * was successful the length will be returned, else -1 is returned.
 116 */
 117int prom_getproperty(phandle node, const char *prop,
 118                     char *buffer, int bufsize)
 119{
 120        unsigned long args[8];
 121        int plen;
 122
 123        plen = prom_getproplen(node, prop);
 124        if ((plen > bufsize) || (plen == 0) || (plen == -1))
 125                return -1;
 126
 127        args[0] = (unsigned long) prom_getprop_name;
 128        args[1] = 4;
 129        args[2] = 1;
 130        args[3] = (unsigned int) node;
 131        args[4] = (unsigned long) prop;
 132        args[5] = (unsigned long) buffer;
 133        args[6] = bufsize;
 134        args[7] = (unsigned long) -1;
 135
 136        p1275_cmd_direct(args);
 137
 138        return (int) args[7];
 139}
 140EXPORT_SYMBOL(prom_getproperty);
 141
 142/* Acquire an integer property and return its value.  Returns -1
 143 * on failure.
 144 */
 145int prom_getint(phandle node, const char *prop)
 146{
 147        int intprop;
 148
 149        if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
 150                return intprop;
 151
 152        return -1;
 153}
 154EXPORT_SYMBOL(prom_getint);
 155
 156/* Acquire an integer property, upon error return the passed default
 157 * integer.
 158 */
 159
 160int prom_getintdefault(phandle node, const char *property, int deflt)
 161{
 162        int retval;
 163
 164        retval = prom_getint(node, property);
 165        if (retval == -1)
 166                return deflt;
 167
 168        return retval;
 169}
 170EXPORT_SYMBOL(prom_getintdefault);
 171
 172/* Acquire a boolean property, 1=TRUE 0=FALSE. */
 173int prom_getbool(phandle node, const char *prop)
 174{
 175        int retval;
 176
 177        retval = prom_getproplen(node, prop);
 178        if (retval == -1)
 179                return 0;
 180        return 1;
 181}
 182EXPORT_SYMBOL(prom_getbool);
 183
 184/* Acquire a property whose value is a string, returns a null
 185 * string on error.  The char pointer is the user supplied string
 186 * buffer.
 187 */
 188void prom_getstring(phandle node, const char *prop, char *user_buf,
 189                int ubuf_size)
 190{
 191        int len;
 192
 193        len = prom_getproperty(node, prop, user_buf, ubuf_size);
 194        if (len != -1)
 195                return;
 196        user_buf[0] = 0;
 197}
 198EXPORT_SYMBOL(prom_getstring);
 199
 200/* Does the device at node 'node' have name 'name'?
 201 * YES = 1   NO = 0
 202 */
 203int prom_nodematch(phandle node, const char *name)
 204{
 205        char namebuf[128];
 206        prom_getproperty(node, "name", namebuf, sizeof(namebuf));
 207        if (strcmp(namebuf, name) == 0)
 208                return 1;
 209        return 0;
 210}
 211
 212/* Search siblings at 'node_start' for a node with name
 213 * 'nodename'.  Return node if successful, zero if not.
 214 */
 215phandle prom_searchsiblings(phandle node_start, const char *nodename)
 216{
 217        phandle thisnode;
 218        int error;
 219        char promlib_buf[128];
 220
 221        for(thisnode = node_start; thisnode;
 222            thisnode=prom_getsibling(thisnode)) {
 223                error = prom_getproperty(thisnode, "name", promlib_buf,
 224                                         sizeof(promlib_buf));
 225                /* Should this ever happen? */
 226                if(error == -1) continue;
 227                if(strcmp(nodename, promlib_buf)==0) return thisnode;
 228        }
 229
 230        return 0;
 231}
 232EXPORT_SYMBOL(prom_searchsiblings);
 233
 234static const char *prom_nextprop_name = "nextprop";
 235
 236/* Return the first property type for node 'node'.
 237 * buffer should be at least 32B in length
 238 */
 239char *prom_firstprop(phandle node, char *buffer)
 240{
 241        unsigned long args[7];
 242
 243        *buffer = 0;
 244        if ((s32)node == -1)
 245                return buffer;
 246
 247        args[0] = (unsigned long) prom_nextprop_name;
 248        args[1] = 3;
 249        args[2] = 1;
 250        args[3] = (unsigned int) node;
 251        args[4] = 0;
 252        args[5] = (unsigned long) buffer;
 253        args[6] = (unsigned long) -1;
 254
 255        p1275_cmd_direct(args);
 256
 257        return buffer;
 258}
 259EXPORT_SYMBOL(prom_firstprop);
 260
 261/* Return the property type string after property type 'oprop'
 262 * at node 'node' .  Returns NULL string if no more
 263 * property types for this node.
 264 */
 265char *prom_nextprop(phandle node, const char *oprop, char *buffer)
 266{
 267        unsigned long args[7];
 268        char buf[32];
 269
 270        if ((s32)node == -1) {
 271                *buffer = 0;
 272                return buffer;
 273        }
 274        if (oprop == buffer) {
 275                strcpy (buf, oprop);
 276                oprop = buf;
 277        }
 278
 279        args[0] = (unsigned long) prom_nextprop_name;
 280        args[1] = 3;
 281        args[2] = 1;
 282        args[3] = (unsigned int) node;
 283        args[4] = (unsigned long) oprop;
 284        args[5] = (unsigned long) buffer;
 285        args[6] = (unsigned long) -1;
 286
 287        p1275_cmd_direct(args);
 288
 289        return buffer;
 290}
 291EXPORT_SYMBOL(prom_nextprop);
 292
 293phandle prom_finddevice(const char *name)
 294{
 295        unsigned long args[5];
 296
 297        if (!name)
 298                return 0;
 299        args[0] = (unsigned long) "finddevice";
 300        args[1] = 1;
 301        args[2] = 1;
 302        args[3] = (unsigned long) name;
 303        args[4] = (unsigned long) -1;
 304
 305        p1275_cmd_direct(args);
 306
 307        return (int) args[4];
 308}
 309EXPORT_SYMBOL(prom_finddevice);
 310
 311int prom_node_has_property(phandle node, const char *prop)
 312{
 313        char buf [32];
 314        
 315        *buf = 0;
 316        do {
 317                prom_nextprop(node, buf, buf);
 318                if (!strcmp(buf, prop))
 319                        return 1;
 320        } while (*buf);
 321        return 0;
 322}
 323EXPORT_SYMBOL(prom_node_has_property);
 324
 325/* Set property 'pname' at node 'node' to value 'value' which has a length
 326 * of 'size' bytes.  Return the number of bytes the prom accepted.
 327 */
 328int
 329prom_setprop(phandle node, const char *pname, char *value, int size)
 330{
 331        unsigned long args[8];
 332
 333        if (size == 0)
 334                return 0;
 335        if ((pname == 0) || (value == 0))
 336                return 0;
 337        
 338#ifdef CONFIG_SUN_LDOMS
 339        if (ldom_domaining_enabled) {
 340                ldom_set_var(pname, value);
 341                return 0;
 342        }
 343#endif
 344        args[0] = (unsigned long) "setprop";
 345        args[1] = 4;
 346        args[2] = 1;
 347        args[3] = (unsigned int) node;
 348        args[4] = (unsigned long) pname;
 349        args[5] = (unsigned long) value;
 350        args[6] = size;
 351        args[7] = (unsigned long) -1;
 352
 353        p1275_cmd_direct(args);
 354
 355        return (int) args[7];
 356}
 357EXPORT_SYMBOL(prom_setprop);
 358
 359inline phandle prom_inst2pkg(int inst)
 360{
 361        unsigned long args[5];
 362        phandle node;
 363        
 364        args[0] = (unsigned long) "instance-to-package";
 365        args[1] = 1;
 366        args[2] = 1;
 367        args[3] = (unsigned int) inst;
 368        args[4] = (unsigned long) -1;
 369
 370        p1275_cmd_direct(args);
 371
 372        node = (int) args[4];
 373        if ((s32)node == -1)
 374                return 0;
 375        return node;
 376}
 377
 378int prom_ihandle2path(int handle, char *buffer, int bufsize)
 379{
 380        unsigned long args[7];
 381
 382        args[0] = (unsigned long) "instance-to-path";
 383        args[1] = 3;
 384        args[2] = 1;
 385        args[3] = (unsigned int) handle;
 386        args[4] = (unsigned long) buffer;
 387        args[5] = bufsize;
 388        args[6] = (unsigned long) -1;
 389
 390        p1275_cmd_direct(args);
 391
 392        return (int) args[6];
 393}
 394