svn commit: r205506 - in head/sys/powerpc: aim powermac

Nathan Whitehorn nwhitehorn at FreeBSD.org
Tue Mar 23 03:14:44 UTC 2010


Author: nwhitehorn
Date: Tue Mar 23 03:14:44 2010
New Revision: 205506
URL: http://svn.freebsd.org/changeset/base/205506

Log:
  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

Modified:
  head/sys/powerpc/aim/nexus.c
  head/sys/powerpc/powermac/cuda.c
  head/sys/powerpc/powermac/cudavar.h
  head/sys/powerpc/powermac/pmu.c
  head/sys/powerpc/powermac/smu.c

Modified: head/sys/powerpc/aim/nexus.c
==============================================================================
--- head/sys/powerpc/aim/nexus.c	Tue Mar 23 02:18:12 2010	(r205505)
+++ head/sys/powerpc/aim/nexus.c	Tue Mar 23 03:14:44 2010	(r205506)
@@ -60,7 +60,6 @@
 #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,7 +73,6 @@
 
 #include <sys/rman.h>
 
-#include "clock_if.h"
 #include "ofw_bus_if.h"
 #include "pic_if.h"
 
@@ -143,12 +141,6 @@ static const char	*nexus_ofw_get_type(de
 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);
@@ -181,10 +173,6 @@ 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 }
 };
 
@@ -240,7 +228,6 @@ nexus_attach(device_t dev)
 
 	}
 
-	clock_register(dev, 1000);
 	return (bus_generic_attach(dev));
 }
 
@@ -512,50 +499,3 @@ nexus_ofw_get_compat(device_t bus, devic
 	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);
-}

Modified: head/sys/powerpc/powermac/cuda.c
==============================================================================
--- head/sys/powerpc/powermac/cuda.c	Tue Mar 23 02:18:12 2010	(r205505)
+++ head/sys/powerpc/powermac/cuda.c	Tue Mar 23 03:14:44 2010	(r205506)
@@ -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
 	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);
+}
+

Modified: head/sys/powerpc/powermac/cudavar.h
==============================================================================
--- head/sys/powerpc/powermac/cudavar.h	Tue Mar 23 02:18:12 2010	(r205505)
+++ head/sys/powerpc/powermac/cudavar.h	Tue Mar 23 03:14:44 2010	(r205506)
@@ -90,6 +90,7 @@ struct cuda_softc {
 	int		sc_polling;
 	int		sc_iic_done;
 	volatile int	sc_autopoll;
+	uint32_t	sc_rtc;
 
 	int sc_i2c_read_len;
 

Modified: head/sys/powerpc/powermac/pmu.c
==============================================================================
--- head/sys/powerpc/powermac/pmu.c	Tue Mar 23 02:18:12 2010	(r205505)
+++ head/sys/powerpc/powermac/pmu.c	Tue Mar 23 03:14:44 2010	(r205506)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/bus.h>
 #include <sys/conf.h>
 #include <sys/kernel.h>
+#include <sys/clock.h>
 #include <sys/sysctl.h>
 
 #include <dev/ofw/ofw_bus.h>
@@ -55,16 +56,27 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/adb/adb.h>
 
+#include "clock_if.h"
 #include "pmuvar.h"
 #include "viareg.h"
 
 /*
- * MacIO interface
+ * Bus interface
  */
 static int	pmu_probe(device_t);
 static int	pmu_attach(device_t);
 static int	pmu_detach(device_t);
 
+/*
+ * Clock interface
+ */
+static int	pmu_gettime(device_t dev, struct timespec *ts);
+static int	pmu_settime(device_t dev, struct timespec *ts);
+
+/*
+ * ADB Interface
+ */
+
 static u_int	pmu_adb_send(device_t dev, u_char command_byte, int len, 
 		    u_char *data, u_char poll);
 static u_int	pmu_adb_autopoll(device_t dev, uint16_t mask);
@@ -110,6 +122,10 @@ static device_method_t  pmu_methods[] = 
 	DEVMETHOD(adb_hb_controller_poll,   pmu_poll),
 	DEVMETHOD(adb_hb_set_autopoll_mask, pmu_adb_autopoll),
 
+	/* Clock interface */
+	DEVMETHOD(clock_gettime,	pmu_gettime),
+	DEVMETHOD(clock_settime,	pmu_settime),
+
 	{ 0, 0 },
 };
 
@@ -453,6 +469,12 @@ pmu_attach(device_t dev)
 
 	sc->sc_leddev = led_create(pmu_set_sleepled, sc, "sleepled");
 
+	/*
+	 * Register RTC
+	 */
+
+	clock_register(dev, 1000);
+
 	return (bus_generic_attach(dev));
 }
 
@@ -926,3 +948,38 @@ pmu_battquery_sysctl(SYSCTL_HANDLER_ARGS
 	return (error);
 }
 
