aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ehci-hcd.c10
-rw-r--r--drivers/usb/host/ehci-hub.c18
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;
126module_param (park, uint, S_IRUGO); 126module_param (park, uint, S_IRUGO);
127MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); 127MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
128 128
129/* for flakey hardware, ignore overcurrent indicators */
130static int ignore_oc = 0;
131module_param (ignore_oc, bool, S_IRUGO);
132MODULE_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!! */