Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between uart_register_driver and platform_driver_register?

I am studying UART Driver in kernel code and want to know, who first comes into picture, device_register() or driver_register() call?

For difference between them follow this.

and in UART probing, we call

uart_register_driver(struct uart_driver *drv)

and after successfully registration,

uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)

Please explain this in details.

like image 503
enfinet Avatar asked Mar 14 '23 09:03

enfinet


1 Answers

That's actually two questions, but I'll try to address both of them.

who first comes into picture, device_register() or driver_register() call?

As it stated in Documentation/driver-model/binding.txt, it doesn't matter in which particular order you call device_register() and driver_register().

  • device_register() adds device to device list and iterates over driver list to find the match
  • driver_register() adds driver to driver list and iterates over device list to find the match

Once match is found, matched device and driver are binded and corresponding probe function is called in driver code.

If you are still curious which one is called first (because it doesn't matter) -- usually it's device_register(), because devices are usually being registered on initcalls from core_initcall to arch_initcall, and drivers are usually being registered on device_initcall, which executed later.

See also:

[1] From where platform device gets it name

[2] Who calls the probe() of driver

[3] module_init() vs. core_initcall() vs. early_initcall()

Difference between uart_register_driver and platform_driver_register?

As you noticed there are 2 drivers (platform driver and UART driver) for one device. But don't let this confuse you: those are just two driver APIs used in one (in fact) driver. The explanation is simple: UART driver API just lacks some functionality we need, and this functionality is implemented in platform driver API. Here is responsibility of each API in regular tty driver:

  • platform driver API is used for 3 things:
    1. Matching device (described in device tree file) with driver; this way probe function will be executed for us by platform driver framework
    2. Obtaining device information (reading from device tree)
    3. Handling Power Management (PM) operations (suspend/resume)
  • UART driver API: handling actual UART functionality: read, write, etc.

Let's use drivers/tty/serial/omap-serial.c for driver reference and arch/arm/boot/dts/omap5.dtsi for device reference. Let's say, for example, we have next device described in device tree:

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

It will be matched with platform driver in omap-serial.c by "ti,omap4-uart" string (you can find it in driver code). Then, using that platform driver, we can read properties from device tree node above, and use them for some platform stuff (setting up clocks, handling UART interrupt, etc.).

But in order to expose our device as standard TTY device we need to use UART framework (all those uart_* functions). Hence 2 different APIs: platform driver and UART driver.

like image 101
Sam Protsenko Avatar answered Apr 07 '23 00:04

Sam Protsenko