aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ohci-dbg.c9
-rw-r--r--drivers/usb/host/ohci-hcd.c10
-rw-r--r--drivers/usb/host/ohci-hub.c22
-rw-r--r--drivers/usb/host/ohci-pxa27x.c3
-rw-r--r--drivers/usb/host/ohci.h1
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
304ohci_hub_status_data (struct usb_hcd *hcd, char *buf) 304ohci_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 */