Index: include/device/pnp.h
===================================================================
--- include/device/pnp.h	(revision 1026)
+++ include/device/pnp.h	(working copy)
@@ -53,12 +53,13 @@
 /* PNP helper operations */
 
 struct io_info {
-	unsigned mask, set;
+	unsigned mask, set, val;
 };
 
 struct pnp_info {
 	struct device_operations *ops;
 	unsigned function;
+	unsigned enable;
 	unsigned flags;
 #define PNP_IO0  0x01
 #define PNP_IO1  0x02
@@ -68,7 +69,7 @@
 #define PNP_IRQ1 0x20
 #define PNP_DRQ0 0x40
 #define PNP_DRQ1 0x80
-	struct io_info io0, io1, io2, io3;
+	struct io_info io0, io1, io2, io3, irq0, irq1, drq0, drq1;
 };
 struct resource *pnp_get_resource(struct device * dev, unsigned index);
 void pnp_enable_devices(struct device *dev, struct device_operations *ops,
Index: superio/winbond/w83627hf/superio.c
===================================================================
--- superio/winbond/w83627hf/superio.c	(revision 1026)
+++ superio/winbond/w83627hf/superio.c	(working copy)
@@ -27,10 +27,8 @@
 #include <device/pnp.h>
 #include <console.h>
 #include <string.h>
-//#include <bitops.h>
 #include <uart8250.h>
 #include <keyboard.h>
-// #include <pc80/mc146818rtc.h>
 #include <statictree.h>
 #include "w83627hf.h"
 
@@ -113,36 +111,29 @@
 	}
 }
 
-static void w83627hf_init(struct device * dev)
+static void w83627hf_init_func(struct device * dev)
 {
-	struct superio_winbond_w83627hf_dts_config *conf;
 	struct resource *res0, *res1;
-	struct pc_keyboard keyboard;
 
-#if 1
-	printk(BIOS_ERR, "dummy init XXXX\n");
-#endif
+	printk(BIOS_DEBUG, "%s: %s dummy init XXXX\n",__func__, dev->dtsname);
 
-	if (!dev->enabled) {
-		return;
-	}
-
-	conf = dev->device_configuration;
 	switch(dev->path.pnp.device) {
 	case W83627HF_SP1:
 		res0 = find_resource(dev, PNP_IDX_IO0);
 #warning init_uart8250
+		printk(BIOS_DEBUG, "%s: Not calling init_uart8250.\n",__func__);
 		//init_uart8250(res0->base, &conf->com1);
 		break;
 	case W83627HF_SP2:
 		res0 = find_resource(dev, PNP_IDX_IO0);
 #warning init_uart8250
+		printk(BIOS_DEBUG, "%s: Not calling init_uart8250.\n",__func__);
 		//init_uart8250(res0->base, &conf->com2);
 		break;
 	case W83627HF_KBC:
 		res0 = find_resource(dev, PNP_IDX_IO0);
 		res1 = find_resource(dev, PNP_IDX_IO1);
-		init_pc_keyboard(res0->base, res1->base, &keyboard);
+		init_pc_keyboard(res0->base, res1->base, NULL);
 		break;
 	case W83627HF_HWM:
 		res0 = find_resource(dev, PNP_IDX_IO0);
@@ -177,6 +168,14 @@
 
 }
 
+void w83627hf_enable_resources(struct device * dev)
+{
+	struct device * child;
+	for(child = dev->link[0].children; child; child = child->sibling)
+		if (child->path.type == DEVICE_PATH_PNP)
+			w83627hf_pnp_enable_resources(child);
+}
+
 void w83627hf_pnp_enable(struct device * dev)
 {
 
@@ -189,10 +188,22 @@
 		pnp_exit_ext_func_mode(dev);
 	}
 }
+
+static void w83627hf_init(struct device * dev)
+{
+	struct device * child;
+	for(child = dev->link[0].children; child; child = child->sibling)
+		/* All children should be PNP. */
+		if (child->path.type == DEVICE_PATH_PNP)
+			w83627hf_init_func(child);
+}
+
 static void phase3_chip_setup_dev(struct device *dev);
