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 97