summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-02-24 18:21:21 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-02-24 18:21:21 +0000
commit43b0044da2a5d872105b5178884c49cebe0809d2 (patch)
treef4f81badbc9217cbe56a1d0e96072c9d7a2cb823 /sys/dev
parent7126722738c20bac0b06770c59408ea7da83033a (diff)
Partially revert r1.134, bring back the code suspending root hub's ports
before reseting the controller in order to save power when the machine is suspended. ok deraadt@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/ehci.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index ed6dcb24069..633fce39a83 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci.c,v 1.140 2014/01/15 11:10:40 mpi Exp $ */
+/* $OpenBSD: ehci.c,v 1.141 2014/02/24 18:21:20 mpi Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
@@ -1041,6 +1041,13 @@ ehci_activate(struct device *self, int act)
rv = config_activate_children(self, act);
sc->sc_bus.use_polling++;
+ for (i = 1; i <= sc->sc_noport; i++) {
+ cmd = EOREAD4(sc, EHCI_PORTSC(i));
+ if ((cmd & (EHCI_PS_PO|EHCI_PS_PE)) == EHCI_PS_PE)
+ EOWRITE4(sc, EHCI_PORTSC(i),
+ cmd | EHCI_PS_SUSP);
+ }
+
/*
* First tell the host to stop processing Asynchronous
* and Periodic schedules.
@@ -1080,7 +1087,27 @@ ehci_activate(struct device *self, int act)
EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
EOWRITE4(sc, EHCI_ASYNCLISTADDR,
- sc->sc_async_head->physaddr | EHCI_LINK_QH);
+ sc->sc_async_head->physaddr | EHCI_LINK_QH);
+
+ hcr = 0;
+ for (i = 1; i <= sc->sc_noport; i++) {
+ cmd = EOREAD4(sc, EHCI_PORTSC(i));
+ if ((cmd & (EHCI_PS_PO|EHCI_PS_SUSP)) == EHCI_PS_SUSP) {
+ EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_FPR);
+ hcr = 1;
+ }
+ }
+
+ if (hcr) {
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
+ for (i = 1; i <= sc->sc_noport; i++) {
+ cmd = EOREAD4(sc, EHCI_PORTSC(i));
+ if ((cmd & (EHCI_PS_PO|EHCI_PS_SUSP)) ==
+ EHCI_PS_SUSP)
+ EOWRITE4(sc, EHCI_PORTSC(i),
+ cmd & ~EHCI_PS_FPR);
+ }
+ }
/* Turn on controller */
EOWRITE4(sc, EHCI_USBCMD,