Loading drivers/char/rtc.c +38 −27 Original line number Diff line number Diff line Loading @@ -149,8 +149,22 @@ static void get_rtc_alm_time (struct rtc_time *alm_tm); #ifdef RTC_IRQ static void rtc_dropped_irq(unsigned long data); static void set_rtc_irq_bit(unsigned char bit); static void mask_rtc_irq_bit(unsigned char bit); static void set_rtc_irq_bit_locked(unsigned char bit); static void mask_rtc_irq_bit_locked(unsigned char bit); static inline void set_rtc_irq_bit(unsigned char bit) { spin_lock_irq(&rtc_lock); set_rtc_irq_bit_locked(bit); spin_unlock_irq(&rtc_lock); } static void mask_rtc_irq_bit(unsigned char bit) { spin_lock_irq(&rtc_lock); mask_rtc_irq_bit_locked(bit); spin_unlock_irq(&rtc_lock); } #endif static int rtc_proc_open(struct inode *inode, struct file *file); Loading Loading @@ -401,18 +415,19 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) } case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ { mask_rtc_irq_bit(RTC_PIE); unsigned long flags; /* can be called from isr via rtc_control() */ spin_lock_irqsave (&rtc_lock, flags); mask_rtc_irq_bit_locked(RTC_PIE); if (rtc_status & RTC_TIMER_ON) { spin_lock_irq (&rtc_lock); rtc_status &= ~RTC_TIMER_ON; del_timer(&rtc_irq_timer); spin_unlock_irq (&rtc_lock); } spin_unlock_irqrestore (&rtc_lock, flags); return 0; } case RTC_PIE_ON: /* Allow periodic ints */ { unsigned long flags; /* can be called from isr via rtc_control() */ /* * We don't really want Joe User enabling more * than 64Hz of interrupts on a multi-user machine. Loading @@ -421,14 +436,14 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) (!capable(CAP_SYS_RESOURCE))) return -EACCES; spin_lock_irqsave (&rtc_lock, flags); if (!(rtc_status & RTC_TIMER_ON)) { spin_lock_irq (&rtc_lock); rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100; add_timer(&rtc_irq_timer); rtc_status |= RTC_TIMER_ON; spin_unlock_irq (&rtc_lock); } set_rtc_irq_bit(RTC_PIE); set_rtc_irq_bit_locked(RTC_PIE); spin_unlock_irqrestore (&rtc_lock, flags); return 0; } case RTC_UIE_OFF: /* Mask ints from RTC updates. */ Loading Loading @@ -609,6 +624,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) { int tmp = 0; unsigned char val; unsigned long flags; /* can be called from isr via rtc_control() */ /* * The max we can do is 8192Hz. Loading @@ -631,9 +647,9 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) if (arg != (1<<tmp)) return -EINVAL; spin_lock_irq(&rtc_lock); spin_lock_irqsave(&rtc_lock, flags); if (hpet_set_periodic_freq(arg)) { spin_unlock_irq(&rtc_lock); spin_unlock_irqrestore(&rtc_lock, flags); return 0; } rtc_freq = arg; Loading @@ -641,7 +657,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; val |= (16 - tmp); CMOS_WRITE(val, RTC_FREQ_SELECT); spin_unlock_irq(&rtc_lock); spin_unlock_irqrestore(&rtc_lock, flags); return 0; } #endif Loading Loading @@ -844,12 +860,15 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) #ifndef RTC_IRQ return -EIO; #else spin_lock_irq(&rtc_task_lock); unsigned long flags; if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET) return -EINVAL; spin_lock_irqsave(&rtc_task_lock, flags); if (rtc_callback != task) { spin_unlock_irq(&rtc_task_lock); spin_unlock_irqrestore(&rtc_task_lock, flags); return -ENXIO; } spin_unlock_irq(&rtc_task_lock); spin_unlock_irqrestore(&rtc_task_lock, flags); return rtc_do_ioctl(cmd, arg, 1); #endif } Loading Loading @@ -1306,40 +1325,32 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm) * meddles with the interrupt enable/disable bits. */ static void mask_rtc_irq_bit(unsigned char bit) static void mask_rtc_irq_bit_locked(unsigned char bit) { unsigned char val; spin_lock_irq(&rtc_lock); if (hpet_mask_rtc_irq_bit(bit)) { spin_unlock_irq(&rtc_lock); if (hpet_mask_rtc_irq_bit(bit)) return; } val = CMOS_READ(RTC_CONTROL); val &= ~bit; CMOS_WRITE(val, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); rtc_irq_data = 0; spin_unlock_irq(&rtc_lock); } static void set_rtc_irq_bit(unsigned char bit) static void set_rtc_irq_bit_locked(unsigned char bit) { unsigned char val; spin_lock_irq(&rtc_lock); if (hpet_set_rtc_irq_bit(bit)) { spin_unlock_irq(&rtc_lock); if (hpet_set_rtc_irq_bit(bit)) return; } val = CMOS_READ(RTC_CONTROL); val |= bit; CMOS_WRITE(val, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); rtc_irq_data = 0; spin_unlock_irq(&rtc_lock); } #endif Loading Loading
drivers/char/rtc.c +38 −27 Original line number Diff line number Diff line Loading @@ -149,8 +149,22 @@ static void get_rtc_alm_time (struct rtc_time *alm_tm); #ifdef RTC_IRQ static void rtc_dropped_irq(unsigned long data); static void set_rtc_irq_bit(unsigned char bit); static void mask_rtc_irq_bit(unsigned char bit); static void set_rtc_irq_bit_locked(unsigned char bit); static void mask_rtc_irq_bit_locked(unsigned char bit); static inline void set_rtc_irq_bit(unsigned char bit) { spin_lock_irq(&rtc_lock); set_rtc_irq_bit_locked(bit); spin_unlock_irq(&rtc_lock); } static void mask_rtc_irq_bit(unsigned char bit) { spin_lock_irq(&rtc_lock); mask_rtc_irq_bit_locked(bit); spin_unlock_irq(&rtc_lock); } #endif static int rtc_proc_open(struct inode *inode, struct file *file); Loading Loading @@ -401,18 +415,19 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) } case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ { mask_rtc_irq_bit(RTC_PIE); unsigned long flags; /* can be called from isr via rtc_control() */ spin_lock_irqsave (&rtc_lock, flags); mask_rtc_irq_bit_locked(RTC_PIE); if (rtc_status & RTC_TIMER_ON) { spin_lock_irq (&rtc_lock); rtc_status &= ~RTC_TIMER_ON; del_timer(&rtc_irq_timer); spin_unlock_irq (&rtc_lock); } spin_unlock_irqrestore (&rtc_lock, flags); return 0; } case RTC_PIE_ON: /* Allow periodic ints */ { unsigned long flags; /* can be called from isr via rtc_control() */ /* * We don't really want Joe User enabling more * than 64Hz of interrupts on a multi-user machine. Loading @@ -421,14 +436,14 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) (!capable(CAP_SYS_RESOURCE))) return -EACCES; spin_lock_irqsave (&rtc_lock, flags); if (!(rtc_status & RTC_TIMER_ON)) { spin_lock_irq (&rtc_lock); rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100; add_timer(&rtc_irq_timer); rtc_status |= RTC_TIMER_ON; spin_unlock_irq (&rtc_lock); } set_rtc_irq_bit(RTC_PIE); set_rtc_irq_bit_locked(RTC_PIE); spin_unlock_irqrestore (&rtc_lock, flags); return 0; } case RTC_UIE_OFF: /* Mask ints from RTC updates. */ Loading Loading @@ -609,6 +624,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) { int tmp = 0; unsigned char val; unsigned long flags; /* can be called from isr via rtc_control() */ /* * The max we can do is 8192Hz. Loading @@ -631,9 +647,9 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) if (arg != (1<<tmp)) return -EINVAL; spin_lock_irq(&rtc_lock); spin_lock_irqsave(&rtc_lock, flags); if (hpet_set_periodic_freq(arg)) { spin_unlock_irq(&rtc_lock); spin_unlock_irqrestore(&rtc_lock, flags); return 0; } rtc_freq = arg; Loading @@ -641,7 +657,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; val |= (16 - tmp); CMOS_WRITE(val, RTC_FREQ_SELECT); spin_unlock_irq(&rtc_lock); spin_unlock_irqrestore(&rtc_lock, flags); return 0; } #endif Loading Loading @@ -844,12 +860,15 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) #ifndef RTC_IRQ return -EIO; #else spin_lock_irq(&rtc_task_lock); unsigned long flags; if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET) return -EINVAL; spin_lock_irqsave(&rtc_task_lock, flags); if (rtc_callback != task) { spin_unlock_irq(&rtc_task_lock); spin_unlock_irqrestore(&rtc_task_lock, flags); return -ENXIO; } spin_unlock_irq(&rtc_task_lock); spin_unlock_irqrestore(&rtc_task_lock, flags); return rtc_do_ioctl(cmd, arg, 1); #endif } Loading Loading @@ -1306,40 +1325,32 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm) * meddles with the interrupt enable/disable bits. */ static void mask_rtc_irq_bit(unsigned char bit) static void mask_rtc_irq_bit_locked(unsigned char bit) { unsigned char val; spin_lock_irq(&rtc_lock); if (hpet_mask_rtc_irq_bit(bit)) { spin_unlock_irq(&rtc_lock); if (hpet_mask_rtc_irq_bit(bit)) return; } val = CMOS_READ(RTC_CONTROL); val &= ~bit; CMOS_WRITE(val, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); rtc_irq_data = 0; spin_unlock_irq(&rtc_lock); } static void set_rtc_irq_bit(unsigned char bit) static void set_rtc_irq_bit_locked(unsigned char bit) { unsigned char val; spin_lock_irq(&rtc_lock); if (hpet_set_rtc_irq_bit(bit)) { spin_unlock_irq(&rtc_lock); if (hpet_set_rtc_irq_bit(bit)) return; } val = CMOS_READ(RTC_CONTROL); val |= bit; CMOS_WRITE(val, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); rtc_irq_data = 0; spin_unlock_irq(&rtc_lock); } #endif Loading