+#define DIFF19041970	2082844800
+
+static int
+pmu_gettime(device_t dev, struct timespec *ts)
+{
+	struct pmu_softc *sc = device_get_softc(dev);
+	uint8_t resp[16];
+	uint32_t sec;
+
+	mtx_lock(&sc->sc_mutex);
+	pmu_send(sc, PMU_READ_RTC, 0, NULL, 16, resp);
+	mtx_unlock(&sc->sc_mutex);
+
+	memcpy(&sec, &resp[1], 4);
+	ts->tv_sec = sec - DIFF19041970;
+	ts->tv_nsec = 0;
+
+	return (0);
+}
+
+static int
+pmu_settime(device_t dev, struct timespec *ts)
+{
+	struct pmu_softc *sc = device_get_softc(dev);
+	uint32_t sec;
+
+	sec = ts->tv_sec + DIFF19041970;
+
+	mtx_lock(&sc->sc_mutex);
+	pmu_send(sc, PMU_SET_RTC, sizeof(sec), (uint8_t *)&sec, 0, NULL);
+	mtx_unlock(&sc->sc_mutex);
+
+	return (0);
+}
+

Modified: head/sys/powerpc/powermac/smu.c
==============================================================================
--- head/sys/powerpc/powermac/smu.c	Tue Mar 23 02:18:12 2010	(r205505)
+++ head/sys/powerpc/powermac/smu.c	Tue Mar 23 03:14:44 2010	(r205506)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/conf.h>
 #include <sys/cpu.h>
+#include <sys/clock.h>
 #include <sys/ctype.h>
 #include <sys/kernel.h>
 #include <sys/kthread.h>
@@ -51,6 +52,8 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus.h>
 #include <powerpc/powermac/macgpiovar.h>
 
+#include "clock_if.h"
+
 struct smu_cmd {
 	volatile uint8_t cmd;
 	uint8_t		len;
@@ -140,6 +143,10 @@ static int	smu_attach(device_t);
 static void	smu_cpufreq_pre_change(device_t, const struct cf_level *level);
 static void	smu_cpufreq_post_change(device_t, const struct cf_level *level);
 
+/* clock interface */
+static int	smu_gettime(device_t dev, struct timespec *ts);
+static int	smu_settime(device_t dev, struct timespec *ts);
+
 /* utility functions */
 static int	smu_run_cmd(device_t dev, struct smu_cmd *cmd, int wait);
 static int	smu_get_datablock(device_t dev, int8_t id, uint8_t *buf,
@@ -160,6 +167,10 @@ static device_method_t  smu_methods[] = 
 	/* Device interface */
 	DEVMETHOD(device_probe,		smu_probe),
 	DEVMETHOD(device_attach,	smu_attach),
+
+	/* Clock interface */
+	DEVMETHOD(clock_gettime,	smu_gettime),
+	DEVMETHOD(clock_settime,	smu_settime),
 	{ 0, 0 },
 };
 
@@ -192,6 +203,9 @@ MALLOC_DEFINE(M_SMU, "smu", "SMU Sensor 
 #define  SMU_PWR_GET_POWERUP	0x00
 #define  SMU_PWR_SET_POWERUP	0x01
 #define  SMU_PWR_CLR_POWERUP	0x02
+#define SMU_RTC			0x8e
+#define  SMU_RTC_GET		0x81
+#define  SMU_RTC_SET		0x80
 
 /* Power event types */
 #define SMU_WAKEUP_KEYPRESS	0x01
@@ -349,6 +363,11 @@ smu_attach(device_t dev)
 	powerpc_config_intr(rman_get_start(sc->sc_doorbellirq),
 	    INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);
 
+	/*
+	 * Connect RTC interface.
+	 */
+	clock_register(dev, 1000);
+
 	return (0);
 }
 
@@ -1043,3 +1062,51 @@ smu_server_mode(SYSCTL_HANDLER_ARGS)
 	return (smu_run_cmd(smu, &cmd, 1));
 }
 
+static int
+smu_gettime(device_t dev, struct timespec *ts)
+{
+	struct smu_cmd cmd;
+	struct clocktime ct;
+
+	cmd.cmd = SMU_RTC;
+	cmd.len = 1;
+	cmd.data[0] = SMU_RTC_GET;
+
+	if (smu_run_cmd(dev, &cmd, 1) != 0)
+		return (ENXIO);
+
+	ct.nsec	= 0;
+	ct.sec	= bcd2bin(cmd.data[0]);
+	ct.min	= bcd2bin(cmd.data[1]);
+	ct.hour	= bcd2bin(cmd.data[2]);
+	ct.dow	= bcd2bin(cmd.data[3]);
+	ct.day	= bcd2bin(cmd.data[4]);
+	ct.mon	= bcd2bin(cmd.data[5]);
+	ct.year	= bcd2bin(cmd.data[6]) + 2000;
+
+	return (clock_ct_to_ts(&ct, ts));
+}
+
+static int
+smu_settime(device_t dev, struct timespec *ts)
+{
+	struct smu_cmd cmd;
+	struct clocktime ct;
+
+	cmd.cmd = SMU_RTC;
+	cmd.len = 8;
+	cmd.data[0] = SMU_RTC_SET;
+
+	clock_ts_to_ct(ts, &ct);
+
+	cmd.data[1] = bin2bcd(ct.sec);
+	cmd.data[2] = bin2bcd(ct.min);
+	cmd.data[3] = bin2bcd(ct.hour);
+	cmd.data[4] = bin2bcd(ct.dow);
+	cmd.data[5] = bin2bcd(ct.day);
+	cmd.data[6] = bin2bcd(ct.mon);
+	cmd.data[7] = bin2bcd(ct.year - 2000);
+
+	return (smu_run_cmd(dev, &cmd, 1));
+}
+


More information about the svn-src-head mailing list