struct device_node *node = pdev->dev.of_node;
时间: 2023-11-27 12:48:26 浏览: 68
这段代码的作用是获取一个设备节点。其中pdev是一个指向设备结构体的指针,dev是该结构体中的一个成员,of_node是dev中的另一个成员,代表设备节点。因此,该代码的作用是获取pdev指向的设备的设备节点,并将其赋值给node指针。
```c
struct device_node *node = pdev->dev.of_node;
```
相关问题
static int sbsa_uart_probe(struct platform_device *pdev) { struct uart_amba_port *uap; struct resource *r; int portnr, ret; int baudrate; /* * Check the mandatory baud rate parameter in the DT node early * so that we can easily exit with the error. */ if (pdev->dev.of_node) { struct device_node *np = pdev->dev.of_node; ret = of_property_read_u32(np, "current-speed", &baudrate); if (ret) return ret; } else { baudrate = 115200; } portnr = pl011_find_free_port(); if (portnr < 0) return portnr; uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port), GFP_KERNEL); if (!uap) return -ENOMEM; ret = platform_get_irq(pdev, 0); if (ret < 0) { if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot obtain irq\n"); return ret; } uap->port.irq = ret; #ifdef CONFIG_ACPI_SPCR_TABLE if (qdf2400_e44_present) { dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n"); uap->vendor = &vendor_qdt_qdf2400_e44; } else #endif uap->vendor = &vendor_sbsa; uap->reg_offset = uap->vendor->reg_offset; uap->fifosize = 32; uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.ops = &sbsa_uart_pops; uap->fixed_baud = baudrate; snprintf(uap->type, sizeof(uap->type), "SBSA"); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ret = pl011_setup_port(&pdev->dev, uap, r, portnr); if (ret) return ret; platform_set_drvdata(pdev, uap); return pl011_register_port(uap); }linux内核uart驱动在设备注册时,使用acpi表定义的波特率来初始化串口,请根据我的要求和上述代码,在代码中添加这一功能
好的,根据你的要求,我可以在该函数中添加获取ACPI表中定义的波特率的功能,并使用该波特率来初始化串口。代码如下:
```
static int sbsa_uart_probe(struct platform_device *pdev) {
struct uart_amba_port *uap;
struct resource *r;
int portnr, ret;
int baudrate;
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
/* Check if ACPI companion device exists, and if so, read the current-speed property */
if (adev) {
struct acpi_device_node *adev_node = acpi_node_get_device_node(adev->handle);
if (adev_node) {
struct fwnode_handle *fwnode = &adev_node->fwnode;
ret = fwnode_property_read_u32(fwnode, "current-speed", &baudrate);
if (ret)
return ret;
}
} else if (pdev->dev.of_node) {
/* If there is no ACPI companion device, fall back to reading the current-speed property from DT node */
struct device_node *np = pdev->dev.of_node;
ret = of_property_read_u32(np, "current-speed", &baudrate);
if (ret)
return ret;
} else {
baudrate = 115200;
}
portnr = pl011_find_free_port();
if (portnr < 0)
return portnr;
uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port), GFP_KERNEL);
if (!uap)
return -ENOMEM;
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "cannot obtain irq\n");
return ret;
}
uap->port.irq = ret;
#ifdef CONFIG_ACPI_SPCR_TABLE
if (qdf2400_e44_present) {
dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n");
uap->vendor = &vendor_qdt_qdf2400_e44;
} else
#endif
uap->vendor = &vendor_sbsa;
uap->reg_offset = uap->vendor->reg_offset;
uap->fifosize = 32;
uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM;
uap->port.ops = &sbsa_uart_pops;
uap->fixed_baud = baudrate;
snprintf(uap->type, sizeof(uap->type), "SBSA");
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ret = pl011_setup_port(&pdev->dev, uap, r, portnr);
if (ret)
return ret;
platform_set_drvdata(pdev, uap);
return pl011_register_port(uap);
}
```
我添加的代码在函数开头处,首先判断是否存在ACPI companion device,如果存在则从其属性中读取波特率,否则从DT node中读取。读取到的波特率将被用于初始化串口。
of_device_id.data对应设备树
`of_device_id`结构体中的`data`字段是一个指向与设备相关的数据的指针,通常用于在驱动程序中访问设备树的节点属性。在设备树中,每个节点都有一个属性列表,驱动程序可以使用`of_device`结构体中的`dev.of_node`成员指针来获取该节点的属性,然后进行相应的操作。
例如,假设我们有一个名为`my-device`的设备节点,其属性列表中包含一个名为`my-property`的属性,我们可以先在`of_device_id`结构体中定义一个与之对应的数据结构:
```c
struct my_device_data {
int my_property;
};
```
然后,在驱动程序初始化时,我们可以将这个数据结构指定为`of_device_id`结构体的`data`字段:
```c
static const struct of_device_id my_driver_of_match[] = {
{
.compatible = "my-device",
.data = &my_device_data
},
{ /* end of list */ },
};
```
接着,在驱动程序的`probe()`函数中,我们可以通过`of_device`结构体中的`dev.of_node`成员指针获取设备节点的属性,并将其保存到之前定义的数据结构中:
```c
static int my_driver_probe(struct platform_device *pdev)
{
struct my_device_data *data;
struct device_node *np = pdev->dev.of_node;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
of_property_read_u32(np, "my-property", &data->my_property);
/* do something with my-property value */
return 0;
}
```
在上面的例子中,`of_property_read_u32()`函数用于从设备节点的属性列表中读取`my-property`属性,并将其保存到`my_device_data`结构体中的`my_property`字段中。这样,我们就可以在驱动程序中访问设备树中的节点属性,并按需进行相应的操作。