# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.592   -> 1.592.2.1
#       drivers/usb/host/usb-ohci.h     1.13    -> 1.14   
#       drivers/usb/host/Config.in      1.11    -> 1.12   
#       drivers/usb/host/usb-ohci.c     1.34    -> 1.35   
#       drivers/usb/Config.in   1.30    -> 1.31   
#       drivers/usb/Makefile    1.31    -> 1.32   
#       drivers/usb/host/Makefile       1.10    -> 1.11   
#                      (new)            -> 1.1     drivers/usb/host/usb-ohci-sa1111.c
#                      (new)            -> 1.1     drivers/usb/host/usb-ohci-pci.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/05/29      [EMAIL PROTECTED]  1.592.2.1
# USB OHCI driver: Added SA1111 support
#   
# Added the patch from Russell King <[EMAIL PROTECTED]> that splits
# the usb-ohci driver into two pieces, enabling the sa1111 hardware to
# work with the driver.
#   
# I also added some changes to get the usb-ohci-pci.o module to build
# and run properly.
# --------------------------------------------
#
diff -Nru a/drivers/usb/Config.in b/drivers/usb/Config.in
--- a/drivers/usb/Config.in     Fri May 31 00:41:19 2002
+++ b/drivers/usb/Config.in     Fri May 31 00:41:19 2002
@@ -4,7 +4,13 @@
 mainmenu_option next_comment
 comment 'USB support'
 
-dep_tristate 'Support for USB' CONFIG_USB $CONFIG_PCI
+# ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
+if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SA1111" = "y" ]; then
+   tristate 'Support for USB' CONFIG_USB
+else
+   define_bool CONFIG_USB n
+fi
+
 if [ "$CONFIG_USB" = "y" -o  "$CONFIG_USB" = "m" ]; then
    source drivers/usb/core/Config.in
 
diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile
--- a/drivers/usb/Makefile      Fri May 31 00:41:19 2002
+++ b/drivers/usb/Makefile      Fri May 31 00:41:19 2002
@@ -6,9 +6,11 @@
 mod-subdirs    := serial
 
 obj-$(CONFIG_USB)              += core/
+
 obj-$(CONFIG_USB_EHCI_HCD)     += host/
 obj-$(CONFIG_USB_OHCI_HCD)     += host/
 obj-$(CONFIG_USB_OHCI)         += host/
+obj-$(CONFIG_USB_OHCI_SA1111)  += host/
 obj-$(CONFIG_USB_SL811HS)      += host/
 obj-$(CONFIG_USB_UHCI_ALT)     += host/
 obj-$(CONFIG_USB_UHCI_HCD_ALT) += host/
diff -Nru a/drivers/usb/host/Config.in b/drivers/usb/host/Config.in
--- a/drivers/usb/host/Config.in        Fri May 31 00:41:19 2002
+++ b/drivers/usb/host/Config.in        Fri May 31 00:41:19 2002
@@ -20,5 +20,6 @@
 #fi
 #dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI 
$CONFIG_USB
 if [ "$CONFIG_ARM" = "y" ]; then
+   dep_tristate '  SA1111 OHCI-compatible host interface support' 
+CONFIG_USB_OHCI_SA1111 $CONFIG_USB
    dep_tristate '  SL811HS support' CONFIG_USB_SL811HS $CONFIG_USB
 fi
diff -Nru a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
--- a/drivers/usb/host/Makefile Fri May 31 00:41:19 2002
+++ b/drivers/usb/host/Makefile Fri May 31 00:41:19 2002
@@ -3,6 +3,8 @@
 # framework and drivers
 #
 
+export-objs := usb-ohci.o
+
 obj-$(CONFIG_USB_EHCI_HCD)     += ehci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)     += ohci-hcd.o
 obj-$(CONFIG_USB_UHCI_HCD)     += usb-uhci-hcd.o
@@ -10,7 +12,8 @@
 
 obj-$(CONFIG_USB_UHCI)         += usb-uhci.o
 obj-$(CONFIG_USB_UHCI_ALT)     += uhci.o
-obj-$(CONFIG_USB_OHCI)         += usb-ohci.o
+obj-$(CONFIG_USB_OHCI)         += usb-ohci.o usb-ohci-pci.o
+obj-$(CONFIG_USB_OHCI_SA1111)  += usb-ohci.o usb-ohci-sa1111.o
 obj-$(CONFIG_USB_SL811HS)      += hc_sl811.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/usb/host/usb-ohci-pci.c b/drivers/usb/host/usb-ohci-pci.c
