aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2011-08-18 16:31:30 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-22 18:57:01 -0400
commite8799906045302776b35b66b16495c575db3b69c (patch)
treee6b5a76bd13ef0a9df24f7a7c8c1e924c0efcedb
parentdfd8c81fd1c09c740140a2334669994d5c6edcaa (diff)
USB: EHCI: remove usages of hcd->state
This patch (as1483) improves the ehci-hcd driver family by getting rid of the reliance on the hcd->state variable. It has no clear owner and it isn't protected by the usual HCD locks. In its place, the patch adds a new, private ehci->rh_state field to record the state of the root hub. Along the way, the patch removes a couple of lines containing redundant assignments to the state variable. Also, the QUIESCING state simply gets changed to the RUNNING state, because the driver doesn't make any distinction between them. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Jingoo Han <jg1.han@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/ehci-au1xxx.c2
-rw-r--r--drivers/usb/host/ehci-dbg.c17
-rw-r--r--drivers/usb/host/ehci-fsl.c4
-rw-r--r--drivers/usb/host/ehci-hcd.c20
-rw-r--r--drivers/usb/host/ehci-hub.c10
-rw-r--r--drivers/usb/host/ehci-pci.c2
-rw-r--r--drivers/usb/host/ehci-q.c22
-rw-r--r--drivers/usb/host/ehci-s5p.c2
-rw-r--r--drivers/usb/host/ehci-sched.c11
-rw-r--r--drivers/usb/host/ehci.h7
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
700static 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
700static ssize_t fill_registers_buffer(struct debug_buffer *buf) 713static 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 (
952static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) 952static 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
65enum ehci_rh_state {
66 EHCI_RH_HALTED,
67 EHCI_RH_SUSPENDED,
68 EHCI_RH_RUNNING
69};
70
65struct ehci_hcd { /* one per controller */ 71struct 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;