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.c70
1 files changed, 23 insertions, 47 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 82e608a4bbd0..25a718eb1d0f 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -84,6 +84,8 @@ static char *errbuf;
84 84
85static kmem_cache_t *uhci_up_cachep; /* urb_priv */ 85static kmem_cache_t *uhci_up_cachep; /* urb_priv */
86 86
87static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
88static void wakeup_rh(struct uhci_hcd *uhci);
87static void uhci_get_current_frame_number(struct uhci_hcd *uhci); 89static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
88 90
89/* If a transfer is still active after this much time, turn off FSBR */ 91/* If a transfer is still active after this much time, turn off FSBR */
@@ -133,12 +135,12 @@ static void reset_hc(struct uhci_hcd *uhci)
133 outw(0, uhci->io_addr + USBINTR); 135 outw(0, uhci->io_addr + USBINTR);
134 outw(0, uhci->io_addr + USBCMD); 136 outw(0, uhci->io_addr + USBCMD);
135 137
136 uhci->resume_detect = 0;
137 uhci->port_c_suspend = uhci->suspended_ports = 138 uhci->port_c_suspend = uhci->suspended_ports =
138 uhci->resuming_ports = 0; 139 uhci->resuming_ports = 0;
139 uhci->rh_state = UHCI_RH_RESET; 140 uhci->rh_state = UHCI_RH_RESET;
140 uhci->is_stopped = UHCI_IS_STOPPED; 141 uhci->is_stopped = UHCI_IS_STOPPED;
141 uhci_to_hcd(uhci)->state = HC_STATE_HALT; 142 uhci_to_hcd(uhci)->state = HC_STATE_HALT;
143 uhci_to_hcd(uhci)->poll_rh = 0;
142} 144}
143 145
144/* 146/*
@@ -148,6 +150,7 @@ static void hc_died(struct uhci_hcd *uhci)
148{ 150{
149 reset_hc(uhci); 151 reset_hc(uhci);
150 uhci->hc_inaccessible = 1; 152 uhci->hc_inaccessible = 1;
153 del_timer(&uhci->stall_timer);
151} 154}
152 155
153/* 156/*
@@ -302,14 +305,14 @@ __acquires(uhci->lock)
302 305
303 uhci->rh_state = new_state; 306 uhci->rh_state = new_state;
304 uhci->is_stopped = UHCI_IS_STOPPED; 307 uhci->is_stopped = UHCI_IS_STOPPED;
305 uhci->resume_detect = 0; 308 del_timer(&uhci->stall_timer);
309 uhci_to_hcd(uhci)->poll_rh = !int_enable;
306 310
307 uhci_scan_schedule(uhci, NULL); 311 uhci_scan_schedule(uhci, NULL);
308} 312}
309 313
310static void start_rh(struct uhci_hcd *uhci) 314static void start_rh(struct uhci_hcd *uhci)
311{ 315{
312 uhci->rh_state = UHCI_RH_RUNNING;
313 uhci->is_stopped = 0; 316 uhci->is_stopped = 0;
314 smp_wmb(); 317 smp_wmb();
315 318
@@ -320,6 +323,9 @@ static void start_rh(struct uhci_hcd *uhci)
320 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, 323 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
321 uhci->io_addr + USBINTR); 324 uhci->io_addr + USBINTR);
322 mb(); 325 mb();
326 uhci->rh_state = UHCI_RH_RUNNING;
327 uhci_to_hcd(uhci)->poll_rh = 1;
328 restart_timer(uhci);
323} 329}
324 330
325static void wakeup_rh(struct uhci_hcd *uhci) 331static void wakeup_rh(struct uhci_hcd *uhci)
@@ -353,36 +359,9 @@ __acquires(uhci->lock)
353 } 359 }
354 360
355 start_rh(uhci); 361 start_rh(uhci);
356}
357
358static void rh_state_transitions(struct uhci_hcd *uhci)
359{
360 switch (uhci->rh_state) {
361 case UHCI_RH_RUNNING:
362 /* are any devices attached? */
363 if (!any_ports_active(uhci)) {
364 uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
365 uhci->auto_stop_time = jiffies + HZ;
366 }
367 break;
368 362
369 case UHCI_RH_RUNNING_NODEVS: 363 /* Restart root hub polling */
370 /* auto-stop if nothing connected for 1 second */ 364 mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
371 if (any_ports_active(uhci))
372 uhci->rh_state = UHCI_RH_RUNNING;
373 else if (time_after_eq(jiffies, uhci->auto_stop_time))
374 suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
375 break;
376
377 case UHCI_RH_AUTO_STOPPED:
378 /* wakeup if requested by a device */
379 if (uhci->resume_detect)
380 wakeup_rh(uhci);
381 break;
382
383 default:
384 break;
385 }
386} 365}
387 366
388static void stall_callback(unsigned long _uhci) 367static void stall_callback(unsigned long _uhci)
@@ -394,14 +373,8 @@ static void stall_callback(unsigned long _uhci)
394 uhci_scan_schedule(uhci, NULL); 373 uhci_scan_schedule(uhci, NULL);
395 check_fsbr(uhci); 374 check_fsbr(uhci);
396 375
397 /* Poll for and perform state transitions */ 376 if (!uhci->is_stopped)
398 if (!uhci->hc_inaccessible) { 377 restart_timer(uhci);
399 rh_state_transitions(uhci);
400 if (uhci->suspended_ports)
401 uhci_check_ports(uhci);
402 }
403
404 restart_timer(uhci);
405 spin_unlock_irqrestore(&uhci->lock, flags); 378 spin_unlock_irqrestore(&uhci->lock, flags);
406} 379}
407 380
@@ -443,7 +416,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
443 } 416 }
444 417
445 if (status & USBSTS_RD) 418 if (status & USBSTS_RD)
446 uhci->resume_detect = 1; 419 usb_hcd_poll_rh_status(hcd);
447 420
448 spin_lock_irqsave(&uhci->lock, flags); 421 spin_lock_irqsave(&uhci->lock, flags);
449 uhci_scan_schedule(uhci, regs); 422 uhci_scan_schedule(uhci, regs);
@@ -542,6 +515,7 @@ static int uhci_start(struct usb_hcd *hcd)
542 struct dentry *dentry; 515 struct dentry *dentry;
543 516
544 io_size = (unsigned) hcd->rsrc_len; 517 io_size = (unsigned) hcd->rsrc_len;
518 hcd->uses_new_polling = 1;
545 if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM)) 519 if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM))
546 hcd->can_wakeup = 1; /* Assume it supports PME# */ 520 hcd->can_wakeup = 1; /* Assume it supports PME# */
547 521
@@ -714,8 +688,6 @@ static int uhci_start(struct usb_hcd *hcd)
714 configure_hc(uhci); 688 configure_hc(uhci);
715 start_rh(uhci); 689 start_rh(uhci);
716 690
717 restart_timer(uhci);
718
719 udev->speed = USB_SPEED_FULL; 691 udev->speed = USB_SPEED_FULL;
720 692
721 if (usb_hcd_register_root_hub(udev, hcd) != 0) { 693 if (usb_hcd_register_root_hub(udev, hcd) != 0) {
@@ -730,8 +702,8 @@ static int uhci_start(struct usb_hcd *hcd)
730 * error exits: 702 * error exits:
731 */ 703 */
732err_start_root_hub: 704err_start_root_hub:
733 del_timer_sync(&uhci->stall_timer);
734 reset_hc(uhci); 705 reset_hc(uhci);
706 del_timer_sync(&uhci->stall_timer);
735 707
736err_alloc_skelqh: 708err_alloc_skelqh:
737 for (i = 0; i < UHCI_NUM_SKELQH; i++) 709 for (i = 0; i < UHCI_NUM_SKELQH; i++)
@@ -771,13 +743,12 @@ static void uhci_stop(struct usb_hcd *hcd)
771{ 743{
772 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 744 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
773 745
774 del_timer_sync(&uhci->stall_timer);
775
776 spin_lock_irq(&uhci->lock); 746 spin_lock_irq(&uhci->lock);
777 reset_hc(uhci); 747 reset_hc(uhci);
778 uhci_scan_schedule(uhci, NULL); 748 uhci_scan_schedule(uhci, NULL);
779 spin_unlock_irq(&uhci->lock); 749 spin_unlock_irq(&uhci->lock);
780 750
751 del_timer_sync(&uhci->stall_timer);
781 release_uhci(uhci); 752 release_uhci(uhci);
782} 753}
783 754
@@ -844,6 +815,8 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
844 815
845done: 816done:
846 spin_unlock_irq(&uhci->lock); 817 spin_unlock_irq(&uhci->lock);
818 if (rc == 0)
819 del_timer_sync(&hcd->rh_timer);
847 return rc; 820 return rc;
848} 821}
849 822
@@ -875,6 +848,9 @@ static int uhci_resume(struct usb_hcd *hcd)
875 suspend_rh(uhci, UHCI_RH_SUSPENDED); 848 suspend_rh(uhci, UHCI_RH_SUSPENDED);
876 849
877 spin_unlock_irq(&uhci->lock); 850 spin_unlock_irq(&uhci->lock);
851
852 if (hcd->poll_rh)
853 usb_hcd_poll_rh_status(hcd);
878 return 0; 854 return 0;
879} 855}
880#endif 856#endif