--- /dev/null   Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/host/usb-ohci-pci.c   Fri May 31 00:41:19 2002
@@ -0,0 +1,445 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>  /* for in_interrupt() */
+#undef DEBUG
+#include <linux/usb.h>
+
+#include "../core/hcd.h"
+#include "usb-ohci.h"
+
+#ifdef CONFIG_PMAC_PBOOK
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/pci-bridge.h>
+#ifndef CONFIG_PM
+#define CONFIG_PM
+#endif
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Increment the module usage count, start the control thread and
+ * return success. */
+
+static struct pci_driver ohci_pci_driver;
+
+static int __devinit
+hc_found_ohci (struct pci_dev *dev, int irq,
+       void *mem_base, const struct pci_device_id *id)
+{
+       u8 latency, limit;
+       ohci_t * ohci;
+       int ret;
+
+       printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
+
+       /* bad pci latencies can contribute to overruns */ 
+       pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
+       if (latency) {
+               pci_read_config_byte (dev, PCI_MAX_LAT, &limit);
+               if (limit && limit < latency) {
+                       dbg ("PCI latency reduced to max %d", limit);
+                       pci_write_config_byte (dev, PCI_LATENCY_TIMER, limit);
+                       latency = limit;
+               }
+       }
+
+       ret = hc_add_ohci(dev, irq, mem_base, id->driver_data,
+                          &ohci, ohci_pci_driver.name, dev->slot_name);
+
+       if (ret == 0) {
+               ohci->pci_latency = latency;
+
+               if (hc_start (ohci, &ohci->ohci_dev->dev) < 0) {
+                       err ("can't start usb-%s", ohci->slot_name);
+                       hc_remove_ohci(ohci);
+                       return -EBUSY;
+               }
+
+#ifdef DEBUG
+               ohci_dump (ohci, 1);
+#endif
+       }
+
+       return ret;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_PM
+
+/* controller died; cleanup debris, then restart */
+/* must not be called from interrupt context */
+
+static void hc_restart (ohci_t *ohci)
+{
+       int temp;
+       int i;
+
+       if (ohci->pci_latency)
+               pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, 
+ohci->pci_latency);
+
+       ohci->disabled = 1;
+       ohci->sleeping = 0;
+       if (ohci->bus->root_hub)
+               usb_disconnect (&ohci->bus->root_hub);
+       
+       /* empty the interrupt branches */
+       for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
+       for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
+       
+       /* no EDs to remove */
+       ohci->ed_rm_list [0] = NULL;
+       ohci->ed_rm_list [1] = NULL;
+
+       /* empty control and bulk lists */       
+       ohci->ed_isotail     = NULL;
+       ohci->ed_controltail = NULL;
+       ohci->ed_bulktail    = NULL;
+
+       if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
+               err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
+       } else
+               dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
+}
+
+#endif /* CONFIG_PM */
+
+/*-------------------------------------------------------------------------*/
+
+/* configured so that an OHCI device is always provided */
+/* always called with process context; sleeping is OK */
+
+static int __devinit
+ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
+{
+       unsigned long mem_resource, mem_len;
+       void *mem_base;
+       int status;
+
+       if (pci_enable_device(dev) < 0)
+               return -ENODEV;
+
+        if (!dev->irq) {
+               err("found OHCI device with no IRQ assigned. check BIOS settings!");
+               pci_disable_device (dev);
+               return -ENODEV;
+        }
+       
+       /* we read its hardware registers as memory */
+       mem_resource = pci_resource_start(dev, 0);
+       mem_len = pci_resource_len(dev, 0);
+       if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
+               dbg ("controller already in use");
+               pci_disable_device (dev);
+               return -EBUSY;
+       }
+
+       mem_base = ioremap_nocache (mem_resource, mem_len);
+       if (!mem_base) {
+               err("Error mapping OHCI memory");
+               release_mem_region(mem_resource, mem_len);
+               pci_disable_device (dev);
+               return -EFAULT;
+       }
+
+       /* controller writes into our memory */
+       pci_set_master (dev);
+
+       status = hc_found_ohci (dev, dev->irq, mem_base, id);
+       if (status < 0) {
+               iounmap (mem_base);
+               release_mem_region(mem_resource, mem_len);
+               pci_disable_device (dev);
+       }
+       return status;
+} 
+
+/*-------------------------------------------------------------------------*/
+
+/* may be called from interrupt context [interface spec] */
+/* may be called without controller present */
+/* may be called with controller, bus, and devices active */
+
+static void __devexit
+ohci_pci_remove (struct pci_dev *dev)
+{
+       ohci_t          *ohci = (ohci_t *) pci_get_drvdata(dev);
+
+       dbg ("remove %s controller usb-%s%s%s",
+               hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
+               dev->slot_name,
+               ohci->disabled ? " (disabled)" : "",
+               in_interrupt () ? " in interrupt" : ""
+               );
+
+       hc_remove_ohci(ohci);
+
+       release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
+}
+
+
+#ifdef CONFIG_PM
+
+/*-------------------------------------------------------------------------*/
+
+static int
+ohci_pci_suspend (struct pci_dev *dev, u32 state)
+{
+       ohci_t                  *ohci = (ohci_t *) pci_get_drvdata(dev);
+       unsigned long           flags;
+       u16 cmd;
+
+       if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
+               dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
+                       hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
+               return -EIO;
+       }
+
+       /* act as if usb suspend can always be used */
+       info ("USB suspend: usb-%s", dev->slot_name);
+       ohci->sleeping = 1;
+
+       /* First stop processing */
+       spin_lock_irqsave (&usb_ed_lock, flags);
+       ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
+       writel (ohci->hc_control, &ohci->regs->control);
+       writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
+       (void) readl (&ohci->regs->intrstatus);
+       spin_unlock_irqrestore (&usb_ed_lock, flags);
+
+       /* Wait a frame or two */
+       mdelay(1);
+       if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
+               mdelay (1);
+               
+#ifdef CONFIG_PMAC_PBOOK
+       if (_machine == _MACH_Pmac)
+               disable_irq (ohci->irq);
+       /* else, 2.4 assumes shared irqs -- don't disable */
+#endif
+       /* Enable remote wakeup */
+       writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, 
+&ohci->regs->intrenable);
+
+       /* Suspend chip and let things settle down a bit */
+       ohci->hc_control = OHCI_USB_SUSPEND;
+       writel (ohci->hc_control, &ohci->regs->control);
+       (void) readl (&ohci->regs->control);
+       mdelay (500); /* No schedule here ! */
+       switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
+               case OHCI_USB_RESET:
+                       dbg("Bus in reset phase ???");
+                       break;
+               case OHCI_USB_RESUME:
+                       dbg("Bus in resume phase ???");
+                       break;
+               case OHCI_USB_OPER:
+                       dbg("Bus in operational phase ???");
+                       break;
+               case OHCI_USB_SUSPEND:
+                       dbg("Bus suspended");
+                       break;
+       }
+       /* In some rare situations, Apple's OHCI have happily trashed
+        * memory during sleep. We disable it's bus master bit during
+        * suspend
+        */
+       pci_read_config_word (dev, PCI_COMMAND, &cmd);
+       cmd &= ~PCI_COMMAND_MASTER;
+       pci_write_config_word (dev, PCI_COMMAND, cmd);
+#ifdef CONFIG_PMAC_PBOOK
+       {
+               struct device_node      *of_node;
+
+               /* Disable USB PAD & cell clock */
+               of_node = pci_device_to_OF_node (ohci->ohci_dev);
+               if (of_node && _machine == _MACH_Pmac)
+                       pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
+       }
+#endif
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int
+ohci_pci_resume (struct pci_dev *dev)
+{
+       ohci_t          *ohci = (ohci_t *) pci_get_drvdata(dev);
+       int             temp;
+       unsigned long   flags;
+
+       /* guard against multiple resumes */
+       atomic_inc (&ohci->resume_count);
+       if (atomic_read (&ohci->resume_count) != 1) {
+               err ("concurrent PCI resumes for usb-%s", dev->slot_name);
+               atomic_dec (&ohci->resume_count);
+               return 0;
+       }
+
+#ifdef CONFIG_PMAC_PBOOK
+       {
+               struct device_node *of_node;
+
+               /* Re-enable USB PAD & cell clock */
+               of_node = pci_device_to_OF_node (ohci->ohci_dev);
+               if (of_node && _machine == _MACH_Pmac)
+                       pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
+       }
+#endif
+
+       /* did we suspend, or were we powered off? */
+       ohci->hc_control = readl (&ohci->regs->control);
+       temp = ohci->hc_control & OHCI_CTRL_HCFS;
+
+#ifdef DEBUG
+       /* the registers may look crazy here */
+       ohci_dump_status (ohci);
+#endif
+
+       /* Re-enable bus mastering */
+       pci_set_master(ohci->ohci_dev);
+       
+       switch (temp) {
+
+       case OHCI_USB_RESET:    // lost power
+               info ("USB restart: usb-%s", dev->slot_name);
+               hc_restart (ohci);
+               break;
+
+       case OHCI_USB_SUSPEND:  // host wakeup
+       case OHCI_USB_RESUME:   // remote wakeup
+               info ("USB continue: usb-%s from %s wakeup", dev->slot_name,
+                       (temp == OHCI_USB_SUSPEND)
+                               ? "host" : "remote");
+               ohci->hc_control = OHCI_USB_RESUME;
+               writel (ohci->hc_control, &ohci->regs->control);
+               (void) readl (&ohci->regs->control);
+               mdelay (20); /* no schedule here ! */
+               /* Some controllers (lucent) need a longer delay here */
+               mdelay (15);
+               temp = readl (&ohci->regs->control);
+               temp = ohci->hc_control & OHCI_CTRL_HCFS;
+               if (temp != OHCI_USB_RESUME) {
+                       err ("controller usb-%s won't resume", dev->slot_name);
+                       ohci->disabled = 1;
+                       return -EIO;
+               }
+
+               /* Some chips likes being resumed first */
+               writel (OHCI_USB_OPER, &ohci->regs->control);
+               (void) readl (&ohci->regs->control);
+               mdelay (3);
+
+               /* Then re-enable operations */
+               spin_lock_irqsave (&usb_ed_lock, flags);
+               ohci->disabled = 0;
+               ohci->sleeping = 0;
+               ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+               if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) {
+                       if (ohci->ed_controltail)
+                               ohci->hc_control |= OHCI_CTRL_CLE;
+                       if (ohci->ed_bulktail)
+                               ohci->hc_control |= OHCI_CTRL_BLE;
+               }
+               writel (ohci->hc_control, &ohci->regs->control);
+               writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
+               writel (OHCI_INTR_SF, &ohci->regs->intrenable);
+               /* Check for a pending done list */
+               writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);       
+               (void) readl (&ohci->regs->intrdisable);
+               spin_unlock_irqrestore (&usb_ed_lock, flags);
+#ifdef CONFIG_PMAC_PBOOK
+               if (_machine == _MACH_Pmac)
+                       enable_irq (ohci->irq);
+#endif
+               if (ohci->hcca->done_head)
+                       dl_done_list (ohci, dl_reverse_done_list (ohci));
+               writel (OHCI_INTR_WDH, &ohci->regs->intrenable); 
+               writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
+               writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
+               break;
+
+       default:
+               warn ("odd PCI resume for usb-%s", dev->slot_name);
+       }
+
+       /* controller is operational, extra resumes are harmless */
+       atomic_dec (&ohci->resume_count);
+
+       return 0;
+}
+
+#endif /* CONFIG_PM */
+
+
+/*-------------------------------------------------------------------------*/
+
+static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
+
+       /*
+        * AMD-756 [Viper] USB has a serious erratum when used with
+        * lowspeed devices like mice.
+        */
+       vendor:         0x1022,
+       device:         0x740c,
+       subvendor:      PCI_ANY_ID,
+       subdevice:      PCI_ANY_ID,
+
+       driver_data:    OHCI_QUIRK_AMD756,
+
+} , {
+
+       /* handle any USB OHCI controller */
+       class:          ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
+       class_mask:     ~0,
+
+       /* no matter who makes it */
+       vendor:         PCI_ANY_ID,
+       device:         PCI_ANY_ID,
+       subvendor:      PCI_ANY_ID,
+       subdevice:      PCI_ANY_ID,
+
+       }, { /* end: all zeroes */ }
+};
+
+MODULE_DEVICE_TABLE (pci, ohci_pci_ids);
+
+static struct pci_driver ohci_pci_driver = {
+       name:           "usb-ohci",
+       id_table:       &ohci_pci_ids [0],
+
+       probe:          ohci_pci_probe,
+       remove:         __devexit_p(ohci_pci_remove),
+
+#ifdef CONFIG_PM
+       suspend:        ohci_pci_suspend,
+       resume:         ohci_pci_resume,
+#endif /* PM */
+};
+
+ 
+/*-------------------------------------------------------------------------*/
+
+static int __init ohci_hcd_init (void) 
+{
+       return pci_module_init (&ohci_pci_driver);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void __exit ohci_hcd_cleanup (void) 
+{      
+       pci_unregister_driver (&ohci_pci_driver);
+}
+
+module_init (ohci_hcd_init);
+module_exit (ohci_hcd_cleanup);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/usb/host/usb-ohci-sa1111.c b/drivers/usb/host/usb-ohci-sa1111.c
--- /dev/null   Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/host/usb-ohci-sa1111.c        Fri May 31 00:41:19 2002
@@ -0,0 +1,130 @@
+/*
+ *  linux/drivers/usb/usb-ohci-sa1111.c
+ *
+ *  The outline of this code was taken from Brad Parkers <[EMAIL PROTECTED]>
+ *  original OHCI driver modifications, and reworked into a cleaner form
+ *  by Russell King <[EMAIL PROTECTED]>.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/errno.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/arch/assabet.h>
+#include <asm/arch/badge4.h>
+#include <asm/hardware/sa1111.h>
+
+#include "usb-ohci.h"
+
+int __devinit
+hc_add_ohci(struct pci_dev *dev, int irq, void *membase, unsigned long flags,
+           ohci_t **ohci, const char *name, const char *slot_name);
+extern void hc_remove_ohci(ohci_t *ohci);
+
+static ohci_t *sa1111_ohci;
+
+static void __init sa1111_ohci_configure(void)
+{
+       unsigned int usb_rst = 0;
+
+       if (machine_is_xp860() ||
+           machine_has_neponset() ||
+           machine_is_pfs168() ||
+           machine_is_badge4())
+               usb_rst = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW;
+
+       /*
+        * Configure the power sense and control lines.  Place the USB
+        * host controller in reset.
+        */
+       USB_RESET = usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
+
+       /*
+        * Now, carefully enable the USB clock, and take
+        * the USB host controller out of reset.
+        */
+       SKPCR |= SKPCR_UCLKEN;
+       udelay(11);
+       USB_RESET = usb_rst;
+}
+
+static int __init sa1111_ohci_init(void)
+{
+       int ret;
+
+       if (!sa1111)
+               return -ENODEV;
+
+       /*
+        * Request memory resources.
+        */
+//     if (!request_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT, "usb-ohci"))
+//             return -EBUSY;
+
+       sa1111_ohci_configure();
+
+       /*
+        * Initialise the generic OHCI driver.
+        */
+       ret = hc_add_ohci((struct pci_dev *)1, NIRQHCIM,
+                         (void *)&USB_OHCI_OP_BASE, 0, &sa1111_ohci,
+                         "usb-ohci", "sa1111");
+
+       if (ret == 0) {
+               if (hc_start (sa1111_ohci, &sa1111->dev) < 0) {
+                       err ("can't start usb-%s", sa1111_ohci->slot_name);
+                       hc_remove_ohci (sa1111_ohci);
+                       return -EBUSY;
+               }
+
+#ifdef DEBUG
+               ohci_dump (ohci, 1);
+#endif
+#ifdef CONFIG_SA1100_BADGE4
+               if (machine_is_badge4()) {
+                       /* found the controller, so now power the bus */
+                       badge4_set_5V(BADGE4_5V_USB, 1);
+               }
+#endif
+       }
+//     else
+//             release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+
+       return ret;
+}
+
+static void __exit sa1111_ohci_exit(void)
+{
+       hc_remove_ohci(sa1111_ohci);
+
+       /*
+        * Put the USB host controller into reset.
+        */
+       USB_RESET |= USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
+
+       /*
+        * Stop the USB clock.
+        */
+       SKPCR &= ~SKPCR_UCLKEN;
+
+       /*
+        * Release memory resources.
+        */
+//     release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+
+#ifdef CONFIG_SA1100_BADGE4
+       if (machine_is_badge4()) {
+               badge4_set_5V(BADGE4_5V_USB, 0);
+       }
+#endif
+}
+
+module_init(sa1111_ohci_init);
+module_exit(sa1111_ohci_exit);
diff -Nru a/drivers/usb/host/usb-ohci.c b/drivers/usb/host/usb-ohci.c
--- a/drivers/usb/host/usb-ohci.c       Fri May 31 00:41:19 2002
+++ b/drivers/usb/host/usb-ohci.c       Fri May 31 00:41:19 2002
@@ -82,16 +82,6 @@
 #include "usb-ohci.h"
 
 
