首先是系統在初始化是, platform bus的注冊:
struct device platform_bus = {
.bus_id = "platform",
};
struct bus_type platform_bus_type = {
.name = "platform",
.match = platform_match,
.suspend = platform_suspend,
.resume = platform_resume,
};
int __init platform_bus_init(void)
{
device_register(&platform_bus);
return bus_register(&platform_bus_type);
}
設備的注冊
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
};
//以上這些設備的結構在devs.c中定義, 如下是一個例子:
/* NAND Controller */
static struct resource s3c_nand_resource[] = {
[0] = {
.start = S3C2410_PA_NAND,
.end = S3C2410_PA_NAND + S3C24XX_SZ_NAND,
.flags = IORESOURCE_MEM,
}
};
struct platform_device s3c_device_nand = {
.name = "s3c2410-nand",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_nand_resource),
.resource = s3c_nand_resource,
};
所以我們就可以通過上面的方法加入我們想要的設備.
==========================================
//上面的設備列表在加入到板級系統中
static struct s3c24xx_board smdk2410_board __initdata = {
.devices = smdk2410_devices,
.devices_count = ARRAY_SIZE(smdk2410_devices)
};
static void __init smdk2410_map_io(void)
{
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
s3c24xx_set_board(&smdk2410_board); //注意這一步
}
static void __init smdk2410_init_irq(void)
{
s3c24xx_init_irq();
}
==========================================
//這是通過一個宏來建立一個結構
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
/* Maintainer: Jonas Dietsche */
.phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = smdk2410_map_io,
.init_irq = smdk2410_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
//宏定義為如下:
/*
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
#define MACHINE_START(_type,_name) \
const struct machine_desc __mach_desc_##_type \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
由此得到一個名為__mach_desc_SMDK2410_type, 類型為struct machine_desc的結構體.
=====================
再看看s3c24xx_set_board(&smdk2410_board)(in cpu.c)
/* board information */
static struct s3c24xx_board *board;
void s3c24xx_set_board(struct s3c24xx_board *b)
{
int i;
board = b; //設置這個全局變量
if (b->clocks_count != 0) {
struct clk **ptr = b->clocks;;
for (i = b->clocks_count; i > 0; i--, ptr++)
s3c24xx_register_clock(*ptr);
}
}
而下面這個初始化函數就會用到這個變量了
static int __init s3c_arch_init(void)
{
int ret;
// do the correct init for cpu
if (cpu == NULL)
panic("s3c_arch_init: NULL cpu\n");
ret = (cpu->init)();
if (ret != 0)
return ret;
if (board != NULL) {
struct platform_device **ptr = board->devices;
int i;
//遍歷platform中的每一個設備
for (i = 0; i < board->devices_count; i++, ptr++) {
//注冊進platform總線中去, 這樣在加載驅動的時候就可以
//找到這些platform device了.
ret = platform_device_register(*ptr);
if (ret) {
printk(KERN_ERR "s3c24xx: failed to add board device %s (%d)
@%p\n", (*ptr)->name, ret, *ptr);
}
}
/* mask any error, we may not need all these board
* devices */
ret = 0;
}
return ret;
}
arch_initcall(s3c_arch_init);
===================================
/**
* platform_device_register - add a platform-level device
* @pdev: platform device we're adding
*
*/
int platform_device_register(struct platform_device * pdev)
{
int i, ret = 0;
if (!pdev)
return -EINVAL;
//關聯父設備
if (!pdev->dev.parent)
pdev->dev.parent = &platform_bus;
pdev->dev.bus = &platform_bus_type;
//id == -1 的處理, 只是名字的不同
if (pdev->id != -1)
snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%u", pdev->name, pdev->id);