diff options
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 32 |
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 | ||
109 | static 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 | |||
109 | static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, | 130 | static 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 | } |
539 | static DEVICE_ATTR(companion, 0644, show_companion, store_companion); | 560 | static DEVICE_ATTR(companion, 0644, show_companion, store_companion); |
540 | 561 | ||
541 | static inline void create_companion_file(struct ehci_hcd *ehci) | 562 | static 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 | ||
551 | static inline void remove_companion_file(struct ehci_hcd *ehci) | 573 | static 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)) |