|
@@ -56,6 +56,8 @@ static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info);
|
|
|
static void ath10k_pci_stop_ce(struct ath10k *ar);
|
|
|
static void ath10k_pci_device_reset(struct ath10k *ar);
|
|
|
static int ath10k_pci_reset_target(struct ath10k *ar);
|
|
|
+static int ath10k_pci_start_intr(struct ath10k *ar);
|
|
|
+static void ath10k_pci_stop_intr(struct ath10k *ar);
|
|
|
|
|
|
static const struct ce_attr host_ce_config_wlan[] = {
|
|
|
/* host->target HTC control and raw streams */
|
|
@@ -1254,10 +1256,25 @@ static void ath10k_pci_ce_deinit(struct ath10k *ar)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void ath10k_pci_disable_irqs(struct ath10k *ar)
|
|
|
+{
|
|
|
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++)
|
|
|
+ disable_irq(ar_pci->pdev->irq + i);
|
|
|
+}
|
|
|
+
|
|
|
static void ath10k_pci_hif_stop(struct ath10k *ar)
|
|
|
{
|
|
|
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
+
|
|
|
ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
|
|
|
|
|
|
+ /* Irqs are never explicitly re-enabled. They are implicitly re-enabled
|
|
|
+ * by ath10k_pci_start_intr(). */
|
|
|
+ ath10k_pci_disable_irqs(ar);
|
|
|
+
|
|
|
ath10k_pci_stop_ce(ar);
|
|
|
|
|
|
/* At this point, asynchronous threads are stopped, the target should
|
|
@@ -1267,6 +1284,8 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
|
|
|
ath10k_pci_process_ce(ar);
|
|
|
ath10k_pci_cleanup_ce(ar);
|
|
|
ath10k_pci_buffer_cleanup(ar);
|
|
|
+
|
|
|
+ ar_pci->started = 0;
|
|
|
}
|
|
|
|
|
|
static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
|
|
@@ -1742,6 +1761,12 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
|
|
|
{
|
|
|
int ret;
|
|
|
|
|
|
+ ret = ath10k_pci_start_intr(ar);
|
|
|
+ if (ret) {
|
|
|
+ ath10k_err("could not start interrupt handling (%d)\n", ret);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Bring the target up cleanly.
|
|
|
*
|
|
@@ -1756,7 +1781,7 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
|
|
|
|
|
|
ret = ath10k_pci_reset_target(ar);
|
|
|
if (ret)
|
|
|
- goto err;
|
|
|
+ goto err_irq;
|
|
|
|
|
|
if (ath10k_target_ps) {
|
|
|
ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save enabled\n");
|
|
@@ -1787,12 +1812,15 @@ err_ce:
|
|
|
err_ps:
|
|
|
if (!ath10k_target_ps)
|
|
|
ath10k_do_pci_sleep(ar);
|
|
|
+err_irq:
|
|
|
+ ath10k_pci_stop_intr(ar);
|
|
|
err:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
static void ath10k_pci_hif_power_down(struct ath10k *ar)
|
|
|
{
|
|
|
+ ath10k_pci_stop_intr(ar);
|
|
|
ath10k_pci_ce_deinit(ar);
|
|
|
if (!ath10k_target_ps)
|
|
|
ath10k_do_pci_sleep(ar);
|
|
@@ -2363,22 +2391,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|
|
|
|
|
ar_pci->cacheline_sz = dma_get_cache_alignment();
|
|
|
|
|
|
- ret = ath10k_pci_start_intr(ar);
|
|
|
- if (ret) {
|
|
|
- ath10k_err("could not start interrupt handling (%d)\n", ret);
|
|
|
- goto err_iomap;
|
|
|
- }
|
|
|
-
|
|
|
ret = ath10k_core_register(ar);
|
|
|
if (ret) {
|
|
|
ath10k_err("could not register driver core (%d)\n", ret);
|
|
|
- goto err_intr;
|
|
|
+ goto err_iomap;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
-err_intr:
|
|
|
- ath10k_pci_stop_intr(ar);
|
|
|
err_iomap:
|
|
|
pci_iounmap(pdev, mem);
|
|
|
err_master:
|
|
@@ -2415,7 +2435,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
|
|
|
tasklet_kill(&ar_pci->msi_fw_err);
|
|
|
|
|
|
ath10k_core_unregister(ar);
|
|
|
- ath10k_pci_stop_intr(ar);
|
|
|
|
|
|
pci_set_drvdata(pdev, NULL);
|
|
|
pci_iounmap(pdev, ar_pci->mem);
|