aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64/rockchip/rk_pcie.c
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2022-06-30 18:16:34 +0000
committerAndrew Turner <andrew@FreeBSD.org>2022-07-04 14:27:01 +0000
commitee2324aaf6e3256ef7396ef6063ec4261486ef94 (patch)
tree8ea364909dae9006669cacf06056f97cf8526275 /sys/arm64/rockchip/rk_pcie.c
parentb1e9313274265645e163508ff1704ace2e0b1294 (diff)
downloadsrc-ee2324aaf6e3256ef7396ef6063ec4261486ef94.tar.gz
src-ee2324aaf6e3256ef7396ef6063ec4261486ef94.zip
Add Rockchip PCIe cleanup on attach faulure
We should clean up on failure as it may panic the kernel later, e.g. if we crate the rman, but fail to destroy it on attach faulure. Reviewed by: imp Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D35682
Diffstat (limited to 'sys/arm64/rockchip/rk_pcie.c')
-rw-r--r--sys/arm64/rockchip/rk_pcie.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/sys/arm64/rockchip/rk_pcie.c b/sys/arm64/rockchip/rk_pcie.c
index 1711d52d2b3e..32f70a9c9b44 100644
--- a/sys/arm64/rockchip/rk_pcie.c
+++ b/sys/arm64/rockchip/rk_pcie.c
@@ -1162,7 +1162,7 @@ rk_pcie_attach(device_t dev)
/* 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 @@ rk_pcie_attach(device_t dev)
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 @@ rk_pcie_attach(device_t dev)
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 @@ rk_pcie_attach(device_t dev)
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 @@ rk_pcie_attach(device_t dev)
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);
}