- Bump the LinuxBIOS major version
- Rename chip_config chip_operations throughout the tree
- Fix Config.lb on most of the Opteron Ports
- Fix the amd 8000 chipset support for setting the subsystem vendor and device ids
- Add detection of devices that are on the motherboard (i.e. In Config.lb)
- Baby step in getting the resource limit handling correct, Ignore fixed resources
- Only call enable_childrens_resources on devices we know will have children
  For some busses like i2c it is non-sense and we don't want it.
- Set the resource limits for pnp devices resources.
- Improve the resource size detection for pnp devices.
- Added a configuration register to amd8111_ide.c so we can enable/disable individual ide channels
- Added a header file to hold the prototype of isa_dma_init
- Fixed most of the superio chips so the should work now, the via superio pci device is the exception.
- The code compiles and runs so it is time for me to go to bed.


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1698 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/src/southbridge/amd/amd8111/amd8111.c b/src/southbridge/amd/amd8111/amd8111.c
index a9b132c..6e7022c 100644
--- a/src/southbridge/amd/amd8111/amd8111.c
+++ b/src/southbridge/amd/amd8111/amd8111.c
@@ -9,31 +9,32 @@
 	device_t lpc_dev;
 	device_t bus_dev;
 	unsigned index;
-	uint32_t dword;
-	uint16_t reg_old, reg;
-	uint8_t byte;
-
+	unsigned reg_old, reg;
 
 	/* See if we are on the behind the amd8111 pci bridge */
 	bus_dev = dev->bus->dev;
 	if ((bus_dev->vendor == PCI_VENDOR_ID_AMD) && 
-	    (bus_dev->device == PCI_DEVICE_ID_AMD_8111_PCI)) {
+		(bus_dev->device == PCI_DEVICE_ID_AMD_8111_PCI)) 
+	{
 		unsigned devfn;
 		devfn = bus_dev->path.u.pci.devfn + (1 << 3);
 		lpc_dev = dev_find_slot(bus_dev->bus->secondary, devfn);
 		index = ((dev->path.u.pci.devfn & ~7) >> 3) + 8;
+		if (dev->path.u.pci.devfn == 2) { /* EHCI */
+			index = 16;
+		}
 	} else {
 		unsigned devfn;
 		devfn = (dev->path.u.pci.devfn) & ~7;
 		lpc_dev = dev_find_slot(dev->bus->secondary, devfn);
 		index = dev->path.u.pci.devfn & 7;
 	}
-
-	if ((!lpc_dev) || (index >= 16)) {
+	if ((!lpc_dev) || (index >= 17)) {
 		return;
 	}
 	if ((lpc_dev->vendor != PCI_VENDOR_ID_AMD) ||
-	    (lpc_dev->device != PCI_DEVICE_ID_AMD_8111_ISA)) {
+		(lpc_dev->device != PCI_DEVICE_ID_AMD_8111_ISA)) 
+	{
 		uint32_t id;
 		id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
 		if (id != (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8111_ISA << 16))) {
@@ -41,34 +42,29 @@
 		}
 	}
 
