Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) .. SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) ==================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) Open Firmware Device Tree Unittest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) ==================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) Author: Gaurav Minocha <gaurav.minocha.os@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 1. Introduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) ===============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) This document explains how the test data required for executing OF unittest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) is attached to the live tree dynamically, independent of the machine's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) architecture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) It is recommended to read the following documents before moving ahead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) (1) Documentation/devicetree/usage-model.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) (2) http://www.devicetree.org/Device_Tree_Usage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) OF Selftest has been designed to test the interface (include/linux/of.h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) provided to device driver developers to fetch the device information..etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) from the unflattened device tree data structure. This interface is used by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) most of the device drivers in various use cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 2. Test-data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) ============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) The Device Tree Source file (drivers/of/unittest-data/testcases.dts) contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) the test data required for executing the unit tests automated in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) drivers/of/unittest.c. Currently, following Device Tree Source Include files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) (.dtsi) are included in testcases.dts::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)     drivers/of/unittest-data/tests-interrupts.dtsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)     drivers/of/unittest-data/tests-platform.dtsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)     drivers/of/unittest-data/tests-phandle.dtsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)     drivers/of/unittest-data/tests-match.dtsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) When the kernel is build with OF_SELFTEST enabled, then the following make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) rule::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)     $(obj)/%.dtb: $(src)/%.dts FORCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	    $(call if_changed_dep, dtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) is used to compile the DT source file (testcases.dts) into a binary blob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) (testcases.dtb), also referred as flattened DT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) After that, using the following rule the binary blob above is wrapped as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) assembly file (testcases.dtb.S)::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)     $(obj)/%.dtb.S: $(obj)/%.dtb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	    $(call cmd, dt_S_dtb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) The assembly file is compiled into an object file (testcases.dtb.o), and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) linked into the kernel image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 2.1. Adding the test data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) -------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) Un-flattened device tree structure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) Un-flattened device tree consists of connected device_node(s) in form of a tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) structure described below::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)     // following struct members are used to construct the tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)     struct device_node {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct  device_node *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct  device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct  device_node *sibling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)     };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) Figure 1, describes a generic structure of machine's un-flattened device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) considering only child and sibling pointers. There exists another pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) ``*parent``, that is used to traverse the tree in the reverse direction. So, at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) a particular level the child node and all the sibling nodes will have a parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) pointer pointing to a common node (e.g. child1, sibling2, sibling3, sibling4's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) parent points to root node)::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)     root ('/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)     child1 -> sibling2 -> sibling3 -> sibling4 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)     |         |           |           |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)     |         |           |          null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)     |         |           |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)     |         |        child31 -> sibling32 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)     |         |           |          |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)     |         |          null       null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)     |         |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)     |      child21 -> sibling22 -> sibling23 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)     |         |          |            |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)     |        null       null         null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)     child11 -> sibling12 -> sibling13 -> sibling14 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)     |           |           |            |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)     |           |           |           null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)     |           |           |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)     null        null       child131 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			    null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) Figure 1: Generic structure of un-flattened device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) Before executing OF unittest, it is required to attach the test data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) machine's device tree (if present). So, when selftest_data_add() is called,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) at first it reads the flattened device tree data linked into the kernel image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) via the following kernel symbols::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)     __dtb_testcases_begin - address marking the start of test data blob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)     __dtb_testcases_end   - address marking the end of test data blob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) Secondly, it calls of_fdt_unflatten_tree() to unflatten the flattened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) blob. And finally, if the machine's device tree (i.e live tree) is present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) then it attaches the unflattened test data tree to the live tree, else it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) attaches itself as a live device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) attach_node_and_children() uses of_attach_node() to attach the nodes into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) live tree as explained below. To explain the same, the test data tree described
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) in Figure 2 is attached to the live tree described in Figure 1::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)     root ('/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)     testcase-data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)     test-child0 -> test-sibling1 -> test-sibling2 -> test-sibling3 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	|               |                |                |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)     test-child01      null             null             null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) Figure 2: Example test data tree to be attached to live tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) According to the scenario above, the live tree is already present so it isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) required to attach the root('/') node. All other nodes are attached by calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) of_attach_node() on each node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) In the function of_attach_node(), the new node is attached as the child of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) given parent in live tree. But, if parent already has a child then the new node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) replaces the current child and turns it into its sibling. So, when the testcase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) data node is attached to the live tree above (Figure 1), the final structure is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) as shown in Figure 3::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)     root ('/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)     testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)     |               |          |           |           |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)     (...)             |          |           |          null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		    |          |         child31 -> sibling32 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		    |          |           |           |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		    |          |          null        null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		    |          |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		    |        child21 -> sibling22 -> sibling23 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		    |          |           |            |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		    |         null        null         null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		    child11 -> sibling12 -> sibling13 -> sibling14 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		    |          |            |            |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		    null       null          |           null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 					    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 					    child131 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 					    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 					    null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)     -----------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)     root ('/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)     testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)     |               |          |           |           |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)     |             (...)      (...)       (...)        null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)     test-sibling3 -> test-sibling2 -> test-sibling1 -> test-child0 -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)     |                |                   |                |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)     null             null                null         test-child01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) Figure 3: Live device tree structure after attaching the testcase-data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) Astute readers would have noticed that test-child0 node becomes the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) sibling compared to the earlier structure (Figure 2). After attaching first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) test-child0 the test-sibling1 is attached that pushes the child node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) (i.e. test-child0) to become a sibling and makes itself a child node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) as mentioned above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) If a duplicate node is found (i.e. if a node with same full_name property is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) already present in the live tree), then the node isn't attached rather its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) properties are updated to the live tree's node by calling the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) update_node_properties().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 2.2. Removing the test data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ---------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) Once the test case execution is complete, selftest_data_remove is called in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) order to remove the device nodes attached initially (first the leaf nodes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) detached and then moving up the parent nodes are removed, and eventually the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) whole tree). selftest_data_remove() calls detach_node_and_children() that uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) of_detach_node() to detach the nodes from the live device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) To detach a node, of_detach_node() either updates the child pointer of given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) node's parent to its sibling or attaches the previous sibling to the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) node's sibling, as appropriate. That is it :)