summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2008-04-21 04:41:37 +0000
committermarcel <marcel@FreeBSD.org>2008-04-21 04:41:37 +0000
commit22a42b41a7795363c5654789fa104aaba2f4e9ae (patch)
tree54e8fa035fe794a66a888a2a4f0a493c9f24c82d /sys
parent19c46f4f03d6363bbbe6543e3f4c0fe81f6f3da5 (diff)
downloadFreeBSD-src-22a42b41a7795363c5654789fa104aaba2f4e9ae.zip
FreeBSD-src-22a42b41a7795363c5654789fa104aaba2f4e9ae.tar.gz
Switch to using genclock. Have nexus double as clock device for
now. While here, add a proper attach() method to nexus. Requested by: phk
Diffstat (limited to 'sys')
-rw-r--r--sys/powerpc/aim/clock.c68
-rw-r--r--sys/powerpc/aim/nexus.c86
-rw-r--r--sys/powerpc/conf/DEFAULTS1
3 files changed, 78 insertions, 77 deletions
diff --git a/sys/powerpc/aim/clock.c b/sys/powerpc/aim/clock.c
index 1b3de58..0116475 100644
--- a/sys/powerpc/aim/clock.c
+++ b/sys/powerpc/aim/clock.c
@@ -83,10 +83,6 @@ static u_long ticks_per_sec = 12500000;
static long ticks_per_intr;
static volatile u_long lasttb;
-#define DIFF19041970 2082844800
-
-static int clockinitted = 0;
-
static timecounter_get_t decr_get_timecount;
static struct timecounter decr_timecounter = {
@@ -98,70 +94,6 @@ static struct timecounter decr_timecounter = {
};
void
-inittodr(time_t base)
-{
- time_t deltat;
- u_int rtc_time;
- struct timespec ts;
- phandle_t phandle;
- ihandle_t ihandle;
- char rtcpath[128];
- u_int rtcsecs;
-
- /*
- * If we can't read from RTC, use the fs time.
- */
- phandle = OF_finddevice("rtc");
- if (phandle != -1) {
- OF_package_to_path(phandle, rtcpath, sizeof(rtcpath));
- ihandle = OF_open(rtcpath);
- if (ihandle != -1) {
- if (OF_call_method("read-rtc", ihandle,
- 0, 1, &rtcsecs))
- printf("RTC call method error\n");
- else {
- ts.tv_sec = rtcsecs - DIFF19041970;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- return;
- }
- }
- }
-
- {
- ts.tv_sec = base;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- return;
- }
- clockinitted = 1;
- ts.tv_sec = rtc_time - DIFF19041970;
-
- deltat = ts.tv_sec - base;
- if (deltat < 0) {
- deltat = -deltat;
- }
- if (deltat < 2 * SECDAY) {
- tc_setclock(&ts);
- return;
- }
-
- printf("WARNING: clock %s %d days",
- ts.tv_sec < base ? "lost" : "gained", (int)(deltat / SECDAY));
-
- printf(" -- CHECK AND RESET THE DATE!\n");
-}
-
-/*
- * Similar to the above
- */
-void
-resettodr()
-{
-
-}
-
-void
decr_intr(struct trapframe *frame)
{
u_long tb;
diff --git a/sys/powerpc/aim/nexus.c b/sys/powerpc/aim/nexus.c
index e31ef61..0d9d0b6 100644
--- a/sys/powerpc/aim/nexus.c
+++ b/sys/powerpc/aim/nexus.c
@@ -60,6 +60,7 @@
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/bus.h>
+#include <sys/clock.h>
#include <sys/cons.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@@ -74,6 +75,7 @@
#include <sys/rman.h>
+#include "clock_if.h"
#include "ofw_bus_if.h"
#include "pic_if.h"
@@ -104,12 +106,13 @@ struct nexus_softc {
* Device interface
*/
static int nexus_probe(device_t);
-static void nexus_probe_nomatch(device_t, device_t);
+static int nexus_attach(device_t);
/*
* Bus interface
*/
static device_t nexus_add_child(device_t, int, const char *, int);
+static void nexus_probe_nomatch(device_t, device_t);
static int nexus_read_ivar(device_t, device_t, int, uintptr_t *);
static int nexus_write_ivar(device_t, device_t, int, uintptr_t);
static int nexus_setup_intr(device_t, device_t, struct resource *, int,
@@ -125,12 +128,21 @@ static int nexus_deactivate_resource(device_t, device_t, int, int,
static int nexus_release_resource(device_t, device_t, int, int,
struct resource *);
+/*
+ * OFW bus interface.
+ */
static phandle_t nexus_ofw_get_node(device_t, device_t);
static const char *nexus_ofw_get_name(device_t, device_t);
static const char *nexus_ofw_get_type(device_t, device_t);
static const char *nexus_ofw_get_compat(device_t, device_t);
/*
+ * Clock interface.
+ */
+static int nexus_gettime(device_t, struct timespec *);
+static int nexus_settime(device_t, struct timespec *);
+
+/*
* Local routines
*/
static device_t nexus_device_from_node(device_t, phandle_t);
@@ -138,7 +150,7 @@ static device_t nexus_device_from_node(device_t, phandle_t);
static device_method_t nexus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, nexus_probe),
- DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_attach, nexus_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
@@ -163,6 +175,10 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(ofw_bus_get_type, nexus_ofw_get_type),
DEVMETHOD(ofw_bus_get_compat, nexus_ofw_get_compat),
+ /* Clock interface */
+ DEVMETHOD(clock_gettime, nexus_gettime),
+ DEVMETHOD(clock_settime, nexus_settime),
+
{ 0, 0 }
};
@@ -179,6 +195,14 @@ DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
static int
nexus_probe(device_t dev)
{
+ bus_generic_probe(dev);
+ device_set_desc(dev, "Open Firmware Nexus device");
+ return (0);
+}
+
+static int
+nexus_attach(device_t dev)
+{
phandle_t root;
phandle_t child;
struct nexus_softc *sc;
@@ -201,11 +225,6 @@ nexus_probe(device_t dev)
panic("nexus_probe IRQ rman");
/*
- * Allow devices to identify
- */
- bus_generic_probe(dev);
-
- /*
* Now walk the OFW tree to locate top-level devices
*/
for (child = OF_child(root); child != 0; child = OF_peer(child)) {
@@ -214,8 +233,9 @@ nexus_probe(device_t dev)
(void)nexus_device_from_node(dev, child);
}
- device_set_desc(dev, "Open Firmware Nexus device");
- return (0);
+
+ clock_register(dev, 1000);
+ return (bus_generic_attach(dev));
}
static void
@@ -485,3 +505,51 @@ nexus_ofw_get_compat(device_t bus, device_t dev)
return (dinfo->ndi_compatible);
}
+
+#define DIFF19041970 2082844800
+
+static int
+nexus_gettime(device_t dev, struct timespec *ts)
+{
+ char path[128];
+ ihandle_t ih;
+ phandle_t ph;
+ u_int rtc;
+
+ ph = OF_finddevice("rtc");
+ if (ph == -1)
+ return (ENOENT);
+
+ OF_package_to_path(ph, path, sizeof(path));
+ ih = OF_open(path);
+ if (ih == -1)
+ return (ENXIO);
+
+ if (OF_call_method("read-rtc", ih, 0, 1, &rtc))
+ return (EIO);
+
+ ts->tv_sec = rtc - DIFF19041970;
+ ts->tv_nsec = 0;
+ return (0);
+}
+
+static int
+nexus_settime(device_t dev, struct timespec *ts)
+{
+ char path[128];
+ ihandle_t ih;
+ phandle_t ph;
+ u_int rtc;
+
+ ph = OF_finddevice("rtc");
+ if (ph == -1)
+ return (ENOENT);
+
+ OF_package_to_path(ph, path, sizeof(path));
+ ih = OF_open(path);
+ if (ih == -1)
+ return (ENXIO);
+
+ rtc = ts->tv_sec + DIFF19041970;
+ return ((OF_call_method("write-rtc", ih, 1, 0, rtc) != 0) ? EIO : 0);
+}
diff --git a/sys/powerpc/conf/DEFAULTS b/sys/powerpc/conf/DEFAULTS
index 7c981d1..232518b 100644
--- a/sys/powerpc/conf/DEFAULTS
+++ b/sys/powerpc/conf/DEFAULTS
@@ -6,6 +6,7 @@
machine powerpc
# Pseudo devices.
+device genclock
device mem # Memory and kernel memory devices
# UART chips on this platform
OpenPOWER on IntegriCloud