serial

make menuconfig:

serial_第1张图片
1.Device Drivers  ---> Character devices  ---> Serial drivers  ---> <*> Samsung Soc Serial support
obj-$(CONFIG_SERIAL_CORE) += serial_core.o   是串口核心
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o    是串口具体实现

2.控制台终端
计算机显示器通常被称为控制台终端(console)。必须有一个(些)特殊文件与console相关联,比如虚拟终端tty1 tty2 串口ttySAC0 ttySAC1等。系统所发出的信息会发送到console对应的文件上。

如果不选此项,在启动kernel后就不输出了。
[cpp] view plain copy print ?
  1. Starting kernel ...  
  2.   
  3. Uncompressing Linux......................................................................................................................................  
  4. ................... done, booting the kernel.  
Starting kernel ... Uncompressing Linux...................................................................................................................................... ................... done, booting the kernel. uboot里设置的 console=ttySAC0 ,决定了使用ttySAC0作控制台终端。

在samsung.c中实现console。
[cpp] view plain copy print ?
  1. /* s3c24xx_serial_initconsole 
  2.  * 
  3.  * initialise the console from one of the uart drivers 
  4. */  
  5.   
  6. static struct console s3c24xx_serial_console = {  
  7.     .name       = S3C24XX_SERIAL_NAME,  
  8.     .device     = uart_console_device,  
  9.     .flags      = CON_PRINTBUFFER,  
  10.     .index      = -1,  
  11.     .write      = s3c24xx_serial_console_write,  
  12.     .setup      = s3c24xx_serial_console_setup  
  13. };  
  14.   
  15. int s3c24xx_serial_initconsole(struct platform_driver *drv,  
  16.                    struct s3c24xx_uart_info *info)  
  17.   
  18. {  
  19.     struct platform_device *dev = s3c24xx_uart_devs[0];  
  20.   
  21.     dbg("s3c24xx_serial_initconsole\n");  
  22.   
  23.     /* select driver based on the cpu */  
  24.   
  25.     if (dev == NULL) {  
  26.         printk(KERN_ERR "s3c24xx: no devices for console init\n");  
  27.         return 0;  
  28.     }  
  29.   
  30.     if (strcmp(dev->name, drv->driver.name) != 0)  
  31.         return 0;  
  32.   
  33.     s3c24xx_serial_console.data = &s3c24xx_uart_drv;  
  34.     s3c24xx_serial_init_ports(info);  
  35.   
  36.     register_console(&s3c24xx_serial_console);  
  37.     return 0;  
  38. }  
/* s3c24xx_serial_initconsole * * initialise the console from one of the uart drivers */ static struct console s3c24xx_serial_console = { .name = S3C24XX_SERIAL_NAME, .device = uart_console_device, .flags = CON_PRINTBUFFER, .index = -1, .write = s3c24xx_serial_console_write, .setup = s3c24xx_serial_console_setup }; int s3c24xx_serial_initconsole(struct platform_driver *drv, struct s3c24xx_uart_info *info) { struct platform_device *dev = s3c24xx_uart_devs[0]; dbg("s3c24xx_serial_initconsole\n"); /* select driver based on the cpu */ if (dev == NULL) { printk(KERN_ERR "s3c24xx: no devices for console init\n"); return 0; } if (strcmp(dev->name, drv->driver.name) != 0) return 0; s3c24xx_serial_console.data = &s3c24xx_uart_drv; s3c24xx_serial_init_ports(info); register_console(&s3c24xx_serial_console); return 0; }
3. <*> Samsung S3C2440/S3C2442 Serial port support
普通串口 /dev/ttySAC*
obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
[cpp] view plain copy print ?
  1. </pre><span style="font-family:SimSun;">1.串口的平台设备分散在mach-mini2440.c,arch/arm/plat-s3c/init.c等,在系统启动时注册。比如<span style="font-family:SimSun;">mach-mini2440.c</span></span><pre name="code" class="cpp">static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {  
  2.     [0] = {//串口0   
  3.         .hwport         = 0,  
  4.         .flags         = 0,  
  5.         .ucon         = 0x3c5,  
  6.         .ulcon         = 0x03,  
  7.         .ufcon         = 0x51,  
  8.     },  
  9.     [1] = {//串口1   
  10.         .hwport         = 1,  
  11.         .flags         = 0,  
  12.         .ucon         = 0x3c5,  
  13.         .ulcon         = 0x03,  
  14.         .ufcon         = 0x51,  
  15.     },  
  16.     [2] = {//串口2   
  17.         .hwport         = 2,  
  18.         .flags         = 0,  
  19.         .ucon         = 0x3c5,  
  20.         .ulcon         = 0x03,  
  21.         .ufcon         = 0x51,  
  22.     }  
  23. };  
