diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-au1xxx.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-dbg.c | 17 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 20 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/ehci-pci.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-q.c | 22 | ||||
-rw-r--r-- | drivers/usb/host/ehci-s5p.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 11 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 7 |
10 files changed, 56 insertions, 41 deletions
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 42ae57409908..4363fea85151 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -293,7 +293,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev) | |||
293 | /* here we "know" root ports should always stay powered */ | 293 | /* here we "know" root ports should always stay powered */ |
294 | ehci_port_power(ehci, 1); | 294 | ehci_port_power(ehci, 1); |
295 | 295 | ||
296 | hcd->state = HC_STATE_SUSPENDED; | 296 | ehci->rh_state = EHCI_RH_SUSPENDED; |
297 | 297 | ||
298 | return 0; | 298 | return 0; |
299 | } | 299 | } |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 40a844c1dbb4..9952505d2357 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -697,6 +697,19 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |||
697 | } | 697 | } |
698 | #undef DBG_SCHED_LIMIT | 698 | #undef DBG_SCHED_LIMIT |
699 | 699 | ||
700 | static const char *rh_state_string(struct ehci_hcd *ehci) | ||
701 | { | ||
702 | switch (ehci->rh_state) { | ||
703 | case EHCI_RH_HALTED: | ||
704 | return "halted"; | ||
705 | case EHCI_RH_SUSPENDED: | ||
706 | return "suspended"; | ||
707 | case EHCI_RH_RUNNING: | ||
708 | return "running"; | ||
709 | } | ||
710 | return "?"; | ||
711 | } | ||
712 | |||
700 | static ssize_t fill_registers_buffer(struct debug_buffer *buf) | 713 | static ssize_t fill_registers_buffer(struct debug_buffer *buf) |
701 | { | 714 | { |
702 | struct usb_hcd *hcd; | 715 | struct usb_hcd *hcd; |
@@ -730,11 +743,11 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) | |||
730 | temp = scnprintf (next, size, | 743 | temp = scnprintf (next, size, |
731 | "bus %s, device %s\n" | 744 | "bus %s, device %s\n" |
732 | "%s\n" | 745 | "%s\n" |
733 | "EHCI %x.%02x, hcd state %d\n", | 746 | "EHCI %x.%02x, rh state %s\n", |
734 | hcd->self.controller->bus->name, | 747 | hcd->self.controller->bus->name, |
735 | dev_name(hcd->self.controller), | 748 | dev_name(hcd->self.controller), |
736 | hcd->product_desc, | 749 | hcd->product_desc, |
737 | i >> 8, i & 0x0ff, hcd->state); | 750 | i >> 8, i & 0x0ff, rh_state_string(ehci)); |
738 | size -= temp; | 751 | size -= temp; |
739 | next += temp; | 752 | next += temp; |
740 | 753 | ||
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 34a3140d1e5f..3bf9f16b4fd8 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -392,7 +392,7 @@ static int ehci_fsl_mpc512x_drv_suspend(struct device *dev) | |||
392 | 392 | ||
393 | dev_dbg(dev, "suspending...\n"); | 393 | dev_dbg(dev, "suspending...\n"); |
394 | 394 | ||
395 | hcd->state = HC_STATE_SUSPENDED; | 395 | ehci->rh_state = EHCI_RH_SUSPENDED; |
396 | dev->power.power_state = PMSG_SUSPEND; | 396 | dev->power.power_state = PMSG_SUSPEND; |
397 | 397 | ||
398 | /* ignore non-host interrupts */ | 398 | /* ignore non-host interrupts */ |
@@ -481,7 +481,7 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev) | |||
481 | ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]); | 481 | ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]); |
482 | 482 | ||
483 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 483 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
484 | hcd->state = HC_STATE_RUNNING; | 484 | ehci->rh_state = EHCI_RH_RUNNING; |
485 | dev->power.power_state = PMSG_ON; | 485 | dev->power.power_state = PMSG_ON; |
486 | 486 | ||
487 | tmp = ehci_readl(ehci, &ehci->regs->command); | 487 | tmp = ehci_readl(ehci, &ehci->regs->command); |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2af3e2a89efc..8696489cde56 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -238,7 +238,7 @@ static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, | |||
238 | error = handshake(ehci, ptr, mask, done, usec); | 238 | error = handshake(ehci, ptr, mask, done, usec); |
239 | if (error) { | 239 | if (error) { |
240 | ehci_halt(ehci); | 240 | ehci_halt(ehci); |
241 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 241 | ehci->rh_state = EHCI_RH_HALTED; |
242 | ehci_err(ehci, "force halt; handshake %p %08x %08x -> %d\n", | 242 | ehci_err(ehci, "force halt; handshake %p %08x %08x -> %d\n", |
243 | ptr, mask, done, error); | 243 | ptr, mask, done, error); |
244 | } | 244 | } |
@@ -278,7 +278,7 @@ static int ehci_reset (struct ehci_hcd *ehci) | |||
278 | command |= CMD_RESET; | 278 | command |= CMD_RESET; |
279 | dbg_cmd (ehci, "reset", command); | 279 | dbg_cmd (ehci, "reset", command); |
280 | ehci_writel(ehci, command, &ehci->regs->command); | 280 | ehci_writel(ehci, command, &ehci->regs->command); |
281 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 281 | ehci->rh_state = EHCI_RH_HALTED; |
282 | ehci->next_statechange = jiffies; | 282 | ehci->next_statechange = jiffies; |
283 | retval = handshake (ehci, &ehci->regs->command, | 283 | retval = handshake (ehci, &ehci->regs->command, |
284 | CMD_RESET, 0, 250 * 1000); | 284 | CMD_RESET, 0, 250 * 1000); |
@@ -307,7 +307,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci) | |||
307 | u32 temp; | 307 | u32 temp; |
308 | 308 | ||
309 | #ifdef DEBUG | 309 | #ifdef DEBUG |
310 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 310 | if (ehci->rh_state != EHCI_RH_RUNNING) |
311 | BUG (); | 311 | BUG (); |
312 | #endif | 312 | #endif |
313 | 313 | ||
@@ -356,7 +356,7 @@ static void ehci_iaa_watchdog(unsigned long param) | |||
356 | */ | 356 | */ |
357 | if (ehci->reclaim | 357 | if (ehci->reclaim |
358 | && !timer_pending(&ehci->iaa_watchdog) | 358 | && !timer_pending(&ehci->iaa_watchdog) |
359 | && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 359 | && ehci->rh_state == EHCI_RH_RUNNING) { |
360 | u32 cmd, status; | 360 | u32 cmd, status; |
361 | 361 | ||
362 | /* If we get here, IAA is *REALLY* late. It's barely | 362 | /* If we get here, IAA is *REALLY* late. It's barely |
@@ -496,7 +496,7 @@ static void ehci_work (struct ehci_hcd *ehci) | |||
496 | * misplace IRQs, and should let us run completely without IRQs. | 496 | * misplace IRQs, and should let us run completely without IRQs. |
497 | * such lossage has been observed on both VT6202 and VT8235. | 497 | * such lossage has been observed on both VT6202 and VT8235. |
498 | */ | 498 | */ |
499 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && | 499 | if (ehci->rh_state == EHCI_RH_RUNNING && |
500 | (ehci->async->qh_next.ptr != NULL || | 500 | (ehci->async->qh_next.ptr != NULL || |
501 | ehci->periodic_sched != 0)) | 501 | ehci->periodic_sched != 0)) |
502 | timer_action (ehci, TIMER_IO_WATCHDOG); | 502 | timer_action (ehci, TIMER_IO_WATCHDOG); |
@@ -516,7 +516,7 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
516 | del_timer_sync(&ehci->iaa_watchdog); | 516 | del_timer_sync(&ehci->iaa_watchdog); |
517 | 517 | ||
518 | spin_lock_irq(&ehci->lock); | 518 | spin_lock_irq(&ehci->lock); |
519 | if (HC_IS_RUNNING (hcd->state)) | 519 | if (ehci->rh_state == EHCI_RH_RUNNING) |
520 | ehci_quiesce (ehci); | 520 | ehci_quiesce (ehci); |
521 | 521 | ||
522 | ehci_silence_controller(ehci); | 522 | ehci_silence_controller(ehci); |
@@ -741,7 +741,7 @@ static int ehci_run (struct usb_hcd *hcd) | |||
741 | * be started before the port switching actions could complete. | 741 | * be started before the port switching actions could complete. |
742 | */ | 742 | */ |
743 | down_write(&ehci_cf_port_reset_rwsem); | 743 | down_write(&ehci_cf_port_reset_rwsem); |
744 | hcd->state = HC_STATE_RUNNING; | 744 | ehci->rh_state = EHCI_RH_RUNNING; |
745 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); | 745 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
746 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ | 746 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
747 | msleep(5); | 747 | msleep(5); |
@@ -788,7 +788,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
788 | 788 | ||
789 | /* Shared IRQ? */ | 789 | /* Shared IRQ? */ |
790 | masked_status = status & INTR_MASK; | 790 | masked_status = status & INTR_MASK; |
791 | if (!masked_status || unlikely(hcd->state == HC_STATE_HALT)) { | 791 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { |
792 | spin_unlock(&ehci->lock); | 792 | spin_unlock(&ehci->lock); |
793 | return IRQ_NONE; | 793 | return IRQ_NONE; |
794 | } | 794 | } |
@@ -952,7 +952,7 @@ static int ehci_urb_enqueue ( | |||
952 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 952 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
953 | { | 953 | { |
954 | /* failfast */ | 954 | /* failfast */ |
955 | if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim) | 955 | if (ehci->rh_state != EHCI_RH_RUNNING && ehci->reclaim) |
956 | end_unlink_async(ehci); | 956 | end_unlink_async(ehci); |
957 | 957 | ||
958 | /* If the QH isn't linked then there's nothing we can do | 958 | /* If the QH isn't linked then there's nothing we can do |
@@ -1079,7 +1079,7 @@ rescan: | |||
1079 | goto idle_timeout; | 1079 | goto idle_timeout; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | if (!HC_IS_RUNNING (hcd->state)) | 1082 | if (ehci->rh_state != EHCI_RH_RUNNING) |
1083 | qh->qh_state = QH_STATE_IDLE; | 1083 | qh->qh_state = QH_STATE_IDLE; |
1084 | switch (qh->qh_state) { | 1084 | switch (qh->qh_state) { |
1085 | case QH_STATE_LINKED: | 1085 | case QH_STATE_LINKED: |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index e051b30c1847..c6104c4f1f38 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -236,10 +236,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
236 | } | 236 | } |
237 | 237 | ||
238 | /* stop schedules, clean any completed work */ | 238 | /* stop schedules, clean any completed work */ |
239 | if (HC_IS_RUNNING(hcd->state)) { | 239 | if (ehci->rh_state == EHCI_RH_RUNNING) |
240 | ehci_quiesce (ehci); | 240 | ehci_quiesce (ehci); |
241 | hcd->state = HC_STATE_QUIESCING; | ||
242 | } | ||
243 | ehci->command = ehci_readl(ehci, &ehci->regs->command); | 241 | ehci->command = ehci_readl(ehci, &ehci->regs->command); |
244 | ehci_work(ehci); | 242 | ehci_work(ehci); |
245 | 243 | ||
@@ -313,7 +311,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
313 | 311 | ||
314 | /* turn off now-idle HC */ | 312 | /* turn off now-idle HC */ |
315 | ehci_halt (ehci); | 313 | ehci_halt (ehci); |
316 | hcd->state = HC_STATE_SUSPENDED; | 314 | ehci->rh_state = EHCI_RH_SUSPENDED; |
317 | 315 | ||
318 | if (ehci->reclaim) | 316 | if (ehci->reclaim) |
319 | end_unlink_async(ehci); | 317 | end_unlink_async(ehci); |
@@ -382,6 +380,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
382 | 380 | ||
383 | /* restore CMD_RUN, framelist size, and irq threshold */ | 381 | /* restore CMD_RUN, framelist size, and irq threshold */ |
384 | ehci_writel(ehci, ehci->command, &ehci->regs->command); | 382 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
383 | ehci->rh_state = EHCI_RH_RUNNING; | ||
385 | 384 | ||
386 | /* Some controller/firmware combinations need a delay during which | 385 | /* Some controller/firmware combinations need a delay during which |
387 | * they set up the port statuses. See Bugzilla #8190. */ | 386 | * they set up the port statuses. See Bugzilla #8190. */ |
@@ -452,7 +451,6 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
452 | } | 451 | } |
453 | 452 | ||
454 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); | 453 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); |
455 | hcd->state = HC_STATE_RUNNING; | ||
456 | 454 | ||
457 | /* Now we can safely re-enable irqs */ | 455 | /* Now we can safely re-enable irqs */ |
458 | ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); | 456 | ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); |
@@ -564,7 +562,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
564 | u32 ppcd = 0; | 562 | u32 ppcd = 0; |
565 | 563 | ||
566 | /* if !USB_SUSPEND, root hub timers won't get shut down ... */ | 564 | /* if !USB_SUSPEND, root hub timers won't get shut down ... */ |
567 | if (!HC_IS_RUNNING(hcd->state)) | 565 | if (ehci->rh_state != EHCI_RH_RUNNING) |
568 | return 0; | 566 | return 0; |
569 | 567 | ||
570 | /* init status to no-changes */ | 568 | /* init status to no-changes */ |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 1102ce65a3a9..8311de7c0a75 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -439,7 +439,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) | |||
439 | /* here we "know" root ports should always stay powered */ | 439 | /* here we "know" root ports should always stay powered */ |
440 | ehci_port_power(ehci, 1); | 440 | ehci_port_power(ehci, 1); |
441 | 441 | ||
442 | hcd->state = HC_STATE_SUSPENDED; | 442 | ehci->rh_state = EHCI_RH_SUSPENDED; |
443 | return 0; | 443 | return 0; |
444 | } | 444 | } |
445 | #endif | 445 | #endif |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 0917e3a32465..6ce0b3a9a0f9 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -153,7 +153,7 @@ static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd, | |||
153 | spin_lock_irqsave(&ehci->lock, flags); | 153 | spin_lock_irqsave(&ehci->lock, flags); |
154 | qh->clearing_tt = 0; | 154 | qh->clearing_tt = 0; |
155 | if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list) | 155 | if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list) |
156 | && HC_IS_RUNNING(hcd->state)) | 156 | && ehci->rh_state == EHCI_RH_RUNNING) |
157 | qh_link_async(ehci, qh); | 157 | qh_link_async(ehci, qh); |
158 | spin_unlock_irqrestore(&ehci->lock, flags); | 158 | spin_unlock_irqrestore(&ehci->lock, flags); |
159 | } | 159 | } |
@@ -425,7 +425,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
425 | 425 | ||
426 | /* stop scanning when we reach qtds the hc is using */ | 426 | /* stop scanning when we reach qtds the hc is using */ |
427 | } else if (likely (!stopped | 427 | } else if (likely (!stopped |
428 | && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) { | 428 | && ehci->rh_state == EHCI_RH_RUNNING)) { |
429 | break; | 429 | break; |
430 | 430 | ||
431 | /* scan the whole queue for unlinks whenever it stops */ | 431 | /* scan the whole queue for unlinks whenever it stops */ |
@@ -433,7 +433,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
433 | stopped = 1; | 433 | stopped = 1; |
434 | 434 | ||
435 | /* cancel everything if we halt, suspend, etc */ | 435 | /* cancel everything if we halt, suspend, etc */ |
436 | if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) | 436 | if (ehci->rh_state != EHCI_RH_RUNNING) |
437 | last_status = -ESHUTDOWN; | 437 | last_status = -ESHUTDOWN; |
438 | 438 | ||
439 | /* this qtd is active; skip it unless a previous qtd | 439 | /* this qtd is active; skip it unless a previous qtd |
@@ -977,9 +977,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
977 | /* in case a clear of CMD_ASE didn't take yet */ | 977 | /* in case a clear of CMD_ASE didn't take yet */ |
978 | (void)handshake(ehci, &ehci->regs->status, | 978 | (void)handshake(ehci, &ehci->regs->status, |
979 | STS_ASS, 0, 150); | 979 | STS_ASS, 0, 150); |
980 | cmd |= CMD_ASE | CMD_RUN; | 980 | cmd |= CMD_ASE; |
981 | ehci_writel(ehci, cmd, &ehci->regs->command); | 981 | ehci_writel(ehci, cmd, &ehci->regs->command); |
982 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | ||
983 | /* posted write need not be known to HC yet ... */ | 982 | /* posted write need not be known to HC yet ... */ |
984 | } | 983 | } |
985 | } | 984 | } |
@@ -1168,14 +1167,13 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
1168 | 1167 | ||
1169 | qh_completions (ehci, qh); | 1168 | qh_completions (ehci, qh); |
1170 | 1169 | ||
1171 | if (!list_empty (&qh->qtd_list) | 1170 | if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) { |
1172 | && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | ||
1173 | qh_link_async (ehci, qh); | 1171 | qh_link_async (ehci, qh); |
1174 | else { | 1172 | } else { |
1175 | /* it's not free to turn the async schedule on/off; leave it | 1173 | /* it's not free to turn the async schedule on/off; leave it |
1176 | * active but idle for a while once it empties. | 1174 | * active but idle for a while once it empties. |
1177 | */ | 1175 | */ |
1178 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) | 1176 | if (ehci->rh_state == EHCI_RH_RUNNING |
1179 | && ehci->async->qh_next.qh == NULL) | 1177 | && ehci->async->qh_next.qh == NULL) |
1180 | timer_action (ehci, TIMER_ASYNC_OFF); | 1178 | timer_action (ehci, TIMER_ASYNC_OFF); |
1181 | } | 1179 | } |
@@ -1211,7 +1209,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1211 | /* stop async schedule right now? */ | 1209 | /* stop async schedule right now? */ |
1212 | if (unlikely (qh == ehci->async)) { | 1210 | if (unlikely (qh == ehci->async)) { |
1213 | /* can't get here without STS_ASS set */ | 1211 | /* can't get here without STS_ASS set */ |
1214 | if (ehci_to_hcd(ehci)->state != HC_STATE_HALT | 1212 | if (ehci->rh_state != EHCI_RH_HALTED |
1215 | && !ehci->reclaim) { | 1213 | && !ehci->reclaim) { |
1216 | /* ... and CMD_IAAD clear */ | 1214 | /* ... and CMD_IAAD clear */ |
1217 | ehci_writel(ehci, cmd & ~CMD_ASE, | 1215 | ehci_writel(ehci, cmd & ~CMD_ASE, |
@@ -1237,7 +1235,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1237 | wmb (); | 1235 | wmb (); |
1238 | 1236 | ||
1239 | /* If the controller isn't running, we don't have to wait for it */ | 1237 | /* If the controller isn't running, we don't have to wait for it */ |
1240 | if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) { | 1238 | if (unlikely(ehci->rh_state != EHCI_RH_RUNNING)) { |
1241 | /* if (unlikely (qh->reclaim != 0)) | 1239 | /* if (unlikely (qh->reclaim != 0)) |
1242 | * this will recurse, probably not much | 1240 | * this will recurse, probably not much |
1243 | */ | 1241 | */ |
@@ -1260,7 +1258,7 @@ static void scan_async (struct ehci_hcd *ehci) | |||
1260 | enum ehci_timer_action action = TIMER_IO_WATCHDOG; | 1258 | enum ehci_timer_action action = TIMER_IO_WATCHDOG; |
1261 | 1259 | ||
1262 | timer_action_done (ehci, TIMER_ASYNC_SHRINK); | 1260 | timer_action_done (ehci, TIMER_ASYNC_SHRINK); |
1263 | stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state); | 1261 | stopped = (ehci->rh_state != EHCI_RH_RUNNING); |
1264 | 1262 | ||
1265 | ehci->qh_scan_next = ehci->async->qh_next.qh; | 1263 | ehci->qh_scan_next = ehci->async->qh_next.qh; |
1266 | while (ehci->qh_scan_next) { | 1264 | while (ehci->qh_scan_next) { |
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index b3958b3d3163..318e0c6d0ab1 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c | |||
@@ -269,7 +269,7 @@ static int s5p_ehci_resume(struct device *dev) | |||
269 | /* here we "know" root ports should always stay powered */ | 269 | /* here we "know" root ports should always stay powered */ |
270 | ehci_port_power(ehci, 1); | 270 | ehci_port_power(ehci, 1); |
271 | 271 | ||
272 | hcd->state = HC_STATE_SUSPENDED; | 272 | ehci->rh_state = EHCI_RH_SUSPENDED; |
273 | 273 | ||
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 2abf8543f083..488151bb45cb 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -479,7 +479,6 @@ static int enable_periodic (struct ehci_hcd *ehci) | |||
479 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; | 479 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; |
480 | ehci_writel(ehci, cmd, &ehci->regs->command); | 480 | ehci_writel(ehci, cmd, &ehci->regs->command); |
481 | /* posted write ... PSS happens later */ | 481 | /* posted write ... PSS happens later */ |
482 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | ||
483 | 482 | ||
484 | /* make sure ehci_work scans these */ | 483 | /* make sure ehci_work scans these */ |
485 | ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) | 484 | ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) |
@@ -677,7 +676,7 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
677 | 676 | ||
678 | /* reschedule QH iff another request is queued */ | 677 | /* reschedule QH iff another request is queued */ |
679 | if (!list_empty(&qh->qtd_list) && | 678 | if (!list_empty(&qh->qtd_list) && |
680 | HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 679 | ehci->rh_state == EHCI_RH_RUNNING) { |
681 | rc = qh_schedule(ehci, qh); | 680 | rc = qh_schedule(ehci, qh); |
682 | 681 | ||
683 | /* An error here likely indicates handshake failure | 682 | /* An error here likely indicates handshake failure |
@@ -2275,7 +2274,7 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2275 | * Touches as few pages as possible: cache-friendly. | 2274 | * Touches as few pages as possible: cache-friendly. |
2276 | */ | 2275 | */ |
2277 | now_uframe = ehci->next_uframe; | 2276 | now_uframe = ehci->next_uframe; |
2278 | if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 2277 | if (ehci->rh_state == EHCI_RH_RUNNING) { |
2279 | clock = ehci_readl(ehci, &ehci->regs->frame_index); | 2278 | clock = ehci_readl(ehci, &ehci->regs->frame_index); |
2280 | clock_frame = (clock >> 3) & (ehci->periodic_size - 1); | 2279 | clock_frame = (clock >> 3) & (ehci->periodic_size - 1); |
2281 | } else { | 2280 | } else { |
@@ -2310,7 +2309,7 @@ restart: | |||
2310 | union ehci_shadow temp; | 2309 | union ehci_shadow temp; |
2311 | int live; | 2310 | int live; |
2312 | 2311 | ||
2313 | live = HC_IS_RUNNING (ehci_to_hcd(ehci)->state); | 2312 | live = (ehci->rh_state == EHCI_RH_RUNNING); |
2314 | switch (hc32_to_cpu(ehci, type)) { | 2313 | switch (hc32_to_cpu(ehci, type)) { |
2315 | case Q_TYPE_QH: | 2314 | case Q_TYPE_QH: |
2316 | /* handle any completions */ | 2315 | /* handle any completions */ |
@@ -2435,7 +2434,7 @@ restart: | |||
2435 | * We can't advance our scan without collecting the ISO | 2434 | * We can't advance our scan without collecting the ISO |
2436 | * transfers that are still pending in this frame. | 2435 | * transfers that are still pending in this frame. |
2437 | */ | 2436 | */ |
2438 | if (incomplete && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 2437 | if (incomplete && ehci->rh_state == EHCI_RH_RUNNING) { |
2439 | ehci->next_uframe = now_uframe; | 2438 | ehci->next_uframe = now_uframe; |
2440 | break; | 2439 | break; |
2441 | } | 2440 | } |
@@ -2451,7 +2450,7 @@ restart: | |||
2451 | if (now_uframe == clock) { | 2450 | if (now_uframe == clock) { |
2452 | unsigned now; | 2451 | unsigned now; |
2453 | 2452 | ||
2454 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) | 2453 | if (ehci->rh_state != EHCI_RH_RUNNING |
2455 | || ehci->periodic_sched == 0) | 2454 | || ehci->periodic_sched == 0) |
2456 | break; | 2455 | break; |
2457 | ehci->next_uframe = now_uframe; | 2456 | ehci->next_uframe = now_uframe; |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index cc7d337ec355..c161d97de7dd 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -62,6 +62,12 @@ struct ehci_stats { | |||
62 | 62 | ||
63 | #define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */ | 63 | #define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */ |
64 | 64 | ||
65 | enum ehci_rh_state { | ||
66 | EHCI_RH_HALTED, | ||
67 | EHCI_RH_SUSPENDED, | ||
68 | EHCI_RH_RUNNING | ||
69 | }; | ||
70 | |||
65 | struct ehci_hcd { /* one per controller */ | 71 | struct ehci_hcd { /* one per controller */ |
66 | /* glue to PCI and HCD framework */ | 72 | /* glue to PCI and HCD framework */ |
67 | struct ehci_caps __iomem *caps; | 73 | struct ehci_caps __iomem *caps; |
@@ -70,6 +76,7 @@ struct ehci_hcd { /* one per controller */ | |||
70 | 76 | ||
71 | __u32 hcs_params; /* cached register copy */ | 77 | __u32 hcs_params; /* cached register copy */ |
72 | spinlock_t lock; | 78 | spinlock_t lock; |
79 | enum ehci_rh_state rh_state; | ||
73 | 80 | ||
74 | /* async schedule support */ | 81 | /* async schedule support */ |
75 | struct ehci_qh *async; | 82 | struct ehci_qh *async; |