搜了一些网上关于device tree的相关文章,在wowotech的站点平时多浏览了几下。理解能力不够,就会多浏览几遍。浏览完了,总要记下点东西,留下点什么东西。目前,百度下device tree点什么东西,基本上都是转载的wowotech站点的文章。比较单一,另外如果有童鞋希望学习点什么东西,可以直接参照内核源码目录下的相关doc文档。
正题:
device tree的device node 最后如何注册到bus上?
1.首先,看下这个platform_device的结构体在哪生成的吧。函数部分如下
/**
* of_platform_device_create_pdata - Alloc, initialize and register an of_device
* @np: pointer to node to create device for
* @bus_id: name to assign device
* @platform_data: pointer to populate platform_data pointer with
* @parent: Linux device model parent device.
*
* Returns pointer to created platform device, or NULL if a device was not
* registered. Unavailable devices will not get registered.
*/
static struct platform_device *of_platform_device_create_pdata(
struct device_node *np,
const char *bus_id,
void *platform_data,
struct device *parent)
{
struct platform_device *dev;
<span style="white-space:pre"> </span>//首先检查device是否是可用的?本节的重点
if (!of_device_is_available(np) ||
of_node_test_and_set_flag(np, OF_POPULATED))
return NULL;
<span style="white-space:pre"> </span>//分配一个platform_device 结构体
dev = of_device_alloc(np, bus_id, parent);
if (!dev)
goto err_clear_flag;
<span style="white-space:pre"> </span>//初始化隶属总线类型,此处当然是platform总线类型
of_dma_configure(&dev->dev);
dev->dev.bus = &platform_bus_type;
dev->dev.platform_data = platform_data;
/* We do not fill the DMA ops for platform devices by default.
* This is currently the responsibility of the platform code
* to do such, possibly using a device notifier
*/
<span style="white-space:pre"> </span>//真正的devic 添加处
if (of_device_add(dev) != 0) {
platform_device_put(dev);
goto err_clear_flag;
}
return dev;
err_clear_flag:
of_node_clear_flag(np, OF_POPULATED);
return NULL;
}
2.上述函数的第1个调用函数具体如下:
/**
* of_device_is_available - check if a device is available for use
*
* @device: Node to check for availability
*
* Returns 1 if the status property is absent or set to "okay" or "ok",
* 0 otherwise
*/
int of_device_is_available(const struct device_node *device)
{
unsigned long flags;
int res;
raw_spin_lock_irqsave(&devtree_lock, flags);
res = __of_device_is_available(device); //--------------------------//关键之处
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return res;
}
/**
* __of_device_is_available - check if a device is available for use
*
* @device: Node to check for availability, with locks already held
*
* Returns 1 if the status property is absent or set to "okay" or "ok",
* 0 otherwise
*/
static int __of_device_is_available(const struct device_node *device)
{
const char *status;
int statlen;
if (!device)
return 0;
status = __of_get_property(device, "status", &statlen); ------------------------------ a
if (status == NULL)
return 1;
if (statlen > 0) {
if (!strcmp(status, "okay") || !strcmp(status, "ok")) ---------------------------- b
return 1;
}
return 0;
}
a.设备树里的常用调用,参数有三个:device_node 的pointer 、属性、长度
b.如果返回的状态是okay or ok,则返回1。
3.实际上,这句话反映到dts编写规则上,就是property里的status是否是okay or ok,否则所编写的device_node并不会注册到platform bus上
栗子如下:
usb0: ohci@00600000 {
status = "okay"; --------------------------------Here!!!!!
num-ports = <3>;
atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW *//* Activate to have access to port A */
&pioD 19 GPIO_ACTIVE_LOW
&pioD 20 GPIO_ACTIVE_LOW
>;
};