[coreboot-gerrit] Change in coreboot[master]: [WIP]sb/intel/*: Use common smbus functions

Arthur Heymans (Code Review) gerrit at coreboot.org
Wed Apr 12 17:06:13 CEST 2017


Arthur Heymans has uploaded a new change for review. ( https://review.coreboot.org/19258 )

Change subject: [WIP]sb/intel/*: Use common smbus functions
......................................................................

[WIP]sb/intel/*: Use common smbus functions

Change-Id: I93bb186e04e8c32dff04fc1abe4b5ecbc4c9c962
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
M src/southbridge/intel/bd82x6x/Kconfig
M src/southbridge/intel/bd82x6x/early_smbus.c
M src/southbridge/intel/bd82x6x/smbus.c
M src/southbridge/intel/bd82x6x/smbus.h
M src/southbridge/intel/common/Kconfig
M src/southbridge/intel/common/Makefile.inc
R src/southbridge/intel/common/smbus.c
A src/southbridge/intel/common/smbus.h
M src/southbridge/intel/fsp_bd82x6x/Kconfig
M src/southbridge/intel/fsp_i89xx/Kconfig
M src/southbridge/intel/fsp_i89xx/early_smbus.c
D src/southbridge/intel/fsp_i89xx/smbus.h
M src/southbridge/intel/fsp_rangeley/Kconfig
M src/southbridge/intel/fsp_rangeley/early_smbus.c
M src/southbridge/intel/fsp_rangeley/smbus.c
M src/southbridge/intel/i3100/Kconfig
M src/southbridge/intel/i3100/early_smbus.c
M src/southbridge/intel/i3100/smbus.c
M src/southbridge/intel/i3100/smbus.h
M src/southbridge/intel/i82371eb/Kconfig
M src/southbridge/intel/i82371eb/early_smbus.c
M src/southbridge/intel/i82371eb/smbus.c
M src/southbridge/intel/i82801ax/Kconfig
M src/southbridge/intel/i82801ax/early_smbus.c
M src/southbridge/intel/i82801ax/smbus.c
D src/southbridge/intel/i82801ax/smbus.h
M src/southbridge/intel/i82801bx/Kconfig
M src/southbridge/intel/i82801bx/early_smbus.c
M src/southbridge/intel/i82801bx/smbus.c
D src/southbridge/intel/i82801bx/smbus.h
M src/southbridge/intel/i82801ex/Kconfig
M src/southbridge/intel/i82801ex/early_smbus.c
M src/southbridge/intel/i82801ex/smbus.c
D src/southbridge/intel/i82801ex/smbus.h
M src/southbridge/intel/i82801gx/Kconfig
M src/southbridge/intel/i82801gx/early_smbus.c
M src/southbridge/intel/i82801gx/smbus.c
M src/southbridge/intel/i82801gx/smbus.h
M src/southbridge/intel/i82801ix/Kconfig
M src/southbridge/intel/i82801ix/early_smbus.c
M src/southbridge/intel/i82801ix/smbus.c
D src/southbridge/intel/i82801ix/smbus.h
M src/southbridge/intel/ibexpeak/Kconfig
M src/southbridge/intel/ibexpeak/early_smbus.c
M src/southbridge/intel/ibexpeak/smbus.c
M src/southbridge/intel/lynxpoint/Kconfig
M src/southbridge/intel/lynxpoint/early_smbus.c
M src/southbridge/intel/lynxpoint/smbus.c
M src/southbridge/intel/lynxpoint/smbus.h
49 files changed, 176 insertions(+), 1,043 deletions(-)


  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/58/19258/1

diff --git a/src/southbridge/intel/bd82x6x/Kconfig b/src/southbridge/intel/bd82x6x/Kconfig
index 6522cce..c24c71c 100644
--- a/src/southbridge/intel/bd82x6x/Kconfig
+++ b/src/southbridge/intel/bd82x6x/Kconfig
@@ -25,6 +25,7 @@
 	def_bool y
 	select ACPI_INTEL_HARDWARE_SLEEP_VALUES
 	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 	select IOAPIC
 	select HAVE_HARD_RESET
 	select HAVE_USBDEBUG_OPTIONS
diff --git a/src/southbridge/intel/bd82x6x/early_smbus.c b/src/southbridge/intel/bd82x6x/early_smbus.c
index 9f74fdd..4c67aea 100644
--- a/src/southbridge/intel/bd82x6x/early_smbus.c
+++ b/src/southbridge/intel/bd82x6x/early_smbus.c
@@ -18,8 +18,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "pch.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/bd82x6x/smbus.c b/src/southbridge/intel/bd82x6x/smbus.c
index 5778e25..78c46a3 100644
--- a/src/southbridge/intel/bd82x6x/smbus.c
+++ b/src/southbridge/intel/bd82x6x/smbus.c
@@ -22,8 +22,8 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "pch.h"
-#include "smbus.h"
 
 static void pch_smbus_init(device_t dev)
 {
@@ -52,49 +52,6 @@
 	res = find_resource(pbus->dev, 0x20);
 
 	return do_smbus_read_byte(res->base, device, address);
-}
-
-static  int do_smbus_write_byte(unsigned smbus_base, unsigned device, unsigned address, unsigned data)
-{
-	unsigned char global_status_register;
-
-	if (smbus_wait_until_ready(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(data, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	if (global_status_register != (1 << 1))
-		return SMBUS_ERROR;
-
-	return 0;
 }
 
 static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
diff --git a/src/southbridge/intel/bd82x6x/smbus.h b/src/southbridge/intel/bd82x6x/smbus.h
index 0978963..48c4c87 100644
--- a/src/southbridge/intel/bd82x6x/smbus.h
+++ b/src/southbridge/intel/bd82x6x/smbus.h
@@ -47,49 +47,3 @@
 	} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
 	return loops ? 0 : -1;
 }
-
-static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
-{
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready(smbus_base) < 0) {
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(0, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0) {
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	byte = inb(smbus_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
-		return SMBUS_ERROR;
-	}
-	return byte;
-}
diff --git a/src/southbridge/intel/common/Kconfig b/src/southbridge/intel/common/Kconfig
index 7bc686d..23fb8ce 100644
--- a/src/southbridge/intel/common/Kconfig
+++ b/src/southbridge/intel/common/Kconfig
@@ -2,3 +2,5 @@
 	def_bool n
 config SOUTHBRIDGE_INTEL_COMMON_GPIO
 	def_bool n
+config SOUTHBRIDGE_INTEL_COMMON_SMBUS
+	def_bool n
diff --git a/src/southbridge/intel/common/Makefile.inc b/src/southbridge/intel/common/Makefile.inc
index 56ba56f..5810394 100644
--- a/src/southbridge/intel/common/Makefile.inc
+++ b/src/southbridge/intel/common/Makefile.inc
@@ -24,4 +24,8 @@
 romstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO) += gpio.c
 ramstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO) += gpio.c
 smm-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO) += gpio.c
+
+romstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS) += smbus.c
+ramstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS) += smbus.c
+
 endif
diff --git a/src/southbridge/intel/ibexpeak/smbus.h b/src/southbridge/intel/common/smbus.c
similarity index 69%
rename from src/southbridge/intel/ibexpeak/smbus.h
rename to src/southbridge/intel/common/smbus.c
index 0815bf4..1ee688b 100644
--- a/src/southbridge/intel/ibexpeak/smbus.h
+++ b/src/southbridge/intel/common/smbus.c
@@ -3,7 +3,6 @@
  *
  * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
  * Copyright (C) 2009 coresystems GmbH
- * Copyright (C) 2013 Vladimir Serbinenko
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -15,8 +14,9 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/io.h>
 #include <device/smbus_def.h>
-#include "pch.h"
+#include "smbus.h"
 
 static void smbus_delay(void)
 {
@@ -25,7 +25,7 @@
 
 static int smbus_wait_until_ready(u16 smbus_base)
 {
-	unsigned loops = SMBUS_TIMEOUT;
+	unsigned int loops = SMBUS_TIMEOUT;
 	unsigned char byte;
 	do {
 		smbus_delay();
@@ -38,7 +38,7 @@
 
 static int smbus_wait_until_done(u16 smbus_base)
 {
-	unsigned loops = SMBUS_TIMEOUT;
+	unsigned int loops = SMBUS_TIMEOUT;
 	unsigned char byte;
 	do {
 		smbus_delay();
@@ -49,14 +49,14 @@
 	return loops ? 0 : -1;
 }
 
-static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
+int do_smbus_read_byte(unsigned int smbus_base, unsigned int device,
+						unsigned int address)
 {
-	unsigned char global_status_register;
+	unsigned char status;
 	unsigned char byte;
 
-	if (smbus_wait_until_ready(smbus_base) < 0) {
+	if (smbus_wait_until_ready(smbus_base) < 0)
 		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
 	/* Setup transaction */
 	/* Disable interrupts */
 	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
