aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r--drivers/usb/host/ehci-hub.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 8a515f0d5988..d05ea03cfb4d 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -106,6 +106,27 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
106 ehci->owned_ports = 0; 106 ehci->owned_ports = 0;
107} 107}
108 108
109static int ehci_port_change(struct ehci_hcd *ehci)
110{
111 int i = HCS_N_PORTS(ehci->hcs_params);
112
113 /* First check if the controller indicates a change event */
114
115 if (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)
116 return 1;
117
118 /*
119 * Not all controllers appear to update this while going from D3 to D0,
120 * so check the individual port status registers as well
121 */
122
123 while (i--)
124 if (ehci_readl(ehci, &ehci->regs->port_status[i]) & PORT_CSC)
125 return 1;
126
127 return 0;
128}
129
109static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, 130static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
110 bool suspending, bool do_wakeup) 131 bool suspending, bool do_wakeup)
111{ 132{
@@ -173,7 +194,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
173 } 194 }
174 195
175 /* Does the root hub have a port wakeup pending? */ 196 /* Does the root hub have a port wakeup pending? */
176 if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)) 197 if (!suspending && ehci_port_change(ehci))
177 usb_hcd_resume_root_hub(ehci_to_hcd(ehci)); 198 usb_hcd_resume_root_hub(ehci_to_hcd(ehci));
178 199
179 spin_unlock_irqrestore(&ehci->lock, flags); 200 spin_unlock_irqrestore(&ehci->lock, flags);
@@ -538,14 +559,15 @@ static ssize_t store_companion(struct device *dev,
538} 559}
539static DEVICE_ATTR(companion, 0644, show_companion, store_companion); 560static DEVICE_ATTR(companion, 0644, show_companion, store_companion);
540 561
541static inline void create_companion_file(struct ehci_hcd *ehci) 562static inline int create_companion_file(struct ehci_hcd *ehci)
542{ 563{
543 int i; 564 int i = 0;
544 565
545 /* with integrated TT there is no companion! */ 566 /* with integrated TT there is no companion! */
546 if (!ehci_is_TDI(ehci)) 567 if (!ehci_is_TDI(ehci))
547 i = device_create_file(ehci_to_hcd(ehci)->self.controller, 568 i = device_create_file(ehci_to_hcd(ehci)->self.controller,
548 &dev_attr_companion); 569 &dev_attr_companion);
570 return i;
549} 571}
550 572
551static inline void remove_companion_file(struct ehci_hcd *ehci) 573static inline void remove_companion_file(struct ehci_hcd *ehci)
@@ -695,8 +717,8 @@ ehci_hub_descriptor (
695 desc->bDescLength = 7 + 2 * temp; 717 desc->bDescLength = 7 + 2 * temp;
696 718
697 /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ 719 /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
698 memset (&desc->bitmap [0], 0, temp); 720 memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
699 memset (&desc->bitmap [temp], 0xff, temp); 721 memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
700 722
701 temp = 0x0008; /* per-port overcurrent reporting */ 723 temp = 0x0008; /* per-port overcurrent reporting */
702 if (HCS_PPC (ehci->hcs_params)) 724 if (HCS_PPC (ehci->hcs_params))