diff options
-rw-r--r-- | drivers/usb/host/ohci-dbg.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 22 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pxa27x.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/ohci.h | 1 |
5 files changed, 25 insertions, 20 deletions
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 447f488f5d93..7924c74f958e 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -228,23 +228,22 @@ ohci_dump_roothub ( | |||
228 | char **next, | 228 | char **next, |
229 | unsigned *size) | 229 | unsigned *size) |
230 | { | 230 | { |
231 | u32 temp, ndp, i; | 231 | u32 temp, i; |
232 | 232 | ||
233 | temp = roothub_a (controller); | 233 | temp = roothub_a (controller); |
234 | if (temp == ~(u32)0) | 234 | if (temp == ~(u32)0) |
235 | return; | 235 | return; |
236 | ndp = (temp & RH_A_NDP); | ||
237 | 236 | ||
238 | if (verbose) { | 237 | if (verbose) { |
239 | ohci_dbg_sw (controller, next, size, | 238 | ohci_dbg_sw (controller, next, size, |
240 | "roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d\n", temp, | 239 | "roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d(%d)\n", temp, |
241 | ((temp & RH_A_POTPGT) >> 24) & 0xff, | 240 | ((temp & RH_A_POTPGT) >> 24) & 0xff, |
242 | (temp & RH_A_NOCP) ? " NOCP" : "", | 241 | (temp & RH_A_NOCP) ? " NOCP" : "", |
243 | (temp & RH_A_OCPM) ? " OCPM" : "", | 242 | (temp & RH_A_OCPM) ? " OCPM" : "", |
244 | (temp & RH_A_DT) ? " DT" : "", | 243 | (temp & RH_A_DT) ? " DT" : "", |
245 | (temp & RH_A_NPS) ? " NPS" : "", | 244 | (temp & RH_A_NPS) ? " NPS" : "", |
246 | (temp & RH_A_PSM) ? " PSM" : "", | 245 | (temp & RH_A_PSM) ? " PSM" : "", |
247 | ndp | 246 | (temp & RH_A_NDP), controller->num_ports |
248 | ); | 247 | ); |
249 | temp = roothub_b (controller); | 248 | temp = roothub_b (controller); |
250 | ohci_dbg_sw (controller, next, size, | 249 | ohci_dbg_sw (controller, next, size, |
@@ -266,7 +265,7 @@ ohci_dump_roothub ( | |||
266 | ); | 265 | ); |
267 | } | 266 | } |
268 | 267 | ||
269 | for (i = 0; i < ndp; i++) { | 268 | for (i = 0; i < controller->num_ports; i++) { |
270 | temp = roothub_portstatus (controller, i); | 269 | temp = roothub_portstatus (controller, i); |
271 | dbg_port_sw (controller, i, temp, next, size); | 270 | dbg_port_sw (controller, i, temp, next, size); |
272 | } | 271 | } |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 6efb69f7c075..67c1aa5eb1c1 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -484,6 +484,10 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
484 | // flush the writes | 484 | // flush the writes |
485 | (void) ohci_readl (ohci, &ohci->regs->control); | 485 | (void) ohci_readl (ohci, &ohci->regs->control); |
486 | 486 | ||
487 | /* Read the number of ports unless overridden */ | ||
488 | if (ohci->num_ports == 0) | ||
489 | ohci->num_ports = roothub_a(ohci) & RH_A_NDP; | ||
490 | |||
487 | if (ohci->hcca) | 491 | if (ohci->hcca) |
488 | return 0; | 492 | return 0; |
489 | 493 | ||
@@ -560,10 +564,8 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
560 | msleep(temp); | 564 | msleep(temp); |
561 | temp = roothub_a (ohci); | 565 | temp = roothub_a (ohci); |
562 | if (!(temp & RH_A_NPS)) { | 566 | if (!(temp & RH_A_NPS)) { |
563 | unsigned ports = temp & RH_A_NDP; | ||
564 | |||
565 | /* power down each port */ | 567 | /* power down each port */ |
566 | for (temp = 0; temp < ports; temp++) | 568 | for (temp = 0; temp < ohci->num_ports; temp++) |
567 | ohci_writel (ohci, RH_PS_LSDA, | 569 | ohci_writel (ohci, RH_PS_LSDA, |
568 | &ohci->regs->roothub.portstatus [temp]); | 570 | &ohci->regs->roothub.portstatus [temp]); |
569 | } | 571 | } |
@@ -861,7 +863,7 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
861 | * and that if we try to turn them back on the root hub | 863 | * and that if we try to turn them back on the root hub |
862 | * will respond to CSC processing. | 864 | * will respond to CSC processing. |
863 | */ | 865 | */ |
864 | i = roothub_a (ohci) & RH_A_NDP; | 866 | i = ohci->num_ports; |
865 | while (i--) | 867 | while (i--) |
866 | ohci_writel (ohci, RH_PS_PSS, | 868 | ohci_writel (ohci, RH_PS_PSS, |
867 | &ohci->regs->roothub.portstatus [temp]); | 869 | &ohci->regs->roothub.portstatus [temp]); |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 83ca4549a50e..ce7b28da7a15 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -184,7 +184,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
184 | if (status != -EINPROGRESS) | 184 | if (status != -EINPROGRESS) |
185 | return status; | 185 | return status; |
186 | 186 | ||
187 | temp = roothub_a (ohci) & RH_A_NDP; | 187 | temp = ohci->num_ports; |
188 | enables = 0; | 188 | enables = 0; |
189 | while (temp--) { | 189 | while (temp--) { |
190 | u32 stat = ohci_readl (ohci, | 190 | u32 stat = ohci_readl (ohci, |
@@ -304,7 +304,7 @@ static int | |||
304 | ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | 304 | ohci_hub_status_data (struct usb_hcd *hcd, char *buf) |
305 | { | 305 | { |
306 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 306 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
307 | int ports, i, changed = 0, length = 1; | 307 | int i, changed = 0, length = 1; |
308 | int can_suspend = hcd->can_wakeup; | 308 | int can_suspend = hcd->can_wakeup; |
309 | unsigned long flags; | 309 | unsigned long flags; |
310 | 310 | ||
@@ -319,9 +319,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
319 | goto done; | 319 | goto done; |
320 | } | 320 | } |
321 | 321 | ||
322 | ports = roothub_a (ohci) & RH_A_NDP; | 322 | /* undocumented erratum seen on at least rev D */ |
323 | if (ports > MAX_ROOT_PORTS) { | 323 | if ((ohci->flags & OHCI_QUIRK_AMD756) |
324 | ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n", ports, | 324 | && (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) { |
325 | ohci_warn (ohci, "bogus NDP, rereads as NDP=%d\n", | ||
325 | ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP); | 326 | ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP); |
326 | /* retry later; "should not happen" */ | 327 | /* retry later; "should not happen" */ |
327 | goto done; | 328 | goto done; |
@@ -332,13 +333,13 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
332 | buf [0] = changed = 1; | 333 | buf [0] = changed = 1; |
333 | else | 334 | else |
334 | buf [0] = 0; | 335 | buf [0] = 0; |
335 | if (ports > 7) { | 336 | if (ohci->num_ports > 7) { |
336 | buf [1] = 0; | 337 | buf [1] = 0; |
337 | length++; | 338 | length++; |
338 | } | 339 | } |
339 | 340 | ||
340 | /* look at each port */ | 341 | /* look at each port */ |
341 | for (i = 0; i < ports; i++) { | 342 | for (i = 0; i < ohci->num_ports; i++) { |
342 | u32 status = roothub_portstatus (ohci, i); | 343 | u32 status = roothub_portstatus (ohci, i); |
343 | 344 | ||
344 | if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | 345 | if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC |
@@ -395,15 +396,14 @@ ohci_hub_descriptor ( | |||
395 | struct usb_hub_descriptor *desc | 396 | struct usb_hub_descriptor *desc |
396 | ) { | 397 | ) { |
397 | u32 rh = roothub_a (ohci); | 398 | u32 rh = roothub_a (ohci); |
398 | int ports = rh & RH_A_NDP; | ||
399 | u16 temp; | 399 | u16 temp; |
400 | 400 | ||
401 | desc->bDescriptorType = 0x29; | 401 | desc->bDescriptorType = 0x29; |
402 | desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24; | 402 | desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24; |
403 | desc->bHubContrCurrent = 0; | 403 | desc->bHubContrCurrent = 0; |
404 | 404 | ||
405 | desc->bNbrPorts = ports; | 405 | desc->bNbrPorts = ohci->num_ports; |
406 | temp = 1 + (ports / 8); | 406 | temp = 1 + (ohci->num_ports / 8); |
407 | desc->bDescLength = 7 + 2 * temp; | 407 | desc->bDescLength = 7 + 2 * temp; |
408 | 408 | ||
409 | temp = 0; | 409 | temp = 0; |
@@ -421,7 +421,7 @@ ohci_hub_descriptor ( | |||
421 | rh = roothub_b (ohci); | 421 | rh = roothub_b (ohci); |
422 | memset(desc->bitmap, 0xff, sizeof(desc->bitmap)); | 422 | memset(desc->bitmap, 0xff, sizeof(desc->bitmap)); |
423 | desc->bitmap [0] = rh & RH_B_DR; | 423 | desc->bitmap [0] = rh & RH_B_DR; |
424 | if (ports > 7) { | 424 | if (ohci->num_ports > 7) { |
425 | desc->bitmap [1] = (rh & RH_B_DR) >> 8; | 425 | desc->bitmap [1] = (rh & RH_B_DR) >> 8; |
426 | desc->bitmap [2] = 0xff; | 426 | desc->bitmap [2] = 0xff; |
427 | } else | 427 | } else |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e5bc1789d18a..5dd20dbe852d 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -258,6 +258,9 @@ ohci_pxa27x_start (struct usb_hcd *hcd) | |||
258 | 258 | ||
259 | ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci); | 259 | ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci); |
260 | 260 | ||
261 | /* The value of NDP in roothub_a is incorrect on this hardware */ | ||
262 | ohci->num_ports = 3; | ||
263 | |||
261 | if ((ret = ohci_init(ohci)) < 0) | 264 | if ((ret = ohci_init(ohci)) < 0) |
262 | return ret; | 265 | return ret; |
263 | 266 | ||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 71cdd2262860..8a9b9d9209e9 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -383,6 +383,7 @@ struct ohci_hcd { | |||
383 | /* | 383 | /* |
384 | * driver state | 384 | * driver state |
385 | */ | 385 | */ |
386 | int num_ports; | ||
386 | int load [NUM_INTS]; | 387 | int load [NUM_INTS]; |
387 | u32 hc_control; /* copy of hc control reg */ | 388 | u32 hc_control; /* copy of hc control reg */ |
388 | unsigned long next_statechange; /* suspend/resume */ | 389 | unsigned long next_statechange; /* suspend/resume */ |