Commit 7da6c042 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - Capture correct oemid-bits for eMMC cards
   - Fix error propagation for some ioctl commands
   - Hold retuning if SDIO is in 1-bit mode

  MMC host:
   - mtk-sd: Use readl_poll_timeout_atomic to not "schedule while atomic"
   - sdhci-msm: Correct minimum number of clocks
   - sdhci-pci-gli: Fix LPM negotiation so x86/S0ix SoCs can suspend
   - sdhci-sprd: Fix error code in sdhci_sprd_tuning()"

* tag 'mmc-v6.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: core: Capture correct oemid-bits for eMMC cards
  mmc: mtk-sd: Use readl_poll_timeout_atomic in msdc_reset_hw
  mmc: core: Fix error propagation for some ioctl commands
  mmc: sdhci-sprd: Fix error code in sdhci_sprd_tuning()
  mmc: sdhci-pci-gli: fix LPM negotiation so x86/S0ix SoCs can suspend
  mmc: core: sdio: hold retuning if sdio in 1-bit mode
  dt-bindings: mmc: sdhci-msm: correct minimum number of clocks
parents c3200081 84ee19bf
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ properties:
    maxItems: 4

  clocks:
    minItems: 3
    minItems: 2
    items:
      - description: Main peripheral bus clock, PCLK/HCLK - AHB Bus clock
      - description: SDC MMC clock, MCLK
+20 −11
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
			       struct mmc_queue *mq);
static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
static int mmc_spi_err_check(struct mmc_card *card);
static int mmc_blk_busy_cb(void *cb_data, bool *busy);

static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
{
@@ -470,7 +471,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
	struct mmc_data data = {};
	struct mmc_request mrq = {};
	struct scatterlist sg;
	bool r1b_resp, use_r1b_resp = false;
	bool r1b_resp;
	unsigned int busy_timeout_ms;
	int err;
	unsigned int target_part;
@@ -551,8 +552,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
	busy_timeout_ms = idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS;
	r1b_resp = (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B;
	if (r1b_resp)
		use_r1b_resp = mmc_prepare_busy_cmd(card->host, &cmd,
						    busy_timeout_ms);
		mmc_prepare_busy_cmd(card->host, &cmd, busy_timeout_ms);

	mmc_wait_for_req(card->host, &mrq);
	memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));
@@ -605,19 +605,28 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
	if (idata->ic.postsleep_min_us)
		usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us);

	/* No need to poll when using HW busy detection. */
	if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp)
		return 0;

	if (mmc_host_is_spi(card->host)) {
		if (idata->ic.write_flag || r1b_resp || cmd.flags & MMC_RSP_SPI_BUSY)
			return mmc_spi_err_check(card);
		return err;
	}
	/* Ensure RPMB/R1B command has completed by polling with CMD13. */
	if (idata->rpmb || r1b_resp)
		err = mmc_poll_for_busy(card, busy_timeout_ms, false,
					MMC_BUSY_IO);

	/*
	 * Ensure RPMB, writes and R1B responses are completed by polling with
	 * CMD13. Note that, usually we don't need to poll when using HW busy
	 * detection, but here it's needed since some commands may indicate the
	 * error through the R1 status bits.
	 */
	if (idata->rpmb || idata->ic.write_flag || r1b_resp) {
		struct mmc_blk_busy_data cb_data = {
			.card = card,
		};

		err = __mmc_poll_for_busy(card->host, 0, busy_timeout_ms,
					  &mmc_blk_busy_cb, &cb_data);

		idata->ic.response[0] = cb_data.status;
	}

	return err;
}
+1 −1
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ static int mmc_decode_cid(struct mmc_card *card)
	case 3: /* MMC v3.1 - v3.3 */
	case 4: /* MMC v4 */
		card->cid.manfid	= UNSTUFF_BITS(resp, 120, 8);
		card->cid.oemid		= UNSTUFF_BITS(resp, 104, 16);
		card->cid.oemid		= UNSTUFF_BITS(resp, 104, 8);
		card->cid.prod_name[0]	= UNSTUFF_BITS(resp, 96, 8);
		card->cid.prod_name[1]	= UNSTUFF_BITS(resp, 88, 8);
		card->cid.prod_name[2]	= UNSTUFF_BITS(resp, 80, 8);
+7 −1
Original line number Diff line number Diff line
@@ -1089,8 +1089,14 @@ static int mmc_sdio_resume(struct mmc_host *host)
		}
		err = mmc_sdio_reinit_card(host);
	} else if (mmc_card_wake_sdio_irq(host)) {
		/* We may have switched to 1-bit mode during suspend */
		/*
		 * We may have switched to 1-bit mode during suspend,
		 * need to hold retuning, because tuning only supprt
		 * 4-bit mode or 8 bit mode.
		 */
		mmc_retune_hold_now(host);
		err = sdio_enable_4bit_bus(host->card);
		mmc_retune_release(host);
	}

	if (err)
+3 −3
Original line number Diff line number Diff line
@@ -669,10 +669,10 @@ static void msdc_reset_hw(struct msdc_host *host)
	u32 val;

	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST);
	readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0);
	readl_poll_timeout_atomic(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0);

	sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR);
	readl_poll_timeout(host->base + MSDC_FIFOCS, val,
	readl_poll_timeout_atomic(host->base + MSDC_FIFOCS, val,
				  !(val & MSDC_FIFOCS_CLR), 0, 0);

	val = readl(host->base + MSDC_INT);
Loading