Subject: Re: generic TODR changes for shark and ofppc
To: Garrett D'Amore <garrett_damore@tadpole.com>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-arm
Date: 09/12/2006 00:13:58
This is a multi-part message in MIME format.
--------------090900010404040503010107
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
My apologies, the diff didn't have everything. I missed the most
important files, which was ofrtc, in a different directory. New diff
attached.
Garrett D'Amore wrote:
> Attached, find a diff that significantly changes the real-time-clock
> support for shark and ofppc.
>
> First, the old oftodclock.c hackery is gone, replaced by dev/ofw/ofrtc.
>
> The old ofrtc.c is changed, it no longer supports character entry
> points, but instead uses the new todr framework.
>
> One side effect of this is that ofppc should gain RTC clock support it
> lacked before.
>
> This has been tested and shown to work on shark.
>
>
> ------------------------------------------------------------------------
>
>
--------------090900010404040503010107
Content-Type: text/x-patch;
name="shark.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="shark.diff"
Index: sys/arch/shark/conf/files.shark
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/conf/files.shark,v
retrieving revision 1.10
diff -d -p -u -r1.10 files.shark
--- sys/arch/shark/conf/files.shark 11 Dec 2005 12:19:02 -0000 1.10
+++ sys/arch/shark/conf/files.shark 12 Sep 2006 07:13:05 -0000
@@ -43,7 +43,6 @@ include "dev/ofw/files.ofw"
include "arch/arm/ofw/files.ofw"
attach ofbus at root with ofbus_root
file arch/shark/ofw/ofw.c
-file arch/shark/ofw/oftodclock.c
# console initialization
file arch/shark/shark/consinit.c
Index: sys/arch/shark/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/include/types.h,v
retrieving revision 1.3
diff -d -p -u -r1.3 types.h
--- sys/arch/shark/include/types.h 3 Sep 2006 13:51:23 -0000 1.3
+++ sys/arch/shark/include/types.h 12 Sep 2006 07:13:05 -0000
@@ -9,5 +9,6 @@
#define __ARM_FIQ_INDIRECT
#define __HAVE_DEVICE_REGISTER
+#define __HAVE_GENERIC_TODR
#endif
Index: sys/arch/shark/ofw/oftodclock.c
===================================================================
RCS file: sys/arch/shark/ofw/oftodclock.c
diff -N sys/arch/shark/ofw/oftodclock.c
--- sys/arch/shark/ofw/oftodclock.c 11 Dec 2005 12:19:05 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,290 +0,0 @@
-/* $NetBSD: oftodclock.c,v 1.5 2005/12/11 12:19:05 christos Exp $ */
-
-/*
- * Copyright 1997
- * Digital Equipment Corporation. All rights reserved.
- *
- * This software is furnished under license and may be used and
- * copied only in accordance with the following terms and conditions.
- * Subject to these conditions, you may download, copy, install,
- * use, modify and distribute this software in source and/or binary
- * form. No title or ownership is transferred hereby.
- *
- * 1) Any source code used, modified or distributed must reproduce
- * and retain this copyright notice and list of conditions as
- * they appear in the source file.
- *
- * 2) No right is granted to use any trade name, trademark, or logo of
- * Digital Equipment Corporation. Neither the "Digital Equipment
- * Corporation" name nor any trademark or logo of Digital Equipment
- * Corporation may be used to endorse or promote products derived
- * from this software without the prior written permission of
- * Digital Equipment Corporation.
- *
- * 3) This software is provided "AS-IS" and any express or implied
- * warranties, including but not limited to, any implied warranties
- * of merchantability, fitness for a particular purpose, or
- * non-infringement are disclaimed. In no event shall DIGITAL be
- * liable for any damages whatsoever, and in particular, DIGITAL
- * shall not be liable for special, indirect, consequential, or
- * incidental damages or damages for lost profits, loss of
- * revenue or loss of use, whether such damages arise in contract,
- * negligence, tort, under statute, in equity, at law or otherwise,
- * even if advised of the possibility of such damage.
- */
-
-/*
- * Real time clock (RTC) functions using OFW /rtc device:
- * inittodr()
- * resettodr()
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: oftodclock.c,v 1.5 2005/12/11 12:19:05 christos Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-
-#include <dev/ofw/openfirm.h>
-
-/* The OFW RTC interface, straight from wmb:
-
-selftest ( -- error? )
- Designed to be called from the "test" user interface command, e.g.
- test /rtc
- which displays a message if the test fails.
- Basically all this does is to check the battery.
-
-check-battery ( -- error? )
- Called from an open instance; returns non-zero if the battery
- is dead. Also displays a message to that effect, which it probably
- should not do.
-
-set-time ( s m h d m y -- )
-get-time ( -- s m h d m y )
- Called from an open instance.
- seconds: 0-59
- minutes: 0-59
- hours: 0-23
- day: 1-31
- month: 1-12
- year: e.g. 1997
-*/
-
-#define OFRTC_SEC 0
-#define OFRTC_MIN 1
-#define OFRTC_HR 2
-#define OFRTC_DOM 3
-#define OFRTC_MON 4
-#define OFRTC_YR 5
-
-static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-#define SECMIN ((unsigned)60) /* seconds per minute */
-#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */
-#define SECDAY ((unsigned)(24*SECHOUR)) /* seconds per day */
-#define SECYR ((unsigned)(365*SECDAY)) /* seconds per common year */
-
-static int yeartoday(int);
-static void setthetime(time_t, int);
-
-static int
-yeartoday(year)
- int year;
-{
-
- return ((year % 4) ? 365 : 366);
-}
-
-static int timeset = 0;
-
-static void
-setthetime(thetime, warning)
- time_t thetime;
- int warning;
-{
-
- timeset = 1;
- time.tv_sec = thetime;
- time.tv_usec = 0;
-
- if (warning)
- printf("WARNING: CHECK AND RESET THE DATE!\n");
-}
-
-static int ofrtc_phandle;
-static int ofrtc_ihandle = 0;
-static int ofrtcinited = 0;
-
-static void
-ofrtcinit(void)
-{
- char buf[256];
- int l;
- int chosen;
-
- if (ofrtcinited) return;
-
- if ((ofrtc_phandle = OF_finddevice("/rtc")) == -1)
- panic("OFW RTC: no package");
-
- if ((l = OF_getprop(ofrtc_phandle, "device_type", buf, sizeof buf - 1)) < 0)
- panic("OFW RTC: no device type");
-
- if ((l >= sizeof buf) || strcmp(buf, "rtc"))
- panic("OFW RTC: bad device type");
-
- if ((chosen = OF_finddevice("/chosen")) == -1 ||
- OF_getprop(chosen, "clock", &ofrtc_ihandle, sizeof(int)) < 0) {
- ofrtc_ihandle = 0;
- return;
- }
-
- ofrtc_ihandle = of_decode_int((unsigned char *)&ofrtc_ihandle);
-
- ofrtcinited = 1;
-}
-
-static int
-ofrtcstatus(void)
-{
- char status[256];
- int l;
-
- if ((ofrtc_ihandle == 0) || (l = OF_getprop(ofrtc_phandle, "status",
- status, sizeof status - 1)) < 0) {
- printf("OFW RTC: old firmware does not support RTC\n");
- return 0;
- }
-
- status[sizeof status - 1] = 0; /* always null terminate */
-
- if (strcmp(status, "okay")) { /* something is wrong */
- printf("RTC: %s\n", status);
- return 0;
- }
-
- return 1; /* all systems are go */
-}
-
-/*
- * Initialize the time of day register, based on the time base which is, e.g.
- * from a filesystem.
- */
-void
-inittodr(base)
- time_t base;
-{
- time_t n;
- int i, days = 0;
- int date[6];
- int yr;
-
- /*
- * We mostly ignore the suggested time and go for the RTC clock time
- * stored in the CMOS RAM. If the time can't be obtained from the
- * CMOS, or if the time obtained from the CMOS is 5 or more years
- * less than the suggested time, we used the suggested time. (In
- * the latter case, it's likely that the CMOS battery has died.)
- */
-
- if (base < 25*SECYR) { /* if before 1995, something's odd... */
- printf("WARNING: preposterous time in file system\n");
- /* read the system clock anyway */
- /* happy b-day sarina */
- base = 26*SECYR + 24*SECDAY + 18 * SECHOUR + 58 * SECMIN;
- }
-
- ofrtcinit();
-
- if (!ofrtcstatus()) {
- setthetime(base, 1);
- return;
- }
-
- if (OF_call_method("get-time", ofrtc_ihandle, 0, 6,
- date, date + 1, date + 2, date + 3, date + 4, date + 5)) {
- printf("OFW RTC: get-time failed\n");
- setthetime(base, 1);
- return;
- }
-
- n = date[OFRTC_SEC];
- n += date[OFRTC_MIN] * SECMIN;
- n += date[OFRTC_HR] * SECHOUR;
- n += (date[OFRTC_DOM] - 1) * SECDAY;
-
- yr = date[OFRTC_YR];
-
- if (yeartoday(yr) == 366)
- month[1] = 29;
- for (i = date[OFRTC_MON] - 2; i >= 0; i--)
- days += month[i];
- month[1] = 28;
- for (i = 1970; i < yr; i++)
- days += yeartoday(i);
- n += days * 3600 * 24;
-
- n += rtc_offset * 60;
-
- if (base < n - 5*SECYR)
- printf("WARNING: file system time much less than clock time\n");
-
- else if (base > n + 5*SECYR) {
- printf("WARNING: clock time much less than file system time\n");
- printf("WARNING: using file system time\n");
- setthetime(base, 1);
- return;
- }
-
- setthetime(n, 0);
-}
-
-/*
- * Reset the clock.
- */
-void
-resettodr(void)
-{
- time_t n;
- int diff, i, j;
- int sec, minute, hr, dom, mon, yr;
-
- /* old version of the firmware? */
- if (ofrtc_ihandle == 0) return;
-
- /*
- * We might have been called by boot() due to a crash early
- * on. Don't reset the clock chip in this case.
- */
- if (!timeset)
- return;
-
- diff = rtc_offset * 60;
- n = (time.tv_sec - diff) % (3600 * 24); /* hrs+mins+secs */
- sec = n % 60;
- n /= 60;
- minute = n % 60;
- hr = n / 60;
-
- n = (time.tv_sec - diff) / (3600 * 24); /* days */
-
- for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j))
- n -= i;
-
- yr = j;
-
- if (i == 366)
- month[1] = 29;
- for (i = 0; n >= month[i]; i++)
- n -= month[i];
- month[1] = 28;
- mon = ++i;
- dom = ++n;
-
- if (OF_call_method("set-time", ofrtc_ihandle, 6, 0,
- sec, minute, hr, dom, mon, yr))
- printf("OFW RTC: set-time failed\n");
-}
Index: sys/arch/ofppc/conf/majors.ofppc
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/conf/majors.ofppc,v
retrieving revision 1.19
diff -d -p -u -r1.19 majors.ofppc
--- sys/arch/ofppc/conf/majors.ofppc 11 Dec 2005 12:18:29 -0000 1.19
+++ sys/arch/ofppc/conf/majors.ofppc 12 Sep 2006 07:13:05 -0000
@@ -12,7 +12,7 @@ device-major log char 5
device-major swap char 6 block 1 vmswap
device-major ofcons char 7 ofcons
device-major ofdisk char 8 block 0 ofdisk
-device-major ofrtc char 9 ofrtc
+#device-major ofrtc char 9 ofrtc
device-major bpf char 10 bpfilter
device-major rnd char 11 rnd
device-major raid char 12 block 2 raid
Index: sys/arch/ofppc/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/include/types.h,v
retrieving revision 1.5
diff -d -p -u -r1.5 types.h
--- sys/arch/ofppc/include/types.h 22 Sep 2002 08:31:00 -0000 1.5
+++ sys/arch/ofppc/include/types.h 12 Sep 2006 07:13:05 -0000
@@ -3,3 +3,4 @@
#include <powerpc/types.h>
#define __HAVE_DEVICE_REGISTER
+#define __HAVE_GENERIC_TODR
Index: sys/arch/ofppc/ofppc/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/ofppc/clock.c,v
retrieving revision 1.12
diff -d -p -u -r1.12 clock.c
--- sys/arch/ofppc/ofppc/clock.c 24 Dec 2005 22:45:36 -0000 1.12
+++ sys/arch/ofppc/ofppc/clock.c 12 Sep 2006 07:13:05 -0000
@@ -50,28 +50,6 @@ static u_long ns_per_tick = 320;
long ticks_per_intr;
volatile u_long lasttb;
-/*
- * For now we let the machine run with boot time, not changing the clock
- * at inittodr at all.
- *
- * We might continue to do this due to setting up the real wall clock with
- * a user level utility in the future.
- */
-/* ARGSUSED */
-void
-inittodr(base)
- time_t base;
-{
-}
-
-/*
- * Similar to the above
- */
-void
-resettodr()
-{
-}
-
void
decr_intr(frame)
struct clockframe *frame;
Index: sys/dev/ofw/ofrtc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ofw/ofrtc.c,v
retrieving revision 1.19
diff -d -p -u -r1.19 ofrtc.c
--- sys/dev/ofw/ofrtc.c 29 Mar 2006 07:10:25 -0000 1.19
+++ sys/dev/ofw/ofrtc.c 12 Sep 2006 07:13:05 -0000
@@ -30,6 +30,38 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and conditions.
+ * Subject to these conditions, you may download, copy, install,
+ * use, modify and distribute this software in source and/or binary
+ * form. No title or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions as
+ * they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of
+ * Digital Equipment Corporation. Neither the "Digital Equipment
+ * Corporation" name nor any trademark or logo of Digital Equipment
+ * Corporation may be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied
+ * warranties, including but not limited to, any implied warranties
+ * of merchantability, fitness for a particular purpose, or
+ * non-infringement are disclaimed. In no event shall DIGITAL be
+ * liable for any damages whatsoever, and in particular, DIGITAL
+ * shall not be liable for special, indirect, consequential, or
+ * incidental damages or damages for lost profits, loss of
+ * revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise,
+ * even if advised of the possibility of such damage.
+ */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ofrtc.c,v 1.19 2006/03/29 07:10:25 thorpej Exp $");
@@ -40,31 +72,31 @@ __KERNEL_RCSID(0, "$NetBSD: ofrtc.c,v 1.
#include <sys/conf.h>
#include <sys/event.h>
+#include <dev/clock_subr.h>
#include <dev/ofw/openfirm.h>
+#define OFRTC_SEC 0
+#define OFRTC_MIN 1
+#define OFRTC_HR 2
+#define OFRTC_DOM 3
+#define OFRTC_MON 4
+#define OFRTC_YR 5
+
struct ofrtc_softc {
struct device sc_dev;
int sc_phandle;
int sc_ihandle;
+ struct todr_chip_handle sc_todr;
};
static int ofrtc_match(struct device *, struct cfdata *, void *);
static void ofrtc_attach(struct device *, struct device *, void *);
+static int ofrtc_gettod(todr_chip_handle_t, struct clock_ymdhms *);
+static int ofrtc_settod(todr_chip_handle_t, struct clock_ymdhms *);
CFATTACH_DECL(ofrtc, sizeof(struct ofrtc_softc),
ofrtc_match, ofrtc_attach, NULL, NULL);
-extern struct cfdriver ofrtc_cd;
-
-dev_type_open(ofrtc_open);
-dev_type_read(ofrtc_read);
-dev_type_write(ofrtc_write);
-
-const struct cdevsw ofrtc_cdevsw = {
- ofrtc_open, nullclose, ofrtc_read, ofrtc_write, noioctl,
- nostop, notty, nopoll, nommap, nokqfilter,
-};
-
static int
ofrtc_match(struct device *parent, struct cfdata *match, void *aux)
{
@@ -88,6 +120,7 @@ ofrtc_attach(struct device *parent, stru
struct ofrtc_softc *of = device_private(self);
struct ofbus_attach_args *oba = aux;
char name[32];
+ char path[256];
int l;
of->sc_phandle = oba->oba_phandle;
@@ -98,115 +131,74 @@ ofrtc_attach(struct device *parent, stru
if (l >= sizeof name)
l = sizeof name - 1;
name[l] = 0;
- printf(": %s\n", name);
-}
-int
-ofrtc_open(dev_t dev, int flags, int fmt, struct lwp *lwp)
-{
- struct ofrtc_softc *of;
- int unit = minor(dev);
- char path[256];
- int l;
-
- if (unit >= ofrtc_cd.cd_ndevs)
- return ENXIO;
- if (!(of = ofrtc_cd.cd_devs[unit]))
- return ENXIO;
if (!of->sc_ihandle) {
if ((l = OF_package_to_path(of->sc_phandle, path,
- sizeof path - 1)) < 0 ||
- l >= sizeof path)
- return ENXIO;
+ sizeof path - 1)) < 0 ||
+ l >= sizeof path) {
+ aprint_error(": cannot determine package path\n");
+ return;
+ }
path[l] = 0;
if (!(of->sc_ihandle = OF_open(path))) {
- if (of->sc_ihandle) {
- OF_close(of->sc_ihandle);
- of->sc_ihandle = 0;
- }
- return ENXIO;
- }
-
- }
-
- return 0;
-}
-
-static void
-twodigit(char *bp, int i)
-{
- *bp++ = i / 10 + '0';
- *bp = i % 10 + '0';
-}
-
-static int
-twodigits(char *bp)
-{
- int i;
+ aprint_error(": cannot open path\n");
+ return;
+ }
+ }
- i = *bp++ - '0';
- return i * 10 + *bp++ - '0';
+ of->sc_todr.todr_gettime_ymdhms = ofrtc_gettod;
+ of->sc_todr.todr_settime_ymdhms = ofrtc_settod;
+ of->sc_todr.cookie = of;
+ todr_attach(&of->sc_todr);
+ printf(": %s\n", name);
}
int
-ofrtc_read(dev_t dev, struct uio *uio, int flag)
+ofrtc_gettod(todr_chip_handle_t tch, struct clock_ymdhms *dt)
{
- struct ofrtc_softc *of = ofrtc_cd.cd_devs[minor(dev)];
+ struct ofrtc_softc *of = tch->cookie;
int date[6];
- char buf[14];
- int xlen;
- if (uio->uio_offset >= sizeof buf)
- return 0;
+ /*
+ * We mostly ignore the suggested time and go for the RTC clock time
+ * stored in the CMOS RAM. If the time can't be obtained from the
+ * CMOS, or if the time obtained from the CMOS is 5 or more years
+ * less than the suggested time, we used the suggested time. (In
+ * the latter case, it's likely that the CMOS battery has died.)
+ */
if (OF_call_method("get-time", of->sc_ihandle, 0, 6,
- date, date + 1, date + 2,
- date + 3, date + 4, date + 5))
+ date, date + 1, date + 2, date + 3, date + 4, date + 5)) {
return EIO;
+ }
- twodigit(buf, date[5] % 100);
- twodigit(buf + 2, date[4]);
- twodigit(buf + 4, date[3]);
- twodigit(buf + 6, date[2]);
- twodigit(buf + 8, date[1]);
- buf[10] = '.';
- twodigit(buf + 11, date[0]);
- buf[13] = '\n';
-
- xlen = sizeof(buf) - uio->uio_offset;
- if (xlen > uio->uio_resid)
- xlen = uio->uio_resid;
+ dt->dt_sec = date[OFRTC_SEC];
+ dt->dt_min = date[OFRTC_MIN];
+ dt->dt_hour = date[OFRTC_HR];
+ dt->dt_day = date[OFRTC_DOM];
+ dt->dt_mon = date[OFRTC_MON];
+ dt->dt_year = date[OFRTC_YR];
- return uiomove((caddr_t)buf, xlen, uio);
+ return 0;
}
int
-ofrtc_write(dev_t dev, struct uio *uio, int flag)
+ofrtc_settod(todr_chip_handle_t tch, struct clock_ymdhms *dt)
{
- struct ofrtc_softc *of = ofrtc_cd.cd_devs[minor(dev)];
- char buf[14];
- int cnt, year, error;
-
- /*
- * We require atomic updates!
- */
- cnt = uio->uio_resid;
- if (uio->uio_offset || (cnt != sizeof buf && cnt != sizeof buf - 1))
- return EINVAL;
-
- if ((error = uiomove((caddr_t)buf, sizeof buf, uio)) != 0)
- return error;
+ struct ofrtc_softc *of = tch->cookie;
+ int sec, minute, hr, dom, mon, yr;
- if (cnt == sizeof buf && buf[sizeof buf - 1] != '\n')
- return EINVAL;
+ sec = dt->dt_sec;
+ minute = dt->dt_min;
+ hr = dt->dt_hour;
+ dom = dt->dt_day;
+ mon = dt->dt_mon;
+ yr = dt->dt_year;
- year = twodigits(buf) + 1900;
- if (year < 1970)
- year += 100;
if (OF_call_method("set-time", of->sc_ihandle, 6, 0,
- twodigits(buf + 11), twodigits(buf + 8), twodigits(buf + 6),
- twodigits(buf + 4), twodigits(buf + 2), year))
+ sec, minute, hr, dom, mon, yr))
return EIO;
+
return 0;
}
--------------090900010404040503010107--