~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: b1c934f610d35233f21039d12d580313f3396a18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright (c) 2017 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 */

#ifndef _DM_OF_H
#define _DM_OF_H

#include <asm/u-boot.h>
#include <asm/global_data.h>

/* integer value within a device tree property which references another node */
typedef u32 phandle;

/**
 * struct property: Device tree property
 *
 * @name: Property name
 * @length: Length of property in bytes
 * @value: Pointer to property value
 * @next: Pointer to next property, or NULL if none
 */
struct property {
	char *name;
	int length;
	void *value;
	struct property *next;
};

/**
 * struct device_node: Device tree node
 *
 * The top of this tree is typically gd->of_root which points to the root node.
 *
 * The head of the list of children for the root node (and any other node) is
 * in @child, with @sibling providing a link to the next child.
 *
 * Each child has a pointer to its parent in @parent.
 *
 * A node may have properties in which case the head of the list of properties
 * @properties pointers to the first one, with struct property->@next pointing
 * to the next one.
 *
 * @name: Node name, "" for the root node
 * @type: Node type (value of device_type property) or "<NULL>" if none
 * @phandle: Phandle value of this none, or 0 if none
 * @full_name: Full path to node, e.g. "/bus@1/spi@1100" ("/" for the root node)
 * @properties: Pointer to head of list of properties, or NULL if none
 * @parent: Pointer to parent node, or NULL if this is the root node
 * @child: Pointer to head of child node list, or NULL if no children
 * @sibling: Pointer to the next sibling node, or NULL if this is the last
 */
struct device_node {
	const char *name;
	const char *type;
	phandle phandle;
	const char *full_name;

	struct property *properties;
	struct device_node *parent;
	struct device_node *child;
	struct device_node *sibling;
};

#define BAD_OF_ROOT	0xdead11e3

#define OF_MAX_PHANDLE_ARGS 16

/**
 * struct of_phandle_args - structure to hold phandle and arguments
 *
 * This is used when decoding a phandle in a device tree property. Typically
 * these look like this::
 *
 *   wibble {
 *     phandle = <5>;
 *   };
 *   ...
 *   some-prop = <&wibble 1 2 3>
 *
 * Here &node is the phandle of the node 'wibble', i.e. 5. There are three
 * arguments: 1, 2, 3.
 *
 * So when decoding the phandle in some-prop, np will point to wibble,
 * args_count will be 3 and the three arguments will be in args.
 *
 * @np: Node that the phandle refers to
 * @args_count: Number of arguments
 * @args: Argument values
 */
struct of_phandle_args {
	struct device_node *np;
	int args_count;
	uint32_t args[OF_MAX_PHANDLE_ARGS];
};

DECLARE_GLOBAL_DATA_PTR;

/**
 * of_live_active() - check if livetree is active
 *
 * @returns true if livetree is active, false it not
 */
static inline bool of_live_active(void)
{
	return gd_of_root() != NULL;
}

#define OF_BAD_ADDR	((u64)-1)

static inline const char *of_node_full_name(const struct device_node *np)
{
	return np ? np->full_name : "<no-node>";
}

/* Default #address and #size cells */
#if !defined(OF_ROOT_NODE_ADDR_CELLS_DEFAULT)
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
#endif

/* Default string compare functions */
#if !defined(of_compat_cmp)
#define of_compat_cmp(s1, s2, l)	strcasecmp((s1), (s2))
#define of_prop_cmp(s1, s2)		strcmp((s1), (s2))
#define of_node_cmp(s1, s2)		strcasecmp((s1), (s2))
#endif

/* Helper to read a big number; size is in cells (not bytes) */
static inline u64 of_read_number(const __be32 *cell, int size)
{
	u64 r = 0;
	while (size--)
		r = (r << 32) | be32_to_cpu(*(cell++));
	return r;
}

/* Like of_read_number, but we want an unsigned long result */
static inline unsigned long of_read_ulong(const __be32 *cell, int size)
{
	/* toss away upper bits if unsigned long is smaller than u64 */
	return of_read_number(cell, size);
}

#endif