xref: /rk3399_rockchip-uboot/include/dm/ofnode.h (revision 4984de2baaaf82bfc9416e9cdbd3040b97856950)
1*4984de2bSSimon Glass /*
2*4984de2bSSimon Glass  * Copyright (c) 2017 Google, Inc
3*4984de2bSSimon Glass  * Written by Simon Glass <sjg@chromium.org>
4*4984de2bSSimon Glass  *
5*4984de2bSSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
6*4984de2bSSimon Glass  */
7*4984de2bSSimon Glass 
8*4984de2bSSimon Glass #ifndef _DM_OFNODE_H
9*4984de2bSSimon Glass #define _DM_OFNODE_H
10*4984de2bSSimon Glass 
11*4984de2bSSimon Glass /**
12*4984de2bSSimon Glass  * ofnode - reference to a device tree node
13*4984de2bSSimon Glass  *
14*4984de2bSSimon Glass  * This union can hold either a straightforward pointer to a struct device_node
15*4984de2bSSimon Glass  * in the live device tree, or an offset within the flat device tree. In the
16*4984de2bSSimon Glass  * latter case, the pointer value is just the integer offset within the flat DT.
17*4984de2bSSimon Glass  *
18*4984de2bSSimon Glass  * Thus we can reference nodes in both the live tree (once available) and the
19*4984de2bSSimon Glass  * flat tree (until then). Functions are available to translate between an
20*4984de2bSSimon Glass  * ofnode and either an offset or a struct device_node *.
21*4984de2bSSimon Glass  *
22*4984de2bSSimon Glass  * The reference can also hold a null offset, in which case the pointer value
23*4984de2bSSimon Glass  * here is (void *)-1. This corresponds to a struct device_node * value of
24*4984de2bSSimon Glass  * NULL, or an offset of -1.
25*4984de2bSSimon Glass  *
26*4984de2bSSimon Glass  * There is no ambiguity as to whether ofnode holds an offset or a node
27*4984de2bSSimon Glass  * pointer: when the live tree is active it holds a node pointer, otherwise it
28*4984de2bSSimon Glass  * holds an offset. The value itself does not need to be unique and in theory
29*4984de2bSSimon Glass  * the same value could point to a valid device node or a valid offset. We
30*4984de2bSSimon Glass  * could arrange for a unique value to be used (e.g. by making the pointer
31*4984de2bSSimon Glass  * point to an offset within the flat device tree in the case of an offset) but
32*4984de2bSSimon Glass  * this increases code size slightly due to the subtraction. Since it offers no
33*4984de2bSSimon Glass  * real benefit, the approach described here seems best.
34*4984de2bSSimon Glass  *
35*4984de2bSSimon Glass  * For now these points use constant types, since we don't allow writing
36*4984de2bSSimon Glass  * the DT.
37*4984de2bSSimon Glass  *
38*4984de2bSSimon Glass  * @np: Pointer to device node, used for live tree
39*4984de2bSSimon Glass  * @flat_ptr: Pointer into flat device tree, used for flat tree. Note that this
40*4984de2bSSimon Glass  *	is not a really a pointer to a node: it is an offset value. See above.
41*4984de2bSSimon Glass  */
42*4984de2bSSimon Glass typedef union ofnode_union {
43*4984de2bSSimon Glass 	const struct device_node *np;	/* will be used for future live tree */
44*4984de2bSSimon Glass 	long of_offset;
45*4984de2bSSimon Glass } ofnode;
46*4984de2bSSimon Glass 
47*4984de2bSSimon Glass /**
48*4984de2bSSimon Glass  * ofnode_to_offset() - convert an ofnode to a flat DT offset
49*4984de2bSSimon Glass  *
50*4984de2bSSimon Glass  * This cannot be called if the reference contains a node pointer.
51*4984de2bSSimon Glass  *
52*4984de2bSSimon Glass  * @node: Reference containing offset (possibly invalid)
53*4984de2bSSimon Glass  * @return DT offset (can be -1)
54*4984de2bSSimon Glass  */
55*4984de2bSSimon Glass static inline int ofnode_to_offset(ofnode node)
56*4984de2bSSimon Glass {
57*4984de2bSSimon Glass 	return node.of_offset;
58*4984de2bSSimon Glass }
59*4984de2bSSimon Glass 
60*4984de2bSSimon Glass /**
61*4984de2bSSimon Glass  * ofnode_valid() - check if an ofnode is valid
62*4984de2bSSimon Glass  *
63*4984de2bSSimon Glass  * @return true if the reference contains a valid ofnode, false if it is NULL
64*4984de2bSSimon Glass  */
65*4984de2bSSimon Glass static inline bool ofnode_valid(ofnode node)
66*4984de2bSSimon Glass {
67*4984de2bSSimon Glass 	return node.of_offset != -1;
68*4984de2bSSimon Glass }
69*4984de2bSSimon Glass 
70*4984de2bSSimon Glass /**
71*4984de2bSSimon Glass  * offset_to_ofnode() - convert a DT offset to an ofnode
72*4984de2bSSimon Glass  *
73*4984de2bSSimon Glass  * @of_offset: DT offset (either valid, or -1)
74*4984de2bSSimon Glass  * @return reference to the associated DT offset
75*4984de2bSSimon Glass  */
76*4984de2bSSimon Glass static inline ofnode offset_to_ofnode(int of_offset)
77*4984de2bSSimon Glass {
78*4984de2bSSimon Glass 	ofnode node;
79*4984de2bSSimon Glass 
80*4984de2bSSimon Glass 	node.of_offset = of_offset;
81*4984de2bSSimon Glass 
82*4984de2bSSimon Glass 	return node;
83*4984de2bSSimon Glass }
84*4984de2bSSimon Glass 
85*4984de2bSSimon Glass /**
86*4984de2bSSimon Glass  * ofnode_equal() - check if two references are equal
87*4984de2bSSimon Glass  *
88*4984de2bSSimon Glass  * @return true if equal, else false
89*4984de2bSSimon Glass  */
90*4984de2bSSimon Glass static inline bool ofnode_equal(ofnode ref1, ofnode ref2)
91*4984de2bSSimon Glass {
92*4984de2bSSimon Glass 	/* We only need to compare the contents */
93*4984de2bSSimon Glass 	return ref1.of_offset == ref2.of_offset;
94*4984de2bSSimon Glass }
95*4984de2bSSimon Glass 
96*4984de2bSSimon Glass #endif
97