aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/uhci-hcd.c')
-rw-r--r--drivers/usb/host/uhci-hcd.c66
1 files changed, 34 insertions, 32 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index fba99b120588..c8ae199cfbb8 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -294,50 +294,50 @@ __acquires(uhci->lock)
294 * and that remote wakeups should be enabled. 294 * and that remote wakeups should be enabled.
295 */ 295 */
296 egsm_enable = USBCMD_EGSM; 296 egsm_enable = USBCMD_EGSM;
297 uhci->RD_enable = 1;
298 int_enable = USBINTR_RESUME; 297 int_enable = USBINTR_RESUME;
299 wakeup_enable = 1; 298 wakeup_enable = 1;
300 299
301 /* In auto-stop mode wakeups must always be detected, but 300 /*
302 * Resume-Detect interrupts may be prohibited. (In the absence 301 * In auto-stop mode, we must be able to detect new connections.
303 * of CONFIG_PM, they are always disallowed.) 302 * The user can force us to poll by disabling remote wakeup;
303 * otherwise we will use the EGSM/RD mechanism.
304 */ 304 */
305 if (auto_stop) { 305 if (auto_stop) {
306 if (!device_may_wakeup(&rhdev->dev)) 306 if (!device_may_wakeup(&rhdev->dev))
307 int_enable = 0; 307 egsm_enable = int_enable = 0;
308 }
308 309
309 /* In bus-suspend mode wakeups may be disabled, but if they are
310 * allowed then so are Resume-Detect interrupts.
311 */
312 } else {
313#ifdef CONFIG_PM 310#ifdef CONFIG_PM
311 /*
312 * In bus-suspend mode, we use the wakeup setting specified
313 * for the root hub.
314 */
315 else {
314 if (!rhdev->do_remote_wakeup) 316 if (!rhdev->do_remote_wakeup)
315 wakeup_enable = 0; 317 wakeup_enable = 0;
316#endif
317 } 318 }
319#endif
318 320
319 /* EGSM causes the root hub to echo a 'K' signal (resume) out any 321 /*
320 * port which requests a remote wakeup. According to the USB spec, 322 * UHCI doesn't distinguish between wakeup requests from downstream
321 * every hub is supposed to do this. But if we are ignoring 323 * devices and local connect/disconnect events. There's no way to
322 * remote-wakeup requests anyway then there's no point to it. 324 * enable one without the other; both are controlled by EGSM. Thus
323 * We also shouldn't enable EGSM if it's broken. 325 * if wakeups are disallowed then EGSM must be turned off -- in which
324 */ 326 * case remote wakeup requests from downstream during system sleep
325 if (!wakeup_enable || global_suspend_mode_is_broken(uhci)) 327 * will be lost.
326 egsm_enable = 0; 328 *
327 329 * In addition, if EGSM is broken then we can't use it. Likewise,
328 /* If we're ignoring wakeup events then there's no reason to 330 * if Resume-Detect interrupts are broken then we can't use them.
329 * enable Resume-Detect interrupts. We also shouldn't enable
330 * them if they are broken or disallowed.
331 * 331 *
332 * This logic may lead us to enabling RD but not EGSM. The UHCI 332 * Finally, neither EGSM nor RD is useful by itself. Without EGSM,
333 * spec foolishly says that RD works only when EGSM is on, but 333 * the RD status bit will never get set. Without RD, the controller
334 * there's no harm in enabling it anyway -- perhaps some chips 334 * won't generate interrupts to tell the system about wakeup events.
335 * will implement it!
336 */ 335 */
337 if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) || 336 if (!wakeup_enable || global_suspend_mode_is_broken(uhci) ||
338 !int_enable) 337 resume_detect_interrupts_are_broken(uhci))
339 uhci->RD_enable = int_enable = 0; 338 egsm_enable = int_enable = 0;
340 339
340 uhci->RD_enable = !!int_enable;
341 uhci_writew(uhci, int_enable, USBINTR); 341 uhci_writew(uhci, int_enable, USBINTR);
342 uhci_writew(uhci, egsm_enable | USBCMD_CF, USBCMD); 342 uhci_writew(uhci, egsm_enable | USBCMD_CF, USBCMD);
343 mb(); 343 mb();
@@ -364,10 +364,12 @@ __acquires(uhci->lock)
364 uhci->rh_state = new_state; 364 uhci->rh_state = new_state;
365 uhci->is_stopped = UHCI_IS_STOPPED; 365 uhci->is_stopped = UHCI_IS_STOPPED;
366 366
367 /* If interrupts don't work and remote wakeup is enabled then 367 /*
368 * the suspended root hub needs to be polled. 368 * If remote wakeup is enabled but either EGSM or RD interrupts
369 * doesn't work, then we won't get an interrupt when a wakeup event
370 * occurs. Thus the suspended root hub needs to be polled.
369 */ 371 */
370 if (!int_enable && wakeup_enable) 372 if (wakeup_enable && (!int_enable || !egsm_enable))
371 set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); 373 set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags);
372 else 374 else
373 clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); 375 clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags);