diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/core/sd.c | 49 | ||||
| -rw-r--r-- | drivers/mmc/host/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/meson-gx-mmc.c | 6 | ||||
| -rw-r--r-- | drivers/mmc/host/mmc_hsq.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/moxart-mmc.c | 17 | ||||
| -rw-r--r-- | drivers/mmc/host/mtk-sd.c | 6 | ||||
| -rw-r--r-- | drivers/mmc/host/pxamci.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-of-dwcmshc.c | 16 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci.c | 4 | 
9 files changed, 53 insertions, 52 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index cee4c0b59f43..3662bf5320ce 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -870,7 +870,8 @@ try_again:  	 * the CCS bit is set as well. We deliberately deviate from the spec in  	 * regards to this, which allows UHS-I to be supported for SDSC cards.  	 */ -	if (!mmc_host_is_spi(host) && rocr && (*rocr & SD_ROCR_S18A)) { +	if (!mmc_host_is_spi(host) && (ocr & SD_OCR_S18R) && +	    rocr && (*rocr & SD_ROCR_S18A)) {  		err = mmc_set_uhs_voltage(host, pocr);  		if (err == -EAGAIN) {  			retries--; @@ -949,16 +950,17 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,  		/* Erase init depends on CSD and SSR */  		mmc_init_erase(card); - -		/* -		 * Fetch switch information from card. -		 */ -		err = mmc_read_switch(card); -		if (err) -			return err;  	}  	/* +	 * Fetch switch information from card. Note, sd3_bus_mode can change if +	 * voltage switch outcome changes, so do this always. +	 */ +	err = mmc_read_switch(card); +	if (err) +		return err; + +	/*  	 * For SPI, enable CRC as appropriate.  	 * This CRC enable is located AFTER the reading of the  	 * card registers because some SDHC cards are not able @@ -1480,26 +1482,15 @@ retry:  	if (!v18_fixup_failed && !mmc_host_is_spi(host) && mmc_host_uhs(host) &&  	    mmc_sd_card_using_v18(card) &&  	    host->ios.signal_voltage != MMC_SIGNAL_VOLTAGE_180) { -		/* -		 * Re-read switch information in case it has changed since -		 * oldcard was initialized. -		 */ -		if (oldcard) { -			err = mmc_read_switch(card); -			if (err) -				goto free_card; -		} -		if (mmc_sd_card_using_v18(card)) { -			if (mmc_host_set_uhs_voltage(host) || -			    mmc_sd_init_uhs_card(card)) { -				v18_fixup_failed = true; -				mmc_power_cycle(host, ocr); -				if (!oldcard) -					mmc_remove_card(card); -				goto retry; -			} -			goto done; +		if (mmc_host_set_uhs_voltage(host) || +		    mmc_sd_init_uhs_card(card)) { +			v18_fixup_failed = true; +			mmc_power_cycle(host, ocr); +			if (!oldcard) +				mmc_remove_card(card); +			goto retry;  		} +		goto cont;  	}  	/* Initialization sequence for UHS-I cards */ @@ -1534,7 +1525,7 @@ retry:  			mmc_set_bus_width(host, MMC_BUS_WIDTH_4);  		}  	} - +cont:  	if (!oldcard) {  		/* Read/parse the extension registers. */  		err = sd_read_ext_regs(card); @@ -1566,7 +1557,7 @@ retry:  		err = -EINVAL;  		goto free_card;  	} -done: +  	host->card = card;  	return 0; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 10c563999d3d..e63608834411 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -171,6 +171,7 @@ config MMC_SDHCI_OF_ASPEED  config MMC_SDHCI_OF_ASPEED_TEST  	bool "Tests for the ASPEED SDHCI driver" if !KUNIT_ALL_TESTS  	depends on MMC_SDHCI_OF_ASPEED && KUNIT +	depends on (MMC_SDHCI_OF_ASPEED=m || KUNIT=y)  	default KUNIT_ALL_TESTS  	help  	  Enable KUnit tests for the ASPEED SDHCI driver. Select this diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 2f08d442e557..fc462995cf94 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -1172,8 +1172,10 @@ static int meson_mmc_probe(struct platform_device *pdev)  	}  	ret = device_reset_optional(&pdev->dev); -	if (ret) -		return dev_err_probe(&pdev->dev, ret, "device reset failed\n"); +	if (ret) { +		dev_err_probe(&pdev->dev, ret, "device reset failed\n"); +		goto free_host; +	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	host->regs = devm_ioremap_resource(&pdev->dev, res); diff --git a/drivers/mmc/host/mmc_hsq.c b/drivers/mmc/host/mmc_hsq.c index a5e05ed0fda3..9d35453e7371 100644 --- a/drivers/mmc/host/mmc_hsq.c +++ b/drivers/mmc/host/mmc_hsq.c @@ -34,7 +34,7 @@ static void mmc_hsq_pump_requests(struct mmc_hsq *hsq)  	spin_lock_irqsave(&hsq->lock, flags);  	/* Make sure we are not already running a request now */ -	if (hsq->mrq) { +	if (hsq->mrq || hsq->recovery_halt) {  		spin_unlock_irqrestore(&hsq->lock, flags);  		return;  	} diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c index b6eb75f4bbfc..dfc3ffd5b1f8 100644 --- a/drivers/mmc/host/moxart-mmc.c +++ b/drivers/mmc/host/moxart-mmc.c @@ -111,8 +111,8 @@  #define CLK_DIV_MASK		0x7f  /* REG_BUS_WIDTH */ -#define BUS_WIDTH_8		BIT(2) -#define BUS_WIDTH_4		BIT(1) +#define BUS_WIDTH_4_SUPPORT	BIT(3) +#define BUS_WIDTH_4		BIT(2)  #define BUS_WIDTH_1		BIT(0)  #define MMC_VDD_360		23 @@ -524,9 +524,6 @@ static void moxart_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  	case MMC_BUS_WIDTH_4:  		writel(BUS_WIDTH_4, host->base + REG_BUS_WIDTH);  		break; -	case MMC_BUS_WIDTH_8: -		writel(BUS_WIDTH_8, host->base + REG_BUS_WIDTH); -		break;  	default:  		writel(BUS_WIDTH_1, host->base + REG_BUS_WIDTH);  		break; @@ -651,16 +648,8 @@ static int moxart_probe(struct platform_device *pdev)  		dmaengine_slave_config(host->dma_chan_rx, &cfg);  	} -	switch ((readl(host->base + REG_BUS_WIDTH) >> 3) & 3) { -	case 1: +	if (readl(host->base + REG_BUS_WIDTH) & BUS_WIDTH_4_SUPPORT)  		mmc->caps |= MMC_CAP_4_BIT_DATA; -		break; -	case 2: -		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; -		break; -	default: -		break; -	}  	writel(0, host->base + REG_INTERRUPT_MASK); diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 4ff73d1883de..69d78604d1fc 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -2446,6 +2446,9 @@ static void msdc_cqe_disable(struct mmc_host *mmc, bool recovery)  	/* disable busy check */  	sdr_clr_bits(host->base + MSDC_PATCH_BIT1, MSDC_PB1_BUSY_CHECK_SEL); +	val = readl(host->base + MSDC_INT); +	writel(val, host->base + MSDC_INT); +  	if (recovery) {  		sdr_set_field(host->base + MSDC_DMA_CTRL,  			      MSDC_DMA_CTRL_STOP, 1); @@ -2932,11 +2935,14 @@ static int __maybe_unused msdc_suspend(struct device *dev)  	struct mmc_host *mmc = dev_get_drvdata(dev);  	struct msdc_host *host = mmc_priv(mmc);  	int ret; +	u32 val;  	if (mmc->caps2 & MMC_CAP2_CQE) {  		ret = cqhci_suspend(mmc);  		if (ret)  			return ret; +		val = readl(host->base + MSDC_INT); +		writel(val, host->base + MSDC_INT);  	}  	/* diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 0db9490dc659..e4003f6058eb 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -648,7 +648,7 @@ static int pxamci_probe(struct platform_device *pdev)  	ret = pxamci_of_init(pdev, mmc);  	if (ret) -		return ret; +		goto out;  	host = mmc_priv(mmc);  	host->mmc = mmc; @@ -672,7 +672,7 @@ static int pxamci_probe(struct platform_device *pdev)  	ret = pxamci_init_ocr(host);  	if (ret < 0) -		return ret; +		goto out;  	mmc->caps = 0;  	host->cmdat = 0; diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index 4e904850973c..a7343d4bc50e 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -349,6 +349,15 @@ static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = {  	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,  }; +#ifdef CONFIG_ACPI +static const struct sdhci_pltfm_data sdhci_dwcmshc_bf3_pdata = { +	.ops = &sdhci_dwcmshc_ops, +	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, +	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | +		   SDHCI_QUIRK2_ACMD23_BROKEN, +}; +#endif +  static const struct sdhci_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {  	.ops = &sdhci_dwcmshc_rk35xx_ops,  	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | @@ -431,7 +440,10 @@ MODULE_DEVICE_TABLE(of, sdhci_dwcmshc_dt_ids);  #ifdef CONFIG_ACPI  static const struct acpi_device_id sdhci_dwcmshc_acpi_ids[] = { -	{ .id = "MLNXBF30" }, +	{ +		.id = "MLNXBF30", +		.driver_data = (kernel_ulong_t)&sdhci_dwcmshc_bf3_pdata, +	},  	{}  };  #endif @@ -447,7 +459,7 @@ static int dwcmshc_probe(struct platform_device *pdev)  	int err;  	u32 extra; -	pltfm_data = of_device_get_match_data(&pdev->dev); +	pltfm_data = device_get_match_data(&pdev->dev);  	if (!pltfm_data) {  		dev_err(&pdev->dev, "Error: No device match data found\n");  		return -ENODEV; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7689ffec5ad1..251172890af7 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3928,7 +3928,7 @@ bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,  	if (intmask & (SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC)) {  		*cmd_error = -EILSEQ; -		if (!mmc_op_tuning(host->cmd->opcode)) +		if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))  			sdhci_err_stats_inc(host, CMD_CRC);  	} else if (intmask & SDHCI_INT_TIMEOUT) {  		*cmd_error = -ETIMEDOUT; @@ -3938,7 +3938,7 @@ bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,  	if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) {  		*data_error = -EILSEQ; -		if (!mmc_op_tuning(host->cmd->opcode)) +		if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))  			sdhci_err_stats_inc(host, DAT_CRC);  	} else if (intmask & SDHCI_INT_DATA_TIMEOUT) {  		*data_error = -ETIMEDOUT;  | 
