diff -ruNp module-init-tools-3.2-pre6/depmod.c module-init-tools-3.2-pre6.macio/depmod.c
--- module-init-tools-3.2-pre6/depmod.c	2005-07-18 22:06:43.119037458 +0200
+++ module-init-tools-3.2-pre6.macio/depmod.c	2005-07-18 22:09:24.107526857 +0200
@@ -706,6 +706,7 @@ static struct depfile depfiles[] = {
 	{ "modules.isapnpmap", output_isapnp_table },
 	{ "modules.inputmap", output_input_table },
 	{ "modules.seriomap", output_serio_table },
+ 	{ "modules.ofmap", output_of_table },
 	{ "modules.alias", output_aliases },
 	{ "modules.symbols", output_symbols },
 };
diff -ruNp module-init-tools-3.2-pre6/depmod.h module-init-tools-3.2-pre6.macio/depmod.h
--- module-init-tools-3.2-pre6/depmod.h	2005-02-07 04:34:32.000000000 +0100
+++ module-init-tools-3.2-pre6.macio/depmod.h	2005-07-18 22:09:47.408781748 +0200
@@ -55,6 +55,8 @@ struct module
 	void *input_table;
 	unsigned int serio_size;
 	void *serio_table;
+ 	unsigned int of_size;
+ 	void *of_table;
 
 	/* File contents and length. */
 	void *data;
