* remote wakeup, we must fail the suspend.
*/
if (hcd->self.root_hub->do_remote_wakeup) {
- if (ehci->resuming_ports) {
- spin_unlock_irq(&ehci->lock);
- ehci_dbg(ehci, "suspend failed because a port is resuming\n");
- return -EBUSY;
+ port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ if (ehci->reset_done[port] != 0) {
+ spin_unlock_irq(&ehci->lock);
+ ehci_dbg(ehci, "suspend failed because "
+ "port %d is resuming\n",
+ port + 1);
+ return -EBUSY;
+ }
}
}
ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
- u32 temp, status;
+ u32 temp, status = 0;
u32 mask;
int ports, i, retval = 1;
unsigned long flags;
u32 ppcd = 0;
+ /* if !USB_SUSPEND, root hub timers won't get shut down ... */
+ if (ehci->rh_state != EHCI_RH_RUNNING)
+ return 0;
+
/* init status to no-changes */
buf [0] = 0;
ports = HCS_N_PORTS (ehci->hcs_params);
retval++;
}
- /* Inform the core about resumes-in-progress by returning
- * a non-zero value even if there are no status changes.
- */
- status = ehci->resuming_ports;
-
/* Some boards (mostly VIA?) report bogus overcurrent indications,
* causing massive log spam unless we completely ignore them. It
* may be relevant that VIA VT8235 controllers, where PORT_POWER is
ehci_writel(ehci,
temp & ~(PORT_RWC_BITS | PORT_RESUME),
status_reg);
- clear_bit(wIndex, &ehci->resuming_ports);
retval = handshake(ehci, status_reg,
PORT_RESUME, 0, 2000 /* 2msec */);
if (retval != 0) {
ehci->reset_done[wIndex])) {
status |= USB_PORT_STAT_C_RESET << 16;
ehci->reset_done [wIndex] = 0;
- clear_bit(wIndex, &ehci->resuming_ports);
/* force reset to complete */
ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
ehci_readl(ehci, status_reg));
}
- if (!(temp & (PORT_RESUME|PORT_RESET))) {
+ if (!(temp & (PORT_RESUME|PORT_RESET)))
ehci->reset_done[wIndex] = 0;
- clear_bit(wIndex, &ehci->resuming_ports);
- }
/* transfer dedicated ports to the companion hc */
if ((temp & PORT_CONNECT) &&
status |= USB_PORT_STAT_SUSPEND;
} else if (test_bit(wIndex, &ehci->suspended_ports)) {
clear_bit(wIndex, &ehci->suspended_ports);
- clear_bit(wIndex, &ehci->resuming_ports);
ehci->reset_done[wIndex] = 0;
if (temp & PORT_PE)
set_bit(wIndex, &ehci->port_c_suspend);
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
/* start resume signaling */
ehci_writel(ehci, temp | PORT_RESUME, status_reg);
- set_bit(wIndex-1, &ehci->resuming_ports);
ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25);
/* whoever resumes must GetPortStatus to complete it!! */
if (hsic && (wIndex == 0))
tegra_usb_phy_bus_reset(tegra->phy);
}
- clear_bit(wIndex-1, &ehci->resuming_ports);
+
break;
}
case USB_PORT_FEAT_POWER: