There is a published errata for the PPC440EPX, USBH_23: EHCI and OHCI
Linux module contention.  The overview states: When running Linux with
both EHCI and OHCI modules loaded, the EHCI module experiences a fatal
error when a high-speed device is connected to the USB2.0 Host
controller.
The EHCI module functions normally when the OHCI module is not loaded.

The patch below is a software work around for the problem. I would like
to
discuss the probability of the patch being accepted into the kernel and
/
or what could be done to increase the probability.  The patch is against
the head of the DENX git repository, linux-2.6-denx.git.

Signed-off-by: Mark Miesfeld <[EMAIL PROTECTED]>

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 012954b..1569c8b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -67,6 +67,26 @@ config USB_EHCI_TT_NEWSCHED

          If unsure, say N.

+config  USB_PPC440EPX_USBH_23_ERRATA
+       bool "PPC440EPX USBH_23 ERRATA EHCI and OHCI contention"
+       depends on USB_EHCI_HCD && 440EPX
+       default y
+       select USB_OHCI_HCD
+       select USB_OHCI_HCD_PPC_SOC
+       ---help---
+         Allows the EHCI and OHCI drivers to be loaded together when
using
+         the USB Host controller on the 440EPX processor chip. This is
+         necessary when either high speed or full speed devices may be
+         connected to the USB Host port.  You must compile and use the
OHCI
+         driver when selecting this option.
+
+         The option is not needed if the USB Host port is only used
with
+         USB 2.0 high speed devices and the OHCI driver is not compiled
or
+         loaded.
+
+         Say N when the OHCI driver for the 440EPX will not be compiled
or
+         will not be loaded.  If unsure, say Y.
+
 config USB_EHCI_BIG_ENDIAN_MMIO
        bool
        depends on USB_EHCI_HCD
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 1813b7c..03516d4 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -289,6 +289,12 @@ static inline void remove_companion_file

 
/*----------------------------------------------------------------------
---*/

+#ifdef CONFIG_USB_PPC440EPX_USBH_23_ERRATA
+extern void ohci_ppc_set_hcfs(int state);
+#define HCFS_SUSPEND      0
+#define HCFS_OPERATIONAL  1
+#endif
+
 static int check_reset_complete (
        struct ehci_hcd *ehci,
        int             index,
@@ -319,8 +325,17 @@ static int check_reset_complete (
                port_status &= ~PORT_RWC_BITS;
                ehci_writel(ehci, port_status, status_reg);

-       } else
+#ifdef CONFIG_USB_PPC440EPX_USBH_23_ERRATA
+               /* ensure 440EPX ohci controller state is operational */
+               ohci_ppc_set_hcfs(HCFS_OPERATIONAL);
+#endif
+       } else {
                ehci_dbg (ehci, "port %d high speed\n", index + 1);
+#ifdef CONFIG_USB_PPC440EPX_USBH_23_ERRATA
+               /* ensure 440EPx ohci controller state is suspended */
+               ohci_ppc_set_hcfs(HCFS_SUSPEND);
+#endif
+       }

        return port_status;
 }
diff --git a/drivers/usb/host/ohci-ppc-soc.c
b/drivers/usb/host/ohci-ppc-soc.c
index 1a2e177..7195311 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -20,6 +20,37 @@ #include <linux/signal.h>
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */

+#ifdef CONFIG_USB_PPC440EPX_USBH_23_ERRATA
+struct ohci_hcd        *cached_ohci = NULL;
+#define HCFS_SUSPEND      0
+#define HCFS_OPERATIONAL  1
+void ohci_ppc_set_hcfs(int state) {
+       u32 hc_control;
+
+       hc_control = (ohci_readl(cached_ohci,
&cached_ohci->regs->control)
+                     & ~OHCI_CTRL_HCFS);
+
+       switch ( state )  {
+       case HCFS_SUSPEND:
+               hc_control |= OHCI_USB_SUSPEND;
+               break;
+       case HCFS_OPERATIONAL :
+               hc_control |= OHCI_USB_OPER;
+               break;
+
+       default:
+               /* this is unexpected, shoud never happen */
+               hc_control |= OHCI_USB_SUSPEND;
+               break;
+       }
+
+       /* write the new state and flush the write. */
+       ohci_writel(cached_ohci, hc_control,
&cached_ohci->regs->control);
+       (void) ohci_readl(cached_ohci, &cached_ohci->regs->control);
+}
+EXPORT_SYMBOL (ohci_ppc_set_hcfs);
+#endif
+
 /**
  * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
  * Context: !in_interrupt()
@@ -76,9 +107,27 @@ static int usb_hcd_ppc_soc_probe(const s
        ohci_hcd_init(ohci);

        retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
-       if (retval == 0)
+       if (retval == 0) {
+#ifdef CONFIG_USB_PPC440EPX_USBH_23_ERRATA
+               /* At this point ohci_run has executed, the controller
is
+                * running, the root ports set up, etc.  Now, put the
core in
+                * the suspended state.  The ehci driver will bring it
out of
+                * suspended state when / if a non-high speed USB device
is
+                * attached to the USB Host port.
+                */
+               u32 hc_control;
+               cached_ohci = ohci;
+               spin_lock_irq(&ohci->lock);
+
+               hc_control = ohci_readl(ohci, &ohci->regs->control);
+               hc_control |= OHCI_USB_SUSPEND;
+               ohci_writel(ohci, hc_control, &ohci->regs->control);
+               (void) ohci_readl(ohci, &ohci->regs->control);
+
+               spin_unlock_irq(&ohci->lock);
+#endif
                return retval;
-
+       }
        pr_debug("Removing PPC-SOC USB Controller\n");

        iounmap(hcd->regs);
--------------------------------------------------------

CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is for 
the sole use of the intended recipient(s) and contains information that is 
confidential and proprietary to Applied Micro Circuits Corporation or its 
subsidiaries. It is to be used solely for the purpose of furthering the 
parties' business relationship. All unauthorized review, use, disclosure or 
distribution is prohibited. If you are not the intended recipient, please 
contact the sender by reply e-mail and destroy all copies of the original 
message.

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to