蜗窝科技

ARM 的 resource 管理, 请赐教

蜗窝讨论区存档 · Linux kernel技术问答 · 楼主 Yoking Wang · 2016-07-08 · 11 帖

本文是原「蜗窝讨论区」的历史存档(2016-07-08),来自版块「Linux kernel技术问答」,共 11 帖。讨论区已停止服务,此处仅供查阅。

Yoking Wang · 2016-07-08 15:58

谁对 resouce管理比较清楚,请赐教! 有相关的文章也欢迎分享!

  1. resource 在哪里定义, 特别是引入 Device Tree 以后, resource的定义是否由Device Tree定义。
  2. resource 是怎么管理的?根据设备管理(申请设备的时候访问该设备的resource)还是board(芯片自带) 管理?

qdzhaozx · 2016-07-08 16:27

;)

qdzhaozx · 2016-07-08 16:31

Q: First, source的定义在哪? A: include/linux/ioport.h / * Resources are tree-like, allowing * nesting etc.. / struct resource { resource_size_t start; resource_size_t end; const char name; unsigned long flags; struct resource parent, sibling, child; }; Q:Second,resource的种类主要有哪些? A: / * IO resources have these defined flags. /

define IORESOURCE_BITS 0x000000ff / Bus-specific bits /

define IORESOURCE_TYPE_BITS 0x00001f00 / Resource type /

define IORESOURCE_IO 0x00000100 / PCI/ISA I/O ports /

define IORESOURCE_MEM 0x00000200 //................................................frequently, 访问设备就是访问那片mem

define IORESOURCE_REG 0x00000300 / Register offsets /

define IORESOURCE_IRQ 0x00000400//.................................................so do it,peripheral用的难免需要个中断

define IORESOURCE_DMA 0x00000800

define IORESOURCE_BUS 0x00001000

qdzhaozx · 2016-07-08 16:45

Q:引入device tree以后,resource在哪定义? A:以前是定义静态数组的方式 but now,是定义在dts文件里的, for instant,

pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>;//对mem的描述 interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>; //对IRQ的描述 #gpio-cells = <2>; gpio-controller; interrupt-controller; #interrupt-cells = <2>; clocks = <&pioAB_clk>; };

qdzhaozx · 2016-07-08 16:51


[== C++ ==]
Q:引入device tree以后,resource在哪定义?
A:以前是定义静态数组的方式
but  now,是定义在dts文件里的,
for instant,

pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>;//对mem的描述 interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>; //对IRQ的描述 #gpio-cells = <2>; gpio-controller; interrupt-controller; #interrupt-cells = <2>; clocks = <&pioAB_clk>; }; Q:怎么管理的? A: 随便找出一个platform driver的probe函数,一般都会有类似的语句 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);

a.走进去,看源码 /**

  • platform_get_resource - get a resource for a device

  • @dev: platform device

  • @type: resource type

  • @num: resource index */ 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) &amp;&amp; num-- == 0)
         return r;
    

    } return NULL; } DESC:只是一个for循环查找,比较resource type

b.so 在哪初始化的呢?猜,应该是在初始化的platform device的时候初始化的吧 c.在哪里初始化的呢?走起,看源码。 看这里:arch/arm/kernel/setup.c static int __init customize_machine(void) { /* * customizes platform devices, or adds new ones * On DT based machines, we fall back to populating the * machine from the device tree, if no callback is provided, * otherwise we would always need an init_machine callback. */ //当然如果定义了init_machine 首先执行这个实现,一般实现里也会实现下面的of_platform_populate //其实,真相就在这个函数里 if (machine_desc->init_machine) machine_desc->init_machine(; #ifdef CONFIG_OF else //如果config_of后,可以走到else ,看到了of_platform_populate of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); #endif return 0; } arch_initcall(customize_machine);

还有这里:init/main.c arch_initcall 定义的函数如何执行,需要到 do_basic_setup->do_initcalls里执行

qdzhaozx · 2016-07-08 16:55

at last,真相 /drivers/of/platforms.c of_platform_populate->of_platform_bus_create->of_platform_device_create_pdata->of_device_alloc


[== C++ ==]
struct platform_device *of_device_alloc(struct device_node *np,
                  const char *bus_id,
                  struct device *parent)
{
    ... ...
    /* count the io and irq resources */
    while (of_address_to_resource(np, num_reg, &temp_res) == 0)
        num_reg++;
    num_irq = of_irq_count(np);
    ... ...

    dev-&gt;num_resources = num_reg + num_irq;
    dev-&gt;resource = res;
    for (i = 0; i &lt; num_reg; i++, res++) {
        rc = of_address_to_resource(np, i, res);
        WARN_ON(rc);
    }
    if (of_irq_to_resource_table(np, res, num_irq) != num_irq)
        pr_debug(&quot;not all legacy IRQ resources mapped for %s\n&quot;,
             np-&gt;name);
}

... ...
return dev;

} EXPORT_SYMBOL(of_device_alloc);

wowo · 2016-07-08 17:22

解释的真清晰啊,赞!

qdzhaozx · 2016-07-08 19:25

相互学习

Yoking Wang · 2016-07-12 11:42

谢谢, 很详细! 受教了

Yoking Wang · 2016-07-12 11:50

另外, 还有一个比较具体的小问题困扰, 不知道有没有大神知道的。

关于device tree 的编译问题。

dtsi 里面已 label 的形式补充dts里面的note item 和value。 例如: A.dts 定义了 note1, B.dtsi 对 note1 进行补充

A.dts: { /{ .... note1{ item1 = <string>; }

}

}

B.dtsi: note1{ item2 = <string>; item3 = <srting>; }

现在的问题是, 我有没有办法在完全不修改 A.dts 的情况下(只修改B.dtsi) 把 item1 这个项从 note1 里面删除。

也就是note的合并有没有办法做替换 而不是做与操作。

wowo · 2016-07-12 14:56

dtsi并不对dts补充,相反,dts会覆盖dtsi中的相同内容。 你这种情况,noway~ 另外,你这个需求,本身也是不合理的。应该遵循这样的原则: dtsi抽象共性,dts抽象差异,因此要改也是改dts。