</pre><span style="font-family:SimSun;">1.串口的平台设备分散在mach-mini2440.c,arch/arm/plat-s3c/init.c等,在系统启动时注册。比如<span style="font-family:SimSun;">mach-mini2440.c</span></span><pre name="code" class="cpp">static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = { [0] = {//串口0 .hwport = 0, .flags = 0, .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, }, [1] = {//串口1 .hwport = 1, .flags = 0, .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, }, [2] = {//串口2 .hwport = 2, .flags = 0, .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, } };比如 init.c
void __init s3c24xx_init_uartdevs(char *name,
                  struct s3c24xx_uart_resources *res,
                  struct s3c2410_uartcfg *cfg, int no)
{
    struct platform_device *platdev;
    struct s3c2410_uartcfg *cfgptr = uart_cfgs;
    struct s3c24xx_uart_resources *resp;
    int uart;

    memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);

    for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
        platdev = s3c24xx_uart_src[cfgptr->hwport];

        resp = res + cfgptr->hwport;

        s3c24xx_uart_devs[uart] = platdev;

        platdev->name = name;
        platdev->resource = resp->resources;
        platdev->num_resources = resp->nr_resources;

        platdev->dev.platform_data = cfgptr;
    }

    nr_uarts = no;
}


2.串口的平台驱动在
arch/arm/mach-s3c2440/s3c2440.c和samsung.c
初始化:
s3c2440.c初始化时注册了平台驱动
[cpp] view plain copy print ?
  1. static int __init s3c2440_serial_init(void)  
  2. {  
  3.     return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf);//见下面  
  4. }  
  5.   
  6. static void __exit s3c2440_serial_exit(void)  
  7. {  
  8.     platform_driver_unregister(&s3c2440_serial_driver);  
  9. }  
  10.   
  11. module_init(s3c2440_serial_init);  
  12. module_exit(s3c2440_serial_exit);  
static int __init s3c2440_serial_init(void) { return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf);//见下面 } static void __exit s3c2440_serial_exit(void) { platform_driver_unregister(&s3c2440_serial_driver); } module_init(s3c2440_serial_init); module_exit(s3c2440_serial_exit);
[cpp] view plain copy print ?
  1. //samsung.c   
  2. int s3c24xx_serial_init(struct platform_driver *drv,  
  3.             struct s3c24xx_uart_info *info)  
  4. {  
  5.     dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);  
  6.   
  7. #ifdef CONFIG_PM   
  8.     drv->suspend = s3c24xx_serial_suspend;  
  9.     drv->resume = s3c24xx_serial_resume;  
  10. #endif   
  11.   
  12.     return platform_driver_register(drv);  
  13. }  
//samsung.c int s3c24xx_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); }
samsung.c在初始化时就注册了串口驱动
[cpp] view plain copy print ?
  1. static int __init s3c24xx_serial_modinit(void)  
  2. {  
  3.     int ret;  
  4.   
  5.     ret = uart_register_driver(&s3c24xx_uart_drv);  
  6.     if (ret < 0) {  
  7.         printk(KERN_ERR "failed to register UART driver\n");  
  8.         return -1;  
  9.     }  
  10.   
  11.     return 0;  
  12. }  
  13.   
  14. static void __exit s3c24xx_serial_modexit(void)  
  15. {  
  16.     uart_unregister_driver(&s3c24xx_uart_drv);  
  17. }  
  18.   
  19. module_init(s3c24xx_serial_modinit);  
  20. module_exit(s3c24xx_serial_modexit);  
static int __init s3c24xx_serial_modinit(void) { int ret; ret = uart_register_driver(&s3c24xx_uart_drv); 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); } module_init(s3c24xx_serial_modinit); module_exit(s3c24xx_serial_modexit);

