We need these USB fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
dl_done_list (ohci);
finish_unlinks (ohci, ohci_frame_no(ohci));
+ /*
+ * Some controllers don't handle "global" suspend properly if
+ * there are unsuspended ports. For these controllers, put all
+ * the enabled ports into suspend before suspending the root hub.
+ */
+ if (ohci->flags & OHCI_QUIRK_GLOBAL_SUSPEND) {
+ __hc32 __iomem *portstat = ohci->regs->roothub.portstatus;
+ int i;
+ unsigned temp;
+
+ for (i = 0; i < ohci->num_ports; (++i, ++portstat)) {
+ temp = ohci_readl(ohci, portstat);
+ if ((temp & (RH_PS_PES | RH_PS_PSS)) ==
+ RH_PS_PES)
+ ohci_writel(ohci, RH_PS_PSS, portstat);
+ }
+ }
+
/* maybe resume can wake root hub */
if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) {
ohci->hc_control |= OHCI_CTRL_RWE;
/* build "status change" packet (one or two bytes) from HC registers */
-static int
-ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
+int ohci_hub_status_data(struct usb_hcd *hcd, char *buf)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int i, changed = 0, length = 1;
return changed ? length : 0;
}
+EXPORT_SYMBOL_GPL(ohci_hub_status_data);
/*-------------------------------------------------------------------------*/
return 0;
}
-static int ohci_hub_control (
+int ohci_hub_control(
struct usb_hcd *hcd,
u16 typeReq,
u16 wValue,
}
return retval;
}
-
+EXPORT_SYMBOL_GPL(ohci_hub_control);
#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
#define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/
#define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */
+ #define OHCI_QUIRK_GLOBAL_SUSPEND 0x800 /* must suspend ports */
+
// there are also chip quirks/bugs in init logic
struct work_struct nec_work; /* Worker for NEC quirk */
extern int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup);
extern int ohci_resume(struct usb_hcd *hcd, bool hibernated);
#endif
+extern int ohci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ u16 wIndex, char *buf, u16 wLength);
+extern int ohci_hub_status_data(struct usb_hcd *hcd, char *buf);
otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE);
break;
case OTG_STATE_A_WAIT_VRISE:
- if (fsm->id || fsm->a_bus_drop || fsm->a_vbus_vld ||
- fsm->a_wait_vrise_tmout) {
+ if (fsm->a_vbus_vld)
otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
- }
+ else if (fsm->id || fsm->a_bus_drop ||
+ fsm->a_wait_vrise_tmout)
+ otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
break;
case OTG_STATE_A_WAIT_BCON:
if (!fsm->a_vbus_vld)
otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
else if (fsm->b_conn)
otg_set_state(fsm, OTG_STATE_A_HOST);
- else if (fsm->id | fsm->a_bus_drop | fsm->a_wait_bcon_tmout)
+ else if (fsm->id || fsm->a_bus_drop || fsm->a_wait_bcon_tmout)
otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
break;
case OTG_STATE_A_HOST:
VDBG("quit statemachine, changed = %d\n", state_changed);
return state_changed;
}
+EXPORT_SYMBOL_GPL(otg_statemachine);