高通单安卓display开发这段代码代表什么ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL); if (ret < 0) { if (ret == -ENODEV) return 0; return ret; }
时间: 2024-02-15 07:28:48 浏览: 101
这段代码的作用是在设备树中查找指定节点的面板或者桥接器,并将其指针赋值给panel变量。具体来说,drm_of_find_panel_or_bridge函数用于在设备树中查找指定节点的面板或者桥接器,并返回一个指向该面板或桥接器节点的指针。np是指向要查找的节点的指针,1表示要查找的节点类型是面板,0表示要查找的节点类型是桥接器,panel是指向查找到的面板或桥接器节点的指针。如果查找成功,ret的值为0;如果查找失败,ret的值为负数,此时会根据ret的值进行相应的错误处理。如果ret的值为-ENODEV,表示该设备没有面板或桥接器节点,可以返回0;否则返回ret。
相关问题
解释一下这段代码int drm_of_find_panel_or_bridge(const struct device_node *np, int port, int endpoint, struct drm_panel **panel, struct drm_bridge **bridge) { int ret = -EPROBE_DEFER; struct device_node *remote; if (!panel && !bridge) return -EINVAL; if (panel) *panel = NULL; /* * of_graph_get_remote_node() produces a noisy error message if port * node isn't found and the absence of the port is a legit case here, * so at first we silently check whether graph presents in the * device-tree node. */ if (!of_graph_is_present(np)) return -ENODEV; remote = of_graph_get_remote_node(np, port, endpoint); if (!remote) return -ENODEV; if (panel) { *panel = of_drm_find_panel(remote); if (!IS_ERR(*panel)) ret = 0; else *panel = NULL; } /* No panel found yet, check for a bridge next. */ if (bridge) { if (ret) { *bridge = of_drm_find_bridge(remote); if (*bridge) ret = 0; } else { *bridge = NULL; } } of_node_put(remote); return ret; }
这段代码是 Linux 内核 DRM 子系统中的函数 `drm_of_find_panel_or_bridge` 的实现代码,该函数用于查找设备树节点下的面板或桥接器。
该函数的参数 `np` 是一个指向设备树节点的指针,`port` 和 `endpoint` 是设备树节点的端口和端点号,`panel` 和 `bridge` 分别是指向 drm_panel 和 drm_bridge 结构体指针的指针。函数返回一个整数值,表示查找结果。
在函数实现中,首先判断传入的参数 `panel` 和 `bridge` 是否都为空指针,如果是则返回 -EINVAL。接着,使用 `of_graph_is_present` 函数判断设备树节点中是否存在 graph 节点,如果不存在则返回 -ENODEV。然后,调用 `of_graph_get_remote_node` 函数获取指定端口和端点号的远程节点,如果获取失败则返回 -ENODEV。
接着,如果 `panel` 不为空,则调用 `of_drm_find_panel` 函数查找面板节点并将结果存入 `panel` 指针中,如果查找成功则将返回值 `ret` 设为 0,否则将 `panel` 指针设为 NULL。如果 `panel` 为空,则不查找面板节点。
如果没有找到面板节点,则继续查找桥接器节点。如果 `bridge` 不为空,则先判断 `ret` 的值,如果不为 0,则调用 `of_drm_find_bridge` 函数查找桥接器节点并将结果存入 `bridge` 指针中,如果查找成功则将返回值 `ret` 设为 0,否则将 `bridge` 指针设为 NULL。如果 `bridge` 为空,则不查找桥接器节点。
最后,使用 `of_node_put` 函数释放获取到的远程节点,最终返回查找结果。
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表定义的波特率来初始化串口,请根据我的要求和上述代码,在代码中添加这一功能
在该代码的if (pdev->dev.of_node)分支中,我们可以添加以下代码来使用ACPI表定义的波特率来初始化串口:
```
#ifdef CONFIG_ACPI
if (!pdev->dev.of_node) {
int acpi_baudrate = 0;
if (acpi_get_integer(uap->port.dev->fwnode, "current-speed", &acpi_baudrate) == 0) {
baudrate = acpi_baudrate;
}
}
#endif
```
这里我们使用了ACPI库中的acpi_get_integer()函数来获取ACPI表中定义的波特率。如果成功获取到了波特率,则将其赋值给baudrate变量,否则使用默认值115200。注意,我们需要在代码中包含CONFIG_ACPI宏的判断,以确保ACPI支持已经被启用。
阅读全文