diff -Naru linux/drivers/usb/host/Config.in linux-new/drivers/usb/host/Config.in
--- linux/drivers/usb/host/Config.in	2003-11-16 20:07:42.000000000 -0500
+++ linux-new/drivers/usb/host/Config.in	2003-12-18 14:19:37.000000000 -0500
@@ -17,3 +17,4 @@
    dep_tristate '  SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
    dep_tristate '  SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL
 fi
+dep_tristate '    Non-PCI OHCI support' CONFIG_USB_NON_PCI_OHCI $CONFIG_USB_OHCI
diff -Naru linux/drivers/usb/host/usb-ohci.c linux-new/drivers/usb/host/usb-ohci.c
--- linux/drivers/usb/host/usb-ohci.c	2003-08-13 13:19:23.000000000 -0400
+++ linux-new/drivers/usb/host/usb-ohci.c	2003-12-18 14:19:53.000000000 -0500
@@ -2517,6 +2517,7 @@
 		hc_release_ohci (ohci);
 		return ret;
 	}
+#ifndef CONFIG_USB_NON_PCI_OHCI
 	ohci->flags = id->driver_data;
 	
 	/* Check for NSC87560. We have to look at the bridge (fn1) to identify
@@ -2535,6 +2536,7 @@
 		printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
 	if (ohci->flags & OHCI_QUIRK_AMD756)
 		printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
+#endif
 
 	if (hc_reset (ohci) < 0) {
 		hc_release_ohci (ohci);
@@ -2580,8 +2582,10 @@
 	int temp;
 	int i;
 
+#ifndef CONFIG_USB_NON_PCI_OHCI
 	if (ohci->pci_latency)
 		pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency);
+#endif
 
 	ohci->disabled = 1;
 	ohci->sleeping = 0;
@@ -2611,6 +2615,7 @@
 
 /*-------------------------------------------------------------------------*/
 
+#ifndef CONFIG_USB_NON_PCI_OHCI
 /* configured so that an OHCI device is always provided */
 /* always called with process context; sleeping is OK */
 
@@ -2658,6 +2663,88 @@
 	}
 	return status;
 } 
+#else  /* CONFIG_USB_NON_PCI_OHCI */
+
+// Boot options
+static int ohci_base=0, ohci_len=0;
+static int ohci_irq=-1;
+
+MODULE_PARM(ohci_base, "i");
+MODULE_PARM(ohci_len, "i");
+MODULE_PARM(ohci_irq, "i");
+MODULE_PARM_DESC(ohci_base, "IO Base address of OHCI Oper. registers");
+MODULE_PARM_DESC(ohci_len, "IO length of OHCI Oper. registers");
+MODULE_PARM_DESC(ohci_irq, "IRQ for OHCI interrupts");
+
+// bogus pci_dev
+static struct pci_dev bogus_pcidev;
+
+static struct pci_driver ohci_pci_driver = {
+	name:		"usb-ohci",
+};
+
+static int __devinit
+ohci_non_pci_init (void)
+{
+	void *mem_base;
+
+	if (!ohci_base || !ohci_len || (ohci_irq < 0)) 
+		return -ENODEV;
+
+	if (!request_mem_region (ohci_base, ohci_len, ohci_pci_driver.name)) {
+		dbg ("controller already in use");
+		return -EBUSY;
+	}
+
+	mem_base = ioremap_nocache (ohci_base, ohci_len);
+	if (!mem_base) {
+		err("Error mapping OHCI memory");
+		return -EFAULT;
+	}
+
+	/*
+	* Fill in the bogus pci_dev. Only those members actually
+	* dereferenced in this driver are initialized.
+	*/
+	memset(&bogus_pcidev, 0, sizeof(struct pci_dev));
+	strcpy(bogus_pcidev.name, "non-PCI OHCI");
+	strcpy(bogus_pcidev.slot_name, "builtin");
+	bogus_pcidev.resource[0].name = "OHCI Operational Registers";
+	bogus_pcidev.resource[0].start = ohci_base;
+	bogus_pcidev.resource[0].end = ohci_base + ohci_len;
+	bogus_pcidev.resource[0].flags = 0;
+	bogus_pcidev.irq = ohci_irq;
+
+	return hc_found_ohci (&bogus_pcidev, bogus_pcidev.irq, mem_base, NULL);
+} 
+
+#ifndef MODULE
+
+static int __init
+ohci_setup (char* options)
+{
+	char* this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	for(this_opt=strtok(options,",");this_opt;this_opt=strtok(NULL,",")) {
+		if (!strncmp(this_opt, "base:", 5)) { 
+			ohci_base = simple_strtoul(this_opt+5, NULL, 0);
+		} else if (!strncmp(this_opt, "len:", 4)) { 
+			ohci_len = simple_strtoul(this_opt+4, NULL, 0);
+		} else if (!strncmp(this_opt, "irq:", 4)) { 
+			ohci_irq = simple_strtoul(this_opt+4, NULL, 0);
+		}
+	}
+	return 0;
+}
+
+__setup("usb_ohci=", ohci_setup);
+
+#endif  /* !MODULE */
+
+#endif  /* CONFIG_USB_NON_PCI_OHCI */
 
 /*-------------------------------------------------------------------------*/
 
@@ -2698,6 +2785,7 @@
 }
 
 
+#ifndef CONFIG_USB_NON_PCI_OHCI
 #ifdef	CONFIG_PM
 
 /*-------------------------------------------------------------------------*/
@@ -2936,20 +3024,29 @@
 	resume:		ohci_pci_resume,
 #endif	/* PM */
 };
+#endif /* CONFIG_USB_NON_PCI_OHCI */
 
  
 /*-------------------------------------------------------------------------*/
 
 static int __init ohci_hcd_init (void) 
 {
+#ifndef CONFIG_USB_NON_PCI_OHCI
 	return pci_module_init (&ohci_pci_driver);
+#else
+	return ohci_non_pci_init();
+#endif
 }
 
 /*-------------------------------------------------------------------------*/
 
 static void __exit ohci_hcd_cleanup (void) 
 {	
+#ifndef CONFIG_USB_NON_PCI_OHCI
 	pci_unregister_driver (&ohci_pci_driver);
+#else
+	ohci_pci_remove(&bogus_pcidev);
+#endif
 }
 
 module_init (ohci_hcd_init);