看一下平台驱动的probe,可知是在probe函数里面添加串口
s3c2440.c
[cpp] view plain copy print ?
  1. static struct s3c24xx_uart_info s3c2440_uart_inf = {  
  2.     .name       = "Samsung S3C2440 UART",  
  3.     .type       = PORT_S3C2440,  
  4.     .fifosize   = 64,  
  5.     .rx_fifomask    = S3C2440_UFSTAT_RXMASK,  
  6.     .rx_fifoshift   = S3C2440_UFSTAT_RXSHIFT,  
  7.     .rx_fifofull    = S3C2440_UFSTAT_RXFULL,  
  8.     .tx_fifofull    = S3C2440_UFSTAT_TXFULL,  
  9.     .tx_fifomask    = S3C2440_UFSTAT_TXMASK,  
  10.     .tx_fifoshift   = S3C2440_UFSTAT_TXSHIFT,  
  11.     .get_clksrc = s3c2440_serial_getsource,  
  12.     .set_clksrc = s3c2440_serial_setsource,  
  13.     .reset_port = s3c2440_serial_resetport,  
  14. };  
  15.   
  16. /* device management */  
  17.   
  18. static int s3c2440_serial_probe(struct platform_device *dev)  
  19. {  
  20.     dbg("s3c2440_serial_probe: dev=%p\n", dev);  
  21.     return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);//见下面  
  22. }  
static struct s3c24xx_uart_info s3c2440_uart_inf = { .name = "Samsung S3C2440 UART", .type = PORT_S3C2440, .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 = s3c2440_serial_getsource, .set_clksrc = s3c2440_serial_setsource, .reset_port = s3c2440_serial_resetport, }; /* device management */ static int s3c2440_serial_probe(struct platform_device *dev) { dbg("s3c2440_serial_probe: dev=%p\n", dev); return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);//见下面 }
[cpp] view plain copy print ?
  1. //samsung.c   
  2. static int probe_index;  
  3.   
  4. int s3c24xx_serial_probe(struct platform_device *dev,  
  5.              struct s3c24xx_uart_info *info)  
  6. {  
  7.     struct s3c24xx_uart_port *ourport;  
  8.     int ret;  
  9.   
  10.     dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);  
  11.   
  12.     ourport = &s3c24xx_serial_ports[probe_index];  
  13.     probe_index++;  
  14.   
  15.     dbg("%s: initialising port %p...\n", __func__, ourport);  
  16.   
  17.     ret = s3c24xx_serial_init_port(ourport, info, dev);  
  18.     if (ret < 0)  
  19.         goto probe_err;  
  20.   
  21.     dbg("%s: adding port\n", __func__);  
  22.     uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);  
  23.     platform_set_drvdata(dev, &ourport->port);  
  24.   
  25.     ret = device_create_file(&dev->dev, &dev_attr_clock_source);  
  26.     if (ret < 0)  
  27.         printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__);  
  28.   
  29.     ret = s3c24xx_serial_cpufreq_register(ourport);  
  30.     if (ret < 0)  
  31.         dev_err(&dev->dev, "failed to add cpufreq notifier\n");  
  32.   
  33.     return 0;  
  34.   
  35.  probe_err:  
  36.     return ret;  
  37. }  
