ARM-Linux s3c2440 之UART分析(三)
UART特定的驅(qū)動(dòng)程序結(jié)構(gòu)定義:struct uart_driver s3c24xx_uart_drv;
本文引用地址:http://www.ex-cimer.com/article/201611/318133.htmUART端口結(jié)構(gòu)定義: struct uart_port s3c24xx_serial_ops;
UART相關(guān)操作函數(shù)結(jié)構(gòu)定義: struct uart_ops s3c24xx_serial_ops;
實(shí)現(xiàn)了這三個(gè)數(shù)據(jù)結(jié)構(gòu)體,基本完成了驅(qū)動(dòng)操作函數(shù)的實(shí)現(xiàn),緊接著需要對(duì)串口設(shè)備及設(shè)備驅(qū)動(dòng)進(jìn)行初始化,首先是模塊初始化module_init(s3c24xx_serial_modinit):
- staticint__inits3c24xx_serial_modinit(void)
- {
- intret;
- ret=uart_register_driver(&s3c24xx_uart_drv);//注冊(cè)u(píng)art驅(qū)動(dòng),在serial_core.c中實(shí)現(xiàn)
- if(ret<0){
- printk(KERN_ERR"failedtoregisterUARTdrivern");
- return-1;
- }
- return0;
- }
uart_register_driver在串口核心及TTY層間進(jìn)行相關(guān)注冊(cè):
- intuart_register_driver(structuart_driver*drv)
- {
structtty_driver*normal=NULL; … - drv->tty_driver=normal;
- normal->owner=drv->owner;
- normal->driver_name=drv->driver_name;
- normal->name=drv->dev_name;
- normal->major=drv->major;
- normal->minor_start=drv->minor;
- normal->type=TTY_DRIVER_TYPE_SERIAL;
- normal->subtype=SERIAL_TYPE_NORMAL;
- normal->init_termios=tty_std_termios;
- normal->init_termios.c_cflag=B9600|CS8|CREAD|HUPCL|CLOCAL;
- normal->init_termios.c_ispeed=normal->init_termios.c_ospeed=9600;
- normal->flags=TTY_DRIVER_REAL_RAW|TTY_DRIVER_DYNAMIC_DEV;
- normal->driver_state=drv;
- tty_set_operations(normal,&uart_ops);
- ….
- retval=tty_register_driver(normal);//tty驅(qū)動(dòng)注冊(cè)
- out:
- if(retval<0){
- put_tty_driver(normal);
- kfree(drv->state);
- }
- returnretval;
- }
接著進(jìn)行總線驅(qū)動(dòng)platform_driver_register:
- ints3c24xx_serial_init(structplatform_driver*drv,
- structs3c24xx_uart_info*info)
- {
- #ifdefCONFIG_PM
- drv->suspend=s3c24xx_serial_suspend;
- drv->resume=s3c24xx_serial_resume;
- #endif
- returnplatform_driver_register(drv);//
- }
其中s3c24xx_serial_init為__init段,模塊加載時(shí)初始化:
- staticint__inits3c2440_serial_init(void)
- {
- returns3c24xx_serial_init(&s3c2440_serial_drv,&s3c2440_uart_inf);//
- }
platfrom_driver_register()中調(diào)用driver_register()
- intplatform_driver_register(structplatform_driver*drv)
- {
- drv->driver.bus=&platform_bus_type;//
- if(drv->probe)
- drv->driver.probe=platform_drv_probe;
- if(drv->remove)
- drv->driver.remove=platform_drv_remove;
- if(drv->shutdown)
- drv->driver.shutdown=platform_drv_shutdown;
- if(drv->suspend)
- drv->driver.suspend=platform_drv_suspend;
- if(drv->resume)
- drv->driver.resume=platform_drv_resume;
- returndriver_register(&drv->driver);//
- }
因?yàn)榇谠O(shè)備在系統(tǒng)是一種platform_device所以是一種總線驅(qū)動(dòng)類型,總線設(shè)備驅(qū)動(dòng)注冊(cè)platform_driver_register()之后,串口設(shè)備即可和相應(yīng)的驅(qū)動(dòng)關(guān)聯(lián)起來(lái)了,這樣就完成了串口設(shè)備與串口驅(qū)動(dòng)的注冊(cè)過(guò)程。
下一篇講進(jìn)一步結(jié)合源碼分析。
評(píng)論