diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-08-31 15:27:46 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-08-31 15:27:46 +0000 |
commit | 655a96888d55c63b6496de2c02332278739d62f6 (patch) | |
tree | 6d62f76674112f0f46965b70b4629824076f5094 /sys/powerpc/powermac/cuda.c | |
parent | 97e3e3670826f9a28781351eebc6280670c370a5 (diff) | |
download | FreeBSD-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.c | 18 |
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 |