基于Linux 3.10.49内核从dts文件里注册platform(2)

dev = of_device_alloc(np, bus_id, parent);  // alloc设备, 设备初始化. 返回dev, 所有的设备都可认为是platform_device, 跳到3-1-1-1看看函数做了什么事情
    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 是 struct device. 继续初始化
        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) {      // 注册device, of_device_add(...) --> device_add(...) // This is part 2 of device_register()
        platform_device_put(dev);
        return NULL;
    }

3-1-1-1. drivers/of/platform.c : of_device_alloc(...)
    1) alloc platform_device *dev
    2) 如果有reg和interrupts的相关属性, 运行of_address_to_resource 和 of_irq_to_resource_table, 加入到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->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); 
        // 这个node属性里有compatible属性, 这个属性从dts来, 后续driver匹配device时, 就是通过这一属性进匹配
        // 我们可以通过添加下面一句话来查看compatible.
        // 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 再给dev, 后续给驱动注册使用.
    4) 运行 of_device_make_bus_id 设定device的名字, 如: soc.2 或 ac000000.serial 等

3-2-1. drivers/of/platform.c :
    以 compatible = "simple-bus"的节点的子节点都会以这个节点作为父节点在这步注册设备.
    这是实际的板载设备, 也是最终目的.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/47a695a3e2e5f9ed0e9f083591c66a07.html