Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 265037
b: refs/heads/master
c: 5c12e78
h: refs/heads/master
i:
  265035: 30312b4
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Sep 26, 2011
1 parent f673d36 commit 905032a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a6eeeb9f45b5a417f574f3bc799b7122270bf59b
refs/heads/master: 5c12e7856d75f68c1ca8372d6cc76cdbc71763c0
66 changes: 34 additions & 32 deletions trunk/drivers/usb/host/uhci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,50 +294,50 @@ __acquires(uhci->lock)
* and that remote wakeups should be enabled.
*/
egsm_enable = USBCMD_EGSM;
uhci->RD_enable = 1;
int_enable = USBINTR_RESUME;
wakeup_enable = 1;

/* In auto-stop mode wakeups must always be detected, but
* Resume-Detect interrupts may be prohibited. (In the absence
* of CONFIG_PM, they are always disallowed.)
/*
* In auto-stop mode, we must be able to detect new connections.
* The user can force us to poll by disabling remote wakeup;
* otherwise we will use the EGSM/RD mechanism.
*/
if (auto_stop) {
if (!device_may_wakeup(&rhdev->dev))
int_enable = 0;
egsm_enable = int_enable = 0;
}

/* In bus-suspend mode wakeups may be disabled, but if they are
* allowed then so are Resume-Detect interrupts.
*/
} else {
#ifdef CONFIG_PM
/*
* In bus-suspend mode, we use the wakeup setting specified
* for the root hub.
*/
else {
if (!rhdev->do_remote_wakeup)
wakeup_enable = 0;
#endif
}
#endif

/* EGSM causes the root hub to echo a 'K' signal (resume) out any
* port which requests a remote wakeup. According to the USB spec,
* every hub is supposed to do this. But if we are ignoring
* remote-wakeup requests anyway then there's no point to it.
* We also shouldn't enable EGSM if it's broken.
*/
if (!wakeup_enable || global_suspend_mode_is_broken(uhci))
egsm_enable = 0;

/* If we're ignoring wakeup events then there's no reason to
* enable Resume-Detect interrupts. We also shouldn't enable
* them if they are broken or disallowed.
/*
* UHCI doesn't distinguish between wakeup requests from downstream
* devices and local connect/disconnect events. There's no way to
* enable one without the other; both are controlled by EGSM. Thus
* if wakeups are disallowed then EGSM must be turned off -- in which
* case remote wakeup requests from downstream during system sleep
* will be lost.
*
* In addition, if EGSM is broken then we can't use it. Likewise,
* if Resume-Detect interrupts are broken then we can't use them.
*
* This logic may lead us to enabling RD but not EGSM. The UHCI
* spec foolishly says that RD works only when EGSM is on, but
* there's no harm in enabling it anyway -- perhaps some chips
* will implement it!
* Finally, neither EGSM nor RD is useful by itself. Without EGSM,
* the RD status bit will never get set. Without RD, the controller
* won't generate interrupts to tell the system about wakeup events.
*/
if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) ||
!int_enable)
uhci->RD_enable = int_enable = 0;
if (!wakeup_enable || global_suspend_mode_is_broken(uhci) ||
resume_detect_interrupts_are_broken(uhci))
egsm_enable = int_enable = 0;

uhci->RD_enable = !!int_enable;
uhci_writew(uhci, int_enable, USBINTR);
uhci_writew(uhci, egsm_enable | USBCMD_CF, USBCMD);
mb();
Expand All @@ -364,10 +364,12 @@ __acquires(uhci->lock)
uhci->rh_state = new_state;
uhci->is_stopped = UHCI_IS_STOPPED;

/* If interrupts don't work and remote wakeup is enabled then
* the suspended root hub needs to be polled.
/*
* If remote wakeup is enabled but either EGSM or RD interrupts
* doesn't work, then we won't get an interrupt when a wakeup event
* occurs. Thus the suspended root hub needs to be polled.
*/
if (!int_enable && wakeup_enable)
if (wakeup_enable && (!int_enable || !egsm_enable))
set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags);
else
clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags);
Expand Down

0 comments on commit 905032a

Please sign in to comment.