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

Commit 7b91369b authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Ulf Hansson
Browse files

mmc: sdhci: Set DMA mask when adding host



Set the DMA mask in sdhci_add_host() after we determined the
capabilities of the device. 64-bit devices in particular are given the
proper mask that ensures bounce buffers are not used.

Also disable DMA if no proper DMA mask can be set, as the DMA-API
documentation specifies.

Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 83c742c3
Loading
Loading
Loading
Loading
+41 −7
Original line number Diff line number Diff line
@@ -2804,6 +2804,36 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,

EXPORT_SYMBOL_GPL(sdhci_alloc_host);

static int sdhci_set_dma_mask(struct sdhci_host *host)
{
	struct mmc_host *mmc = host->mmc;
	struct device *dev = mmc_dev(mmc);
	int ret = -EINVAL;

	if (host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA)
		host->flags &= ~SDHCI_USE_64_BIT_DMA;

	/* Try 64-bit mask if hardware is capable  of it */
	if (host->flags & SDHCI_USE_64_BIT_DMA) {
		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
		if (ret) {
			pr_warn("%s: Failed to set 64-bit DMA mask.\n",
				mmc_hostname(mmc));
			host->flags &= ~SDHCI_USE_64_BIT_DMA;
		}
	}

	/* 32-bit mask as default & fallback */
	if (ret) {
		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
		if (ret)
			pr_warn("%s: Failed to set 32-bit DMA mask.\n",
				mmc_hostname(mmc));
	}

	return ret;
}

int sdhci_add_host(struct sdhci_host *host)
{
	struct mmc_host *mmc;
@@ -2879,13 +2909,17 @@ int sdhci_add_host(struct sdhci_host *host)
		host->flags |= SDHCI_USE_64_BIT_DMA;

	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
		if (host->ops->enable_dma) {
			if (host->ops->enable_dma(host)) {
		ret = sdhci_set_dma_mask(host);

		if (!ret && host->ops->enable_dma)
			ret = host->ops->enable_dma(host);

		if (ret) {
			pr_warn("%s: No suitable DMA available - falling back to PIO\n",
				mmc_hostname(mmc));
				host->flags &=
					~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);
			}
			host->flags &= ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);

			ret = 0;
		}
	}