//samsung.c static int probe_index; int s3c24xx_serial_probe(struct platform_device *dev, struct s3c24xx_uart_info *info) { struct s3c24xx_uart_port *ourport; int ret; dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index); ourport = &s3c24xx_serial_ports[probe_index]; probe_index++; dbg("%s: initialising port %p...\n", __func__, ourport); ret = s3c24xx_serial_init_port(ourport, info, dev); if (ret < 0) goto probe_err; dbg("%s: adding port\n", __func__); uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); platform_set_drvdata(dev, &ourport->port); ret = device_create_file(&dev->dev, &dev_attr_clock_source); if (ret < 0) printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__); ret = s3c24xx_serial_cpufreq_register(ourport); if (ret < 0) dev_err(&dev->dev, "failed to add cpufreq notifier\n"); return 0; probe_err: return ret; }
几个重要的结构体
[cpp] view plain copy print ?
  1. //uart_ops   
  2. static struct uart_ops s3c24xx_serial_ops = {  
  3.     .pm     = s3c24xx_serial_pm,  
  4.     .tx_empty   = s3c24xx_serial_tx_empty,  
  5.     .get_mctrl  = s3c24xx_serial_get_mctrl,  
  6.     .set_mctrl  = s3c24xx_serial_set_mctrl,  
  7.     .stop_tx    = s3c24xx_serial_stop_tx,  
  8.     .start_tx   = s3c24xx_serial_start_tx,  
  9.     .stop_rx    = s3c24xx_serial_stop_rx,  
  10.     .enable_ms  = s3c24xx_serial_enable_ms,  
  11.     .break_ctl  = s3c24xx_serial_break_ctl,  
  12.     .startup    = s3c24xx_serial_startup,  
  13.     .shutdown   = s3c24xx_serial_shutdown,  
  14.     .set_termios    = s3c24xx_serial_set_termios,  
  15.     .type       = s3c24xx_serial_type,  
  16.     .release_port   = s3c24xx_serial_release_port,  
  17.     .request_port   = s3c24xx_serial_request_port,  
  18.     .config_port    = s3c24xx_serial_config_port,  
  19.     .verify_port    = s3c24xx_serial_verify_port,  
  20. };  
  21.   
  22. //uart_driver   
  23. static struct uart_driver s3c24xx_uart_drv = {  
  24.     .owner      = THIS_MODULE,  
  25.     .dev_name   = "s3c2410_serial",  
  26.     .nr     = CONFIG_SERIAL_SAMSUNG_UARTS,  
  27.     .cons       = S3C24XX_SERIAL_CONSOLE,  
  28.     .driver_name    = S3C24XX_SERIAL_NAME,  
  29.     .major      = S3C24XX_SERIAL_MAJOR,  
  30.     .minor      = S3C24XX_SERIAL_MINOR,  
  31. };  
  32.   
  33. //s3c24xx_uart_port   
  34. static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {  
  35.     [0] = {  
  36.         .port = {  
  37.             .lock       = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),  
  38.             .iotype     = UPIO_MEM,  
  39.             .irq        = IRQ_S3CUART_RX0,  
  40.             .uartclk    = 0,  
  41.             .fifosize   = 16,  
  42.             .ops        = &s3c24xx_serial_ops,  
  43.             .flags      = UPF_BOOT_AUTOCONF,  
  44.             .line       = 0,  
  45.         }  
  46.     },  
  47.     [1] = {  
  48.         .port = {  
  49.             .lock       = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),  
  50.             .iotype     = UPIO_MEM,  
  51.             .irq        = IRQ_S3CUART_RX1,  
  52.             .uartclk    = 0,  
  53.             .fifosize   = 16,  
  54.             .ops        = &s3c24xx_serial_ops,  
  55.             .flags      = UPF_BOOT_AUTOCONF,  
  56.             .line       = 1,  
  57.         }  
  58.     },  
  59. #if CONFIG_SERIAL_SAMSUNG_UARTS > 2  
  60.   
  61.     [2] = {  
  62.         .port = {  
  63.             .lock       = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),  
  64.             .iotype     = UPIO_MEM,  
  65.             .irq        = IRQ_S3CUART_RX2,  
  66.             .uartclk    = 0,  
  67.             .fifosize   = 16,  
  68.             .ops        = &s3c24xx_serial_ops,  
  69.             .flags      = UPF_BOOT_AUTOCONF,  
  70.             .line       = 2,  
  71.         }  
  72.     },  
  73. #endif   
  74. #if CONFIG_SERIAL_SAMSUNG_UARTS > 3   
  75.     [3] = {  
  76.         .port = {  
  77.             .lock       = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock),  
  78.             .iotype     = UPIO_MEM,  
  79.             .irq        = IRQ_S3CUART_RX3,  
  80.             .uartclk    = 0,  
  81.             .fifosize   = 16,  
  82.             .ops        = &s3c24xx_serial_ops,  
  83.             .flags      = UPF_BOOT_AUTOCONF,  
  84.             .line       = 3,  
  85.         }  
  86.     }  
  87. #endif   
  88. };  
