diff options
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 7c170a29f959..0a56dfa2745d 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -218,6 +218,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
218 | { | 218 | { |
219 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 219 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
220 | u32 temp, status = 0; | 220 | u32 temp, status = 0; |
221 | u32 mask; | ||
221 | int ports, i, retval = 1; | 222 | int ports, i, retval = 1; |
222 | unsigned long flags; | 223 | unsigned long flags; |
223 | 224 | ||
@@ -233,6 +234,18 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
233 | retval++; | 234 | retval++; |
234 | } | 235 | } |
235 | 236 | ||
237 | /* Some boards (mostly VIA?) report bogus overcurrent indications, | ||
238 | * causing massive log spam unless we completely ignore them. It | ||
239 | * may be relevant that VIA VT8235 controlers, where PORT_POWER is | ||
240 | * always set, seem to clear PORT_OCC and PORT_CSC when writing to | ||
241 | * PORT_POWER; that's surprising, but maybe within-spec. | ||
242 | */ | ||
243 | if (!ignore_oc) | ||
244 | mask = PORT_CSC | PORT_PEC | PORT_OCC; | ||
245 | else | ||
246 | mask = PORT_CSC | PORT_PEC; | ||
247 | // PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND | ||
248 | |||
236 | /* no hub change reports (bit 0) for now (power, ...) */ | 249 | /* no hub change reports (bit 0) for now (power, ...) */ |
237 | 250 | ||
238 | /* port N changes (bit N)? */ | 251 | /* port N changes (bit N)? */ |
@@ -250,8 +263,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
250 | } | 263 | } |
251 | if (!(temp & PORT_CONNECT)) | 264 | if (!(temp & PORT_CONNECT)) |
252 | ehci->reset_done [i] = 0; | 265 | ehci->reset_done [i] = 0; |
253 | if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0 | 266 | if ((temp & mask) != 0 |
254 | // PORT_STAT_C_SUSPEND? | ||
255 | || ((temp & PORT_RESUME) != 0 | 267 | || ((temp & PORT_RESUME) != 0 |
256 | && time_after (jiffies, | 268 | && time_after (jiffies, |
257 | ehci->reset_done [i]))) { | 269 | ehci->reset_done [i]))) { |
@@ -418,7 +430,7 @@ static int ehci_hub_control ( | |||
418 | status |= 1 << USB_PORT_FEAT_C_CONNECTION; | 430 | status |= 1 << USB_PORT_FEAT_C_CONNECTION; |
419 | if (temp & PORT_PEC) | 431 | if (temp & PORT_PEC) |
420 | status |= 1 << USB_PORT_FEAT_C_ENABLE; | 432 | status |= 1 << USB_PORT_FEAT_C_ENABLE; |
421 | if (temp & PORT_OCC) | 433 | if ((temp & PORT_OCC) && !ignore_oc) |
422 | status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; | 434 | status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; |
423 | 435 | ||
424 | /* whoever resumes must GetPortStatus to complete it!! */ | 436 | /* whoever resumes must GetPortStatus to complete it!! */ |