@@ -78,26 +78,25 @@
 	     smbus_base + SMBHSTCTL);
 
 	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0) {
+	if (smbus_wait_until_done(smbus_base) < 0)
 		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
 
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
+	status = inb(smbus_base + SMBHSTSTAT);
 
 	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
+	status &= ~(3 << 5);
 
 	/* Read results of transaction */
 	byte = inb(smbus_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
+	if (status != (1 << 1))
 		return SMBUS_ERROR;
-	}
 	return byte;
 }
 
-static  int do_smbus_write_byte(unsigned smbus_base, unsigned device, unsigned address, unsigned data)
+int do_smbus_write_byte(unsigned int smbus_base, unsigned int device,
+			unsigned int address, unsigned int data)
 {
-	unsigned char global_status_register;
+	unsigned char status;
 
 	if (smbus_wait_until_ready(smbus_base) < 0)
 		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
@@ -126,22 +125,71 @@
 	if (smbus_wait_until_done(smbus_base) < 0)
 		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
 
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
+	status = inb(smbus_base + SMBHSTSTAT);
 
 	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
+	status &= ~(3 << 5);
 
 	/* Read results of transaction */
-	if (global_status_register != (1 << 1))
+	if (status != (1 << 1))
 		return SMBUS_ERROR;
 
 	return 0;
 }
 
-#ifdef __PRE_RAM__
+int do_smbus_block_read(unsigned int smbus_base, unsigned int device,
+				unsigned int cmd, unsigned int bytes, u8 *buf)
+{
+	u8 status;
+	int bytes_read = 0;
+	if (smbus_wait_until_ready(smbus_base) < 0)
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
 
-static int do_smbus_block_write(unsigned smbus_base, unsigned device,
-			      unsigned cmd, unsigned bytes, const u8 *buf)
+	/* Setup transaction */
+	/* Disable interrupts */
+	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
+	/* Set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
+	/* Set the command/address... */
+	outb(cmd & 0xff, smbus_base + SMBHSTCMD);
+	/* Set up for a block data read */
+	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x5 << 2),
+	     (smbus_base + SMBHSTCTL));
+	/* Clear any lingering errors, so the transaction will run */
+	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
+
+	/* Start the command */
+	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
+	     smbus_base + SMBHSTCTL);
+
+	while (!(inb(smbus_base + SMBHSTSTAT) & 1))
+		;
+	/* Poll for transaction completion */
+	do {
+		status = inb(smbus_base + SMBHSTSTAT);
+		if (status & ((1 << 4) | /* FAILED */
+			      (1 << 3) | /* BUS ERR */
+			      (1 << 2))) /* DEV ERR */
+			return SMBUS_ERROR;
+
+		if (status & 0x80) { /* Byte done */
+			*buf = inb(smbus_base + SMBBLKDAT);
+			buf++;
+			bytes_read++;
+			outb(status, smbus_base + SMBHSTSTAT);
+			if (--bytes == 1) {
+				/* indicate that next byte is the last one */
+				outb(inb(smbus_base + SMBHSTCTL) | 0x20,
+					 smbus_base + SMBHSTCTL);
+			}
+		}
+	} while (status & 0x01);
+
+	return bytes_read;
+}
+
+int do_smbus_block_write(unsigned int smbus_base, unsigned int device,
+			unsigned int cmd, unsigned int bytes, const u8 *buf)
 {
 	u8 status;
 
@@ -171,7 +219,8 @@
 	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
 	     smbus_base + SMBHSTCTL);
 
