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

Commit 58f18403 authored by Maya Erez's avatar Maya Erez Committed by Gerrit - the friendly Code Review server
Browse files

Revert "mmc: host: disable only sdhci irqs in sdhci_request"



This reverts commit b680bce5.

Spin lock recursion introduced, when SD card inserted during sdhci
transaction, because it is not enough to disable sdhci irq and power irq,
besides this card detect irq need to be disabled.

Change-Id: If6aa64e9d92aec70237ab8fe72a6ea7c212530b9
CRs-Fixed: 744511
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
Signed-off-by: default avatarKonstantin Dorfman <kdorfman@codeaurora.org>
parent 9b2ed4b6
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -2459,16 +2459,7 @@ out:
	return rc;
}

static void sdhci_msm_cfg_power_irq(struct sdhci_host *host, bool enable)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;

	if (enable)
		enable_irq(msm_host->pwr_irq);
	else
		disable_irq(msm_host->pwr_irq);
}

static int sdhci_msm_prepare_clocks(struct sdhci_host *host, bool enable)
{
@@ -2909,7 +2900,6 @@ static struct sdhci_ops sdhci_msm_ops = {
	.dump_vendor_regs = sdhci_msm_dump_vendor_regs,
	.config_auto_tuning_cmd = sdhci_msm_config_auto_tuning_cmd,
	.enable_controller_clock = sdhci_msm_enable_controller_clock,
	.cfg_power_irq = sdhci_msm_cfg_power_irq,
};

static int sdhci_msm_cfg_mpm_pin_wakeup(struct sdhci_host *host, unsigned mode)
+20 −37
Original line number Diff line number Diff line
@@ -1633,39 +1633,11 @@ static int sdhci_get_tuning_cmd(struct sdhci_host *host)
		return MMC_SEND_TUNING_BLOCK;
}

static void sdhci_cfg_irq(struct sdhci_host *host, bool enable, bool sync)
{
	if (enable && !host->irq_enabled) {
		enable_irq(host->irq);
		host->irq_enabled = true;
	} else if (!enable && host->irq_enabled) {
		if (sync)
			disable_irq(host->irq);
		else
			disable_irq_nosync(host->irq);
		host->irq_enabled = false;
	}
}

#define SDHCI_SPIN_LOCK(host, enable)					\
	do {								\
		if (enable) {						\
			sdhci_cfg_irq(host, !enable, true);		\
			if (host->ops->cfg_power_irq)			\
				host->ops->cfg_power_irq(host, !enable);\
			spin_lock(&host->lock);				\
		} else {						\
			spin_unlock(&host->lock);			\
			sdhci_cfg_irq(host, !enable, true);		\
			if (host->ops->cfg_power_irq)			\
				host->ops->cfg_power_irq(host, !enable);\
		}							\
	} while (0)

static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct sdhci_host *host;
	int present;
	unsigned long flags;
	u32 tuning_opcode;

	host = mmc_priv(mmc);
@@ -1699,7 +1671,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
					SDHCI_CARD_PRESENT;
	}

	SDHCI_SPIN_LOCK(host, true);
	spin_lock_irqsave(&host->lock, flags);

	WARN_ON(host->mrq != NULL);

@@ -1745,9 +1717,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
					MMC_SEND_TUNING_BLOCK;
				host->mrq = NULL;
				host->flags &= ~SDHCI_NEEDS_RETUNING;
				SDHCI_SPIN_LOCK(host, false);
				spin_unlock_irqrestore(&host->lock, flags);
				sdhci_execute_tuning(mmc, tuning_opcode);
				SDHCI_SPIN_LOCK(host, true);
				spin_lock_irqsave(&host->lock, flags);

				/* Restore original mmc_request structure */
				host->mrq = mrq;
@@ -1770,7 +1742,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
	}

	mmiowb();
	SDHCI_SPIN_LOCK(host, false);
	spin_unlock_irqrestore(&host->lock, flags);
}

static void sdhci_cfg_async_intr(struct sdhci_host *host, bool enable)
@@ -1789,6 +1761,17 @@ static void sdhci_cfg_async_intr(struct sdhci_host *host, bool enable)
			     SDHCI_HOST_CONTROL2);
}

static void sdhci_cfg_irq(struct sdhci_host *host, bool enable)
{
	if (enable && !host->irq_enabled) {
		enable_irq(host->irq);
		host->irq_enabled = true;
	} else if (!enable && host->irq_enabled) {
		disable_irq_nosync(host->irq);
		host->irq_enabled = false;
	}
}

static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
{
	unsigned long flags;
@@ -1806,7 +1789,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)

	spin_lock_irqsave(&host->lock, flags);
	/* lock is being released intermittently below, hence disable irq */
	sdhci_cfg_irq(host, false, false);
	sdhci_cfg_irq(host, false);
	spin_unlock_irqrestore(&host->lock, flags);
	if (ios->clock) {
		sdhci_set_clock(host, ios->clock);
@@ -1849,7 +1832,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
	}
	spin_lock_irqsave(&host->lock, flags);
	if (!host->clock) {
		sdhci_cfg_irq(host, true, false);
		sdhci_cfg_irq(host, true);
		spin_unlock_irqrestore(&host->lock, flags);
		mutex_unlock(&host->ios_mutex);
		return;
@@ -2030,7 +2013,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
		sdhci_set_clock(host, ios->clock);
	}
	spin_lock_irqsave(&host->lock, flags);
	sdhci_cfg_irq(host, true, false);
	sdhci_cfg_irq(host, true);
	spin_unlock_irqrestore(&host->lock, flags);
	mmiowb();
	mutex_unlock(&host->ios_mutex);
@@ -3017,7 +3000,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
	if (!host->clock && host->mmc->card &&
	    mmc_card_sdio(host->mmc->card)) {
		/* SDIO async. interrupt is level-sensitive */
		sdhci_cfg_irq(host, false, false);
		sdhci_cfg_irq(host, false);
		pr_debug("%s: got async-irq: clocks: %d gated: %d host-irq[en:1/dis:0]: %d\n",
			mmc_hostname(host->mmc), host->clock,
			host->mmc->clk_gated, host->irq_enabled);
+0 −1
Original line number Diff line number Diff line
@@ -321,7 +321,6 @@ struct sdhci_ops {
					  bool enable,
					  u32 type);
	int	(*enable_controller_clock)(struct sdhci_host *host);
	void	(*cfg_power_irq)(struct sdhci_host *host, bool enable);
};

#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS