分类: LINUX
2010-04-07 09:32:52
首先你需要为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等的事情了