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

Commit 71fe5cca authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc:
  mmc: core: Fix deadlock when the CONFIG_MMC_UNSAFE_RESUME is not defined
  mmc: sdhci-s3c: Remove old and misprototyped suspend operations
  mmc: tmio: fix clock gating on platforms with a .set_pwr() method
  mmc: sh_mmcif: fix clock gating on platforms with a .down_pwr() method
  mmc: core: Fix typo at mmc_card_sleep
  mmc: core: Fix power_off_notify during suspend
  mmc: core: Fix setting power notify state variable for non-eMMC
  mmc: core: Add quirk for long data read time
  mmc: Add module.h include to sdhci-cns3xxx.c
  mmc: mxcmmc: fix falling back to PIO
  mmc: omap_hsmmc: DMA unmap only once in case of MMC error
parents dc47ce90 49df7807
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1606,6 +1606,14 @@ static const struct mmc_fixup blk_fixups[] =
		  MMC_QUIRK_BLK_NO_CMD23),
	MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
		  MMC_QUIRK_BLK_NO_CMD23),

	/*
	 * Some Micron MMC cards needs longer data read timeout than
	 * indicated in CSD.
	 */
	MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc,
		  MMC_QUIRK_LONG_READ_TIME),

	END_FIXUP
};

+64 −34
Original line number Diff line number Diff line
@@ -529,6 +529,18 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
			data->timeout_clks = 0;
		}
	}

	/*
	 * Some cards require longer data read timeout than indicated in CSD.
	 * Address this by setting the read timeout to a "reasonably high"
	 * value. For the cards tested, 300ms has proven enough. If necessary,
	 * this value can be increased if other problematic cards require this.
	 */
	if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) {
		data->timeout_ns = 300000000;
		data->timeout_clks = 0;
	}

	/*
	 * Some cards need very high timeouts if driven in SPI mode.
	 * The worst observed timeout was 900ms after writing a
@@ -1213,6 +1225,46 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
	mmc_host_clk_release(host);
}

static void mmc_poweroff_notify(struct mmc_host *host)
{
	struct mmc_card *card;
	unsigned int timeout;
	unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
	int err = 0;

	card = host->card;

	/*
	 * Send power notify command only if card
	 * is mmc and notify state is powered ON
	 */
	if (card && mmc_card_mmc(card) &&
	    (card->poweroff_notify_state == MMC_POWERED_ON)) {

		if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
			notify_type = EXT_CSD_POWER_OFF_SHORT;
			timeout = card->ext_csd.generic_cmd6_time;
			card->poweroff_notify_state = MMC_POWEROFF_SHORT;
		} else {
			notify_type = EXT_CSD_POWER_OFF_LONG;
			timeout = card->ext_csd.power_off_longtime;
			card->poweroff_notify_state = MMC_POWEROFF_LONG;
		}

		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
				 EXT_CSD_POWER_OFF_NOTIFICATION,
				 notify_type, timeout);

		if (err && err != -EBADMSG)
			pr_err("Device failed to respond within %d poweroff "
			       "time. Forcefully powering down the device\n",
			       timeout);

		/* Set the card state to no notification after the poweroff */
		card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
	}
}

/*
 * Apply power to the MMC stack.  This is a two-stage process.
 * First, we enable power to the card without the clock running.
@@ -1269,42 +1321,12 @@ static void mmc_power_up(struct mmc_host *host)

void mmc_power_off(struct mmc_host *host)
{
	struct mmc_card *card;
	unsigned int notify_type;
	unsigned int timeout;
	int err;

	mmc_host_clk_hold(host);

	card = host->card;
	host->ios.clock = 0;
	host->ios.vdd = 0;

	if (card && mmc_card_mmc(card) &&
	    (card->poweroff_notify_state == MMC_POWERED_ON)) {

		if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
			notify_type = EXT_CSD_POWER_OFF_SHORT;
			timeout = card->ext_csd.generic_cmd6_time;
			card->poweroff_notify_state = MMC_POWEROFF_SHORT;
		} else {
			notify_type = EXT_CSD_POWER_OFF_LONG;
			timeout = card->ext_csd.power_off_longtime;
			card->poweroff_notify_state = MMC_POWEROFF_LONG;
		}

		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
				 EXT_CSD_POWER_OFF_NOTIFICATION,
				 notify_type, timeout);

		if (err && err != -EBADMSG)
			pr_err("Device failed to respond within %d poweroff "
			       "time. Forcefully powering down the device\n",
			       timeout);

		/* Set the card state to no notification after the poweroff */
		card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
	}
	mmc_poweroff_notify(host);

	/*
	 * Reset ocr mask to be the highest possible voltage supported for
@@ -2196,7 +2218,7 @@ int mmc_card_sleep(struct mmc_host *host)

	mmc_bus_get(host);

	if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
	if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
		err = host->bus_ops->sleep(host);

	mmc_bus_put(host);
@@ -2302,8 +2324,17 @@ int mmc_suspend_host(struct mmc_host *host)
		 * pre-claim the host.
		 */
		if (mmc_try_claim_host(host)) {
			if (host->bus_ops->suspend)
			if (host->bus_ops->suspend) {
				/*
				 * For eMMC 4.5 device send notify command
				 * before sleep, because in sleep state eMMC 4.5
				 * devices respond to only RESET and AWAKE cmd
				 */
				mmc_poweroff_notify(host);
				err = host->bus_ops->suspend(host);
			}
			mmc_do_release_host(host);

			if (err == -ENOSYS || !host->bus_ops->resume) {
				/*
				 * We simply "remove" the card in this case.
@@ -2318,7 +2349,6 @@ int mmc_suspend_host(struct mmc_host *host)
				host->pm_flags = 0;
				err = 0;
			}
			mmc_do_release_host(host);
		} else {
			err = -EBUSY;
		}
+8 −4
Original line number Diff line number Diff line
@@ -876,17 +876,21 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
	 * set the notification byte in the ext_csd register of device
	 */
	if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) &&
	    (card->poweroff_notify_state == MMC_NO_POWER_NOTIFICATION)) {
	    (card->ext_csd.rev >= 6)) {
		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
				 EXT_CSD_POWER_OFF_NOTIFICATION,
				 EXT_CSD_POWER_ON,
				 card->ext_csd.generic_cmd6_time);
		if (err && err != -EBADMSG)
			goto free_card;
	}

		/*
		 * The err can be -EBADMSG or 0,
		 * so check for success and update the flag
		 */
		if (!err)
			card->poweroff_notify_state = MMC_POWERED_ON;
	}

	/*
	 * Activate high speed (if supported)
+1 −0
Original line number Diff line number Diff line
@@ -732,6 +732,7 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
				"failed to config DMA channel. Falling back to PIO\n");
			dma_release_channel(host->dma);
			host->do_dma = 0;
			host->dma = NULL;
		}
	}

+5 −2
Original line number Diff line number Diff line
@@ -1010,6 +1010,7 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
			host->data->sg_len,
			omap_hsmmc_get_dma_dir(host, host->data));
		omap_free_dma(dma_ch);
		host->data->host_cookie = 0;
	}
	host->data = NULL;
}
@@ -1575,7 +1576,9 @@ static void omap_hsmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
	struct mmc_data *data = mrq->data;

	if (host->use_dma) {
		dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
		if (data->host_cookie)
			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
				     data->sg_len,
				     omap_hsmmc_get_dma_dir(host, data));
		data->host_cookie = 0;
	}
Loading