2 * Copyright (C) 2001-2004 by David Brownell
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* this file is part of ehci-hcd.c */
21 /*-------------------------------------------------------------------------*/
24 * EHCI Root Hub ... the nonsharable stuff
26 * Registers don't need cpu_to_le32, that happens transparently
29 /*-------------------------------------------------------------------------*/
33 static int ehci_bus_suspend (struct usb_hcd
*hcd
)
35 struct ehci_hcd
*ehci
= hcd_to_ehci (hcd
);
38 if (time_before (jiffies
, ehci
->next_statechange
))
41 port
= HCS_N_PORTS (ehci
->hcs_params
);
42 spin_lock_irq (&ehci
->lock
);
44 /* stop schedules, clean any completed work */
45 if (HC_IS_RUNNING(hcd
->state
)) {
47 hcd
->state
= HC_STATE_QUIESCING
;
49 ehci
->command
= readl (&ehci
->regs
->command
);
51 ehci
->reclaim_ready
= 1;
52 ehci_work(ehci
, NULL
);
54 /* suspend any active/unsuspended ports, maybe allow wakeup */
56 u32 __iomem
*reg
= &ehci
->regs
->port_status
[port
];
57 u32 t1
= readl (reg
) & ~PORT_RWC_BITS
;
60 if ((t1
& PORT_PE
) && !(t1
& PORT_OWNER
))
62 if (hcd
->remote_wakeup
)
63 t2
|= PORT_WKOC_E
|PORT_WKDISC_E
|PORT_WKCONN_E
;
65 t2
&= ~(PORT_WKOC_E
|PORT_WKDISC_E
|PORT_WKCONN_E
);
68 ehci_vdbg (ehci
, "port %d, %08x -> %08x\n",
74 /* turn off now-idle HC */
75 del_timer_sync (&ehci
->watchdog
);
77 hcd
->state
= HC_STATE_SUSPENDED
;
79 ehci
->next_statechange
= jiffies
+ msecs_to_jiffies(10);
80 spin_unlock_irq (&ehci
->lock
);
85 /* caller has locked the root hub, and should reset/reinit on error */
86 static int ehci_bus_resume (struct usb_hcd
*hcd
)
88 struct ehci_hcd
*ehci
= hcd_to_ehci (hcd
);
93 if (time_before (jiffies
, ehci
->next_statechange
))
95 spin_lock_irq (&ehci
->lock
);
97 /* re-init operational registers in case we lost power */
98 if (readl (&ehci
->regs
->intr_enable
) == 0) {
99 /* at least some APM implementations will try to deliver
100 * IRQs right away, so delay them until we're ready.
103 writel (0, &ehci
->regs
->segment
);
104 writel (ehci
->periodic_dma
, &ehci
->regs
->frame_list
);
105 writel ((u32
)ehci
->async
->qh_dma
, &ehci
->regs
->async_next
);
108 ehci_dbg(ehci
, "resume root hub%s\n",
109 intr_enable
? " after power loss" : "");
111 /* restore CMD_RUN, framelist size, and irq threshold */
112 writel (ehci
->command
, &ehci
->regs
->command
);
114 /* take ports out of suspend */
115 i
= HCS_N_PORTS (ehci
->hcs_params
);
117 temp
= readl (&ehci
->regs
->port_status
[i
]);
118 temp
&= ~(PORT_RWC_BITS
119 | PORT_WKOC_E
| PORT_WKDISC_E
| PORT_WKCONN_E
);
120 if (temp
& PORT_SUSPEND
) {
121 ehci
->reset_done
[i
] = jiffies
+ msecs_to_jiffies (20);
124 writel (temp
, &ehci
->regs
->port_status
[i
]);
126 i
= HCS_N_PORTS (ehci
->hcs_params
);
129 temp
= readl (&ehci
->regs
->port_status
[i
]);
130 if ((temp
& PORT_SUSPEND
) == 0)
132 temp
&= ~(PORT_RWC_BITS
| PORT_RESUME
);
133 writel (temp
, &ehci
->regs
->port_status
[i
]);
134 ehci_vdbg (ehci
, "resumed port %d\n", i
+ 1);
136 (void) readl (&ehci
->regs
->command
);
138 /* maybe re-activate the schedule(s) */
140 if (ehci
->async
->qh_next
.qh
)
142 if (ehci
->periodic_sched
)
145 ehci
->command
|= temp
;
146 writel (ehci
->command
, &ehci
->regs
->command
);
149 ehci
->next_statechange
= jiffies
+ msecs_to_jiffies(5);
150 hcd
->state
= HC_STATE_RUNNING
;
152 /* Now we can safely re-enable irqs */
154 writel (INTR_MASK
, &ehci
->regs
->intr_enable
);
156 spin_unlock_irq (&ehci
->lock
);
162 #define ehci_bus_suspend NULL
163 #define ehci_bus_resume NULL
165 #endif /* CONFIG_PM */
167 /*-------------------------------------------------------------------------*/
169 static int check_reset_complete (
170 struct ehci_hcd
*ehci
,
174 if (!(port_status
& PORT_CONNECT
)) {
175 ehci
->reset_done
[index
] = 0;
179 /* if reset finished and it's still not enabled -- handoff */
180 if (!(port_status
& PORT_PE
)) {
182 /* with integrated TT, there's nobody to hand it to! */
183 if (ehci_is_TDI(ehci
)) {
185 "Failed to enable port %d on root hub TT\n",
190 ehci_dbg (ehci
, "port %d full speed --> companion\n",
193 // what happens if HCS_N_CC(params) == 0 ?
194 port_status
|= PORT_OWNER
;
195 port_status
&= ~PORT_RWC_BITS
;
196 writel (port_status
, &ehci
->regs
->port_status
[index
]);
199 ehci_dbg (ehci
, "port %d high speed\n", index
+ 1);
204 /*-------------------------------------------------------------------------*/
207 /* build "status change" packet (one or two bytes) from HC registers */
210 ehci_hub_status_data (struct usb_hcd
*hcd
, char *buf
)
212 struct ehci_hcd
*ehci
= hcd_to_ehci (hcd
);
213 u32 temp
, status
= 0;
214 int ports
, i
, retval
= 1;
217 /* if !USB_SUSPEND, root hub timers won't get shut down ... */
218 if (!HC_IS_RUNNING(hcd
->state
))
221 /* init status to no-changes */
223 ports
= HCS_N_PORTS (ehci
->hcs_params
);
229 /* no hub change reports (bit 0) for now (power, ...) */
231 /* port N changes (bit N)? */
232 spin_lock_irqsave (&ehci
->lock
, flags
);
233 for (i
= 0; i
< ports
; i
++) {
234 temp
= readl (&ehci
->regs
->port_status
[i
]);
235 if (temp
& PORT_OWNER
) {
236 /* don't report this in GetPortStatus */
237 if (temp
& PORT_CSC
) {
238 temp
&= ~PORT_RWC_BITS
;
240 writel (temp
, &ehci
->regs
->port_status
[i
]);
244 if (!(temp
& PORT_CONNECT
))
245 ehci
->reset_done
[i
] = 0;
246 if ((temp
& (PORT_CSC
| PORT_PEC
| PORT_OCC
)) != 0
247 // PORT_STAT_C_SUSPEND?
248 || ((temp
& PORT_RESUME
) != 0
249 && time_after (jiffies
,
250 ehci
->reset_done
[i
]))) {
252 buf
[0] |= 1 << (i
+ 1);
254 buf
[1] |= 1 << (i
- 7);
258 /* FIXME autosuspend idle root hubs */
259 spin_unlock_irqrestore (&ehci
->lock
, flags
);
260 return status
? retval
: 0;
263 /*-------------------------------------------------------------------------*/
266 ehci_hub_descriptor (
267 struct ehci_hcd
*ehci
,
268 struct usb_hub_descriptor
*desc
270 int ports
= HCS_N_PORTS (ehci
->hcs_params
);
273 desc
->bDescriptorType
= 0x29;
274 desc
->bPwrOn2PwrGood
= 10; /* ehci 1.0, 2.3.9 says 20ms max */
275 desc
->bHubContrCurrent
= 0;
277 desc
->bNbrPorts
= ports
;
278 temp
= 1 + (ports
/ 8);
279 desc
->bDescLength
= 7 + 2 * temp
;
281 /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
282 memset (&desc
->bitmap
[0], 0, temp
);
283 memset (&desc
->bitmap
[temp
], 0xff, temp
);
285 temp
= 0x0008; /* per-port overcurrent reporting */
286 if (HCS_PPC (ehci
->hcs_params
))
287 temp
|= 0x0001; /* per-port power control */
289 temp
|= 0x0002; /* no power switching */
291 // re-enable when we support USB_PORT_FEAT_INDICATOR below.
292 if (HCS_INDICATOR (ehci
->hcs_params
))
293 temp
|= 0x0080; /* per-port indicators (LEDs) */
295 desc
->wHubCharacteristics
= (__force __u16
)cpu_to_le16 (temp
);
298 /*-------------------------------------------------------------------------*/
300 #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
302 static int ehci_hub_control (
310 struct ehci_hcd
*ehci
= hcd_to_ehci (hcd
);
311 int ports
= HCS_N_PORTS (ehci
->hcs_params
);
317 * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
318 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
319 * (track current state ourselves) ... blink for diagnostics,
320 * power, "this is the one", etc. EHCI spec supports this.
323 spin_lock_irqsave (&ehci
->lock
, flags
);
325 case ClearHubFeature
:
327 case C_HUB_LOCAL_POWER
:
328 case C_HUB_OVER_CURRENT
:
329 /* no hub-wide feature/status flags */
335 case ClearPortFeature
:
336 if (!wIndex
|| wIndex
> ports
)
339 temp
= readl (&ehci
->regs
->port_status
[wIndex
]);
340 if (temp
& PORT_OWNER
)
344 case USB_PORT_FEAT_ENABLE
:
345 writel (temp
& ~PORT_PE
,
346 &ehci
->regs
->port_status
[wIndex
]);
348 case USB_PORT_FEAT_C_ENABLE
:
349 writel((temp
& ~PORT_RWC_BITS
) | PORT_PEC
,
350 &ehci
->regs
->port_status
[wIndex
]);
352 case USB_PORT_FEAT_SUSPEND
:
353 if (temp
& PORT_RESET
)
355 if (temp
& PORT_SUSPEND
) {
356 if ((temp
& PORT_PE
) == 0)
358 /* resume signaling for 20 msec */
359 temp
&= ~(PORT_RWC_BITS
| PORT_WAKE_BITS
);
360 writel (temp
| PORT_RESUME
,
361 &ehci
->regs
->port_status
[wIndex
]);
362 ehci
->reset_done
[wIndex
] = jiffies
363 + msecs_to_jiffies (20);
366 case USB_PORT_FEAT_C_SUSPEND
:
367 /* we auto-clear this feature */
369 case USB_PORT_FEAT_POWER
:
370 if (HCS_PPC (ehci
->hcs_params
))
371 writel (temp
& ~(PORT_RWC_BITS
| PORT_POWER
),
372 &ehci
->regs
->port_status
[wIndex
]);
374 case USB_PORT_FEAT_C_CONNECTION
:
375 writel((temp
& ~PORT_RWC_BITS
) | PORT_CSC
,
376 &ehci
->regs
->port_status
[wIndex
]);
378 case USB_PORT_FEAT_C_OVER_CURRENT
:
379 writel((temp
& ~PORT_RWC_BITS
) | PORT_OCC
,
380 &ehci
->regs
->port_status
[wIndex
]);
382 case USB_PORT_FEAT_C_RESET
:
383 /* GetPortStatus clears reset */
388 readl (&ehci
->regs
->command
); /* unblock posted write */
390 case GetHubDescriptor
:
391 ehci_hub_descriptor (ehci
, (struct usb_hub_descriptor
*)
395 /* no hub-wide feature/status flags */
397 //cpu_to_le32s ((u32 *) buf);
400 if (!wIndex
|| wIndex
> ports
)
404 temp
= readl (&ehci
->regs
->port_status
[wIndex
]);
408 status
|= 1 << USB_PORT_FEAT_C_CONNECTION
;
410 status
|= 1 << USB_PORT_FEAT_C_ENABLE
;
412 status
|= 1 << USB_PORT_FEAT_C_OVER_CURRENT
;
414 /* whoever resumes must GetPortStatus to complete it!! */
415 if ((temp
& PORT_RESUME
)
416 && time_after (jiffies
,
417 ehci
->reset_done
[wIndex
])) {
418 status
|= 1 << USB_PORT_FEAT_C_SUSPEND
;
419 ehci
->reset_done
[wIndex
] = 0;
421 /* stop resume signaling */
422 temp
= readl (&ehci
->regs
->port_status
[wIndex
]);
423 writel (temp
& ~(PORT_RWC_BITS
| PORT_RESUME
),
424 &ehci
->regs
->port_status
[wIndex
]);
426 &ehci
->regs
->port_status
[wIndex
],
427 PORT_RESUME
, 0, 2000 /* 2msec */);
429 ehci_err (ehci
, "port %d resume error %d\n",
433 temp
&= ~(PORT_SUSPEND
|PORT_RESUME
|(3<<10));
436 /* whoever resets must GetPortStatus to complete it!! */
437 if ((temp
& PORT_RESET
)
438 && time_after (jiffies
,
439 ehci
->reset_done
[wIndex
])) {
440 status
|= 1 << USB_PORT_FEAT_C_RESET
;
441 ehci
->reset_done
[wIndex
] = 0;
443 /* force reset to complete */
444 writel (temp
& ~(PORT_RWC_BITS
| PORT_RESET
),
445 &ehci
->regs
->port_status
[wIndex
]);
446 /* REVISIT: some hardware needs 550+ usec to clear
447 * this bit; seems too long to spin routinely...
450 &ehci
->regs
->port_status
[wIndex
],
453 ehci_err (ehci
, "port %d reset error %d\n",
458 /* see what we found out */
459 temp
= check_reset_complete (ehci
, wIndex
,
460 readl (&ehci
->regs
->port_status
[wIndex
]));
463 // don't show wPortStatus if it's owned by a companion hc
464 if (!(temp
& PORT_OWNER
)) {
465 if (temp
& PORT_CONNECT
) {
466 status
|= 1 << USB_PORT_FEAT_CONNECTION
;
467 // status may be from integrated TT
468 status
|= ehci_port_speed(ehci
, temp
);
471 status
|= 1 << USB_PORT_FEAT_ENABLE
;
472 if (temp
& (PORT_SUSPEND
|PORT_RESUME
))
473 status
|= 1 << USB_PORT_FEAT_SUSPEND
;
475 status
|= 1 << USB_PORT_FEAT_OVER_CURRENT
;
476 if (temp
& PORT_RESET
)
477 status
|= 1 << USB_PORT_FEAT_RESET
;
478 if (temp
& PORT_POWER
)
479 status
|= 1 << USB_PORT_FEAT_POWER
;
482 #ifndef EHCI_VERBOSE_DEBUG
483 if (status
& ~0xffff) /* only if wPortChange is interesting */
485 dbg_port (ehci
, "GetStatus", wIndex
+ 1, temp
);
486 // we "know" this alignment is good, caller used kmalloc()...
487 *((__le32
*) buf
) = cpu_to_le32 (status
);
491 case C_HUB_LOCAL_POWER
:
492 case C_HUB_OVER_CURRENT
:
493 /* no hub-wide feature/status flags */
500 if (!wIndex
|| wIndex
> ports
)
503 temp
= readl (&ehci
->regs
->port_status
[wIndex
]);
504 if (temp
& PORT_OWNER
)
507 temp
&= ~PORT_RWC_BITS
;
509 case USB_PORT_FEAT_SUSPEND
:
510 if ((temp
& PORT_PE
) == 0
511 || (temp
& PORT_RESET
) != 0)
513 if (hcd
->remote_wakeup
)
514 temp
|= PORT_WAKE_BITS
;
515 writel (temp
| PORT_SUSPEND
,
516 &ehci
->regs
->port_status
[wIndex
]);
518 case USB_PORT_FEAT_POWER
:
519 if (HCS_PPC (ehci
->hcs_params
))
520 writel (temp
| PORT_POWER
,
521 &ehci
->regs
->port_status
[wIndex
]);
523 case USB_PORT_FEAT_RESET
:
524 if (temp
& PORT_RESUME
)
526 /* line status bits may report this as low speed,
527 * which can be fine if this root hub has a
528 * transaction translator built in.
530 if ((temp
& (PORT_PE
|PORT_CONNECT
)) == PORT_CONNECT
531 && !ehci_is_TDI(ehci
)
532 && PORT_USB11 (temp
)) {
534 "port %d low speed --> companion\n",
538 ehci_vdbg (ehci
, "port %d reset\n", wIndex
+ 1);
543 * caller must wait, then call GetPortStatus
544 * usb 2.0 spec says 50 ms resets on root
546 ehci
->reset_done
[wIndex
] = jiffies
547 + msecs_to_jiffies (50);
549 writel (temp
, &ehci
->regs
->port_status
[wIndex
]);
554 readl (&ehci
->regs
->command
); /* unblock posted writes */
559 /* "stall" on error */
562 spin_unlock_irqrestore (&ehci
->lock
, flags
);