This diff converts octrtc(4) to use the <dev/clock_subr.h> interface,
to reduce use of <mips64/dev/clockvar.h>.

Some highlights for reviewing:

* dt.dt_year contains the actual year, while tt->year has base 1900.
* dt.dt_wday uses range 0-6, whereas tt->dow's range is 1-7.
* octrtc_gettime() no longer extracts day of week because
  clock_ymdhms_to_secs() does not use the value.

Testing is welcome. I don't have the hardware to test this myself.

OK?

Index: arch/octeon/dev/octrtc.c
===================================================================
RCS file: src/sys/arch/octeon/dev/octrtc.c,v
retrieving revision 1.11
diff -u -p -r1.11 octrtc.c
--- arch/octeon/dev/octrtc.c    20 Nov 2017 15:20:03 -0000      1.11
+++ arch/octeon/dev/octrtc.c    16 May 2020 16:04:12 -0000
@@ -21,7 +21,7 @@
 #include <sys/device.h>
 #include <sys/proc.h>
 
-#include <mips64/dev/clockvar.h>
+#include <dev/clock_subr.h>
 
 #include <machine/bus.h>
 #include <machine/autoconf.h>
@@ -37,6 +37,11 @@
 #define MIO_TWS_SW_TWSI_EXT    0x0001180000001018ULL
 #define OCTRTC_REG     0x68
 
+struct octrtc_softc {
+       struct device                   sc_dev;
+       struct todr_chip_handle         sc_todr;
+};
+
 struct cfdriver octrtc_cd = {
        NULL, "octrtc", DV_DULL
 };
