summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/controller/uhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/controller/uhci.c')
-rw-r--r--sys/dev/usb/controller/uhci.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c
index c365e01..d9091c9 100644
--- a/sys/dev/usb/controller/uhci.c
+++ b/sys/dev/usb/controller/uhci.c
@@ -373,9 +373,10 @@ done_1:
done_2:
- /* reload the configuration */
- UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
- UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
+ /* reset frame number */
+ UWRITE2(sc, UHCI_FRNUM, 0);
+ /* set default SOF value */
+ UWRITE1(sc, UHCI_SOF, 0x40);
USB_BUS_UNLOCK(&sc->sc_bus);
@@ -463,9 +464,6 @@ uhci_init(uhci_softc_t *sc)
uhci_dumpregs(sc);
}
#endif
- sc->sc_saved_sof = 0x40; /* default value */
- sc->sc_saved_frnum = 0; /* default frame number */
-
/*
* Setup QH's
*/
@@ -658,24 +656,16 @@ uhci_init(uhci_softc_t *sc)
return (0);
}
-/* NOTE: suspend/resume is called from
- * interrupt context and cannot sleep!
- */
-
-void
+static void
uhci_suspend(uhci_softc_t *sc)
{
- USB_BUS_LOCK(&sc->sc_bus);
-
#ifdef USB_DEBUG
if (uhcidebug > 2) {
uhci_dumpregs(sc);
}
#endif
- /* save some state if BIOS doesn't */
- sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
- sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
+ USB_BUS_LOCK(&sc->sc_bus);
/* stop the controller */
@@ -685,13 +675,10 @@ uhci_suspend(uhci_softc_t *sc)
UHCICMD(sc, UHCI_CMD_EGSM);
- usb_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_WAIT));
-
USB_BUS_UNLOCK(&sc->sc_bus);
}
-void
+static void
uhci_resume(uhci_softc_t *sc)
{
USB_BUS_LOCK(&sc->sc_bus);
@@ -704,21 +691,17 @@ uhci_resume(uhci_softc_t *sc)
UHCICMD(sc, UHCI_CMD_FGR);
- usb_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_DELAY));
-
/* and start traffic again */
uhci_start(sc);
+ USB_BUS_UNLOCK(&sc->sc_bus);
+
#ifdef USB_DEBUG
- if (uhcidebug > 2) {
+ if (uhcidebug > 2)
uhci_dumpregs(sc);
- }
#endif
- USB_BUS_UNLOCK(&sc->sc_bus);
-
/* catch lost interrupts */
uhci_do_poll(&sc->sc_bus);
}
@@ -3179,6 +3162,24 @@ uhci_device_suspend(struct usb_device *udev)
}
static void
+uhci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct uhci_softc *sc = UHCI_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ case USB_HW_POWER_SHUTDOWN:
+ uhci_suspend(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ uhci_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
uhci_set_hw_power(struct usb_bus *bus)
{
struct uhci_softc *sc = UHCI_BUS2SC(bus);
@@ -3225,6 +3226,7 @@ struct usb_bus_methods uhci_bus_methods =
.device_resume = uhci_device_resume,
.device_suspend = uhci_device_suspend,
.set_hw_power = uhci_set_hw_power,
+ .set_hw_power_sleep = uhci_set_hw_power_sleep,
.roothub_exec = uhci_roothub_exec,
.xfer_poll = uhci_do_poll,
};
OpenPOWER on IntegriCloud