rtc-cmos: Fix binary mode support
Subsystems (2)
PATCH 1/1 rtc-cmos: Fix binary mode support
As a follow-up to the thread about rtc support for some loongson 2e/2f boards, this patch tries to address the "REVISIT"/"FIXME" comments about rtc binary mode handling and allow rtc to work with rtc in binary mode. I've also raised the message about 24-h mode not supported to warning otherwise, one may end up with no rtc without any message in the kernel log.
Signed-off-by Arnaud Patard <[email protected]>
drivers/rtc/rtc-cmos.c +40 -43
@@ -238,31 +238,32 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) rtc_control =CMOS_READ (RTC_CONTROL );spin_unlock_irq (&rtc_lock); -/* REVISIT this assumes PC style usage: always BCD */ - -if (((unsigned )t->time.tm_sec) <0x60 ) - t->time.tm_sec =bcd2bin (t->time.tm_sec); -else - t->time.tm_sec =-1 ; -if (((unsigned )t->time.tm_min) <0x60 ) - t->time.tm_min =bcd2bin (t->time.tm_min); -else - t->time.tm_min =-1 ; -if (((unsigned )t->time.tm_hour) <0x24 ) - t->time.tm_hour =bcd2bin (t->time.tm_hour); -else - t->time.tm_hour =-1 ; - -if (cmos->day_alrm) { -if (((unsigned )t->time.tm_mday) <=0x31 ) - t->time.tm_mday =bcd2bin (t->time.tm_mday); +if (!(rtc_control &RTC_DM_BINARY ) ||RTC_ALWAYS_BCD ) { +if (((unsigned )t->time.tm_sec) <0x60 ) + t->time.tm_sec =bcd2bin (t->time.tm_sec);else - t->time.tm_mday =-1 ; -if (cmos->mon_alrm) { -if (((unsigned )t->time.tm_mon) <=0x12 ) - t->time.tm_mon =bcd2bin (t->time.tm_mon) -1 ; + t->time.tm_sec =-1 ; +if (((unsigned )t->time.tm_min) <0x60 ) + t->time.tm_min =bcd2bin (t->time.tm_min); +else + t->time.tm_min =-1 ; +if (((unsigned )t->time.tm_hour) <0x24 ) + t->time.tm_hour =bcd2bin (t->time.tm_hour); +else + t->time.tm_hour =-1 ; + +if (cmos->day_alrm) { +if (((unsigned )t->time.tm_mday) <=0x31 ) + t->time.tm_mday =bcd2bin (t->time.tm_mday);else - t->time.tm_mon =-1 ; + t->time.tm_mday =-1 ; + +if (cmos->mon_alrm) { +if (((unsigned )t->time.tm_mon) <=0x12 ) + t->time.tm_mon =bcd2bin (t->time.tm_mon)-1 ; +else + t->time.tm_mon =-1 ; + } } } t->time.tm_year =-1 ;
@@ -322,29 +323,26 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)static int cmos_set_alarm (struct device *dev,struct rtc_wkalrm *t) {struct cmos_rtc *cmos =dev_get_drvdata (dev); -unsigned char mon, mday, hrs, min, sec; +unsigned char mon, mday, hrs, min, sec, rtc_control;if (!is_valid_irq (cmos->irq))return -EIO ; -/* REVISIT this assumes PC style usage: always BCD */ - -/* Writing 0xff means "don't care" or "match all". */ - mon = t->time.tm_mon +1 ; - mon = (mon <=12 ) ?bin2bcd (mon) :0xff ; - mday = t->time.tm_mday; - mday = (mday >=1 && mday <=31 ) ?bin2bcd (mday) :0xff ; - hrs = t->time.tm_hour; - hrs = (hrs <24 ) ?bin2bcd (hrs) :0xff ; - min = t->time.tm_min; - min = (min <60 ) ?bin2bcd (min) :0xff ; - sec = t->time.tm_sec; - sec = (sec <60 ) ?bin2bcd (sec) :0xff ; + + rtc_control =CMOS_READ (RTC_CONTROL ); +if (!(rtc_control &RTC_DM_BINARY ) ||RTC_ALWAYS_BCD ) { +/* Writing 0xff means "don't care" or "match all". */ + mon = (mon <=12 ) ?bin2bcd (mon) :0xff ; + mday = (mday >=1 && mday <=31 ) ?bin2bcd (mday) :0xff ; + hrs = (hrs <24 ) ?bin2bcd (hrs) :0xff ; + min = (min <60 ) ?bin2bcd (min) :0xff ; + sec = (sec <60 ) ?bin2bcd (sec) :0xff ; + }spin_lock_irq (&rtc_lock);
@@ -478,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)"update_IRQ\t: %s\n" "HPET_emulated\t: %s\n" // "square_wave\t: %s\n" -// "BCD\t\t: %s\n" +"BCD\t\t: %s\n" "DST_enable\t: %s\n" "periodic_freq\t: %d\n" "batt_status\t: %s\n",
@@ -486,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) (rtc_control &RTC_UIE ) ?"yes" :"no" ,is_hpet_enabled () ?"yes" :"no" ,// (rtc_control & RTC_SQWE) ? "yes" : "no", -// (rtc_control & RTC_DM_BINARY) ? "no" : "yes", + (rtc_control &RTC_DM_BINARY ) ?"no" :"yes" , (rtc_control &RTC_DST_EN ) ?"yes" :"no" , cmos->rtc->irq_freq, (valid & RTC_VRT) ? "okay" : "dead");
@@ -749,12 +747,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)spin_unlock_irq (&rtc_lock); -/* FIXME teach the alarm code how to handle binary mode; +/* FIXME: * <asm-generic/rtc.h> doesn't know 12-hour mode either. */ -if (is_valid_irq (rtc_irq) && - (!(rtc_control &RTC_24H ) || (rtc_control & (RTC_DM_BINARY )))) { -dev_dbg (dev,"only 24-hr BCD mode supported\n" ); +if (is_valid_irq (rtc_irq) && !(rtc_control &RTC_24H )) { +dev_warn (dev,"only 24-hr supported\n" ) retval = -ENXIO; goto cleanup1; }