+
 struct device_operations w83627hf_ops = {
+	.id = {.type = DEVICE_ID_PNP},
 	.phase3_chip_setup_dev   = phase3_chip_setup_dev,
-	.phase3_enable           = w83627hf_pnp_enable_resources,
+	.phase3_enable           = w83627hf_enable_resources,
 	.phase4_read_resources   = pnp_read_resources,
 	.phase4_set_resources    = w83627hf_pnp_set_resources,
 	.phase5_enable_resources = w83627hf_pnp_enable,
@@ -200,23 +211,109 @@
 };
 
 static struct pnp_info pnp_dev_info[] = {
-	{ &w83627hf_ops, W83627HF_FDC,  PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
-	{ &w83627hf_ops, W83627HF_PP,   PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
-	{ &w83627hf_ops, W83627HF_SP1,  PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
-	{ &w83627hf_ops, W83627HF_SP2,  PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
-	// No 4 { 0,},
-	{ &w83627hf_ops, W83627HF_KBC,  PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, { 0x7ff, 0 }, { 0x7ff, 0x4}, },
-	{ &w83627hf_ops, W83627HF_CIR, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
-	{ &w83627hf_ops, W83627HF_GAME_MIDI_GPIO1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7ff, 0 }, {0x7fe, 0x4}, },
-	{ &w83627hf_ops, W83627HF_GPIO2, },
-	{ &w83627hf_ops, W83627HF_GPIO3, },
-	{ &w83627hf_ops, W83627HF_ACPI, },
-	{ &w83627hf_ops, W83627HF_HWM,  PNP_IO0 | PNP_IRQ0, { 0xff8, 0 }, },
+				/* Enable,  All resources need by dev,  io_info_structs */
+	{ &w83627hf_ops, W83627HF_FDC, 0, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
+	{ &w83627hf_ops, W83627HF_PP, 0,  PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
+	{ &w83627hf_ops, W83627HF_SP1, 0, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+	{ &w83627hf_ops, W83627HF_SP2, 0, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+	{ 0,},
+	{ &w83627hf_ops, W83627HF_KBC, 0, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, { 0x7ff, 0 }, { 0x7ff, 0x4}, },
+	{ &w83627hf_ops, W83627HF_CIR, 0,PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+	{ &w83627hf_ops, W83627HF_GAME_MIDI_GPIO1, 0,PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7ff, 0 }, {0x7fe, 0x4}, },
+	{ &w83627hf_ops, W83627HF_GPIO2, 0 },
+	{ &w83627hf_ops, W83627HF_GPIO3, 0 },
+	{ &w83627hf_ops, W83627HF_ACPI, 0 },
+	{ &w83627hf_ops, W83627HF_HWM, 0, PNP_IO0 | PNP_IRQ0, { 0xff8, 0 }, },
 };
 
 
 static void phase3_chip_setup_dev(struct device *dev)
 {
+	/* Get dts values and populate pnp_dev_info. */
+	const struct superio_winbond_w83627hf_dts_config * const conf = dev->device_configuration;
+
+	/* Floppy */
+	if(conf->floppyconf) {
+		pnp_dev_info[W83627HF_FDC].enable = conf->floppyenable;
+		pnp_dev_info[W83627HF_FDC].io0.val = conf->floppyio;
+		pnp_dev_info[W83627HF_FDC].irq0.val = conf->floppyirq;
+		pnp_dev_info[W83627HF_FDC].drq0.val = conf->floppydrq;
+	}
+
+	/* Parallel port */
+	if(conf->ppconf) {
+		pnp_dev_info[W83627HF_PP].enable = conf->ppenable;
+		pnp_dev_info[W83627HF_PP].io0.val = conf->ppio;
+		pnp_dev_info[W83627HF_PP].irq0.val = conf->ppirq;
+	}
+
+	/* COM1 */
+	if(conf->com1conf) {
+		pnp_dev_info[W83627HF_SP1].enable = conf->com1enable;
+		pnp_dev_info[W83627HF_SP1].io0.val = conf->com1io;
+		pnp_dev_info[W83627HF_SP1].irq0.val = conf->com1irq;
+	}
+
+	/* COM2 */
+	if(conf->com2conf) {
+		pnp_dev_info[W83627HF_SP2].enable = conf->com2enable;
+		pnp_dev_info[W83627HF_SP2].io0.val = conf->com2io;
+		pnp_dev_info[W83627HF_SP2].irq0.val = conf->com2irq;
+	}
+
+	/* Keyboard */
+	if(conf->kbconf) {
+		pnp_dev_info[W83627HF_KBC].enable = conf->kbenable;
+		pnp_dev_info[W83627HF_KBC].io0.val = conf->kbio;
+		pnp_dev_info[W83627HF_KBC].io1.val = conf->kbio2;
+		pnp_dev_info[W83627HF_KBC].irq0.val = conf->kbirq;
+		pnp_dev_info[W83627HF_KBC].irq1.val = conf->kbirq2;
+	}
+
+	/* Consumer IR */
+	if(conf->circonf) {
+		pnp_dev_info[W83627HF_CIR].enable = conf->cirenable;
+	}
+
+	/* Game port */
+	if(conf->gameconf) {
+		pnp_dev_info[W83627HF_GAME_MIDI_GPIO1].enable = conf->gameenable;
+		pnp_dev_info[W83627HF_GAME_MIDI_GPIO1].io0.val = conf->gameio;
+		pnp_dev_info[W83627HF_GAME_MIDI_GPIO1].io1.val = conf->gameio2;
+		pnp_dev_info[W83627HF_GAME_MIDI_GPIO1].irq0.val = conf->gameirq;
+	}
+
+	/* GPIO2 */
+	if(conf->gpio2conf) {
+		pnp_dev_info[W83627HF_GPIO2].enable = conf->gpio2enable;
+	}
+
+	/* GPIO3 */
+	if(conf->gpio3conf) {
+		pnp_dev_info[W83627HF_GPIO3].enable = conf->gpio3enable;
+	}
+
+	/* ACPI */
+	if(conf->acpiconf) {
+		pnp_dev_info[W83627HF_ACPI].enable = conf->acpienable;
+	}
+
+	/* Hardware Monitor */
+	if(conf->hwmconf) {
+		pnp_dev_info[W83627HF_HWM].enable = conf->hwmenable;
+		pnp_dev_info[W83627HF_HWM].io0.val = conf->hwmio;
+		pnp_dev_info[W83627HF_HWM].irq0.val = conf->hwmirq;
+	}
+
+	/* Initialize SuperIO for PNP children. */
+	if (!dev->links) {
+		dev->links = 1;
+		dev->link[0].dev = dev;
+		dev->link[0].children = NULL;
+		dev->link[0].link = 0;
+	}
+
+	/* Call init with updated tables to create children. */
 	pnp_enable_devices(dev, &w83627hf_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
 }
 
Index: superio/winbond/w83627hf/dts
===================================================================
--- superio/winbond/w83627hf/dts	(revision 1026)
+++ superio/winbond/w83627hf/dts	(working copy)
@@ -23,32 +23,32 @@
 	/* To override any of these, put the over-ride in mainboard dts. */
 
 	/* Floppy */
-	floppydev = "0x0";
+	floppyconf = "0";
 	floppyenable = "0";
 	floppyio = "0x3f0";
 	floppyirq = "0x60";
 	floppydrq = "0x02";
 
 	/* Parallel port */
-	ppdev = "2";
+	ppconf = "0";
 	ppenable = "0";
 	ppio = "0x378";
 	ppirq = "7";
 
 	/* COM1 */
-	com1dev = "2";
+	com1conf = "0";
 	com1enable = "0";
 	com1io = "0x3f8";
 	com1irq = "4";
 
 	/* COM2 */
-	com2dev = "3";
+	com2conf = "0";
 	com2enable = "0";
 	com2io = "0x2f8";
 	com2irq = "3";
 
 	/* Keyboard */
-	kbdev = "5";
+	kbconf = "0";
 	kbenable = "0";
 	kbio = "0x60";
 	kbio2 = "0x62";
@@ -56,30 +56,30 @@
 	kbirq2 = "12";
 
 	/* Consumer IR */
-	cirdev = "6";
+	circonf = "0";
 	cirenable = "0";
 
 	/* Game port */
-	gamedev = "7";
+	gameconf = "0";
 	gameenable = "0";
 	gameio = "0x220";
 	gameio2 = "0x400";
 	gameirq = "9";
 
 	/* GPIO2 */
-	gpio2dev = "8";
+	gpio2conf = "0";
 	gpio2enable = "0";
 
 	/* GPIO3 */
-	gpio3dev = "9";
+	gpio3conf = "0";
 	gpio3enable = "0";
 
 	/* ACPI */
-	acpidev = "0xa";
+	acpiconf = "0";
 	acpienable = "0";
 
 	/* Hardware Monitor */
-	hwmdev = "0xb";
+	hwmconf = "0";
 	hwmenable = "0";
 	hwmio = "0x290";
 	hwmirq = "5";
Index: mainboard/amd/serengeti/dts
===================================================================
--- mainboard/amd/serengeti/dts	(revision 1026)
+++ mainboard/amd/serengeti/dts	(working copy)
@@ -79,9 +79,16 @@
 		pci@18,1 {};
 		pci@18,2 {};
 		pci@18,3 {};
-		ioport@2e {
-			/config/("superio/winbond/w83627hf/dts");
-			com1enable = "1";
-		};
 	};
+	ioport@2e {
+		/config/("superio/winbond/w83627hf/dts");
+		kbconf = "1";
+		kbenable = "1";
+
+		com1conf = "1";
+		com1enable = "1";
+
+		hwmconf = "1";
+		hwmenable = "1";
+	};
 };
Index: device/device.c
===================================================================
--- device/device.c	(revision 1026)
+++ device/device.c	(working copy)
@@ -254,7 +254,12 @@
 	last_dev_p = &dev->next;
 
 	/* Give the device a name. */
-	sprintf(dev->dtsname, "dynamic %s", dev_path(dev));
+	if (dev->id.type == DEVICE_ID_PNP && 
+			    parent->dev->id.type == DEVICE_ID_PNP)
+		sprintf(dev->dtsname, "%s_pnp_child_%d", parent->dev->dtsname,
+			dev->id.pnp.device);
+	else
+		sprintf(dev->dtsname, "dynamic %s", dev_path(dev));
 
 	/* Run the device specific constructor as last part of the chain
 	 * so it gets the chance to overwrite the "inherited" values above
@@ -1093,7 +1098,8 @@
 	printk(debug_level, "%s%s(%s): enabled %d have_resources %d devfn %x\n",
 	       depth_str, dev->dtsname, dev_path(dev), dev->enabled,
 	       dev->have_resources,
-	       dev->path.type == DEVICE_PATH_PCI ? dev->path.pci.devfn : 0xff);
+	       dev->path.type == DEVICE_PATH_PCI ? dev->path.pci.devfn :
+		dev->path.type == DEVICE_PATH_PNP ? dev->path.pnp.device : 0xff);
 	for (i = 0; i < dev->links; i++) {
 		for (sibling = dev->link[i].children; sibling;
 		     sibling = sibling->sibling)
Index: device/pnp_device.c
===================================================================
--- device/pnp_device.c	(revision 1026)
+++ device/pnp_device.c	(working copy)
@@ -156,7 +156,6 @@
 	resource = new_resource(dev, index);
 
 	/* Initialize the resource. */
-	resource->limit = 0xffff;
 	resource->flags |= IORESOURCE_IO;
 
 	/* Get the resource size. */
@@ -189,6 +188,8 @@
 	resource->align = gran;
 	resource->limit = info->mask | (step - 1);
 	resource->size = 1 << gran;
+	resource->base = info->val;
+	resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
 }
 
 static void get_resources(struct device *dev, struct pnp_info *info)
@@ -211,21 +212,29 @@
 		resource = new_resource(dev, PNP_IDX_IRQ0);
 		resource->size = 1;
 		resource->flags |= IORESOURCE_IRQ;
+		resource->base = info->irq0.val;
+		resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
 	}
 	if (info->flags & PNP_IRQ1) {
 		resource = new_resource(dev, PNP_IDX_IRQ1);
 		resource->size = 1;
 		resource->flags |= IORESOURCE_IRQ;
+		resource->base = info->irq1.val;
+		resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
 	}
 	if (info->flags & PNP_DRQ0) {
 		resource = new_resource(dev, PNP_IDX_DRQ0);
 		resource->size = 1;
 		resource->flags |= IORESOURCE_DRQ;
+		resource->base = info->drq0.val;
+		resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
 	}
 	if (info->flags & PNP_DRQ1) {
 		resource = new_resource(dev, PNP_IDX_DRQ1);
 		resource->size = 1;
 		resource->flags |= IORESOURCE_DRQ;
+		resource->base = info->drq0.val;
+		resource->flags |= IORESOURCE_FIXED || IORESOURCE_ASSIGNED;
 	}
 }
 
@@ -243,12 +252,23 @@
 	/* Setup the ops and resources on the newly allocated devices. */
 	for (i = 0; i < functions; i++) {
 		path.pnp.device = info[i].function;
-		dev = alloc_find_dev(base_dev->bus, &path, &id);
 
-		/* Don't initialize a device multiple times. */
-		if (dev->ops)
+		dev = find_dev_path(&base_dev->link[0], &path);
+
+		if (dev) {
+			printk(BIOS_DEBUG,"%s: %s is already at %s.\n",
+			       __func__, dev->dtsname, dev_path(dev));
 			continue;
+		}
+		
+		dev = alloc_dev(&base_dev->link[0], &path, &id);
 
+		if (!dev)
+			printk(BIOS_DEBUG,"%s: Couldn't allocate child %d.\n",
+			       __func__, i);
+
+		dev->enabled = info[i].enable;
+
 		if (info[i].ops == 0) {
 			dev->ops = ops;
 		} else {
