分类: LINUX
2011-05-13 10:57:01
首先你需要为SOC的各个功能部分定义他的一些资源.例如可用于访问的寄存器地址.中断号,DMA什 么的。然后将这些资源(resource) 作为 platform 的dev .通过platform_add_devices函数将你定义的paltform_device变量注册到系统的dev里面.。或者你可以象我这样将你需 要的驱动添加:
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_bl,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_sdi,
&s3c_device_adc,
&s3c_device_nand,
&s3c_device_usbgadget,
&s3c_device_ts,
&s3c_device_buttons,
&s3c_device_rtc,
&s3c_device_spi0,
&s3c_device_timer1,//add by cefanty for battery charging
};
这样你的硬件的信息和资源就会注册到系统中.
说了半天,这回该说这有什么用了。
你编写的驱动或者移植别人的驱动,一般在驱动里有这样的代码,例如:
static struct platform_driver s3c2410sdi_driver =
{
.probe = s3c2410sdi_probe,
.remove = s3c2410sdi_remove,
.suspend= s3c2410mci_suspend,
.resume= s3c2410mci_resume,
.driver={
.name= "s3c2410-sdi",
.bus = &platform_bus_type,
.owner= THIS_MODULE,
},
};
看到 .name= "s3c2410-sdi",这条关键的语句没有??,它和我在上面注册的&s3c_device_sdi,里的device的名称是一致的.我这里展开我的s3c_device_sdi,的内容
:
/* SDI */
static struct resource s3c_sdi_resource[] = {
[0] = {
.start = S3C2410_PA_SDI,
.end = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_SDI,
.end = IRQ_SDI,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = 3,
.end = 3,
.flags = IORESOURCE_DMA,
}
};
struct platform_device s3c_device_sdi = {
.name = "s3c2410-sdi",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_sdi_resource),
.resource = s3c_sdi_resource,
};
在驱动程序里的init代码大致如下:
static int __init s3c2410sdi_init(void)
{
return platform_driver_register(&s3c2410sdi_driver);
}
用platform_driver_register 向系统注册这个驱动程序.而这个函数会在s3c2410sdi_driver的信息里提取name为搜索内容,搜索系统注册的device中有没有这个 platform_device。 如果有注册,那么接着会执行platform_driver 里probe函数.在这里显然是s3c2410sdi_probe函数 在probe函数里,用的最多和刚才platform_device有关的语句是platform_get_resource,这条语句用于获取 platform_device里的resource资料.例如映射的IO地址,中断等.剩下等得就是ioremap,和 request_irq等的事情了
====