Commit 4984de2baaaf82bfc9416e9cdbd3040b97856950

Authored by Simon Glass
1 parent da409ccc4a

dm: core: Add ofnode to represent device tree nodes

With live tree we need a struct device_node * to reference a node. With
the existing flat tree, we need an int offset. We need to unify these into
a single value which can represent both.

Add an ofnode union for this and adjust existing code to move to this.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 5 changed files with 109 additions and 6 deletions Side-by-side Diff

drivers/core/device.c
... ... @@ -60,7 +60,7 @@
60 60 dev->platdata = platdata;
61 61 dev->driver_data = driver_data;
62 62 dev->name = name;
63   - dev->of_offset = of_offset;
  63 + dev->node = offset_to_ofnode(of_offset);
64 64 dev->parent = parent;
65 65 dev->driver = drv;
66 66 dev->uclass = uc;
... ... @@ -167,7 +167,7 @@
167 167 if (ret)
168 168 return ret;
169 169 #if CONFIG_IS_ENABLED(OF_CONTROL)
170   - DM_ROOT_NON_CONST->of_offset = 0;
  170 + DM_ROOT_NON_CONST->node = offset_to_ofnode(0);
171 171 #endif
172 172 ret = device_probe(DM_ROOT_NON_CONST);
173 173 if (ret)
... ... @@ -7,6 +7,7 @@
7 7 #ifndef _DM_H_
8 8 #define _DM_H_
9 9  
  10 +#include <dm/ofnode.h>
10 11 #include <dm/device.h>
11 12 #include <dm/fdtaddr.h>
12 13 #include <dm/platdata.h>
... ... @@ -11,6 +11,7 @@
11 11 #ifndef _DM_DEVICE_H
12 12 #define _DM_DEVICE_H
13 13  
  14 +#include <dm/ofnode.h>
14 15 #include <dm/uclass-id.h>
15 16 #include <fdtdec.h>
16 17 #include <linker_lists.h>
... ... @@ -103,7 +104,7 @@
103 104 * @platdata: Configuration data for this device
104 105 * @parent_platdata: The parent bus's configuration data for this device
105 106 * @uclass_platdata: The uclass's configuration data for this device
106   - * @of_offset: Device tree node offset for this device (- for none)
  107 + * @node: Reference to device tree node for this device
107 108 * @driver_data: Driver data word for the entry that matched this device with
108 109 * its driver
109 110 * @parent: Parent of this device, or NULL for the top level device
... ... @@ -129,7 +130,7 @@
129 130 void *platdata;
130 131 void *parent_platdata;
131 132 void *uclass_platdata;
132   - int of_offset;
  133 + ofnode node;
133 134 ulong driver_data;
134 135 struct udevice *parent;
135 136 void *priv;
136 137  
... ... @@ -158,12 +159,17 @@
158 159  
159 160 static inline int dev_of_offset(const struct udevice *dev)
160 161 {
161   - return dev->of_offset;
  162 + return ofnode_to_offset(dev->node);
162 163 }
163 164  
164 165 static inline void dev_set_of_offset(struct udevice *dev, int of_offset)
165 166 {
166   - dev->of_offset = of_offset;
  167 + dev->node = offset_to_ofnode(of_offset);
  168 +}
  169 +
  170 +static inline bool dev_has_of_node(struct udevice *dev)
  171 +{
  172 + return ofnode_valid(dev->node);
167 173 }
168 174  
169 175 /**
  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