标签:resume module queue cal mono tca 初始化 creat sysfs
//s3c-rtc 子系统分析
//刘术河
2016.08.25
//这里先从驱动层入手
\linux-2.6.39-at91-2016.08.11-lsh\drivers\rtc\Rtc-s3c.c
1.从rtc层入手看rtc驱动框架
static struct platform_driver s3c_rtc_driver = {
.probe = s3c_rtc_probe,
.remove = __devexit_p(s3c_rtc_remove),
.suspend = s3c_rtc_suspend,
.resume = s3c_rtc_resume,
.id_table = s3c_rtc_driver_ids,
.driver = {
.name = "s3c-rtc",
.owner = THIS_MODULE,
},
};
//rtc-s3c的fops函数
static const struct rtc_class_ops s3c_rtcops = {
.open = s3c_rtc_open,
.release = s3c_rtc_release,
.read_time = s3c_rtc_gettime,
.set_time = s3c_rtc_settime,
.read_alarm = s3c_rtc_getalarm,
.set_alarm = s3c_rtc_setalarm,
.proc = s3c_rtc_proc,
.alarm_irq_enable = s3c_rtc_setaie,
};
module_init(s3c_rtc_init);
s3c_rtc_init(void)
platform_driver_register(&s3c_rtc_driver); //平台总线已经分析过,这里不再分析,这里会调用s3c_rtc_probe
s3c_rtc_probe
rtc_clk = clk_get(&pdev->dev, "rtc");
clk_enable(rtc_clk);
s3c_rtc_enable(pdev, 1);
device_init_wakeup(&pdev->dev, 1);
rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,THIS_MODULE); //这里是注册rtc设备
s3c_rtc_gettime(NULL, &rtc_tm);
s3c_rtc_settime(NULL, &rtc_tm);
s3c_rtc_setfreq(&pdev->dev, 1);
2.分析 rtc_device_register 注册函数,发现rtc_device_register是在drivers/rtc/class里的api
3.分析 class.c 框架
subsys_initcall(rtc_init);
rtc_init
rtc_class = class_create(THIS_MODULE, "rtc"); //创建一个类
rtc_dev_init(); //初始化设备
alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); //分配一个字符设备
rtc_sysfs_init(rtc_class); //文件目录初始化
4.可见class核心层只是分配一个类,并给自动分配设备号
核心层提供了一个rtc_device_register函数
5.回到 rtc-s3c的probe函数继续分析rtc_device_register函数
rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,THIS_MODULE);
struct rtc_device *rtc;
rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
init_waitqueue_head(&rtc->irq_queue);
timerqueue_init_head(&rtc->timerqueue);
INIT_WORK(&rtc->irqwork, rtc_timer_do_work);
rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc);
rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc);
hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
rtc_dev_prepare(rtc);
rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
cdev_init(&rtc->char_dev, &rtc_dev_fops);
rtc->char_dev.owner = rtc->owner;
device_register(&rtc->dev);
rtc_dev_add_device(rtc);
cdev_add(&rtc->char_dev, rtc->dev.devt, 1)
rtc_sysfs_add_device(rtc);
device_create_file(&rtc->dev, &dev_attr_wakealarm);
rtc_proc_add_device(rtc);
proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc);
标签:resume module queue cal mono tca 初始化 creat sysfs
原文地址:https://www.cnblogs.com/liushuhe1990/p/9609010.html