Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 348685
b: refs/heads/master
c: c52804a
h: refs/heads/master
i:
  348683: 6dc3f61
v: v3
  • Loading branch information
Sarah Sharp committed Jan 3, 2013
1 parent 5d247d6 commit c340611
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 65bdac5effd15d6af619b3b7218627ef4d84ed6a
refs/heads/master: c52804a472649b2e5005342308739434cbd51119
7 changes: 7 additions & 0 deletions trunk/drivers/usb/host/xhci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
int max_ports;
__le32 __iomem **port_array;
struct xhci_bus_state *bus_state;
bool reset_change = false;

max_ports = xhci_get_ports(hcd, &port_array);
bus_state = &xhci->bus_state[hcd_index(hcd)];
Expand Down Expand Up @@ -1015,6 +1016,12 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
buf[(i + 1) / 8] |= 1 << (i + 1) % 8;
status = 1;
}
if ((temp & PORT_RC))
reset_change = true;
}
if (!status && !reset_change) {
xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
}
spin_unlock_irqrestore(&xhci->lock, flags);
return status ? retval : 0;
Expand Down
9 changes: 9 additions & 0 deletions trunk/drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,15 @@ static void handle_port_status(struct xhci_hcd *xhci,
if (bogus_port_status)
return;

/*
* xHCI port-status-change events occur when the "or" of all the
* status-change bits in the portsc register changes from 0 to 1.
* New status changes won't cause an event if any other change
* bits are still set. When an event occurs, switch over to
* polling to avoid losing status changes.
*/
xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
spin_unlock(&xhci->lock);
/* Pass this up to the core */
usb_hcd_poll_rh_status(hcd);
Expand Down
10 changes: 10 additions & 0 deletions trunk/drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,11 @@ int xhci_suspend(struct xhci_hcd *xhci)
xhci->shared_hcd->state != HC_STATE_SUSPENDED)
return -EINVAL;

/* Don't poll the roothubs on bus suspend. */
xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
del_timer_sync(&hcd->rh_timer);

spin_lock_irq(&xhci->lock);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
Expand Down Expand Up @@ -1069,6 +1074,11 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
compliance_mode_recovery_timer_init(xhci);

/* Re-enable port polling. */
xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
usb_hcd_poll_rh_status(hcd);

return retval;
}
#endif /* CONFIG_PM */
Expand Down

0 comments on commit c340611

Please sign in to comment.