Linux gets the resource "go" described in the device tree source file (DTS)

Source: Internet
Author: User

Transferred from: http://www.linuxidc.com/Linux/2013-07/86839.htm

Transferred from: http://blog.sina.com.cn/s/blog_636a55070101mced.html

When Linux uses Platform_driver_register () to register platform_driver, it needs to know the device's interrupt number, memory address and other resources in Platform_driver's probe ().

The description information of these resources is stored in the resource data structure, the same resources are stored in a tree-shaped tree data structure, through the parent node, the sibling node, the child node is connected. such as interrupt resources, IO port resources, IO memory resources, DMA resources have different resource tree.

Linux uses struct resource to describe a resouce

struct Resource {
resource_size_t start; Start of resource scope
resource_size_t end; End of resource scope
const char *name; Resource Owner Name
unsigned long flags; Resource attribute Identification
struct resource *parent, *sibling, *child; Parent node of the resource tree, sibling node, byte point pointer
};

The resource_size_t is determined by the system for uint32_t or uint64_t.

In the platform mechanism, use Platform_get_resource () to obtain the specified resource type.


For example, to get the interrupt number,


IRQ = PLATFORM_GET_IRQ (Pdev, 0);

int Platform_get_irq (struct platform_device *dev, unsigned int num)
{
struct Resource *r = Platform_get_resource (dev, Ioresource_irq, num);

Return r? R->start:-enxio;
}
EXPORT_SYMBOL_GPL (PLATFORM_GET_IRQ);

PLATFORM_GET_IRQ () Returns a start that can be used with the interrupt number.


You can then use REQUEST_IRQ () to register the interrupt service function.


Again, for example, to get IO memory resources:

struct Resource *res_mem = Platform_get_resource (Pdev, Ioresource_mem, 0);


Can get an IO memory resource node pointer, including the beginning of the address, the end address, and so on, the length of the IO memory can be obtained by resource_size (), but this resource is just a description, want to really use this IO memory, but also through the first application, re-mapping process. For example, you can use Devm_request_mem_region () to request the use of this IO memory, and then use Ioremap () to map it out for user space.

Devm_request_mem_region (&pdev->dev, Res_mem->start, Resource_size (RES_MEM),
Res_mem->name))

Addr_start = Ioremap (Res_mem->start, Resource_size (Res_mem));


The return value of Ioremap () is the virtual address of the resource.


The resources for IO memory are given in the device tree source file (end of. DTS), the. dts file is used to describe the target board hardware information, and after Uboot is started, it is obtained using a specific API provided by Uboot, such as Fdt_ Getprop (), Fdt_path_offset (), these APIs are included in the Uboot header file <libfdt.h> inside.

Uboot the description in the. dts file, then assigns values to the corresponding registers and, after Linux boot, uses Platform_get_resource () to obtain the given resources and use them in the drive.


For example, a description of the GPIO resource in the. dts file:

