Register Platform_device process analysis based on Linux 3.10.49 kernel from DTS file __linux

Source: Internet
Author: User
process Analysis of registering platform_device from DTS file based on Linux 3.10.49 kernel

Linux kernel 3.10.49+
Here, let's talk about how Linux registers and initializes onboard information through DTS for device (Platform_device).
Locate the Dt_machine_start and Machine_end macros in ARCH/ARM/MACH-******/******.C, as follows:
Dt_machine_start (******_dt, "************* SoC (flattened Device tree)")
. Atag_offset = 0x100,
. Dt_compat = ******_dt_compat,//matching DTS
. Map_io = ******_map_io,//board-level address memory mapping, Linux MMU
. INIT_IRQ = irqchip_init,//board level interrupt initialization.
. Init_time = ******_timer_and_clk_init,//board-level clock initialization, such as AHB,APB
. Init_machine = ******_dt_init,//Here is the parse DTS file entry.
. Restart = ******_restart,//reboot, watchdog register related can be set here
Machine_end

where. Dt_compat = ******_dt_compat This struct is the one that matches the DTS file, such as:
static const char * Const ******_dt_compat[] = {
"******,******-soc",
Null
};
This "******,******-SOC" string can be found under the root node of our DTS.

Okay, let's take a look at init_machine = ******_dt_init this callback function.
1. Arch/arm/mach-******/******.c:void __init ******_dt_init (void)
_dt_init (void)--> of_platform_populate (null, of_default_bus_match_table, NULL, NULL);
Of_default_bus_match_table This is the global variable for the struct of_device_id.
const struct OF_DEVICE_ID of_default_bus_match_table[] = {
{. compatible = "Simple-bus",},
#ifdef Config_arm_amba
{. compatible = "Arm,amba-bus",},
#endif/* Config_arm_amba * *
{}/* Empty terminated list * *
};
When we design DTS, we put some devices that need to specify a register base address under a device node with compatible = "Simple-bus" as a match. Here are some introductions on why.

2. Drivers/of/platform.c:int of_platform_populate (...)
Of_platform_populate (...)--> of_platform_bus_create (...)
Before that, there will be Of_get_property (bus, "compatible", NULL)
Check if there are compatible, if not, return, continue next, that is to say no compatible, this device will not be registered
For_each_child_of_node (root, child) {
PRINTK ("[%s%s%d] Child->name =%s, Child->full_name =%s\n", __file__, __func__, __line__, Child->name, child-& Gt;full_name);
rc = Of_platform_bus_create (child, matches, lookup, parent, true);
if (RC)
Break
}
To inquire about the child devices under the DTS root node, each child device must be of_platform_bus_create (...);
When all is done, through of_node_put (root); Frees the root node because it has been processed;

3. Drivers/of/platform.c:of_platform_bus_create (bus, ...)
dev = of_platform_device_create_pdata (bus, bus_id, platform_data, parent); We jump to 3-1-1 steps to run
if (!dev | |!of_match_node (matches, bus))//IS matching
Dt_compat = ******_dt_compat, which is compatible = "Simple-bus",
If the match succeeds, with this node as the parent node, continue polling all child nodes under this node
return 0;

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); Dev->dev with this node as the parent node, we jump to 3-2-1 steps to run
if (RC) {
Of_node_put (child);
Break
}
}

3-1-1. Drivers/of/platform.c:of_platform_device_create_pdata (...)
if (!of_device_is_available (NP))//view node is valid, if node has ' status ' attribute, must be okay or OK, is valid, no ' status ' attribute, also valid
return NULL;

dev = Of_device_alloc (NP, bus_id, parent); Alloc device, device initialization. Back to Dev, all devices can be considered platform_device, jump to 3-1-1-1 to see what the function does
if (!dev)
return NULL;

#if defined (config_microblaze)
Dev->archdata.dma_mask = 0xffffffffUL;
#endif
Dev->dev.coherent_dma_mask = Dma_bit_mask (32); Dev->dev is struct device. Continue initialization
Dev->dev.bus = &platform_bus_type; //
Dev->dev.platform_data = Platform_data;

PRINTK ("[%s%s%d] Of_device_add (device register) Np->name =%s\n", __file__, __func__, __line__, np->name);
if (Of_device_add (dev)!= 0) {//Registered device, Of_device_add (...)--> device_add (...)//This is part 2 of Device_re Gister ()
Platform_device_put (Dev);
return NULL;
}

3-1-1-1. Drivers/of/platform.c:of_device_alloc (...)
1) alloc Platform_device *dev
2 If there are reg and interrupts related properties, run Of_address_to_resource and of_irq_to_resource_table, add to Dev->resource
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);
/* PRINTK ("[%s%s%d] Res->name =%s, Res->start = 0x%X, Res->end = 0x%x\n", __file__, __func__, __line__, RES-&G T;name, Res->start, res->end); */
WARN_ON (RC);
}
WARN_ON (Of_irq_to_resource_table (NP, RES, NUM_IRQ)!= NUM_IRQ);

3) Dev->dev.of_node = Of_node_get (NP);
This node property has the compatible attribute, which comes from DTS, followed by driver matching device, which is matched by this attribute
We can view compatible by adding the following sentence.
PRINTK ("[%s%s%d] Bus->name =%s, Of_get_property (...) =%s\n ", __file__, __func__, __line__, Np->name, (char*) Of_get_property (NP," compatible ", NULL));
Node again to Dev, subsequent to the driver registration use.
4 run of_device_make_bus_id set device name, such as: Soc.2 or ac000000.serial, etc.

3-2-1. DRIVERS/OF/PLATFORM.C:
The child nodes of the node with compatible = "Simple-bus" will register the device with this node as the parent node in this step.
This is the actual onboard equipment and is also the ultimate goal.

The next analysis, we talk about the registration of Platform_driver, is how to match the platform_device we have just registered


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.