Module Name:    src
Committed By:   macallan
Date:           Wed Mar 16 05:08:29 UTC 2011

Modified Files:
        src/sys/arch/macppc/dev: obio.c

Log Message:
change the CPU speed sysctl to look more like the ACPI ones, as in
machdep.<name>.frequency.available etc. so estd can work with minimal changes


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/macppc/dev/obio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/macppc/dev/obio.c
diff -u src/sys/arch/macppc/dev/obio.c:1.31 src/sys/arch/macppc/dev/obio.c:1.32
--- src/sys/arch/macppc/dev/obio.c:1.31	Sun Dec  5 13:33:50 2010
+++ src/sys/arch/macppc/dev/obio.c	Wed Mar 16 05:08:29 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: obio.c,v 1.31 2010/12/05 13:33:50 phx Exp $	*/
+/*	$NetBSD: obio.c,v 1.32 2011/03/16 05:08:29 macallan Exp $	*/
 
 /*-
  * Copyright (C) 1998	Internet Research Institute, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.31 2010/12/05 13:33:50 phx Exp $");
+__KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.32 2011/03/16 05:08:29 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -71,6 +71,7 @@
 #ifdef OBIO_SPEED_CONTROL
 	int sc_voltage;
 	int sc_busspeed;
+	int sc_spd_hi, sc_spd_lo;
 #endif
 };
 
@@ -81,6 +82,8 @@
 static void obio_set_cpu_speed(struct obio_softc *, int);
 static int  obio_get_cpu_speed(struct obio_softc *);
 static int  sysctl_cpuspeed_temp(SYSCTLFN_ARGS);
+static int  sysctl_cpuspeed_cur(SYSCTLFN_ARGS);
+static int  sysctl_cpuspeed_available(SYSCTLFN_ARGS);
 
 static const char *keylargo[] = {"Keylargo",
 				 "AAPL,Keylargo",
@@ -131,6 +134,8 @@
 #ifdef OBIO_SPEED_CONTROL
 	sc->sc_voltage = -1;
 	sc->sc_busspeed = -1;
+	sc->sc_spd_lo = 600;
+	sc->sc_spd_hi = 800;
 #endif
 
 	switch (PCI_PRODUCT(pa->pa_id)) {
@@ -330,9 +335,9 @@
 obio_setup_gpios(struct obio_softc *sc, int node)
 {
 	uint32_t gpio_base, reg[6];
-	struct sysctlnode *sysctl_node;
+	struct sysctlnode *sysctl_node, *me, *freq;
 	char name[32];
-	int child, use_dfs;
+	int child, use_dfs, cpunode, hiclock;
 
 	if (of_compatible(sc->sc_node, keylargo) == -1)
 		return;
@@ -384,14 +389,55 @@
 	printf("%s: enabling Intrepid CPU speed control\n",
 	    sc->sc_dev.dv_xname);
 
+	sc->sc_spd_lo = curcpu()->ci_khz / 1000;
+	hiclock = 0;
+	cpunode = OF_finddevice("/cpus/@0");
+	OF_getprop(cpunode, "clock-frequency", &hiclock, 4);
+	printf("hiclock: %d\n", (hiclock + 500000) / 1000000);
 	sysctl_node = NULL;
-	sysctl_createv(NULL, 0, NULL, 
+
+	if (sysctl_createv(NULL, 0, NULL, 
+	    (const struct sysctlnode **)&me, 
+	    CTLFLAG_READWRITE, CTLTYPE_NODE, "intrepid", NULL, NULL,
+	    0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL) != 0)
+		printf("couldn't create 'interpid' node\n");
+	
+	if (sysctl_createv(NULL, 0, NULL, 
+	    (const struct sysctlnode **)&freq, 
+	    CTLFLAG_READWRITE, CTLTYPE_NODE, "frequency", NULL, NULL,
+	    0, NULL, 0, CTL_MACHDEP, me->sysctl_num, CTL_CREATE, CTL_EOL) != 0)
+		printf("couldn't create 'frequency' node\n");
+
+	if (sysctl_createv(NULL, 0, NULL, 
 	    (const struct sysctlnode **)&sysctl_node, 
 	    CTLFLAG_READWRITE | CTLFLAG_OWNDESC | CTLFLAG_IMMEDIATE,
-	    CTLTYPE_INT, "cpu_speed", "CPU speed", sysctl_cpuspeed_temp, 
-	    (unsigned long)sc, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
-	if (sysctl_node != NULL)
+	    CTLTYPE_INT, "target", "CPU speed", sysctl_cpuspeed_temp, 
+	    0, NULL, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num, 
+	    CTL_CREATE, CTL_EOL) == 0) {
+		sysctl_node->sysctl_data = (void *)sc;
+	} else
+		printf("couldn't create 'target' node\n");
+
+	if (sysctl_createv(NULL, 0, NULL, 
+	    (const struct sysctlnode **)&sysctl_node, 
+	    CTLFLAG_READWRITE | CTLFLAG_IMMEDIATE,
+	    CTLTYPE_INT, "current", NULL, sysctl_cpuspeed_cur, 
+	    1, NULL, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num, 
+	    CTL_CREATE, CTL_EOL) == 0) {
 		sysctl_node->sysctl_data = (void *)sc;
+	} else
+		printf("couldn't create 'current' node\n");
+
+	if (sysctl_createv(NULL, 0, NULL, 
+	    (const struct sysctlnode **)&sysctl_node, 
+	    CTLFLAG_READWRITE,
+	    CTLTYPE_STRING, "available", NULL, sysctl_cpuspeed_available, 
+	    2, NULL, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num, 
+	    CTL_CREATE, CTL_EOL) == 0) {
+		sysctl_node->sysctl_data = (void *)sc;
+	} else
+		printf("couldn't create 'available' node\n");
+	printf("speed: %d\n", curcpu()->ci_khz);
 }
 
 static void
@@ -458,27 +504,83 @@
 {
 	struct sysctlnode node = *rnode;
 	struct obio_softc *sc = node.sysctl_data;
-	const int *np = newp;
-	int speed, nd = 0;
+	int speed, mhz;
 
 	speed = obio_get_cpu_speed(sc);	
-	node.sysctl_idata = speed;
-	if (np) {
-		/* we're asked to write */	
-		nd = *np;
-		node.sysctl_data = &speed;
-		if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) {
-			int new_reg;
-
-			new_reg = (max(0, min(1, node.sysctl_idata)));
-			obio_set_cpu_speed(sc, new_reg);
-			return 0;
+	switch (speed) {
+		case 0:
+			mhz = sc->sc_spd_lo;
+			break;
+		case 1:
+			mhz = sc->sc_spd_hi;
+			break;
+		default:
+			speed = -1;
+	}
+	node.sysctl_idata = mhz;
+	node.sysctl_data = &mhz;
+	if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) {
+		int new_reg;
+
+		new_reg = node.sysctl_idata;
+		if (new_reg == sc->sc_spd_lo) {
+			obio_set_cpu_speed(sc, 0);
+		} else if (new_reg == sc->sc_spd_hi) {
+			obio_set_cpu_speed(sc, 1);
+		} else {
+			printf("%s: new_reg %d\n", __func__, new_reg);
+			return EINVAL;
 		}
-		return EINVAL;
-	} else {
-		node.sysctl_size = 4;
-		return(sysctl_lookup(SYSCTLFN_CALL(&node)));
+		return 0;
 	}
+	return EINVAL;
+}
+
+static int
+sysctl_cpuspeed_cur(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct obio_softc *sc = node.sysctl_data;
+	int speed, mhz;
+
+	speed = obio_get_cpu_speed(sc);
+	switch (speed) {
+		case 0:
+			mhz = sc->sc_spd_lo;
+			break;
+		case 1:
+			mhz = sc->sc_spd_hi;
+			break;
+		default:
+			speed = -1;
+	}
+	node.sysctl_idata = mhz;
+	node.sysctl_data = &mhz;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+static int
+sysctl_cpuspeed_available(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct obio_softc *sc = node.sysctl_data;
+	char buf[128];
+	int speed;
+
+	speed = obio_get_cpu_speed(sc);
+	snprintf(buf, 128, "%d %d", sc->sc_spd_lo, sc->sc_spd_hi);	
+	node.sysctl_data = buf;
+	return(sysctl_lookup(SYSCTLFN_CALL(&node)));
+}
+
+SYSCTL_SETUP(sysctl_ams_setup, "sysctl obio subtree setup")
+{
+
+	sysctl_createv(NULL, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "machdep", NULL,
+		       NULL, 0, NULL, 0,
+		       CTL_MACHDEP, CTL_EOL);
 }
 
 #endif /* OBIO_SPEEDCONTROL */

Reply via email to