static int set_rtc_mmss(unsigned long nowtime) 
{ 
int retval = 0. 
int real_seconds, real_minutes, cmos_minutes. 
unsigned char save_control, save_freq_0select. 
/* gets recalled with irq locally disabled */ 
spin_lock(&.rtc_lock). 
save_control = CMOS_READ(RTC_CONTROL). /* tell the clock it s being set */ 
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL). 
save_freq_0select = CMOS_READ(RTC_FREQ_SELECT). /* stop and reset prescaler */ 
CMOS_WRITE((save_freq_0select|RTC_DIV_RESET2), RTC_FREQ_SELECT). 
cmos_minutes = CMOS_READ(RTC_MINUTES). 
if (!(save_control &. RTC_DM_BINARY) || RTC_ALWAYS_BCD) 
BCD_TO_BIN(cmos_minutes). 
/* 
* since we re only adjusting minutes and seconds, 
* don t interfere with hour overflow. This avoids 
* messing with unknown time zones but requires your 
* RTC not to be off by more than 15 minutes 
*/ 
real_seconds = nowtime % 60. 
real_minutes = nowtime / 60. 
if (((abs(real_minutes - cmos_minutes)   15)/30) &. 1) 
real_minutes  = 30. /* correct for half hour time zone */ 
real_minutes %= 60. 
if (abs(real_minutes - cmos_minutes) < 30) { 
if (!(save_control &. RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 
BIN_TO_BCD(real_seconds). 
BIN_TO_BCD(real_minutes). 
} 
CMOS_WRITE(real_seconds,RTC_SECONDS). 
CMOS_WRITE(real_minutes,RTC_MINUTES). 
} else { 
printk(KERN_WARNING 
"set_rtc_mmss: can t 0update from %d to %d\n", 
cmos_minutes, real_minutes). 
retval = -1. 
} 
/* The following flags have to be released exactly in this order, 
* otherwise the DS12887 (popular MC146818A clone with integrated 
* battery and quartz) will not reset the oscillator and will not 
* 0update precisely 500 ms later. You won t find this mentioned in 
* the Dallas Semiconductor data sheets, but who believes data 
* sheets anyway ... -- Markus Kuhn 
*/ 
CMOS_WRITE(save_control, RTC_CONTROL). 
CMOS_WRITE(save_freq_0select, RTC_FREQ_SELECT). 
spin_unlock(&.rtc_lock). 
return retval. 
}  |