Wednesday, 6 July 2016

UART Subsystem

UART driver Layers in serial subsystem:
 TTY CORE
       |
 TTY Driver
        |
UART/Low level
        |
Hardware
Uart Drivers revolve around three data structures.(include/linux/serial_core.h)
Struct uart_driver
Struct uart_port
Struct uart_ops
Struct console serial_omap_console
APIs
Uart_driver_register(struct uart_driver*)
Uart_add_one_port(uart_driver *,uart_port*);
 
UART driver
Drivers/tty/serial/omap_serial.c
Serial_omap_init()
{
   uart_register_driver(uart_driver *);
    platform_driver_register(serial_omap_driver);
}
static struct platform_driver serial_omap_driver = {
        .probe          = serial_omap_probe,
        .remove         = serial_omap_remove,
        .driver         = {
                .name   = DRIVER_NAME(omap-uart),
                .pm = &omap_serial_dev_pm_ops,
        },
};
uart_register_driver(uart_driver *);
static struct uart_driver serial_omap_reg = {
        .owner          = THIS_MODULE,
        .driver_name    = "OMAP-SERIAL",
        .dev_name       = OMAP_SERIAL_NAME,
        .nr             = OMAP_MAX_HSUART_PORTS,
        .cons           = OMAP_CONSOLE,
};
During initialization, the OMAP-SERIAL driver first registers itself with the serial core using uart_register_driver()
. When this is done, you will find a new line starting with OMAP-SERIAL in /proc/tty/drivers
The driver_name variable should be set to something short, descriptive, and unique among all tty drivers in the kernel. This is because it shows up in the /proc/tty/drivers file to describe the driver to the user and in the sysfs tty class directory of tty drivers currently loaded
The name field is used to define a name for the individual tty  nodes assigned to this tty driver in the /dev tree. This string is used to create a tty device by appending the number of the tty device being used at the end of the string.It is also used to create the device name in the sysfs /sys/class/tty/ directory
Platform driver
platform_driver_register(serial_omap_driver);
After this step, you will see two new directories appearing in sysfs, each
corresponding to a OMAP-SERIAL port: /sys/devices/platform/omap_uart.0/
      /sys/devices/platform/omap_uart.1/ ……. /sys/devices/platform/omap_uart.3
Probe
serial_omap_probe(struct platform_device *pdev)
   {
                 serial_omap_add_console_port(up);
      ret = uart_add_one_port(&serial_omap_reg, &up->port);
   }
Uart_add_one_port
int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
{
            uart_configure_port(drv, state, uport);
        /*Register the port whether it's detected or not.  This allows
         * setserial to be used to alter this ports parameters.*/
        tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev);
}
uart_configure_port(struct uart_driver *drv, struct uart_state *state,struct uart_port *port)
{
            port->ops->config_port(port, flags);
/* If this driver supports console, and it hasn't been  successfully registered yet, try to re-register it. It may be that the port was not available.*/
                if (port->cons && !(port->cons->flags & CON_ENABLED))
                        register_console(port->cons);
}

No comments:

Post a Comment