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