diff -ruNp module-init-tools-3.2-pre6/moduleops_core.c module-init-tools-3.2-pre6.macio/moduleops_core.c
--- module-init-tools-3.2-pre6/moduleops_core.c	2005-03-29 06:40:34.000000000 +0200
+++ module-init-tools-3.2-pre6.macio/moduleops_core.c	2005-07-18 22:12:45.960432436 +0200
@@ -224,6 +224,11 @@ static void PERBIT(fetch_tables)(struct 
 	module->serio_table = PERBIT(deref_sym)(module->data,
 					"__mod_serio_device_table",
 					module->conv);
+
+	module->of_size = PERBIT(OF_DEVICE_SIZE);
+	module->of_table = PERBIT(deref_sym)(module->data,
+					"__mod_of_device_table",
+                                        module->conv);
 }
 
 struct module_ops PERBIT(mod_ops) = {
diff -ruNp module-init-tools-3.2-pre6/moduleops_core.c~ module-init-tools-3.2-pre6.macio/moduleops_core.c~
--- module-init-tools-3.2-pre6/moduleops_core.c~	1970-01-01 01:00:00.000000000 +0100
+++ module-init-tools-3.2-pre6.macio/moduleops_core.c~	2005-07-18 22:08:52.393068411 +0200
@@ -0,0 +1,239 @@
+/* Load the given section: NULL on error. */
+static void *PERBIT(load_section)(ElfPERBIT(Ehdr) *hdr,
+			    const char *secname,
+			    unsigned long *size,
+			    int conv)
+{
+	ElfPERBIT(Shdr) *sechdrs;
+	unsigned int i;
+	char *secnames;
+
+	/* Grab section headers and strings so we can tell who is who */
+	sechdrs = (void *)hdr + END(hdr->e_shoff, conv);
+	secnames = (void *)hdr
+		+ END(sechdrs[END(hdr->e_shstrndx, conv)].sh_offset, conv);
+
+	/* Find the section they want */
+	for (i = 1; i < END(hdr->e_shnum, conv); i++) {
+		if (streq(secnames+END(sechdrs[i].sh_name, conv), secname)) {
+			*size = END(sechdrs[i].sh_size, conv);
+			return (void *)hdr + END(sechdrs[i].sh_offset, conv);
+		}
+	}
+	*size = 0;
+	return NULL;
+}
+
+static void PERBIT(load_symbols)(struct module *module)
+{
+	struct PERBIT(kernel_symbol) *ksyms;
+	char *ksymstrings;
+	unsigned long i, size;
+
+	/* New-style: strings are in this section. */
+	ksymstrings = PERBIT(load_section)(module->data, "__ksymtab_strings",
+					   &size, module->conv);
+	if (ksymstrings) {
+		unsigned int i = 0;
+		for (;;) {
+			/* Skip any zero padding. */
+			while (!ksymstrings[i])
+				if (++i >= size)
+					return;
+			add_symbol(ksymstrings+i, module);
+			i += strlen(ksymstrings+i);
+		}
+		/* GPL symbols too */
+		ksymstrings = PERBIT(load_section)(module->data,
+						   "__ksymtab_strings_gpl",
+						   &size, module->conv);
+		for (;;) {
+			/* Skip any zero padding. */
+			while (!ksymstrings[i])
+				if (++i >= size)
+					return;
+			add_symbol(ksymstrings+i, module);
+			i += strlen(ksymstrings+i);
+		}
+		return;
+	}
+
+	/* Old-style. */
+	ksyms = PERBIT(load_section)(module->data, "__ksymtab", &size,
+				     module->conv);
+	for (i = 0; i < size / sizeof(struct PERBIT(kernel_symbol)); i++)
+		add_symbol(ksyms[i].name, module);
+	ksyms = PERBIT(load_section)(module->data, "__gpl_ksymtab", &size,
+				     module->conv);
+	for (i = 0; i < size / sizeof(struct PERBIT(kernel_symbol)); i++)
+		add_symbol(ksyms[i].name, module);
+}
+
+static char *PERBIT(get_aliases)(struct module *module, unsigned long *size)
+{
+	return PERBIT(load_section)(module->data, ".modalias", size,
+				    module->conv);
+}
+
+static char *PERBIT(get_modinfo)(struct module *module, unsigned long *size)
+{
+	return PERBIT(load_section)(module->data, ".modinfo", size,
+				    module->conv);
+}
+
+#ifndef STT_REGISTER
+#define STT_REGISTER    13              /* Global register reserved to app. */
+#endif
+
+/* Calculate the dependencies for this module */
+static void PERBIT(calculate_deps)(struct module *module, int verbose)
+{
+	unsigned int i;
+	unsigned long size;
+	char *strings;
+	ElfPERBIT(Sym) *syms;
+	ElfPERBIT(Ehdr) *hdr;
+	int handle_register_symbols;
+
+	strings = PERBIT(load_section)(module->data, ".strtab", &size,
+				       module->conv);
+	syms = PERBIT(load_section)(module->data, ".symtab", &size,
+				    module->conv);
+
+	if (!strings || !syms) {
+		warn("Couldn't find symtab and strtab in module %s\n",
+		     module->pathname);
+		return;
+	}
+
+	hdr = module->data;
+	handle_register_symbols = 0;
+	if (END(hdr->e_machine, module->conv) == EM_SPARC ||
+	    END(hdr->e_machine, module->conv) == EM_SPARCV9)
+		handle_register_symbols = 1;
+
+	module->num_deps = 0;
+	module->deps = NULL;
+	for (i = 1; i < size / sizeof(syms[0]); i++) {
+		if (END(syms[i].st_shndx, module->conv) == SHN_UNDEF) {
+			/* Look for symbol */
+			const char *name;
+			struct module *owner;
+			int weak;
+
+			name = strings + END(syms[i].st_name, module->conv);
+
+			/* Not really undefined: sparc gcc 3.3 creates
+                           U references when you have global asm
+                           variables, to avoid anyone else misusing
+                           them. */
+			if (handle_register_symbols
+			    && (ELFPERBIT(ST_TYPE)(END(syms[i].st_info,
+						       module->conv))
+				== STT_REGISTER))
+				continue;
+
+			weak = (ELFPERBIT(ST_BIND)(END(syms[i].st_info,
+						       module->conv))
+				== STB_WEAK);
+			owner = find_symbol(name, module->pathname, weak);
+			if (owner) {
+				if (verbose)
+					printf("%s needs \"%s\": %s\n",
+					       module->pathname, name,
+					       owner->pathname);
+				add_dep(module, owner);
+			}
+		}
+	}
+}
+
+static void *PERBIT(deref_sym)(ElfPERBIT(Ehdr) *hdr, const char *name,
+			       int conv)
+{
+	unsigned int i;
+	unsigned long size;
+	char *strings;
+	ElfPERBIT(Sym) *syms;
+	ElfPERBIT(Shdr) *sechdrs;
+
+	sechdrs = (void *)hdr + END(hdr->e_shoff, conv);
+	strings = PERBIT(load_section)(hdr, ".strtab", &size, conv);
+	syms = PERBIT(load_section)(hdr, ".symtab", &size, conv);
+
+	/* Don't warn again: we already have above */
+	if (!strings || !syms)
+		return NULL;
+
+	for (i = 0; i < size / sizeof(syms[0]); i++) {
+		if (streq(strings + END(syms[i].st_name, conv), name)) {
+			/* In BSS?  Happens for empty device tables on
+			 * recent GCC versions. */
+			if (END(sechdrs[END(syms[i].st_shndx, conv)].sh_type,
+				conv) == SHT_NOBITS)
+				return NULL;
+			return (void *)hdr
+				+ END(sechdrs[END(syms[i].st_shndx, conv)]
+				      .sh_offset, conv)
+				+ END(syms[i].st_value, conv);
+		}
+	}
+	return NULL;
+}
+
+/* FIXME: Check size, unless we end up using aliases anyway --RR */
+static void PERBIT(fetch_tables)(struct module *module)
+{
+	module->pci_size = PERBIT(PCI_DEVICE_SIZE);
+	module->pci_table = PERBIT(deref_sym)(module->data,
+					"__mod_pci_device_table",
+					module->conv);
+
+	module->usb_size = PERBIT(USB_DEVICE_SIZE);
+	module->usb_table = PERBIT(deref_sym)(module->data,
+					"__mod_usb_device_table",
+					module->conv);
+
+	module->ccw_size = PERBIT(CCW_DEVICE_SIZE);
+	module->ccw_table = PERBIT(deref_sym)(module->data,
+					"__mod_ccw_device_table",
+					module->conv);
+
+	module->ieee1394_size = PERBIT(IEEE1394_DEVICE_SIZE);
+	module->ieee1394_table = PERBIT(deref_sym)(module->data,
+					"__mod_ieee1394_device_table",
+					module->conv);
+
+	module->pnp_size = PERBIT(PNP_DEVICE_SIZE);
+	module->pnp_table = PERBIT(deref_sym)(module->data,
+					"__mod_pnp_device_table",
+					module->conv);
+
+	module->pnp_card_size = PERBIT(PNP_CARD_DEVICE_SIZE);
+	module->pnp_card_table = PERBIT(deref_sym)(module->data,
+					"__mod_pnp_card_device_table",
+					module->conv);
+	module->pnp_card_offset = PERBIT(PNP_CARD_DEVICE_OFFSET);
+
+	module->input_size = PERBIT(INPUT_DEVICE_SIZE);
+	module->input_table = PERBIT(deref_sym)(module->data,
+					"__mod_input_device_table",
+					module->conv);
+
+	module->serio_size = PERBIT(SERIO_DEVICE_SIZE);
+	module->serio_table = PERBIT(deref_sym)(module->data,
+					"__mod_serio_device_table",
+					module->conv);
+
+	module->of_size = PERBIT(OF_DEVICE_SIZE);
+	module->of_table = PERBIT(deref_sym)(module->data,
+					"__mod_of_device_table");
+}
+
+struct module_ops PERBIT(mod_ops) = {
+	.load_symbols	= PERBIT(load_symbols),
+	.calculate_deps	= PERBIT(calculate_deps),
+	.fetch_tables	= PERBIT(fetch_tables),
+	.get_aliases	= PERBIT(get_aliases),
+	.get_modinfo	= PERBIT(get_modinfo),
+};
diff -ruNp module-init-tools-3.2-pre6/tables.c module-init-tools-3.2-pre6.macio/tables.c
--- module-init-tools-3.2-pre6/tables.c	2005-02-07 04:34:33.000000000 +0100
+++ module-init-tools-3.2-pre6.macio/tables.c	2005-07-18 22:07:48.260385358 +0200
@@ -408,3 +408,55 @@ void output_serio_table(struct module *m
 }
 
 
+static void strip_whitespace (char *str, char chr)
+{
+	int i;
+	if (!str)
+		return;
+	for (i = strlen (str); i >= 0; --i)
+		if (isspace (*str))
+			*str = chr;
+}
+
+/* We set driver_data to zero */
+static void output_of_entry(struct of_device_id *dev, char *name, FILE *out)
+{
+	char *ofname = NULL, *type = NULL, *compatible = NULL;
+	if (dev->name[0]) {
+		ofname = strdup (dev->name);
+		strip_whitespace (ofname, '_');
+	}
+
+	if (dev->type[0]) {
+		type = strdup (dev->type);
+		strip_whitespace (type, '_');
+       }
+
+	if (dev->compatible[0]) {
+		compatible = strdup (dev->compatible);
+		strip_whitespace (compatible, '_');
+	}
+
+        fprintf (out, "%-20s %-20s %-20s %s\n",
+                name, ofname ? ofname : "*", type ? type : "*",
+                compatible ? compatible : "*");
+}
+
+void output_of_table(struct module *modules, FILE *out)
+{
+	struct module *i;
+
+        fprintf (out, "# of module          name                 type                 compatible\n");                                 
+	for (i = modules; i; i = i->next) {
+		struct of_device_id *e;
+		char shortname[strlen(i->pathname) + 1];
+
+		if (!i->of_table)
+			continue;
+
+		make_shortname(shortname, i->pathname);
+		for (e = i->of_table; e->name[0]|e->type[0]|e->compatible[0];
+                     e = (void *)e + i->of_size)
+			output_of_entry(e, shortname, out);
+	}
+}
diff -ruNp module-init-tools-3.2-pre6/tables.h module-init-tools-3.2-pre6.macio/tables.h
--- module-init-tools-3.2-pre6/tables.h	2005-02-07 04:34:33.000000000 +0100
+++ module-init-tools-3.2-pre6.macio/tables.h	2005-07-18 22:08:18.761247246 +0200
@@ -125,6 +125,15 @@ struct serio_device_id {
 #define SERIO_DEVICE_SIZE32 (4 * 1)
 #define SERIO_DEVICE_SIZE64 (4 * 1 + 4)
 
+struct of_device_id {
+	char name[32];
+	char type[32];
+	char compatible[128];
+};
+
+#define OF_DEVICE_SIZE32 (32 * 2 + 128 + 4)
+#define OF_DEVICE_SIZE64 (32 * 2 + 128 + 8)
+
 /* Functions provided by tables.c */
 struct module;
 void output_usb_table(struct module *modules, FILE *out);
@@ -134,5 +143,6 @@ void output_ccw_table(struct module *mod
 void output_isapnp_table(struct module *modules, FILE *out);
 void output_input_table(struct module *modules, FILE *out);
 void output_serio_table(struct module *modules, FILE *out);
+void output_of_table(struct module *modules, FILE *out);
 
 #endif /* MODINITTOOLS_TABLES_H */
