summaryrefslogtreecommitdiffstats
path: root/sys/arm/samsung
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2015-03-02 20:38:17 +0000
committerhselasky <hselasky@FreeBSD.org>2015-03-02 20:38:17 +0000
commit4f0a7fb0b170ca7894ac9ab92853da86521c956c (patch)
treec944406bc7f734c623a933f3bddf7dcc254770bf /sys/arm/samsung
parente549774cf351fd0017e15dc3bf8d672083a73919 (diff)
downloadFreeBSD-src-4f0a7fb0b170ca7894ac9ab92853da86521c956c.zip
FreeBSD-src-4f0a7fb0b170ca7894ac9ab92853da86521c956c.tar.gz
Update Exynos5 XHCI attach code after r276717.
MFC after: 3 days
Diffstat (limited to 'sys/arm/samsung')
-rw-r--r--sys/arm/samsung/exynos/exynos5_xhci.c124
1 files changed, 52 insertions, 72 deletions
diff --git a/sys/arm/samsung/exynos/exynos5_xhci.c b/sys/arm/samsung/exynos/exynos5_xhci.c
index ae581e5..87ecd8a 100644
--- a/sys/arm/samsung/exynos/exynos5_xhci.c
+++ b/sys/arm/samsung/exynos/exynos5_xhci.c
@@ -89,9 +89,9 @@ __FBSDID("$FreeBSD$");
#define GUSB3PIPECTL_SUSPHY (1 << 17)
/* Forward declarations */
-static int exynos_xhci_attach(device_t dev);
-static int exynos_xhci_detach(device_t dev);
-static int exynos_xhci_probe(device_t dev);
+static device_attach_t exynos_xhci_attach;
+static device_detach_t exynos_xhci_detach;
+static device_probe_t exynos_xhci_probe;
struct exynos_xhci_softc {
device_t dev;
@@ -152,13 +152,10 @@ exynos_xhci_probe(device_t dev)
static int
dwc3_init(struct exynos_xhci_softc *esc)
{
- struct xhci_softc *sc;
int hwparams1;
int rev;
int reg;
- sc = &esc->base;
-
rev = READ4(esc, GSNPSID);
if ((rev & GSNPSID_MASK) != 0x55330000) {
printf("It is not DWC3 controller\n");
@@ -210,32 +207,21 @@ dwc3_init(struct exynos_xhci_softc *esc)
static int
exynos_xhci_attach(device_t dev)
{
- struct exynos_xhci_softc *esc;
- struct xhci_softc *sc;
+ struct exynos_xhci_softc *esc = device_get_softc(dev);
bus_space_handle_t bsh;
int err;
- esc = device_get_softc(dev);
esc->dev = dev;
- sc = &esc->base;
-
- if (xhci_init(sc, dev)) {
- device_printf(dev, "Could not initialize softc\n");
- return (ENXIO);
- }
-
if (bus_alloc_resources(dev, exynos_xhci_spec, esc->res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
- usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0);
-
/* XHCI registers */
- sc->sc_io_tag = rman_get_bustag(esc->res[0]);
+ esc->base.sc_io_tag = rman_get_bustag(esc->res[0]);
bsh = rman_get_bushandle(esc->res[0]);
- sc->sc_io_size = rman_get_size(esc->res[0]);
+ esc->base.sc_io_size = rman_get_size(esc->res[0]);
/* DWC3 ctrl registers */
esc->bst = rman_get_bustag(esc->res[1]);
@@ -245,95 +231,89 @@ exynos_xhci_attach(device_t dev)
* Set handle to USB related registers subregion used by
* generic XHCI driver.
*/
- err = bus_space_subregion(sc->sc_io_tag, bsh, 0x0,
- sc->sc_io_size, &sc->sc_io_hdl);
- if (err != 0)
+ err = bus_space_subregion(esc->base.sc_io_tag, bsh, 0x0,
+ esc->base.sc_io_size, &esc->base.sc_io_hdl);
+ if (err != 0) {
+ device_printf(dev, "Subregion failed\n");
+ bus_release_resources(dev, exynos_xhci_spec, esc->res);
return (ENXIO);
+ }
+
+ if (xhci_init(&esc->base, dev)) {
+ device_printf(dev, "Could not initialize softc\n");
+ bus_release_resources(dev, exynos_xhci_spec, esc->res);
+ return (ENXIO);
+ }
/* Setup interrupt handler */
err = bus_setup_intr(dev, esc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (driver_intr_t *)xhci_interrupt, sc,
- &sc->sc_intr_hdl);
+ NULL, (driver_intr_t *)xhci_interrupt, &esc->base,
+ &esc->base.sc_intr_hdl);
if (err) {
device_printf(dev, "Could not setup irq, %d\n", err);
- return (1);
+ esc->base.sc_intr_hdl = NULL;
+ goto error;
}
/* Add USB device */
- sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
- if (!sc->sc_bus.bdev) {
+ esc->base.sc_bus.bdev = device_add_child(dev, "usbus", -1);
+ if (esc->base.sc_bus.bdev == NULL) {
device_printf(dev, "Could not add USB device\n");
- err = bus_teardown_intr(dev, esc->res[2],
- sc->sc_intr_hdl);
- if (err)
- device_printf(dev, "Could not tear down irq,"
- " %d\n", err);
- return (1);
+ goto error;
}
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
- strlcpy(sc->sc_vendor, "Samsung", sizeof(sc->sc_vendor));
+ device_set_ivars(esc->base.sc_bus.bdev, &esc->base.sc_bus);
+ strlcpy(esc->base.sc_vendor, "Samsung", sizeof(esc->base.sc_vendor));
dwc3_init(esc);
- err = xhci_halt_controller(sc);
+ err = xhci_halt_controller(&esc->base);
if (err == 0) {
device_printf(dev, "Starting controller\n");
- err = xhci_start_controller(sc);
+ err = xhci_start_controller(&esc->base);
}
-
if (err == 0) {
device_printf(dev, "Controller started\n");
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err == 0) {
- device_printf(dev, "Attached success\n");
- } else {
- device_printf(dev, "USB 3.0 init failed err=%d\n", err);
-
- device_delete_child(dev, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
-
- err = bus_teardown_intr(dev, esc->res[2],
- sc->sc_intr_hdl);
- if (err)
- device_printf(dev, "Could not tear down irq,"
- " %d\n", err);
- return (1);
+ err = device_probe_and_attach(esc->base.sc_bus.bdev);
}
+ if (err != 0)
+ goto error;
return (0);
+
+error:
+ exynos_xhci_detach(dev);
+ return (ENXIO);
}
static int
exynos_xhci_detach(device_t dev)
{
- struct exynos_xhci_softc *esc;
- struct xhci_softc *sc;
+ struct exynos_xhci_softc *esc = device_get_softc(dev);
+ device_t bdev;
int err;
- esc = device_get_softc(dev);
- sc = &esc->base;
+ if (esc->base.sc_bus.bdev != NULL) {
+ bdev = esc->base.sc_bus.bdev;
+ device_detach(bdev);
+ device_delete_child(dev, bdev);
+ }
+ /* During module unload there are lots of children leftover */
+ device_delete_children(dev);
- if (esc->res[2] && sc->sc_intr_hdl) {
+ xhci_halt_controller(&esc->base);
+
+ if (esc->res[2] && esc->base.sc_intr_hdl) {
err = bus_teardown_intr(dev, esc->res[2],
- sc->sc_intr_hdl);
+ esc->base.sc_intr_hdl);
if (err) {
- device_printf(dev, "Could not tear down irq,"
+ device_printf(dev, "Could not tear down IRQ,"
" %d\n", err);
return (err);
}
- sc->sc_intr_hdl = NULL;
- }
-
- if (sc->sc_bus.bdev) {
- device_delete_child(dev, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
}
- /* During module unload there are lots of children leftover */
- device_delete_children(dev);
-
bus_release_resources(dev, exynos_xhci_spec, esc->res);
+ xhci_uninit(&esc->base);
+
return (0);
}
OpenPOWER on IntegriCloud