您的位置:首页 > 其它

s3c6410的UART设备驱动(4)

2012-05-17 21:22 351 查看
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)的链接地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: