drivers\tty\serial\imx.c
#define SERIAL_IMX_MAJOR 207
#define MINOR_START 16
#define DEV_NAME "ttymxc"
/*
* This determines how often we check the modem status signals
* for any change. They generally aren't connected to an IRQ
* so we have to poll them. We also check immediately before
* filling the TX fifo incase CTS has been dropped.
*/
#define MCTRL_TIMEOUT (250*HZ/1000)
#define DRIVER_NAME "IMX-uart"
#define UART_NR 8
static struct imx_port *imx_ports[UART_NR];
static struct uart_driver imx_reg = {
.owner = THIS_MODULE,
.driver_name = DRIVER_NAME,
.dev_name = DEV_NAME,
.major = SERIAL_IMX_MAJOR,
.minor = MINOR_START,
.nr = ARRAY_SIZE(imx_ports),
.cons = IMX_CONSOLE,
};
static struct platform_driver serial_imx_driver = {
.probe = serial_imx_probe,
.remove = serial_imx_remove,
.suspend = serial_imx_suspend,
.resume = serial_imx_resume,
.id_table = imx_uart_devtype,
.driver = {
.name = "imx-uart",
.of_match_table = imx_uart_dt_ids,
},
};
static struct uart_ops imx_pops = {
.tx_empty = imx_tx_empty,
.set_mctrl = imx_set_mctrl,//设置串口modem控制模式
.get_mctrl = imx_get_mctrl,//获取串口modem控制模式
.stop_tx = imx_stop_tx,//停止发送
.start_tx = imx_start_tx,//开始发送
.stop_rx = imx_stop_rx,//停止接收
.enable_ms = imx_enable_ms,//使能modem状态信息
.break_ctl = imx_break_ctl,
.startup = imx_startup,//打开串口
.shutdown = imx_shutdown,//关闭串口
.flush_buffer = imx_flush_buffer,
.set_termios = imx_set_termios,//设置串口参数
.type = imx_type,//io访问类型
.config_port = imx_config_port,//配置端口
.verify_port = imx_verify_port,//校验端口
#if defined(CONFIG_CONSOLE_POLL)
.poll_init = imx_poll_init,
.poll_get_char = imx_poll_get_char,
.poll_put_char = imx_poll_put_char,
#endif
};
imx_serial_init
uart_register_driver(&imx_reg);-------------------------------> uart_register_driver
platform_driver_register(&serial_imx_driver);
///
struct uart_state {
struct tty_port port;
enum uart_pm_state pm_state;
struct circ_buf xmit;
struct uart_port *uart_port;
};
///
struct ktermios tty_std_termios = { /* for the benefit of tty drivers */
.c_iflag = ICRNL | IXON,
.c_oflag = OPOST | ONLCR,
.c_cflag = B38400 | CS8 | CREAD | HUPCL,
.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
ECHOCTL | ECHOKE | IEXTEN,
.c_cc = INIT_C_CC,
.c_ispeed = 38400,
.c_ospeed = 38400
};
// drivers\tty\serial\serial_core.c
int uart_register_driver(struct uart_driver *drv)
struct tty_driver *normal;
drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);// 分配8个struct uart_state
normal = alloc_tty_driver(drv->nr);// drv->nr = 8
struct tty_driver *ret = tty_alloc_driver(lines, 0);// struct tty_driver,分配lines = 8
__tty_alloc_driver(lines, THIS_MODULE, flags)// lines = 8 flags=0
struct tty_driver *driver;
driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
if (!(flags & TTY_DRIVER_DEVPTS_MEM)) {
driver->ttys = kcalloc(lines, sizeof(*driver->ttys), GFP_KERNEL);// 分配struct tty_struct **ttys;
driver->termios = kcalloc(lines, sizeof(*driver->termios), GFP_KERNEL);// 分配struct ktermios **termios;
}
if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
driver-