aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ehci-hcd.c19
-rw-r--r--drivers/usb/host/ehci-hub.c9
-rw-r--r--drivers/usb/host/ehci.h1
3 files changed, 27 insertions, 2 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index baf9b648bb1f..8697ad19f313 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -584,6 +584,11 @@ static int ehci_init(struct usb_hcd *hcd)
584 if (log2_irq_thresh < 0 || log2_irq_thresh > 6) 584 if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
585 log2_irq_thresh = 0; 585 log2_irq_thresh = 0;
586 temp = 1 << (16 + log2_irq_thresh); 586 temp = 1 << (16 + log2_irq_thresh);
587 if (HCC_PER_PORT_CHANGE_EVENT(hcc_params)) {
588 ehci->has_ppcd = 1;
589 ehci_dbg(ehci, "enable per-port change event\n");
590 temp |= CMD_PPCEE;
591 }
587 if (HCC_CANPARK(hcc_params)) { 592 if (HCC_CANPARK(hcc_params)) {
588 /* HW default park == 3, on hardware that supports it (like 593 /* HW default park == 3, on hardware that supports it (like
589 * NVidia and ALI silicon), maximizes throughput on the async 594 * NVidia and ALI silicon), maximizes throughput on the async
@@ -782,6 +787,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
782 /* remote wakeup [4.3.1] */ 787 /* remote wakeup [4.3.1] */
783 if (status & STS_PCD) { 788 if (status & STS_PCD) {
784 unsigned i = HCS_N_PORTS (ehci->hcs_params); 789 unsigned i = HCS_N_PORTS (ehci->hcs_params);
790 u32 ppcd = 0;
785 791
786 /* kick root hub later */ 792 /* kick root hub later */
787 pcd_status = status; 793 pcd_status = status;
@@ -790,9 +796,18 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
790 if (!(cmd & CMD_RUN)) 796 if (!(cmd & CMD_RUN))
791 usb_hcd_resume_root_hub(hcd); 797 usb_hcd_resume_root_hub(hcd);
792 798
799 /* get per-port change detect bits */
800 if (ehci->has_ppcd)
801 ppcd = status >> 16;
802
793 while (i--) { 803 while (i--) {
794 int pstatus = ehci_readl(ehci, 804 int pstatus;
795 &ehci->regs->port_status [i]); 805
806 /* leverage per-port change bits feature */
807 if (ehci->has_ppcd && !(ppcd & (1 << i)))
808 continue;
809 pstatus = ehci_readl(ehci,
810 &ehci->regs->port_status[i]);
796 811
797 if (pstatus & PORT_OWNER) 812 if (pstatus & PORT_OWNER)
798 continue; 813 continue;
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 8a28dae8a375..84e792d71c22 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -603,6 +603,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
603 u32 mask; 603 u32 mask;
604 int ports, i, retval = 1; 604 int ports, i, retval = 1;
605 unsigned long flags; 605 unsigned long flags;
606 u32 ppcd = 0;
606 607
607 /* if !USB_SUSPEND, root hub timers won't get shut down ... */ 608 /* if !USB_SUSPEND, root hub timers won't get shut down ... */
608 if (!HC_IS_RUNNING(hcd->state)) 609 if (!HC_IS_RUNNING(hcd->state))
@@ -632,7 +633,15 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
632 633
633 /* port N changes (bit N)? */ 634 /* port N changes (bit N)? */
634 spin_lock_irqsave (&ehci->lock, flags); 635 spin_lock_irqsave (&ehci->lock, flags);
636
637 /* get per-port change detect bits */
638 if (ehci->has_ppcd)
639 ppcd = ehci_readl(ehci, &ehci->regs->status) >> 16;
640
635 for (i = 0; i < ports; i++) { 641 for (i = 0; i < ports; i++) {
642 /* leverage per-port change bits feature */
643 if (ehci->has_ppcd && !(ppcd & (1 << i)))
644 continue;
636 temp = ehci_readl(ehci, &ehci->regs->port_status [i]); 645 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
637 646
638 /* 647 /*
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 21f30a0c3d2f..e6c57cc416f6 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -141,6 +141,7 @@ struct ehci_hcd { /* one per controller */
141 __hc32 *ohci_hcctrl_reg; 141 __hc32 *ohci_hcctrl_reg;
142 unsigned has_hostpc:1; 142 unsigned has_hostpc:1;
143 unsigned has_lpm:1; /* support link power management */ 143 unsigned has_lpm:1; /* support link power management */
144 unsigned has_ppcd:1; /* support per-port change bits */
144 u8 sbrn; /* packed release number */ 145 u8 sbrn; /* packed release number */
145 146
146 /* irq statistics */ 147 /* irq statistics */