summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/powermac
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-02-24 01:27:36 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-02-24 01:27:36 +0000
commit8e85b4c3727d0ecd8b7562c84598204916227128 (patch)
tree21788935e9d977248da42a8da1e2dece507aeca5 /sys/powerpc/powermac
parent0150e93df959dff11b326dafa8dd409cf8ec4445 (diff)
downloadFreeBSD-src-8e85b4c3727d0ecd8b7562c84598204916227128.zip
FreeBSD-src-8e85b4c3727d0ecd8b7562c84598204916227128.tar.gz
Add the ability to set SMU-based machines to restart automatically after
power loss.
Diffstat (limited to 'sys/powerpc/powermac')
-rw-r--r--sys/powerpc/powermac/smu.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/sys/powerpc/powermac/smu.c b/sys/powerpc/powermac/smu.c
index 2692757..061ac1c 100644
--- a/sys/powerpc/powermac/smu.c
+++ b/sys/powerpc/powermac/smu.c
@@ -137,6 +137,7 @@ static void smu_attach_fans(device_t dev, phandle_t fanroot);
static void smu_attach_sensors(device_t dev, phandle_t sensroot);
static void smu_fanmgt_callout(void *xdev);
static void smu_set_sleepled(void *xdev, int onoff);
+static int smu_server_mode(SYSCTL_HANDLER_ARGS);
/* where to find the doorbell GPIO */
@@ -174,6 +175,16 @@ MALLOC_DEFINE(M_SMU, "smu", "SMU Sensor Information");
#define SMU_MISC_GET_DATA 0x02
#define SMU_MISC_LED_CTRL 0x04
#define SMU_POWER 0xaa
+#define SMU_POWER_EVENTS 0x8f
+#define SMU_PWR_GET_POWERUP 0x00
+#define SMU_PWR_SET_POWERUP 0x01
+#define SMU_PWR_CLR_POWERUP 0x02
+
+/* Power event types */
+#define SMU_WAKEUP_KEYPRESS 0x01
+#define SMU_WAKEUP_AC_INSERT 0x02
+#define SMU_WAKEUP_AC_CHANGE 0x04
+#define SMU_WAKEUP_RING 0x10
/* Data blocks */
#define SMU_CPUTEMP_CAL 0x18
@@ -301,6 +312,15 @@ smu_attach(device_t dev)
*/
sc->sc_leddev = led_create(smu_set_sleepled, dev, "sleepled");
+ /*
+ * Reset on power loss behavior
+ */
+
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+ "server_mode", CTLTYPE_INT | CTLFLAG_RW, dev, 0,
+ smu_server_mode, "I", "Enable reboot after power failure");
+
return (0);
}
@@ -877,3 +897,41 @@ smu_set_sleepled(void *xdev, int onoff)
smu_run_cmd(smu, &cmd);
}
+static int
+smu_server_mode(SYSCTL_HANDLER_ARGS)
+{
+ struct smu_cmd cmd;
+ u_int server_mode;
+ device_t smu = arg1;
+ int error;
+
+ cmd.cmd = SMU_POWER_EVENTS;
+ cmd.len = 1;
+ cmd.data[0] = SMU_PWR_GET_POWERUP;
+
+ error = smu_run_cmd(smu, &cmd);
+
+ if (error)
+ return (error);
+
+ server_mode = (cmd.data[1] & SMU_WAKEUP_AC_INSERT) ? 1 : 0;
+
+ error = sysctl_handle_int(oidp, &server_mode, 0, req);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (server_mode == 1)
+ cmd.data[0] = SMU_PWR_SET_POWERUP;
+ else if (server_mode == 0)
+ cmd.data[0] = SMU_PWR_CLR_POWERUP;
+ else
+ return (EINVAL);
+
+ cmd.len = 3;
+ cmd.data[1] = 0;
+ cmd.data[2] = SMU_WAKEUP_AC_INSERT;
+
+ return (smu_run_cmd(smu, &cmd));
+}
+
OpenPOWER on IntegriCloud