Re: [RFC PATCH 2/2] software node: Add documentation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
Below are a few doc edits for you.


On 10/2/19 5:33 AM, Heikki Krogerus wrote:
> API documentation for the software nodes.
> 
> Signed-off-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>
> ---
>  Documentation/driver-api/software_node.rst | 197 +++++++++++++++++++++
>  1 file changed, 197 insertions(+)
>  create mode 100644 Documentation/driver-api/software_node.rst
> 
> diff --git a/Documentation/driver-api/software_node.rst b/Documentation/driver-api/software_node.rst
> new file mode 100644
> index 000000000000..cf8a05c34e9e
> --- /dev/null
> +++ b/Documentation/driver-api/software_node.rst
> @@ -0,0 +1,197 @@
> +
> +.. _software_node:
> +
> +==============
> +Software nodes
> +==============
> +
> +Introduction
> +============
> +
> +Software node is a :c:type:`struct fwnode_handle <fwnode_handle>` type,
> +analogous to the ACPI and DT firmware nodes except that the software nodes are
> +created in kernel code (hence the name "software" node). The software nodes can
> +be used to complement fwnodes representing real firmware nodes when they are
> +incomplete, for example missing device properties, and to supply the primary
> +fwnode when the firmware lacks hardware description for a device completely.
> +
> +NOTE! The primary hardware description should always come from either ACPI
> +tables or DT. Describing an entire system with software nodes, though possible,
> +is not acceptable! The software nodes should only complement the primary
> +hardware description.
> +
> +Hierarchy
> +=========
> +
> +The software nodes support hierarchy (i.e. the software nodes can have child

I would s/child/children/

> +software nodes and a parent software node) just like ACPI and DT firmware nodes,
> +but there is no dedicated root software node object. It means that a software
> +node at the root level does not have a parent.
> +
> +Note! Only other software nodes can be children and the parent for a software
> +node.
> +
> +Device properties
> +=================
> +
> +The software node device properties are described with :c:type:`struct
> +property_entry <property_entry>`. When a software node is created that has
> +device properties, it is supplied with a zero terminated array of property
> +entries. Normally the properties are described with helper macros::
> +
> +	static const u8 u8_array[] = { 0, 1, 2, 3 };
> +	static const u16 u16_array[] = { 0, 1, 2, 3 };
> +	static const u32 u32_array[] = { 0, 1, 2, 3 };
> +	static const u64 u64_array[] = { 0, 1, 2, 3 };
> +
> +	static const struct property_entry my_props[] = {
> +		PROPERTY_ENTRY_U8_ARRAY("u8_array_example", u8_array),
> +		PROPERTY_ENTRY_U16_ARRAY("u16_array_example", u16_array),
> +		PROPERTY_ENTRY_U32_ARRAY("u32_array_example", u32_array),
> +		PROPERTY_ENTRY_U64_ARRAY("u64_array_example", u64_array),
> +		PROPERTY_ENTRY_U8("u8_example", 0xff),
> +		PROPERTY_ENTRY_U16("u16_example", 0xffff),
> +		PROPERTY_ENTRY_U32("u32_example", 0xffffffff),
> +		PROPERTY_ENTRY_U64("u64_example", 0xffffffffffffffff),
> +		PROPERTY_ENTRY_STRING("string_example", "string"),
> +		{ }
> +	};
> +
> +Note! If "build-in" device properties are supplied to already existing device

            "built-in"

> +entries by using :c:func:`device_add_properties`, a software node is actually
> +created for that device. That software node is just assigned to the device
> +automatically in the function.
> +
> +Usage
> +=====
> +
> +Node creation
> +-------------
> +
> +Static nodes
> +~~~~~~~~~~~~
> +
> +In a normal case the software nodes are described statically with
> +:c:type:`struct software_node <software_node>`, and then registered with
> +:c:func:`software_node_register`. Usually there is more then one software node

                                                           than

