Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 317037
b: refs/heads/master
c: 43fe3a9
h: refs/heads/master
i:
  317035: 49ea063
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jul 16, 2012
1 parent dbaeb07 commit d2363b3
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 6 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: c4f3476436f7452b97c8accb5dd7d53219a11a3f
refs/heads/master: 43fe3a99d9caf10b25f9c596e9854cdae30db418
20 changes: 19 additions & 1 deletion trunk/drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ static void ehci_shutdown(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);

spin_lock_irq(&ehci->lock);
ehci->shutdown = true;
ehci->rh_state = EHCI_RH_STOPPING;
ehci->enabled_hrtimer_events = 0;
spin_unlock_irq(&ehci->lock);
Expand Down Expand Up @@ -823,6 +824,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
usb_hc_died(hcd);

/* Don't let the controller do anything more */
ehci->shutdown = true;
ehci->rh_state = EHCI_RH_STOPPING;
ehci->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
ehci_writel(ehci, ehci->command, &ehci->regs->command);
Expand Down Expand Up @@ -1129,6 +1131,9 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
/* Mark hardware accessible again as we are back to full power by now */
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

if (ehci->shutdown)
return 0; /* Controller is dead */

/*
* If CF is still set and we aren't resuming from hibernation
* then we maintained suspend power.
Expand All @@ -1139,10 +1144,17 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
int mask = INTR_MASK;

ehci_prepare_ports_for_controller_resume(ehci);

spin_lock_irq(&ehci->lock);
if (ehci->shutdown)
goto skip;

if (!hcd->self.root_hub->do_remote_wakeup)
mask &= ~STS_PCD;
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
ehci_readl(ehci, &ehci->regs->intr_enable);
skip:
spin_unlock_irq(&ehci->lock);
return 0;
}

Expand All @@ -1154,14 +1166,20 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
(void) ehci_halt(ehci);
(void) ehci_reset(ehci);

spin_lock_irq(&ehci->lock);
if (ehci->shutdown)
goto skip;

ehci_writel(ehci, ehci->command, &ehci->regs->command);
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */

ehci->rh_state = EHCI_RH_SUSPENDED;
spin_unlock_irq(&ehci->lock);

/* here we "know" root ports should always stay powered */
ehci_port_power(ehci, 1);

ehci->rh_state = EHCI_RH_SUSPENDED;
return 1;
}

Expand Down
27 changes: 23 additions & 4 deletions trunk/drivers/usb/host/ehci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
ehci_quiesce(ehci);

spin_lock_irq (&ehci->lock);
if (ehci->rh_state < EHCI_RH_RUNNING)
goto done;

/* Once the controller is stopped, port resumes that are already
* in progress won't complete. Hence if remote wakeup is enabled
Expand Down Expand Up @@ -306,6 +308,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
ehci_halt (ehci);

spin_lock_irq(&ehci->lock);
if (ehci->enabled_hrtimer_events & BIT(EHCI_HRTIMER_POLL_DEAD))
ehci_handle_controller_death(ehci);
if (ehci->rh_state != EHCI_RH_RUNNING)
goto done;
ehci->rh_state = EHCI_RH_SUSPENDED;

end_unlink_async(ehci);
Expand All @@ -320,6 +326,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
ehci_readl(ehci, &ehci->regs->intr_enable);

done:
ehci->next_statechange = jiffies + msecs_to_jiffies(10);
ehci->enabled_hrtimer_events = 0;
ehci->next_hrtimer_event = EHCI_HRTIMER_NO_EVENT;
Expand All @@ -342,10 +349,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
if (time_before (jiffies, ehci->next_statechange))
msleep(5);
spin_lock_irq (&ehci->lock);
if (!HCD_HW_ACCESSIBLE(hcd)) {
spin_unlock_irq(&ehci->lock);
return -ESHUTDOWN;
}
if (!HCD_HW_ACCESSIBLE(hcd) || ehci->shutdown)
goto shutdown;

if (unlikely(ehci->debug)) {
if (!dbgp_reset_prep())
Expand Down Expand Up @@ -384,6 +389,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
spin_unlock_irq(&ehci->lock);
msleep(8);
spin_lock_irq(&ehci->lock);
if (ehci->shutdown)
goto shutdown;

/* clear phy low-power mode before resume */
if (ehci->bus_suspended && ehci->has_hostpc) {
Expand All @@ -401,6 +408,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
spin_unlock_irq(&ehci->lock);
msleep(5);
spin_lock_irq(&ehci->lock);
if (ehci->shutdown)
goto shutdown;
}

/* manually resume the ports we suspended during bus_suspend() */
Expand All @@ -421,6 +430,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
spin_unlock_irq(&ehci->lock);
msleep(20);
spin_lock_irq(&ehci->lock);
if (ehci->shutdown)
goto shutdown;
}

i = HCS_N_PORTS (ehci->hcs_params);
Expand All @@ -439,10 +450,18 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
ehci_handover_companion_ports(ehci);

/* Now we can safely re-enable irqs */
spin_lock_irq(&ehci->lock);
if (ehci->shutdown)
goto shutdown;
ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
(void) ehci_readl(ehci, &ehci->regs->intr_enable);
spin_unlock_irq(&ehci->lock);

return 0;

shutdown:
spin_unlock_irq(&ehci->lock);
return -ESHUTDOWN;
}

#else
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/host/ehci.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ struct ehci_hcd { /* one per controller */
bool need_rescan:1;
bool intr_unlinking:1;
bool async_unlinking:1;
bool shutdown:1;
struct ehci_qh *qh_scan_next;

/* async schedule support */
Expand Down

0 comments on commit d2363b3

Please sign in to comment.