aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2011-06-15 15:08:48 +0000
committerPeter Maydell <peter.maydell@linaro.org>2011-06-15 15:08:48 +0000
commit2d601b5fb663bb2876b85bec255d73bba01e38e6 (patch)
tree71417c64a721b4190186c60b906c39a02933cd1b
parent1f84962a0a5207906b86a725bd45e4e58ca2800d (diff)
downloadqemu-linaro.tar.gz
hw/usb-ohci.c: Correct handling of OHCI wakeuplinaro
Fix some issues with the implementation of OHCI wakeup that meant that we didn't always wake up properly and the keyboard would appear to stop working. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/usb-ohci.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 23a5e66b00..3f98617934 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -373,14 +373,25 @@ static void ohci_wakeup(USBDevice *dev)
OHCIState *s = container_of(bus, OHCIState, bus);
int portnum = dev->port->index;
OHCIPort *port = &s->rhport[portnum];
+ uint32_t intr = 0;
if (port->ctrl & OHCI_PORT_PSS) {
DPRINTF("usb-ohci: port %d: wakeup\n", portnum);
port->ctrl |= OHCI_PORT_PSSC;
port->ctrl &= ~OHCI_PORT_PSS;
- if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
- ohci_set_interrupt(s, OHCI_INTR_RD);
- }
+ intr = OHCI_INTR_RHSC;
+ }
+ /* Note that the controller can be suspended even if this port is not */
+ if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
+ DPRINTF("usb-ohci: remote-wakeup: SUSPEND->RESUME\n");
+ /* This is the one state transition the controller can do by itself */
+ s->ctl &= ~OHCI_CTL_HCFS;
+ s->ctl |= OHCI_USB_RESUME;
+ /* In suspend mode only ResumeDetected is possible, not RHSC:
+ * see the OHCI spec 5.1.2.3.
+ */
+ intr = OHCI_INTR_RD;
}
+ ohci_set_interrupt(s, intr);
}
/* Reset the controller */