-/* $OpenBSD: xhci_fdt.c,v 1.23 2023/04/03 01:55:00 dlg Exp $ */
+/* $OpenBSD: xhci_fdt.c,v 1.24 2023/07/23 11:49:17 kettenis Exp $ */
/*
* Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
*
int xhci_fdt_match(struct device *, void *, void *);
void xhci_fdt_attach(struct device *, struct device *, void *);
+int xhci_fdt_activate(struct device *, int);
const struct cfattach xhci_fdt_ca = {
sizeof(struct xhci_fdt_softc), xhci_fdt_match, xhci_fdt_attach, NULL,
- xhci_activate
+ xhci_fdt_activate
};
-int xhci_cdns_init(struct xhci_fdt_softc *);
+int xhci_cdns_attach(struct xhci_fdt_softc *);
+int xhci_snps_attach(struct xhci_fdt_softc *);
int xhci_snps_init(struct xhci_fdt_softc *);
void xhci_init_phys(struct xhci_fdt_softc *);
* functionality.
*/
if (OF_is_compatible(sc->sc_node, "cdns,usb3"))
- error = xhci_cdns_init(sc);
+ error = xhci_cdns_attach(sc);
if (OF_is_compatible(sc->sc_node, "snps,dwc3"))
- error = xhci_snps_init(sc);
+ error = xhci_snps_attach(sc);
if (error) {
printf(": can't initialize hardware\n");
goto disestablish_ret;
bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
}
+int
+xhci_fdt_activate(struct device *self, int act)
+{
+ struct xhci_fdt_softc *sc = (struct xhci_fdt_softc *)self;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_POWERDOWN:
+ rv = xhci_activate(self, act);
+ power_domain_disable(sc->sc_node);
+ break;
+ case DVACT_RESUME:
+ power_domain_enable(sc->sc_node);
+ if (OF_is_compatible(sc->sc_node, "snps,dwc3"))
+ xhci_snps_init(sc);
+ rv = xhci_activate(self, act);
+ break;
+ default:
+ rv = xhci_activate(self, act);
+ break;
+ }
+
+ return rv;
+}
+
/*
* Cadence USB3 controller.
*/
#define OTG_STS_XHCI_READY (1 << 26)
int
-xhci_cdns_init(struct xhci_fdt_softc *sc)
+xhci_cdns_attach(struct xhci_fdt_softc *sc)
{
uint32_t did, sts;
int timo;
}
int
-xhci_snps_init(struct xhci_fdt_softc *sc)
+xhci_snps_attach(struct xhci_fdt_softc *sc)
{
- char phy_type[16] = { 0 };
- int node = sc->sc_node;
- uint32_t reg;
-
/*
* On Apple hardware we need to reset the controller when we
* see a new connection.
*/
- if (OF_is_compatible(node, "apple,dwc3")) {
+ if (OF_is_compatible(sc->sc_node, "apple,dwc3")) {
sc->sc_usb_controller_port.up_cookie = sc;
sc->sc_usb_controller_port.up_connect = xhci_snps_connect;
task_set(&sc->sc_snps_connect_task, xhci_snps_do_connect, sc);
- sc->sc_ports.dp_node = node;
+ sc->sc_ports.dp_node = sc->sc_node;
sc->sc_ports.dp_cookie = &sc->sc_usb_controller_port;
sc->sc_ports.dp_ep_get_cookie = xhci_snps_ep_get_cookie;
device_ports_register(&sc->sc_ports, EP_USB_CONTROLLER_PORT);
}
+ return xhci_snps_init(sc);
+}
+
+int
+xhci_snps_init(struct xhci_fdt_softc *sc)
+{
+ char phy_type[16] = { 0 };
+ int node = sc->sc_node;
+ uint32_t reg;
+
/* We don't support device mode, so always force host mode. */
reg = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USB3_GCTL);
reg &= ~USB3_GCTL_PRTCAPDIR_MASK;