2410下rtc驱动分析

首先RTC设备是一种片上设备, platform_device来表示 该设备(platform_deviceRTC对象)在设备的初始化过程中就已经注册进了系统(可以参考2410soc上的设备的驱动流程(RTC, watchdog)), 因此我们在RTC驱动的初始化里把RTC驱动注册到系统后,系统会probe到这个RTC设备,最后调用我们RTC驱动的probe函数.

下面就重点分析2410RTC驱动.

首先是初始化函数和退出函数:

static void __init s3c2410_rtc_init(void)

{

    printk(banner);

 

     /*

* 这就把这个RTC驱动注册进了系统,同时系统会查找匹配的RTC设备,并调用

* s3c2410_rtcdrvprobe函数.

*/

    return platform_driver_register(&s3c2410_rtcdrv);

}

Static void __exit s3c2410_rtc_exit(void)

{

    /*卸载这个RTC驱动, 之后RTC设备就无法使用了*/

    platform_driver_unregister(&s3c2410_rtcdrv); 

}

static struct platform_driver s3c2410_rtcdrv = {

      .probe    = s3c2410_rtc_probe,

      .remove   = s3c2410_rtc_remove,

      .suspend  = s3c2410_rtc_suspend,

      .resume   = s3c2410_rtc_resume,

      .driver    = {

           .name = “s3c2410-rtc”,  //这个字符串必须和RTC设备的定义一样,系统才会匹配正确.

           .owner = THIS_MODULE,

       },

};

当系统把RTC设备注册到系统后,它就开始查找相应总线上的所有设备, 并与这个驱动比较, 如果系统找到匹配的RTC设备就会调用RTC驱动的s3c2410_rtc_probe函数, 注意RTC设备实在系统初始化时就注册进了系统.

static int s3c2410_rtc_probe(struct platform_device *pdev /*rtc设备*/)

{

    struct resource *res;

       int ret;

 

       pr_debug("%s: probe=%p/n", __FUNCTION__, pdev);

 

       /*

* 获取设备的tick中断资源, 通过查看platform_get_irq可知,实际上通过查找pdev的资源获得的, * pdev的资源是在构建platform_device对象的时候就指定好的, 可到Devs.c中查看

*/

       s3c2410_rtc_tickno = platform_get_irq(pdev, 1);

       if (s3c2410_rtc_tickno < 0) {

              dev_err(&pdev->dev, "no irq for rtc tick/n");

              return -ENOENT;

       }

 

       /*

* 获取设备的rtc中断资源, 通过查看platform_get_irq可知,实际上通过查找pdev的资源获得的, * pdev的资源是在构建platform_device对象的时候就指定好的, 可到Devs.c中查看

*/

       s3c2410_rtc_alarmno = platform_get_irq(pdev, 0);

       if (s3c2410_rtc_alarmno < 0) {

              dev_err(&pdev->dev, "no irq for alarm/n");

              return -ENOENT;

       }

 

       pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d/n",

               s3c2410_rtc_tickno, s3c2410_rtc_alarmno);

 

       /*

* 获取设备的memory资源, 通过查看platform_get_irq可知,实际上通过查找pdev的资源获得的, * pdev的资源是在构建platform_device对象的时候就指定好的, 可到Devs.c中查看

*/

       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

       if (res == NULL) {

              dev_err(&pdev->dev, "failed to get memory region resource/n");

              return -ENOENT;

       }

   

    /*

     * 查看指定的memory是否可以使用.

     */

       s3c2410_rtc_mem = request_mem_region(res->start, res->end-res->start+1,

                                 pdev->name);

 

       if (s3c2410_rtc_mem == NULL) {

              dev_err(&pdev->dev, "failed to reserve memory region/n");

              ret = -ENOENT;

              goto exit_err;

       }

   

    /*

* 重映射指定的内存区域,即把原来的物理地址映射到相应的虚拟地址, 这样以后就可以用这个* 虚拟地址直接访问原来的物理地址了, 这里是映射RTC的寄存器地址区间.

*/

       s3c2410_rtc_base = ioremap(res->start, res->end - res->start + 1);

       if (s3c2410_rtc_base == NULL) {

              dev_err(&pdev->dev, "failed ioremap()/n");

              ret = -EINVAL;

              goto exit_err;

       }

 

       s3c2410_rtc_mem = res;

       pr_debug("s3c2410_rtc_base=%p/n", s3c2410_rtc_base);

 

      pr_debug("s3c2410_rtc: RTCCON=%02x/n", readb(S3C2410_RTCCON));

 

       /*正确初始化RTC设备 */

       s3c2410_rtc_enable(pdev, 1);

 

      pr_debug("s3c2410_rtc: RTCCON=%02x/n", readb(S3C2410_RTCCON));

   

    /*设置好设备的频率*/

       s3c2410_rtc_setfreq(s3c2410_rtc_freq);

 

       /* 注册RTC设备的操作函数, 以后对该设备的访问将调用这些操作函数*/

       register_rtc(&s3c2410_rtcops);

       return 0;

 

 exit_err:

       dev_err(&pdev->dev, "error %d during initialisation/n", ret);

 

       return ret;

}

