- UID
- 1029342
- 性别
- 男
|
ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq,
IRQF_DISABLED, "s3c2410-rtc tick", rtc_dev); //申请一个计数中断,将中断函数设为s3c_rtc_tickirq(),并传递rtc_dev作为参数
if (ret) {
dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
goto tick_err;
}
return ret;
tick_err:
free_irq(s3c_rtc_alarmno, rtc_dev);
return ret;
}
RTC设备释放函数由s3c_rtc_release()来实现。用户空间调用close()时,最终会调用s3c_rtc_release()函数。该函数主要释放s3c_rtc_open()函数申请的两个中断
static void s3c_rtc_release(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev); //从device结构体转到platform_device
struct rtc_device *rtc_dev = platform_get_drvdata(pdev); //从pdev->dev的私有数据中得到rtc_device
/* do not clear AIE here, it may be needed for wake */
s3c_rtc_setpie(dev, 0);
free_irq(s3c_rtc_alarmno, rtc_dev);
free_irq(s3c_rtc_tickno, rtc_dev);
}
RTC实时时钟获得时间安函数
当调用read()函数时会间接的调用s3c_rtc_gettime()函数来获得实时时钟的时间。时间值分别保存在RTC实时时钟的各个寄存器中。这些寄存器是秒寄存器、日期寄存器、分钟寄存器、和小时寄存器。s3c_rtc_gettime()函数会使用一个struct rtc_time 的机构体来表示一个时间值
struct rtc_time {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday; //这三个RTC实时时钟未用
int tm_yday;
int tm_isdst;
};
存储在RTC实时时钟寄存器中的值都是以BCD码保存的。但是Linux驱动程序中使用二进制码形式。通过bcd2bin()
unsigned bcd2bin(unsigned char val)
{
return (val & 0x0f) + (val >> 4) * 10;
}
unsigned char bin2bcd(unsigned val)
{
return ((val / 10) << 4) + val % 10;
}
从RTC实时时钟得到时间的函数是s3c_rtc_gettime()。第一个参数是RTC设备结构体指针,第二个参数是前面提到的struct rtc_time。
static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
{
unsigned int have_retried = 0;
void __iomem *base = s3c_rtc_base;
retry_get_time:
rtc_tm->tm_min = readb(base + S3C2410_RTCMIN);
rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR);
rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE);
rtc_tm->tm_mon = readb(base + S3C2410_RTCMON);
rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);
rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC);
/* the only way to work out wether the system was mid-update
* when we read it is to check the second counter, and if it
* is zero, then we re-try the entire read
*/
if (rtc_tm->tm_sec == 0 && !have_retried) { //如果秒寄存器中是0,则表示过去了一分钟,那么小时,天,月,等寄存器中的值都可能已经变化,则重新读取这些寄存器的值
have_retried = 1;
goto retry_get_time;
} |
|