//uart_ops static struct uart_ops s3c24xx_serial_ops = { .pm = s3c24xx_serial_pm, .tx_empty = s3c24xx_serial_tx_empty, .get_mctrl = s3c24xx_serial_get_mctrl, .set_mctrl = s3c24xx_serial_set_mctrl, .stop_tx = s3c24xx_serial_stop_tx, .start_tx = s3c24xx_serial_start_tx, .stop_rx = s3c24xx_serial_stop_rx, .enable_ms = s3c24xx_serial_enable_ms, .break_ctl = s3c24xx_serial_break_ctl, .startup = s3c24xx_serial_startup, .shutdown = s3c24xx_serial_shutdown, .set_termios = s3c24xx_serial_set_termios, .type = s3c24xx_serial_type, .release_port = s3c24xx_serial_release_port, .request_port = s3c24xx_serial_request_port, .config_port = s3c24xx_serial_config_port, .verify_port = s3c24xx_serial_verify_port, }; //uart_driver 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, }; //s3c24xx_uart_port static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { [0] = { .port = { .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX0, .uartclk = 0, .fifosize = 16, .ops = &s3c24xx_serial_ops, .flags = UPF_BOOT_AUTOCONF, .line = 0, } }, [1] = { .port = { .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX1, .uartclk = 0, .fifosize = 16, .ops = &s3c24xx_serial_ops, .flags = UPF_BOOT_AUTOCONF, .line = 1, } }, #if CONFIG_SERIAL_SAMSUNG_UARTS > 2 [2] = { .port = { .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX2, .uartclk = 0, .fifosize = 16, .ops = &s3c24xx_serial_ops, .flags = UPF_BOOT_AUTOCONF, .line = 2, } }, #endif #if CONFIG_SERIAL_SAMSUNG_UARTS > 3 [3] = { .port = { .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock), .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX3, .uartclk = 0, .fifosize = 16, .ops = &s3c24xx_serial_ops, .flags = UPF_BOOT_AUTOCONF, .line = 3, } } #endif };
[cpp] view plain copy print ?
  1. //serial_core.h   
  2. struct uart_port {  
  3.     spinlock_t      lock;           /* port lock */  
  4.     unsigned long       iobase;         /* in/out[bwl] */  
  5.     unsigned char __iomem   *membase;       /* read/write[bwl] */  
  6.     unsigned int        (*serial_in)(struct uart_port *, int);  
  7.     void            (*serial_out)(struct uart_port *, intint);  
  8.     unsigned int        irq;            /* irq number */  
  9.     unsigned long       irqflags;       /* irq flags  */  
  10.     unsigned int        uartclk;        /* base uart clock */  
  11.     unsigned int        fifosize;       /* tx fifo size */  
  12.     unsigned char       x_char;         /* xon/xoff char */  
  13.     unsigned char       regshift;       /* reg offset shift */  
  14.     unsigned char       iotype;         /* io access style */  
  15.     unsigned char       unused1;  
  16.   
  17. #define UPIO_PORT       (0)  
  18. #define UPIO_HUB6       (1)   
  19. #define UPIO_MEM        (2)  
  20. #define UPIO_MEM32      (3)   
  21. #define UPIO_AU         (4)         /* Au1x00 type IO */  
  22. #define UPIO_TSI        (5)         /* Tsi108/109 type IO */  
  23. #define UPIO_DWAPB      (6)         /* DesignWare APB UART */  
  24. #define UPIO_RM9000     (7)         /* RM9000 type IO */  
  25.   
  26.     unsigned int        read_status_mask;   /* driver specific */  
  27.     unsigned int        ignore_status_mask; /* driver specific */  
  28.     struct uart_state   *state;         /* pointer to parent state */  
  29.     struct uart_icount  icount;         /* statistics */  
  30.   
  31.     struct console      *cons;          /* struct console, if any */  
  32. #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)  
  33.     unsigned long       sysrq;          /* sysrq timeout */  
  34. #endif   
  35.   
  36.     upf_t           flags;  
  37.   
  38. #define UPF_FOURPORT        ((__force upf_t) (1 << 1))  
  39. #define UPF_SAK         ((__force upf_t) (1 << 2))  
  40. #define UPF_SPD_MASK        ((__force upf_t) (0x1030))  
  41. #define UPF_SPD_HI      ((__force upf_t) (0x0010))  
  42. #define UPF_SPD_VHI     ((__force upf_t) (0x0020))  
  43. #define UPF_SPD_CUST        ((__force upf_t) (0x0030))  
  44. #define UPF_SPD_SHI     ((__force upf_t) (0x1000))  
  45. #define UPF_SPD_WARP        ((__force upf_t) (0x1010))  
  46. #define UPF_SKIP_TEST       ((__force upf_t) (1 << 6))  
  47. #define UPF_AUTO_IRQ        ((__force upf_t) (1 << 7))  
  48. #define UPF_HARDPPS_CD      ((__force upf_t) (1 << 11))  
  49. #define UPF_LOW_LATENCY     ((__force upf_t) (1 << 13))  
  50. #define UPF_BUGGY_UART      ((__force upf_t) (1 << 14))  
  51. #define UPF_NO_TXEN_TEST    ((__force upf_t) (1 << 15))  
  52. #define UPF_MAGIC_MULTIPLIER    ((__force upf_t) (1 << 16))  
  53. #define UPF_CONS_FLOW       ((__force upf_t) (1 << 23))  
  54. #define UPF_SHARE_IRQ       ((__force upf_t) (1 << 24))  
  55. /* The exact UART type is known and should not be probed.  */  
  56. #define UPF_FIXED_TYPE      ((__force upf_t) (1 << 27))  
  57. #define UPF_BOOT_AUTOCONF   ((__force upf_t) (1 << 28))  
  58. #define UPF_FIXED_PORT      ((__force upf_t) (1 << 29))  
  59. #define UPF_DEAD        ((__force upf_t) (1 << 30))  
  60. #define UPF_IOREMAP     ((__force upf_t) (1 << 31))  
  61.   
  62. #define UPF_CHANGE_MASK     ((__force upf_t) (0x17fff))  
  63. #define UPF_USR_MASK        ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))  
  64.   
  65.     unsigned int        mctrl;          /* current modem ctrl settings */  
  66.     unsigned int        timeout;        /* character-based timeout */  
  67.     unsigned int        type;           /* port type */  
  68.     const struct uart_ops   *ops;  
  69.     unsigned int        custom_divisor;  
  70.     unsigned int        line;           /* port index */  
  71.     resource_size_t     mapbase;        /* for ioremap */  
  72.     struct device       *dev;           /* parent device */  
  73.     unsigned char       hub6;           /* this should be in the 8250 driver */  
  74.     unsigned char       suspended;  
  75.     unsigned char       unused[2];  
  76.     void            *private_data;      /* generic platform data pointer */  
  77. };  
