On attach check if clock is running, mark it invalid if not. Return

error from gettime method if clock is not valid.  Mark clock as valid
on settime.

Report more debugging info.
This commit is contained in:
uwe 2007-03-30 00:32:58 +00:00
parent a4d20321d9
commit 3ce2a9cb4d
1 changed files with 73 additions and 22 deletions

View File

@ -35,7 +35,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rtc.c,v 1.1 2006/09/20 00:41:11 uwe Exp $"); __KERNEL_RCSID(0, "$NetBSD: rtc.c,v 1.2 2007/03/30 00:32:58 uwe Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/kernel.h> #include <sys/kernel.h>
@ -50,10 +50,15 @@ __KERNEL_RCSID(0, "$NetBSD: rtc.c,v 1.1 2006/09/20 00:41:11 uwe Exp $");
#include <sh3/rtcreg.h> #include <sh3/rtcreg.h>
#if defined(DEBUG) && !defined(RTC_DEBUG)
#define RTC_DEBUG
#endif
struct rtc_softc { struct rtc_softc {
struct device sc_dev; struct device sc_dev;
int sc_valid;
struct todr_chip_handle sc_todr; struct todr_chip_handle sc_todr;
}; };
@ -82,41 +87,67 @@ static void
rtc_attach(struct device *parent, struct device *self, void *aux) rtc_attach(struct device *parent, struct device *self, void *aux)
{ {
struct rtc_softc *sc = (void *)self; struct rtc_softc *sc = (void *)self;
uint8_t r;
#ifdef RTC_DEBUG
char bits[128];
#endif
printf("\n"); printf("\n");
/* Make sure RTC is started */ r = _reg_read_1(SH_(RCR2));
_reg_write_1(SH_(RCR2), SH_RCR2_ENABLE | SH_RCR2_START);
#ifdef RTC_DEBUG #ifdef RTC_DEBUG
{ printf("%s: RCR2=%s\n", sc->sc_dev.dv_xname,
struct clock_ymdhms dt; bitmask_snprintf(r, SH_RCR2_BITS, bits, sizeof(bits)));
int error;
error = rtc_gettime_ymdhms(NULL, &dt);
if (error)
printf("%s: error %d\n", sc->sc_dev.dv_xname, error);
else
printf("%s: %04d-%02d-%02d %02d:%02d:%02d\n",
sc->sc_dev.dv_xname,
dt.dt_year, dt.dt_mon, dt.dt_day,
dt.dt_hour, dt.dt_min, dt.dt_sec);
}
#endif #endif
/* Was the clock running? */
if ((r & (SH_RCR2_ENABLE | SH_RCR2_START)) == (SH_RCR2_ENABLE
| SH_RCR2_START))
sc->sc_valid = 1;
else {
sc->sc_valid = 0;
printf("%s: WARNING: clock was stopped\n",
sc->sc_dev.dv_xname);
}
/* Disable carry and alarm interrupts */
_reg_write_1(SH_(RCR1), 0);
/* Clock runs, no periodic interrupts, no 30-sec adjustment */
_reg_write_1(SH_(RCR2), SH_RCR2_ENABLE | SH_RCR2_START);
sc->sc_todr.cookie = sc; sc->sc_todr.cookie = sc;
sc->sc_todr.todr_gettime_ymdhms = rtc_gettime_ymdhms; sc->sc_todr.todr_gettime_ymdhms = rtc_gettime_ymdhms;
sc->sc_todr.todr_settime_ymdhms = rtc_settime_ymdhms; sc->sc_todr.todr_settime_ymdhms = rtc_settime_ymdhms;
todr_attach(&sc->sc_todr); todr_attach(&sc->sc_todr);
#ifdef RTC_DEBUG
{
struct clock_ymdhms dt;
rtc_gettime_ymdhms(&sc->sc_todr, &dt);
}
#endif
} }
static int static int
rtc_gettime_ymdhms(todr_chip_handle_t h, struct clock_ymdhms *dt) rtc_gettime_ymdhms(todr_chip_handle_t h, struct clock_ymdhms *dt)
{ {
struct rtc_softc *sc = h->cookie;
unsigned int year; unsigned int year;
int retry = 8; int retry = 8;
if (!sc->sc_valid) {
#ifdef RTC_DEBUG
printf("RTC: gettime: not valid\n");
/* but proceed and read/print it anyway */
#else
return EIO;
#endif
}
/* disable carry interrupt */ /* disable carry interrupt */
_reg_bclr_1(SH_(RCR1), SH_RCR1_CIE); _reg_bclr_1(SH_(RCR1), SH_RCR1_CIE);
@ -145,13 +176,26 @@ rtc_gettime_ymdhms(todr_chip_handle_t h, struct clock_ymdhms *dt)
#undef RTCGET #undef RTCGET
} while ((_reg_read_1(SH_(RCR1)) & SH_RCR1_CF) && --retry > 0); } while ((_reg_read_1(SH_(RCR1)) & SH_RCR1_CF) && --retry > 0);
if (retry == 0) if (retry == 0) {
#ifdef RTC_DEBUG
printf("RTC: gettime: retry failed\n");
#endif
return EIO; return EIO;
}
dt->dt_year += 1900; dt->dt_year += 1900;
if (dt->dt_year < POSIX_BASE_YEAR) if (dt->dt_year < POSIX_BASE_YEAR)
dt->dt_year += 100; dt->dt_year += 100;
#ifdef RTC_DEBUG
printf("RTC: gettime: %04d-%02d-%02d %02d:%02d:%02d\n",
dt->dt_year, dt->dt_mon, dt->dt_day,
dt->dt_hour, dt->dt_min, dt->dt_sec);
if (!sc->sc_valid)
return EIO;
#endif
return 0; return 0;
} }
@ -159,16 +203,16 @@ rtc_gettime_ymdhms(todr_chip_handle_t h, struct clock_ymdhms *dt)
static int static int
rtc_settime_ymdhms(todr_chip_handle_t h, struct clock_ymdhms *dt) rtc_settime_ymdhms(todr_chip_handle_t h, struct clock_ymdhms *dt)
{ {
struct rtc_softc *sc = h->cookie;
unsigned int year; unsigned int year;
uint8_t r; uint8_t r;
year = TOBCD(dt->dt_year % 100); year = TOBCD(dt->dt_year % 100);
/* stop clock */
r = _reg_read_1(SH_(RCR2)); r = _reg_read_1(SH_(RCR2));
r |= SH_RCR2_RESET;
r &= ~SH_RCR2_START; /* stop clock */
_reg_write_1(SH_(RCR2), r); _reg_write_1(SH_(RCR2), (r & ~SH_RCR2_START) | SH_RCR2_RESET);
/* set time */ /* set time */
if (CPU_IS_SH3) if (CPU_IS_SH3)
@ -189,7 +233,14 @@ rtc_settime_ymdhms(todr_chip_handle_t h, struct clock_ymdhms *dt)
#undef RTCSET #undef RTCSET
/* start clock */ /* start clock */
_reg_write_1(SH_(RCR2), r | SH_RCR2_START); _reg_write_1(SH_(RCR2), r);
sc->sc_valid = 1;
#ifdef RTC_DEBUG
printf("RTC: settime: %04d-%02d-%02d %02d:%02d:%02d\n",
dt->dt_year, dt->dt_mon, dt->dt_day,
dt->dt_hour, dt->dt_min, dt->dt_sec);
#endif
return 0; return 0;
} }