ARM-Linux驱动--DMA驱动分析(一)
时间:11-20
来源:互联网
点击:
硬件平台:FL2440 (s3c2440)
内核版本:2.6.35
主机平台:Ubuntu 11.04
内核版本:2.6.39
1、DMA的功能和工作原理这里就不多说了,可以查看s3c2440的手册
2、在正式分析DMA驱动之前,我们先来看一下DMA的注册和初始化过程
系统设备:(翻译自源码注释)
系统设备和系统模型有点不同,它不需要动态绑定驱动,不能被探测(probe),不归结为任何的系统总线,所以要区分对待。对待系统设备我们仍然要有设备驱动的观念,因为我们需要对设备进行基本的操作。
定义系统设备,在./arch/arm/mach-s3c2440/s3c244x.c中
- /*定义系统设备类*/
- structsysdev_classs3c2440_sysclass={
- .name="s3c2440-core",
- .suspend=s3c244x_suspend,
- .resume=s3c244x_resume
- };
- staticint__inits3c2440_core_init(void)
- {
- returnsysdev_class_register(&s3c2440_sysclass);
- }
下面就是系统设备类的注册函数,在./drivers/base/sys.c中
- intsysdev_class_register(structsysdev_class*cls)
- {
- intretval;
- pr_debug("Registeringsysdevclass%s\n",cls->name);
- INIT_LIST_HEAD(&cls->drivers);
- memset(&cls->kset.kobj,0x00,sizeof(structkobject));
- cls->kset.kobj.parent=&system_kset->kobj;
- cls->kset.kobj.ktype=&ktype_sysdev_class;
- cls->kset.kobj.kset=system_kset;
- retval=kobject_set_name(&cls->kset.kobj,"%s",cls->name);
- if(retval)
- returnretval;
- retval=kset_register(&cls->kset);
- if(!retval&&cls->attrs)
- retval=sysfs_create_files(&cls->kset.kobj,
- (conststructattribute**)cls->attrs);
- returnretval;
- }
- /*定义DMA系统设备驱动*/
- staticstructsysdev_drivers3c2440_dma_driver={
- .add=s3c2440_dma_add,/*添加add函数*/
- };
- staticint__inits3c2440_dma_add(structsys_device*sysdev)
- {
- s3c2410_dma_init();
- s3c24xx_dma_order_set(&s3c2440_dma_order);
- returns3c24xx_dma_init_map(&s3c2440_dma_sel);
- }
- staticint__inits3c2440_dma_init(void)
- {
- returnsysdev_driver_register(&s3c2440_sysclass,&s3c2440_dma_driver);
- }
- /**
- *sysdev_driver_register-Registerauxillarydriver
- *@cls:Deviceclassdriverbelongsto.
- *@drv:Driver.
- *
- *@drvisinsertedinto@cls->driverstobe
- *calledoneachoperationondevicesofthatclass.Therefcount
- *of@clsisincremented.
- */
- intsysdev_driver_register(structsysdev_class*cls,structsysdev_driver*drv)
- {
- interr=0;
- if(!cls){
- WARN(1,KERN_WARNING"sysdev:invalidclasspassedto"
- "sysdev_driver_register!\n");
- return-EINVAL;
- }
- /*Checkwhetherthisdriverhasalreadybeenaddedtoaclass.*/
- if(drv->entry.next&&!list_empty(&drv->entry))
- WARN(1,KERN_WARNING"sysdev:class%s:driver(%p)hasalready"
- "beenregisteredtoaclass,somethingiswrong,but"
- "willforgeon!\n",cls->name,drv);
- mutex_lock(&sysdev_drivers_lock);
- if(cls&&kset_get(&cls->kset)){
- list_add_tail(&drv->entry,&cls->drivers);/*将设备驱动添加到系统设备类的链表中*/
- /*Ifdevicesofthisclassalreadyexist,tellthedriver*/
- if(drv->add){
- structsys_device*dev;
- list_for_each_entry(dev,&cls->kset.list,kobj.entry)
- drv->add(dev);
- }
- }else{
- err=-EINVAL;
- WARN(1,KERN_ERR"%s:invaliddeviceclass\n",__func__);
- }
- mutex_unlock(&sysdev_drivers_lock);
- returnerr;
- }
- staticstructsys_devices3c2440_sysdev={
- .cls=&s3c2440_sysclass,/*定义系统设备的所属系统设备类,用于系统设备注册到指定设备类*/
- };
- /*S3C2440初始化*/
- int__inits3c2440_init(void)
- {
- printk("S3C2440:Initialisingarchitecture\n");
- s3c24xx_gpiocfg_default.set_pull=s3c_gpio_setpull_1up;
- s3c24xx_gpiocfg_default.get_pull=s3c_gpio_getpull_1up;
- /*changeirqforwatchdog*/
- s3c_device_wdt.resource[1].start=IRQ_S3C2440_WDT;
- s3c_device_wdt.resource[1].end=IRQ_S3C2440_WDT;
- /*registeroursystemdeviceforeverythingelse*/
- returnsysdev_register(&s3c2440_sysdev);/*注册s3c2440的系统设备*/
- }
- /**
- *sysdev_register-addasystemdevicetothetree
- *@sysdev:deviceinquestion
- *
- */
- /*系统设备的注册*/
- intsysdev_register(structsys_device
ARM-Linux驱动DMA驱动分 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)