static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* * Can be an alarm interrupt, update complete interrupt, * or a periodic interrupt. We store the status in the * low byte and the number of interrupts received since * the last read in the remainder of rtc_irq_data. */
spin_lock(&rtc_lock); rtc_irq_data += 0x100; rtc_irq_data &= ~0xff; rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) &0xF0);
if (rtc_status &RTC_TIMER_ON) mod_timer(&rtc_irq_timer, jiffies + HZ / rtc_freq + 2 * HZ / 100);
spin_unlock(&rtc_lock);
/* Now do the rest of the actions */ wake_up_interruptible(&rtc_wait);
kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); }
static int rtc_fasync (int fd, struct file *filp, int on) { return fasync_helper (fd, filp, on, &rtc_async_queue); }
static void rtc_dropped_irq(unsigned long data) { unsigned long freq;
spin_lock_irq(&rtc_lock);
/* Just in case someone disabled the timer from behind our back... */ if (rtc_status &RTC_TIMER_ON) mod_timer(&rtc_irq_timer, jiffies + HZ / rtc_freq + 2 * HZ / 100);
rtc_irq_data += ((rtc_freq / HZ) << 8); rtc_irq_data &= ~0xff; rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) &0xF0); /* restart */
freq = rtc_freq;
spin_unlock_irq(&rtc_lock); printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq);
/* Now we have new data */ wake_up_interruptible(&rtc_wait);
kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); }
|