linuxdriver_code_tool |-- 03 | `-- 2.6内核升级工具 | |-- device-mapper-1.00.19-2.i386.rpm | |-- lvm2-2.00.25-1.01.i386.rpm | |-- mkinitrd-4.2.0.3.tar.tar | |-- module-init-tools-3.2.2.tar.bz2 | `-- modutils-2.4.5-1.src.rpm |-- 04 | |-- 内核模块参数范例 | | `-- book.c | |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem设备的驱动 | `-- globalmem_two.c |-- 07 | `-- 含并发控制的globalmem驱动 | `-- globalmem_lock.c |-- 08 | |-- globalfifo驱动 | | `-- globalfifo.c | `-- poll应用程序范例 | `-- pollmonitor.c |-- 09 | |-- 异步通知应用程序范例 | | `-- asyncmonitor.c | `-- 支持异步通知的globalfifo | `-- globalfifo_async.c |-- 10 | |-- S3C2410实时钟驱动 | | `-- s3c2410-rtc.c | `-- 秒设备驱动与应用程序 | |-- second.c | `-- second_test.c |-- 11 | |-- DMA范例 | | |-- 3c505.c | | |-- 3c505.h | | `-- dma.h | `-- 静态映射范例 | `-- mach-smdk2440.c |-- 12 | |-- NVRAM驱动 | | `-- generic_nvram.c | |-- 触摸屏驱动 | | |-- 作为input设备 | | | |-- s3c2410_ts.c | | | `-- s3c2410_ts.h | | `-- 作为普通字符设备 | | `-- s3c2410-ts.c | |-- 看门狗驱动 | | `-- s3c2410_wdt.c | `-- 平台设备 | `-- devs.c |-- 13 | |-- IDE驱动 | | |-- ide-disk.c | | `-- ide-h8300.c | `-- RAMDISK驱动 | `-- rd.c |-- 14 | |-- S3C2410串口驱动 | | |-- regs-gpio.h | | |-- regs-serial.h | | `-- s3c2410.c | `-- 串口核心层 | |-- serial_core.c | `-- serial_core.h |-- 15 | |-- S3C2410 I2C主机驱动 | | |-- i2c-s3c2410.c | | |-- iic.h | | |-- regs-gpio.h | | `-- regs-iic.h | `-- SAA711x I2C设备驱动 | `-- saa711x.c |-- 16 | `-- CS8900以太网设备驱动 | |-- cs89x0.c | `-- cs89x0.h |-- 17 | |-- ALSA工具及库 | | |-- alsa-driver-1.0.15.tar.bz2 | | |-- alsa-firmware-1.0.15.tar.bz2 | | |-- alsa-lib-1.0.15.tar.bz2 | | |-- alsa-oss-1.0.15.tar.bz2 | | |-- alsa-tools-1.0.15.tar.bz2 | | |-- alsa-utils-1.0.13.tar.bz2 | | `-- pyalsa-1.0.15.tar.bz2 | |-- ALSA驱动范例 | | |-- sa11xx-uda1341.c | | `-- uda1341.h | |-- ALSA应用程序范例 | | |-- pcm.c | | `-- pcm_min.c | |-- OSS驱动范例 | | `-- s3c2410-uda1341.c | `-- OSS应用程序范例 | |-- mixer.c | `-- sound.c |-- 18 | |-- FRAMEBUFFER应用程序范例 | | `-- fb_display | | |-- fb_display.c | | |-- fb_display.h | | |-- Makefile | | |-- README | | `-- test.c | `-- S3C2410 LCD驱动 | |-- s3c2410fb.c | `-- s3c2410fb.h |-- 19 | |-- busybox源代码 | | `-- busybox-1.2.1.tar.bz2 | |-- MTD工具 | | `-- mtd-utils-1.0.0.tar.gz | |-- nand驱动范例 | | `-- s3c2410.c | |-- nor驱动范例 | | `-- s3c2410nor.c | `-- yaffs&yaffs2源代码 | |-- yaffs.tar.gz | `-- yaffs2.tar.gz |-- 20 | |-- USB串口驱动 | | |-- usb-serial.c | | `-- usb-serial.h | |-- USB工具 | | `-- usbview-1.0.tar.tar | |-- USB骨架程序 | | `-- usb-skeleton.c | |-- USB键盘驱动 | | |-- input.h | | |-- usb_input.h | | `-- usbkbd.c | `-- usb主机控制器驱动范例 | |-- ohci-s3c2410.c | `-- usb-control.h |-- 21 | |-- PCI骨架程序 | | `-- pci-skeleton.c | `-- PCI驱动范例 | `-- i810_audio.c `-- 22 |-- 范例代码 | |-- oops范例 | | |-- oops_example.asm | | `-- oops_example.c | `-- proc范例 | `-- sim_proc.c `-- 内核调试工具 |-- ddd-3.3.11.tar.gz |-- gdbmod-2.4.bz2 |-- kdb-v4.4-2.6.15-rc5-common-1.bz2 |-- kdb-v4.4-2.6.15-rc5-common-2.bz2 |-- kdb-v4.4-2.6.15-rc5-i386-1.bz2 `-- linux-2.6.15.5-kgdb-2.4.tar.tar 73 directories, 91 files
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值