diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-03-23 03:14:44 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-03-23 03:14:44 +0000 |
commit | bbf5ab2a3952a5c4354849865f12845751a696fd (patch) | |
tree | ed01872a037bb02b93fe09e25506a6a9bb3aa2e3 /sys/powerpc/powermac/cuda.c | |
parent | a4998a854d601c5a59c9f51479188de6d29c8919 (diff) | |
download | FreeBSD-src-bbf5ab2a3952a5c4354849865f12845751a696fd.zip FreeBSD-src-bbf5ab2a3952a5c4354849865f12845751a696fd.tar.gz |
Get nexus(4) out of the RTC business. The interface used by nexus(4)
in Open Firmware was Apple-specific, and we have complete coverage of Apple
system controllers, so move RTC responsibilities into the system controller
drivers. This avoids interesting problems from manipulating these devices
through Open Firmware behind the backs of their drivers.
Obtained from: NetBSD
MFC after: 2 weeks
Diffstat (limited to 'sys/powerpc/powermac/cuda.c')
-rw-r--r-- | sys/powerpc/powermac/cuda.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/sys/powerpc/powermac/cuda.c b/sys/powerpc/powermac/cuda.c index 203889c..230298e 100644 --- a/sys/powerpc/powermac/cuda.c +++ b/sys/powerpc/powermac/cuda.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <sys/conf.h> #include <sys/kernel.h> +#include <sys/clock.h> #include <dev/ofw/ofw_bus.h> #include <dev/ofw/openfirm.h> @@ -55,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include <dev/adb/adb.h> +#include "clock_if.h" #include "cudavar.h" #include "viareg.h" @@ -72,6 +74,12 @@ static u_int cuda_poll(device_t dev); static void cuda_send_inbound(struct cuda_softc *sc); static void cuda_send_outbound(struct cuda_softc *sc); +/* + * Clock interface + */ +static int cuda_gettime(device_t dev, struct timespec *ts); +static int cuda_settime(device_t dev, struct timespec *ts); + static device_method_t cuda_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cuda_probe), @@ -90,6 +98,10 @@ static device_method_t cuda_methods[] = { DEVMETHOD(adb_hb_controller_poll, cuda_poll), DEVMETHOD(adb_hb_set_autopoll_mask, cuda_adb_autopoll), + /* Clock interface */ + DEVMETHOD(clock_gettime, cuda_gettime), + DEVMETHOD(clock_settime, cuda_settime), + { 0, 0 }, }; @@ -173,6 +185,7 @@ cuda_attach(device_t dev) sc->sc_polling = 0; sc->sc_state = CUDA_NOTREADY; sc->sc_autopoll = 0; + sc->sc_rtc = -1; STAILQ_INIT(&sc->sc_inq); STAILQ_INIT(&sc->sc_outq); @@ -236,6 +249,8 @@ cuda_attach(device_t dev) } } + clock_register(dev, 1000); + return (bus_generic_attach(dev)); } @@ -444,8 +459,18 @@ cuda_send_inbound(struct cuda_softc *sc) break; case CUDA_PSEUDO: mtx_lock(&sc->sc_mutex); - if (pkt->data[0] == CMD_AUTOPOLL) + switch (pkt->data[1]) { + case CMD_AUTOPOLL: sc->sc_autopoll = 1; + break; + case CMD_READ_RTC: + memcpy(&sc->sc_rtc, &pkt->data[2], + sizeof(sc->sc_rtc)); + wakeup(&sc->sc_rtc); + break; + case CMD_WRITE_RTC: + break; + } mtx_unlock(&sc->sc_mutex); break; case CUDA_ERROR: @@ -715,3 +740,41 @@ cuda_adb_autopoll(device_t dev, uint16_t mask) { return (0); } +#define DIFF19041970 2082844800 + +static int +cuda_gettime(device_t dev, struct timespec *ts) +{ + struct cuda_softc *sc = device_get_softc(dev); + uint8_t cmd[] = {CUDA_PSEUDO, CMD_READ_RTC}; + + mtx_lock(&sc->sc_mutex); + sc->sc_rtc = -1; + cuda_send(sc, 1, 2, cmd); + if (sc->sc_rtc == -1) + mtx_sleep(&sc->sc_rtc, &sc->sc_mutex, 0, "rtc", 100); + + ts->tv_sec = sc->sc_rtc - DIFF19041970; + ts->tv_nsec = 0; + mtx_unlock(&sc->sc_mutex); + + return (0); +} + +static int +cuda_settime(device_t dev, struct timespec *ts) +{ + struct cuda_softc *sc = device_get_softc(dev); + uint8_t cmd[] = {CUDA_PSEUDO, CMD_WRITE_RTC, 0, 0, 0, 0}; + uint32_t sec; + + sec = ts->tv_sec + DIFF19041970; + memcpy(&cmd[2], &sec, sizeof(sec)); + + mtx_lock(&sc->sc_mutex); + cuda_send(sc, 0, 6, cmd); + mtx_unlock(&sc->sc_mutex); + + return (0); +} + |