diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 2718e8a7df83e7748e7bbea637e729822f70b5d3..8c5c06a509d2516b5412ada726ebdedc6e6e12c5 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -30,6 +30,7 @@
 #include <linux/proc_fs.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
+#include <linux/seq_file.h>
 #include <asm/uaccess.h>
 
 
@@ -448,45 +449,7 @@ int i2c_release_client(struct i2c_client *client)
 	return 0;
 }
 
-/* ----------------------------------------------------
- * The /proc functions
- * ----------------------------------------------------
- */
-
 #ifdef CONFIG_PROC_FS
-/* This function generates the output for /proc/bus/i2c */
-static int read_bus_i2c(char *buf, char **start, off_t offset,
-			int len, int *eof, void *private)
-{
-	int i;
-	int nr = 0;
-
-	/* Note that it is safe to write a `little' beyond len. Yes, really. */
-	/* Fuck you.  Will convert this to seq_file later.  --hch */
-
-	down(&core_lists);
-	for (i = 0; (i < I2C_ADAP_MAX) && (nr < len); i++) {
-		if (adapters[i]) {
-			nr += sprintf(buf+nr, "i2c-%d\t", i);
-			if (adapters[i]->algo->smbus_xfer) {
-				if (adapters[i]->algo->master_xfer)
-					nr += sprintf(buf+nr,"smbus/i2c");
-				else
-					nr += sprintf(buf+nr,"smbus    ");
-			} else if (adapters[i]->algo->master_xfer)
-				nr += sprintf(buf+nr,"i2c       ");
-			else
-				nr += sprintf(buf+nr,"dummy     ");
-			nr += sprintf(buf+nr,"\t%-32s\t%-32s\n",
-			              adapters[i]->name,
-			              adapters[i]->algo->name);
-		}
-	}
-	up(&core_lists);
-
-	return nr;
-}
-
 /* This function generates the output for /proc/bus/i2c-? */
 static ssize_t i2cproc_bus_read(struct file *file, char *buf,
 				size_t count, loff_t *ppos)
@@ -556,6 +519,50 @@ static struct file_operations i2cproc_operations = {
 	.read		= i2cproc_bus_read,
 };
 
+/* This function generates the output for /proc/bus/i2c */
+static int bus_i2c_show(struct seq_file *s, void *p)
+{
+	int i;
+
+	down(&core_lists);
+	for (i = 0; i < I2C_ADAP_MAX; i++) {
+		struct i2c_adapter *adapter = adapters[i];
+
+		if (!adapter)
+			continue;
+
+		seq_printf(s, "i2c-%d\t", i);
+
+		if (adapter->algo->smbus_xfer) {
+			if (adapter->algo->master_xfer)
+				seq_printf(s, "smbus/i2c");
+			else
+				seq_printf(s, "smbus    ");
+		} else if (adapter->algo->master_xfer)
+			seq_printf(s ,"i2c       ");
+		else
+			seq_printf(s, "dummy     ");
+
+		seq_printf(s, "\t%-32s\t%-32s\n",
+			      adapter->name, adapter->algo->name);
+	}
+	up(&core_lists);
+
+	return 0;
+}
+
+static int bus_i2c_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, bus_i2c_show, NULL);
+}
+
+static struct file_operations bus_i2c_fops = {
+	.open		= bus_i2c_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+ };
+
 static int i2cproc_register(struct i2c_adapter *adap, int bus)
 {
 	struct proc_dir_entry *proc_entry;
@@ -588,15 +595,16 @@ static int __init i2cproc_init(void)
 {
 	struct proc_dir_entry *proc_bus_i2c;
 
-	proc_bus_i2c = create_proc_entry("i2c",0,proc_bus);
-	if (!proc_bus_i2c) {
-		printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c");
-		return -ENOENT;
- 	}
+	proc_bus_i2c = create_proc_entry("i2c", 0, proc_bus);
+	if (!proc_bus_i2c)
+		goto fail;
+	proc_bus_i2c->proc_fops = &bus_i2c_fops;
+ 	proc_bus_i2c->owner = THIS_MODULE;
+ 	return 0;
 
-	proc_bus_i2c->read_proc = &read_bus_i2c;
-	proc_bus_i2c->owner = THIS_MODULE;
-	return 0;
+ fail:
+	printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c");
+	return -ENOENT;
 }
 
 static void __exit i2cproc_cleanup(void)