summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2008-04-15 17:02:23 +0000
committermarcel <marcel@FreeBSD.org>2008-04-15 17:02:23 +0000
commite920d11c2c3dcf18a24213ffd10a3d466f6af47c (patch)
tree47adf688d91ca07ff4b7da82e3a3782ea0760ced /sys/ia64
parent0a1ecdd2e84b6fef841d34c4bf72c2db962b0c24 (diff)
downloadFreeBSD-src-e920d11c2c3dcf18a24213ffd10a3d466f6af47c.zip
FreeBSD-src-e920d11c2c3dcf18a24213ffd10a3d466f6af47c.tar.gz
Use genclock for RTC handling. This eliminates the MD versions for
inittodr() and resettodr(). Have nexus double as the clock device, because it's the firmware that provides RTC services. We could create a special (pseudo-) device for it, but that wasn't superior enough to actually do it. Maybe later... Requested by: phk
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/conf/DEFAULTS1
-rw-r--r--sys/ia64/ia64/clock.c92
-rw-r--r--sys/ia64/ia64/nexus.c93
3 files changed, 51 insertions, 135 deletions
diff --git a/sys/ia64/conf/DEFAULTS b/sys/ia64/conf/DEFAULTS
index 1a96cd6..9717728 100644
--- a/sys/ia64/conf/DEFAULTS
+++ b/sys/ia64/conf/DEFAULTS
@@ -9,6 +9,7 @@ machine ia64
device acpi # ACPI support
# Pseudo devices.
+device genclock # Real-time clock
device mem # Memory and kernel memory devices
# UART chips on this platform
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c
index dcfc6e8..c774dad 100644
--- a/sys/ia64/ia64/clock.c
+++ b/sys/ia64/ia64/clock.c
@@ -44,8 +44,6 @@ __FBSDID("$FreeBSD$");
uint64_t ia64_clock_reload;
-static int clock_initialized = 0;
-
#ifndef SMP
static timecounter_get_t ia64_get_timecount;
@@ -110,93 +108,3 @@ cpu_stopprofclock(void)
/* nothing to do */
}
-
-void
-inittodr(time_t base)
-{
- long days;
- struct efi_tm tm;
- struct timespec ts;
- struct clocktime ct;
-
- efi_get_time(&tm);
-
- /*
- * This code was written in 2005, so logically EFI cannot return
- * a year smaller than that. Assume the EFI clock is out of whack
- * in that case and reset the EFI clock.
- */
- if (tm.tm_year < 2005) {
- printf("WARNING: CHECK AND RESET THE DATE!\n");
- memset(&tm, 0, sizeof(tm));
- tm.tm_year = 2005;
- tm.tm_mon = tm.tm_mday = 1;
- if (efi_set_time(&tm))
- printf("ERROR: COULD NOT RESET EFI CLOCK!\n");
- }
-
- ct.nsec = tm.tm_nsec;
- ct.sec = tm.tm_sec;
- ct.min = tm.tm_min;
- ct.hour = tm.tm_hour;
- ct.day = tm.tm_mday;
- ct.mon = tm.tm_mon;
- ct.year = tm.tm_year;
- ct.dow = -1;
- if (clock_ct_to_ts(&ct, &ts))
- printf("Invalid time in clock: check and reset the date!\n");
- ts.tv_sec += utc_offset();
-
- /*
- * The EFI clock is supposed to be a real-time clock, whereas the
- * base argument is coming from a saved (as on disk) time. It's
- * impossible for a saved time to represent a time in the future,
- * so we expect the EFI clock to be larger. If not, the EFI clock
- * may not be reliable and we trust the base.
- * Warn if the EFI clock was off by 2 or more days.
- */
- if (ts.tv_sec < base) {
- days = (base - ts.tv_sec) / (60L * 60L * 24L);
- if (days >= 2)
- printf("WARNING: EFI clock lost %ld days!\n", days);
- ts.tv_sec = base;
- ts.tv_nsec = 0;
- }
-
- tc_setclock(&ts);
- clock_initialized = 1;
-}
-
-/*
- * Reset the TODR based on the time value; used when the TODR has a
- * preposterous value and also when the time is reset by the stime
- * system call. Also called when the TODR goes past
- * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
- * to wrap the TODR around.
- */
-void
-resettodr()
-{
- struct timespec ts;
- struct clocktime ct;
- struct efi_tm tm;
-
- if (!clock_initialized || disable_rtc_set)
- return;
-
- efi_get_time(&tm);
- getnanotime(&ts);
- ts.tv_sec -= utc_offset();
- clock_ts_to_ct(&ts, &ct);
-
- tm.tm_nsec = ts.tv_nsec;
- tm.tm_sec = ct.sec;
- tm.tm_min = ct.min;
- tm.tm_hour = ct.hour;
-
- tm.tm_year = ct.year;
- tm.tm_mon = ct.mon;
- tm.tm_mday = ct.day;
- if (efi_set_time(&tm))
- printf("ERROR: COULD NOT RESET EFI CLOCK!\n");
-}
diff --git a/sys/ia64/ia64/nexus.c b/sys/ia64/ia64/nexus.c
index fad54de..a069399 100644
--- a/sys/ia64/ia64/nexus.c
+++ b/sys/ia64/ia64/nexus.c
@@ -43,6 +43,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/clock.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
@@ -53,6 +54,7 @@
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/efi.h>
#include <machine/intr.h>
#include <machine/nexusvar.h>
#include <machine/pmap.h>
@@ -66,6 +68,8 @@
#include <isa/isareg.h>
#include <sys/rtprio.h>
+#include "clock_if.h"
+
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
struct nexus_device {
struct resource_list nx_resources;
@@ -104,6 +108,9 @@ static void nexus_delete_resource(device_t, device_t, int, int);
static int nexus_config_intr(device_t, int, enum intr_trigger,
enum intr_polarity);
+static int nexus_gettime(device_t, struct timespec *);
+static int nexus_settime(device_t, struct timespec *);
+
static device_method_t nexus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, nexus_probe),
@@ -130,6 +137,10 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_delete_resource, nexus_delete_resource),
DEVMETHOD(bus_config_intr, nexus_config_intr),
+ /* Clock interface */
+ DEVMETHOD(clock_gettime, nexus_gettime),
+ DEVMETHOD(clock_settime, nexus_settime),
+
{ 0, 0 }
};
@@ -229,6 +240,7 @@ nexus_attach(device_t dev)
if (acpi_identify() == 0)
BUS_ADD_CHILD(dev, 10, "acpi", 0);
+ clock_register(dev, 1000);
bus_generic_attach(dev);
return 0;
}
@@ -521,54 +533,49 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
return (sapic_config_intr(irq, trig, pol));
}
-#if 0
-
-/*
- * Placeholder which claims PnP 'devices' which describe system
- * resources.
- */
-static struct isa_pnp_id sysresource_ids[] = {
- { 0x010cd041 /* PNP0c01 */, "System Memory" },
- { 0x020cd041 /* PNP0c02 */, "System Resource" },
- { 0 }
-};
-
static int
-sysresource_probe(device_t dev)
+nexus_gettime(device_t dev, struct timespec *ts)
{
- int result;
-
- if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) {
- device_quiet(dev);
- }
- return(result);
+ struct clocktime ct;
+ struct efi_tm tm;
+
+ efi_get_time(&tm);
+
+ /*
+ * This code was written in 2005, so logically EFI cannot return
+ * a year smaller than that. Assume the EFI clock is out of whack
+ * in that case and reset the EFI clock.
+ */
+ if (tm.tm_year < 2005)
+ return (EINVAL);
+
+ ct.nsec = tm.tm_nsec;
+ ct.sec = tm.tm_sec;
+ ct.min = tm.tm_min;
+ ct.hour = tm.tm_hour;
+ ct.day = tm.tm_mday;
+ ct.mon = tm.tm_mon;
+ ct.year = tm.tm_year;
+ ct.dow = -1;
+ return (clock_ct_to_ts(&ct, ts));
}
static int
-sysresource_attach(device_t dev)
+nexus_settime(device_t dev, struct timespec *ts)
{
- return(0);
+ struct clocktime ct;
+ struct efi_tm tm;
+
+ efi_get_time(&tm);
+
+ clock_ts_to_ct(ts, &ct);
+ tm.tm_nsec = ts->tv_nsec;
+ tm.tm_sec = ct.sec;
+ tm.tm_min = ct.min;
+ tm.tm_hour = ct.hour;
+ tm.tm_year = ct.year;
+ tm.tm_mon = ct.mon;
+ tm.tm_mday = ct.day;
+ return (efi_set_time(&tm));
}
-static device_method_t sysresource_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sysresource_probe),
- DEVMETHOD(device_attach, sysresource_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- { 0, 0 }
-};
-
-static driver_t sysresource_driver = {
- "sysresource",
- sysresource_methods,
- 1, /* no softc */
-};
-
-static devclass_t sysresource_devclass;
-
-DRIVER_MODULE(sysresource, isa, sysresource_driver, sysresource_devclass, 0, 0);
-
-#endif
OpenPOWER on IntegriCloud