Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa6d7ed7 authored by Ram Prakash Gupta's avatar Ram Prakash Gupta
Browse files

mmc: sdhci-msm: Use auto suspend instead of sync



With use of sync suspend, driver is going to suspend
in atomic context which is not permitted and leading to
below below stack.

pc : __schedule_bug
lr : __schedule_bug
Call trace:
__schedule_bug
__schedule
schedule
rpm_suspend
__pm_runtime_suspend
mmc_release_host
mmc_put_card
mmc_blk_cqe_complete_rq
mmc_blk_mq_complete
blk_done_softirq

To avoid this use auto suspend.

Change-Id: Ie19c06ba07c8340faefebbde9810e65dc11ec6b2
Signed-off-by: default avatarRam Prakash Gupta <rampraka@codeaurora.org>
parent 295a7cb9
Loading
Loading
Loading
Loading
+6 −26
Original line number Diff line number Diff line
@@ -145,8 +145,7 @@
#define CMUX_SHIFT_PHASE_SHIFT	24
#define CMUX_SHIFT_PHASE_MASK	(7 << CMUX_SHIFT_PHASE_SHIFT)

#define MSM_MMC_AUTOSUSPEND_DELAY_MS	50
#define MSM_PMQOS_UNVOTING_DELAY_MS	10 /* msec */
#define MSM_MMC_AUTOSUSPEND_DELAY_MS	10
#define MSM_CLK_GATING_DELAY_MS		200 /* msec */

/* Timeout value to avoid infinite waiting for pwr_irq */
@@ -441,7 +440,6 @@ struct sdhci_msm_host {
	bool skip_bus_bw_voting;
	struct sdhci_msm_bus_vote_data *bus_vote_data;
	struct delayed_work bus_vote_work;
	struct delayed_work pmqos_unvote_work;
	struct delayed_work clk_gating_work;
	bool pltfm_init_done;
	bool core_3_0v_support;
@@ -3573,10 +3571,8 @@ static int add_group_qos(struct qos_cpu_group *qcg, enum constraint type)
}

/* Function to remove pm qos vote */
static void sdhci_msm_unvote_qos_all(struct work_struct *work)
static void sdhci_msm_unvote_qos_all(struct sdhci_msm_host *msm_host)
{
	struct sdhci_msm_host *msm_host = container_of(work,
			struct sdhci_msm_host, pmqos_unvote_work.work);
	struct sdhci_msm_qos_req *qos_req = msm_host->sdhci_qos;
	struct qos_cpu_group *qcg;
	int i, err;
@@ -3654,7 +3650,6 @@ sdhci_msm_irq_affinity_notify(struct irq_affinity_notify *notify,
					mmc_hostname(msm_host->mmc), err, i);
	}

	cancel_delayed_work_sync(&msm_host->pmqos_unvote_work);
	sdhci_msm_vote_pmqos(msm_host->mmc,
			msm_host->sdhci_qos->active_mask);
}
@@ -3717,9 +3712,6 @@ static int sdhci_msm_setup_qos(struct sdhci_msm_host *msm_host)
				 __func__, qcg, qcg->mask);
	}

	INIT_DELAYED_WORK(&msm_host->pmqos_unvote_work,
			sdhci_msm_unvote_qos_all);

	/* Vote pmqos during setup for first set of mask*/
	sdhci_msm_update_qos_constraints(qr->qcg, QOS_PERF);
	qr->active_mask = cpumask_first(&qr->qcg->mask);
@@ -4040,7 +4032,7 @@ static int sdhci_msm_init_sysfs(struct platform_device *pdev)

static void sdhci_msm_set_caps(struct sdhci_msm_host *msm_host)
{
	msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM | MMC_CAP_SYNC_RUNTIME_PM;
	msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM;
	msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
}

@@ -4309,7 +4301,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
		dev_err(&pdev->dev, "Generic swq creation failed\n");

	msm_host->clk_gating_delay = MSM_CLK_GATING_DELAY_MS;
	msm_host->pm_qos_delay = MSM_PMQOS_UNVOTING_DELAY_MS;
	msm_host->pm_qos_delay = MSM_MMC_AUTOSUSPEND_DELAY_MS;
	/* Initialize pmqos */
	sdhci_msm_qos_init(msm_host);
	/* Initialize sysfs entries */
@@ -4419,9 +4411,7 @@ static __maybe_unused int sdhci_msm_runtime_suspend(struct device *dev)

	if (!qos_req)
		goto skip_qos;
	queue_delayed_work(msm_host->workq,
			&msm_host->pmqos_unvote_work,
			msecs_to_jiffies(msm_host->pm_qos_delay));
	sdhci_msm_unvote_qos_all(msm_host);

skip_qos:
	queue_delayed_work(msm_host->workq,
@@ -4461,8 +4451,6 @@ static __maybe_unused int sdhci_msm_runtime_resume(struct device *dev)

	if (!qos_req)
		return 0;
	ret = cancel_delayed_work_sync(&msm_host->pmqos_unvote_work);
	if (!ret)
	sdhci_msm_vote_pmqos(msm_host->mmc,
					msm_host->sdhci_qos->active_mask);

@@ -4475,14 +4463,6 @@ static int sdhci_msm_suspend_late(struct device *dev)
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);

	if (!msm_host->sdhci_qos)
		goto skip_qos;

	if (flush_delayed_work(&msm_host->pmqos_unvote_work))
		dev_dbg(dev, "%s Waited for pmqos_unvote_work to finish\n",
			 __func__);

skip_qos:
	if (flush_delayed_work(&msm_host->clk_gating_work))
		dev_dbg(dev, "%s Waited for clk_gating_work to finish\n",
			 __func__);