s3c6410的UART设备驱动(4)
2015-01-13 17:29
309 查看
上两篇说了在模块初始化是调用uart_register_driver和uart_add_one_port注册UART驱动并添加端口,在模块卸载时调用uart_unregister_driver和uart_remove_one_port以注销UART驱动并移除端口,主要讲述的是这些函数的具体代码,但没说这些函数在何处被调用,这一篇讲述这些函数的调用。
1、在Samsung.c (linux2.6.28\drivers\serial)文件中,有如下代码:
module_init(s3c24xx_serial_modinit);
module_exit(s3c24xx_serial_modexit);
看到这两个,应该知道了此模块调用的函数,和卸载时的函数。列出其源码:
/* module initialisation code */
static int __init s3c24xx_serial_modinit(void)
{
int ret;
ret = uart_register_driver(&s3c24xx_uart_drv);在上一篇中讲的有,可以去查看。
其中它的参数为
static struct uart_driver s3c24xx_uart_drv = {
.owner
= THIS_MODULE,
.dev_name
= "s3c2410_serial",
.nr = CONFIG_SERIAL_SAMSUNG_UARTS,
.cons = S3C24XX_SERIAL_CONSOLE,
.driver_name
= S3C24XX_SERIAL_NAME,
.major
= S3C24XX_SERIAL_MAJOR,
.minor
= S3C24XX_SERIAL_MINOR,
};
if (ret < 0) {
printk(KERN_ERR "failed to register UART driver\n");
return -1;
}
return 0;
}
static void __exit s3c24xx_serial_modexit(void)
{
uart_unregister_driver(&s3c24xx_uart_drv);
}
/**
*
uart_unregister_driver - remove a driver from the uart core layer
*
@drv: low level driver structure
*/
void uart_unregister_driver(struct uart_driver *drv)
{
struct tty_driver *p = drv->tty_driver;
tty_unregister_driver(p);
put_tty_driver(p);//减小引用数,为0是释放p
kfree(drv->state);
drv->tty_driver = NULL;
}
2、板级相关在S3c6400.c (linux2.6.28\drivers\serial)文件中有如下:
module_init(s3c6400_serial_init);
module_exit(s3c6400_serial_exit);
和上面一样列出其源码:
static int __init s3c6400_serial_init(void)
{
return s3c24xx_serial_init(&s3c6400_serial_drv, &s3c6400_uart_inf);
}
调用s3c24xx_serial_init函数,传入的参数为
static struct platform_driver s3c6400_serial_drv = {
.probe
= s3c6400_serial_probe,
.remove
= s3c24xx_serial_remove,
.driver
= {
.name = "s3c6400-uart",
.owner
= THIS_MODULE,
},
};
static struct s3c24xx_uart_info s3c6400_uart_inf = {
.name
= "Samsung S3C6400 UART",
.type
= PORT_S3C6400,
.fifosize
= 64,
.rx_fifomask
= S3C2440_UFSTAT_RXMASK,
.rx_fifoshift
= S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull
= S3C2440_UFSTAT_RXFULL,
.tx_fifofull
= S3C2440_UFSTAT_TXFULL,
.tx_fifomask
= S3C2440_UFSTAT_TXMASK,
.tx_fifoshift
= S3C2440_UFSTAT_TXSHIFT,
.get_clksrc
= s3c6400_serial_getsource,
.set_clksrc
= s3c6400_serial_setsource,
.reset_port
= s3c6400_serial_resetport,
};这个结构体的原型在Samsung.h (linux2.6.28\drivers\serial)文件中,如下所示:
struct s3c24xx_uart_info {
char *name;
unsigned int
type;
unsigned int
fifosize;
unsigned long
rx_fifomask;
unsigned long
rx_fifoshift;
unsigned long
rx_fifofull;
unsigned long
tx_fifomask;
unsigned long
tx_fifoshift;
unsigned long
tx_fifofull;
/* clock source control */
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
/* uart controls */
int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
};
ints3c24xx_serial_init(struct platform_driver *drv,struct s3c24xx_uart_info *info)
{
dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
#ifdef CONFIG_PM
drv->suspend = s3c24xx_serial_suspend;
drv->resume = s3c24xx_serial_resume;
#endif
return platform_driver_register(drv);
}
platform_driver_register这个函数才是重点,因为uart是作为一种平台设备存在的。大家都知道,会调用其
static struct platform_driver s3c6400_serial_drv = {
.probe= s3c6400_serial_probe
结构体中的probe函数,源码如下:
static int s3c6400_serial_probe(struct platform_device *dev)
{
dbg("s3c6400_serial_probe: dev=%p\n", dev);
return s3c24xx_serial_probe(dev, &s3c6400_uart_inf);//该函数里调用uart_add_one_port
}
因为这个函数实在太长,所以放在下一篇中在说。
1、在Samsung.c (linux2.6.28\drivers\serial)文件中,有如下代码:
module_init(s3c24xx_serial_modinit);
module_exit(s3c24xx_serial_modexit);
看到这两个,应该知道了此模块调用的函数,和卸载时的函数。列出其源码:
/* module initialisation code */
static int __init s3c24xx_serial_modinit(void)
{
int ret;
ret = uart_register_driver(&s3c24xx_uart_drv);在上一篇中讲的有,可以去查看。
其中它的参数为
static struct uart_driver s3c24xx_uart_drv = {
.owner
= THIS_MODULE,
.dev_name
= "s3c2410_serial",
.nr = CONFIG_SERIAL_SAMSUNG_UARTS,
.cons = S3C24XX_SERIAL_CONSOLE,
.driver_name
= S3C24XX_SERIAL_NAME,
.major
= S3C24XX_SERIAL_MAJOR,
.minor
= S3C24XX_SERIAL_MINOR,
};
if (ret < 0) {
printk(KERN_ERR "failed to register UART driver\n");
return -1;
}
return 0;
}
static void __exit s3c24xx_serial_modexit(void)
{
uart_unregister_driver(&s3c24xx_uart_drv);
}
/**
*
uart_unregister_driver - remove a driver from the uart core layer
*
@drv: low level driver structure
*/
void uart_unregister_driver(struct uart_driver *drv)
{
struct tty_driver *p = drv->tty_driver;
tty_unregister_driver(p);
put_tty_driver(p);//减小引用数,为0是释放p
kfree(drv->state);
drv->tty_driver = NULL;
}
2、板级相关在S3c6400.c (linux2.6.28\drivers\serial)文件中有如下:
module_init(s3c6400_serial_init);
module_exit(s3c6400_serial_exit);
和上面一样列出其源码:
static int __init s3c6400_serial_init(void)
{
return s3c24xx_serial_init(&s3c6400_serial_drv, &s3c6400_uart_inf);
}
调用s3c24xx_serial_init函数,传入的参数为
static struct platform_driver s3c6400_serial_drv = {
.probe
= s3c6400_serial_probe,
.remove
= s3c24xx_serial_remove,
.driver
= {
.name = "s3c6400-uart",
.owner
= THIS_MODULE,
},
};
static struct s3c24xx_uart_info s3c6400_uart_inf = {
.name
= "Samsung S3C6400 UART",
.type
= PORT_S3C6400,
.fifosize
= 64,
.rx_fifomask
= S3C2440_UFSTAT_RXMASK,
.rx_fifoshift
= S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull
= S3C2440_UFSTAT_RXFULL,
.tx_fifofull
= S3C2440_UFSTAT_TXFULL,
.tx_fifomask
= S3C2440_UFSTAT_TXMASK,
.tx_fifoshift
= S3C2440_UFSTAT_TXSHIFT,
.get_clksrc
= s3c6400_serial_getsource,
.set_clksrc
= s3c6400_serial_setsource,
.reset_port
= s3c6400_serial_resetport,
};这个结构体的原型在Samsung.h (linux2.6.28\drivers\serial)文件中,如下所示:
struct s3c24xx_uart_info {
char *name;
unsigned int
type;
unsigned int
fifosize;
unsigned long
rx_fifomask;
unsigned long
rx_fifoshift;
unsigned long
rx_fifofull;
unsigned long
tx_fifomask;
unsigned long
tx_fifoshift;
unsigned long
tx_fifofull;
/* clock source control */
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
/* uart controls */
int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
};
ints3c24xx_serial_init(struct platform_driver *drv,struct s3c24xx_uart_info *info)
{
dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
#ifdef CONFIG_PM
drv->suspend = s3c24xx_serial_suspend;
drv->resume = s3c24xx_serial_resume;
#endif
return platform_driver_register(drv);
}
platform_driver_register这个函数才是重点,因为uart是作为一种平台设备存在的。大家都知道,会调用其
static struct platform_driver s3c6400_serial_drv = {
.probe= s3c6400_serial_probe
结构体中的probe函数,源码如下:
static int s3c6400_serial_probe(struct platform_device *dev)
{
dbg("s3c6400_serial_probe: dev=%p\n", dev);
return s3c24xx_serial_probe(dev, &s3c6400_uart_inf);//该函数里调用uart_add_one_port
}
因为这个函数实在太长,所以放在下一篇中在说。
相关文章推荐
- s3c6410的UART设备驱动(3)
- s3c6410的UART设备驱动(1)
- s3c6410的UART设备驱动(2)
- s3c6410的UART设备驱动(4)
- s3c6410的UART设备驱动(5)
- s3c6410的UART设备驱动(5)
- s3c6410的UART设备驱动(5)
- s3c6410的UART设备驱动(1)
- s3c6410的UART设备驱动(5)
- s3c6410的UART设备驱动(3)
- s3c6410的UART设备驱动(2)
- linux设备模型之uart驱动架构分析
- linux设备模型之uart驱动架构分析
- S3C6410裸机UART驱动(将printf重定义到串口)
- S3C6410 按键驱动(五) --- 驱动源代码(我采用自动分配设备号的方法,注册设备)
- Linux终端设备驱动 ----UART的驱动
- 设备驱动之七----s3c6410 GPIO驱动总结
- linux设备模型之uart驱动架构分析
- Linux设备驱动之UART驱动结构
- S3C6410使用---25 I2C设备驱动分析