S5PV210平台之UART 的 platform_device

来源:互联网 发布:excel怎样复制一列数据 编辑:程序博客网 时间:2024/05/17 06:35

UART 的platform_device  

1、/kernel/arch/arm/mach-s5pv210/mach-smdkv210.c
static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
.ufcon = S5PV210_UFCON_DEFAULT,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
.ufcon = S5PV210_UFCON_DEFAULT,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
.ufcon = S5PV210_UFCON_DEFAULT,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
.ufcon = S5PV210_UFCON_DEFAULT,
},
};


下面是具体过程:

MACHINE_START(SMDKV210, "SMDKV210")
.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= smdkv210_map_io,
.init_machine= smdkv210_machine_init,
.timer= &s5p_systimer,
MACHINE_END

static void __init smdkv210_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
s5pv210_reserve_bootmem();
}

2、
static struct cpu_table cpu_ids[] __initdata = {
{
.idcode= 0x43110000,
.idmask= 0xfffff000,
.map_io= s5pv210_map_io,
.init_clocks= s5pv210_init_clocks,
.init_uartss5pv210_init_uarts,
.init= s5pv210_init,
.name= name_s5pv210,
},
};
void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)/* 3 */
{
if (cpu == NULL)
return;
if (cpu->init_uarts == NULL) {
printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
} else
(cpu->init_uarts)(cfg, no);//这里最终会调用上面的s5pv210_init_uarts
}

#define s5pv210_init_uarts s5pv210_common_init_uarts

void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
......
//关于s5p_uart_resources可参考:UART的资源(struct resource)
s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
}


3、这里很重要
static int nr_uarts __initdata = 0;//全局变量-------表示uart数
static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];//全局变量   

regs-serial.h中
/* s3c24xx_uart_devs
 * this is exported from the core as we cannot use driver_register(), or platform_add_device() before the console_initcall()
*/
extern struct platform_device *s3c24xx_uart_devs[4];



/* s3c24xx_init_uartdevs
 *
 * copy the specified platform data and configuration into our central
 * set of devices, before the data is thrown away after the init process.
 *
 * This also fills in the array passed to the serial driver for the
 * early initialisation of the console.
*/

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]; //关于s3c24xx_uart_src可参考:UART的资源(struct resource)

resp = res + cfgptr->hwport;

s3c24xx_uart_devs[uart] = platdev;//保存到platform_device

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

platdev->dev.platform_data = cfgptr;
}

nr_uarts = no;
}

static int __init s3c_arch_init(void)
{
.....
ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);//注册platform_device
}
arch_initcall(s3c_arch_init);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#define S5PV210_UART_DEFAULT_INFO(fifo_size) \
.name = "Samsung S5PV210 UART0", \
.type = PORT_S3C6400, \
.fifosize= fifo_size,\
.has_divslot= 1,\
.rx_fifomask= S5PV210_UFSTAT_RXMASK,\
.rx_fifoshift= S5PV210_UFSTAT_RXSHIFT,\
.rx_fifofull= S5PV210_UFSTAT_RXFULL,\
.tx_fifofull= S5PV210_UFSTAT_TXFULL,\
.tx_fifomask= S5PV210_UFSTAT_TXMASK,\
.tx_fifoshift= S5PV210_UFSTAT_TXSHIFT,\
.get_clksrc= s5pv210_serial_getsource,\
.set_clksrc= s5pv210_serial_setsource,\
.reset_port= s5pv210_serial_resetport

static struct s3c24xx_uart_info s5p_port_fifo256 = {
S5PV210_UART_DEFAULT_INFO(256),
};

static struct s3c24xx_uart_info s5p_port_fifo64 = {
S5PV210_UART_DEFAULT_INFO(64),
};

static struct s3c24xx_uart_info s5p_port_fifo16 = {
S5PV210_UART_DEFAULT_INFO(16),
};

static struct s3c24xx_uart_info *s5p_uart_inf[] = {
[0] = &s5p_port_fifo256,
[1] = &s5p_port_fifo64,
[2] = &s5p_port_fifo16,
[3] = &s5p_port_fifo16,
};

/* device management */
static int s5p_serial_probe(struct platform_device *pdev)
{
return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]);
}

static struct platform_drivers5p_serial_drv = {
.probe = s5p_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
.driver = {
.name = "s5pv210-uart",
.owner = THIS_MODULE,
},
};

static int __init s5pv210_serial_console_init(void)
{
return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf);
}
console_initcall(s5pv210_serial_console_init);

static int __init s5p_serial_init(void)
{
return platform_driver_register(&s5p_serial_drv);//注册platform_driver
}
module_init(s5p_serial_init);




原文出处:http://fangjian0518.blog.163.com/blog/static/55919656201152535253959/

原创粉丝点击