ARM-Linux s3c2440 之UART分析(五)
2012-01-16 14:23
183 查看
====本文系本站原创,欢迎转载! 转载请注明出处:http://blog.csdn.net/yyplc====
从上面四篇介绍文章中,已经清楚了串口设备与串口驱动实现的各层次关系流程。是一种从上而下的关系,从第二篇的层次流程图中可以看出。之前说过串口设备是一种platform device,下面看看串口作为platform device的实现细节。
串口的硬件平台实现smdk2440_map_io()初始化入口:
s3c24xx_init_uarts()初始化串口, 主要完成platform device结构相关参数的赋值,如IO,中断,以及platform device私有数据赋值等。
串口platform_device结构:
要完成platform_device参数初始化,主要涉及到一下数据结构:
串口配置数据结构:
串口资源:
最后通过函数s3c24xx_init_uartdevs()完成 串口platform_device的初始化:
最终在platform_add_device()中完成注册
从上面四篇介绍文章中,已经清楚了串口设备与串口驱动实现的各层次关系流程。是一种从上而下的关系,从第二篇的层次流程图中可以看出。之前说过串口设备是一种platform device,下面看看串口作为platform device的实现细节。
串口的硬件平台实现smdk2440_map_io()初始化入口:
static void __init smdk2440_map_io(void) { s3c24xx_init_io(smdk2440_iodesc,ARRAY_SIZE(smdk2440_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2440_uartcfgs,ARRAY_SIZE(smdk2440_uartcfgs)); //串口初始化 }
s3c24xx_init_uarts()初始化串口, 主要完成platform device结构相关参数的赋值,如IO,中断,以及platform device私有数据赋值等。
串口platform_device结构:
static struct platform_device s3c24xx_uart_device0= { .id = 0, // ID号 }; static struct platform_devices3c24xx_uart_device1 = { .id = 1, }; static struct platform_devices3c24xx_uart_device2 = { .id = 2, };
要完成platform_device参数初始化,主要涉及到一下数据结构:
串口配置数据结构:
static struct s3c2410_uartcfgtq2440_uartcfgs[] __initdata = { [0]= { .hwport =0, .flags = 0, .ucon = 0x3c5, // rx,tx采用中断方式 .ulcon = 0x03, //数据长度设置为8-bits .ufcon = 0x51, //开启FIFO,并设置rx,tx触发字节数 }, [1]= { .hwport =1, .flags = 0, .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, }, [2]= { .hwport =2, .flags = 0, .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, } };
串口资源:
static struct resources3c2410_uart0_resource[] = { [0]= { .start= S3C2410_PA_UART0, .end = S3C2410_PA_UART0 + 0x3fff, .flags= IORESOURCE_MEM, }, [1]= { .start= IRQ_S3CUART_RX0, .end = IRQ_S3CUART_ERR0, .flags= IORESOURCE_IRQ, } }; struct s3c24xx_uart_resourcess3c2410_uart_resources[] __initdata = { [0]= { .resources = s3c2410_uart0_resource, .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource), }, [1]= { .resources = s3c2410_uart1_resource, .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource), }, [2]= { .resources = s3c2410_uart2_resource, .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource), }, [3]= { .resources = s3c2410_uart3_resource, .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource), }, };
最后通过函数s3c24xx_init_uartdevs()完成 串口platform_device的初始化:
void __init s3c24xx_init_uartdevs(char*name, struct s3c24xx_uart_resources *res, struct s3c2410_uartcfg *cfg, int no) {//name = s3c2440-uart, res =s3c2410_uart_resources[], cfg = tq2440_uartcfgs, no = 3 structplatform_device *platdev; structs3c2410_uartcfg *cfgptr = uart_cfgs; structs3c24xx_uart_resources *resp; intuart; memcpy(cfgptr,cfg, sizeof(struct s3c2410_uartcfg) * no); for(uart = 0; uart < no; uart++, cfg++, cfgptr++) { platdev= s3c24xx_uart_src[cfgptr->hwport]; //platdev = s3c24xx_uart_device0 resp= res + cfgptr->hwport; //resp =s3c2410_uart_resources[] + tq2440_uartcfgs.hwport s3c24xx_uart_devs[uart]= platdev; // platdev->name= name; platdev->resource= resp->resources; platdev->num_resources= resp->nr_resources; platdev->dev.platform_data= cfgptr;//plat_form_data = cfgptr = tq2440_uartcfgs } nr_uarts= no; }
最终在platform_add_device()中完成注册
platform_add_devices(s3c24xx_uart_devs,nr_uarts); int platform_add_devices(structplatform_device **devs, int num) { inti, ret = 0; for(i = 0; i < num; i++) { ret= platform_device_register(devs[i]); if(ret) { while(--i >= 0) platform_device_unregister(devs[i]); break; } } return ret; }
相关文章推荐
- ARM-Linux s3c2440 之UART分析(四)
- ARM-Linux s3c2440 之UART分析(一)
- ARM-Linux s3c2440 之UART分析(三)
- ARM-Linux s3c2440 之UART分析(二)
- ARM Linux S3C2440 之UART分析
- ARM-linux s3c2440 之时钟分析
- ARM-Linux s3c2440 之中断分析(三)
- ARM-Linux s3c2440 之中断分析(一)
- ARM-Linux s3c2440 之I2C分析
- ARM-Linux s3c2440 之SPI分析
- ARM-Linux s3c2440 之中断分析(二)
- Linux Support for ARM LPAE 分析
- 交叉编译场景分析(arm-linux)(三)--编译zlib
- 详解 ARM Linux启动过程分析
- ARM-Linux驱动-触摸屏驱动分析
- 交叉编译场景分析(arm-linux)
- 2009-2010网络最热的 嵌入式学习|ARM|Linux|wince|ucos|经典资料与实例分析 完整版
- Arm&nbsp;linux启动分析(4)
- arm-linux-androideabi-gcc 4.8的选项分析
- ARM-Linux代码的执行效率分析