diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index f83427b349504a62d854d93b60ca94c4ca79dd0b..92167d0ecb5f9217153d79a5d9776f16aea90c7e 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -424,13 +424,6 @@ static int filesystems_read_proc(char *page, char **start, off_t off,
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-static int ioports_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = get_ioport_list(page);
-	return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
 static int cmdline_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
@@ -469,13 +462,6 @@ static int execdomains_read_proc(char *page, char **start, off_t off,
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-static int memory_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = get_mem_list(page);
-	return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
 /*
  * This function accesses profiling information. The returned data is
  * binary: the sampling step and the actual contents of the profile
@@ -569,13 +555,11 @@ void __init proc_misc_init(void)
 		{"stat",	kstat_read_proc},
 		{"devices",	devices_read_proc},
 		{"filesystems",	filesystems_read_proc},
-		{"ioports",	ioports_read_proc},
 		{"cmdline",	cmdline_read_proc},
 #ifdef CONFIG_SGI_DS1286
 		{"rtc",		ds1286_read_proc},
 #endif
 		{"locks",	locks_read_proc},
-		{"iomem",	memory_read_proc},
 		{"execdomains",	execdomains_read_proc},
 		{NULL,}
 	};
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 7a9431f4673f3bb9ed870eb239c7c2734b8d4210..6730ec8233218be93a00cb08c2763feb44e57c0a 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -112,7 +112,4 @@ extern struct resource * __request_region(struct resource *, unsigned long start
 extern int __deprecated __check_region(struct resource *, unsigned long, unsigned long);
 extern void __release_region(struct resource *, unsigned long, unsigned long);
 
-#define get_ioport_list(buf)	get_resource_list(&ioport_resource, buf, PAGE_SIZE)
-#define get_mem_list(buf)	get_resource_list(&iomem_resource, buf, PAGE_SIZE)
-
 #endif	/* _LINUX_IOPORT_H */
diff --git a/kernel/resource.c b/kernel/resource.c
index 83d04826245dba403fd9335d7744231d88f8e864..ca82abf27fc9376b1732c71130a5ae1d5a78ceba 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -7,61 +7,125 @@
  * Arbitrary resource management.
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <asm/io.h>
 
+
 struct resource ioport_resource = { "PCI IO", 0x0000, IO_SPACE_LIMIT, IORESOURCE_IO };
 struct resource iomem_resource = { "PCI mem", 0x00000000, 0xffffffff, IORESOURCE_MEM };
 
 static rwlock_t resource_lock = RW_LOCK_UNLOCKED;
 
+#ifdef CONFIG_PROC_FS
+
+#define MAX_IORES_LEVEL		5
+
 /*
- * This generates reports for /proc/ioports and /proc/iomem
+ * do_resource_list():
+ * for reports of /proc/ioports and /proc/iomem;
+ * do current entry, then children, then siblings;
  */
-static char * do_resource_list(struct resource *entry, const char *fmt, int offset, char *buf, char *end)
+static int do_resource_list(struct seq_file *m, struct resource *res, const char *fmt, int level)
 {
-	if (offset < 0)
-		offset = 0;
+	while (res) {
+		const char *name;
 
-	while (entry) {
-		const char *name = entry->name;
-		unsigned long from, to;
+		name = res->name ? res->name : "<BAD>";
+		if (level > MAX_IORES_LEVEL)
+			level = MAX_IORES_LEVEL;
+		seq_printf (m, fmt + 2 * MAX_IORES_LEVEL - 2 * level,
+				res->start, res->end, name);
 
-		if ((int) (end-buf) < 80)
-			return buf;
+		if (res->child)
+			do_resource_list(m, res->child, fmt, level + 1);
 
-		from = entry->start;
-		to = entry->end;
-		if (!name)
-			name = "<BAD>";
-
-		buf += sprintf(buf, fmt + offset, from, to, name);
-		if (entry->child)
-			buf = do_resource_list(entry->child, fmt, offset-2, buf, end);
-		entry = entry->sibling;
+		res = res->sibling;
 	}
 
-	return buf;
+	return 0;
 }
 
-int get_resource_list(struct resource *root, char *buf, int size)
+static int ioresources_show(struct seq_file *m, void *v)
 {
+	struct resource *root = m->private;
 	char *fmt;
 	int retval;
 
-	fmt = "        %08lx-%08lx : %s\n";
-	if (root->end < 0x10000)
-		fmt = "        %04lx-%04lx : %s\n";
+	fmt = root->end < 0x10000
+		? "          %04lx-%04lx : %s\n"
+		: "          %08lx-%08lx : %s\n";
 	read_lock(&resource_lock);
-	retval = do_resource_list(root->child, fmt, 8, buf, buf + size) - buf;
+	retval = do_resource_list(m, root->child, fmt, 0);
 	read_unlock(&resource_lock);
 	return retval;
-}	
+}
+
+static int ioresources_open(struct file *file, struct resource *root)
+{
+	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	struct seq_file *m;
+	int res;
+
+	if (!buf)
+		return -ENOMEM;
+	res = single_open(file, ioresources_show, root);
+	if (!res) {
+		m = file->private_data;
+		m->buf = buf;
+		m->size = PAGE_SIZE;
+	} else
+		kfree(buf);
+	return res;
+}
+
+static int ioports_open(struct inode *inode, struct file *file)
+{
+	return ioresources_open(file, &ioport_resource);
+}
+
+static struct file_operations proc_ioports_operations = {
+	.open		= ioports_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int iomem_open(struct inode *inode, struct file *file)
+{
+	return ioresources_open(file, &iomem_resource);
+}
+
+static struct file_operations proc_iomem_operations = {
+	.open		= iomem_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init ioresources_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	entry = create_proc_entry("ioports", 0, NULL);
+	if (entry)
+		entry->proc_fops = &proc_ioports_operations;
+	entry = create_proc_entry("iomem", 0, NULL);
+	if (entry)
+		entry->proc_fops = &proc_iomem_operations;
+	return 0;
+}
+__initcall(ioresources_init);
+
+#endif /* CONFIG_PROC_FS */
 
 /* Return the conflict entry if you can't request it */
 static struct resource * __request_resource(struct resource *root, struct resource *new)