A.串行子系统层次:
/dev/tty* , /dev/ir*, /dev/ppp*
______________________________
|
线路规程
|
tty核心层
|
tty驱动程序
|
底层驱动程序
//这里的理解就是高通平台里,serial_core.c就是串口tty核心层,tty_register_driver驱动的注册也是在
//这个文件里面注册的.
//而msm_serial.c,msm_serial_hs_lite.c,msm_serial_hs.c是底层的驱动程序.
B.设备驱动匹配:
1.compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; //--->/dev/HSL*
./msm_serial.c
{ .compatible = "qcom,msm-uartdm-v1.1", .data = (void *)UARTDM_1P1 },
{ .compatible = "qcom,msm-uartdm-v1.2", .data = (void *)UARTDM_1P2 },
{ .compatible = "qcom,msm-uartdm-v1.3", .data = (void *)UARTDM_1P3 },
{ .compatible = "qcom,msm-uartdm-v1.4", .data = (void *)UARTDM_1P4 },
{ .compatible = "qcom,msm-uartdm" },
2.compatible = "qcom,msm-lsuart-v14"; //--->/dev/HSL*
./msm_serial_hs_lite.c
{ .compatible = "qcom,msm-lsuart-v14"
3. compatible = "qcom,msm-hsuart-v14"; //--->/dev/HS*
./msm_serial_hs.c
{ .compatible = "qcom,msm-hsuart-v14"},
C.串口驱动:
/dev/tty*
|
---msm_serial.c
| 提供接口
---msm_serial_hs_lite.c <----------- serial_core.c
|
---msm_serial_hs.c
//serial_core.c为实际的驱动提供核心api,完成driver注册和ops实现
简单分析一下uart驱动:
msm_serial_init:
---> uart_register_driver(&msm_uart_driver);
---> platform_driver_register(&msm_platform_driver)
uart_register_driver作用:
向uart核心层注册driver. 依次向tty层注册,并初始化driver每个端口的状态。
platform_driver_register作用:
平台驱动的作用就是完成devic和driver的匹配,也即是dsti与driver的probe,probe到了就把dtsi里面的内容填充到driver
里面的结构体中,完成驱动的初始化,向应用层提供文件ops机制(或者说伪总线的作用是将设备和linux设备模型连接在一起)。
-----------------
msm_uart_driver:
static struct uart_driver msm_uart_driver = {
.owner = THIS_MODULE,
.driver_name = "msm_serial",
.dev_name = "ttyMSM",
.nr = UART_NR, //line nums (tty nums)
.cons = MSM_CONSOLE, //console
};
msm_platform_driver:
static struct platform_driver msm_platform_driver = {
.remove = msm_serial_remove,
.probe = msm_serial_probe,
.driver = {
.name = "msm_serial",
.of_match_table = msm_match_table,
.pm = &msm_serial_pm_ops,
},
};
--------------------
msm_serial_probe:
//找到serial节点,计数增加line
of_alias_get_id(pdev->dev.of_node, "serial");
//初始化时钟
msm_port->clk = devm_clk_get(&pdev->dev, "core");
if (IS_ERR(msm_port->clk))
return PTR_ERR(msm_port->clk);
if (msm_port->is_uartdm) {
msm_port->pclk = devm_clk_get(&pdev->dev, "iface");
if (IS_ERR(msm_port->pclk))
//注释说了这个函数是让每个driver增加一个port, 目的是允许扩展uart_port
uart_add_one_port(&msm_uart_driver, port);
static const struct dev_pm_ops msm_serial_pm_ops = {
#ifdef CONFIG_PM_SLEEP
.suspend = msm_serial_suspend,
.resume = msm_serial_resume,
.freeze = msm_serial_freeze,
.thaw = msm_serial_resume,
.poweroff = msm_serial_suspend,
.restore = msm_serial_resume,
#endif
};
--------------------------------------
ops里面暂时没见解,调用的是serial_core.c里面的api