Beispiel #1
0
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;
}
Beispiel #2
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);
}