diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/usb/early/ehci-dbgp.c | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 7deae97fe50f..6198ebded3a4 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
| @@ -9,6 +9,12 @@ | |||
| 9 | #include <asm/pci-direct.h> | 9 | #include <asm/pci-direct.h> |
| 10 | #include <asm/fixmap.h> | 10 | #include <asm/fixmap.h> |
| 11 | 11 | ||
| 12 | #ifdef DBGP_DEBUG | ||
| 13 | # define dbgp_printk printk | ||
| 14 | #else | ||
| 15 | static inline void dbgp_printk(const char *fmt, ...) { } | ||
| 16 | #endif | ||
| 17 | |||
| 12 | static struct ehci_caps __iomem *ehci_caps; | 18 | static struct ehci_caps __iomem *ehci_caps; |
| 13 | static struct ehci_regs __iomem *ehci_regs; | 19 | static struct ehci_regs __iomem *ehci_regs; |
| 14 | static struct ehci_dbg_port __iomem *ehci_debug; | 20 | static struct ehci_dbg_port __iomem *ehci_debug; |
| @@ -342,6 +348,7 @@ static int __init ehci_reset_port(int port) | |||
| 342 | u32 delay_time, delay; | 348 | u32 delay_time, delay; |
| 343 | int loop; | 349 | int loop; |
| 344 | 350 | ||
| 351 | dbgp_printk("ehci_reset_port %i\n", port); | ||
| 345 | /* Reset the usb debug port */ | 352 | /* Reset the usb debug port */ |
| 346 | portsc = readl(&ehci_regs->port_status[port - 1]); | 353 | portsc = readl(&ehci_regs->port_status[port - 1]); |
| 347 | portsc &= ~PORT_PE; | 354 | portsc &= ~PORT_PE; |
| @@ -352,14 +359,17 @@ static int __init ehci_reset_port(int port) | |||
| 352 | for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT; | 359 | for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT; |
| 353 | delay_time += delay) { | 360 | delay_time += delay) { |
| 354 | dbgp_mdelay(delay); | 361 | dbgp_mdelay(delay); |
| 355 | |||
| 356 | portsc = readl(&ehci_regs->port_status[port - 1]); | 362 | portsc = readl(&ehci_regs->port_status[port - 1]); |
| 363 | if (!(portsc & PORT_RESET)) | ||
| 364 | break; | ||
| 365 | } | ||
| 357 | if (portsc & PORT_RESET) { | 366 | if (portsc & PORT_RESET) { |
| 358 | /* force reset to complete */ | 367 | /* force reset to complete */ |
| 359 | loop = 2; | 368 | loop = 100 * 1000; |
| 360 | writel(portsc & ~(PORT_RWC_BITS | PORT_RESET), | 369 | writel(portsc & ~(PORT_RWC_BITS | PORT_RESET), |
| 361 | &ehci_regs->port_status[port - 1]); | 370 | &ehci_regs->port_status[port - 1]); |
| 362 | do { | 371 | do { |
| 372 | udelay(1); | ||
| 363 | portsc = readl(&ehci_regs->port_status[port-1]); | 373 | portsc = readl(&ehci_regs->port_status[port-1]); |
| 364 | } while ((portsc & PORT_RESET) && (--loop > 0)); | 374 | } while ((portsc & PORT_RESET) && (--loop > 0)); |
| 365 | } | 375 | } |
| @@ -375,7 +385,6 @@ static int __init ehci_reset_port(int port) | |||
| 375 | /* If we've finished resetting, then break out of the loop */ | 385 | /* If we've finished resetting, then break out of the loop */ |
| 376 | if (!(portsc & PORT_RESET) && (portsc & PORT_PE)) | 386 | if (!(portsc & PORT_RESET) && (portsc & PORT_PE)) |
| 377 | return 0; | 387 | return 0; |
| 378 | } | ||
| 379 | return -EBUSY; | 388 | return -EBUSY; |
| 380 | } | 389 | } |
| 381 | 390 | ||
| @@ -384,24 +393,18 @@ static int __init ehci_wait_for_port(int port) | |||
| 384 | u32 status; | 393 | u32 status; |
| 385 | int ret, reps; | 394 | int ret, reps; |
| 386 | 395 | ||
| 387 | for (reps = 0; reps < 3; reps++) { | 396 | for (reps = 0; reps < 300; reps++) { |
| 388 | dbgp_mdelay(100); | ||
| 389 | status = readl(&ehci_regs->status); | 397 | status = readl(&ehci_regs->status); |
| 390 | if (status & STS_PCD) { | 398 | if (status & STS_PCD) |
| 391 | ret = ehci_reset_port(port); | 399 | break; |
| 392 | if (ret == 0) | 400 | dbgp_mdelay(1); |
| 393 | return 0; | ||
| 394 | } | ||
| 395 | } | 401 | } |
| 402 | ret = ehci_reset_port(port); | ||
| 403 | if (ret == 0) | ||
| 404 | return 0; | ||
| 396 | return -ENOTCONN; | 405 | return -ENOTCONN; |
| 397 | } | 406 | } |
| 398 | 407 | ||
| 399 | #ifdef DBGP_DEBUG | ||
| 400 | # define dbgp_printk early_printk | ||
| 401 | #else | ||
| 402 | static inline void dbgp_printk(const char *fmt, ...) { } | ||
| 403 | #endif | ||
| 404 | |||
| 405 | typedef void (*set_debug_port_t)(int port); | 408 | typedef void (*set_debug_port_t)(int port); |
| 406 | 409 | ||
| 407 | static void __init default_set_debug_port(int port) | 410 | static void __init default_set_debug_port(int port) |
| @@ -520,7 +523,7 @@ try_next_port: | |||
| 520 | return -1; | 523 | return -1; |
| 521 | } | 524 | } |
| 522 | 525 | ||
| 523 | loop = 100000; | 526 | loop = 250 * 1000; |
| 524 | /* Reset the EHCI controller */ | 527 | /* Reset the EHCI controller */ |
| 525 | cmd = readl(&ehci_regs->command); | 528 | cmd = readl(&ehci_regs->command); |
| 526 | cmd |= CMD_RESET; | 529 | cmd |= CMD_RESET; |
| @@ -540,6 +543,7 @@ try_next_port: | |||
| 540 | ctrl |= DBGP_OWNER; | 543 | ctrl |= DBGP_OWNER; |
| 541 | ctrl &= ~(DBGP_ENABLED | DBGP_INUSE); | 544 | ctrl &= ~(DBGP_ENABLED | DBGP_INUSE); |
| 542 | writel(ctrl, &ehci_debug->control); | 545 | writel(ctrl, &ehci_debug->control); |
| 546 | udelay(1); | ||
| 543 | 547 | ||
| 544 | /* Start the ehci running */ | 548 | /* Start the ehci running */ |
| 545 | cmd = readl(&ehci_regs->command); | 549 | cmd = readl(&ehci_regs->command); |
| @@ -554,10 +558,13 @@ try_next_port: | |||
| 554 | loop = 10; | 558 | loop = 10; |
| 555 | do { | 559 | do { |
| 556 | status = readl(&ehci_regs->status); | 560 | status = readl(&ehci_regs->status); |
| 557 | } while ((status & STS_HALT) && (--loop > 0)); | 561 | if (!(status & STS_HALT)) |
| 562 | break; | ||
| 563 | udelay(1); | ||
| 564 | } while (--loop > 0); | ||
| 558 | 565 | ||
| 559 | if (!loop) { | 566 | if (!loop) { |
| 560 | dbgp_printk("ehci can be started\n"); | 567 | dbgp_printk("ehci can not be started\n"); |
| 561 | return -1; | 568 | return -1; |
| 562 | } | 569 | } |
| 563 | dbgp_printk("ehci started\n"); | 570 | dbgp_printk("ehci started\n"); |