-	while (!(inb(smbus_base + SMBHSTSTAT) & 1));
+	while (!(inb(smbus_base + SMBHSTSTAT) & 1))
+		;
 	/* Poll for transaction completion */
 	do {
 		status = inb(smbus_base + SMBHSTSTAT);
@@ -189,8 +238,8 @@
 	return 0;
 }
 
-static int do_smbus_block_read(unsigned smbus_base, unsigned device,
-			      unsigned cmd, unsigned bytes, u8 *buf)
+int i2c_block_read(unsigned int smbus_base, unsigned int device,
+		unsigned int offset, u32 bytes, u8 *buf)
 {
 	u8 status;
 	int bytes_read = 0;
@@ -200,21 +249,24 @@
 	/* Setup transaction */
 	/* Disable interrupts */
 	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(cmd & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a block data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x5 << 2),
-	     (smbus_base + SMBHSTCTL));
+	/* Set the device I'm talking to */
+	outb((device & 0x7f) << 1, smbus_base + SMBXMITADD);
+
+	/* SPD offset */
+	outb(offset, smbus_base + SMBHSTDAT1);
+
+	/* Set up for a i2c block data read */
+	outb((inb(smbus_base + SMBHSTCTL) & 0xc3) | (0x6 << 2),
+		(smbus_base + SMBHSTCTL));
+
 	/* Clear any lingering errors, so the transaction will run */
 	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
 	/* Start the command */
 	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
 	     smbus_base + SMBHSTCTL);
 
-	while (!(inb(smbus_base + SMBHSTSTAT) & 1));
+	while (!(inb(smbus_base + SMBHSTSTAT) & 1))
+		;
 	/* Poll for transaction completion */
 	do {
 		status = inb(smbus_base + SMBHSTSTAT);
@@ -227,15 +279,14 @@
 			*buf = inb(smbus_base + SMBBLKDAT);
 			buf++;
 			bytes_read++;
-			outb(status, smbus_base + SMBHSTSTAT);
 			if (--bytes == 1) {
 				/* indicate that next byte is the last one */
 				outb(inb(smbus_base + SMBHSTCTL) | 0x20,
 					 smbus_base + SMBHSTCTL);
 			}
+			outb(status, smbus_base + SMBHSTSTAT);
 		}
 	} while (status & 0x01);
 
 	return bytes_read;
 }
-#endif
diff --git a/src/southbridge/intel/common/smbus.h b/src/southbridge/intel/common/smbus.h
new file mode 100644
index 0000000..6850df5
--- /dev/null
+++ b/src/southbridge/intel/common/smbus.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define SMBUS_TIMEOUT		(10 * 1000 * 100)
+
+/* SMBus I/O bits. */
+#define SMBHSTSTAT		0x0
+#define SMBHSTCTL		0x2
+#define SMBHSTCMD		0x3
+#define SMBXMITADD		0x4
+#define SMBHSTDAT0		0x5
+#define SMBHSTDAT1		0x6
+#define SMBBLKDAT		0x7
+#define SMBTRNSADD		0x9
+#define SMBSLVDATA		0xa
+#define SMLINK_PIN_CTL		0xe
+#define SMBUS_PIN_CTL		0xf
+
+
+
+int do_smbus_read_byte(unsigned int smbus_base, unsigned int device,
+		unsigned int address);
+int do_smbus_write_byte(unsigned int smbus_base, unsigned int device,
+			unsigned int address, unsigned int data);
+int do_smbus_block_read(unsigned int smbus_base, unsigned int device,
+			unsigned int cmd, unsigned int bytes, u8 *buf);
+int do_smbus_block_write(unsigned int smbus_base, unsigned int device,
+			unsigned int cmd, unsigned int bytes, const u8 *buf);
+int i2c_block_read(unsigned int smbus_base, unsigned int device,
+		unsigned int offset, u32 bytes, u8 *buf);
diff --git a/src/southbridge/intel/fsp_bd82x6x/Kconfig b/src/southbridge/intel/fsp_bd82x6x/Kconfig
index 516362c..cebd96d 100644
--- a/src/southbridge/intel/fsp_bd82x6x/Kconfig
+++ b/src/southbridge/intel/fsp_bd82x6x/Kconfig
@@ -31,6 +31,8 @@
 	select SPI_FLASH
 	select COMMON_FADT
 	select HAVE_INTEL_FIRMWARE
+	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 
 config EHCI_BAR
 	hex
diff --git a/src/southbridge/intel/fsp_i89xx/Kconfig b/src/southbridge/intel/fsp_i89xx/Kconfig
index 9dfbbf7..67c2665 100644
--- a/src/southbridge/intel/fsp_i89xx/Kconfig
+++ b/src/southbridge/intel/fsp_i89xx/Kconfig
@@ -32,6 +32,8 @@
 	select COMMON_FADT
 	select HAVE_INTEL_FIRMWARE
 	select NO_EARLY_BOOTBLOCK_POSTCODES
+	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 
 config EHCI_BAR
 	hex
