root/arch/sparc/prom/tree_32.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __prom_getchild
  2. prom_getchild
  3. __prom_getsibling
  4. prom_getsibling
  5. prom_getproplen
  6. prom_getproperty
  7. prom_getint
  8. prom_getintdefault
  9. prom_getbool
  10. prom_getstring
  11. prom_searchsiblings
  12. __prom_nextprop
  13. prom_nextprop
  14. prom_finddevice
  15. prom_setprop
  16. prom_inst2pkg

   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  */
   8 
   9 #include <linux/string.h>
  10 #include <linux/types.h>
  11 #include <linux/kernel.h>
  12 #include <linux/sched.h>
  13 #include <linux/ctype.h>
  14 #include <linux/module.h>
  15 
  16 #include <asm/openprom.h>
  17 #include <asm/oplib.h>
  18 
  19 extern void restore_current(void);
  20 
  21 static char promlib_buf[128];
  22 
  23 /* Internal version of prom_getchild that does not alter return values. */
  24 static phandle __prom_getchild(phandle node)
  25 {
  26         unsigned long flags;
  27         phandle cnode;
  28 
  29         spin_lock_irqsave(&prom_lock, flags);
  30         cnode = prom_nodeops->no_child(node);
  31         restore_current();
  32         spin_unlock_irqrestore(&prom_lock, flags);
  33 
  34         return cnode;
  35 }
  36 
  37 /* Return the child of node 'node' or zero if no this node has no
  38  * direct descendent.
  39  */
  40 phandle prom_getchild(phandle node)
  41 {
  42         phandle cnode;
  43 
  44         if ((s32)node == -1)
  45                 return 0;
  46 
  47         cnode = __prom_getchild(node);
  48         if (cnode == 0 || (s32)cnode == -1)
  49                 return 0;
  50 
  51         return cnode;
  52 }
  53 EXPORT_SYMBOL(prom_getchild);
  54 
  55 /* Internal version of prom_getsibling that does not alter return values. */
  56 static phandle __prom_getsibling(phandle node)
  57 {
  58         unsigned long flags;
  59         phandle cnode;
  60 
  61         spin_lock_irqsave(&prom_lock, flags);
  62         cnode = prom_nodeops->no_nextnode(node);
  63         restore_current();
  64         spin_unlock_irqrestore(&prom_lock, flags);
  65 
  66         return cnode;
  67 }
  68 
  69 /* Return the next sibling of node 'node' or zero if no more siblings
  70  * at this level of depth in the tree.
  71  */
  72 phandle prom_getsibling(phandle node)
  73 {
  74         phandle sibnode;
  75 
  76         if ((s32)node == -1)
  77                 return 0;
  78 
  79         sibnode = __prom_getsibling(node);
  80         if (sibnode == 0 || (s32)sibnode == -1)
  81                 return 0;
  82 
  83         return sibnode;
  84 }
  85 EXPORT_SYMBOL(prom_getsibling);
  86 
  87 /* Return the length in bytes of property 'prop' at node 'node'.
  88  * Return -1 on error.
  89  */
  90 int prom_getproplen(phandle node, const char *prop)
  91 {
  92         int ret;
  93         unsigned long flags;
  94 
  95         if((!node) || (!prop))
  96                 return -1;
  97                 
  98         spin_lock_irqsave(&prom_lock, flags);
  99         ret = prom_nodeops->no_proplen(node, prop);
 100         restore_current();
 101         spin_unlock_irqrestore(&prom_lock, flags);
 102         return ret;
 103 }
 104 EXPORT_SYMBOL(prom_getproplen);
 105 
 106 /* Acquire a property 'prop' at node 'node' and place it in
 107  * 'buffer' which has a size of 'bufsize'.  If the acquisition
 108  * was successful the length will be returned, else -1 is returned.
 109  */
 110 int prom_getproperty(phandle node, const char *prop, char *buffer, int bufsize)
 111 {
 112         int plen, ret;
 113         unsigned long flags;
 114 
 115         plen = prom_getproplen(node, prop);
 116         if((plen > bufsize) || (plen == 0) || (plen == -1))
 117                 return -1;
 118         /* Ok, things seem all right. */
 119         spin_lock_irqsave(&prom_lock, flags);
 120         ret = prom_nodeops->no_getprop(node, prop, buffer);
 121         restore_current();
 122         spin_unlock_irqrestore(&prom_lock, flags);
 123         return ret;
 124 }
 125 EXPORT_SYMBOL(prom_getproperty);
 126 
 127 /* Acquire an integer property and return its value.  Returns -1
 128  * on failure.
 129  */
 130 int prom_getint(phandle node, char *prop)
 131 {
 132         static int intprop;
 133 
 134         if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
 135                 return intprop;
 136 
 137         return -1;
 138 }
 139 EXPORT_SYMBOL(prom_getint);
 140 
 141 /* Acquire an integer property, upon error return the passed default
 142  * integer.
 143  */
 144 int prom_getintdefault(phandle node, char *property, int deflt)
 145 {
 146         int retval;
 147 
 148         retval = prom_getint(node, property);
 149         if(retval == -1) return deflt;
 150 
 151         return retval;
 152 }
 153 EXPORT_SYMBOL(prom_getintdefault);
 154 
 155 /* Acquire a boolean property, 1=TRUE 0=FALSE. */
 156 int prom_getbool(phandle node, char *prop)
 157 {
 158         int retval;
 159 
 160         retval = prom_getproplen(node, prop);
 161         if(retval == -1) return 0;
 162         return 1;
 163 }
 164 EXPORT_SYMBOL(prom_getbool);
 165 
 166 /* Acquire a property whose value is a string, returns a null
 167  * string on error.  The char pointer is the user supplied string
 168  * buffer.
 169  */
 170 void prom_getstring(phandle node, char *prop, char *user_buf, int ubuf_size)
 171 {
 172         int len;
 173 
 174         len = prom_getproperty(node, prop, user_buf, ubuf_size);
 175         if(len != -1) return;
 176         user_buf[0] = 0;
 177 }
 178 EXPORT_SYMBOL(prom_getstring);
 179 
 180 
 181 /* Search siblings at 'node_start' for a node with name
 182  * 'nodename'.  Return node if successful, zero if not.
 183  */
 184 phandle prom_searchsiblings(phandle node_start, char *nodename)
 185 {
 186 
 187         phandle thisnode;
 188         int error;
 189 
 190         for(thisnode = node_start; thisnode;
 191             thisnode=prom_getsibling(thisnode)) {
 192                 error = prom_getproperty(thisnode, "name", promlib_buf,
 193                                          sizeof(promlib_buf));
 194                 /* Should this ever happen? */
 195                 if(error == -1) continue;
 196                 if(strcmp(nodename, promlib_buf)==0) return thisnode;
 197         }
 198 
 199         return 0;
 200 }
 201 EXPORT_SYMBOL(prom_searchsiblings);
 202 
 203 /* Interal version of nextprop that does not alter return values. */
 204 static char *__prom_nextprop(phandle node, char * oprop)
 205 {
 206         unsigned long flags;
 207         char *prop;
 208 
 209         spin_lock_irqsave(&prom_lock, flags);
 210         prop = prom_nodeops->no_nextprop(node, oprop);
 211         restore_current();
 212         spin_unlock_irqrestore(&prom_lock, flags);
 213 
 214         return prop;
 215 }
 216 
 217 /* Return the property type string after property type 'oprop'
 218  * at node 'node' .  Returns empty string if no more
 219  * property types for this node.
 220  */
 221 char *prom_nextprop(phandle node, char *oprop, char *buffer)
 222 {
 223         if (node == 0 || (s32)node == -1)
 224                 return "";
 225 
 226         return __prom_nextprop(node, oprop);
 227 }
 228 EXPORT_SYMBOL(prom_nextprop);
 229 
 230 phandle prom_finddevice(char *name)
 231 {
 232         char nbuf[128];
 233         char *s = name, *d;
 234         phandle node = prom_root_node, node2;
 235         unsigned int which_io, phys_addr;
 236         struct linux_prom_registers reg[PROMREG_MAX];
 237 
 238         while (*s++) {
 239                 if (!*s) return node; /* path '.../' is legal */
 240                 node = prom_getchild(node);
 241 
 242                 for (d = nbuf; *s != 0 && *s != '@' && *s != '/';)
 243                         *d++ = *s++;
 244                 *d = 0;
 245                 
 246                 node = prom_searchsiblings(node, nbuf);
 247                 if (!node)
 248                         return 0;
 249 
 250                 if (*s == '@') {
 251                         if (isxdigit(s[1]) && s[2] == ',') {
 252                                 which_io = simple_strtoul(s+1, NULL, 16);
 253                                 phys_addr = simple_strtoul(s+3, &d, 16);
 254                                 if (d != s + 3 && (!*d || *d == '/')
 255                                     && d <= s + 3 + 8) {
 256                                         node2 = node;
 257                                         while (node2 && (s32)node2 != -1) {
 258                                                 if (prom_getproperty (node2, "reg", (char *)reg, sizeof (reg)) > 0) {
 259                                                         if (which_io == reg[0].which_io && phys_addr == reg[0].phys_addr) {
 260                                                                 node = node2;
 261                                                                 break;
 262                                                         }
 263                                                 }
 264                                                 node2 = prom_getsibling(node2);
 265                                                 if (!node2 || (s32)node2 == -1)
 266                                                         break;
 267                                                 node2 = prom_searchsiblings(prom_getsibling(node2), nbuf);
 268                                         }
 269                                 }
 270                         }
 271                         while (*s != 0 && *s != '/') s++;
 272                 }
 273         }
 274         return node;
 275 }
 276 EXPORT_SYMBOL(prom_finddevice);
 277 
 278 /* Set property 'pname' at node 'node' to value 'value' which has a length
 279  * of 'size' bytes.  Return the number of bytes the prom accepted.
 280  */
 281 int prom_setprop(phandle node, const char *pname, char *value, int size)
 282 {
 283         unsigned long flags;
 284         int ret;
 285 
 286         if (size == 0)
 287                 return 0;
 288         if ((pname == NULL) || (value == NULL))
 289                 return 0;
 290         spin_lock_irqsave(&prom_lock, flags);
 291         ret = prom_nodeops->no_setprop(node, pname, value, size);
 292         restore_current();
 293         spin_unlock_irqrestore(&prom_lock, flags);
 294         return ret;
 295 }
 296 EXPORT_SYMBOL(prom_setprop);
 297 
 298 phandle prom_inst2pkg(int inst)
 299 {
 300         phandle node;
 301         unsigned long flags;
 302         
 303         spin_lock_irqsave(&prom_lock, flags);
 304         node = (*romvec->pv_v2devops.v2_inst2pkg)(inst);
 305         restore_current();
 306         spin_unlock_irqrestore(&prom_lock, flags);
 307         if ((s32)node == -1)
 308                 return 0;
 309         return node;
 310 }

/* [<][>][^][v][top][bottom][index][help] */