aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-sead3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-sead3.c')
-rw-r--r--drivers/usb/host/ehci-sead3.c74
1 files changed, 3 insertions, 71 deletions
diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c
index cc199e87a7a9..58c96bd50d22 100644
--- a/drivers/usb/host/ehci-sead3.c
+++ b/drivers/usb/host/ehci-sead3.c
@@ -160,84 +160,16 @@ static int ehci_hcd_sead3_drv_remove(struct platform_device *pdev)
160static int ehci_hcd_sead3_drv_suspend(struct device *dev) 160static int ehci_hcd_sead3_drv_suspend(struct device *dev)
161{ 161{
162 struct usb_hcd *hcd = dev_get_drvdata(dev); 162 struct usb_hcd *hcd = dev_get_drvdata(dev);
163 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 163 bool do_wakeup = device_may_wakeup(dev);
164 unsigned long flags;
165 int rc = 0;
166
167 if (time_before(jiffies, ehci->next_statechange))
168 msleep(20);
169
170 /* Root hub was already suspended. Disable irq emission and
171 * mark HW unaccessible. The PM and USB cores make sure that
172 * the root hub is either suspended or stopped.
173 */
174 ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
175 spin_lock_irqsave(&ehci->lock, flags);
176 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
177 (void)ehci_readl(ehci, &ehci->regs->intr_enable);
178
179 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
180 spin_unlock_irqrestore(&ehci->lock, flags);
181 164
182 /* could save FLADJ in case of Vaux power loss 165 return ehci_suspend(hcd, do_wakeup);
183 * ... we'd only use it to handle clock skew
184 */
185
186 return rc;
187} 166}
188 167
189static int ehci_hcd_sead3_drv_resume(struct device *dev) 168static int ehci_hcd_sead3_drv_resume(struct device *dev)
190{ 169{
191 struct usb_hcd *hcd = dev_get_drvdata(dev); 170 struct usb_hcd *hcd = dev_get_drvdata(dev);
192 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
193
194 /* maybe restore FLADJ. */
195
196 if (time_before(jiffies, ehci->next_statechange))
197 msleep(100);
198
199 /* Mark hardware accessible again as we are out of D3 state by now */
200 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
201
202 /* If CF is still set, we maintained PCI Vaux power.
203 * Just undo the effect of ehci_pci_suspend().
204 */
205 if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
206 int mask = INTR_MASK;
207
208 ehci_prepare_ports_for_controller_resume(ehci);
209 if (!hcd->self.root_hub->do_remote_wakeup)
210 mask &= ~STS_PCD;
211 ehci_writel(ehci, mask, &ehci->regs->intr_enable);
212 ehci_readl(ehci, &ehci->regs->intr_enable);
213 return 0;
214 }
215
216 ehci_dbg(ehci, "lost power, restarting\n");
217 usb_root_hub_lost_power(hcd->self.root_hub);
218
219 /* Else reset, to cope with power loss or flush-to-storage
220 * style "resume" having let BIOS kick in during reboot.
221 */
222 (void) ehci_halt(ehci);
223 (void) ehci_reset(ehci);
224
225 /* emptying the schedule aborts any urbs */
226 spin_lock_irq(&ehci->lock);
227 if (ehci->reclaim)
228 end_unlink_async(ehci);
229 ehci_work(ehci);
230 spin_unlock_irq(&ehci->lock);
231
232 ehci_writel(ehci, ehci->command, &ehci->regs->command);
233 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
234 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
235
236 /* here we "know" root ports should always stay powered */
237 ehci_port_power(ehci, 1);
238
239 ehci->rh_state = EHCI_RH_SUSPENDED;
240 171
172 ehci_resume(hcd, false);
241 return 0; 173 return 0;
242} 174}
243 175