aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-hub.c')
-rw-r--r--drivers/usb/host/ohci-hub.c172
1 files changed, 91 insertions, 81 deletions
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 6f113596af66..2441642cb7b4 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -41,7 +41,11 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd)
41{ 41{
42 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 42 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
43 43
44 ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); 44 spin_lock_irq(&ohci->lock);
45 if (!ohci->autostop)
46 del_timer(&hcd->rh_timer); /* Prevent next poll */
47 ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
48 spin_unlock_irq(&ohci->lock);
45} 49}
46 50
47#define OHCI_SCHED_ENABLES \ 51#define OHCI_SCHED_ENABLES \
@@ -50,6 +54,9 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd)
50static void dl_done_list (struct ohci_hcd *); 54static void dl_done_list (struct ohci_hcd *);
51static void finish_unlinks (struct ohci_hcd *, u16); 55static void finish_unlinks (struct ohci_hcd *, u16);
52 56
57#ifdef CONFIG_PM
58static int ohci_restart(struct ohci_hcd *ohci);
59
53static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) 60static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop)
54__releases(ohci->lock) 61__releases(ohci->lock)
55__acquires(ohci->lock) 62__acquires(ohci->lock)
@@ -132,8 +139,6 @@ static inline struct ed *find_head (struct ed *ed)
132 return ed; 139 return ed;
133} 140}
134 141
135static int ohci_restart (struct ohci_hcd *ohci);
136
137/* caller has locked the root hub */ 142/* caller has locked the root hub */
138static int ohci_rh_resume (struct ohci_hcd *ohci) 143static int ohci_rh_resume (struct ohci_hcd *ohci)
139__releases(ohci->lock) 144__releases(ohci->lock)
@@ -169,7 +174,8 @@ __acquires(ohci->lock)
169 break; 174 break;
170 case OHCI_USB_RESUME: 175 case OHCI_USB_RESUME:
171 /* HCFS changes sometime after INTR_RD */ 176 /* HCFS changes sometime after INTR_RD */
172 ohci_info (ohci, "wakeup\n"); 177 ohci_dbg(ohci, "%swakeup root hub\n",
178 autostopped ? "auto-" : "");
173 break; 179 break;
174 case OHCI_USB_OPER: 180 case OHCI_USB_OPER:
175 /* this can happen after resuming a swsusp snapshot */ 181 /* this can happen after resuming a swsusp snapshot */
@@ -180,7 +186,6 @@ __acquires(ohci->lock)
180 ohci_dbg (ohci, "lost power\n"); 186 ohci_dbg (ohci, "lost power\n");
181 status = -EBUSY; 187 status = -EBUSY;
182 } 188 }
183#ifdef CONFIG_PM
184 if (status == -EBUSY) { 189 if (status == -EBUSY) {
185 if (!autostopped) { 190 if (!autostopped) {
186 spin_unlock_irq (&ohci->lock); 191 spin_unlock_irq (&ohci->lock);
@@ -190,25 +195,12 @@ __acquires(ohci->lock)
190 } 195 }
191 return status; 196 return status;
192 } 197 }
193#endif
194 if (status != -EINPROGRESS) 198 if (status != -EINPROGRESS)
195 return status; 199 return status;
196 if (autostopped) 200 if (autostopped)
197 goto skip_resume; 201 goto skip_resume;
198 spin_unlock_irq (&ohci->lock); 202 spin_unlock_irq (&ohci->lock);
199 203
200 temp = ohci->num_ports;
201 while (temp--) {
202 u32 stat = ohci_readl (ohci,
203 &ohci->regs->roothub.portstatus [temp]);
204
205 /* force global, not selective, resume */
206 if (!(stat & RH_PS_PSS))
207 continue;
208 ohci_writel (ohci, RH_PS_POCI,
209 &ohci->regs->roothub.portstatus [temp]);
210 }
211
212 /* Some controllers (lucent erratum) need extra-long delays */ 204 /* Some controllers (lucent erratum) need extra-long delays */
213 msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1); 205 msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1);
214 206
@@ -216,6 +208,7 @@ __acquires(ohci->lock)
216 temp &= OHCI_CTRL_HCFS; 208 temp &= OHCI_CTRL_HCFS;
217 if (temp != OHCI_USB_RESUME) { 209 if (temp != OHCI_USB_RESUME) {
218 ohci_err (ohci, "controller won't resume\n"); 210 ohci_err (ohci, "controller won't resume\n");
211 spin_lock_irq(&ohci->lock);
219 return -EBUSY; 212 return -EBUSY;
220 } 213 }
221 214
@@ -295,8 +288,6 @@ skip_resume:
295 return 0; 288 return 0;
296} 289}
297 290
298#ifdef CONFIG_PM
299
300static int ohci_bus_suspend (struct usb_hcd *hcd) 291static int ohci_bus_suspend (struct usb_hcd *hcd)
301{ 292{
302 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 293 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
@@ -334,6 +325,83 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
334 return rc; 325 return rc;
335} 326}
336 327
328/* Carry out polling-, autostop-, and autoresume-related state changes */
329static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
330 int any_connected)
331{
332 int poll_rh = 1;
333
334 switch (ohci->hc_control & OHCI_CTRL_HCFS) {
335
336 case OHCI_USB_OPER:
337 /* keep on polling until we know a device is connected
338 * and RHSC is enabled */
339 if (!ohci->autostop) {
340 if (any_connected ||
341 !device_may_wakeup(&ohci_to_hcd(ohci)
342 ->self.root_hub->dev)) {
343 if (ohci_readl(ohci, &ohci->regs->intrenable) &
344 OHCI_INTR_RHSC)
345 poll_rh = 0;
346 } else {
347 ohci->autostop = 1;
348 ohci->next_statechange = jiffies + HZ;
349 }
350
351 /* if no devices have been attached for one second, autostop */
352 } else {
353 if (changed || any_connected) {
354 ohci->autostop = 0;
355 ohci->next_statechange = jiffies +
356 STATECHANGE_DELAY;
357 } else if (time_after_eq(jiffies,
358 ohci->next_statechange)
359 && !ohci->ed_rm_list
360 && !(ohci->hc_control &
361 OHCI_SCHED_ENABLES)) {
362 ohci_rh_suspend(ohci, 1);
363 }
364 }
365 break;
366
367 /* if there is a port change, autostart or ask to be resumed */
368 case OHCI_USB_SUSPEND:
369 case OHCI_USB_RESUME:
370 if (changed) {
371 if (ohci->autostop)
372 ohci_rh_resume(ohci);
373 else
374 usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
375 } else {
376 /* everything is idle, no need for polling */
377 poll_rh = 0;
378 }
379 break;
380 }
381 return poll_rh;
382}
383
384#else /* CONFIG_PM */
385
386static inline int ohci_rh_resume(struct ohci_hcd *ohci)
387{
388 return 0;
389}
390
391/* Carry out polling-related state changes.
392 * autostop isn't used when CONFIG_PM is turned off.
393 */
394static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
395 int any_connected)
396{
397 int poll_rh = 1;
398
399 /* keep on polling until RHSC is enabled */
400 if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
401 poll_rh = 0;
402 return poll_rh;
403}
404
337#endif /* CONFIG_PM */ 405#endif /* CONFIG_PM */
338 406
339/*-------------------------------------------------------------------------*/ 407/*-------------------------------------------------------------------------*/
@@ -345,7 +413,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
345{ 413{
346 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 414 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
347 int i, changed = 0, length = 1; 415 int i, changed = 0, length = 1;
348 int any_connected = 0, rhsc_enabled = 1; 416 int any_connected = 0;
349 unsigned long flags; 417 unsigned long flags;
350 418
351 spin_lock_irqsave (&ohci->lock, flags); 419 spin_lock_irqsave (&ohci->lock, flags);
@@ -386,66 +454,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
386 } 454 }
387 } 455 }
388 456
389 /* NOTE: vendors didn't always make the same implementation 457 hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
390 * choices for RHSC. Sometimes it triggers on an edge (like 458 any_connected);
391 * setting and maybe clearing a port status change bit); and
392 * it's level-triggered on other silicon, active until khubd
393 * clears all active port status change bits. If it's still
394 * set (level-triggered) we must disable it and rely on
395 * polling until khubd re-enables it.
396 */
397 if (ohci_readl (ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC) {
398 ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable);
399 (void) ohci_readl (ohci, &ohci->regs->intrdisable);
400 rhsc_enabled = 0;
401 }
402 hcd->poll_rh = 1;
403
404 /* carry out appropriate state changes */
405 switch (ohci->hc_control & OHCI_CTRL_HCFS) {
406
407 case OHCI_USB_OPER:
408 /* keep on polling until we know a device is connected
409 * and RHSC is enabled */
410 if (!ohci->autostop) {
411 if (any_connected) {
412 if (rhsc_enabled)
413 hcd->poll_rh = 0;
414 } else {
415 ohci->autostop = 1;
416 ohci->next_statechange = jiffies + HZ;
417 }
418
419 /* if no devices have been attached for one second, autostop */
420 } else {
421 if (changed || any_connected) {
422 ohci->autostop = 0;
423 ohci->next_statechange = jiffies +
424 STATECHANGE_DELAY;
425 } else if (time_after_eq (jiffies,
426 ohci->next_statechange)
427 && !ohci->ed_rm_list
428 && !(ohci->hc_control &
429 OHCI_SCHED_ENABLES)) {
430 ohci_rh_suspend (ohci, 1);
431 }
432 }
433 break;
434
435 /* if there is a port change, autostart or ask to be resumed */
436 case OHCI_USB_SUSPEND:
437 case OHCI_USB_RESUME:
438 if (changed) {
439 if (ohci->autostop)
440 ohci_rh_resume (ohci);
441 else
442 usb_hcd_resume_root_hub (hcd);
443 } else {
444 /* everything is idle, no need for polling */
445 hcd->poll_rh = 0;
446 }
447 break;
448 }
449 459
450done: 460done:
451 spin_unlock_irqrestore (&ohci->lock, flags); 461 spin_unlock_irqrestore (&ohci->lock, flags);