uart_register_driver和platform_driver_register之间的区别?

enf*_*net 3 kernel serial-port linux-device-driver linux-kernel uart

我正在研究内核代码中的UART驱动程序,想知道,谁首先进入图片,device_register()或者driver_register()打电话?

为了区别他们,请遵循.

在UART探测中,我们打电话

uart_register_driver(struct uart_driver *drv)
Run Code Online (Sandbox Code Playgroud)

成功注册后,

uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
Run Code Online (Sandbox Code Playgroud)

请详细解释一下.

Sam*_*nko 6

这实际上是两个问题,但我会尝试解决这两个问题.

谁首先进入图片,device_register()driver_register()打电话?

由于它在说明文档/驱动程序模型/ binding.txt,不要紧在特定的顺序调用device_register()driver_register().

  • device_register() 将设备添加到设备列表并迭代驱动程序列表以查找匹配项
  • driver_register() 将驱动程序添加到驱动程序列表并迭代设备列表以查找匹配项

找到匹配后,匹配的设备和驱动程序将绑定,并在驱动程序代码中调用相应的探测功能.

如果你还在好奇哪一个是第一次调用(因为它并不重要) -通常这是device_register()因为设备通常被登记在initcalls从core_initcallarch_initcall,并且驱动程序通常被注册的device_initcall,后来执行.

也可以看看:

[1] 从平台设备获取名称的位置

[2] 谁调用了驱动程序的probe()

[3] Linux:module_init()与core_initcall()与early_initcall()

区别uart_register_driverplatform_driver_register

正如您所注意到的,一台设备有2个驱动程序(平台驱动程序和UART驱动程序).但是不要让这让你感到困惑:这些只是在一个(实际上)驱动程序中使用的两个驱动程序API.解释很简单:UART驱动程序API只缺少我们需要的一些功能,并且此功能在平台驱动程序API中实现.以下是常规tty驱动程序中每个API的责任:

  • 平台驱动程序API用于3件事:
    1. 匹配设备(在设备树文件中描述)与驱动程序; 这样,探针功能将由平台驱动程序框架为我们执行
    2. 获取设备信息(从设备树中读取)
    3. 处理电源管理(PM)操作(暂停/恢复)
  • UART驱动程序API:处理实际的UART功能:读取,写入等.

让我们drivers/tty/serial/omap-serial.c用于驱动程序参考和arch/arm/boot/dts/omap5.dtsi设备参考.比方说,我们在设备树中描述了下一个设备:

uart1: serial@4806a000 {
    compatible = "ti,omap4-uart";
    reg = <0x4806a000 0x100>;
    interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
    ti,hwmods = "uart1";
    clock-frequency = <48000000>;
};
Run Code Online (Sandbox Code Playgroud)

它将omap-serial.c通过"ti,omap4-uart"字符串与平台驱动程序匹配(您可以在驱动程序代码中找到它).然后,使用该平台驱动程序,我们可以从上面的设备树节点读取属性,并将它们用于某些平台内容(设置时钟,处理UART中断等).

但是为了将我们的设备作为标准TTY设备公开,我们需要使用UART框架(所有这些uart_*功能).因此有两种不同的API:平台驱动程序和UART驱动程序.