blob: 0cf59c6070fc1c18699fba4cccfb7ef2b87bb747 [file] [log] [blame] [view]
# Devicetree visitors
**Devicetree visitors** are responsible for converting devicetree data into
driver-specific metadata and bind rules. They parse the relevant devicetree
nodes with respect to a particular [devicetree binding][devicetree-binding]
and produce driver metadata and driver framework node properties. Devicetree
visitor objects implement the interfaces in the
[`driver-visitor.h`][driver-visitor-h] header file and all `Visitor::Visit`
calls are invoked during the devicetree manager's `Walk` call.
## Visitor types {:#visitor-types}
There are two types of devicetree visitors:
[default visitors](#default-visitors) and [driver visitors](#driver-visitors).
### Default visitors {:#default-visitors}
[Default visitors][default-visitors] are for the properties or bind rules
mentioned as standard properties in the devicetree specification. Additionally,
a number of visitors are for the properties that are generic in the Fuchsia
platform (that is, the properties explicitly mentioned in the
`fuchsia_hardware_platform_bus::Node` protocol). These visitors are considered
default for Fuchsia and are also added to the default visitor set.
### Driver visitors {:#driver-visitors}
[Driver visitors][driver-visitors] correspond to driver-specific metadata or
dependencies. These visitors are built as shared libraries using the
`devicetree_visitor` GN target. Creating a shared library of the visitor helps
Fuchsia keep the list of visitors dynamic, that is, visitors can be added and
removed from the [board driver][board-driver] without having to recompile it.
This also helps Fuchsia update and contribute visitors independent of the board
driver.
## Writing a new visitor {:#writing-a-new-visitor}
A new visitor will be needed when a new devicetree
[binding][bindings]{:.external} is created. Typically, a new devicetree binding
is created because either a new metadata is introduced or a composite node
needs to be created from the board driver.
You can use the following `fx` command as a starting point for writing a new
visitor:
```posix-terminal
fx create devicetree visitor --lang cpp --path <VISITOR_PATH>
```
All visitors must include a devicetree schema file (for example, see
[`smc.yaml`][smc-yaml]) representing the bindings that it is parsing.
For a complete devicetree visitor example, see the
[`example-visitor`][example-visitor] directory.
### Helper libraries {:#helper-libraries}
The following helper libraries are available for writing a new visitor:
- **Driver visitors**: This library provides a constructor that takes in a list
of compatible strings and only calls the visitor when the node with the
matching compatible string is found.
- **Property parser**: This library provides a parser object which can be
configured to parse all relevant properties for a node. It also reduces some
of the complexity involved around parsing [phandle][phandle]{:.external}
(pointer handle) references.
- **Multi-visitor**: Used for combining multiple visitors into a single object
that can be passed to the devicetree manager's `Walk` call.
- **Load visitors**: This can be used by the board driver to load shared library
visitors packaged with the driver in its `/lib/visitors` folder.
## Testing a visitor {:#testing-visitor}
A visitor integration test can be created using the `visitor-test-helper`
library to test the parsing and creation of metadata and bind rules by the
visitor. The helper library creates an instance of the devicetree manager along
with fakes for platform-bus protocols. The DTB containing the test nodes for the
visitor is passed during the initialization of the test helper. All of the
properties set by the visitor (that is, metadata and properties or bind rules)
are recorded by the test helper and can be used to verify the visitor's
behavior.
<!-- Reference links -->
[smc-yaml]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/driver/devicetree/visitors/default/smc/smc.yaml
[driver-visitor-h]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/driver/devicetree/visitors/driver-visitor.h
[bindings]: https://devicetree-specification.readthedocs.io/en/v0.3/device-bindings.html#device-bindings
[example-visitor]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/driver/devicetree/examples/example-visitor/
[phandle]: https://devicetree-specification.readthedocs.io/en/v0.3/devicetree-basics.html#phandle
[devicetree-binding]: /docs/development/boards/devicetree-overview.md#devicetree-bindings-and-visitors
[board-driver]: /docs/development/boards/bringup.md#board-driver
[default-visitors]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/driver/devicetree/visitors/default/
[driver-visitors]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/driver/devicetree/visitors/drivers/