s3c6410的UART设备驱动(4)

 s3c6410的UART设备驱动(1)的链接   

s3c6410的UART设备驱动(2)的链接


s3c6410的UART设备驱动(3)的链接


       上两篇说了在模块初始化是调用uart_register_driver和uart_add_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);
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);
}

因为这个函数实在太长,所以放在下一篇中在说。


s3c6410的UART设备驱动(5)的链接地址




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值