svn commit: r204270 - in head: share/man/man4/man4.powerpc sys/powerpc/powermac

Nathan Whitehorn nwhitehorn at FreeBSD.org
Wed Feb 24 01:27:37 UTC 2010


Author: nwhitehorn
Date: Wed Feb 24 01:27:36 2010
New Revision: 204270
URL: http://svn.freebsd.org/changeset/base/204270

Log:
  Add the ability to set SMU-based machines to restart automatically after
  power loss.

Modified:
  head/share/man/man4/man4.powerpc/smu.4
  head/sys/powerpc/powermac/smu.c

Modified: head/share/man/man4/man4.powerpc/smu.4
==============================================================================
--- head/share/man/man4/man4.powerpc/smu.4	Wed Feb 24 00:55:55 2010	(r204269)
+++ head/share/man/man4/man4.powerpc/smu.4	Wed Feb 24 01:27:36 2010	(r204270)
@@ -75,6 +75,9 @@ The following sysctls can be used to con
 power management behavior and to examine current system power and
 thermal conditions.
 .Bl -tag -width indent
+.It Va dev.smu.%d.server_mode
+Restart after power failure behavior (1 causes system to reboot after power
+cut, 0 causes system to remain off).
 .It Va dev.smu.%d.target_temp
 Target system temperature, in degrees Celsius. The
 .Nm

Modified: head/sys/powerpc/powermac/smu.c
==============================================================================
--- head/sys/powerpc/powermac/smu.c	Wed Feb 24 00:55:55 2010	(r204269)
+++ head/sys/powerpc/powermac/smu.c	Wed Feb 24 01:27:36 2010	(r204270)
@@ -137,6 +137,7 @@ static void	smu_attach_fans(device_t dev
 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 
 #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));
+}
+


More information about the svn-src-all mailing list