diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 18 |
2 files changed, 23 insertions, 5 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 9030994aba98..f2ceb5fdbeb7 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -126,6 +126,11 @@ static unsigned park = 0; | |||
126 | module_param (park, uint, S_IRUGO); | 126 | module_param (park, uint, S_IRUGO); |
127 | MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); | 127 | MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); |
128 | 128 | ||
129 | /* for flakey hardware, ignore overcurrent indicators */ | ||
130 | static int ignore_oc = 0; | ||
131 | module_param (ignore_oc, bool, S_IRUGO); | ||
132 | MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); | ||
133 | |||
129 | #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) | 134 | #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) |
130 | 135 | ||
131 | /*-------------------------------------------------------------------------*/ | 136 | /*-------------------------------------------------------------------------*/ |
@@ -541,9 +546,10 @@ static int ehci_run (struct usb_hcd *hcd) | |||
541 | 546 | ||
542 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 547 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); |
543 | ehci_info (ehci, | 548 | ehci_info (ehci, |
544 | "USB %x.%x started, EHCI %x.%02x, driver %s\n", | 549 | "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", |
545 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), | 550 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), |
546 | temp >> 8, temp & 0xff, DRIVER_VERSION); | 551 | temp >> 8, temp & 0xff, DRIVER_VERSION, |
552 | ignore_oc ? ", overcurrent ignored" : ""); | ||
547 | 553 | ||
548 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ | 554 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ |
549 | 555 | ||
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!! */ |