diff options
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
| -rw-r--r-- | drivers/usb/host/ehci-hub.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 36cc1f2218d5..18d3f2270316 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
| @@ -54,7 +54,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd) | |||
| 54 | /* suspend any active/unsuspended ports, maybe allow wakeup */ | 54 | /* suspend any active/unsuspended ports, maybe allow wakeup */ |
| 55 | while (port--) { | 55 | while (port--) { |
| 56 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 56 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
| 57 | u32 t1 = readl (reg); | 57 | u32 t1 = readl (reg) & ~PORT_RWC_BITS; |
| 58 | u32 t2 = t1; | 58 | u32 t2 = t1; |
| 59 | 59 | ||
| 60 | if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) | 60 | if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) |
| @@ -115,7 +115,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd) | |||
| 115 | i = HCS_N_PORTS (ehci->hcs_params); | 115 | i = HCS_N_PORTS (ehci->hcs_params); |
| 116 | while (i--) { | 116 | while (i--) { |
| 117 | temp = readl (&ehci->regs->port_status [i]); | 117 | temp = readl (&ehci->regs->port_status [i]); |
| 118 | temp &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); | 118 | temp &= ~(PORT_RWC_BITS |
| 119 | | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); | ||
| 119 | if (temp & PORT_SUSPEND) { | 120 | if (temp & PORT_SUSPEND) { |
| 120 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); | 121 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); |
| 121 | temp |= PORT_RESUME; | 122 | temp |= PORT_RESUME; |
| @@ -128,7 +129,7 @@ static int ehci_hub_resume (struct usb_hcd *hcd) | |||
| 128 | temp = readl (&ehci->regs->port_status [i]); | 129 | temp = readl (&ehci->regs->port_status [i]); |
| 129 | if ((temp & PORT_SUSPEND) == 0) | 130 | if ((temp & PORT_SUSPEND) == 0) |
| 130 | continue; | 131 | continue; |
| 131 | temp &= ~PORT_RESUME; | 132 | temp &= ~(PORT_RWC_BITS | PORT_RESUME); |
| 132 | writel (temp, &ehci->regs->port_status [i]); | 133 | writel (temp, &ehci->regs->port_status [i]); |
| 133 | ehci_vdbg (ehci, "resumed port %d\n", i + 1); | 134 | ehci_vdbg (ehci, "resumed port %d\n", i + 1); |
| 134 | } | 135 | } |
| @@ -191,6 +192,7 @@ static int check_reset_complete ( | |||
| 191 | 192 | ||
| 192 | // what happens if HCS_N_CC(params) == 0 ? | 193 | // what happens if HCS_N_CC(params) == 0 ? |
| 193 | port_status |= PORT_OWNER; | 194 | port_status |= PORT_OWNER; |
| 195 | port_status &= ~PORT_RWC_BITS; | ||
| 194 | writel (port_status, &ehci->regs->port_status [index]); | 196 | writel (port_status, &ehci->regs->port_status [index]); |
| 195 | 197 | ||
| 196 | } else | 198 | } else |
| @@ -233,7 +235,8 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
| 233 | if (temp & PORT_OWNER) { | 235 | if (temp & PORT_OWNER) { |
| 234 | /* don't report this in GetPortStatus */ | 236 | /* don't report this in GetPortStatus */ |
| 235 | if (temp & PORT_CSC) { | 237 | if (temp & PORT_CSC) { |
| 236 | temp &= ~PORT_CSC; | 238 | temp &= ~PORT_RWC_BITS; |
| 239 | temp |= PORT_CSC; | ||
| 237 | writel (temp, &ehci->regs->port_status [i]); | 240 | writel (temp, &ehci->regs->port_status [i]); |
| 238 | } | 241 | } |
| 239 | continue; | 242 | continue; |
| @@ -343,7 +346,7 @@ static int ehci_hub_control ( | |||
| 343 | &ehci->regs->port_status [wIndex]); | 346 | &ehci->regs->port_status [wIndex]); |
| 344 | break; | 347 | break; |
| 345 | case USB_PORT_FEAT_C_ENABLE: | 348 | case USB_PORT_FEAT_C_ENABLE: |
| 346 | writel (temp | PORT_PEC, | 349 | writel((temp & ~PORT_RWC_BITS) | PORT_PEC, |
| 347 | &ehci->regs->port_status [wIndex]); | 350 | &ehci->regs->port_status [wIndex]); |
| 348 | break; | 351 | break; |
| 349 | case USB_PORT_FEAT_SUSPEND: | 352 | case USB_PORT_FEAT_SUSPEND: |
| @@ -353,7 +356,8 @@ static int ehci_hub_control ( | |||
| 353 | if ((temp & PORT_PE) == 0) | 356 | if ((temp & PORT_PE) == 0) |
| 354 | goto error; | 357 | goto error; |
| 355 | /* resume signaling for 20 msec */ | 358 | /* resume signaling for 20 msec */ |
| 356 | writel ((temp & ~PORT_WAKE_BITS) | PORT_RESUME, | 359 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); |
| 360 | writel (temp | PORT_RESUME, | ||
| 357 | &ehci->regs->port_status [wIndex]); | 361 | &ehci->regs->port_status [wIndex]); |
| 358 | ehci->reset_done [wIndex] = jiffies | 362 | ehci->reset_done [wIndex] = jiffies |
| 359 | + msecs_to_jiffies (20); | 363 | + msecs_to_jiffies (20); |
| @@ -364,15 +368,15 @@ static int ehci_hub_control ( | |||
| 364 | break; | 368 | break; |
| 365 | case USB_PORT_FEAT_POWER: | 369 | case USB_PORT_FEAT_POWER: |
| 366 | if (HCS_PPC (ehci->hcs_params)) | 370 | if (HCS_PPC (ehci->hcs_params)) |
| 367 | writel (temp & ~PORT_POWER, | 371 | writel (temp & ~(PORT_RWC_BITS | PORT_POWER), |
| 368 | &ehci->regs->port_status [wIndex]); | 372 | &ehci->regs->port_status [wIndex]); |
| 369 | break; | 373 | break; |
| 370 | case USB_PORT_FEAT_C_CONNECTION: | 374 | case USB_PORT_FEAT_C_CONNECTION: |
| 371 | writel (temp | PORT_CSC, | 375 | writel((temp & ~PORT_RWC_BITS) | PORT_CSC, |
| 372 | &ehci->regs->port_status [wIndex]); | 376 | &ehci->regs->port_status [wIndex]); |
| 373 | break; | 377 | break; |
| 374 | case USB_PORT_FEAT_C_OVER_CURRENT: | 378 | case USB_PORT_FEAT_C_OVER_CURRENT: |
| 375 | writel (temp | PORT_OCC, | 379 | writel((temp & ~PORT_RWC_BITS) | PORT_OCC, |
| 376 | &ehci->regs->port_status [wIndex]); | 380 | &ehci->regs->port_status [wIndex]); |
| 377 | break; | 381 | break; |
| 378 | case USB_PORT_FEAT_C_RESET: | 382 | case USB_PORT_FEAT_C_RESET: |
| @@ -416,7 +420,7 @@ static int ehci_hub_control ( | |||
| 416 | 420 | ||
| 417 | /* stop resume signaling */ | 421 | /* stop resume signaling */ |
| 418 | temp = readl (&ehci->regs->port_status [wIndex]); | 422 | temp = readl (&ehci->regs->port_status [wIndex]); |
| 419 | writel (temp & ~PORT_RESUME, | 423 | writel (temp & ~(PORT_RWC_BITS | PORT_RESUME), |
| 420 | &ehci->regs->port_status [wIndex]); | 424 | &ehci->regs->port_status [wIndex]); |
| 421 | retval = handshake ( | 425 | retval = handshake ( |
| 422 | &ehci->regs->port_status [wIndex], | 426 | &ehci->regs->port_status [wIndex], |
| @@ -437,7 +441,7 @@ static int ehci_hub_control ( | |||
| 437 | ehci->reset_done [wIndex] = 0; | 441 | ehci->reset_done [wIndex] = 0; |
| 438 | 442 | ||
| 439 | /* force reset to complete */ | 443 | /* force reset to complete */ |
| 440 | writel (temp & ~PORT_RESET, | 444 | writel (temp & ~(PORT_RWC_BITS | PORT_RESET), |
| 441 | &ehci->regs->port_status [wIndex]); | 445 | &ehci->regs->port_status [wIndex]); |
| 442 | /* REVISIT: some hardware needs 550+ usec to clear | 446 | /* REVISIT: some hardware needs 550+ usec to clear |
| 443 | * this bit; seems too long to spin routinely... | 447 | * this bit; seems too long to spin routinely... |
| @@ -500,6 +504,7 @@ static int ehci_hub_control ( | |||
| 500 | if (temp & PORT_OWNER) | 504 | if (temp & PORT_OWNER) |
| 501 | break; | 505 | break; |
| 502 | 506 | ||
| 507 | temp &= ~PORT_RWC_BITS; | ||
| 503 | switch (wValue) { | 508 | switch (wValue) { |
| 504 | case USB_PORT_FEAT_SUSPEND: | 509 | case USB_PORT_FEAT_SUSPEND: |
| 505 | if ((temp & PORT_PE) == 0 | 510 | if ((temp & PORT_PE) == 0 |