@@ -44,15 +49,15 @@ struct cfdriver octrtc_cd = {
 int    octrtc_match(struct device *, void *, void *);
 void   octrtc_attach(struct device *, struct device *, void *);
 
-void   octrtc_gettime(void *, time_t, struct tod_time *);
+int    octrtc_gettime(struct todr_chip_handle *, struct timeval *);
 int    octrtc_read(uint8_t *, char);
 
-void   octrtc_settime(void *, struct tod_time *);
+int    octrtc_settime(struct todr_chip_handle *, struct timeval *);
 int    octrtc_write(uint8_t);
 
 
 struct cfattach octrtc_ca = {
-       sizeof(struct device), octrtc_match, octrtc_attach,
+       sizeof(struct octrtc_softc), octrtc_match, octrtc_attach,
 };
 
 
@@ -105,16 +110,18 @@ octrtc_attach(struct device *parent, str
 {
        struct octrtc_softc *sc = (struct octrtc_softc *)self;
 
-       sys_tod.tod_cookie = sc;
-       sys_tod.tod_get = octrtc_gettime;
-       sys_tod.tod_set = octrtc_settime;
+       sc->sc_todr.cookie = sc;
+       sc->sc_todr.todr_gettime = octrtc_gettime;
+       sc->sc_todr.todr_settime = octrtc_settime;
+       todr_attach(&sc->sc_todr);
 
        printf(": DS1337\n");
 }
 
-void
-octrtc_gettime(void *cookie, time_t unused, struct tod_time *tt)
+int
+octrtc_gettime(struct todr_chip_handle *handle, struct timeval *tv)
 {
+       struct clock_ymdhms dt;
        uint8_t tod[8];
        uint8_t check;
        int i, rc;
@@ -126,14 +133,14 @@ octrtc_gettime(void *cookie, time_t unus
                rc = octrtc_read(&tod[0], 1);   /* ia read */
                if (rc) {
                        DPRINTF(("octrtc_read(0) failed %d", rc));
-                       return;
+                       return EIO;
                }
 
                for (i = 1; i < 8; i++) {
                        rc = octrtc_read(&tod[i], 0);   /* current address */
                        if (rc) {
                                DPRINTF(("octrtc_read(%d) failed %d", i, rc));
-                               return;
+                               return EIO;
                        }
                        DPRINTF(("%#X ", tod[i]));
                }
@@ -141,8 +148,8 @@ octrtc_gettime(void *cookie, time_t unus
                /* Check against time-wrap */
                rc = octrtc_read(&check, 1);    /* ia read */
                if (rc) {
-                       DPRINTF(("octrtc_read(check) failed %d", i, rc));
-                       return;
+                       DPRINTF(("octrtc_read(check) failed %d", rc));
+                       return EIO;
                }
                if ((check & 0xf) == (tod[0] & 0xf))
                        break;
@@ -158,15 +165,24 @@ octrtc_gettime(void *cookie, time_t unus
            FROMBCD(tod[1] & 0x7f),     /* minute */
            FROMBCD(tod[0] & 0x7f)));   /* second */
 
-       tt->year = ((tod[5] & 0x80) ? 100 : 0) + FROMBCD(tod[6]);
-       tt->mon = FROMBCD(tod[5] & 0x1f);
-       tt->day = FROMBCD(tod[4] & 0x3f);
-       tt->dow = (tod[3] & 0x7);
-       tt->hour = FROMBCD(tod[2] & 0x3f);
+       dt.dt_year = ((tod[5] & 0x80) ? 2000 : 1900) + FROMBCD(tod[6]);
+       dt.dt_mon = FROMBCD(tod[5] & 0x1f);
+       dt.dt_day = FROMBCD(tod[4] & 0x3f);
+       dt.dt_hour = FROMBCD(tod[2] & 0x3f);
        if ((tod[2] & 0x40) && (tod[2] & 0x20)) /* adjust AM/PM format */
-               tt->hour = (tt->hour + 12) % 24;
-       tt->min = FROMBCD(tod[1] & 0x7f);
-       tt->sec = FROMBCD(tod[0] & 0x7f);
+               dt.dt_hour = (dt.dt_hour + 12) % 24;
+       dt.dt_min = FROMBCD(tod[1] & 0x7f);
+       dt.dt_sec = FROMBCD(tod[0] & 0x7f);
+
+       if (dt.dt_sec > 59 || dt.dt_min > 59 || dt.dt_hour > 23 ||
+           dt.dt_day > 31 || dt.dt_day == 0 ||
+           dt.dt_mon > 12 || dt.dt_mon == 0 ||
+           dt.dt_year < POSIX_BASE_YEAR)
+               return EINVAL;
+
+       tv->tv_sec = clock_ymdhms_to_secs(&dt);
+       tv->tv_usec = 0;
+       return 0;
 }
 
 int
@@ -217,46 +233,51 @@ again:
        return 0;
 }
 
-void
-octrtc_settime(void *cookie, struct tod_time *tt)
+int
+octrtc_settime(struct todr_chip_handle *handle, struct timeval *tv)
 {
+       struct clock_ymdhms dt;
        int nretries = 2;
        int rc, i;
        uint8_t tod[8];
        uint8_t check;
 
+       clock_secs_to_ymdhms(tv->tv_sec, &dt);
+
        DPRINTF(("settime: %d %d %d (%d) %02d:%02d:%02d\n",
-           tt->year, tt->mon, tt->day, tt->dow,
-           tt->hour, tt->min, tt->sec));
+           dt.dt_year, dt.dt_mon, dt.dt_day, dt.dt_wday,
+           dt.dt_hour, dt.dt_min, dt.dt_sec));
 
-       tod[0] = TOBCD(tt->sec);
-       tod[1] = TOBCD(tt->min);
-       tod[2] = TOBCD(tt->hour);
-       tod[3] = TOBCD(tt->dow);
-       tod[4] = TOBCD(tt->day);
-       tod[5] = TOBCD(tt->mon);
-       if (tt->year >= 100)
+       tod[0] = TOBCD(dt.dt_sec);
+       tod[1] = TOBCD(dt.dt_min);
+       tod[2] = TOBCD(dt.dt_hour);
+       tod[3] = TOBCD(dt.dt_wday + 1);
+       tod[4] = TOBCD(dt.dt_day);
+       tod[5] = TOBCD(dt.dt_mon);
+       if (dt.dt_year >= 2000)
                tod[5] |= 0x80;
-       tod[6] = TOBCD(tt->year % 100);
+       tod[6] = TOBCD(dt.dt_year % 100);
 
        while (nretries--) {
                for (i = 0; i < 7; i++) {
                        rc = octrtc_write(tod[i]);
                        if (rc) {
                                DPRINTF(("octrtc_write(%d) failed %d", i, rc));
-                               return;
+                               return EIO;
                        }
                }
 
                rc = octrtc_read(&check, 1);
                if (rc) {
                        DPRINTF(("octrtc_read(check) failed %d", rc));
-                       return;
+                       return EIO;
                }
 
                if ((check & 0xf) == (tod[0] & 0xf))
                        break;
        }
+
+       return 0;
 }
 
 int

Reply via email to