aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ohci-hub.c133
1 files changed, 79 insertions, 54 deletions
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 4c9492779ede..2441642cb7b4 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -56,7 +56,6 @@ static void finish_unlinks (struct ohci_hcd *, u16);
56 56
57#ifdef CONFIG_PM 57#ifdef CONFIG_PM
58static int ohci_restart(struct ohci_hcd *ohci); 58static int ohci_restart(struct ohci_hcd *ohci);
59#endif
60 59
61static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) 60static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop)
62__releases(ohci->lock) 61__releases(ohci->lock)
@@ -187,7 +186,6 @@ __acquires(ohci->lock)
187 ohci_dbg (ohci, "lost power\n"); 186 ohci_dbg (ohci, "lost power\n");
188 status = -EBUSY; 187 status = -EBUSY;
189 } 188 }
190#ifdef CONFIG_PM
191 if (status == -EBUSY) { 189 if (status == -EBUSY) {
192 if (!autostopped) { 190 if (!autostopped) {
193 spin_unlock_irq (&ohci->lock); 191 spin_unlock_irq (&ohci->lock);
@@ -197,7 +195,6 @@ __acquires(ohci->lock)
197 } 195 }
198 return status; 196 return status;
199 } 197 }
200#endif
201 if (status != -EINPROGRESS) 198 if (status != -EINPROGRESS)
202 return status; 199 return status;
203 if (autostopped) 200 if (autostopped)
@@ -291,8 +288,6 @@ skip_resume:
291 return 0; 288 return 0;
292} 289}
293 290
294#ifdef CONFIG_PM
295
296static int ohci_bus_suspend (struct usb_hcd *hcd) 291static int ohci_bus_suspend (struct usb_hcd *hcd)
297{ 292{
298 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 293 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
@@ -330,6 +325,83 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
330 return rc; 325 return rc;
331} 326}
332 327
328/* Carry out polling-, autostop-, and autoresume-related state changes */
329static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
330 int any_connected)
331{
332 int poll_rh = 1;
333
334 switch (ohci->hc_control & OHCI_CTRL_HCFS) {
335
336 case OHCI_USB_OPER:
337 /* keep on polling until we know a device is connected
338 * and RHSC is enabled */
339 if (!ohci->autostop) {
340 if (any_connected ||
341 !device_may_wakeup(&ohci_to_hcd(ohci)
342 ->self.root_hub->dev)) {
343 if (ohci_readl(ohci, &ohci->regs->intrenable) &
344 OHCI_INTR_RHSC)
345 poll_rh = 0;
346 } else {
347 ohci->autostop = 1;
348 ohci->next_statechange = jiffies + HZ;
349 }
350
351 /* if no devices have been attached for one second, autostop */
352 } else {
353 if (changed || any_connected) {
354 ohci->autostop = 0;
355 ohci->next_statechange = jiffies +
356 STATECHANGE_DELAY;
357 } else if (time_after_eq(jiffies,
358 ohci->next_statechange)
359 && !ohci->ed_rm_list
360 && !(ohci->hc_control &
361 OHCI_SCHED_ENABLES)) {
362 ohci_rh_suspend(ohci, 1);
363 }
364 }
365 break;
366
367 /* if there is a port change, autostart or ask to be resumed */
368 case OHCI_USB_SUSPEND:
369 case OHCI_USB_RESUME:
370 if (changed) {
371 if (ohci->autostop)
372 ohci_rh_resume(ohci);
373 else
374 usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
375 } else {
376 /* everything is idle, no need for polling */
377 poll_rh = 0;
378 }
379 break;
380 }
381 return poll_rh;
382}
383
384#else /* CONFIG_PM */
385
386static inline int ohci_rh_resume(struct ohci_hcd *ohci)
387{
388 return 0;
389}
390
391/* Carry out polling-related state changes.
392 * autostop isn't used when CONFIG_PM is turned off.
393 */
394static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
395 int any_connected)
396{
397 int poll_rh = 1;
398
399 /* keep on polling until RHSC is enabled */
400 if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
401 poll_rh = 0;
402 return poll_rh;
403}
404
333#endif /* CONFIG_PM */ 405#endif /* CONFIG_PM */
334 406
335/*-------------------------------------------------------------------------*/ 407/*-------------------------------------------------------------------------*/
@@ -382,55 +454,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
382 } 454 }
383 } 455 }
384 456
385 hcd->poll_rh = 1; 457 hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
386 458 any_connected);
387 /* carry out appropriate state changes */
388 switch (ohci->hc_control & OHCI_CTRL_HCFS) {
389
390 case OHCI_USB_OPER:
391 /* keep on polling until we know a device is connected
392 * and RHSC is enabled */
393 if (!ohci->autostop) {
394 if (any_connected) {
395 if (ohci_readl(ohci, &ohci->regs->intrenable) &
396 OHCI_INTR_RHSC)
397 hcd->poll_rh = 0;
398 } else {
399 ohci->autostop = 1;
400 ohci->next_statechange = jiffies + HZ;
401 }
402
403 /* if no devices have been attached for one second, autostop */
404 } else {
405 if (changed || any_connected) {
406 ohci->autostop = 0;
407 ohci->next_statechange = jiffies +
408 STATECHANGE_DELAY;
409 } else if (device_may_wakeup(&hcd->self.root_hub->dev)
410 && time_after_eq(jiffies,
411 ohci->next_statechange)
412 && !ohci->ed_rm_list
413 && !(ohci->hc_control &
414 OHCI_SCHED_ENABLES)) {
415 ohci_rh_suspend (ohci, 1);
416 }
417 }
418 break;
419
420 /* if there is a port change, autostart or ask to be resumed */
421 case OHCI_USB_SUSPEND:
422 case OHCI_USB_RESUME:
423 if (changed) {
424 if (ohci->autostop)
425 ohci_rh_resume (ohci);
426 else
427 usb_hcd_resume_root_hub (hcd);
428 } else {
429 /* everything is idle, no need for polling */
430 hcd->poll_rh = 0;
431 }
432 break;
433 }
434 459
435done: 460done:
436 spin_unlock_irqrestore (&ohci->lock, flags); 461 spin_unlock_irqrestore (&ohci->lock, flags);