baseport/src/cedar/generic/base/syborg/svpplatform/libfdt/fdt_ro.c
author martin.trojer@nokia.com
Fri, 31 Jul 2009 14:43:15 +0100
changeset 0 ffa851df0825
permissions -rw-r--r--
Initial syborg (baseport) and documentation import
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     1
/*
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     2
 * libfdt - Flat Device Tree manipulation
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     3
 * Copyright (C) 2006 David Gibson, IBM Corporation.
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     4
 *
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     5
 * libfdt is dual licensed: you can use it either under the terms of
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     6
 * the GPL, or the BSD license, at your option.
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     7
 *
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     8
 *  a) This library is free software; you can redistribute it and/or
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
     9
 *     modify it under the terms of the GNU General Public License as
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    10
 *     published by the Free Software Foundation; either version 2 of the
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    11
 *     License, or (at your option) any later version.
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    12
 *
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    13
 *     This library is distributed in the hope that it will be useful,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    14
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    15
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    16
 *     GNU General Public License for more details.
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    17
 *
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    18
 *     You should have received a copy of the GNU General Public
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    19
 *     License along with this library; if not, write to the Free
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    20
 *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    21
 *     MA 02110-1301 USA
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    22
 *
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    23
 * Alternatively,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    24
 *
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    25
 *  b) Redistribution and use in source and binary forms, with or
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    26
 *     without modification, are permitted provided that the following
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    27
 *     conditions are met:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    28
 *
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    29
 *     1. Redistributions of source code must retain the above
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    30
 *        copyright notice, this list of conditions and the following
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    31
 *        disclaimer.
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    32
 *     2. Redistributions in binary form must reproduce the above
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    33
 *        copyright notice, this list of conditions and the following
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    34
 *        disclaimer in the documentation and/or other materials
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    35
 *        provided with the distribution.
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    36
 *
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    37
 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    38
 *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    39
 *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    40
 *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    41
 *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    42
 *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    43
 *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    44
 *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    45
 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    46
 *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    47
 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    48
 *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    49
 *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    50
 */
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    51
#include "libfdt_env.h"
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    52
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    53
#include <fdt.h>
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    54
#include <libfdt.h>
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    55
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    56
#include "libfdt_internal.h"
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    57
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    58
#define CHECK_HEADER(fdt) \
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    59
	{ \
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    60
		int err; \
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    61
		if ((err = fdt_check_header(fdt)) != 0) \
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    62
			return err; \
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    63
	}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    64
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    65
static int nodename_eq(const void *fdt, int offset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    66
		       const char *s, int len)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    67
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    68
	const char *p = fdt_offset_ptr(fdt, offset, len+1);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    69
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    70
	if (! p)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    71
		/* short match */
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    72
		return 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    73
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    74
	if (memcmp(p, s, len) != 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    75
		return 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    76
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    77
	if (p[len] == '\0')
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    78
		return 1;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    79
	else if (!memchr(s, '@', len) && (p[len] == '@'))
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    80
		return 1;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    81
	else
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    82
		return 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    83
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    84
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    85
const char *fdt_string(const void *fdt, int stroffset)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    86
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    87
	return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    88
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    89
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    90
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    91
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    92
	CHECK_HEADER(fdt);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    93
	*address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    94
	*size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    95
	return 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    96
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    97
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    98
int fdt_num_mem_rsv(const void *fdt)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
    99
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   100
	int i = 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   101
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   102
	while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   103
		i++;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   104
	return i;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   105
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   106
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   107
int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   108
			       const char *name, int namelen)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   109
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   110
	int level = 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   111
	uint32_t tag;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   112
	int offset, nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   113
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   114
	CHECK_HEADER(fdt);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   115
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   116
	tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   117
	if (tag != FDT_BEGIN_NODE)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   118
		return -FDT_ERR_BADOFFSET;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   119
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   120
	do {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   121
		offset = nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   122
		tag = fdt_next_tag(fdt, offset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   123
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   124
		switch (tag) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   125
		case FDT_END:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   126
			return -FDT_ERR_TRUNCATED;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   127
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   128
		case FDT_BEGIN_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   129
			level++;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   130
			if (level != 1)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   131
				continue;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   132
			if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen))
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   133
				/* Found it! */
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   134
				return offset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   135
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   136
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   137
		case FDT_END_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   138
			level--;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   139
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   140
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   141
		case FDT_PROP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   142
		case FDT_NOP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   143
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   144
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   145
		default:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   146
			return -FDT_ERR_BADSTRUCTURE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   147
		}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   148
	} while (level >= 0);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   149
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   150
	return -FDT_ERR_NOTFOUND;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   151
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   152
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   153
int fdt_subnode_offset(const void *fdt, int parentoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   154
		       const char *name)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   155
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   156
	return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   157
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   158
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   159
int fdt_path_offset(const void *fdt, const char *path)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   160
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   161
	const char *end = path + strlen(path);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   162
	const char *p = path;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   163
	int offset = 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   164
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   165
	CHECK_HEADER(fdt);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   166
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   167
	if (*path != '/')
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   168
		return -FDT_ERR_BADPATH;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   169
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   170
	while (*p) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   171
		const char *q;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   172
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   173
		while (*p == '/')
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   174
			p++;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   175
		if (! *p)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   176
			return offset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   177
		q = strchr(p, '/');
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   178
		if (! q)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   179
			q = end;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   180
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   181
		offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   182
		if (offset < 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   183
			return offset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   184
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   185
		p = q;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   186
	}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   187
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   188
	return offset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   189
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   190
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   191
const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   192
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   193
	const struct fdt_node_header *nh;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   194
	int err;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   195
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   196
	if ((err = fdt_check_header(fdt)) != 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   197
		goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   198
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   199
	err = -FDT_ERR_BADOFFSET;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   200
	nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh));
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   201
	if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE))
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   202
		goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   203
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   204
	if (len)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   205
		*len = strlen(nh->name);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   206
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   207
	return nh->name;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   208
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   209
 fail:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   210
	if (len)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   211
		*len = err;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   212
	return NULL;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   213
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   214
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   215
const struct fdt_property *fdt_get_property(const void *fdt,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   216
					    int nodeoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   217
					    const char *name, int *lenp)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   218
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   219
	uint32_t tag;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   220
	const struct fdt_property *prop;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   221
	int namestroff;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   222
	int offset, nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   223
	int err;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   224
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   225
	if ((err = fdt_check_header(fdt)) != 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   226
		goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   227
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   228
	err = -FDT_ERR_BADOFFSET;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   229
	if (nodeoffset % FDT_TAGSIZE)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   230
		goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   231
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   232
	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   233
	if (tag != FDT_BEGIN_NODE)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   234
		goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   235
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   236
	do {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   237
		offset = nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   238
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   239
		tag = fdt_next_tag(fdt, offset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   240
		switch (tag) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   241
		case FDT_END:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   242
			err = -FDT_ERR_TRUNCATED;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   243
			goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   244
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   245
		case FDT_BEGIN_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   246
		case FDT_END_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   247
		case FDT_NOP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   248
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   249
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   250
		case FDT_PROP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   251
			err = -FDT_ERR_BADSTRUCTURE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   252
			prop = fdt_offset_ptr(fdt, offset, sizeof(*prop));
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   253
			if (! prop)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   254
				goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   255
			namestroff = fdt32_to_cpu(prop->nameoff);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   256
			if (streq(fdt_string(fdt, namestroff), name)) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   257
				/* Found it! */
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   258
				int len = fdt32_to_cpu(prop->len);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   259
				prop = fdt_offset_ptr(fdt, offset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   260
						      sizeof(*prop)+len);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   261
				if (! prop)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   262
					goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   263
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   264
				if (lenp)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   265
					*lenp = len;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   266
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   267
				return prop;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   268
			}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   269
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   270
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   271
		default:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   272
			err = -FDT_ERR_BADSTRUCTURE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   273
			goto fail;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   274
		}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   275
	} while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   276
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   277
	err = -FDT_ERR_NOTFOUND;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   278
 fail:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   279
	if (lenp)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   280
		*lenp = err;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   281
	return NULL;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   282
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   283
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   284
const void *fdt_getprop(const void *fdt, int nodeoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   285
		  const char *name, int *lenp)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   286
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   287
	const struct fdt_property *prop;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   288
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   289
	prop = fdt_get_property(fdt, nodeoffset, name, lenp);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   290
	if (! prop)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   291
		return NULL;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   292
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   293
	return prop->data;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   294
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   295
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   296
uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   297
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   298
	const uint32_t *php;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   299
	int len;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   300
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   301
	php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   302
	if (!php || (len != sizeof(*php)))
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   303
		return 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   304
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   305
	return fdt32_to_cpu(*php);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   306
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   307
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   308
int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   309
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   310
	uint32_t tag;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   311
	int p = 0, overflow = 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   312
	int offset, nextoffset, namelen;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   313
	const char *name;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   314
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   315
	CHECK_HEADER(fdt);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   316
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   317
	tag = fdt_next_tag(fdt, 0, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   318
	if (tag != FDT_BEGIN_NODE)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   319
		return -FDT_ERR_BADSTRUCTURE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   320
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   321
	if (buflen < 2)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   322
		return -FDT_ERR_NOSPACE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   323
	buf[0] = '/';
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   324
	p = 1;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   325
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   326
	while (nextoffset <= nodeoffset) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   327
		offset = nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   328
		tag = fdt_next_tag(fdt, offset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   329
		switch (tag) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   330
		case FDT_END:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   331
			return -FDT_ERR_BADOFFSET;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   332
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   333
		case FDT_BEGIN_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   334
			name = fdt_get_name(fdt, offset, &namelen);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   335
			if (!name)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   336
				return namelen;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   337
			if (overflow || ((p + namelen + 1) > buflen)) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   338
				overflow++;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   339
				break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   340
			}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   341
			memcpy(buf + p, name, namelen);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   342
			p += namelen;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   343
			buf[p++] = '/';
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   344
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   345
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   346
		case FDT_END_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   347
			if (overflow) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   348
				overflow--;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   349
				break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   350
			}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   351
			do {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   352
				p--;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   353
			} while  (buf[p-1] != '/');
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   354
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   355
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   356
		case FDT_PROP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   357
		case FDT_NOP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   358
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   359
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   360
		default:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   361
			return -FDT_ERR_BADSTRUCTURE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   362
		}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   363
	}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   364
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   365
	if (overflow)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   366
		return -FDT_ERR_NOSPACE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   367
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   368
	if (p > 1) /* special case so that root path is "/", not "" */
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   369
		p--;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   370
	buf[p] = '\0';
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   371
	return p;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   372
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   373
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   374
int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   375
				 int supernodedepth, int *nodedepth)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   376
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   377
	int level = -1;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   378
	uint32_t tag;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   379
	int offset, nextoffset = 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   380
	int supernodeoffset = -FDT_ERR_INTERNAL;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   381
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   382
	CHECK_HEADER(fdt);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   383
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   384
	if (supernodedepth < 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   385
		return -FDT_ERR_NOTFOUND;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   386
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   387
	do {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   388
		offset = nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   389
		tag = fdt_next_tag(fdt, offset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   390
		switch (tag) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   391
		case FDT_END:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   392
			return -FDT_ERR_BADOFFSET;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   393
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   394
		case FDT_BEGIN_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   395
			level++;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   396
			if (level == supernodedepth)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   397
				supernodeoffset = offset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   398
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   399
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   400
		case FDT_END_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   401
			level--;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   402
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   403
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   404
		case FDT_PROP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   405
		case FDT_NOP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   406
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   407
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   408
		default:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   409
			return -FDT_ERR_BADSTRUCTURE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   410
		}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   411
	} while (offset < nodeoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   412
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   413
	if (nodedepth)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   414
		*nodedepth = level;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   415
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   416
	if (supernodedepth > level)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   417
		return -FDT_ERR_NOTFOUND;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   418
	return supernodeoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   419
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   420
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   421
int fdt_node_depth(const void *fdt, int nodeoffset)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   422
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   423
	int nodedepth;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   424
	int err;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   425
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   426
	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   427
	if (err)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   428
		return (err < 0) ? err : -FDT_ERR_INTERNAL;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   429
	return nodedepth;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   430
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   431
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   432
int fdt_parent_offset(const void *fdt, int nodeoffset)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   433
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   434
	int nodedepth = fdt_node_depth(fdt, nodeoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   435
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   436
	if (nodedepth < 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   437
		return nodedepth;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   438
	return fdt_supernode_atdepth_offset(fdt, nodeoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   439
					    nodedepth - 1, NULL);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   440
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   441
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   442
int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   443
				  const char *propname,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   444
				  const void *propval, int proplen)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   445
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   446
	uint32_t tag;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   447
	int offset, nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   448
	const void *val;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   449
	int len;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   450
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   451
	CHECK_HEADER(fdt);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   452
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   453
	if (startoffset >= 0) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   454
		tag = fdt_next_tag(fdt, startoffset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   455
		if (tag != FDT_BEGIN_NODE)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   456
			return -FDT_ERR_BADOFFSET;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   457
	} else {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   458
		nextoffset = 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   459
	}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   460
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   461
	/* FIXME: The algorithm here is pretty horrible: we scan each
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   462
	 * property of a node in fdt_getprop(), then if that didn't
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   463
	 * find what we want, we scan over them again making our way
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   464
	 * to the next node.  Still it's the easiest to implement
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   465
	 * approach; performance can come later. */
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   466
	do {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   467
		offset = nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   468
		tag = fdt_next_tag(fdt, offset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   469
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   470
		switch (tag) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   471
		case FDT_BEGIN_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   472
			val = fdt_getprop(fdt, offset, propname, &len);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   473
			if (val
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   474
			    && (len == proplen)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   475
			    && (memcmp(val, propval, len) == 0))
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   476
				return offset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   477
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   478
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   479
		case FDT_PROP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   480
		case FDT_END:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   481
		case FDT_END_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   482
		case FDT_NOP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   483
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   484
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   485
		default:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   486
			return -FDT_ERR_BADSTRUCTURE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   487
		}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   488
	} while (tag != FDT_END);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   489
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   490
	return -FDT_ERR_NOTFOUND;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   491
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   492
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   493
int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   494
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   495
	if ((phandle == 0) || (phandle == -1))
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   496
		return -FDT_ERR_BADPHANDLE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   497
	phandle = cpu_to_fdt32(phandle);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   498
	return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   499
					     &phandle, sizeof(phandle));
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   500
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   501
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   502
int _stringlist_contains(const void *strlist, int listlen, const char *str)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   503
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   504
	int len = strlen(str);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   505
	const void *p;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   506
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   507
	while (listlen >= len) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   508
		if (memcmp(str, strlist, len+1) == 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   509
			return 1;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   510
		p = memchr(strlist, '\0', listlen);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   511
		if (!p)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   512
			return 0; /* malformed strlist.. */
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   513
		listlen -= (p-strlist) + 1;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   514
		strlist = p + 1;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   515
	}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   516
	return 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   517
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   518
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   519
int fdt_node_check_compatible(const void *fdt, int nodeoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   520
			      const char *compatible)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   521
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   522
	const void *prop;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   523
	int len;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   524
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   525
	prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   526
	if (!prop)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   527
		return len;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   528
	if (_stringlist_contains(prop, len, compatible))
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   529
		return 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   530
	else
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   531
		return 1;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   532
}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   533
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   534
int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   535
				  const char *compatible)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   536
{
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   537
	uint32_t tag;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   538
	int offset, nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   539
	int err;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   540
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   541
	CHECK_HEADER(fdt);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   542
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   543
	if (startoffset >= 0) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   544
		tag = fdt_next_tag(fdt, startoffset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   545
		if (tag != FDT_BEGIN_NODE)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   546
			return -FDT_ERR_BADOFFSET;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   547
	} else {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   548
		nextoffset = 0;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   549
	}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   550
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   551
	/* FIXME: The algorithm here is pretty horrible: we scan each
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   552
	 * property of a node in fdt_node_check_compatible(), then if
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   553
	 * that didn't find what we want, we scan over them again
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   554
	 * making our way to the next node.  Still it's the easiest to
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   555
	 * implement approach; performance can come later. */
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   556
	do {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   557
		offset = nextoffset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   558
		tag = fdt_next_tag(fdt, offset, &nextoffset);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   559
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   560
		switch (tag) {
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   561
		case FDT_BEGIN_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   562
			err = fdt_node_check_compatible(fdt, offset,
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   563
							compatible);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   564
			if ((err < 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   565
			    && (err != -FDT_ERR_NOTFOUND))
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   566
				return err;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   567
			else if (err == 0)
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   568
				return offset;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   569
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   570
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   571
		case FDT_PROP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   572
		case FDT_END:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   573
		case FDT_END_NODE:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   574
		case FDT_NOP:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   575
			break;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   576
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   577
		default:
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   578
			return -FDT_ERR_BADSTRUCTURE;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   579
		}
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   580
	} while (tag != FDT_END);
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   581
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   582
	return -FDT_ERR_NOTFOUND;
ffa851df0825 Initial syborg (baseport) and documentation import
martin.trojer@nokia.com
parents:
diff changeset
   583
}