-#ifdef CONFIG_PMAC_PBOOK
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/pci-bridge.h>
-#ifndef CONFIG_PM
-#define CONFIG_PM
-#endif
-#endif
-
-
 /*
  * Version Information
  */
@@ -99,14 +89,10 @@
 #define DRIVER_AUTHOR "Roman Weissgaerber <[EMAIL PROTECTED]>, David Brownell"
 #define DRIVER_DESC "USB OHCI Host Controller Driver"
 
-/* For initializing controller (mask in an HCFS mode too) */
-#define        OHCI_CONTROL_INIT \
-       (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
-
 #define OHCI_UNLINK_TIMEOUT    (HZ / 10)
 
 static LIST_HEAD (ohci_hcd_list);
-static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
 
 
 /*-------------------------------------------------------------------------*/
@@ -443,7 +429,7 @@
 
 static void ohci_dump (ohci_t *controller, int verbose)
 {
-       dbg ("OHCI controller usb-%s state", controller->ohci_dev->slot_name);
+       dbg ("OHCI controller usb-%s state", controller->slot_name);
 
        // dumps some of the state we know about
        ohci_dump_status (controller);
@@ -465,7 +451,7 @@
 static int sohci_return_urb (struct ohci *hc, struct urb * urb)
 {
        urb_priv_t * urb_priv = urb->hcpriv;
-       struct urb * urbt;
+       struct urb * urbt = NULL;
        unsigned long flags;
        int i;
        
@@ -499,7 +485,7 @@
                        break;
                        
                case PIPE_ISOCHRONOUS:
-                       for (urbt = urb->next; urbt && (urbt != urb); urbt = 
urbt->next);
+                       // for (urbt = urb->next; urbt && (urbt != urb); urbt = 
+urbt->next);
                        if (urbt) { /* send the reply and requeue URB */        
                                pci_unmap_single (hc->ohci_dev,
                                        urb_priv->td [0]->data_dma,
@@ -865,7 +851,7 @@
                                if (ed->state == ED_OPER) {
                                        /* driver on that interface didn't unlink an 
urb */
                                        dbg ("driver usb-%s dev %d ed 0x%x unfreed 
URB",
-                                               ohci->ohci_dev->slot_name, 
usb_dev->devnum, i);
+                                               ohci->slot_name, usb_dev->devnum, i);
                                        ep_unlink (ohci, ed);
                                }
                                ep_rm_ed (usb_dev, ed);
@@ -910,7 +896,7 @@
                        } else {
                                /* likely some interface's driver has a refcount bug */
                                err ("bus %s devnum %d deletion in interrupt",
-                                       ohci->ohci_dev->slot_name, usb_dev->devnum);
+                                       ohci->slot_name, usb_dev->devnum);
                                BUG ();
                        }
                }