> +that needs to be registered. A helper :c:func:`software_node_register_nodes`
> +registers a zero terminated array of software nodes::
> +
> +	static const struct property_entry props[] = {
> +		PROPERTY_ENTRY_STRING("foo", "bar"),
> +		{ }
> +	};
> +
> +	static const struct software_node my_nodes[] = {
> +		{ "grandparent" },		/* no parent nor properties */
> +		{ "parent", &my_nodes[0] },	/* parent, but no propreties */

		                                                  properties

> +		{ "child", &my_nodes[1], props }, /* parent and properties */
> +		{ }
> +	};
> +
> +	static int my_init(void)
> +	{
> +		return software_node_register_nodes(my_nodes);
> +	}
> +
> +Note! The above example names the nodes "grandparent", "parent" and "child", but
> +the software nodes don't actually have to be named. If no name is supplied for a
> +software node when it's being registered, the API names the node "node<n>" where
> +<n> is index number.
> +
> +Dynamic nodes
> +~~~~~~~~~~~~~
> +
> +The Quick (and dirty) method. A software node can be created on the fly with
> +:c:func:`fwnode_create_software_node`. The nodes create "on-the-fly" don't

                                                    created

> +differ from statically described software nodes in any way, but for now the API
> +does not support naming of these nodes::
> +
> +	static const struct property_entry my_props[] = {
> +		PROPERTY_ENTRY_STRING("foo", "bar"),
> +		{ }
> +	};
> +
> +	static int my_init(void)
> +	{
> +		struct fwnode_handle *fwnode;
> +
> +		/* Software node without a parent. */
> +		fwnode = fwnode_create_software_node(my_props, NULL);
> +		if (IS_ERR(fwnode))
> +			return PTR_ERR(fwnode);
> +
> +		return -1;
> +	}
> +
> +Linking software nodes with the device (struct device) entries
> +--------------------------------------------------------------
> +
> +Ideally the software node should be assigned to the device entry before the
> +device is registered (just like any other fwnode).
> +
> +When the software node is the primary fwnode for the device, the fwnode of the
> +device needs to simply point to the software node fwnode. Using a helper
> +:c:func:`software_node_fwnode` in the following example::
> +
> +	static const struct software_node my_node = {
> +		.name = "thenode",
> +	};
> +
> +	static int my_init(void)
> +	{
> +		struct device my_device = { };
> +		int ret;
> +
> +		ret = software_node_register(my_node);
> +		if (ret)
> +			return ret;
> +
> +		device_initialize(&my_device);
> +		dev_set_name(&my_device, "thedevice")
> +
> +		my_device.fwnode = software_node_fwnode(swnode);
> +
> +		return device_add(&my_device);
> +	}
> +
> +When the software node is the secondary fwnode for a device, i.e. the device has
> +either ACPI or DT (or something else) firmware node as the primary fwnode, the
> +node should be assigned with :c:func:`set_secondary_fwnode`. If the
> +``secondary`` member of the primary fwnode needs to be manually made to point
> +to the software node, the code needs to make sure that the ``secondary`` member
> +of the software node fwnode points to a specific value of ``ERR_PTR(-ENODEV)``::
> +
> +	struct fwnode_handle *fwnode = software_node_fwnode(swnode);
> +
> +	fwnode->secondary = ERR_PTR(-ENODEV);
> +	dev->fwnode->secondary = fwnode;
> +
> +Note! There is no requirement to bind a software node with a device entry, i.e.
> +having "sub-nodes" that represent for example certain resources the parent
> +software node has is not a problem.
> +
> +Node References
> +---------------
> +
> +TODO
> +
> +Device graph
> +------------
> +
> +TODO
> +
> +API
> +===
> +
> +.. kernel-doc:: include/linux/property.h
> +   :internal: software_node
> +
> +.. kernel-doc:: include/linux/fwnode.h
> +   :internal: fwnode_handle
> +
> +.. kernel-doc:: drivers/base/core.c
> +   :functions: set_secondary_fwnode
> +
> +.. kernel-doc:: drivers/base/swnode.c
> +   :functions: is_software_node is_software_node software_node_fwnode software_node_find_by_name software_node_register_nodes software_node_unregister_nodes software_node_register software_node_register fwnode_create_software_node fwnode_remove_software_node
> 

Thanks for the doc.
-- 
~Randy



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux