Home | History | Annotate | Line # | Download | only in dev
obio.c revision 1.34
      1 /*	$NetBSD: obio.c,v 1.34 2011/07/26 08:36:02 macallan Exp $	*/
      2 
      3 /*-
      4  * Copyright (C) 1998	Internet Research Institute, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by
     18  *	Internet Research Institute, Inc.
     19  * 4. The name of the author may not be used to endorse or promote products
     20  *    derived from this software without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 #include <sys/cdefs.h>
     35 __KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.34 2011/07/26 08:36:02 macallan Exp $");
     36 
     37 #include <sys/param.h>
     38 #include <sys/systm.h>
     39 #include <sys/kernel.h>
     40 #include <sys/device.h>
     41 #include <sys/sysctl.h>
     42 
     43 #include <dev/pci/pcivar.h>
     44 #include <dev/pci/pcidevs.h>
     45 
     46 #include <dev/ofw/openfirm.h>
     47 
     48 #include <machine/autoconf.h>
     49 
     50 #include <macppc/dev/obiovar.h>
     51 
     52 #include <powerpc/cpu.h>
     53 
     54 #include "opt_obio.h"
     55 
     56 #ifdef OBIO_DEBUG
     57 # define DPRINTF printf
     58 #else
     59 # define DPRINTF while (0) printf
     60 #endif
     61 
     62 static void obio_attach(device_t, device_t, void *);
     63 static int obio_match(device_t, cfdata_t, void *);
     64 static int obio_print(void *, const char *);
     65 
     66 struct obio_softc {
     67 	device_t sc_dev;
     68 	bus_space_tag_t sc_tag;
     69 	bus_space_handle_t sc_bh;
     70 	int sc_node;
     71 #ifdef OBIO_SPEED_CONTROL
     72 	int sc_voltage;
     73 	int sc_busspeed;
     74 	int sc_spd_hi, sc_spd_lo;
     75 #endif
     76 };
     77 
     78 static struct obio_softc *obio0 = NULL;
     79 
     80 #ifdef OBIO_SPEED_CONTROL
     81 static void obio_setup_gpios(struct obio_softc *, int);
     82 static void obio_set_cpu_speed(struct obio_softc *, int);
     83 static int  obio_get_cpu_speed(struct obio_softc *);
     84 static int  sysctl_cpuspeed_temp(SYSCTLFN_ARGS);
     85 static int  sysctl_cpuspeed_cur(SYSCTLFN_ARGS);
     86 static int  sysctl_cpuspeed_available(SYSCTLFN_ARGS);
     87 
     88 static const char *keylargo[] = {"Keylargo",
     89 				 "AAPL,Keylargo",
     90 				 NULL};
     91 
     92 #endif
     93 
     94 CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc),
     95     obio_match, obio_attach, NULL, NULL);
     96 
     97 int
     98 obio_match(device_t parent, cfdata_t cf, void *aux)
     99 {
    100 	struct pci_attach_args *pa = aux;
    101 
    102 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE)
    103 		switch (PCI_PRODUCT(pa->pa_id)) {
    104 		case PCI_PRODUCT_APPLE_GC:
    105 		case PCI_PRODUCT_APPLE_OHARE:
    106 		case PCI_PRODUCT_APPLE_HEATHROW:
    107 		case PCI_PRODUCT_APPLE_PADDINGTON:
    108 		case PCI_PRODUCT_APPLE_KEYLARGO:
    109 		case PCI_PRODUCT_APPLE_PANGEA_MACIO:
    110 		case PCI_PRODUCT_APPLE_INTREPID:
    111 		case PCI_PRODUCT_APPLE_K2:
    112 			return 1;
    113 		}
    114 
    115 	return 0;
    116 }
    117 
    118 /*
    119  * Attach all the sub-devices we can find
    120  */
    121 void
    122 obio_attach(device_t parent, device_t self, void *aux)
    123 {
    124 	struct obio_softc *sc = device_private(self);
    125 	struct pci_attach_args *pa = aux;
    126 	struct confargs ca;
    127 	bus_space_handle_t bsh;
    128 	int node, child, namelen, error;
    129 	u_int reg[20];
    130 	int intr[6], parent_intr = 0, parent_nintr = 0;
    131 	char name[32];
    132 	char compat[32];
    133 
    134 	sc->sc_dev = self;
    135 #ifdef OBIO_SPEED_CONTROL
    136 	sc->sc_voltage = -1;
    137 	sc->sc_busspeed = -1;
    138 	sc->sc_spd_lo = 600;
    139 	sc->sc_spd_hi = 800;
    140 #endif
    141 
    142 	switch (PCI_PRODUCT(pa->pa_id)) {
    143 
    144 	case PCI_PRODUCT_APPLE_GC:
    145 	case PCI_PRODUCT_APPLE_OHARE:
    146 	case PCI_PRODUCT_APPLE_HEATHROW:
    147 	case PCI_PRODUCT_APPLE_PADDINGTON:
    148 	case PCI_PRODUCT_APPLE_KEYLARGO:
    149 	case PCI_PRODUCT_APPLE_PANGEA_MACIO:
    150 	case PCI_PRODUCT_APPLE_INTREPID:
    151 		node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
    152 		if (node == -1)
    153 			node = OF_finddevice("mac-io");
    154 			if (node == -1)
    155 				node = OF_finddevice("/pci/mac-io");
    156 		break;
    157 	case PCI_PRODUCT_APPLE_K2:
    158 		node = OF_finddevice("mac-io");
    159 		break;
    160 
    161 	default:
    162 		node = -1;
    163 		break;
    164 	}
    165 	if (node == -1)
    166 		panic("macio not found or unknown");
    167 
    168 	sc->sc_node = node;
    169 
    170 #if defined (PMAC_G5)
    171 	if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 20)
    172 	{
    173 		return;
    174 	}
    175 #else
    176 	if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12)
    177 		return;
    178 #endif /* PMAC_G5 */
    179 
    180 	/*
    181 	 * XXX
    182 	 * This relies on the primary obio always attaching first which is
    183 	 * true on the PowerBook 3400c and similar machines but may or may
    184 	 * not work on others. We can't rely on the node name since Apple
    185 	 * didn't follow anything remotely resembling a consistent naming
    186 	 * scheme.
    187 	 */
    188 	if (obio0 == NULL)
    189 		obio0 = sc;
    190 
    191 	ca.ca_baseaddr = reg[2];
    192 	ca.ca_tag = pa->pa_memt;
    193 	sc->sc_tag = pa->pa_memt;
    194 	error = bus_space_map (pa->pa_memt, ca.ca_baseaddr, 0x80, 0, &bsh);
    195 	if (error)
    196 		panic(": failed to map mac-io %#x", ca.ca_baseaddr);
    197 	sc->sc_bh = bsh;
    198 
    199 	printf(": addr 0x%x\n", ca.ca_baseaddr);
    200 
    201 	/* Enable internal modem (KeyLargo) */
    202 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_KEYLARGO) {
    203 		aprint_normal("%s: enabling KeyLargo internal modem\n",
    204 		    self->dv_xname);
    205 		bus_space_write_4(ca.ca_tag, bsh, 0x40,
    206 		    bus_space_read_4(ca.ca_tag, bsh, 0x40) & ~(1<<25));
    207 	}
    208 
    209 	/* Enable internal modem (Pangea) */
    210 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PANGEA_MACIO) {
    211 		/* set reset */
    212 		bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x04);
    213 		/* power modem on */
    214 		bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x02, 0x04);
    215 		/* unset reset */
    216 		bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x05);
    217 	}
    218 
    219 	/* Gatwick and Paddington use same product ID */
    220 	namelen = OF_getprop(node, "compatible", compat, sizeof(compat));
    221 
    222 	if (strcmp(compat, "gatwick") == 0) {
    223 		parent_nintr = OF_getprop(node, "AAPL,interrupts", intr,
    224 					sizeof(intr));
    225 		parent_intr = intr[0];
    226 	} else {
    227   		/* Enable CD and microphone sound input. */
    228 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PADDINGTON)
    229 			bus_space_write_1(ca.ca_tag, bsh, 0x37, 0x03);
    230 	}
    231 
    232 	for (child = OF_child(node); child; child = OF_peer(child)) {
    233 		namelen = OF_getprop(child, "name", name, sizeof(name));
    234 		if (namelen < 0)
    235 			continue;
    236 		if (namelen >= sizeof(name))
    237 			continue;
    238 
    239 #ifdef OBIO_SPEED_CONTROL
    240 		if (strcmp(name, "gpio") == 0) {
    241 
    242 			obio_setup_gpios(sc, child);
    243 			continue;
    244 		}
    245 #endif
    246 
    247 		name[namelen] = 0;
    248 		ca.ca_name = name;
    249 		ca.ca_node = child;
    250 		ca.ca_tag = pa->pa_memt;
    251 
    252 		ca.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg));
    253 
    254 		if (strcmp(compat, "gatwick") != 0) {
    255 			ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr,
    256 					sizeof(intr));
    257 			if (ca.ca_nintr == -1)
    258 				ca.ca_nintr = OF_getprop(child, "interrupts", intr,
    259 						sizeof(intr));
    260 		} else {
    261 			intr[0] = parent_intr;
    262 			ca.ca_nintr = parent_nintr;
    263 		}
    264 		ca.ca_reg = reg;
    265 		ca.ca_intr = intr;
    266 
    267 		config_found(self, &ca, obio_print);
    268 	}
    269 }
    270 
    271 static const char * const skiplist[] = {
    272 	"interrupt-controller",
    273 	"gpio",
    274 	"escc-legacy",
    275 	"timer",
    276 	"i2c",
    277 	"power-mgt",
    278 	"escc",
    279 	"battery",
    280 	"backlight"
    281 
    282 };
    283 
    284 #define N_LIST (sizeof(skiplist) / sizeof(skiplist[0]))
    285 
    286 int
    287 obio_print(void *aux, const char *obio)
    288 {
    289 	struct confargs *ca = aux;
    290 	int i;
    291 
    292 	for (i = 0; i < N_LIST; i++)
    293 		if (strcmp(ca->ca_name, skiplist[i]) == 0)
    294 			return QUIET;
    295 
    296 	if (obio)
    297 		aprint_normal("%s at %s", ca->ca_name, obio);
    298 
    299 	if (ca->ca_nreg > 0)
    300 		aprint_normal(" offset 0x%x", ca->ca_reg[0]);
    301 
    302 	return UNCONF;
    303 }
    304 
    305 void obio_write_4(int offset, uint32_t value)
    306 {
    307 	if (obio0 == NULL)
    308 		return;
    309 	bus_space_write_4(obio0->sc_tag, obio0->sc_bh, offset, value);
    310 }
    311 
    312 void obio_write_1(int offset, uint8_t value)
    313 {
    314 	if (obio0 == NULL)
    315 		return;
    316 	bus_space_write_1(obio0->sc_tag, obio0->sc_bh, offset, value);
    317 }
    318 
    319 uint32_t obio_read_4(int offset)
    320 {
    321 	if (obio0 == NULL)
    322 		return 0xffffffff;
    323 	return bus_space_read_4(obio0->sc_tag, obio0->sc_bh, offset);
    324 }
    325 
    326 uint8_t obio_read_1(int offset)
    327 {
    328 	if (obio0 == NULL)
    329 		return 0xff;
    330 	return bus_space_read_1(obio0->sc_tag, obio0->sc_bh, offset);
    331 }
    332 
    333 #ifdef OBIO_SPEED_CONTROL
    334 
    335 static void
    336 obio_setup_gpios(struct obio_softc *sc, int node)
    337 {
    338 	uint32_t gpio_base, reg[6];
    339 	struct sysctlnode *sysctl_node, *me, *freq;
    340 	char name[32];
    341 	int child, use_dfs, cpunode, hiclock;
    342 
    343 	if (of_compatible(sc->sc_node, keylargo) == -1)
    344 		return;
    345 
    346 	if (OF_getprop(node, "reg", reg, sizeof(reg)) < 4)
    347 		return;
    348 
    349 	gpio_base = reg[0];
    350 	DPRINTF("gpio_base: %02x\n", gpio_base);
    351 
    352 	/* now look for voltage and bus speed gpios */
    353 	use_dfs = 0;
    354 	for (child = OF_child(node); child; child = OF_peer(child)) {
    355 
    356 		if (OF_getprop(child, "name", name, sizeof(name)) < 1)
    357 			continue;
    358 
    359 		if (OF_getprop(child, "reg", reg, sizeof(reg)) < 4)
    360 			continue;
    361 
    362 		/*
    363 		 * These register offsets either have to be added to the obio
    364 		 * base address or to the gpio base address. This differs
    365 		 * even in the same OF-tree! So we guess the offset is
    366 		 * based on obio when it is larger than the gpio_base.
    367 		 */
    368 		if (reg[0] >= gpio_base)
    369 			reg[0] -= gpio_base;
    370 
    371 		if (strcmp(name, "frequency-gpio") == 0) {
    372 			DPRINTF("found frequency_gpio at %02x\n", reg[0]);
    373 			sc->sc_busspeed = gpio_base + reg[0];
    374 		}
    375 		if (strcmp(name, "voltage-gpio") == 0) {
    376 			DPRINTF("found voltage_gpio at %02x\n", reg[0]);
    377 			sc->sc_voltage = gpio_base + reg[0];
    378 		}
    379 		if (strcmp(name, "cpu-vcore-select") == 0) {
    380 			DPRINTF("found cpu-vcore-select at %02x\n", reg[0]);
    381 			sc->sc_voltage = gpio_base + reg[0];
    382 			/* frequency gpio is not needed, we use cpu's DFS */
    383 			use_dfs = 1;
    384 		}
    385 	}
    386 
    387 	if ((sc->sc_voltage < 0) || (sc->sc_busspeed < 0 && !use_dfs))
    388 		return;
    389 
    390 	printf("%s: enabling Intrepid CPU speed control\n",
    391 	    device_xname(sc->sc_dev));
    392 
    393 	sc->sc_spd_lo = curcpu()->ci_khz / 1000;
    394 	hiclock = 0;
    395 	cpunode = OF_finddevice("/cpus/@0");
    396 	OF_getprop(cpunode, "clock-frequency", &hiclock, 4);
    397 	printf("hiclock: %d\n", (hiclock + 500000) / 1000000);
    398 	sysctl_node = NULL;
    399 
    400 	if (sysctl_createv(NULL, 0, NULL,
    401 	    (const struct sysctlnode **)&me,
    402 	    CTLFLAG_READWRITE, CTLTYPE_NODE, "intrepid", NULL, NULL,
    403 	    0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL) != 0)
    404 		printf("couldn't create 'interpid' node\n");
    405 
    406 	if (sysctl_createv(NULL, 0, NULL,
    407 	    (const struct sysctlnode **)&freq,
    408 	    CTLFLAG_READWRITE, CTLTYPE_NODE, "frequency", NULL, NULL,
    409 	    0, NULL, 0, CTL_MACHDEP, me->sysctl_num, CTL_CREATE, CTL_EOL) != 0)
    410 		printf("couldn't create 'frequency' node\n");
    411 
    412 	if (sysctl_createv(NULL, 0, NULL,
    413 	    (const struct sysctlnode **)&sysctl_node,
    414 	    CTLFLAG_READWRITE | CTLFLAG_OWNDESC | CTLFLAG_IMMEDIATE,
    415 	    CTLTYPE_INT, "target", "CPU speed", sysctl_cpuspeed_temp,
    416 	    0, NULL, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
    417 	    CTL_CREATE, CTL_EOL) == 0) {
    418 		sysctl_node->sysctl_data = (void *)sc;
    419 	} else
    420 		printf("couldn't create 'target' node\n");
    421 
    422 	if (sysctl_createv(NULL, 0, NULL,
    423 	    (const struct sysctlnode **)&sysctl_node,
    424 	    CTLFLAG_READWRITE | CTLFLAG_IMMEDIATE,
    425 	    CTLTYPE_INT, "current", NULL, sysctl_cpuspeed_cur,
    426 	    1, NULL, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
    427 	    CTL_CREATE, CTL_EOL) == 0) {
    428 		sysctl_node->sysctl_data = (void *)sc;
    429 	} else
    430 		printf("couldn't create 'current' node\n");
    431 
    432 	if (sysctl_createv(NULL, 0, NULL,
    433 	    (const struct sysctlnode **)&sysctl_node,
    434 	    CTLFLAG_READWRITE,
    435 	    CTLTYPE_STRING, "available", NULL, sysctl_cpuspeed_available,
    436 	    2, NULL, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
    437 	    CTL_CREATE, CTL_EOL) == 0) {
    438 		sysctl_node->sysctl_data = (void *)sc;
    439 	} else
    440 		printf("couldn't create 'available' node\n");
    441 	printf("speed: %d\n", curcpu()->ci_khz);
    442 }
    443 
    444 static void
    445 obio_set_cpu_speed(struct obio_softc *sc, int fast)
    446 {
    447 
    448 	if (sc->sc_voltage < 0)
    449 		return;
    450 
    451 	if (sc->sc_busspeed >= 0) {
    452 		/* set voltage and speed via gpio */
    453 		if (fast) {
    454 			bus_space_write_1(sc->sc_tag, sc->sc_bh,
    455 			    sc->sc_voltage, 5);
    456 			bus_space_write_1(sc->sc_tag, sc->sc_bh,
    457 			    sc->sc_busspeed, 5);
    458 		} else {
    459 			bus_space_write_1(sc->sc_tag, sc->sc_bh,
    460 			    sc->sc_busspeed, 4);
    461 			bus_space_write_1(sc->sc_tag, sc->sc_bh,
    462 			    sc->sc_voltage, 4);
    463 		}
    464 	}
    465 	else {
    466 		/* set voltage via gpio and speed via the 7447A's DFS bit */
    467 		if (fast) {
    468 			bus_space_write_1(sc->sc_tag, sc->sc_bh,
    469 			    sc->sc_voltage, 5);
    470 			DELAY(1000);
    471 		}
    472 
    473 		/* set DFS for all cpus */
    474 		cpu_set_dfs(fast ? 1 : 2);
    475 		DELAY(100);
    476 
    477 		if (!fast) {
    478 			bus_space_write_1(sc->sc_tag, sc->sc_bh,
    479 			    sc->sc_voltage, 4);
    480 			DELAY(1000);
    481 		}
    482 	}
    483 }
    484 
    485 static int
    486 obio_get_cpu_speed(struct obio_softc *sc)
    487 {
    488 
    489 	if (sc->sc_voltage < 0)
    490 		return 0;
    491 
    492 	if (sc->sc_busspeed >= 0) {
    493 		if (bus_space_read_1(sc->sc_tag, sc->sc_bh, sc->sc_busspeed)
    494 		    & 1)
    495 			return 1;
    496 	}
    497 	else
    498 		return cpu_get_dfs() == 1;
    499 
    500 	return 0;
    501 }
    502 
    503 static int
    504 sysctl_cpuspeed_temp(SYSCTLFN_ARGS)
    505 {
    506 	struct sysctlnode node = *rnode;
    507 	struct obio_softc *sc = node.sysctl_data;
    508 	int speed, mhz;
    509 
    510 	speed = obio_get_cpu_speed(sc);
    511 	switch (speed) {
    512 		case 0:
    513 			mhz = sc->sc_spd_lo;
    514 			break;
    515 		case 1:
    516 			mhz = sc->sc_spd_hi;
    517 			break;
    518 		default:
    519 			speed = -1;
    520 	}
    521 	node.sysctl_idata = mhz;
    522 	node.sysctl_data = &mhz;
    523 	if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) {
    524 		int new_reg;
    525 
    526 		new_reg = node.sysctl_idata;
    527 		if (new_reg == sc->sc_spd_lo) {
    528 			obio_set_cpu_speed(sc, 0);
    529 		} else if (new_reg == sc->sc_spd_hi) {
    530 			obio_set_cpu_speed(sc, 1);
    531 		} else {
    532 			printf("%s: new_reg %d\n", __func__, new_reg);
    533 			return EINVAL;
    534 		}
    535 		return 0;
    536 	}
    537 	return EINVAL;
    538 }
    539 
    540 static int
    541 sysctl_cpuspeed_cur(SYSCTLFN_ARGS)
    542 {
    543 	struct sysctlnode node = *rnode;
    544 	struct obio_softc *sc = node.sysctl_data;
    545 	int speed, mhz;
    546 
    547 	speed = obio_get_cpu_speed(sc);
    548 	switch (speed) {
    549 		case 0:
    550 			mhz = sc->sc_spd_lo;
    551 			break;
    552 		case 1:
    553 			mhz = sc->sc_spd_hi;
    554 			break;
    555 		default:
    556 			speed = -1;
    557 	}
    558 	node.sysctl_idata = mhz;
    559 	node.sysctl_data = &mhz;
    560 	return sysctl_lookup(SYSCTLFN_CALL(&node));
    561 }
    562 
    563 static int
    564 sysctl_cpuspeed_available(SYSCTLFN_ARGS)
    565 {
    566 	struct sysctlnode node = *rnode;
    567 	struct obio_softc *sc = node.sysctl_data;
    568 	char buf[128];
    569 	int speed;
    570 
    571 	speed = obio_get_cpu_speed(sc);
    572 	snprintf(buf, 128, "%d %d", sc->sc_spd_lo, sc->sc_spd_hi);
    573 	node.sysctl_data = buf;
    574 	return(sysctl_lookup(SYSCTLFN_CALL(&node)));
    575 }
    576 
    577 SYSCTL_SETUP(sysctl_ams_setup, "sysctl obio subtree setup")
    578 {
    579 
    580 	sysctl_createv(NULL, 0, NULL, NULL,
    581 		       CTLFLAG_PERMANENT,
    582 		       CTLTYPE_NODE, "machdep", NULL,
    583 		       NULL, 0, NULL, 0,
    584 		       CTL_MACHDEP, CTL_EOL);
    585 }
    586 
    587 #endif /* OBIO_SPEEDCONTROL */
    588