在drivers/tty/serail/sw_uart.c中
module_init(sw_uart_init);
注: 很有意思的一点,这儿的 platform_device 与 platform_driver都是在init函数中调用的,
而不像原来一样在/arch/arm/mach-s3c64xx/dev-uart.c(6410为例)中定义platform_device,在drivers/tty/serail中定义platform_driver
进入probe函数
module_init(sw_uart_init);
- static int __init sw_uart_init(void)
- {
- struct sw_uart_pdata *pdata;
-
- ret = sw_uart_get_devinfo(); //获取串口的硬件信息: gpio口与irq号
-
- ret = uart_register_driver(&sw_uart_driver); //向tty层注册串口驱动
-
- for (i=0; i<SW_UART_NR; i++) {
- pdata = &sw_uport_pdata[i];
- if (pdata->used)
- platform_device_register(&sw_uport_device[i]); //注册平台设备
- }
-
- return platform_driver_register(&sw_uport_platform_driver); //注册平台驱动
- }
注: 很有意思的一点,这儿的 platform_device 与 platform_driver都是在init函数中调用的,
而不像原来一样在/arch/arm/mach-s3c64xx/dev-uart.c(6410为例)中定义platform_device,在drivers/tty/serail中定义platform_driver
- static struct platform_driver sw_uport_platform_driver = {
- .probe = sw_uart_probe,
- .remove = __devexit_p(sw_uart_remove),
- .driver.name = "sw_serial",
- .driver.pm = SERIAL_SW_PM_OPS,
- .driver.owner = THIS_MODULE,
- };
- static int __devinit sw_uart_probe(struct platform_device *pdev)
- {
- u32 id = pdev->id;
- struct uart_port *port;
- struct sw_uart_port *sw_uport;
- struct clk *apbclk;
- int ret = -1;
-
- if (unlikely(pdev->id < 0 || pdev->id >= SW_UART_NR))
- return -ENXIO;
- port = &sw_uart_port[id].port;
- port->dev = &pdev->dev;
- sw_uport = UART_TO_SPORT(port);
- sw_uport->id = id;
- sw_uport->ier = 0;
- sw_uport->lcr = 0;
- sw_uport->mcr = 0;
- sw_uport->fcr = 0;
- sw_uport->dll = 0;
- sw_uport->dlh = 0;
-
- /* request system resource and init them */
- ret = sw_uart_request_resource(sw_uport);
- if (unlikely(ret)) {
- SERIAL_MSG("uart%d error to get resource\n", id);
- return -ENXIO;
- }
-
- apbclk = clk_get(&pdev->dev, CLK_SYS_APB1);
- if (IS_ERR(apbclk)) {
- SERIAL_MSG("uart%d error to get source clock\n", id);
- return -ENXIO;
- }
- ret = clk_set_parent(sw_uport->mclk, apbclk);
- if (ret) {
- SERIAL_MSG("uart%d set mclk parent error\n", id);
- clk_put(apbclk);
- return -ENXIO;
- }
- port->uartclk = clk_get_rate(apbclk);
- clk_put(apbclk);
-
- port->type = PORT_SW;
- port->flags = UPF_BOOT_AUTOCONF;
- port->mapbase = sw_uport->pdata->base;
- port->irq = sw_uport->pdata->irq;
- platform_set_drvdata(pdev, port);
- #ifdef CONFIG_PROC_FS
- sw_uart_procfs_attach(sw_uport);
- #endif
- SERIAL_DBG("add uart%d port, port_type %d, uartclk %d\n",
- id, port->type, port->uartclk);
- return uart_add_one_port(&sw_uart_driver, port);
- }