zoukankan      html  css  js  c++  java
  • ARM-Linux S5PV210 UART驱动(6)----platform device的添加

    开发板是飞凌OK210

    arch/arm/mach-s5pv210/mach-smdkc110.c

    首先是UART的寄存器默认配置信息:

    /* Following are default values for UCON, ULCON and UFCON UART registers */
    #define S5PV210_UCON_DEFAULT    (S3C2410_UCON_TXILEVEL |    
                     S3C2410_UCON_RXILEVEL |    
                     S3C2410_UCON_TXIRQMODE |    
                     S3C2410_UCON_RXIRQMODE |    
                     S3C2410_UCON_RXFIFO_TOI |    
                     S3C2443_UCON_RXERR_IRQEN)
    
    #define S5PV210_ULCON_DEFAULT    S3C2410_LCON_CS8
    
    #define S5PV210_UFCON_DEFAULT    (S3C2410_UFCON_FIFOMODE |    
                     S5PV210_UFCON_TXTRIG4 |    
                     S5PV210_UFCON_RXTRIG4)
    
    static struct s3c2410_uartcfg smdkc110_uartcfgs[] __initdata = {
        {
            .hwport        = 0,
            .flags        = 0,
            .ucon        = S5PV210_UCON_DEFAULT,
            .ulcon        = S5PV210_ULCON_DEFAULT,
            .ufcon        = S5PV210_UFCON_DEFAULT,
        },
        {
            .hwport        = 1,
            .flags        = 0,
            .ucon        = S5PV210_UCON_DEFAULT,
            .ulcon        = S5PV210_ULCON_DEFAULT,
            .ufcon        = S5PV210_UFCON_DEFAULT,
        },
    #ifndef CONFIG_FIQ_DEBUGGER
        {
            .hwport        = 2,
            .flags        = 0,
            .ucon        = S5PV210_UCON_DEFAULT,
            .ulcon        = S5PV210_ULCON_DEFAULT,
            .ufcon        = S5PV210_UFCON_DEFAULT,
        },
    #endif
        {
            .hwport        = 3,
            .flags        = 0,
            .ucon        = S5PV210_UCON_DEFAULT,
            .ulcon        = S5PV210_ULCON_DEFAULT,
            .ufcon        = S5PV210_UFCON_DEFAULT,
        },
    };

     下面是添加platform device的具体过程:

    1.

    /*调用MACHINE_START宏
    MACHINE_START和MACHINE_END框起了一个machine_desc结构体的声明并根据MACHINE_START宏的参数初始化其.nr和.name成员
    并将该结构体标记编译到.arch.info.init段
    在MACHINE_START和MACHINE_END宏之间可以初始化machine_desc结构体的剩余成员
    */
    #ifdef CONFIG_MACH_SMDKC110
    MACHINE_START(SMDKC110, "SMDKC110")
    #elif CONFIG_MACH_SMDKV210
    MACHINE_START(SMDKV210, "SMDKV210")
    #endif
        /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
        .phys_io    = S3C_PA_UART & 0xfff00000,
        .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S5P_PA_SDRAM + 0x100,
        .init_irq    = s5pv210_init_irq,//板级中断初始化函数
        .map_io        = smdkc110_map_io,//板级io初始化函数
        .init_machine    = smdkc110_machine_init,//板级初始化函数
        .timer        = &s5p_systimer,
    MACHINE_END

     2.

    static void __init smdkc110_map_io(void)
    {
        s5p_init_io(NULL, 0, S5P_VA_CHIPID);
        s3c24xx_init_clocks(24000000);
        s5pv210_gpiolib_init();
        s3c24xx_init_uarts(smdkc110_uartcfgs, ARRAY_SIZE(smdkc110_uartcfgs));
        s5p_reserve_bootmem(smdkc110_media_devs, ARRAY_SIZE(smdkc110_media_devs));
    #ifdef CONFIG_MTD_ONENAND
        s5pc110_device_onenand.name = "s5pc110-onenand";
    #endif
    #ifdef CONFIG_MTD_NAND
        s3c_device_nand.name = "s5pv210-nand";
    #endif
        s5p_device_rtc.name = "smdkc110-rtc";
    
    }

     3.

    /* table of supported CPUs */
    static
    struct cpu_table cpu_ids[] __initdata = { { .idcode = 0x43110000, .idmask = 0xfffff000, .map_io = s5pv210_map_io, .init_clocks = s5pv210_init_clocks, .init_uarts = s5pv210_init_uarts, .init = s5pv210_init, .name = name_s5pv210, }, };

    arch/arm/plat-samsung/init.c

    void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
    {
        if (cpu == NULL)
            return;
    
        if (cpu->init_uarts == NULL) {
            printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init
    ");
        } else
            (cpu->init_uarts)(cfg, no);//这里最终会调用上面的s5pv210_init_uarts
    }

     4.

    #define s5pv210_init_uarts s5pv210_common_init_uarts
    /* uart registration process */
    void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
    {
        struct s3c2410_uartcfg *tcfg = cfg;
        u32 ucnt;
    
        for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
            if (!tcfg->clocks) {
                tcfg->clocks = s5pv210_serial_clocks;
                tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
            }
        }
    
        s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
    }

     5.

    arch/arm/plat-samsung/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;//将cfg挂到platdev->dev.platform_data上
        }
    
        nr_uarts = no;
    }
    static int __init s3c_arch_init(void)
    {
        int ret;
    
        // do the correct init for cpu
    
        if (cpu == NULL)
            panic("s3c_arch_init: NULL cpu
    ");
    
        ret = (cpu->init)();
        if (ret != 0)
            return ret;
    
        ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
        return ret;
    }
    
    arch_initcall(s3c_arch_init);
  • 相关阅读:
    创建一个新的进程os.fork
    进程的特征
    进程的状态
    多进程概念
    IO多路复用
    Objective-C 和 C++中指针的格式和.方法 和内存分配
    生活需要奋斗的目标
    iOS 关于UITableView的dequeueReusableCellWithIdentifier
    哈哈,发现了刚毕业时发布的求职帖子
    iOS 和Android中的基本日期处理
  • 原文地址:https://www.cnblogs.com/hello2mhb/p/3337555.html
Copyright © 2011-2022 走看看