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: Arnaud 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: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
893556e602
commit
3804a89bfb
|
@ -238,31 +238,32 @@ 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
|
|
||||||
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
|
else
|
||||||
t->time.tm_mday = -1;
|
t->time.tm_sec = -1;
|
||||||
if (cmos->mon_alrm) {
|
if (((unsigned)t->time.tm_min) < 0x60)
|
||||||
if (((unsigned)t->time.tm_mon) <= 0x12)
|
t->time.tm_min = bcd2bin(t->time.tm_min);
|
||||||
t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1;
|
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
|
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;
|
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)
|
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 */
|
|
||||||
|
|
||||||
/* Writing 0xff means "don't care" or "match all". */
|
|
||||||
|
|
||||||
mon = t->time.tm_mon + 1;
|
mon = t->time.tm_mon + 1;
|
||||||
mon = (mon <= 12) ? bin2bcd(mon) : 0xff;
|
|
||||||
|
|
||||||
mday = t->time.tm_mday;
|
mday = t->time.tm_mday;
|
||||||
mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff;
|
|
||||||
|
|
||||||
hrs = t->time.tm_hour;
|
hrs = t->time.tm_hour;
|
||||||
hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff;
|
|
||||||
|
|
||||||
min = t->time.tm_min;
|
min = t->time.tm_min;
|
||||||
min = (min < 60) ? bin2bcd(min) : 0xff;
|
|
||||||
|
|
||||||
sec = t->time.tm_sec;
|
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);
|
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"
|
"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)
|
||||||
(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)
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue