Commit 79250ef3 authored by Dario Binacchi's avatar Dario Binacchi Committed by Lokesh Vutla
Browse files

rtc: davinci: check BUSY bit before set TC registers



To write correct data to the TC registers, the STATUS register must be
read until the BUSY bit is equal to zero. Once the BUSY flag is zero,
there is a 15 μs access period in which the TC registers can be
programmed.
The rtc_wait_not_busy() has been inspired by the Kernel.
Signed-off-by: default avatarDario Binacchi <dariobin@libero.it>
Signed-off-by: Lokesh Vutla's avatarLokesh Vutla <lokeshvutla@ti.com>
Link: https://lore.kernel.org/r/20210602203805.11494-5-dariobin@libero.it
parent 82a456a0
......@@ -16,19 +16,39 @@
#define RTC_BASE DAVINCI_RTC_BASE
#endif
int rtc_get(struct rtc_time *tmp)
static int davinci_rtc_wait_not_busy(struct davinci_rtc *rtc)
{
struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
unsigned long sec, min, hour, mday, wday, mon_cent, year;
unsigned long status;
int count;
u8 status;
status = readb(&rtc->status);
if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) {
printf("RTC doesn't run\n");
return -1;
}
if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY)
udelay(20);
/* BUSY may stay active for 1/32768 second (~30 usec) */
for (count = 0; count < 50; count++) {
if (!(status & RTC_STATE_BUSY))
break;
udelay(1);
status = readb(&rtc->status);
}
/* now we have ~15 usec to read/write various registers */
return 0;
}
int rtc_get(struct rtc_time *tmp)
{
struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
unsigned long sec, min, hour, mday, wday, mon_cent, year;
int ret;
ret = davinci_rtc_wait_not_busy(rtc);
if (ret)
return ret;
sec = readb(&rtc->second);
min = readb(&rtc->minutes);
......@@ -63,10 +83,12 @@ int rtc_get(struct rtc_time *tmp)
int rtc_set(struct rtc_time *tmp)
{
struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
int ret;
ret = davinci_rtc_wait_not_busy(rtc);
if (ret)
return ret;
debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
writeb(bin2bcd(tmp->tm_year % 100), &rtc->year);
writeb(bin2bcd(tmp->tm_mon), &rtc->month);
......@@ -75,6 +97,11 @@ int rtc_set(struct rtc_time *tmp)
writeb(bin2bcd(tmp->tm_hour), &rtc->hours);
writeb(bin2bcd(tmp->tm_min), &rtc->minutes);
writeb(bin2bcd(tmp->tm_sec), &rtc->second);
debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
return 0;
}
......
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