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

Commit 904a9802 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'mmc-v3.19-3' of git://git.linaro.org/people/ulf.hansson/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC host:
   - sdhci-pci|acpi: Support some new IDs
   - sdhci: Fix sleep from atomic context
   - sdhci-pxav3: Prevent hang during ->probe()
   - sdhci: Disable re-tuning for HS400"

* tag 'mmc-v3.19-3' of git://git.linaro.org/people/ulf.hansson/mmc:
  mmc: sdhci-pci: Add support for Intel SPT
  mmc: sdhci-acpi: Add ACPI HID INT344D
  mmc: sdhci: Fix sleep in atomic after inserting SD card
  mmc: sdhci-pxav3: do the mbus window configuration after enabling clocks
  mmc: sdhci: Disable re-tuning for HS400
  mmc: sdhci: Simplify use of tuning timer
  mmc: sdhci: Add out_unlock to sdhci_execute_tuning
  mmc: sdhci: Tuning should not change max_blk_count
parents fb43bd08 1f7f2652
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
	{ "INT33BB"  , "3" , &sdhci_acpi_slot_int_sd },
	{ "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },
	{ "INT3436"  , NULL, &sdhci_acpi_slot_int_sdio },
	{ "INT344D"  , NULL, &sdhci_acpi_slot_int_sdio },
	{ "PNP0D40"  },
	{ },
};
@@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = {
	{ "INT33BB"  },
	{ "INT33C6"  },
	{ "INT3436"  },
	{ "INT344D"  },
	{ "PNP0D40"  },
	{ },
};
+25 −0
Original line number Diff line number Diff line
@@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = {
		.subdevice	= PCI_ANY_ID,
		.driver_data	= (kernel_ulong_t)&sdhci_intel_mrfl_mmc,
	},

	{
		.vendor		= PCI_VENDOR_ID_INTEL,
		.device		= PCI_DEVICE_ID_INTEL_SPT_EMMC,
		.subvendor	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_emmc,
	},

	{
		.vendor		= PCI_VENDOR_ID_INTEL,
		.device		= PCI_DEVICE_ID_INTEL_SPT_SDIO,
		.subvendor	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sdio,
	},

	{
		.vendor		= PCI_VENDOR_ID_INTEL,
		.device		= PCI_DEVICE_ID_INTEL_SPT_SD,
		.subvendor	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sd,
	},

	{
		.vendor		= PCI_VENDOR_ID_O2,
		.device		= PCI_DEVICE_ID_O2_8120,
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@
#define PCI_DEVICE_ID_INTEL_CLV_EMMC0	0x08e5
#define PCI_DEVICE_ID_INTEL_CLV_EMMC1	0x08e6
#define PCI_DEVICE_ID_INTEL_QRK_SD	0x08A7
#define PCI_DEVICE_ID_INTEL_SPT_EMMC	0x9d2b
#define PCI_DEVICE_ID_INTEL_SPT_SDIO	0x9d2c
#define PCI_DEVICE_ID_INTEL_SPT_SD	0x9d2d

/*
 * PCI registers
+7 −8
Original line number Diff line number Diff line
@@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
	if (IS_ERR(host))
		return PTR_ERR(host);

	if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
		ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
		if (ret < 0)
			goto err_mbus_win;
	}


	pltfm_host = sdhci_priv(host);
	pltfm_host->priv = pxa;

@@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
	if (!IS_ERR(pxa->clk_core))
		clk_prepare_enable(pxa->clk_core);

	if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
		ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
		if (ret < 0)
			goto err_mbus_win;
	}

	/* enable 1/8V DDR capable */
	host->mmc->caps |= MMC_CAP_1_8V_DDR;

@@ -396,11 +395,11 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
	pm_runtime_disable(&pdev->dev);
err_of_parse:
err_cd_req:
err_mbus_win:
	clk_disable_unprepare(pxa->clk_io);
	if (!IS_ERR(pxa->clk_core))
		clk_disable_unprepare(pxa->clk_core);
err_clk_get:
err_mbus_win:
	sdhci_pltfm_free(pdev);
	return ret;
}
+48 −26
Original line number Diff line number Diff line
@@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host)

		del_timer_sync(&host->tuning_timer);
		host->flags &= ~SDHCI_NEEDS_RETUNING;
		host->mmc->max_blk_count =
			(host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
	}
	sdhci_enable_card_detection(host);
}
@@ -1353,6 +1351,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)

	sdhci_runtime_pm_get(host);

	present = mmc_gpio_get_cd(host->mmc);

	spin_lock_irqsave(&host->lock, flags);

	WARN_ON(host->mrq != NULL);
@@ -1381,7 +1381,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
	 *     zero: cd-gpio is used, and card is removed
	 *     one: cd-gpio is used, and card is present
	 */
	present = mmc_gpio_get_cd(host->mmc);
	if (present < 0) {
		/* If polling, assume that the card is always present. */
		if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
@@ -1880,6 +1879,18 @@ static int sdhci_card_busy(struct mmc_host *mmc)
	return !(present_state & SDHCI_DATA_LVL_MASK);
}

