aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
authorAlek Du <alek.du@intel.com>2010-06-04 03:47:56 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:35 -0400
commit5a9cdf332eae724b11906cb1712e3a662eba32b2 (patch)
tree67aad1a4e795b2b26e4e320305accba16c4d201e /drivers/usb/host/ehci-hcd.c
parent48f24970144479c29b8cee6d2e1dbedf6dcf9cfb (diff)
USB: EHCI: EHCI 1.1 addendum: Enable Per-port change detect bits
This patch will enable Per-port event feature defined in EHCI 1.1 addendum. This feature addresses an issue where HCD is currently required to read and parse PORTSC for all enabled root hub ports. With this patch, the overhead will be reduced. Signed-off-by: Alek Du <alek.du@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index baf9b648bb1..8697ad19f31 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;