What is the relationship between data in devicetree and structdevice?
In general, the relationship between devicetree and structdevice should still be the structdevice * parent parameter that is always passed when platformdevice is generated. Next we will first describe the transfer process in the source code (taking at91rm9200 as an example ):
1,
Dt_machine_start (at91sam_dt, "Atmel at91sam (Device Tree )")
/* Maintainer: Atmel */
. Timer = & at91sam926x_timer,
. Map_io = at91_map_io,
. Init_early = at91_dt_initialize,
. Init_irq = at91_dt_init_irq,
. Init_machine = at91_dt_device_init,
. Dt_compat = at91_dt_board_compat,
Machine_end
2,
Staticvoid _ init at91_dt_device_init (void)
{
Of_platform_populate (null, of_default_bus_match_table, null, null );
}
3,
/**
* Of_platform_populate ()-populate platform_devices from device treedata
* @ Root: parent of the first level to probe or NULL for the root of Thetree
* @ Matches: match table, null to use the default
* @ Parent: parent to hook devicesfrom, null for toplevel
*
* Similar to of_platform_bus_probe (), this function walks the devicetree
* And creates devices from nodes. It differs in that it follows themodern
* Convention of requiring all device nodes to have a 'compute' property,
* And it is suitable for creating devices which are children of theroot
* Node (of_platform_bus_probe will only create children of the rootwhich
* Are selected by the @ matches argument ).
*
* New board support shoshould be using this function instead
* Of_platform_bus_probe ().
*
* Returns 0 on success, <0 on failure.
*/
// Populateplatform devices from the devicetree data.
Intof_platform_populate (structdevice_node * root,
Conststruct of_device_id * matches,
Conststruct of_dev_auxdata * lookup,
Structdevice * parent)
{
Structdevice_node * child;
Intrc = 0;
Root = root? Of_node_get (Root): of_find_node_by_path ("/");
If (! Root)
Return-einval;
For_each_child_of_node (root, child ){
// Generate platformdevice
Rc = of_platform_bus_create (child, matches, lookup, parent, true );
If (RC)
Break;
}
Of_node_put (Root );
Returnrc;
}
4,
/**
* Of_platform_bus_create ()-create a device for a node and itschil.pdf.
* @ Bus: Device node of the bus to instantiate
* @ Matches: match table for bus nodes
* @ Lookup: auxdata table for matching ID and platform_data with devicenodes
* @ Parent: parent for new device, or NULL for top level.
* @ Strict: require compatible property
*
* Creates a platform_device for the provided device_node, andoptionally
* Recursively create devices for all the child nodes.
*/
// Generate a device file for the node and its child node.
Staticint of_platform_bus_create (structdevice_node * bus,
Const struct of_device_id * matches,
Const struct of_dev_auxdata * lookup,
Struct device * parent, boolstrict)
{
Conststruct of_dev_auxdata * auxdata;
Structdevice_node * child;
Structplatform_device * dev;
Constchar * bus_id = NULL;
Void * platform_data = NULL;
Intrc = 0;
/* Make sure it has a compatible property */
If (strict &&(! Of_get_property (bus, "compatible", null ))){
Pr_debug ("% s ()-skipping % s, no compatible prop \ n ",
_ FUNC __, bus-> full_name );
Return0;
}
Auxdata = of_dev_lookup (lookup, bus );
If (auxdata ){
Bus_id = auxdata-> name;
Platform_data = auxdata-> platform_data;
}
If (of_device_is_compatible (bus, "arm, primecell ")){
Of_amba_device_create (bus, bus_id, platform_data, parent );
Return0;
}
Dev = of_platform_device_create_pdata (bus, bus_id, platform_data, parent );
If (! Dev |! Of_match_node (matches, bus ))
Return0;
For_each_child_of_node (bus, child ){
Pr_debug ("create child: % s \ n", child-> full_name );
Rc = of_platform_bus_create (child, matches, lookup, & Dev-> Dev, strict );
If (RC ){
Of_node_put (child );
Break;
}
}
Returnrc;
}
The code is divided into two steps: 4.1 and 4.2.
4.1
Staticstruct amba_device * of_amba_device_create (structdevice_node * node,
Const char * bus_id,
Void * platform_data,
Struct device * parent)
{
Structamba_device * dev;
Constvoid * prop;
Inti, RET;
Pr_debug ("creatingamba device % s \ n", node-> full_name );
If (! Of_device_is_available (node ))
Returnnull;
Dev = amba_device_alloc (null, 0, 0 );
If (! Dev)
Returnnull;
/* Setup generic device info */
Dev-> Dev. coherent_dma_mask = ~ 0;
Dev-> Dev. of_node = of_node_get (node );
Dev-> Dev. Parent = parent;
Dev-> Dev. platform_data = platform_data;
......
}
4.2
/**
* Of_platform_device_create_pdata-alloc, initialize and register anof_device
* @ NP: pointer to node to create device
* @ Bus_id: Name to assign Device
* @ Platform_data: pointer to populate platform_data pointer
* @ Parent: Linux Device Model parentdevice.
*
* Returns pointer to created platform device, or null if a device wasnot
* Registered. unavailable devices will not get registered.
*/
// Allocate memory, initialize and register an of_device
Structplatform_device * of_platform_device_create_pdata (
Structdevice_node * NP,
Constchar * bus_id,
Void * platform_data,
Structdevice * parent)
{
Structplatform_device * dev;
If (! Of_device_is_available (NP ))
Returnnull;
Dev = of_device_alloc (NP, bus_id, parent );
......
Returndev;
}
4.2.1
/**
* Of_device_alloc-allocate and initialize an of_device
* @ NP: Device node to assign to Device
* @ Bus_id: Name to assign to the device. May be null to use defaultname.
* @ Parent: parent device.
*/
// Allocate memory and initialize of_device
Structplatform_device * of_device_alloc (structdevice_node * NP,
Const char * bus_id,
Struct device * parent)
{
Structplatform_device * dev;
Intrc, I, num_reg = 0, num_irq;
Structresource * res, temp_res;
Dev = platform_device_alloc ("",-1 );
If (! Dev)
Returnnull;
/* Count the IO and IRQ Resources */
If (of_can_translate_address (NP ))
While (of_address_to_resource (NP, num_reg, & temp_res) = 0)
Num_reg ++;
Num_irq = of_irq_count (NP );
/* Populate the resource table */
If (num_irq | num_reg ){
Res = kzarloc (sizeof (* res) * (num_irq + num_reg), gfp_kernel );
If (! Res ){
Platform_device_put (Dev );
Returnnull;
}
Dev-> num_resources = num_reg + num_irq;
Dev-> resource = res;
For (I = 0; I <num_reg; I ++, Res ++ ){
Rc = of_address_to_resource (NP, I, Res );
Warn_on (RC );
}
Warn_on (of_irq_to_resource_table (NP, res, num_irq )! = Num_irq );
}
Dev-> Dev. of_node = of_node_get (NP );
# Ifdefined (config_microblze)
Dev-> Dev. dma_mask = & Dev-> archdata. dma_mask;
# Endif
Dev-> Dev. Parent = parent;
If (bus_id)
Dev_set_name (& Dev-> Dev, "% s", bus_id );
Else
Of_device_make_bus_id (& Dev-> Dev );
Returndev;
}
Overall analysis: the parent parameter is initially initialized to null, with no value assigned until it is assigned to the dev. Parent attribute of platformdevice. The relationship is intriguing.
(DT Series 6) What is the relationship between data in devicetree and struct device?