分类: LINUX
2009-05-29 13:13:11
1.arch/arm/mach-xxx/devices.c文件设置了所有设备的资源(物理地址,中断号等)。把每个device和resource保存在devices数组中;然后platform_add_devices把传入的devices中的每个设备调用platform_device_register注册到系统中。
arch_initcall宏将调用xxx_devices_init函数,注册各个设备。
arch_initcall at6600_devices_init platform_add_devices lm_add_devices platform_device_register lm_device_register device_initialize.分配初始化device结构体的各个成员 platform_device_add insert_resource device_add
platform_device_register:注册传入的struct platform_device.
(1)调用device_initialize初始化platform_device中的dev(struct device)成员。
(2)调用platform_device_add函数。
platform_device_add:加入一个platform_device进入设备树。
(1) 调用insert_resource加入该设备的每个资源。
(2) 调用device_add加入platform_device的成员dev。
device_add(driver/base/core.c):加入一个device进入device树。
2内核设备驱动编写
(1) 定义struct platform_driver变量。
static struct platform_driver xxx_driver = {
.probe = xxx_probe,
.remove = xxx_remove,
.suspend = xxx_suspend,
.resume = xxx_resume,
.shutdown = xxx_shutdown,
.driver = {
.name = "xxx",
.owner = THIS_MODULE,
},
};
probe函数在驱动邦定到设备时被调用。当设备引用计数是0时,调用remove函数。Suspend和resume用于电源管理功能。driver.name用于匹配设备。
(2) 模块初始化函数
调用platform_driver_register(&xxx_driver),注册xxx_driver驱动。
Platform_driver_register(xxx_driver) Driver_register(&xxx_driver->driver) Bus_add_driver(drv) driver_attach(drv) bus_for_each_dev(drv->bus,NULL,drv,__driver_attach).该函数在总线bus上根据name匹配驱动和设备,驱动匹配到设备后调用驱动的probe函数 __driver_attach(struct device * dev,void * data) driver_probe_device(struct device_driver * drv, struct device * dev)。该函数调用总线的match函数匹配驱动和设备的name,然后调用驱动的probe函数。 really_probe;drv->probe(dev)。
(3) Probe函数
取得资源(物理地址,中断号)信息,申请资源(申请中断等);初始化驱动私有数据成员。
(4) Remove函数
释放资源(中断等)。
(5) 模块卸载函数
调用platform_driver_unregister.
platform_driver_unregister(struct platform_driver *drv) driver_unregister(struct device_driver * drv) bus_remove_driver(struct device_driver * drv) driver_detach(struct device_driver * drv) __device_release_driver(struct device * dev)。该函数将调用驱动的remove函数