static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct sdhci_host *host = mmc_priv(mmc);
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);
	host->flags |= SDHCI_HS400_TUNING;
	spin_unlock_irqrestore(&host->lock, flags);

	return 0;
}

static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
	struct sdhci_host *host = mmc_priv(mmc);
@@ -1887,10 +1898,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
	int tuning_loop_counter = MAX_TUNING_LOOP;
	int err = 0;
	unsigned long flags;
	unsigned int tuning_count = 0;
	bool hs400_tuning;

	sdhci_runtime_pm_get(host);
	spin_lock_irqsave(&host->lock, flags);

	hs400_tuning = host->flags & SDHCI_HS400_TUNING;
	host->flags &= ~SDHCI_HS400_TUNING;

	if (host->tuning_mode == SDHCI_TUNING_MODE_1)
		tuning_count = host->tuning_count;

	/*
	 * The Host Controller needs tuning only in case of SDR104 mode
	 * and for SDR50 mode when Use Tuning for SDR50 is set in the
@@ -1899,8 +1918,20 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
	 * tuning function has to be executed.
	 */
	switch (host->timing) {
	/* HS400 tuning is done in HS200 mode */
	case MMC_TIMING_MMC_HS400:
		err = -EINVAL;
		goto out_unlock;

	case MMC_TIMING_MMC_HS200:
		/*
		 * Periodic re-tuning for HS400 is not expected to be needed, so
		 * disable it here.
		 */
		if (hs400_tuning)
			tuning_count = 0;
		break;

	case MMC_TIMING_UHS_SDR104:
		break;

@@ -1911,9 +1942,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
		/* FALLTHROUGH */

	default:
		spin_unlock_irqrestore(&host->lock, flags);
		sdhci_runtime_pm_put(host);
		return 0;
		goto out_unlock;
	}

	if (host->ops->platform_execute_tuning) {
@@ -2037,24 +2066,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
	}

out:
	/*
	 * If this is the very first time we are here, we start the retuning
	 * timer. Since only during the first time, SDHCI_NEEDS_RETUNING
	 * flag won't be set, we check this condition before actually starting
	 * the timer.
	 */
	if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count &&
	    (host->tuning_mode == SDHCI_TUNING_MODE_1)) {
		host->flags |= SDHCI_USING_RETUNING_TIMER;
		mod_timer(&host->tuning_timer, jiffies +
			host->tuning_count * HZ);
		/* Tuning mode 1 limits the maximum data length to 4MB */
		mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size;
	} else if (host->flags & SDHCI_USING_RETUNING_TIMER) {
	host->flags &= ~SDHCI_NEEDS_RETUNING;
		/* Reload the new initial value for timer */
		mod_timer(&host->tuning_timer, jiffies +
			  host->tuning_count * HZ);

	if (tuning_count) {
		host->flags |= SDHCI_USING_RETUNING_TIMER;
		mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ);
	}

	/*
@@ -2070,6 +2086,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)

	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
out_unlock:
	spin_unlock_irqrestore(&host->lock, flags);
	sdhci_runtime_pm_put(host);

@@ -2110,15 +2127,18 @@ static void sdhci_card_event(struct mmc_host *mmc)
{
	struct sdhci_host *host = mmc_priv(mmc);
	unsigned long flags;
	int present;

	/* First check if client has provided their own card event */
	if (host->ops->card_event)
		host->ops->card_event(host);

	present = sdhci_do_get_cd(host);

	spin_lock_irqsave(&host->lock, flags);

	/* Check host->mrq first in case we are runtime suspended */
	if (host->mrq && !sdhci_do_get_cd(host)) {
	if (host->mrq && !present) {
		pr_err("%s: Card removed during transfer!\n",
			mmc_hostname(host->mmc));
		pr_err("%s: Resetting controller.\n",
@@ -2142,6 +2162,7 @@ static const struct mmc_host_ops sdhci_ops = {
	.hw_reset	= sdhci_hw_reset,
	.enable_sdio_irq = sdhci_enable_sdio_irq,
	.start_signal_voltage_switch	= sdhci_start_signal_voltage_switch,
	.prepare_hs400_tuning		= sdhci_prepare_hs400_tuning,
	.execute_tuning			= sdhci_execute_tuning,
	.card_event			= sdhci_card_event,
	.card_busy	= sdhci_card_busy,
@@ -3260,8 +3281,9 @@ int sdhci_add_host(struct sdhci_host *host)
		mmc->max_segs = SDHCI_MAX_SEGS;

	/*
	 * Maximum number of sectors in one transfer. Limited by DMA boundary
	 * size (512KiB).
	 * Maximum number of sectors in one transfer. Limited by SDMA boundary
	 * size (512KiB). Note some tuning modes impose a 4MiB limit, but this
	 * is less anyway.
	 */
	mmc->max_req_size = 524288;

Loading