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));
+}
+
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to