-        /* Now read the vendor and device id */
-        dword= pci_read_config32(dev, PCI_VENDOR_ID);
-#if 0
-	printk_debug(" %s dev->vendor= %04x, dev->device= %04x, id = %08x\n", dev_path(dev), dev->vendor, dev->device, dword);
-#endif
-	
-        if (dword == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8111_USB2 << 16)))  {
-		if(!dev->enabled) {
-		        byte = pci_read_config8(lpc_dev, 0x47);
-		        byte |= (1<<7);
-		        pci_write_config8(lpc_dev, 0x47, byte);
-			return;
+	if (index < 16) {
+		reg = reg_old = pci_read_config16(lpc_dev, 0x48);
+		reg &= ~(1 << index);
+		if (dev->enabled) {
+			reg |= (1 << index);
 		}
-		
+		if (reg != reg_old) {
+			pci_write_config16(lpc_dev, 0x48, reg);
+		}
 	}
-	
-	reg = reg_old = pci_read_config16(lpc_dev, 0x48);
-	reg &= ~(1 << index);
-	if (dev->enabled) {
-		reg |= (1 << index);
+	else if (index == 16) {
+		reg = reg_old = pci_read_config8(lpc_dev, 0x47);
+		reg &= ~(1 << 7);
+		if (!dev->enabled) {
+			reg |= (1 << 7);
+		}
+		if (reg != reg_old) {
+			pci_write_config8(lpc_dev, 0x47, reg);
+		}
 	}
-	if (reg != reg_old) {
-		pci_write_config16(lpc_dev, 0x48, reg);
-	}
-	
 }
 
 struct chip_operations southbridge_amd_amd8111_ops = {
-	.name       = "AMD 8111 Southbridge",
+	.name       = "AMD 8111",
 	.enable_dev = amd8111_enable,
 };
diff --git a/src/southbridge/amd/amd8111/amd8111_ac97.c b/src/southbridge/amd/amd8111/amd8111_ac97.c
index 36ed41f..40f663d 100644
--- a/src/southbridge/amd/amd8111/amd8111_ac97.c
+++ b/src/southbridge/amd/amd8111/amd8111_ac97.c
@@ -8,14 +8,24 @@
 #include <device/pci_ops.h>
 #include "amd8111.h"
 
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	pci_write_config32(dev, 0x2c, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = lpci_set_subsystem,
+};
 
 static struct device_operations ac97audio_ops  = {
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
-//	.enable           = amd8111_enable,
+	.enable           = amd8111_enable,
 	.init             = 0,
 	.scan_bus         = 0,
+	.ops_pci          = &lops_pci,
 };
 
 static struct pci_driver ac97audio_driver __pci_driver = {
@@ -29,9 +39,10 @@
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
-//	.enable           = amd8111_enable,
+	.enable           = amd8111_enable,
 	.init             = 0,
 	.scan_bus         = 0,
+	.ops_pci          = &lops_pci,
 };
 
 static struct pci_driver ac97modem_driver __pci_driver = {
diff --git a/src/southbridge/amd/amd8111/amd8111_acpi.c b/src/southbridge/amd/amd8111/amd8111_acpi.c
index 557e54f..38c3269 100644
--- a/src/southbridge/amd/amd8111/amd8111_acpi.c
+++ b/src/southbridge/amd/amd8111/amd8111_acpi.c
@@ -3,10 +3,12 @@
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
+#include <device/smbus.h>
 #include <pc80/mc146818rtc.h>
 #include <bitops.h>
 #include <arch/io.h>
 #include "amd8111.h"
+#include "amd8111_smbus.h"
 
 #define PREVIOUS_POWER_STATE 0x43
 #define MAINBOARD_POWER_OFF 0
@@ -19,6 +21,51 @@
 #endif
 
 
+static int lsmbus_recv_byte(device_t dev)
+{
+	unsigned device;
+	struct resource *res;
+
+	device = dev->path.u.i2c.device;
+	res = find_resource(dev->bus->dev, 0x20);
+	
+	return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, uint8_t val)
+{
+	unsigned device;
+	struct resource *res;
+
+	device = dev->path.u.i2c.device;
+	res = find_resource(dev->bus->dev, 0x20);
+
+	return do_smbus_send_byte(res->base, device, val);
+}
+
+
+static int lsmbus_read_byte(device_t dev, uint8_t address)
+{
+	unsigned device;
+	struct resource *res;
+
+	device = dev->path.u.i2c.device;
+	res = find_resource(dev->bus->dev, 0x20);
+	
+	return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
+{
+	unsigned device;
+	struct resource *res;
+
+	device = dev->path.u.i2c.device;
+	res = find_resource(dev->bus->dev, 0x20);
+	
+	return do_smbus_write_byte(res->base, device, address, val);
+}
+
 static void acpi_init(struct device *dev)
 {
 	uint8_t byte;
@@ -29,29 +76,26 @@
 
 #if 0
 	printk_debug("ACPI: disabling NMI watchdog.. ");
-	pci_read_config_byte(dev, 0x49, &byte);
-	pci_write_config_byte(dev, 0x49, byte | (1<<2));
+	byte = pci_read_config8(dev, 0x49);
+	pci_write_config8(dev, 0x49, byte | (1<<2));
 
 
-	pci_read_config_byte(dev, 0x41, &byte);
-	pci_write_config_byte(dev, 0x41, byte | (1<<6)|(1<<2));
+	byte = pci_read_config8(dev, 0x41);
+	pci_write_config8(dev, 0x41, byte | (1<<6)|(1<<2));
 
 	/* added from sourceforge */
-	pci_read_config_byte(dev, 0x48, &byte);
-	pci_write_config_byte(dev, 0x48, byte | (1<<3));
+	byte = pci_read_config8(dev, 0x48);
+	pci_write_config8(dev, 0x48, byte | (1<<3));
 
 	printk_debug("done.\n");
 
 
 	printk_debug("ACPI: Routing IRQ 12 to PS2 port.. ");
-	pci_read_config_word(dev, 0x46, &word);
-	pci_write_config_word(dev, 0x46, word | (1<<9));
+	word = pci_read_config16(dev, 0x46);
+	pci_write_config16(dev, 0x46, word | (1<<9));
 	printk_debug("done.\n");
 
 	
-	printk_debug("ACPI: setting PM class code.. ");
-	pci_write_config_dword(dev, 0x60, 0x06800000);
-	printk_debug("done.\n");
 #endif
 	on = MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
 	get_option(&on, "power_on_after_fail");
@@ -78,33 +122,63 @@
 
 static void acpi_read_resources(device_t dev)
 {
+	struct resource *resource;
+
 	/* Handle the generic bars */
 	pci_dev_read_resources(dev);
 
-	if ((dev->resources + 1) < MAX_RESOURCES) {
-		struct resource *resource = &dev->resource[dev->resources];
-		dev->resources++;
-		resource->base  = 0;
-		resource->size  = 256;
-		resource->align = log2(256);
-		resource->gran  = log2(256);
-		resource->limit = 65536;
-		resource->flags = IORESOURCE_IO;
-		resource->index = 0x58;
-	}
-	else {
-		printk_err("%s Unexpected resource shortage\n",
-			dev_path(dev));
-	}
+	/* Add the ACPI/SMBUS bar */
+	resource = new_resource(dev, 0x58);
+	resource->base  = 0;
+	resource->size  = 256;
+	resource->align = log2(256);
+	resource->gran  = log2(256);
+	resource->limit = 65536;
+	resource->flags = IORESOURCE_IO;
+	resource->index = 0x58;
 }
 
+static void acpi_enable_resources(device_t dev)
+{
+	uint8_t byte;
+	/* Enable the generic pci resources */
+	pci_dev_enable_resources(dev);
+
+	/* Enable the ACPI/SMBUS Bar */
+	byte = pci_read_config8(dev, 0x41);
+	byte |= (1 << 7);
+	pci_write_config8(dev, 0x41, byte);
+
+	/* Set the class code */
+	pci_write_config32(dev, 0x60, 0x06800000);
+	
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	pci_write_config32(dev, 0x7c, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+	.recv_byte  = lsmbus_recv_byte,
+	.send_byte  = lsmbus_send_byte,
+	.read_byte  = lsmbus_read_byte,
+	.write_byte = lsmbus_write_byte,
+};
+static struct pci_operations lops_pci = {
+	.set_subsystem = lpci_set_subsystem,
+};
+
 static struct device_operations acpi_ops  = {
 	.read_resources   = acpi_read_resources,
 	.set_resources    = pci_dev_set_resources,
-	.enable_resources = pci_dev_enable_resources,
+	.enable_resources = acpi_enable_resources,
 	.init             = acpi_init,
-	.scan_bus         = 0,
-//	.enable           = amd8111_enable,
+	.scan_bus         = scan_static_bus,
+	.enable           = amd8111_enable,
+	.ops_pci          = &lops_pci,
+	.ops_smbus_bus    = &lops_smbus_bus,
 };
 
 static struct pci_driver acpi_driver __pci_driver = {
diff --git a/src/southbridge/amd/amd8111/amd8111_early_smbus.c b/src/southbridge/amd/amd8111/amd8111_early_smbus.c
index 5157609..8ad3589 100644
--- a/src/southbridge/amd/amd8111/amd8111_early_smbus.c
+++ b/src/southbridge/amd/amd8111/amd8111_early_smbus.c
@@ -1,14 +1,7 @@
+#include "amd8111_smbus.h"
+
 #define SMBUS_IO_BASE 0x0f00
 
-#define SMBGSTATUS 0xe0
-#define SMBGCTL    0xe2
-#define SMBHSTADDR 0xe4
-#define SMBHSTDAT  0xe6
-#define SMBHSTCMD  0xe8
-#define SMBHSTFIFO 0xe9
-
-#define SMBUS_TIMEOUT (100*1000*10)
-
 static void enable_smbus(void)
 {
 	device_t dev;
@@ -25,114 +18,22 @@
 	outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
 }
 
-
-static inline void smbus_delay(void)
+static int smbus_recv_byte(unsigned device)
 {
-	outb(0x80, 0x80);
+	return do_smbus_recv_byte(SMBUS_IO_BASE, device);
 }
 
-static int smbus_wait_until_ready(void)
+static int smbus_send_byte(unsigned device, unsigned char val)
 {
-	unsigned long loops;
-	loops = SMBUS_TIMEOUT;
-	do {
-		unsigned short val;
-		smbus_delay();
-		val = inw(SMBUS_IO_BASE + SMBGSTATUS);
-		if ((val & 0x800) == 0) {
-			break;
-		}
-		if(loops == (SMBUS_TIMEOUT / 2)) {
-			outw(inw(SMBUS_IO_BASE + SMBGSTATUS), 
-				SMBUS_IO_BASE + SMBGSTATUS);
-		}
-	} while(--loops);
-	return loops?0:-2;
-}
-
-static int smbus_wait_until_done(void)
-{
-	unsigned long loops;
-	loops = SMBUS_TIMEOUT;
-	do {
-		unsigned short val;
-		smbus_delay();
-		
-		val = inw(SMBUS_IO_BASE + SMBGSTATUS);
-		if (((val & 0x8) == 0) | ((val & 0x437) != 0)) {
-			break;
-		}
-	} while(--loops);
-	return loops?0:-3;
+	return do_smbus_send_byte(SMBUS_IO_BASE, device, val);
 }
 
 static int smbus_read_byte(unsigned device, unsigned address)
 {
-	unsigned char global_control_register;
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready() < 0) {
-		return -2;
-	}
-	
-	/* setup transaction */
-	/* disable interrupts */
-	outw(inw(SMBUS_IO_BASE + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), SMBUS_IO_BASE + SMBGCTL);
-	/* set the device I'm talking too */
-	outw(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADDR);
-	/* set the command/address... */
-	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
-	/* set up for a byte data read */
-	outw((inw(SMBUS_IO_BASE + SMBGCTL) & ~7) | (0x2), SMBUS_IO_BASE + SMBGCTL);
-
-	/* clear any lingering errors, so the transaction will run */
-	/* Do I need to write the bits to a 1 to clear an error? */
-	outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
-
-	/* clear the data word...*/
-	outw(0, SMBUS_IO_BASE + SMBHSTDAT);
-
-	/* start the command */
-	outw((inw(SMBUS_IO_BASE + SMBGCTL) | (1 << 3)), SMBUS_IO_BASE + SMBGCTL);
-
-
-	/* poll for transaction completion */
-	if (smbus_wait_until_done() < 0) {
-		return -3;
-	}
-
-	global_status_register = inw(SMBUS_IO_BASE + SMBGSTATUS);
-
-	/* read results of transaction */
-	byte = inw(SMBUS_IO_BASE + SMBHSTDAT) & 0xff;
-
-	if (global_status_register != (1 << 4)) {
-		return -1;
-	}
-	return byte;
+	return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
 }
 
-static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+static int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
 {
-	if (smbus_wait_until_ready() < 0) {
-		return;
-	}
-
-	/* by LYH */
-	outb(0x37,SMBUS_IO_BASE + SMBGSTATUS);
-	/* set the device I'm talking too */
-	outw(((device & 0x7f) << 1) | 0, SMBUS_IO_BASE + SMBHSTADDR);
-
-	/* data to send */
-	outb(val, SMBUS_IO_BASE + SMBHSTDAT);
-
-	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
-
-	/* start the command */
-	outb(0xa, SMBUS_IO_BASE + SMBGCTL);
-
-	/* poll for transaction completion */
-	smbus_wait_until_done();
-	return;
+	return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val);
 }
diff --git a/src/southbridge/amd/amd8111/amd8111_enable_rom.c b/src/southbridge/amd/amd8111/amd8111_enable_rom.c
index 468801a..8c4e4da 100644
--- a/src/southbridge/amd/amd8111/amd8111_enable_rom.c
+++ b/src/southbridge/amd/amd8111/amd8111_enable_rom.c
@@ -4,12 +4,12 @@
 	unsigned char byte;
 	device_t dev;
 
-	/* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */
+	/* Enable 5MB rom access at 0xFFB00000 - 0xFFFFFFFF */
 	/* Locate the amd8111 */
 	dev = pci_locate_device(PCI_ID(0x1022, 0x7468), 0);
 
-	/* Set the 4MB enable bit bit */
+	/* Set the 5MB enable bits */
 	byte = pci_read_config8(dev, 0x43);
-	byte |= 0x80;
+	byte |= 0xC0;
 	pci_write_config8(dev, 0x43, byte);
 }
diff --git a/src/southbridge/amd/amd8111/amd8111_ide.c b/src/southbridge/amd/amd8111/amd8111_ide.c
index a922746..1674844 100644
--- a/src/southbridge/amd/amd8111/amd8111_ide.c
+++ b/src/southbridge/amd/amd8111/amd8111_ide.c
@@ -7,21 +7,21 @@
 
 static void ide_init(struct device *dev)
 {
-
+	struct southbridge_amd_amd8111_config *conf;
 	/* Enable ide devices so the linux ide driver will work */
 	uint16_t word;
 	uint8_t byte;
-	int enable_a=1, enable_b=1;
+	conf = dev->chip_info;
 
 	word = pci_read_config16(dev, 0x40);
 	/* Ensure prefetch is disabled */
 	word &= ~((1 << 15) | (1 << 13));
-	if (enable_b) {
+	if (conf->ide1_enable) {
 		/* Enable secondary ide interface */
 		word |= (1<<0);
 		printk_debug("IDE1 ");
 	}
-	if (enable_a) {
+	if (conf->ide0_enable) {
 		/* Enable primary ide interface */
 		word |= (1<<1);
 		printk_debug("IDE0 ");
@@ -40,12 +40,22 @@
 	pci_write_config16(dev, 0x42, word);
 }
 
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	pci_write_config32(dev, 0x70, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+	.set_subsystem = lpci_set_subsystem,
+};
 static struct device_operations ide_ops  = {
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
 	.init             = ide_init,
 	.scan_bus         = 0,
+	.enable           = amd8111_enable,
+	.ops_pci          = &lops_pci
 };
 
 static struct pci_driver ide_driver __pci_driver = {
diff --git a/src/southbridge/amd/amd8111/amd8111_lpc.c b/src/southbridge/amd/amd8111/amd8111_lpc.c
index 6441c86..b94b19b 100644
--- a/src/southbridge/amd/amd8111/amd8111_lpc.c
+++ b/src/southbridge/amd/amd8111/amd8111_lpc.c
@@ -7,10 +7,9 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
 #include "amd8111.h"
 
-void isa_dma_init(void); /* from /pc80/isa-dma.c */
-
 #define NMI_OFF 0
 
 struct ioapicreg {
@@ -85,7 +84,7 @@
 			return;
 		}
 		printk_spew("for IRQ, reg 0x%08x value 0x%08x 0x%08x\n", 
-			    a->reg, a->value_low, a->value_high);
+			a->reg, a->value_low, a->value_high);
 	}
 }
 
@@ -158,43 +157,36 @@
 
 static void amd8111_lpc_read_resources(device_t dev)
 {
-	unsigned int reg;
+	struct resource *res;
 
 	/* Get the normal pci resources of this device */
 	pci_dev_read_resources(dev);
 
-	/* Find my place in the resource list */
-	reg = dev->resources;
-
 	/* Add an extra subtractive resource for both memory and I/O */
-	dev->resource[reg].base  = 0;
-	dev->resource[reg].size  = 0;
-	dev->resource[reg].align = 0;
-	dev->resource[reg].gran  = 0;
-	dev->resource[reg].limit = 0;
-	dev->resource[reg].flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
-	dev->resource[reg].index = 0;
-	reg++;
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
 	
-	dev->resource[reg].base  = 0;
-	dev->resource[reg].size  = 0;
-	dev->resource[reg].align = 0;
-	dev->resource[reg].gran  = 0;
-	dev->resource[reg].limit = 0;
-	dev->resource[reg].flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
-	dev->resource[reg].index = 0;
-	reg++;
-	
-	dev->resources = reg;
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+	res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
 }
 
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	pci_write_config32(dev, 0x70, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+	.set_subsystem = lpci_set_subsystem,
+};
 static struct device_operations lpc_ops  = {
 	.read_resources   = amd8111_lpc_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
 	.init             = lpc_init,
 	.scan_bus         = scan_static_bus,
-//	.enable           = amd8111_enable,
+	.enable           = amd8111_enable,
+	.ops_pci          = &lops_pci,
 };
 
 static struct pci_driver lpc_driver __pci_driver = {
diff --git a/src/southbridge/amd/amd8111/amd8111_nic.c b/src/southbridge/amd/amd8111/amd8111_nic.c
index 512b268..b379208 100644
--- a/src/southbridge/amd/amd8111/amd8111_nic.c
+++ b/src/southbridge/amd/amd8111/amd8111_nic.c
@@ -13,7 +13,7 @@
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
-//	.enable           = amd8111_enable,
+	.enable           = amd8111_enable,
 	.init             = 0,
 	.scan_bus         = 0,
 };
diff --git a/src/southbridge/amd/amd8111/amd8111_pci.c b/src/southbridge/amd/amd8111/amd8111_pci.c
index 29d3fb8..9fe1f98 100644
--- a/src/southbridge/amd/amd8111/amd8111_pci.c
+++ b/src/southbridge/amd/amd8111/amd8111_pci.c
@@ -45,12 +45,17 @@
 	pci_write_config32(dev, 0x1c, dword);
 }
 
+static struct pci_operations lops_pci = {
+	.set_subsystem = 0,
+};
+
 static struct device_operations pci_ops  = {
 	.read_resources   = pci_bus_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_bus_enable_resources,
 	.init             = pci_init,
 	.scan_bus         = pci_scan_bridge,
+	.ops_pci          = &lops_pci,
 };
 
 static struct pci_driver pci_driver __pci_driver = {
diff --git a/src/southbridge/amd/amd8111/amd8111_smbus.c b/src/southbridge/amd/amd8111/amd8111_smbus.c
index bfa78b3..2fec77b 100644
--- a/src/southbridge/amd/amd8111/amd8111_smbus.c
+++ b/src/southbridge/amd/amd8111/amd8111_smbus.c
@@ -1,96 +1,42 @@
-#include <smbus.h>
-#include <pci.h>
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/chip.h>
+#include <device/smbus.h>
 #include <arch/io.h>
+#include "amd8111.h"
 
-#define PM_BUS 0
-#define PM_DEVFN PCI_DEVFN(0x7,3)
 
-#define SMBUS_IO_BASE 0x1000
-#define SMBHSTSTAT 0
-#define SMBHSTCTL  2
-#define SMBHSTCMD  3
-#define SMBHSTADD  4
-#define SMBHSTDAT0 5
-#define SMBHSTDAT1 6
-#define SMBBLKDAT  7
-
-void smbus_enable(void)
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
 {
-	unsigned char byte;
-#if 0
-	/* iobase addr */
-	pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x90, SMBUS_IO_BASE | 1);
-	/* smbus enable */
-	pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0xd2, (0x4 << 1) | 1);
-	/* iospace enable */
-	pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1);
-#endif
-	/* Set PMIOEN, leaving default address 0xDD00 in 0x58 */
-	byte=pcibios_read_config_byte(0,PCI_DEVFN(0x7,3), 0x41);
-	pcibios_write_config_byte(0,PCI_DEVFN(0x7,3), byte | 0x80 );
-
-
-	/* cont reading 207 */
+	pci_write_config32(dev, 0x44, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
 }
 
-void smbus_setup(void)
-{
-	outb(0, SMBUS_IO_BASE + SMBHSTSTAT);
-}
+static struct smbus_bus_operations lops_smbus_bus = {
+	/* I haven't seen the 2.0 SMBUS controller used yet. */
+};
+static struct pci_operations lops_pci = {
+	.set_subsystem = lpci_set_subsystem,
+};
+static struct device_operations smbus_ops = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = scan_static_bus,
+	.enable           = amd8111_enable,
+	.ops_pci          = &lops_pci,
+	.ops_smbus_bus    = &lops_smbus_bus,
+};
 
-static void smbus_wait_until_ready(void)
-{
-	while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
-		/* nop */
-	}
-}
-
-static void smbus_wait_until_done(void)
-{
-	unsigned char byte;
-	do {
-		byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-	}
-	while((byte &1) == 1);
-	while( (byte & ~1) == 0) {
-		byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-	}
-}
-
-int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
-{
-	unsigned char host_status_register;
-	unsigned char byte;
-
-	smbus_wait_until_ready();
-
-	/* setup transaction */
-	/* disable interrupts */
-	outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
-	/* set the device I'm talking too */
-	outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
-	/* set the command/address... */
-	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
-	/* set up for a byte data read */
-	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
-
-	/* clear any lingering errors, so the transaction will run */
-	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
-	/* clear the data byte...*/
-	outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
-	/* start the command */
-	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
-
-	/* poll for transaction completion */
-	smbus_wait_until_done();
-
-	host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-
-	/* read results of transaction */
-	byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
-
-	*result = byte;
-	return host_status_register != 0x02;
-}
+static struct pci_driver smbus_driver __pci_driver = {
+	.ops = &smbus_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_AMD_8111_SMB,
+};
diff --git a/src/southbridge/amd/amd8111/amd8111_smbus.h b/src/southbridge/amd/amd8111/amd8111_smbus.h
new file mode 100644
index 0000000..b579966
--- /dev/null
+++ b/src/southbridge/amd/amd8111/amd8111_smbus.h
@@ -0,0 +1,224 @@
+#include <device/smbus_def.h>
+
+#define SMBGSTATUS 0xe0
+#define SMBGCTL    0xe2
+#define SMBHSTADDR 0xe4
+#define SMBHSTDAT  0xe6
+#define SMBHSTCMD  0xe8
+#define SMBHSTFIFO 0xe9
+
+#define SMBUS_TIMEOUT (100*1000*10)
+#define SMBUS_STATUS_MASK 0xfbff
+
+static inline void smbus_delay(void)
+{
+	outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+	unsigned long loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		unsigned short val;
+		smbus_delay();
+		val = inw(smbus_io_base + SMBGSTATUS);
+		if ((val & 0x800) == 0) {
+			break;
+		}
+		if(loops == (SMBUS_TIMEOUT / 2)) {
+			outw(inw(smbus_io_base + SMBGSTATUS), 
+				smbus_io_base + SMBGSTATUS);
+		}
+	} while(--loops);
+	return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+	unsigned long loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		unsigned short val;
+		smbus_delay();
+		
+		val = inw(smbus_io_base + SMBGSTATUS);
+		if (((val & 0x8) == 0) | ((val & 0x0037) != 0)) {
+			break;
+		}
+	} while(--loops);
+	return loops?0:SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+}
+
+static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
+{
+	unsigned global_status_register;
+	unsigned byte;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+	}
+	
+	/* setup transaction */
+	/* disable interrupts */
+	outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
+	/* set the device I'm talking too */
+	outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
+	/* set the command/address... */
+	outb(0, smbus_io_base + SMBHSTCMD);
+	/* set up for a send byte */
+	outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
+
+	/* clear any lingering errors, so the transaction will run */
+	/* Do I need to write the bits to a 1 to clear an error? */
+	outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
+
+	/* set the data word...*/
+	outw(0, smbus_io_base + SMBHSTDAT);
+
+	/* start the command */
+	outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
+
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+	}
+
+	global_status_register = inw(smbus_io_base + SMBGSTATUS);
+
+	/* read results of transaction */
+	byte = inw(smbus_io_base + SMBHSTDAT) & 0xff;
+
+	if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) {
+		return SMBUS_ERROR;
+	}
+	return byte;
+}
+
+static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned value)
+{
+	unsigned global_status_register;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+	}
+	
+	/* setup transaction */
+	/* disable interrupts */
+	outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
+	/* set the device I'm talking too */
+	outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
+	/* set the command/address... */
+	outb(0, smbus_io_base + SMBHSTCMD);
+	/* set up for a send byte */
+	outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
+
+	/* clear any lingering errors, so the transaction will run */
+	/* Do I need to write the bits to a 1 to clear an error? */
+	outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
+
+	/* set the data word...*/
+	outw(value, smbus_io_base + SMBHSTDAT);
+
+	/* start the command */
+	outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
+
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+	}
+	global_status_register = inw(smbus_io_base + SMBGSTATUS);
+
+	if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) {
+		return SMBUS_ERROR;
+	}
+	return 0;
+}
+
+
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+	unsigned global_status_register;
+	unsigned byte;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+	}
+	
+	/* setup transaction */
+	/* disable interrupts */
+	outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
+	/* set the device I'm talking too */
+	outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
+	/* set the command/address... */
+	outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
+	/* set up for a byte data read */
+	outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x2), smbus_io_base + SMBGCTL);
+
+	/* clear any lingering errors, so the transaction will run */
+	/* Do I need to write the bits to a 1 to clear an error? */
+	outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
+
+	/* clear the data word...*/
+	outw(0, smbus_io_base + SMBHSTDAT);
+
+	/* start the command */
+	outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
+
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+	}
+
+	global_status_register = inw(smbus_io_base + SMBGSTATUS);
+
+	/* read results of transaction */
+	byte = inw(smbus_io_base + SMBHSTDAT) & 0xff;
+
+	if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) {
+		return SMBUS_ERROR;
+	}
+	return byte;
+}
+
+static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
+{
+	unsigned global_status_register;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+	}
+
+	/* setup transaction */
+	/* disable interrupts */
+	outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
+	/* set the device I'm talking too */
+	outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
+	outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
+	/* set up for a byte data write */ /* FIXME */
+	outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x2), smbus_io_base + SMBGCTL);
+	/* clear any lingering errors, so the transaction will run */
+	/* Do I need to write the bits to a 1 to clear an error? */
+	outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
+
+	/* write the data word...*/
+	outw(val, smbus_io_base + SMBHSTDAT);
+
+	/* start the command */
+	outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+	}
+	global_status_register = inw(smbus_io_base + SMBGSTATUS);
+
+	if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) {
+		return SMBUS_ERROR;
+	}
+	return 0;
+}
+
diff --git a/src/southbridge/amd/amd8111/amd8111_usb.c b/src/southbridge/amd/amd8111/amd8111_usb.c
index 680b610..2fec77b 100644
--- a/src/southbridge/amd/amd8111/amd8111_usb.c
+++ b/src/southbridge/amd/amd8111/amd8111_usb.c
@@ -1,39 +1,42 @@
+/*
+ * (C) 2004 Linux Networx
+ */
 #include <console/console.h>
 #include <device/device.h>
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
+#include <device/chip.h>
+#include <device/smbus.h>
+#include <arch/io.h>
 #include "amd8111.h"
 
