diff --git a/sys/arm64/rockchip/rk_pcie.c b/sys/arm64/rockchip/rk_pcie.c --- a/sys/arm64/rockchip/rk_pcie.c +++ b/sys/arm64/rockchip/rk_pcie.c @@ -1162,7 +1162,7 @@ /* Read FDT properties */ rv = rk_pcie_parse_fdt_resources(sc); if (rv != 0) - return (rv); + goto out; sc->coherent = OF_hasprop(sc->node, "dma-coherent"); sc->no_l0s = OF_hasprop(sc->node, "aspm-no-l0s"); @@ -1283,21 +1283,21 @@ rv = rk_pcie_decode_ranges(sc, sc->ofw_pci.sc_range, sc->ofw_pci.sc_nrange); if (rv != 0) - goto out; + goto out_full; rv = rk_pcie_setup_hw(sc); if (rv != 0) - goto out; + goto out_full; rv = rk_pcie_setup_sw(sc); if (rv != 0) - goto out; + goto out_full; rv = bus_setup_intr(dev, sc->client_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, rk_pcie_client_irq, NULL, sc, &sc->client_irq_cookie); if (rv != 0) { device_printf(dev, "cannot setup client interrupt handler\n"); rv = ENXIO; - goto out; + goto out_full; } rv = bus_setup_intr(dev, sc->legacy_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, @@ -1305,7 +1305,7 @@ if (rv != 0) { device_printf(dev, "cannot setup client interrupt handler\n"); rv = ENXIO; - goto out; + goto out_full; } rv = bus_setup_intr(dev, sc->sys_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, @@ -1313,7 +1313,7 @@ if (rv != 0) { device_printf(dev, "cannot setup client interrupt handler\n"); rv = ENXIO; - goto out; + goto out_full; } /* Enable interrupts */ @@ -1344,8 +1344,42 @@ DELAY(250000); device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); + +out_full: + bus_teardown_intr(dev, sc->sys_irq_res, sc->sys_irq_cookie); + bus_teardown_intr(dev, sc->legacy_irq_res, sc->legacy_irq_cookie); + bus_teardown_intr(dev, sc->client_irq_res, sc->client_irq_cookie); + ofw_pcib_fini(dev); out: - /* XXX Cleanup */ + bus_dma_tag_destroy(sc->dmat); + bus_free_resource(dev, SYS_RES_IRQ, sc->sys_irq_res); + bus_free_resource(dev, SYS_RES_IRQ, sc->legacy_irq_res); + bus_free_resource(dev, SYS_RES_IRQ, sc->client_irq_res); + bus_free_resource(dev, SYS_RES_MEMORY, sc->apb_mem_res); + bus_free_resource(dev, SYS_RES_MEMORY, sc->axi_mem_res); + /* GPIO */ + gpio_pin_release(sc->gpio_ep); + /* Phys */ + for (int i = 0; i < MAX_LANES; i++) { + phy_release(sc->phys[i]); + } + /* Clocks */ + clk_release(sc->clk_aclk); + clk_release(sc->clk_aclk_perf); + clk_release(sc->clk_hclk); + clk_release(sc->clk_pm); + /* Resets */ + hwreset_release(sc->hwreset_core); + hwreset_release(sc->hwreset_mgmt); + hwreset_release(sc->hwreset_pipe); + hwreset_release(sc->hwreset_pm); + hwreset_release(sc->hwreset_aclk); + hwreset_release(sc->hwreset_pclk); + /* Regulators */ + regulator_release(sc->supply_12v); + regulator_release(sc->supply_3v3); + regulator_release(sc->supply_1v8); + regulator_release(sc->supply_0v9); return (rv); }