142 int (*open)(struct device *); //打開設備時的回調函數,這個函數應該初始化硬件並申請資源
143 void (*release)(struct device *); //這個函數是設備關閉時被調用的,應該註銷申請的資源。
144 int (*ioctl)(struct device *, unsigned int, unsigned long); //ioctl函數,對於想讓RTC自己實現的命令應返回ENOIOCTLCMD
145 int (*read_time)(struct device *, struct rtc_time *); //讀取時間
146 int (*set_time)(struct device *, struct rtc_time *); //設置時間
147 int (*read_alarm)(struct device *, struct rtc_wkalrm *); //讀取下一次定時中斷的時間
148 int (*set_alarm)(struct device *, struct rtc_wkalrm *); //設置下一次定時中斷的時間
149 int (*proc)(struct device *, struct seq_file *); //procfs接口,該函數決定你在終端中cat /proc/driver/rtc時輸出相關的信息
150 int (*set_mmss)(struct device *, unsigned long secs); // 將傳入的參數secs轉換爲struct rtc_time然後調用set_time函數。程序員可以不實現這個函數,但前提是定義好了read_time/set_time,因爲RTC框架需要用這兩個函數來實現這個功能。
151 int (*irq_set_state)(struct device *, int enabled); //週期採樣中斷的開關,根據enabled的值來設置
152 int (*irq_set_freq)(struct device *, int freq); //設置週期中斷的頻率
153 int (*read_callback)(struct device *, int data); //用戶空間獲得數據後會傳入讀取的數據,並用這個函數返回的數據更新數據。
154 int (*alarm_irq_enable)(struct device *, unsigned int enabled); //alarm中斷使能開關,根據enabled的值來設置
155 int (*update_irq_enable)(struct device *, unsigned int enabled); //更新中斷使能開關,根據enabled的值來設置
156 };
rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
//這裏睡眠並等待讀取數據
/* Check for any data updates */
if (rtc->ops->read_callback)
data = rtc->ops->read_callback(rtc->dev.parent, data);//調用read_callback並用它返回的值更新數據
if (sizeof(int) != sizeof(long) &&
count == sizeof(unsigned int))
ret = put_user(data, (unsigned int __user *)buf) ?:
sizeof(unsigned int);
else
ret = put_user(data, (unsigned long __user *)buf) ?:
sizeof(unsigned long);
}
return ret;
}
{
unsigned int int_stat;
struct rtc_device *rdev = id;
void __iomem *base = sep0611_rtc_base;
int_stat = readl(base + SEP0611_RTC_INT_STS);
writel(int_stat, base + SEP0611_RTC_INT_STS);
if (int_stat & ALARM_FLAG) {
rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
}
if (int_stat & SAMP_FLAG) {
/*reload the samp_count every time after a samp_int triggers*/
writel(SAMP_COUNT << 16, base + SEP0611_RTC_SAMP);
rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
}
if (int_stat & SEC_FLAG) {
rtc_update_irq(rdev, 1, RTC_UF | RTC_IRQF);
}
return IRQ_HANDLED;
}
#define RTC_PF 0x40
#define RTC_AF 0x20
#define RTC_UF 0x10
unsigned long num, unsigned long events)
{
spin_lock(&rtc->irq_lock);
rtc->irq_data = (rtc->irq_data + (num << 8)) | events;
spin_unlock(&rtc->irq_lock);
spin_lock(&rtc->irq_task_lock);
if (rtc->irq_task)
rtc->irq_task->func(rtc->irq_task->private_data);
spin_unlock(&rtc->irq_task_lock);
wake_up_interruptible(&rtc->irq_queue);
kill_fasync(&rtc->async_queue, SIGIO, POLL_IN);
}
{
int retval = -EBUSY;
if (task == NULL || task->func == NULL)
return -EINVAL;
/* Cannot register while the char dev is in use */
if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
return -EBUSY;
spin_lock_irq(&rtc->irq_task_lock);
if (rtc->irq_task == NULL) {
rtc->irq_task = task;
retval = 0;
}
spin_unlock_irq(&rtc->irq_task_lock);
clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
return retval;
}
void (*func)(void *private_data); //回調函數
void *private_data; //傳給回調函數的參數
} rtc_task_t;
const struct rtc_class_ops *ops,
struct module *owner)
int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);//讀取定時中斷的時間
int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);//設置定時中斷
unsigned long num, unsigned long events);//中斷到來後,這個函數被調用來更新數據。
這是2.6.27.8的內核,沒有給其它模塊提供更新中斷的接口。因爲更新中斷是用軟件模擬的。
2.6.27.8的更新中斷在 定義CONFIG_RTC_INTF_DEV_UIE_EMUL的情況下用軟件定時器模擬