linux uart驱动——uart platfrom 注册(三)
一:注册platform device
注册一个platfrom device一般需要初始化两个内容,设备占用的资源resource和设备私有数据dev.platfrom_data。设备的resource占用的资源主要包含两个方面:IO内存和IRQ资源信息,有时也包含DMA。
resource结构:
1: struct resource {
2: resource_size_t start;//定义资源的起始地址
3: resource_size_t end;//定义资源的结束地址
4: const char *name;//定义资源的名称
5: unsigned long flags;//定义资源的类型,比如MEM,IO,IRQ,DMA类型
6: struct resource *parent, *sibling, *child;//资源链表指针
7: };笔者当前的君正board有三个串口:
1: #ifdef CONFIG_SERIAL_JZ47XX_UART02: /* UART ( uart controller) */
3: static struct resource jz_uart0_resources[] = {
4: [0] = { 5: .start = UART0_IOBASE, 6: .end = UART0_IOBASE + 0x1000 - 1, 7: .flags = IORESOURCE_MEM, 8: }, 9: [1] = { 10: .start = IRQ_UART0, 11: .end = IRQ_UART0, 12: .flags = IORESOURCE_IRQ, 13: }, 14: #ifdef CONFIG_SERIAL_JZ47XX_UART0_DMA 15: [2] = { 16: .start = JZDMA_REQ_UART0, 17: .flags = IORESOURCE_DMA, 18: },19: #endif
20: }; 21: 22: struct platform_device jz_uart0_device = {
23: .name = "jz-uart",
24: .id = 0, 25: .num_resources = ARRAY_SIZE(jz_uart0_resources), 26: .resource = jz_uart0_resources, 27: };28: #endif
29: #ifdef CONFIG_SERIAL_JZ47XX_UART130: static struct resource jz_uart1_resources[] = {
31: [0] = { 32: .start = UART1_IOBASE, 33: .end = UART1_IOBASE + 0x1000 - 1, 34: .flags = IORESOURCE_MEM, 35: }, 36: [1] = { 37: .start = IRQ_UART1, 38: .end = IRQ_UART1, 39: .flags = IORESOURCE_IRQ, 40: }, 41: #ifdef CONFIG_SERIAL_JZ47XX_UART1_DMA 42: [2] = { 43: .start = JZDMA_REQ_UART1, 44: .flags = IORESOURCE_DMA, 45: },46: #endif
47: };48: struct platform_device jz_uart1_device = {
49: .name = "jz-uart",
50: .id = 1, 51: .num_resources = ARRAY_SIZE(jz_uart1_resources), 52: .resource = jz_uart1_resources, 53: };54: #endif
55: #ifdef CONFIG_SERIAL_JZ47XX_UART256: static struct resource jz_uart2_resources[] = {
57: [0] = { 58: .start = UART2_IOBASE, 59: .end = UART2_IOBASE + 0x1000 - 1, 60: .flags = IORESOURCE_MEM, 61: }, 62: [1] = { 63: .start = IRQ_UART2, 64: .end = IRQ_UART2, 65: .flags = IORESOURCE_IRQ, 66: }, 67: #ifdef CONFIG_SERIAL_JZ47XX_UART2_DMA 68: [2] = { 69: .start = JZDMA_REQ_UART2, 70: .flags = IORESOURCE_DMA, 71: },72: #endif
73: }; 74: 75: struct platform_device jz_uart2_device = {
76: .name = "jz-uart",
77: .id = 2, 78: .num_resources = ARRAY_SIZE(jz_uart2_resources), 79: .resource = jz_uart2_resources, 80: };81: #endif
platform_device_register(&jz_uartXX_device);
注册成功后:(多个device)
ls /sys/bus/platform/devices/
jz-uart.0/ jz-uart.2/
二:注册platfrom driver
1: /* serial platfrom driver */
2: static struct platform_driver serial_jz47xx_driver = {
3: .probe = serial_jz47xx_probe, 4: .remove = serial_jz47xx_remove, 5: 6: .driver = {7: .name = "jz-uart",
8: .owner = THIS_MODULE, 9: #ifdef CONFIG_PM 10: .pm = &serial_jz47xx_pm_ops,11: #endif
12: }, 13: }; 14: 15: int __init serial_jz47xx_init(void)
16: {17: int ret;
18: /* 功能:uart_register_driver用于将串口驱动uart_driver注册到内核(串口核心层)中,
19: 通常在模块初始化函数调用该函数。
20: * 参数 drv:要注册的uart_driver
21: * 返回值: 成功,返回0;否则返回错误码
22: */
23: ret = uart_register_driver(&serial_jz47xx_reg);24: if (ret != 0)
25: return ret;
26: 27: /* 注册serial platfrom驱动 */
28: ret = platform_driver_register(&serial_jz47xx_driver); 29: if (ret != 0)
30: uart_unregister_driver(&serial_jz47xx_reg); 31: 32: return ret;
33: } 34: 35: void __exit serial_jz47xx_exit(void)
36: { 37: platform_driver_unregister(&serial_jz47xx_driver); 38: uart_unregister_driver(&serial_jz47xx_reg); 39: } 40: 41: 42: #ifdef CONFIG_EARLY_INIT_RUN43: rootfs_initcall(serial_jz47xx_init);/*先于module注册*/
44: 45: #else
46: module_init(serial_jz47xx_init); 47: 48: #endif
49: 50: module_exit(serial_jz47xx_exit); 51: 52: MODULE_LICENSE("GPL");
53: MODULE_ALIAS("platform:jz47xx-uart");
注册成功后:(一个driver对应多个device)
ls /sys/bus/platform/drivers/jz-uart/
bind jz-uart.0 jz-uart.2 uevent unbind

浙公网安备 33010602011771号