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