diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index d81d2fcbff1894d79f0606d831d91b628c44f71e..3be3df233a0e0b73b8bdc198d5aae050b6e520be 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -370,6 +370,15 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; +#ifdef CONFIG_PPC_83xx + /* + * Deal with MPC834X that need port power to be cycled after the power + * fault condition is removed. Otherwise the state machine does not + * reflect PORTSC[CSC] correctly. + */ + ehci->need_oc_pp_cycle = 1; +#endif + hcd->has_tt = 1; retval = ehci_setup(hcd); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 7b04ca96b58598dbac7dec332af8061ba3ebba35..9ab4a4d9768a5a3ed3fa791746e01977445ba840 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -840,7 +840,8 @@ static int ehci_hub_control ( * power switching; they're allowed to just limit the * current. khubd will turn the power back on. */ - if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) { + if (((temp & PORT_OC) || (ehci->need_oc_pp_cycle)) + && HCS_PPC(ehci->hcs_params)) { ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_POWER), status_reg); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index e66699950997b7c11d5b2cbde4c379a46dff1c63..7c978b23520d07a871396db9626293fd352944ca 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -199,6 +199,7 @@ struct ehci_hcd { /* one per controller */ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ unsigned has_synopsys_hc_bug:1; /* Synopsys HC */ unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ + unsigned need_oc_pp_cycle:1; /* MPC834X port power */ /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6)