diff --git a/src/southbridge/intel/fsp_i89xx/early_smbus.c b/src/southbridge/intel/fsp_i89xx/early_smbus.c
index 0d41d5e..1451179 100644
--- a/src/southbridge/intel/fsp_i89xx/early_smbus.c
+++ b/src/southbridge/intel/fsp_i89xx/early_smbus.c
@@ -19,8 +19,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "pch.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/fsp_i89xx/smbus.h b/src/southbridge/intel/fsp_i89xx/smbus.h
deleted file mode 100644
index 92b05b7..0000000
--- a/src/southbridge/intel/fsp_i89xx/smbus.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
- * Copyright (C) 2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <device/smbus_def.h>
-#include "pch.h"
-#include <delay.h>
-
-static int smbus_wait_until_ready(u16 smbus_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		udelay(1);
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_base + SMBHSTSTAT);
-	} while (byte & 1);
-	return loops ? 0 : -1;
-}
-
-static int smbus_wait_until_done(u16 smbus_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		udelay(1);
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_base + SMBHSTSTAT);
-	} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
-	return loops ? 0 : -1;
-}
-
-static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
-{
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready(smbus_base) < 0) {
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(0, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0) {
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	byte = inb(smbus_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
-		return SMBUS_ERROR;
-	}
-	return byte;
-}
diff --git a/src/southbridge/intel/fsp_rangeley/Kconfig b/src/southbridge/intel/fsp_rangeley/Kconfig
index 092cf1d..4d2e89f 100644
--- a/src/southbridge/intel/fsp_rangeley/Kconfig
+++ b/src/southbridge/intel/fsp_rangeley/Kconfig
@@ -30,6 +30,8 @@
 	select PCIEXP_COMMON_CLOCK
 	select SPI_FLASH
 	select HAVE_INTEL_FIRMWARE
+	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 
 config EHCI_BAR
 	hex
diff --git a/src/southbridge/intel/fsp_rangeley/early_smbus.c b/src/southbridge/intel/fsp_rangeley/early_smbus.c
index f27fa87..84b750e 100644
--- a/src/southbridge/intel/fsp_rangeley/early_smbus.c
+++ b/src/southbridge/intel/fsp_rangeley/early_smbus.c
@@ -18,8 +18,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "soc.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/fsp_rangeley/smbus.c b/src/southbridge/intel/fsp_rangeley/smbus.c
index 9a4d867..9ea8126 100644
--- a/src/southbridge/intel/fsp_rangeley/smbus.c
+++ b/src/southbridge/intel/fsp_rangeley/smbus.c
@@ -22,8 +22,8 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "soc.h"
-#include "smbus.h"
 
 static int lsmbus_read_byte(device_t dev, u8 address)
 {
diff --git a/src/southbridge/intel/i3100/Kconfig b/src/southbridge/intel/i3100/Kconfig
index 1dd0931..20990ba 100644
--- a/src/southbridge/intel/i3100/Kconfig
+++ b/src/southbridge/intel/i3100/Kconfig
@@ -2,6 +2,8 @@
 	bool
 	select IOAPIC
 	select HAVE_HARD_RESET
+	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 
 if SOUTHBRIDGE_INTEL_I3100
 
diff --git a/src/southbridge/intel/i3100/early_smbus.c b/src/southbridge/intel/i3100/early_smbus.c
index 35c32a4..35fe614 100644
--- a/src/southbridge/intel/i3100/early_smbus.c
+++ b/src/southbridge/intel/i3100/early_smbus.c
@@ -14,7 +14,7 @@
  *
  */
 
-#include "smbus.h"
+#include <southbridge/intel/common/smbus.h>
 
 #define SMBUS_IO_BASE 0x0f00
 
diff --git a/src/southbridge/intel/i3100/smbus.c b/src/southbridge/intel/i3100/smbus.c
index 32cf709..850982a 100644
--- a/src/southbridge/intel/i3100/smbus.c
+++ b/src/southbridge/intel/i3100/smbus.c
@@ -21,8 +21,8 @@
 #include <device/pci_ops.h>
 #include <device/smbus.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i3100.h"
-#include "smbus.h"
 
 static int lsmbus_read_byte(device_t dev, u8 address)
 {
diff --git a/src/southbridge/intel/i3100/smbus.h b/src/southbridge/intel/i3100/smbus.h
index 0b2f060..93a6269 100644
--- a/src/southbridge/intel/i3100/smbus.h
+++ b/src/southbridge/intel/i3100/smbus.h
@@ -63,89 +63,3 @@
 	return loops ? 0 : -1;
 }
 
-static int do_smbus_read_byte(u32 smbus_io_base, u16 device, u8 address)
-{
-	u8 global_status_register;
-	u8 byte;
-
-	if (smbus_wait_until_ready(smbus_io_base) < 0) {
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
-	/* 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 + SMBXMITADD);
-	/* 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 */
-	if (smbus_wait_until_done(smbus_io_base) < 0) {
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
-	/* Ignore the In Use Status... */
-	global_status_register &= ~(3 << 5);
-
-	/* read results of transaction */
-	byte = inb(smbus_io_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
-		return SMBUS_ERROR;
-	}
-	return byte;
-}
-
-static  int do_smbus_write_byte(unsigned smbus_base, unsigned device, unsigned address, unsigned data)
-{
-	unsigned char global_status_register;
-
-	if (smbus_wait_until_ready(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(data, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	if (global_status_register != (1 << 1))
-		return SMBUS_ERROR;
-
-	return 0;
-}
diff --git a/src/southbridge/intel/i82371eb/Kconfig b/src/southbridge/intel/i82371eb/Kconfig
index 5466b12..f22c6e9 100644
--- a/src/southbridge/intel/i82371eb/Kconfig
+++ b/src/southbridge/intel/i82371eb/Kconfig
@@ -1,4 +1,6 @@
 config SOUTHBRIDGE_INTEL_I82371EB
+	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 	bool
 
 config BOOTBLOCK_SOUTHBRIDGE_INIT
diff --git a/src/southbridge/intel/i82371eb/early_smbus.c b/src/southbridge/intel/i82371eb/early_smbus.c
index af6b14b..8db8a31 100644
--- a/src/southbridge/intel/i82371eb/early_smbus.c
+++ b/src/southbridge/intel/i82371eb/early_smbus.c
@@ -19,8 +19,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82371eb.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/i82371eb/smbus.c b/src/southbridge/intel/i82371eb/smbus.c
index 9231402..3477c52 100644
--- a/src/southbridge/intel/i82371eb/smbus.c
+++ b/src/southbridge/intel/i82371eb/smbus.c
@@ -24,8 +24,8 @@
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <device/smbus.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82371eb.h"
-#include "smbus.h"
 
 static void pwrmgt_enable(struct device *dev)
 {
diff --git a/src/southbridge/intel/i82801ax/Kconfig b/src/southbridge/intel/i82801ax/Kconfig
index 740c69d..cade3f5 100644
--- a/src/southbridge/intel/i82801ax/Kconfig
+++ b/src/southbridge/intel/i82801ax/Kconfig
@@ -18,3 +18,5 @@
 	select IOAPIC
 	select HAVE_HARD_RESET
 	select USE_WATCHDOG_ON_BOOT
+	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
diff --git a/src/southbridge/intel/i82801ax/early_smbus.c b/src/southbridge/intel/i82801ax/early_smbus.c
index 2a224bf..836721b 100644
--- a/src/southbridge/intel/i82801ax/early_smbus.c
+++ b/src/southbridge/intel/i82801ax/early_smbus.c
@@ -20,8 +20,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82801ax.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/i82801ax/smbus.c b/src/southbridge/intel/i82801ax/smbus.c
index 54fa34f..1e71a98 100644
--- a/src/southbridge/intel/i82801ax/smbus.c
+++ b/src/southbridge/intel/i82801ax/smbus.c
@@ -19,8 +19,8 @@
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82801ax.h"
-#include "smbus.h"
 
 static int lsmbus_read_byte(device_t dev, u8 address)
 {
diff --git a/src/southbridge/intel/i82801ax/smbus.h b/src/southbridge/intel/i82801ax/smbus.h
deleted file mode 100644
index 0ca7d8e..0000000
--- a/src/southbridge/intel/i82801ax/smbus.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <device/smbus_def.h>
-#include "i82801ax.h"
-
-int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address);
-
-static void smbus_delay(void)
-{
-	inb(0x80);
-}
-
-static int smbus_wait_until_ready(u16 smbus_io_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		smbus_delay();
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_io_base + SMBHSTSTAT);
-	} while (byte & 1);
-	return loops ? 0 : -1;
-}
-
-static int smbus_wait_until_done(u16 smbus_io_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		smbus_delay();
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_io_base + SMBHSTSTAT);
-	} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
-	return loops ? 0 : -1;
-}
-
-int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address)
-{
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready(smbus_io_base) < 0) {
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
-	/* 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 + SMBXMITADD);
-	/* 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 */
-	if (smbus_wait_until_done(smbus_io_base) < 0) {
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	byte = inb(smbus_io_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
-		return SMBUS_ERROR;
-	}
-	return byte;
-}
diff --git a/src/southbridge/intel/i82801bx/Kconfig b/src/southbridge/intel/i82801bx/Kconfig
index f142300..9d25cbf 100644
--- a/src/southbridge/intel/i82801bx/Kconfig
+++ b/src/southbridge/intel/i82801bx/Kconfig
@@ -18,3 +18,5 @@
 	select IOAPIC
 	select HAVE_HARD_RESET
 	select USE_WATCHDOG_ON_BOOT
+	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
diff --git a/src/southbridge/intel/i82801bx/early_smbus.c b/src/southbridge/intel/i82801bx/early_smbus.c
index c038e0a..103e1a3 100644
--- a/src/southbridge/intel/i82801bx/early_smbus.c
+++ b/src/southbridge/intel/i82801bx/early_smbus.c
@@ -20,8 +20,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82801bx.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/i82801bx/smbus.c b/src/southbridge/intel/i82801bx/smbus.c
index 6cc05ca..01e8c37 100644
--- a/src/southbridge/intel/i82801bx/smbus.c
+++ b/src/southbridge/intel/i82801bx/smbus.c
@@ -19,8 +19,8 @@
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82801bx.h"
-#include "smbus.h"
 
 static int lsmbus_read_byte(device_t dev, u8 address)
 {
diff --git a/src/southbridge/intel/i82801bx/smbus.h b/src/southbridge/intel/i82801bx/smbus.h
deleted file mode 100644
index ffb983e..0000000
--- a/src/southbridge/intel/i82801bx/smbus.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <device/smbus_def.h>
-
-static void smbus_delay(void)
-{
-	inb(0x80);
-}
-
-static int smbus_wait_until_ready(u16 smbus_io_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		smbus_delay();
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_io_base + SMBHSTSTAT);
-	} while (byte & 1);
-	return loops ? 0 : -1;
-}
-
-static int smbus_wait_until_done(u16 smbus_io_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		smbus_delay();
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_io_base + SMBHSTSTAT);
-	} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
-	return loops ? 0 : -1;
-}
-
-static int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address)
-{
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready(smbus_io_base) < 0) {
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
-	/* 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 + SMBXMITADD);
-	/* 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 */
-	if (smbus_wait_until_done(smbus_io_base) < 0) {
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	byte = inb(smbus_io_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
-		return SMBUS_ERROR;
-	}
-	return byte;
-}
diff --git a/src/southbridge/intel/i82801ex/Kconfig b/src/southbridge/intel/i82801ex/Kconfig
index caa5c79..c619a71 100644
--- a/src/southbridge/intel/i82801ex/Kconfig
+++ b/src/southbridge/intel/i82801ex/Kconfig
@@ -1,6 +1,7 @@
 config SOUTHBRIDGE_INTEL_I82801EX
 	bool
 	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 	select IOAPIC
 	select HAVE_HARD_RESET
 	select HAVE_USBDEBUG
diff --git a/src/southbridge/intel/i82801ex/early_smbus.c b/src/southbridge/intel/i82801ex/early_smbus.c
index ad543e7..7ac959e 100644
--- a/src/southbridge/intel/i82801ex/early_smbus.c
+++ b/src/southbridge/intel/i82801ex/early_smbus.c
@@ -1,4 +1,4 @@
-#include "smbus.h"
+#include <southbridge/intel/common/smbus.h>
 
 #define SMBUS_IO_BASE 0x0f00
 
diff --git a/src/southbridge/intel/i82801ex/smbus.c b/src/southbridge/intel/i82801ex/smbus.c
index 75ea119..0c89dce 100644
--- a/src/southbridge/intel/i82801ex/smbus.c
+++ b/src/southbridge/intel/i82801ex/smbus.c
@@ -5,8 +5,8 @@
 #include <device/pci_ops.h>
 #include <device/smbus.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82801ex.h"
-#include "smbus.h"
 
 static int lsmbus_read_byte(device_t dev, u8 address)
 {
diff --git a/src/southbridge/intel/i82801ex/smbus.h b/src/southbridge/intel/i82801ex/smbus.h
deleted file mode 100644
index dbb7b7a..0000000
--- a/src/southbridge/intel/i82801ex/smbus.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#include <device/smbus_def.h>
-
-#define SMBHSTSTAT 0x0
-#define SMBHSTCTL  0x2
-#define SMBHSTCMD  0x3
-#define SMBXMITADD 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBBLKDAT  0x7
-#define SMBTRNSADD 0x9
-#define SMBSLVDATA 0xa
-#define SMLINK_PIN_CTL 0xe
-#define SMBUS_PIN_CTL  0xf
-
-#define SMBUS_TIMEOUT (100*1000*10)
-
-
-static void smbus_delay(void)
-{
-	outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_ready(unsigned smbus_io_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		smbus_delay();
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_io_base + SMBHSTSTAT);
-	} while (byte & 1);
-	return loops?0:-1;
-}
-
-static int smbus_wait_until_done(unsigned smbus_io_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-	        smbus_delay();
-	        if (--loops == 0)
-	               break;
-	        byte = inb(smbus_io_base + SMBHSTSTAT);
-	} while ((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0);
-	return loops?0:-1;
-}
-
-static inline int smbus_wait_until_blk_done(unsigned smbus_io_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-	        smbus_delay();
-	        if (--loops == 0)
-	               break;
-	        byte = inb(smbus_io_base + SMBHSTSTAT);
-	} while ((byte&(1<<7)) == 0);
-	return loops?0:-1;
-}
-
-static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
-{
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready(smbus_io_base) < 0) {
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
-	/* 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 + SMBXMITADD);
-	/* 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 */
-	if (smbus_wait_until_done(smbus_io_base) < 0) {
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
-	/* Ignore the In Use Status... */
-	global_status_register &= ~(3 << 5);
-
-	/* read results of transaction */
-	byte = inb(smbus_io_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
-		return SMBUS_ERROR;
-	}
-	return byte;
-}
diff --git a/src/southbridge/intel/i82801gx/Kconfig b/src/southbridge/intel/i82801gx/Kconfig
index b2265c4..68c2362 100644
--- a/src/southbridge/intel/i82801gx/Kconfig
+++ b/src/southbridge/intel/i82801gx/Kconfig
@@ -24,6 +24,7 @@
 	select HAVE_SMI_HANDLER
 	select COMMON_FADT
 	select SOUTHBRIDGE_INTEL_COMMON_GPIO
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 
 if SOUTHBRIDGE_INTEL_I82801GX
 
diff --git a/src/southbridge/intel/i82801gx/early_smbus.c b/src/southbridge/intel/i82801gx/early_smbus.c
index b8852e9..6c3a0f6 100644
--- a/src/southbridge/intel/i82801gx/early_smbus.c
+++ b/src/southbridge/intel/i82801gx/early_smbus.c
@@ -18,8 +18,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82801gx.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/i82801gx/smbus.c b/src/southbridge/intel/i82801gx/smbus.c
index d028f73..fdf76a0 100644
--- a/src/southbridge/intel/i82801gx/smbus.c
+++ b/src/southbridge/intel/i82801gx/smbus.c
@@ -22,8 +22,8 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82801gx.h"
-#include "smbus.h"
 
 static int lsmbus_read_byte(device_t dev, u8 address)
 {
@@ -38,49 +38,6 @@
 	return do_smbus_read_byte(res->base, device, address);
 }
 
-static int do_smbus_write_byte(unsigned int smbus_base, unsigned int device,
-			unsigned int address, unsigned int data)
-{
-	unsigned char global_status_register;
-
-	if (smbus_wait_until_ready(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(data, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	if (global_status_register != (1 << 1))
-		return SMBUS_ERROR;
-	return 0;
-}
-
 static int lsmbus_write_byte(device_t dev, u8 address, u8 data)
 {
 	u16 device;
@@ -93,58 +50,6 @@
 	return do_smbus_write_byte(res->base, device, address, data);
 }
 
-static int do_smbus_block_write(unsigned int smbus_base, unsigned int device,
-			      unsigned int cmd, unsigned int bytes, const u8 *buf)
-{
-	u8 status;
-
-	if (smbus_wait_until_ready(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(cmd & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a block data write */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x5 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* set number of bytes to transfer */
-	outb(bytes, smbus_base + SMBHSTDAT0);
-
-	outb(*buf++, smbus_base + SMBBLKDAT);
-	bytes--;
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	while (!(inb(smbus_base + SMBHSTSTAT) & 1))
-		;
-	/* Poll for transaction completion */
-	do {
-		status = inb(smbus_base + SMBHSTSTAT);
-		if (status & ((1 << 4) | /* FAILED */
-			      (1 << 3) | /* BUS ERR */
-			      (1 << 2))) /* DEV ERR */
-			return SMBUS_ERROR;
-
-		if (status & 0x80) { /* Byte done */
-			outb(*buf++, smbus_base + SMBBLKDAT);
-			outb(status, smbus_base + SMBHSTSTAT);
-		}
-	} while (status & 0x01);
-
-	return 0;
-}
-
-
-
 static int lsmbus_block_write(device_t dev, u8 cmd, u8 bytes, const u8 *buf)
 {
 	u16 device;
@@ -155,57 +60,6 @@
 	pbus = get_pbus_smbus(dev);
 	res = find_resource(pbus->dev, 0x20);
 	return do_smbus_block_write(res->base, device, cmd, bytes, buf);
-}
-
-static int do_smbus_block_read(unsigned int smbus_base, unsigned int device,
-			      unsigned int cmd, unsigned int bytes, u8 *buf)
-{
-	u8 status;
-	int bytes_read = 0;
-	if (smbus_wait_until_ready(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(cmd & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a block data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x5 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	while (!(inb(smbus_base + SMBHSTSTAT) & 1))
-		;
-	/* Poll for transaction completion */
-	do {
-		status = inb(smbus_base + SMBHSTSTAT);
-		if (status & ((1 << 4) | /* FAILED */
-			      (1 << 3) | /* BUS ERR */
-			      (1 << 2))) /* DEV ERR */
-			return SMBUS_ERROR;
-
-		if (status & 0x80) { /* Byte done */
-			*buf = inb(smbus_base + SMBBLKDAT);
-			buf++;
-			bytes_read++;
-			outb(status, smbus_base + SMBHSTSTAT);
-			if (--bytes == 1) {
-				/* indicate that next byte is the last one */
-				outb(inb(smbus_base + SMBHSTCTL) | 0x20,
-					 smbus_base + SMBHSTCTL);
-			}
-		}
-	} while (status & 0x01);
-
-	return bytes_read;
 }
 
 static int lsmbus_block_read(device_t dev, u8 cmd, u8 bytes, u8 *buf)
diff --git a/src/southbridge/intel/i82801gx/smbus.h b/src/southbridge/intel/i82801gx/smbus.h
index ff8e1fb..392ea0b 100644
--- a/src/southbridge/intel/i82801gx/smbus.h
+++ b/src/southbridge/intel/i82801gx/smbus.h
@@ -47,46 +47,3 @@
 	} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
 	return loops ? 0 : -1;
 }
-
-static int do_smbus_read_byte(unsigned int smbus_base, unsigned int device, unsigned int address)
-{
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(0, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	byte = inb(smbus_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1))
-		return SMBUS_ERROR;
-	return byte;
-}
diff --git a/src/southbridge/intel/i82801ix/Kconfig b/src/southbridge/intel/i82801ix/Kconfig
index e4d1f91..6879bce 100644
--- a/src/southbridge/intel/i82801ix/Kconfig
+++ b/src/southbridge/intel/i82801ix/Kconfig
@@ -17,6 +17,7 @@
 config SOUTHBRIDGE_INTEL_I82801IX
 	bool
 	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 	select IOAPIC
 	select HAVE_USBDEBUG
 	select HAVE_HARD_RESET
diff --git a/src/southbridge/intel/i82801ix/early_smbus.c b/src/southbridge/intel/i82801ix/early_smbus.c
index 31b33e9..0e4195c 100644
--- a/src/southbridge/intel/i82801ix/early_smbus.c
+++ b/src/southbridge/intel/i82801ix/early_smbus.c
@@ -19,8 +19,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "i82801ix.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/i82801ix/smbus.c b/src/southbridge/intel/i82801ix/smbus.c
index 2113722..3ac0db2 100644
--- a/src/southbridge/intel/i82801ix/smbus.c
+++ b/src/southbridge/intel/i82801ix/smbus.c
@@ -22,7 +22,7 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <arch/io.h>
-#include "smbus.h"
+#include <southbridge/intel/common/smbus.h>
 
 static void pch_smbus_init(device_t dev)
 {
diff --git a/src/southbridge/intel/i82801ix/smbus.h b/src/southbridge/intel/i82801ix/smbus.h
deleted file mode 100644
index bcc7587..0000000
--- a/src/southbridge/intel/i82801ix/smbus.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
- * Copyright (C) 2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <device/smbus_def.h>
-#include "i82801ix.h"
-
-static void smbus_delay(void)
-{
-	inb(0x80);
-}
-
-static int smbus_wait_until_ready(u16 smbus_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		smbus_delay();
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_base + SMBHSTSTAT);
-	} while (byte & 1);
-	return loops ? 0 : -1;
-}
-
-static int smbus_wait_until_done(u16 smbus_base)
-{
-	unsigned loops = SMBUS_TIMEOUT;
-	unsigned char byte;
-	do {
-		smbus_delay();
-		if (--loops == 0)
-			break;
-		byte = inb(smbus_base + SMBHSTSTAT);
-	} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
-	return loops ? 0 : -1;
-}
-
-static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
-{
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready(smbus_base) < 0) {
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(0, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0) {
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	byte = inb(smbus_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
-		return SMBUS_ERROR;
-	}
-	return byte;
-}
-
-#ifndef __PRE_RAM__
-static  int do_smbus_write_byte(unsigned smbus_base, unsigned device, unsigned address, unsigned data)
-{
-	unsigned char global_status_register;
-
-	if (smbus_wait_until_ready(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(data, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	if (global_status_register != (1 << 1))
-		return SMBUS_ERROR;
-
-	return 0;
-}
-#endif
diff --git a/src/southbridge/intel/ibexpeak/Kconfig b/src/southbridge/intel/ibexpeak/Kconfig
index ad32a9b..41ace46 100644
--- a/src/southbridge/intel/ibexpeak/Kconfig
+++ b/src/southbridge/intel/ibexpeak/Kconfig
@@ -30,6 +30,7 @@
 	select PCIEXP_COMMON_CLOCK
 	select SPI_FLASH
 	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 	select HAVE_USBDEBUG_OPTIONS
 	select COMMON_FADT
 	select ACPI_SATA_GENERATOR
diff --git a/src/southbridge/intel/ibexpeak/early_smbus.c b/src/southbridge/intel/ibexpeak/early_smbus.c
index f3dab8d..b7823eb 100644
--- a/src/southbridge/intel/ibexpeak/early_smbus.c
+++ b/src/southbridge/intel/ibexpeak/early_smbus.c
@@ -18,8 +18,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "pch.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/ibexpeak/smbus.c b/src/southbridge/intel/ibexpeak/smbus.c
index 3b2f18c..aea52de 100644
--- a/src/southbridge/intel/ibexpeak/smbus.c
+++ b/src/southbridge/intel/ibexpeak/smbus.c
@@ -22,8 +22,8 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "pch.h"
-#include "smbus.h"
 
 static void pch_smbus_init(device_t dev)
 {
diff --git a/src/southbridge/intel/lynxpoint/Kconfig b/src/southbridge/intel/lynxpoint/Kconfig
index 742f95c..c65e5d7 100644
--- a/src/southbridge/intel/lynxpoint/Kconfig
+++ b/src/southbridge/intel/lynxpoint/Kconfig
@@ -22,6 +22,7 @@
 	def_bool y
 	select ACPI_INTEL_HARDWARE_SLEEP_VALUES
 	select SOUTHBRIDGE_INTEL_COMMON
+	select SOUTHBRIDGE_INTEL_COMMON_SMBUS
 	select IOAPIC
 	select HAVE_HARD_RESET
 	select HAVE_USBDEBUG_OPTIONS
diff --git a/src/southbridge/intel/lynxpoint/early_smbus.c b/src/southbridge/intel/lynxpoint/early_smbus.c
index 2b174c7..cf3a34c 100644
--- a/src/southbridge/intel/lynxpoint/early_smbus.c
+++ b/src/southbridge/intel/lynxpoint/early_smbus.c
@@ -18,8 +18,8 @@
 #include <console/console.h>
 #include <device/pci_ids.h>
 #include <device/pci_def.h>
+#include <southbridge/intel/common/smbus.h>
 #include "pch.h"
-#include "smbus.h"
 
 void enable_smbus(void)
 {
diff --git a/src/southbridge/intel/lynxpoint/smbus.c b/src/southbridge/intel/lynxpoint/smbus.c
index d81a097..ccb5ea0 100644
--- a/src/southbridge/intel/lynxpoint/smbus.c
+++ b/src/southbridge/intel/lynxpoint/smbus.c
@@ -22,8 +22,8 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <arch/io.h>
+#include <southbridge/intel/common/smbus.h>
 #include "pch.h"
-#include "smbus.h"
 
 static void pch_smbus_init(device_t dev)
 {
@@ -52,54 +52,6 @@
 	res = find_resource(pbus->dev, PCI_BASE_ADDRESS_4);
 
 	return do_smbus_read_byte(res->base, device, address);
-}
-
-static int do_smbus_write_byte(unsigned smbus_base, unsigned device,
-			       unsigned address, unsigned data)
-{
-	unsigned char global_status_register;
-
-	if (smbus_wait_until_ready(smbus_base) < 0)
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(data, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0) {
-		printk(BIOS_ERR, "SMBUS transaction timeout\n");
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	if (global_status_register != (1 << 1)) {
-		printk(BIOS_ERR, "SMBUS transaction error\n");
-		return SMBUS_ERROR;
-	}
-
-	return 0;
 }
 
 static int lsmbus_write_byte(device_t dev, u8 address, u8 data)
diff --git a/src/southbridge/intel/lynxpoint/smbus.h b/src/southbridge/intel/lynxpoint/smbus.h
index 0978963..48c4c87 100644
--- a/src/southbridge/intel/lynxpoint/smbus.h
+++ b/src/southbridge/intel/lynxpoint/smbus.h
@@ -47,49 +47,3 @@
 	} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
 	return loops ? 0 : -1;
 }
-
-static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
-{
-	unsigned char global_status_register;
-	unsigned char byte;
-
-	if (smbus_wait_until_ready(smbus_base) < 0) {
-		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-	}
-	/* Setup transaction */
-	/* Disable interrupts */
-	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
-	/* Set the device I'm talking too */
-	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
-	/* Set the command/address... */
-	outb(address & 0xff, smbus_base + SMBHSTCMD);
-	/* Set up for a byte data read */
-	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
-	     (smbus_base + SMBHSTCTL));
-	/* Clear any lingering errors, so the transaction will run */
-	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
-	/* Clear the data byte... */
-	outb(0, smbus_base + SMBHSTDAT0);
-
-	/* Start the command */
-	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
-	     smbus_base + SMBHSTCTL);
-
-	/* Poll for transaction completion */
-	if (smbus_wait_until_done(smbus_base) < 0) {
-		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-	}
-
-	global_status_register = inb(smbus_base + SMBHSTSTAT);
-
-	/* Ignore the "In Use" status... */
-	global_status_register &= ~(3 << 5);
-
-	/* Read results of transaction */
-	byte = inb(smbus_base + SMBHSTDAT0);
-	if (global_status_register != (1 << 1)) {
-		return SMBUS_ERROR;
-	}
-	return byte;
-}

-- 
To view, visit https://review.coreboot.org/19258
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I93bb186e04e8c32dff04fc1abe4b5ecbc4c9c962
Gerrit-PatchSet: 1
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>



More information about the coreboot-gerrit mailing list