diff options
author | David Brownell <david-b@pacbell.net> | 2005-08-31 14:52:57 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-09-12 15:23:46 -0400 |
commit | fdd13b36c4a501d8787a27e54635fbd943f2685d (patch) | |
tree | eebcc2fc677b5b625235e2e0797b5f9ab6d74905 /drivers/usb/host/ohci-hub.c | |
parent | e0fd3cbc50a8c925e8e7d8448df689015362c458 (diff) |
[PATCH] USB: OHCI relies less on NDP register
Some OHCI implementations have differences in the way the NDP register
(in roothub_a) reports the number of ports present. This patch allows the
platform specific code to optionally supply the number of ports. The
driver just reads the value at init (if not supplied) instead of reading
it every time its needed (except for an AMD756 bug workaround).
It also sets the value correctly for the ARM pxa27x architecture.
Signed-Off-By: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ohci-hub.c')
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 22 |
1 files changed, 11 insertions, 11 deletions
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 |