@@ -1529,7 +1515,7 @@
 /* replies to the request have to be on a FIFO basis so
  * we reverse the reversed done-list */
  
-static td_t * dl_reverse_done_list (ohci_t * ohci)
+td_t * dl_reverse_done_list (ohci_t * ohci)
 {
        __u32 td_list_hc;
        td_t * td_rev = NULL;
@@ -1677,7 +1663,7 @@
 
 /* td done list */
 
-static void dl_done_list (ohci_t * ohci, td_t * td_list)
+void dl_done_list (ohci_t * ohci, td_t * td_list)
 {
        td_t * td_list_next = NULL;
        ed_t * ed;
@@ -1822,7 +1808,7 @@
        num_ports = roothub_a (ohci) & RH_A_NDP; 
        if (num_ports > MAX_ROOT_PORTS) {
                err ("bogus NDP=%d for OHCI usb-%s", num_ports,
-                       ohci->ohci_dev->slot_name);
+                       ohci->slot_name);
                err ("rereads as NDP=%d",
                        readl (&ohci->regs->roothub.a) & RH_A_NDP);
                /* retry later; "should not happen" */
@@ -2148,7 +2134,7 @@
 
 /* reset the HC and BUS */
 
-static int hc_reset (ohci_t * ohci)
+int hc_reset (ohci_t * ohci)
 {
        int timeout = 30;
        int smm_timeout = 50; /* 0,5 sec */
@@ -2169,7 +2155,7 @@
        writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
 
        dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;",
-               ohci->ohci_dev->slot_name,
+               ohci->slot_name,
                readl (&ohci->regs->control));
 
        /* Reset USB (needed by some controllers) */
@@ -2193,7 +2179,7 @@
  * enable interrupts 
  * connect the virtual root hub */
 
-static int hc_start (ohci_t * ohci)
+int hc_start (ohci_t * ohci, struct device *parent_dev)
 {
        __u32 mask;
        unsigned int fminterval;
@@ -2247,7 +2233,7 @@
        dev = usb_to_ohci (usb_dev);
        ohci->bus->root_hub = usb_dev;
        usb_connect (usb_dev);
-       if (usb_register_root_hub (usb_dev, &ohci->ohci_dev->dev) != 0) {
+       if (usb_register_root_hub (usb_dev, parent_dev) != 0) {
                usb_free_dev (usb_dev); 
                ohci->disabled = 1;
                return -ENODEV;
@@ -2308,7 +2294,7 @@
        if (ints & OHCI_INTR_UE) {
                ohci->disabled++;
                err ("OHCI Unrecoverable Error, controller usb-%s disabled",
-                       ohci->ohci_dev->slot_name);
+                       ohci->slot_name);
                // e.g. due to PCI Master/Target Abort
 
 #ifdef DEBUG
@@ -2385,7 +2371,9 @@
        ohci->regs = mem_base;   
 
        ohci->ohci_dev = dev;
+#ifdef CONFIG_PCI
        pci_set_drvdata(dev, ohci);
+#endif
  
        INIT_LIST_HEAD (&ohci->ohci_hcd_list);
        list_add (&ohci->ohci_hcd_list, &ohci_hcd_list);
@@ -2394,7 +2382,9 @@
 
        ohci->bus = usb_alloc_bus (&sohci_device_operations);
        if (!ohci->bus) {
+#ifdef CONFIG_PCI
                pci_set_drvdata (dev, NULL);
+#endif
                pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
                                ohci->hcca, ohci->hcca_dma);
                kfree (ohci);
@@ -2413,7 +2403,7 @@
 
 static void hc_release_ohci (ohci_t * ohci)
 {      
-       dbg ("USB HC release ohci usb-%s", ohci->ohci_dev->slot_name);
+       dbg ("USB HC release ohci usb-%s", ohci->slot_name);
 
        /* disconnect all devices */    
        if (ohci->bus->root_hub)
@@ -2426,7 +2416,9 @@
                free_irq (ohci->irq, ohci);
                ohci->irq = -1;
        }
+#ifdef CONFIG_PCI
        pci_set_drvdata(ohci->ohci_dev, NULL);
+#endif
        if (ohci->bus) {
                if (ohci->bus->busnum)
                        usb_deregister_bus (ohci->bus);
@@ -2448,18 +2440,15 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* Increment the module usage count, start the control thread and
- * return success. */
-
-static struct pci_driver ohci_pci_driver;
- 
-static int __devinit
-hc_found_ohci (struct pci_dev *dev, int irq,
-       void *mem_base, const struct pci_device_id *id)
+/*
+ * Host bus independent add one OHCI host controller.
+ */
+int
+hc_add_ohci(struct pci_dev *dev, int irq, void *mem_base, unsigned long flags,
+           ohci_t **ohcip, const char *name, const char *slot_name)
 {
-       ohci_t * ohci;
-       u8 latency, limit;
        char buf[8], *bufp = buf;
+       ohci_t * ohci;
        int ret;
 
 #ifndef __sparc__
@@ -2469,34 +2458,20 @@
 #endif
        printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
                (unsigned long) mem_base, bufp);
-       printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
     
        ohci = hc_alloc_ohci (dev, mem_base);
        if (!ohci) {
                return -ENOMEM;
        }
+       ohci->slot_name = slot_name;
        if ((ret = ohci_mem_init (ohci)) < 0) {
                hc_release_ohci (ohci);
                return ret;
        }
-       ohci->flags = id->driver_data;
+       ohci->flags = flags;
        if (ohci->flags & OHCI_QUIRK_AMD756)
                printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
 
-       /* bad pci latencies can contribute to overruns */ 
-       pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
-       if (latency) {
-               pci_read_config_byte (dev, PCI_MAX_LAT, &limit);
-               if (limit && limit < latency) {
-                       dbg ("PCI latency reduced to max %d", limit);
-                       pci_write_config_byte (dev, PCI_LATENCY_TIMER, limit);
-                       ohci->pci_latency = limit;
-               } else {
-                       /* it might already have been reduced */
-                       ohci->pci_latency = latency;
-               }
-       }
-
        if (hc_reset (ohci) < 0) {
                hc_release_ohci (ohci);
                return -ENODEV;
@@ -2508,134 +2483,23 @@
 
        usb_register_bus (ohci->bus);
        
-       if (request_irq (irq, hc_interrupt, SA_SHIRQ,
-                       ohci_pci_driver.name, ohci) != 0) {
+       if (request_irq (irq, hc_interrupt, SA_SHIRQ, name, ohci) != 0) {
                err ("request interrupt %s failed", bufp);
                hc_release_ohci (ohci);
                return -EBUSY;
        }
        ohci->irq = irq;     
 
-       if (hc_start (ohci) < 0) {
-               err ("can't start usb-%s", dev->slot_name);
-               hc_release_ohci (ohci);
-               return -EBUSY;
-       }
+       *ohcip = ohci;
 
-#ifdef DEBUG
-       ohci_dump (ohci, 1);
-#endif
        return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_PM
-
-/* controller died; cleanup debris, then restart */
-/* must not be called from interrupt context */
-
-static void hc_restart (ohci_t *ohci)
-{
-       int temp;
-       int i;
-
-       if (ohci->pci_latency)
-               pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, 
ohci->pci_latency);
-
-       ohci->disabled = 1;
-       ohci->sleeping = 0;
-       if (ohci->bus->root_hub)
-               usb_disconnect (&ohci->bus->root_hub);
-       
-       /* empty the interrupt branches */
-       for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
-       for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
-       
-       /* no EDs to remove */
-       ohci->ed_rm_list [0] = NULL;
-       ohci->ed_rm_list [1] = NULL;
-
-       /* empty control and bulk lists */       
-       ohci->ed_isotail     = NULL;
-       ohci->ed_controltail = NULL;
-       ohci->ed_bulktail    = NULL;
-
-       if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
-               err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
-       } else
-               dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
-}
-
-#endif /* CONFIG_PM */
-
-/*-------------------------------------------------------------------------*/
-
-/* configured so that an OHCI device is always provided */
-/* always called with process context; sleeping is OK */
-
-static int __devinit
-ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
+/*
+ * Host bus independent remove one OHCI host controller.
+ */
+void hc_remove_ohci(ohci_t *ohci)
 {
-       unsigned long mem_resource, mem_len;
-       void *mem_base;
-       int status;
-
-       if (pci_enable_device(dev) < 0)
-               return -ENODEV;
-
-        if (!dev->irq) {
-               err("found OHCI device with no IRQ assigned. check BIOS settings!");
-               pci_disable_device (dev);
-               return -ENODEV;
-        }
-       
-       /* we read its hardware registers as memory */
-       mem_resource = pci_resource_start(dev, 0);
-       mem_len = pci_resource_len(dev, 0);
-       if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
-               dbg ("controller already in use");
-               pci_disable_device (dev);
-               return -EBUSY;
-       }
-
-       mem_base = ioremap_nocache (mem_resource, mem_len);
-       if (!mem_base) {
-               err("Error mapping OHCI memory");
-               release_mem_region (mem_resource, mem_len);
-               pci_disable_device (dev);
-               return -EFAULT;
-       }
-
-       /* controller writes into our memory */
-       pci_set_master (dev);
-
-       status = hc_found_ohci (dev, dev->irq, mem_base, id);
-       if (status < 0) {
-               iounmap (mem_base);
-               release_mem_region (mem_resource, mem_len);
-               pci_disable_device (dev);
-       }
-       return status;
-} 
-
-/*-------------------------------------------------------------------------*/
-
-/* may be called from interrupt context [interface spec] */
-/* may be called without controller present */
-/* may be called with controller, bus, and devices active */
-
-static void __devexit
-ohci_pci_remove (struct pci_dev *dev)
-{
-       ohci_t          *ohci = pci_get_drvdata(dev);
-
-       dbg ("remove %s controller usb-%s%s%s",
-               hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
-               dev->slot_name,
-               ohci->disabled ? " (disabled)" : "",
-               in_interrupt () ? " in interrupt" : ""
-               );
 #ifdef DEBUG
        ohci_dump (ohci, 1);
 #endif
@@ -2652,270 +2516,16 @@
                        &ohci->regs->control);
 
        hc_release_ohci (ohci);
-
-       release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
-       pci_disable_device (dev);
-}
-
-
-#ifdef CONFIG_PM
-
-/*-------------------------------------------------------------------------*/
-
-static int
-ohci_pci_suspend (struct pci_dev *dev, u32 state)
-{
-       ohci_t                  *ohci = pci_get_drvdata(dev);
-       unsigned long           flags;
-       u16 cmd;
-
-       if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
-               dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
-                       hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
-               return -EIO;
-       }
-
-       /* act as if usb suspend can always be used */
-       info ("USB suspend: usb-%s", dev->slot_name);
-       ohci->sleeping = 1;
-
-       /* First stop processing */
-       spin_lock_irqsave (&usb_ed_lock, flags);
-       ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
-       writel (ohci->hc_control, &ohci->regs->control);
-       writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-       (void) readl (&ohci->regs->intrstatus);
-       spin_unlock_irqrestore (&usb_ed_lock, flags);
-
-       /* Wait a frame or two */
-       mdelay(1);
-       if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
-               mdelay (1);
-               
-#ifdef CONFIG_PMAC_PBOOK
-       if (_machine == _MACH_Pmac)
-               disable_irq (ohci->irq);
-       /* else, 2.4 assumes shared irqs -- don't disable */
-#endif
-       /* Enable remote wakeup */
-       writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, 
&ohci->regs->intrenable);
-
-       /* Suspend chip and let things settle down a bit */
-       ohci->hc_control = OHCI_USB_SUSPEND;
-       writel (ohci->hc_control, &ohci->regs->control);
-       (void) readl (&ohci->regs->control);
-       mdelay (500); /* No schedule here ! */
-       switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
-               case OHCI_USB_RESET:
-                       dbg("Bus in reset phase ???");
-                       break;
-               case OHCI_USB_RESUME:
-                       dbg("Bus in resume phase ???");
-                       break;
-               case OHCI_USB_OPER:
-                       dbg("Bus in operational phase ???");
-                       break;
-               case OHCI_USB_SUSPEND:
-                       dbg("Bus suspended");
-                       break;
-       }
-       /* In some rare situations, Apple's OHCI have happily trashed
-        * memory during sleep. We disable it's bus master bit during
-        * suspend
-        */
-       pci_read_config_word (dev, PCI_COMMAND, &cmd);
-       cmd &= ~PCI_COMMAND_MASTER;
-       pci_write_config_word (dev, PCI_COMMAND, cmd);
-#ifdef CONFIG_PMAC_PBOOK
-       {
-               struct device_node      *of_node;
-
-               /* Disable USB PAD & cell clock */
-               of_node = pci_device_to_OF_node (ohci->ohci_dev);
-               if (of_node)
-                       pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
-       }
-#endif
-       return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int
-ohci_pci_resume (struct pci_dev *dev)
-{
-       ohci_t          *ohci = pci_get_drvdata(dev);
-       int             temp;
-       unsigned long   flags;
-
-       /* guard against multiple resumes */
-       atomic_inc (&ohci->resume_count);
-       if (atomic_read (&ohci->resume_count) != 1) {
-               err ("concurrent PCI resumes for usb-%s", dev->slot_name);
-               atomic_dec (&ohci->resume_count);
-               return 0;
-       }
-
-#ifdef CONFIG_PMAC_PBOOK
-       {
-               struct device_node *of_node;
-
-               /* Re-enable USB PAD & cell clock */
-               of_node = pci_device_to_OF_node (ohci->ohci_dev);
-               if (of_node)
-                       pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
-       }
-#endif
-
-       /* did we suspend, or were we powered off? */
-       ohci->hc_control = readl (&ohci->regs->control);
-       temp = ohci->hc_control & OHCI_CTRL_HCFS;
-
-#ifdef DEBUG
-       /* the registers may look crazy here */
-       ohci_dump_status (ohci);
-#endif
-
-       /* Re-enable bus mastering */
-       pci_set_master(ohci->ohci_dev);
-       
-       switch (temp) {
-
-       case OHCI_USB_RESET:    // lost power
-               info ("USB restart: usb-%s", dev->slot_name);
-               hc_restart (ohci);
-               break;
-
-       case OHCI_USB_SUSPEND:  // host wakeup
-       case OHCI_USB_RESUME:   // remote wakeup
-               info ("USB continue: usb-%s from %s wakeup", dev->slot_name,
-                       (temp == OHCI_USB_SUSPEND)
-                               ? "host" : "remote");
-               ohci->hc_control = OHCI_USB_RESUME;
-               writel (ohci->hc_control, &ohci->regs->control);
-               (void) readl (&ohci->regs->control);
-               mdelay (20); /* no schedule here ! */
-               /* Some controllers (lucent) need a longer delay here */
-               mdelay (15);
-               temp = readl (&ohci->regs->control);
-               temp = ohci->hc_control & OHCI_CTRL_HCFS;
-               if (temp != OHCI_USB_RESUME) {
-                       err ("controller usb-%s won't resume", dev->slot_name);
-                       ohci->disabled = 1;
-                       return -EIO;
-               }
-
-               /* Some chips likes being resumed first */
-               writel (OHCI_USB_OPER, &ohci->regs->control);
-               (void) readl (&ohci->regs->control);
-               mdelay (3);
-
-               /* Then re-enable operations */
-               spin_lock_irqsave (&usb_ed_lock, flags);
-               ohci->disabled = 0;
-               ohci->sleeping = 0;
-               ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-               if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) {
-                       if (ohci->ed_controltail)
-                               ohci->hc_control |= OHCI_CTRL_CLE;
-                       if (ohci->ed_bulktail)
-                               ohci->hc_control |= OHCI_CTRL_BLE;
-               }
-               writel (ohci->hc_control, &ohci->regs->control);
-               writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-               writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-               /* Check for a pending done list */
-               writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);       
-               (void) readl (&ohci->regs->intrdisable);
-               spin_unlock_irqrestore (&usb_ed_lock, flags);
-#ifdef CONFIG_PMAC_PBOOK
-               if (_machine == _MACH_Pmac)
-                       enable_irq (ohci->irq);
-#endif
-               if (ohci->hcca->done_head)
-                       dl_done_list (ohci, dl_reverse_done_list (ohci));
-               writel (OHCI_INTR_WDH, &ohci->regs->intrenable); 
-               writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
-               writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
-               break;
-
-       default:
-               warn ("odd PCI resume for usb-%s", dev->slot_name);
-       }
-
-       /* controller is operational, extra resumes are harmless */
-       atomic_dec (&ohci->resume_count);
-
-       return 0;
-}
-
-#endif /* CONFIG_PM */
-
-
-/*-------------------------------------------------------------------------*/
-
-static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
-
-       /*
-        * AMD-756 [Viper] USB has a serious erratum when used with
-        * lowspeed devices like mice.
-        */
-       vendor:         0x1022,
-       device:         0x740c,
-       subvendor:      PCI_ANY_ID,
-       subdevice:      PCI_ANY_ID,
-
-       driver_data:    OHCI_QUIRK_AMD756,
-
-} , {
-
-       /* handle any USB OHCI controller */
-       class:          ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
-       class_mask:     ~0,
-
-       /* no matter who makes it */
-       vendor:         PCI_ANY_ID,
-       device:         PCI_ANY_ID,
-       subvendor:      PCI_ANY_ID,
-       subdevice:      PCI_ANY_ID,
-
-       }, { /* end: all zeroes */ }
-};
-
-MODULE_DEVICE_TABLE (pci, ohci_pci_ids);
-
-static struct pci_driver ohci_pci_driver = {
-       name:           "usb-ohci",
-       id_table:       &ohci_pci_ids [0],
-
-       probe:          ohci_pci_probe,
-       remove:         __devexit_p(ohci_pci_remove),
-
-#ifdef CONFIG_PM
-       suspend:        ohci_pci_suspend,
-       resume:         ohci_pci_resume,
-#endif /* PM */
-};
-
- 
-/*-------------------------------------------------------------------------*/
-
-static int __init ohci_hcd_init (void) 
-{
-       return pci_module_init (&ohci_pci_driver);
 }
 
