summaryrefslogtreecommitdiff
path: root/sys/arch/arm/xscale/pxa2x0_ohci.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2005-03-30 14:24:40 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2005-03-30 14:24:40 +0000
commit8887acff246fd9c44af093d31c0643b73d4b2184 (patch)
tree8e1008f108a9021f1ac6e80a615a803fbae8a948 /sys/arch/arm/xscale/pxa2x0_ohci.c
parent1ecd922a40cf3efdd2f45cdc3bf870b7be0bd249 (diff)
extra gunk to make ohci suspend and resume work on the zaurus
help from and ok uwe@
Diffstat (limited to 'sys/arch/arm/xscale/pxa2x0_ohci.c')
-rw-r--r--sys/arch/arm/xscale/pxa2x0_ohci.c96
1 files changed, 66 insertions, 30 deletions
diff --git a/sys/arch/arm/xscale/pxa2x0_ohci.c b/sys/arch/arm/xscale/pxa2x0_ohci.c
index a635a003e68..03f6bce7e78 100644
--- a/sys/arch/arm/xscale/pxa2x0_ohci.c
+++ b/sys/arch/arm/xscale/pxa2x0_ohci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_ohci.c,v 1.14 2005/03/30 14:02:02 dlg Exp $ */
+/* $OpenBSD: pxa2x0_ohci.c,v 1.15 2005/03/30 14:24:39 dlg Exp $ */
/*
* Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
@@ -39,12 +39,15 @@
int pxaohci_match(struct device *, void *, void *);
void pxaohci_attach(struct device *, struct device *, void *);
int pxaohci_detach(struct device *, int);
+void pxaohci_power(int, void *);
struct pxaohci_softc {
ohci_softc_t sc;
void *sc_ih;
};
+void pxaohci_enable(struct pxaohci_softc *);
+
struct cfattach pxaohci_ca = {
sizeof (struct pxaohci_softc), pxaohci_match, pxaohci_attach,
pxaohci_detach, ohci_activate
@@ -64,7 +67,6 @@ pxaohci_attach(struct device *parent, struct device *self, void *aux)
{
struct pxaohci_softc *sc = (struct pxaohci_softc *)self;
struct pxaip_attach_args *pxa = aux;
- u_int32_t hr;
usbd_status r;
sc->sc.iot = pxa->pxa_iot;
@@ -86,34 +88,7 @@ pxaohci_attach(struct device *parent, struct device *self, void *aux)
/* start the usb clock */
pxa2x0_clkman_config(CKEN_USBHC, 1);
-
- /* Full host reset */
- hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
- bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
- (hr & USBHC_HR_MASK) | USBHC_HR_FHR);
-
- DELAY(mstohz(USBHC_RST_WAIT));
-
- hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
- bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
- (hr & USBHC_HR_MASK) & ~(USBHC_HR_FHR));
-
- /* Force system bus interface reset */
- hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
- bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
- (hr & USBHC_HR_MASK) | USBHC_HR_FSBIR);
-
- while (bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR) & \
- USBHC_HR_FSBIR)
- DELAY(3);
-
- /* Enable the ports (physically only one, only enable that one?) */
- hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
- bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
- (hr & USBHC_HR_MASK) & ~(USBHC_HR_SSE));
- hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
- bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
- (hr & USBHC_HR_MASK) & ~(USBHC_HR_SSEP2));
+ pxaohci_enable(sc);
/* Disable interrupts, so we don't get any spurious ones. */
bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
@@ -178,3 +153,64 @@ pxaohci_detach(struct device *self, int flags)
return (0);
}
+
+
+void
+pxaohci_power(int why, void *arg)
+{
+ struct pxaohci_softc *sc = (struct pxaohci_softc *)arg;
+ int s;
+
+ s = splhardusb();
+ sc->sc.sc_bus.use_polling++;
+ switch (why) {
+ case PWR_STANDBY:
+ case PWR_SUSPEND:
+ ohci_power(why, arg);
+ pxa2x0_clkman_config(CKEN_USBHC, 0);
+ break;
+
+ case PWR_RESUME:
+ pxa2x0_clkman_config(CKEN_USBHC, 1);
+ pxaohci_enable(sc);
+ ohci_power(why, arg);
+ break;
+ }
+ sc->sc.sc_bus.use_polling--;
+ splx(s);
+}
+
+void
+pxaohci_enable(struct pxaohci_softc *sc)
+{
+ u_int32_t hr;
+
+ /* Full host reset */
+ hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
+ bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
+ (hr & USBHC_HR_MASK) | USBHC_HR_FHR);
+
+ DELAY(mstohz(USBHC_RST_WAIT));
+
+ hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
+ bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
+ (hr & USBHC_HR_MASK) & ~(USBHC_HR_FHR));
+
+ /* Force system bus interface reset */
+ hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
+ bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
+ (hr & USBHC_HR_MASK) | USBHC_HR_FSBIR);
+
+ while (bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR) & \
+ USBHC_HR_FSBIR)
+ DELAY(3);
+
+ /* Enable the ports (physically only one, only enable that one?) */
+ hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
+ bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
+ (hr & USBHC_HR_MASK) & ~(USBHC_HR_SSE));
+ hr = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USBHC_HR);
+ bus_space_write_4(sc->sc.iot, sc->sc.ioh, USBHC_HR,
+ (hr & USBHC_HR_MASK) & ~(USBHC_HR_SSEP2));
+}
+