-static void usb_init(struct device *dev)
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
 {
-	uint32_t cmd;
-
-#if 0
-	printk_debug("USB: Setting up controller.. ");
-	cmd = pci_read_config32(dev, PCI_COMMAND);
-	pci_write_config32(dev, PCI_COMMAND, 
-		cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 
-		PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
-
-
-	printk_debug("done.\n");
-#endif
-
+	pci_write_config32(dev, 0x44, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
 }
 
-static struct device_operations usb_ops  = {
+static struct smbus_bus_operations lops_smbus_bus = {
+	/* I haven't seen the 2.0 SMBUS controller used yet. */
+};
+static struct pci_operations lops_pci = {
+	.set_subsystem = lpci_set_subsystem,
+};
+static struct device_operations smbus_ops = {
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
-	.init             = usb_init,
-	.scan_bus         = 0,
-//	.enable           = amd8111_enable,
+	.init             = 0,
+	.scan_bus         = scan_static_bus,
+	.enable           = amd8111_enable,
+	.ops_pci          = &lops_pci,
+	.ops_smbus_bus    = &lops_smbus_bus,
 };
 
-static struct pci_driver usb_driver __pci_driver = {
-	.ops    = &usb_ops,
+static struct pci_driver smbus_driver __pci_driver = {
+	.ops = &smbus_ops,
 	.vendor = PCI_VENDOR_ID_AMD,
-	.device = PCI_DEVICE_ID_AMD_8111_USB,
+	.device = PCI_DEVICE_ID_AMD_8111_SMB,
 };
-
diff --git a/src/southbridge/amd/amd8111/amd8111_usb2.c b/src/southbridge/amd/amd8111/amd8111_usb2.c
index d3393ae..8ec9dc8 100644
--- a/src/southbridge/amd/amd8111/amd8111_usb2.c
+++ b/src/southbridge/amd/amd8111/amd8111_usb2.c
@@ -23,13 +23,24 @@
 #endif
 }
 
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	pci_write_config32(dev, 0x70, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = lpci_set_subsystem,
+};
+
 static struct device_operations usb2_ops  = {
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
 	.init             = usb2_init,
 	.scan_bus         = 0,
-//	.enable           = amd8111_enable,
+	.enable           = amd8111_enable,
+	.ops_pci          = &lops_pci,
 };
 
 static struct pci_driver usb2_driver __pci_driver = {
diff --git a/src/southbridge/amd/amd8111/chip.h b/src/southbridge/amd/amd8111/chip.h
index d100e98..a4ae278 100644
--- a/src/southbridge/amd/amd8111/chip.h
+++ b/src/southbridge/amd/amd8111/chip.h
@@ -3,7 +3,10 @@
 
 struct southbridge_amd_amd8111_config 
 {
+	unsigned int ide0_enable : 1;
+	unsigned int ide1_enable : 1;
 };
+
 struct chip_operations;
 extern struct chip_operations southbridge_amd_amd8111_ops;
 
diff --git a/src/southbridge/amd/amd8131/amd8131_bridge.c b/src/southbridge/amd/amd8131/amd8131_bridge.c
index dc474fc..357059d 100644
--- a/src/southbridge/amd/amd8131/amd8131_bridge.c
+++ b/src/southbridge/amd/amd8131/amd8131_bridge.c
@@ -1,5 +1,5 @@
 /*
- * (C) 2003 Linux Networx
+ * (C) 2003-2004 Linux Networx
  */
 #include <console/console.h>
 #include <device/device.h>
@@ -106,20 +106,19 @@
 		value &= ~((1 << 1) | (1 << 0));
 	}
 	pci_write_config32(dev, 0x44, value);
-
-	/* We have to enable MEM and Bus Master for IOAPIC */
-        value = pci_read_config32(dev, 0x4);
-        value |= 6;
-        pci_write_config32(dev, 0x4, value);
 }
 
+static struct pci_operations pci_ops_pci_dev = {
+	.set_subsystem    = pci_dev_set_subsystem,
+};
 static struct device_operations ioapic_ops = {
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
-	.init     = 0,
-	.scan_bus = 0,
-	.enable   = ioapic_enable,
+	.init             = 0,
+	.scan_bus         = 0,
+	.enable           = ioapic_enable,
+	.ops_pci          = &pci_ops_pci_dev,
 };
 
 static struct pci_driver ioapic_driver __pci_driver = {
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm.c b/src/southbridge/intel/i82801dbm/i82801dbm.c
index 281836b..ee9b60a 100644
--- a/src/southbridge/intel/i82801dbm/i82801dbm.c
+++ b/src/southbridge/intel/i82801dbm/i82801dbm.c
@@ -50,7 +50,7 @@
 
 }
 
-struct chip_control southbridge_intel_i82801dbm_control = {
+struct chip_operations southbridge_intel_i82801dbm_control = {
 	.name       = "Intel 82801dbm Southbridge",
 	.enable_dev = i82801dbm_enable,
 };
diff --git a/src/southbridge/intel/i82801er/i82801er.c b/src/southbridge/intel/i82801er/i82801er.c
index 0e4e3b3..863dbcd 100644
--- a/src/southbridge/intel/i82801er/i82801er.c
+++ b/src/southbridge/intel/i82801er/i82801er.c
@@ -50,7 +50,7 @@
 
 }
 
-struct chip_control southbridge_intel_i82801er_control = {
+struct chip_operations southbridge_intel_i82801er_control = {
 	.name       = "Intel 82801er Southbridge",
 	.enable_dev = i82801er_enable,
 };
diff --git a/src/southbridge/ricoh/rl5c476/chip.h b/src/southbridge/ricoh/rl5c476/chip.h
index d951a8a..5d7a2e3 100644
--- a/src/southbridge/ricoh/rl5c476/chip.h
+++ b/src/southbridge/ricoh/rl5c476/chip.h
@@ -1,7 +1,7 @@
 #ifndef _SOUTHBRIDGE_RICOH_RL5C476
 #define _SOUTHBRIDGE_RICOH_RL5C476
 
-extern struct chip_control southbridge_ricoh_rl5c476_control;
+extern struct chip_operations southbridge_ricoh_rl5c476_control;
 
 struct southbridge_ricoh_rl5c476_config {
 	int num;
diff --git a/src/southbridge/ricoh/rl5c476/rl5c476.c b/src/southbridge/ricoh/rl5c476/rl5c476.c
index 1eed368..4240f96a 100644
--- a/src/southbridge/ricoh/rl5c476/rl5c476.c
+++ b/src/southbridge/ricoh/rl5c476/rl5c476.c
@@ -77,22 +77,16 @@
 }
 
 
-static void rl5c476_init(struct southbridge_rl5c476_config *conf)
+static void rl5c476_init(device_t dev)
 {
 	//unsigned char enables;
-	device_t dev;
 	pc16reg_t *pc16;
 	int i;
 
-	printk_debug("rl5c476 init\n");
+#error "FIXME implement carbus bridge support"
+#error "FIXME this code is close to a but the conversion needs more work"
 	/* cardbus controller function 1 for CF Socket */
-	dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0);
-
-	if (!dev ){
-		// probably an epia-m rather than mii
-		printk_debug("No rl5c476 found\n");
-		return;
-	}	
+	printk_debug("rl5c476 init\n");
 
 	/* setup pci header manually because 'pci_device.c' doesn't know how to handle
          * pci to cardbus bridges - (header type 2 I think)
@@ -214,41 +208,21 @@
 
 }
 
-static void southbridge_init(struct chip *chip, enum chip_pass pass)
-{
+static struct device_operations ricoh_rl5c476_ops = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.inti             = rl5c476_init,
+	.scan_bus         = pci_scan_bridge,
+};
 
-	struct southbridge_rl5c476_config *conf = 
-		(struct southbridge_rl5c476_config *)chip->chip_info;
+static struct pci_driver ricoh_rl5c476_driver __pci_driver = {
+	.ops    = &ricoh_rl5c476_ops,
+	.vendor = PCI_VENDOR_ID_RICOH,
+	.device = PCI_DEVICE_ID_RICOH_RL5C476,
+};
 
-	switch (pass) {
-	case CONF_PASS_PRE_PCI:
-		//rl5c476_pci_enable(conf);
-		break;
-		
-	case CONF_PASS_POST_PCI:
-		rl5c476_init(conf);
-
-		break;
-
-	case CONF_PASS_PRE_BOOT:
-		//dump_south();
-		break;
-		
-	default:
-		/* nothing yet */
-		break;
-	}
-}
-
-static void enumerate(struct chip *chip)
-{
-	extern struct device_operations default_pci_ops_bus;
-	chip_enumerate(chip);
-	chip->dev->ops = &default_pci_ops_bus;
-}
-
-struct chip_control southbridge_ricoh_rl5c476_control = {
-	.enumerate = enumerate,
+struct chip_operations southbridge_ricoh_rl5c476_control = {
 	.enable    = southbridge_init,
 	.name      = "RICOH RL5C476"
 };
diff --git a/src/southbridge/via/vt8231/chip.h b/src/southbridge/via/vt8231/chip.h
index fe3d332..28c3b2e 100644
--- a/src/southbridge/via/vt8231/chip.h
+++ b/src/southbridge/via/vt8231/chip.h
@@ -1,7 +1,7 @@
 #ifndef _SOUTHBRIDGE_VIA_VT8231
 #define _SOUTHBRIDGE_VIA_VT8231
 
-extern struct chip_control southbridge_via_vt8231_control;
+extern struct chip_operations southbridge_via_vt8231_control;
 
 struct southbridge_via_vt8231_config {
 	/* PCI function enables */
diff --git a/src/southbridge/via/vt8231/vt8231.c b/src/southbridge/via/vt8231/vt8231.c
index 99fef4c..27d635d 100644
--- a/src/southbridge/via/vt8231/vt8231.c
+++ b/src/southbridge/via/vt8231/vt8231.c
@@ -449,15 +449,7 @@
 	}
 }
 
-static void enumerate(struct chip *chip)
-{
-	extern struct device_operations default_pci_ops_bus;
-	chip_enumerate(chip);
-	chip->dev->ops = &default_pci_ops_bus;
-}
-
-struct chip_control southbridge_via_vt8231_control = {
-	.enumerate = enumerate,
+struct chip_operations southbridge_via_vt8231_control = {
 	.enable    = southbridge_init,
 	.name      = "VIA vt8231"
 };
diff --git a/src/southbridge/via/vt8235/chip.h b/src/southbridge/via/vt8235/chip.h
index 897ba13..b855a94 100644
--- a/src/southbridge/via/vt8235/chip.h
+++ b/src/southbridge/via/vt8235/chip.h
@@ -1,7 +1,7 @@
 #ifndef _SOUTHBRIDGE_VIA_VT8235
 #define _SOUTHBRIDGE_VIA_VT8235
 
-extern struct chip_control southbridge_via_vt8235_control;
+extern struct chip_operations southbridge_via_vt8235_control;
 
 struct southbridge_via_vt8235_config {
 	/* PCI function enables */
diff --git a/src/southbridge/via/vt8235/vt8235.c b/src/southbridge/via/vt8235/vt8235.c
index a8dc4ba..29d32df 100644
--- a/src/southbridge/via/vt8235/vt8235.c
+++ b/src/southbridge/via/vt8235/vt8235.c
@@ -557,15 +557,7 @@
 	}
 }
 
-static void enumerate(struct chip *chip)
-{
-	extern struct device_operations default_pci_ops_bus;
-	chip_enumerate(chip);
-	chip->dev->ops = &default_pci_ops_bus;
-}
-
-struct chip_control southbridge_via_vt8235_control = {
-	.enumerate = enumerate,
+struct chip_operations southbridge_via_vt8235_control = {
 	.enable    = southbridge_init,
 	.name      = "VIA vt8235"
 };
diff --git a/src/southbridge/winbond/w83c553/chip.h b/src/southbridge/winbond/w83c553/chip.h
index 0edcbb0..20a9a69 100644
--- a/src/southbridge/winbond/w83c553/chip.h
+++ b/src/southbridge/winbond/w83c553/chip.h
@@ -1,7 +1,7 @@
 #ifndef _SOUTHBRIDGE_WINBOND_W83C553
 #define _SOUTHBRIDGE_WINBOND_W83C553
 
-extern struct chip_control southbridge_winbond_w83c553_control;
+extern struct chip_operations southbridge_winbond_w83c553_control;
 
 struct southbridge_winbond_w83c553_config {
 };