-/*-------------------------------------------------------------------------*/
-
-static void __exit ohci_hcd_cleanup (void) 
-{      
-       pci_unregister_driver (&ohci_pci_driver);
-}
-
-module_init (ohci_hcd_init);
-module_exit (ohci_hcd_cleanup);
-
-
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
 MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(hc_add_ohci);
+EXPORT_SYMBOL(hc_remove_ohci);
+EXPORT_SYMBOL(hc_start);
+EXPORT_SYMBOL(hc_reset);
+EXPORT_SYMBOL(dl_done_list);
+EXPORT_SYMBOL(dl_reverse_done_list);
+EXPORT_SYMBOL(usb_ed_lock);
diff -Nru a/drivers/usb/host/usb-ohci.h b/drivers/usb/host/usb-ohci.h
--- a/drivers/usb/host/usb-ohci.h       Fri May 31 00:41:19 2002
+++ b/drivers/usb/host/usb-ohci.h       Fri May 31 00:41:19 2002
@@ -403,6 +403,7 @@
 
        /* PCI device handle, settings, ... */
        struct pci_dev  *ohci_dev;
+       const char      *slot_name;
        u8              pci_latency;
        struct pci_pool *td_cache;
        struct pci_pool *dev_cache;
@@ -423,6 +424,10 @@
 // #define ohci_to_usb(ohci)   ((ohci)->usb)
 #define usb_to_ohci(usb)       ((struct ohci_device *)(usb)->hcpriv)
 
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+       (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
 /* hcd */
 /* endpoint */
 static int ep_link(ohci_t * ohci, ed_t * ed);
@@ -447,11 +452,6 @@
 #      define OHCI_MEM_FLAGS   0
 #endif
  
-#ifndef CONFIG_PCI
-#      error "usb-ohci currently requires PCI-based controllers"
-       /* to support non-PCI OHCIs, you need custom bus/mem/... glue */
-#endif
-
 
 /* Recover a TD/ED using its collision chain */
 static void *
@@ -640,4 +640,9 @@
 {
        pci_pool_free (hc->dev_cache, dev, dev->dma);
 }
+
+extern spinlock_t usb_ed_lock;
+extern void dl_done_list (ohci_t * ohci, td_t * td_list);
+extern td_t * dl_reverse_done_list (ohci_t * ohci);
+
 

_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to