static int ath10k_ahb_remove(struct platform_device *pdev) { struct ath10k *ar = platform_get_drvdata(pdev); struct ath10k_ahb *ar_ahb; if (!ar) return -EINVAL; ar_ahb = ath10k_ahb_priv(ar); if (!ar_ahb) return -EINVAL; ath10k_dbg(ar, ATH10K_DBG_AHB, "ahb remove\n"); ath10k_core_unregister(ar); ath10k_ahb_irq_disable(ar); ath10k_ahb_release_irq_legacy(ar); ath10k_pci_release_resource(ar); ath10k_ahb_halt_chip(ar); ath10k_ahb_clock_disable(ar); ath10k_ahb_resource_deinit(ar); ath10k_core_destroy(ar); platform_set_drvdata(pdev, NULL); return 0; }
static int athp_pci_detach(device_t dev) { struct ath10k_pci *ar_pci = device_get_softc(dev); struct ath10k *ar = &ar_pci->sc_sc; ath10k_warn(ar, "%s: called\n", __func__); /* Signal things we're going down.. */ ATHP_LOCK(ar); ar->sc_invalid = 1; ATHP_UNLOCK(ar); /* Shutdown ioctl handler */ athp_ioctl_teardown(ar); /* XXX TODO: synchronise with running things first */ /* * Do a config read to clear pre-existing pci error status. */ (void) pci_read_config(dev, PCIR_COMMAND, 4); /* stop/free the core - this detaches net80211 state */ ath10k_core_unregister(ar); /* kill tasklet(s) */ /* deinit irq - stop getting more interrupts */ ath10k_pci_deinit_irq(ar_pci); /* ce deinit */ ath10k_pci_ce_deinit(ar); /* free pipes */ ath10k_pci_free_pipes(ar); /* free HTT RX buffers */ ath10k_htt_rx_free_desc(ar, &ar->htt); /* pci release */ /* sleep sync */ /* buffers */ athp_pci_free_bufs(ar_pci); /* core itself - destroys taskqueues, etc */ ath10k_core_destroy(ar); /* Free bus resources */ bus_generic_detach(dev); /* Tear down interrupt */ ath10k_pci_free_irq(ar_pci); bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, ar_pci->sc_sr); /* XXX disable busmastering? */ /* Free BMI buffers */ athp_descdma_free(ar, &ar_pci->sc_bmi_txbuf); athp_descdma_free(ar, &ar_pci->sc_bmi_rxbuf); athp_trace_close(ar); /* Free locks */ mtx_destroy(&ar_pci->ps_mtx); mtx_destroy(&ar_pci->ce_mtx); mtx_destroy(&ar->sc_conf_mtx); mtx_destroy(&ar->sc_data_mtx); mtx_destroy(&ar->sc_buf_mtx); mtx_destroy(&ar->sc_dma_mtx); mtx_destroy(&ar->sc_mtx); /* Tear down the pipe taskqueue */ if (ar_pci->pipe_taskq) { taskqueue_drain_all(ar_pci->pipe_taskq); taskqueue_free(ar_pci->pipe_taskq); } return (0); }