summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/powermac/cuda.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-08-31 15:27:46 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-08-31 15:27:46 +0000
commit655a96888d55c63b6496de2c02332278739d62f6 (patch)
tree6d62f76674112f0f46965b70b4629824076f5094 /sys/powerpc/powermac/cuda.c
parent97e3e3670826f9a28781351eebc6280670c370a5 (diff)
downloadFreeBSD-src-655a96888d55c63b6496de2c02332278739d62f6.zip
FreeBSD-src-655a96888d55c63b6496de2c02332278739d62f6.tar.gz
Restructure how reset and poweroff are handled on PowerPC systems, since
the existing code was very platform specific, and broken for SMP systems trying to reboot from KDB. - Add a new PLATFORM_RESET() method to the platform KOBJ interface, and migrate existing reset functions into platform modules. - Modify the OF_reboot() routine to submit the request by hand to avoid the IPIs involved in the regular openfirmware() routine. This fixes reboot from KDB on SMP machines. - Move non-KDB reset and poweroff functions on the Powermac platform into the relevant power control drivers (cuda, pmu, smu), instead of using them through the Open Firmware backdoor. - Rename platform_chrp to platform_powermac since it has become increasingly Powermac specific. When we gain support for IBM systems, we will grow a new platform_chrp.
Diffstat (limited to 'sys/powerpc/powermac/cuda.c')
-rw-r--r--sys/powerpc/powermac/cuda.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/powerpc/powermac/cuda.c b/sys/powerpc/powermac/cuda.c
index 0499352..99a0ea9 100644
--- a/sys/powerpc/powermac/cuda.c
+++ b/sys/powerpc/powermac/cuda.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/clock.h>
+#include <sys/reboot.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
@@ -72,6 +73,7 @@ static u_int cuda_adb_autopoll(device_t dev, uint16_t mask);
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);
+static void cuda_shutdown(void *xsc, int howto);
/*
* Clock interface
@@ -249,6 +251,8 @@ cuda_attach(device_t dev)
}
clock_register(dev, 1000);
+ EVENTHANDLER_REGISTER(shutdown_final, cuda_shutdown, sc,
+ SHUTDOWN_PRI_LAST);
return (bus_generic_attach(dev));
}
@@ -739,6 +743,20 @@ cuda_adb_autopoll(device_t dev, uint16_t mask) {
return (0);
}
+static void
+cuda_shutdown(void *xsc, int howto)
+{
+ struct cuda_softc *sc = xsc;
+ uint8_t cmd[] = {CUDA_PSEUDO, 0};
+
+ cmd[1] = (howto & RB_HALT) ? CMD_POWEROFF : CMD_RESET;
+ cuda_poll(sc->sc_dev);
+ cuda_send(sc, 1, 2, cmd);
+
+ while (1)
+ cuda_poll(sc->sc_dev);
+}
+
#define DIFF19041970 2082844800
static int
OpenPOWER on IntegriCloud