S5PV210平台之UART 的 platform_device

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_uarts s5pv210_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_driver s5p_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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值