GPIO: [email protected] {
#gpio-cells = <2>;
compatible = "Cavium,octeon-3860-gpio";
reg = <0x10700 0x00000800 0x0 0x100>;

Gpio-controller;

...

According to its description, it is known that the GPIO controller's IO Memory start address is: 0x107900000800, and the length is 0x100.

That is, from 0x107900000800 to 0X1079000008FF.

Use CAT/PROC/IOMEM in the target board to see:


1070000000800-10700000008FF:/[email protected]/[email protected]


A description of the i²c:

TWSI0: [email protected] {
#address-cells = <1>;
#size-cells = <0>;
compatible = "Cavium,octeon-3860-twsi";
reg = <0x11800 0x00001000 0x0 0x200>;

Interrupts = <0 45>;
Clock-rate = <100000>;

IO Memory start address is: 0x118000001000, length is 0x200.

From 0x118000001000 to 0x1180000011ff.

Use CAT/PROC/IOMEM in the target board to see:


1180000001000-11800000011FF:/[email protected]/[email protected]

=====================================================================================

=====================================================================================

Platform_get_resource function source code is as follows:

struct resource *platform_get_resource (struct Platform_device *dev,

unsigned int type, unsigned int num)

{

int i;

for (i = 0; i < dev->num_resources; i++) {

struct Resource *r = &dev->resource[i];

if (type = = Resource_type (r) && num--= = 0)

return R;

}

return NULL;

}

Function Analysis:

struct Resource *r = &dev->resource[i];

This line of code allows you to search from the first resource, regardless of which resource you want to get.

if (type = = Resource_type (r) && num--= = 0)

This line of code first through the type = = Resource_type (r) to determine whether the current resource type is matched, if the match is then num--= = 0 To determine whether you want to, if not match the next copy of the resource will not be executed num--= = 0 of the sentence code.

With the above two steps you can locate the resources you are looking for, and then return the resources. Returns null if all do not match.

Example Analysis:

Here's an example of how it gets the resources of the device.

The device resources are as follows:

static struct resource s3c_buttons_resource[] = {

[0]={

. Start = S3c24xx_pa_gpio,

. end = S3c24xx_pa_gpio + S3c24xx_sz_gpio-1,

. Flags = Ioresource_mem,

},

[1]={

. Start = Irq_eint8,

. end = Irq_eint8,

. Flags = IORESOURCE_IRQ,

},

[2]={

. Start = irq_eint11,

. end = Irq_eint11,

. Flags = IORESOURCE_IRQ,

},

[3]={

. Start = irq_eint13,

. end = Irq_eint13,

. Flags = IORESOURCE_IRQ,

},

[4]={

. Start = irq_eint14,

. end = Irq_eint14,

. Flags = IORESOURCE_IRQ,

},

[5]={

. Start = irq_eint15,

. end = irq_eint15,

. Flags = IORESOURCE_IRQ,

},

[6]={

. Start = irq_eint19,

. end = irq_eint19,

. Flags = IORESOURCE_IRQ,

}

};

The driver gets the first resource through the following code:

struct resource *res;

res = Platform_get_resource (Pdev, Ioresource_mem, 0);

The function enters for inside, I=0,num_resources=7, takes out resource[0] resources. Resource_type (r) extracts the resource type of the resource and compares it to the type of resource passed down by the function. The num=0 (which first determines if it equals 0 and then 1) meets the requirements and returns the resource.

The code to get the remaining resources is as follows:

for (i=0; i<6; i++) {

BUTTONS_IRQ = Platform_get_resource (pdev,ioresource_irq,i);

if (Buttons_irq = = NULL) {

Dev_err (Dev, "no IRQ resource specified\n");

ret =-enoent;

Goto Err_map;

}

Button_irqs[i] = buttons_irq->start;

}

The analysis is as follows:

For the first loop:

BUTTONS_IRQ = Platform_get_resource (pdev,ioresource_irq,0);

In taking out the first resource for Resource_type (R) to determine the resource type is not met (at this time num--= = 0 This sentence did not execute), and then take out a second resource, at this time I=1,num_resources=7,num pass down to 0, the resource type to determine when matching, Num is also equal to 0, which determines the resource and returns.

For the second loop:

BUTTONS_IRQ = Platform_get_resource (pdev,ioresource_irq,1);

Take out the second resource when the Resource_type (r) resource type matches, but Num passes it down to 1, execution num--= = 0 o'clock does not match (but Num starts from minus 1, which results in a third resource being num==0) and has to come up with a third resource. The rest and so on.

Summarize:

struct resource *platform_get_resource (struct Platform_device *dev,

unsigned int type, unsigned int num)

The unsigned int type determines the type of resource, and unsigned int num determines the resource for the type (starting from 0). This resource can be located even if the same type of resource is not continuously emitted in the resource array.

such as the first IORESOURCE_IRQ type resources in resource[2], and the second in resource[5], that

Platform_get_resource (pdev,ioresource_irq,0);

Can locate the first IORESOURCE_IRQ resources;

Platform_get_resourc

Linux gets the resource "go" described in the device tree source file (DTS)

Related Article

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.