//serial_core.h struct uart_port { spinlock_t lock; /* port lock */ unsigned long iobase; /* in/out[bwl] */ unsigned char __iomem *membase; /* read/write[bwl] */ unsigned int (*serial_in)(struct uart_port *, int); void (*serial_out)(struct uart_port *, int, int); unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */ unsigned int fifosize; /* tx fifo size */ unsigned char x_char; /* xon/xoff char */ unsigned char regshift; /* reg offset shift */ unsigned char iotype; /* io access style */ unsigned char unused1; #define UPIO_PORT (0) #define UPIO_HUB6 (1) #define UPIO_MEM (2) #define UPIO_MEM32 (3) #define UPIO_AU (4) /* Au1x00 type IO */ #define UPIO_TSI (5) /* Tsi108/109 type IO */ #define UPIO_DWAPB (6) /* DesignWare APB UART */ #define UPIO_RM9000 (7) /* RM9000 type IO */ unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ struct uart_state *state; /* pointer to parent state */ struct uart_icount icount; /* statistics */ struct console *cons; /* struct console, if any */ #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ) unsigned long sysrq; /* sysrq timeout */ #endif upf_t flags; #define UPF_FOURPORT ((__force upf_t) (1 << 1)) #define UPF_SAK ((__force upf_t) (1 << 2)) #define UPF_SPD_MASK ((__force upf_t) (0x1030)) #define UPF_SPD_HI ((__force upf_t) (0x0010)) #define UPF_SPD_VHI ((__force upf_t) (0x0020)) #define UPF_SPD_CUST ((__force upf_t) (0x0030)) #define UPF_SPD_SHI ((__force upf_t) (0x1000)) #define UPF_SPD_WARP ((__force upf_t) (0x1010)) #define UPF_SKIP_TEST ((__force upf_t) (1 << 6)) #define UPF_AUTO_IRQ ((__force upf_t) (1 << 7)) #define UPF_HARDPPS_CD ((__force upf_t) (1 << 11)) #define UPF_LOW_LATENCY ((__force upf_t) (1 << 13)) #define UPF_BUGGY_UART ((__force upf_t) (1 << 14)) #define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) /* The exact UART type is known and should not be probed. */ #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) #define UPF_FIXED_PORT ((__force upf_t) (1 << 29)) #define UPF_DEAD ((__force upf_t) (1 << 30)) #define UPF_IOREMAP ((__force upf_t) (1 << 31)) #define UPF_CHANGE_MASK ((__force upf_t) (0x17fff)) #define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY)) unsigned int mctrl; /* current modem ctrl settings */ unsigned int timeout; /* character-based timeout */ unsigned int type; /* port type */ const struct uart_ops *ops; unsigned int custom_divisor; unsigned int line; /* port index */ resource_size_t mapbase; /* for ioremap */ struct device *dev; /* parent device */ unsigned char hub6; /* this should be in the 8250 driver */ unsigned char suspended; unsigned char unused[2]; void *private_data; /* generic platform data pointer */ };
在probe中(s3c24xx_serial_probe(),samsung.c)用uart_add_one_port()将uart_port加入uart_driver

每一uart_port对应一个uart_ops,主要工作就是实现这些函数指针。

你可能感兴趣的:(serial)