Cubietruck---11. Linux3.3_serail串口驱动分析

在drivers/tty/serail/sw_uart.c中
module_init(sw_uart_init);
  1. static int __init sw_uart_init(void)
  2. {
  3.     struct sw_uart_pdata *pdata;

  4.     ret = sw_uart_get_devinfo();       //获取串口的硬件信息: gpio口与irq号
  5.     
  6.     ret = uart_register_driver(&sw_uart_driver);    //向tty层注册串口驱动

  7.     for (i=0; i<SW_UART_NR; i++) {
  8.         pdata = &sw_uport_pdata[i];
  9.         if (pdata->used)
  10.             platform_device_register(&sw_uport_device[i]);    //注册平台设备
  11.     }

  12.     return platform_driver_register(&sw_uport_platform_driver);  //注册平台驱动
  13. }

注: 很有意思的一点,这儿的 platform_device 与 platform_driver都是在init函数中调用的,
而不像原来一样在/arch/arm/mach-s3c64xx/dev-uart.c(6410为例)中定义platform_device,在drivers/tty/serail中定义platform_driver


  1. static struct platform_driver sw_uport_platform_driver = {
  2.     .probe = sw_uart_probe,
  3.     .remove = __devexit_p(sw_uart_remove),
  4.     .driver.name = "sw_serial",
  5.     .driver.pm = SERIAL_SW_PM_OPS,
  6.     .driver.owner = THIS_MODULE,
  7. };
进入probe函数
  1. static int __devinit sw_uart_probe(struct platform_device *pdev)
  2. {
  3.     u32 id = pdev->id;
  4.     struct uart_port *port;
  5.     struct sw_uart_port *sw_uport;
  6.     struct clk *apbclk;
  7.     int ret = -1;

  8.     if (unlikely(pdev->id < 0 || pdev->id >= SW_UART_NR))
  9.         return -ENXIO;
  10.     port = &sw_uart_port[id].port;
  11.     port->dev = &pdev->dev;
  12.     sw_uport = UART_TO_SPORT(port);
  13.     sw_uport->id = id;
  14.     sw_uport->ier = 0;
  15.     sw_uport->lcr = 0;
  16.     sw_uport->mcr = 0;
  17.     sw_uport->fcr = 0;
  18.     sw_uport->dll = 0;
  19.     sw_uport->dlh = 0;

  20.     /* request system resource and init them */
  21.     ret = sw_uart_request_resource(sw_uport);
  22.     if (unlikely(ret)) {
  23.         SERIAL_MSG("uart%d error to get resource\n", id);
  24.         return -ENXIO;
  25.     }

  26.     apbclk = clk_get(&pdev->dev, CLK_SYS_APB1);
  27.     if (IS_ERR(apbclk)) {
  28.         SERIAL_MSG("uart%d error to get source clock\n", id);
  29.         return -ENXIO;
  30.     }
  31.     ret = clk_set_parent(sw_uport->mclk, apbclk);
  32.     if (ret) {
  33.         SERIAL_MSG("uart%d set mclk parent error\n", id);
  34.         clk_put(apbclk);
  35.         return -ENXIO;
  36.     }
  37.     port->uartclk = clk_get_rate(apbclk);
  38.     clk_put(apbclk);

  39.     port->type = PORT_SW;
  40.     port->flags = UPF_BOOT_AUTOCONF;
  41.     port->mapbase = sw_uport->pdata->base;
  42.     port->irq = sw_uport->pdata->irq;
  43.     platform_set_drvdata(pdev, port);
  44. #ifdef CONFIG_PROC_FS
  45.     sw_uart_procfs_attach(sw_uport);
  46. #endif
  47.     SERIAL_DBG("add uart%d port, port_type %d, uartclk %d\n",
  48.             id, port->type, port->uartclk);
  49.     return uart_add_one_port(&sw_uart_driver, port);
  50. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值