Commit 3804a89b authored by Arnaud Patard's avatar Arnaud Patard Committed by Ralf Baechle

RTC: 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: default avatarArnaud Patard <apatard@mandriva.com>
To: linux-mips@linux-mips.org
To: rtc-linux@googlegroups.com
Cc: david-b@pacbell.net
Cc: a.zummo@towertech.it
Cc: akpm@linux-foundation.org
Patchwork: http://patchwork.linux-mips.org/patch/1158/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 893556e6
...@@ -238,8 +238,7 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -238,8 +238,7 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
rtc_control = CMOS_READ(RTC_CONTROL); rtc_control = CMOS_READ(RTC_CONTROL);
spin_unlock_irq(&rtc_lock); spin_unlock_irq(&rtc_lock);
/* REVISIT this assumes PC style usage: always BCD */ if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
if (((unsigned)t->time.tm_sec) < 0x60) if (((unsigned)t->time.tm_sec) < 0x60)
t->time.tm_sec = bcd2bin(t->time.tm_sec); t->time.tm_sec = bcd2bin(t->time.tm_sec);
else else
...@@ -258,13 +257,15 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -258,13 +257,15 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
t->time.tm_mday = bcd2bin(t->time.tm_mday); t->time.tm_mday = bcd2bin(t->time.tm_mday);
else else
t->time.tm_mday = -1; t->time.tm_mday = -1;
if (cmos->mon_alrm) { if (cmos->mon_alrm) {
if (((unsigned)t->time.tm_mon) <= 0x12) if (((unsigned)t->time.tm_mon) <= 0x12)
t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1; t->time.tm_mon = bcd2bin(t->time.tm_mon)-1;
else else
t->time.tm_mon = -1; t->time.tm_mon = -1;
} }
} }
}
t->time.tm_year = -1; t->time.tm_year = -1;
t->enabled = !!(rtc_control & RTC_AIE); t->enabled = !!(rtc_control & RTC_AIE);
...@@ -322,29 +323,26 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) ...@@ -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) static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{ {
struct cmos_rtc *cmos = dev_get_drvdata(dev); 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)) if (!is_valid_irq(cmos->irq))
return -EIO; return -EIO;
/* REVISIT this assumes PC style usage: always BCD */ mon = t->time.tm_mon + 1;
mday = t->time.tm_mday;
hrs = t->time.tm_hour;
min = t->time.tm_min;
sec = t->time.tm_sec;
rtc_control = CMOS_READ(RTC_CONTROL);
if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
/* Writing 0xff means "don't care" or "match all". */ /* Writing 0xff means "don't care" or "match all". */
mon = t->time.tm_mon + 1;
mon = (mon <= 12) ? bin2bcd(mon) : 0xff; mon = (mon <= 12) ? bin2bcd(mon) : 0xff;
mday = t->time.tm_mday;
mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff;
hrs = t->time.tm_hour;
hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff;
min = t->time.tm_min;
min = (min < 60) ? bin2bcd(min) : 0xff; min = (min < 60) ? bin2bcd(min) : 0xff;
sec = t->time.tm_sec;
sec = (sec < 60) ? bin2bcd(sec) : 0xff; sec = (sec < 60) ? bin2bcd(sec) : 0xff;
}
spin_lock_irq(&rtc_lock); spin_lock_irq(&rtc_lock);
...@@ -478,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) ...@@ -478,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
"update_IRQ\t: %s\n" "update_IRQ\t: %s\n"
"HPET_emulated\t: %s\n" "HPET_emulated\t: %s\n"
// "square_wave\t: %s\n" // "square_wave\t: %s\n"
// "BCD\t\t: %s\n" "BCD\t\t: %s\n"
"DST_enable\t: %s\n" "DST_enable\t: %s\n"
"periodic_freq\t: %d\n" "periodic_freq\t: %d\n"
"batt_status\t: %s\n", "batt_status\t: %s\n",
...@@ -486,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) ...@@ -486,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
(rtc_control & RTC_UIE) ? "yes" : "no", (rtc_control & RTC_UIE) ? "yes" : "no",
is_hpet_enabled() ? "yes" : "no", is_hpet_enabled() ? "yes" : "no",
// (rtc_control & RTC_SQWE) ? "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", (rtc_control & RTC_DST_EN) ? "yes" : "no",
cmos->rtc->irq_freq, cmos->rtc->irq_freq,
(valid & RTC_VRT) ? "okay" : "dead"); (valid & RTC_VRT) ? "okay" : "dead");
...@@ -751,12 +749,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) ...@@ -751,12 +749,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
spin_unlock_irq(&rtc_lock); 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. * <asm-generic/rtc.h> doesn't know 12-hour mode either.
*/ */
if (is_valid_irq(rtc_irq) && if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
(!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { dev_warn(dev, "only 24-hr supported\n");
dev_dbg(dev, "only 24-hr BCD mode supported\n");
retval = -ENXIO; retval = -ENXIO;
goto cleanup1; goto cleanup1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment