summaryrefslogtreecommitdiff
path: root/sys/arch/atari/dev/clock.c
diff options
context:
space:
mode:
authorjoerg <joerg@NetBSD.org>2008-01-08 18:04:15 +0000
committerjoerg <joerg@NetBSD.org>2008-01-08 18:04:15 +0000
commit732cd3c8a0b8e88d75ac6ff6b198bc4cbe531bd9 (patch)
tree422cab1b77827097c12a9642398f96911f7b81b3 /sys/arch/atari/dev/clock.c
parent30cd7dc199b73a41d51666fe7f2b3f1e21da9de3 (diff)
Convert Atari to generic TODR and timecounter.
Diffstat (limited to 'sys/arch/atari/dev/clock.c')
-rw-r--r--sys/arch/atari/dev/clock.c153
1 files changed, 80 insertions, 73 deletions
diff --git a/sys/arch/atari/dev/clock.c b/sys/arch/atari/dev/clock.c
index 5a425de8428..d4a5ec96b88 100644
--- a/sys/arch/atari/dev/clock.c
+++ b/sys/arch/atari/dev/clock.c
@@ -1,4 +1,4 @@
-/* $NetBSD: clock.c,v 1.39 2008/01/03 01:02:04 joerg Exp $ */
+/* $NetBSD: clock.c,v 1.40 2008/01/08 18:04:16 joerg Exp $ */
/*
* Copyright (c) 1982, 1990 The Regents of the University of California.
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.39 2008/01/03 01:02:04 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.40 2008/01/08 18:04:16 joerg Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -87,6 +87,7 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.39 2008/01/03 01:02:04 joerg Exp $");
#include <sys/conf.h>
#include <sys/proc.h>
#include <sys/event.h>
+#include <sys/timetc.h>
#include <dev/clock_subr.h>
@@ -101,6 +102,9 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.39 2008/01/03 01:02:04 joerg Exp $");
#include <machine/profile.h>
#endif
+static int atari_rtc_get(todr_chip_handle_t, struct clock_ymdhms *);
+static int atari_rtc_set(todr_chip_handle_t, struct clock_ymdhms *);
+
/*
* The MFP clock runs at 2457600Hz. We use a {system,stat,prof}clock divider
* of 200. Therefore the timer runs at an effective rate of:
@@ -108,6 +112,19 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.39 2008/01/03 01:02:04 joerg Exp $");
*/
#define CLOCK_HZ 12288
+static u_int clk_getcounter(struct timecounter *);
+
+static struct timecounter clk_timecounter = {
+ clk_getcounter, /* get_timecount */
+ 0, /* no poll_pps */
+ ~0u, /* counter_mask */
+ CLOCK_HZ, /* frequency */
+ "clock", /* name, overriden later */
+ 100, /* quality */
+ NULL, /* prev */
+ NULL, /* next */
+};
+
/*
* Machine-dependent clock routines.
*
@@ -147,7 +164,6 @@ const struct cdevsw rtc_cdevsw = {
void statintr __P((struct clockframe));
-static u_long gettod __P((void));
static int twodigits __P((char *, int));
static int divisor; /* Systemclock divisor */
@@ -186,12 +202,6 @@ void *auxp;
MFP->mf_tbdr = 0;
MFP->mf_tbcr = T_Q004; /* Start timer */
- /*
- * Initialize the time structure
- */
- time.tv_sec = 0;
- time.tv_usec = 0;
-
return 0;
}
if(!strcmp("clock", auxp))
@@ -207,6 +217,13 @@ struct device *pdp, *dp;
void *auxp;
{
struct clock_softc *sc = (void *)dp;
+ static struct todr_chip_handle tch;
+
+ tch.todr_gettime_ymdhms = atari_rtc_get;
+ tch.todr_settime_ymdhms = atari_rtc_set;
+ tch.todr_setwen = NULL;
+
+ todr_attach(&tch);
sc->sc_flags = 0;
@@ -221,6 +238,9 @@ void *auxp;
MFP->mf_iera &= ~IA_TIMA; /* Disable timer interrupts */
MFP->mf_tadr = divisor; /* Set divisor */
+ clk_timecounter.tc_frequency = CLOCK_HZ;
+ tc_init(&clk_timecounter);
+
if (hz != 48 && hz != 64 && hz != 96) { /* XXX */
printf (": illegal value %d for systemclock, reset to %d\n\t",
hz, 64);
@@ -296,32 +316,24 @@ statintr(frame)
}
#endif /* STATCLOCK */
-/*
- * Returns number of usec since last recorded clock "tick"
- * (i.e. clock interrupt).
- */
-long
-clkread()
+static u_int
+clk_getcounter(struct timecounter *tc)
{
- u_int delta;
- u_char ipra, tadr;
+ u_int delta;
+ u_char ipra, tadr;
+ int s, cur_hardclock;
- /*
- * Note: Order is important!
- * By reading 'ipra' before 'tadr' and caching the data, I try to avoid
- * the situation that very low value in 'tadr' is read (== a big delta)
- * while also acccounting for a full 'tick' because the counter went
- * through zero during the calculations.
- */
- ipra = MFP->mf_ipra; tadr = MFP->mf_tadr;
+ s = splhigh();
+ ipra = MFP->mf_ipra;
+ tadr = MFP->mf_tadr;
+ delta = divisor - tadr;
- delta = ((divisor - tadr) * tick) / divisor;
- /*
- * Account for pending clock interrupts
- */
- if(ipra & IA_TIMA)
- return(delta + tick);
- return(delta);
+ if (ipra & IA_TIMA)
+ delta += divisor;
+ cur_hardclock = hardclock_ticks;
+ splx(s);
+
+ return (divisor - tadr) + divisor * cur_hardclock;
}
#define TIMB_FREQ 614400
@@ -426,38 +438,12 @@ u_int regno, value;
((struct rtc *)rtc)->rtc_data = value;
}
-/*
- * Initialize the time of day register, assuming the RTC runs in UTC.
- * Since we've got the 'rtc' device, this functionality should be removed
- * from the kernel. The only problem to be solved before that can happen
- * is the possibility of init(1) providing a way (rc.boot?) to set
- * the RTC before single-user mode is entered.
- */
-void
-inittodr(base)
-time_t base;
-{
- /* Battery clock does not store usec's, so forget about it. */
- time.tv_sec = gettod();
- time.tv_usec = 0;
-}
-
-/*
- * Function turned into a No-op. Use /dev/rtc to update the RTC.
- */
-void
-resettodr()
-{
- return;
-}
-
-static u_long
-gettod()
+static int
+atari_rtc_get(todr_chip_handle_t todr, struct clock_ymdhms *dtp)
{
int sps;
mc_todregs clkregs;
u_int regb;
- struct clock_ymdhms dt;
sps = splhigh();
regb = mc146818_read(RTC, MC_REGB);
@@ -472,27 +458,48 @@ gettod()
return(0);
}
if(clkregs[MC_SEC] > 59)
- return(0);
+ return -1;
if(clkregs[MC_MIN] > 59)
- return(0);
+ return -1;
if(clkregs[MC_HOUR] > 23)
- return(0);
+ return -1;
if(range_test(clkregs[MC_DOM], 1, 31))
- return(0);
+ return -1;
if (range_test(clkregs[MC_MONTH], 1, 12))
- return(0);
+ return -1;
if(clkregs[MC_YEAR] > 99)
- return(0);
+ return -1;
+
+ dtp->dt_year = clkregs[MC_YEAR] + GEMSTARTOFTIME;
+ dtp->dt_mon = clkregs[MC_MONTH];
+ dtp->dt_day = clkregs[MC_DOM];
+ dtp->dt_hour = clkregs[MC_HOUR];
+ dtp->dt_min = clkregs[MC_MIN];
+ dtp->dt_sec = clkregs[MC_SEC];
+
+ return 0;
+}
+
+static int
+atari_rtc_set(todr_chip_handle_t todr, struct clock_ymdhms *dtp)
+{
+ int s;
+ mc_todregs clkregs;
- dt.dt_year = clkregs[MC_YEAR] + GEMSTARTOFTIME;
- dt.dt_mon = clkregs[MC_MONTH];
- dt.dt_day = clkregs[MC_DOM];
- dt.dt_hour = clkregs[MC_HOUR];
- dt.dt_min = clkregs[MC_MIN];
- dt.dt_sec = clkregs[MC_SEC];
+ clkregs[MC_YEAR] = dtp->dt_year - GEMSTARTOFTIME;
+ clkregs[MC_MONTH] = dtp->dt_mon;
+ clkregs[MC_DOM] = dtp->dt_day;
+ clkregs[MC_HOUR] = dtp->dt_hour;
+ clkregs[MC_MIN] = dtp->dt_min;
+ clkregs[MC_SEC] = dtp->dt_sec;
- return(clock_ymdhms_to_secs(&dt));
+ s = splclock();
+ MC146818_PUTTOD(RTC, &clkregs);
+ splx(s);
+
+ return 0;
}
+
/***********************************************************************
* RTC-device support *
***********************************************************************/