diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2011-06-15 15:08:48 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2011-06-15 15:08:48 +0000 |
commit | 2d601b5fb663bb2876b85bec255d73bba01e38e6 (patch) | |
tree | 71417c64a721b4190186c60b906c39a02933cd1b | |
parent | 1f84962a0a5207906b86a725bd45e4e58ca2800d (diff) |
hw/usb-ohci.c: Correct handling of OHCI wakeup2011.06-0
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.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index 23a5e66b0..3f9861793 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 */ |