diff options
Diffstat (limited to 'drivers/mmc')
32 files changed, 670 insertions, 180 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 672ab90c4b2d..00c33edb9fb9 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -76,8 +76,6 @@ MODULE_ALIAS("mmc:block");  #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)  #define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8) -#define mmc_req_rel_wr(req)	((req->cmd_flags & REQ_FUA) && \ -				  (rq_data_dir(req) == WRITE))  static DEFINE_MUTEX(block_mutex);  /* diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 426c7f66b349..3d3e0ca52614 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2257,6 +2257,11 @@ void mmc_rescan(struct work_struct *work)  			break;  	} +	/* A non-removable card should have been detected by now. */ +	if (!mmc_card_is_removable(host) && !host->bus_ops) +		pr_info("%s: Failed to initialize a non-removable card", +			mmc_hostname(host)); +  	/*  	 * Ignore the command timeout errors observed during  	 * the card init as those are excepted. diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index fe6808771bc7..2c97b94aab23 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -246,7 +246,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(mmc_err_state, mmc_err_state_get, NULL, "%llu\n");  static int mmc_err_stats_show(struct seq_file *file, void *data)  { -	struct mmc_host *host = (struct mmc_host *)file->private; +	struct mmc_host *host = file->private;  	const char *desc[MMC_ERR_MAX] = {  		[MMC_ERR_CMD_TIMEOUT] = "Command Timeout Occurred",  		[MMC_ERR_CMD_CRC] = "Command CRC Errors Occurred", diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c index 156d34b2ed4d..0f6a563103fd 100644 --- a/drivers/mmc/core/mmc_test.c +++ b/drivers/mmc/core/mmc_test.c @@ -3045,7 +3045,7 @@ static LIST_HEAD(mmc_test_file_test);  static int mtf_test_show(struct seq_file *sf, void *data)  { -	struct mmc_card *card = (struct mmc_card *)sf->private; +	struct mmc_card *card = sf->private;  	struct mmc_test_general_result *gr;  	mutex_lock(&mmc_test_lock); @@ -3079,8 +3079,8 @@ static int mtf_test_open(struct inode *inode, struct file *file)  static ssize_t mtf_test_write(struct file *file, const char __user *buf,  	size_t count, loff_t *pos)  { -	struct seq_file *sf = (struct seq_file *)file->private_data; -	struct mmc_card *card = (struct mmc_card *)sf->private; +	struct seq_file *sf = file->private_data; +	struct mmc_card *card = sf->private;  	struct mmc_test_card *test;  	long testcase;  	int ret; diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c index 609201a467ef..005247a49e51 100644 --- a/drivers/mmc/core/regulator.c +++ b/drivers/mmc/core/regulator.c @@ -110,6 +110,9 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,  	int			result = 0;  	int			min_uV, max_uV; +	if (IS_ERR(supply)) +		return 0; +  	if (vdd_bit) {  		mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV); @@ -271,3 +274,44 @@ int mmc_regulator_get_supply(struct mmc_host *mmc)  	return 0;  }  EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); + +/** + * mmc_regulator_enable_vqmmc - enable VQMMC regulator for a host + * @mmc: the host to regulate + * + * Returns 0 or errno. Enables the regulator for vqmmc. + * Keeps track of the enable status for ensuring that calls to + * regulator_enable/disable are balanced. + */ +int mmc_regulator_enable_vqmmc(struct mmc_host *mmc) +{ +	int ret = 0; + +	if (!IS_ERR(mmc->supply.vqmmc) && !mmc->vqmmc_enabled) { +		ret = regulator_enable(mmc->supply.vqmmc); +		if (ret < 0) +			dev_err(mmc_dev(mmc), "enabling vqmmc regulator failed\n"); +		else +			mmc->vqmmc_enabled = true; +	} + +	return ret; +} +EXPORT_SYMBOL_GPL(mmc_regulator_enable_vqmmc); + +/** + * mmc_regulator_disable_vqmmc - disable VQMMC regulator for a host + * @mmc: the host to regulate + * + * Returns 0 or errno. Disables the regulator for vqmmc. + * Keeps track of the enable status for ensuring that calls to + * regulator_enable/disable are balanced. + */ +void mmc_regulator_disable_vqmmc(struct mmc_host *mmc) +{ +	if (!IS_ERR(mmc->supply.vqmmc) && mmc->vqmmc_enabled) { +		regulator_disable(mmc->supply.vqmmc); +		mmc->vqmmc_enabled = false; +	} +} +EXPORT_SYMBOL_GPL(mmc_regulator_disable_vqmmc); diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index 50536fe59f1a..aa659758563f 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -478,13 +478,13 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)  			int cts = (status & UART_MSR_CTS);  			if (tty->hw_stopped) {  				if (cts) { -					tty->hw_stopped = 0; +					tty->hw_stopped = false;  					sdio_uart_start_tx(port);  					tty_wakeup(tty);  				}  			} else {  				if (!cts) { -					tty->hw_stopped = 1; +					tty->hw_stopped = true;  					sdio_uart_stop_tx(port);  				}  			} @@ -633,7 +633,7 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)  	if (C_CRTSCTS(tty))  		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) -			tty->hw_stopped = 1; +			tty->hw_stopped = true;  	clear_bit(TTY_IO_ERROR, &tty->flags); @@ -882,14 +882,14 @@ static void sdio_uart_set_termios(struct tty_struct *tty,  	/* Handle turning off CRTSCTS */  	if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { -		tty->hw_stopped = 0; +		tty->hw_stopped = false;  		sdio_uart_start_tx(port);  	}  	/* Handle turning on CRTSCTS */  	if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {  		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) { -			tty->hw_stopped = 1; +			tty->hw_stopped = true;  			sdio_uart_stop_tx(port);  		}  	} diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 4745fe217ade..9f793892123c 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -255,6 +255,7 @@ config MMC_SDHCI_CADENCE  	tristate "SDHCI support for the Cadence SD/SDIO/eMMC controller"  	depends on MMC_SDHCI_PLTFM  	depends on OF +	select MMC_SDHCI_IO_ACCESSORS  	help  	  This selects the Cadence SD/SDIO/eMMC driver. diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index 13e55cff8237..48b7da2b86b3 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c @@ -46,8 +46,7 @@ int dw_mci_pltfm_register(struct platform_device *pdev,  	host->irq_flags = 0;  	host->pdata = pdev->dev.platform_data; -	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	host->regs = devm_ioremap_resource(&pdev->dev, regs); +	host->regs = devm_platform_get_and_ioremap_resource(pdev, 0, ®s);  	if (IS_ERR(host->regs))  		return PTR_ERR(host->regs); diff --git a/drivers/mmc/host/dw_mmc-starfive.c b/drivers/mmc/host/dw_mmc-starfive.c index 40f5969b07a6..dab1508bf83c 100644 --- a/drivers/mmc/host/dw_mmc-starfive.c +++ b/drivers/mmc/host/dw_mmc-starfive.c @@ -51,7 +51,7 @@ static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,  	struct dw_mci *host = slot->host;  	struct starfive_priv *priv = host->priv;  	int rise_point = -1, fall_point = -1; -	int err, prev_err; +	int err, prev_err = 0;  	int i;  	bool found = 0;  	u32 regval; diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 698450afa7bb..1846a05210e3 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -1079,8 +1079,7 @@ static int jz4740_mmc_probe(struct platform_device* pdev)  		goto err_free_host;  	} -	host->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	host->base = devm_ioremap_resource(&pdev->dev, host->mem_res); +	host->base = devm_platform_get_and_ioremap_resource(pdev, 0, &host->mem_res);  	if (IS_ERR(host->base)) {  		ret = PTR_ERR(host->base);  		goto err_free_host; diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 2b963a81c2ad..b8514d9d5e73 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -174,7 +174,6 @@ struct meson_host {  	int irq; -	bool vqmmc_enabled;  	bool needs_pre_post_req;  	spinlock_t lock; @@ -604,32 +603,18 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  	 */  	switch (ios->power_mode) {  	case MMC_POWER_OFF: -		if (!IS_ERR(mmc->supply.vmmc)) -			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); - -		if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { -			regulator_disable(mmc->supply.vqmmc); -			host->vqmmc_enabled = false; -		} +		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); +		mmc_regulator_disable_vqmmc(mmc);  		break;  	case MMC_POWER_UP: -		if (!IS_ERR(mmc->supply.vmmc)) -			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); +		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);  		break;  	case MMC_POWER_ON: -		if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { -			int ret = regulator_enable(mmc->supply.vqmmc); - -			if (ret < 0) -				dev_err(host->dev, -					"failed to enable vqmmc regulator\n"); -			else -				host->vqmmc_enabled = true; -		} +		mmc_regulator_enable_vqmmc(mmc);  		break;  	} @@ -1181,7 +1166,6 @@ static int meson_mmc_probe(struct platform_device *pdev)  					"amlogic,dram-access-quirk");  	/* Get regulators and the supported OCR mask */ -	host->vqmmc_enabled = false;  	ret = mmc_regulator_get_supply(mmc);  	if (ret)  		return ret; diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index b9e5dfe74e5c..f2b2e8b0574e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1962,28 +1962,28 @@ static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc)  	if (ret)  		return ret; -	if (of_get_property(np, "st,sig-dir-dat0", NULL)) +	if (of_property_read_bool(np, "st,sig-dir-dat0"))  		host->pwr_reg_add |= MCI_ST_DATA0DIREN; -	if (of_get_property(np, "st,sig-dir-dat2", NULL)) +	if (of_property_read_bool(np, "st,sig-dir-dat2"))  		host->pwr_reg_add |= MCI_ST_DATA2DIREN; -	if (of_get_property(np, "st,sig-dir-dat31", NULL)) +	if (of_property_read_bool(np, "st,sig-dir-dat31"))  		host->pwr_reg_add |= MCI_ST_DATA31DIREN; -	if (of_get_property(np, "st,sig-dir-dat74", NULL)) +	if (of_property_read_bool(np, "st,sig-dir-dat74"))  		host->pwr_reg_add |= MCI_ST_DATA74DIREN; -	if (of_get_property(np, "st,sig-dir-cmd", NULL)) +	if (of_property_read_bool(np, "st,sig-dir-cmd"))  		host->pwr_reg_add |= MCI_ST_CMDDIREN; -	if (of_get_property(np, "st,sig-pin-fbclk", NULL)) +	if (of_property_read_bool(np, "st,sig-pin-fbclk"))  		host->pwr_reg_add |= MCI_ST_FBCLKEN; -	if (of_get_property(np, "st,sig-dir", NULL)) +	if (of_property_read_bool(np, "st,sig-dir"))  		host->pwr_reg_add |= MCI_STM32_DIRPOL; -	if (of_get_property(np, "st,neg-edge", NULL)) +	if (of_property_read_bool(np, "st,neg-edge"))  		host->clk_reg_add |= MCI_STM32_CLK_NEGEDGE; -	if (of_get_property(np, "st,use-ckin", NULL)) +	if (of_property_read_bool(np, "st,use-ckin"))  		mmci_probe_level_translator(mmc); -	if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) +	if (of_property_read_bool(np, "mmc-cap-mmc-highspeed"))  		mmc->caps |= MMC_CAP_MMC_HIGHSPEED; -	if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) +	if (of_property_read_bool(np, "mmc-cap-sd-highspeed"))  		mmc->caps |= MMC_CAP_SD_HIGHSPEED;  	return 0; diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 57d39283924d..ce78edfb402b 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1345,8 +1345,7 @@ static int mmc_omap_probe(struct platform_device *pdev)  	if (irq < 0)  		return -ENXIO; -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	host->virt_base = devm_ioremap_resource(&pdev->dev, res); +	host->virt_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);  	if (IS_ERR(host->virt_base))  		return PTR_ERR(host->virt_base); diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4bd744755205..517dde777413 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1736,18 +1736,18 @@ static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev)  	if (legacy && legacy->name)  		pdata->name = legacy->name; -	if (of_find_property(np, "ti,dual-volt", NULL)) +	if (of_property_read_bool(np, "ti,dual-volt"))  		pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; -	if (of_find_property(np, "ti,non-removable", NULL)) { +	if (of_property_read_bool(np, "ti,non-removable")) {  		pdata->nonremovable = true;  		pdata->no_regulator_off_init = true;  	} -	if (of_find_property(np, "ti,needs-special-reset", NULL)) +	if (of_property_read_bool(np, "ti,needs-special-reset"))  		pdata->features |= HSMMC_HAS_UPDATED_RESET; -	if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) +	if (of_property_read_bool(np, "ti,needs-special-hs-handling"))  		pdata->features |= HSMMC_HAS_HSPE_SUPPORT;  	return pdata; diff --git a/drivers/mmc/host/owl-mmc.c b/drivers/mmc/host/owl-mmc.c index 3dc143b03939..6f9d31a886ba 100644 --- a/drivers/mmc/host/owl-mmc.c +++ b/drivers/mmc/host/owl-mmc.c @@ -578,8 +578,7 @@ static int owl_mmc_probe(struct platform_device *pdev)  	owl_host->mmc = mmc;  	spin_lock_init(&owl_host->lock); -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	owl_host->base = devm_ioremap_resource(&pdev->dev, res); +	owl_host->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);  	if (IS_ERR(owl_host->base)) {  		ret = PTR_ERR(owl_host->base);  		goto err_free_host; diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index f38003f6b1ca..9ab813903b2c 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c @@ -72,11 +72,10 @@ enum renesas_sdhi_dma_cookie {  static unsigned long global_flags;  /* - * Workaround for avoiding to use RX DMAC by multiple channels. - * On R-Car H3 ES1.* and M3-W ES1.0, when multiple SDHI channels use - * RX DMAC simultaneously, sometimes hundreds of bytes data are not - * stored into the system memory even if the DMAC interrupt happened. - * So, this driver then uses one RX DMAC channel only. + * Workaround for avoiding to use RX DMAC by multiple channels. On R-Car M3-W + * ES1.0, when multiple SDHI channels use RX DMAC simultaneously, sometimes + * hundreds of data bytes are not stored into the system memory even if the + * DMAC interrupt happened. So, this driver then uses one RX DMAC channel only.   */  #define SDHI_INTERNAL_DMAC_RX_IN_USE	0 @@ -222,7 +221,6 @@ static const struct renesas_sdhi_quirks sdhi_quirks_r9a09g011 = {   */  static const struct soc_device_attribute sdhi_quirks_match[]  = {  	{ .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, -	{ .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400_one_rx },  	{ .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },  	{ .soc_id = "r8a7796", .revision = "ES1.0", .data = &sdhi_quirks_4tap_nohs400_one_rx },  	{ .soc_id = "r8a7796", .revision = "ES1.[12]", .data = &sdhi_quirks_4tap_nohs400 }, diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 6f2de54a5987..b24aa27da50c 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c @@ -12,6 +12,7 @@  #include <linux/mmc/mmc.h>  #include <linux/of.h>  #include <linux/of_device.h> +#include <linux/reset.h>  #include "sdhci-pltfm.h" @@ -66,7 +67,11 @@ struct sdhci_cdns_phy_param {  struct sdhci_cdns_priv {  	void __iomem *hrs_addr; +	void __iomem *ctl_addr;	/* write control */ +	spinlock_t wrlock;	/* write lock */  	bool enhanced_strobe; +	void (*priv_writel)(struct sdhci_cdns_priv *priv, u32 val, void __iomem *reg); +	struct reset_control *rst_hw;  	unsigned int nr_phy_params;  	struct sdhci_cdns_phy_param phy_params[];  }; @@ -76,6 +81,11 @@ struct sdhci_cdns_phy_cfg {  	u8 addr;  }; +struct sdhci_cdns_drv_data { +	int (*init)(struct platform_device *pdev); +	const struct sdhci_pltfm_data pltfm_data; +}; +  static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = {  	{ "cdns,phy-input-delay-sd-highspeed", SDHCI_CDNS_PHY_DLY_SD_HS, },  	{ "cdns,phy-input-delay-legacy", SDHCI_CDNS_PHY_DLY_SD_DEFAULT, }, @@ -90,6 +100,12 @@ static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = {  	{ "cdns,phy-dll-delay-strobe", SDHCI_CDNS_PHY_DLY_STROBE, },  }; +static inline void cdns_writel(struct sdhci_cdns_priv *priv, u32 val, +			       void __iomem *reg) +{ +	writel(val, reg); +} +  static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv,  				    u8 addr, u8 data)  { @@ -104,17 +120,17 @@ static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv,  	tmp = FIELD_PREP(SDHCI_CDNS_HRS04_WDATA, data) |  	      FIELD_PREP(SDHCI_CDNS_HRS04_ADDR, addr); -	writel(tmp, reg); +	priv->priv_writel(priv, tmp, reg);  	tmp |= SDHCI_CDNS_HRS04_WR; -	writel(tmp, reg); +	priv->priv_writel(priv, tmp, reg);  	ret = readl_poll_timeout(reg, tmp, tmp & SDHCI_CDNS_HRS04_ACK, 0, 10);  	if (ret)  		return ret;  	tmp &= ~SDHCI_CDNS_HRS04_WR; -	writel(tmp, reg); +	priv->priv_writel(priv, tmp, reg);  	ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS04_ACK),  				 0, 10); @@ -191,7 +207,7 @@ static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv *priv, u32 mode)  	tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06);  	tmp &= ~SDHCI_CDNS_HRS06_MODE;  	tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_MODE, mode); -	writel(tmp, priv->hrs_addr + SDHCI_CDNS_HRS06); +	priv->priv_writel(priv, tmp, priv->hrs_addr + SDHCI_CDNS_HRS06);  }  static u32 sdhci_cdns_get_emmc_mode(struct sdhci_cdns_priv *priv) @@ -223,7 +239,7 @@ static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val)  	 */  	for (i = 0; i < 2; i++) {  		tmp |= SDHCI_CDNS_HRS06_TUNE_UP; -		writel(tmp, reg); +		priv->priv_writel(priv, tmp, reg);  		ret = readl_poll_timeout(reg, tmp,  					 !(tmp & SDHCI_CDNS_HRS06_TUNE_UP), @@ -309,6 +325,91 @@ static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host,  		sdhci_set_uhs_signaling(host, timing);  } +/* Elba control register bits [6:3] are byte-lane enables */ +#define ELBA_BYTE_ENABLE_MASK(x)	((x) << 3) + +/* + * The Pensando Elba SoC explicitly controls byte-lane enabling on writes + * which includes writes to the HRS registers.  The write lock (wrlock) + * is used to ensure byte-lane enable, using write control (ctl_addr), + * occurs before the data write. + */ +static void elba_priv_writel(struct sdhci_cdns_priv *priv, u32 val, +			     void __iomem *reg) +{ +	unsigned long flags; + +	spin_lock_irqsave(&priv->wrlock, flags); +	writel(GENMASK(7, 3), priv->ctl_addr); +	writel(val, reg); +	spin_unlock_irqrestore(&priv->wrlock, flags); +} + +static void elba_write_l(struct sdhci_host *host, u32 val, int reg) +{ +	elba_priv_writel(sdhci_cdns_priv(host), val, host->ioaddr + reg); +} + +static void elba_write_w(struct sdhci_host *host, u16 val, int reg) +{ +	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); +	u32 shift = reg & GENMASK(1, 0); +	unsigned long flags; +	u32 byte_enables; + +	byte_enables = GENMASK(1, 0) << shift; +	spin_lock_irqsave(&priv->wrlock, flags); +	writel(ELBA_BYTE_ENABLE_MASK(byte_enables), priv->ctl_addr); +	writew(val, host->ioaddr + reg); +	spin_unlock_irqrestore(&priv->wrlock, flags); +} + +static void elba_write_b(struct sdhci_host *host, u8 val, int reg) +{ +	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); +	u32 shift = reg & GENMASK(1, 0); +	unsigned long flags; +	u32 byte_enables; + +	byte_enables = BIT(0) << shift; +	spin_lock_irqsave(&priv->wrlock, flags); +	writel(ELBA_BYTE_ENABLE_MASK(byte_enables), priv->ctl_addr); +	writeb(val, host->ioaddr + reg); +	spin_unlock_irqrestore(&priv->wrlock, flags); +} + +static const struct sdhci_ops sdhci_elba_ops = { +	.write_l = elba_write_l, +	.write_w = elba_write_w, +	.write_b = elba_write_b, +	.set_clock = sdhci_set_clock, +	.get_timeout_clock = sdhci_cdns_get_timeout_clock, +	.set_bus_width = sdhci_set_bus_width, +	.reset = sdhci_reset, +	.set_uhs_signaling = sdhci_cdns_set_uhs_signaling, +}; + +static int elba_drv_init(struct platform_device *pdev) +{ +	struct sdhci_host *host = platform_get_drvdata(pdev); +	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); +	void __iomem *ioaddr; + +	host->mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA; +	spin_lock_init(&priv->wrlock); + +	/* Byte-lane control register */ +	ioaddr = devm_platform_ioremap_resource(pdev, 1); +	if (IS_ERR(ioaddr)) +		return PTR_ERR(ioaddr); + +	priv->ctl_addr = ioaddr; +	priv->priv_writel = elba_priv_writel; +	writel(ELBA_BYTE_ENABLE_MASK(0xf), priv->ctl_addr); + +	return 0; +} +  static const struct sdhci_ops sdhci_cdns_ops = {  	.set_clock = sdhci_set_clock,  	.get_timeout_clock = sdhci_cdns_get_timeout_clock, @@ -318,13 +419,24 @@ static const struct sdhci_ops sdhci_cdns_ops = {  	.set_uhs_signaling = sdhci_cdns_set_uhs_signaling,  }; -static const struct sdhci_pltfm_data sdhci_cdns_uniphier_pltfm_data = { -	.ops = &sdhci_cdns_ops, -	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, +static const struct sdhci_cdns_drv_data sdhci_cdns_uniphier_drv_data = { +	.pltfm_data = { +		.ops = &sdhci_cdns_ops, +		.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, +	},  }; -static const struct sdhci_pltfm_data sdhci_cdns_pltfm_data = { -	.ops = &sdhci_cdns_ops, +static const struct sdhci_cdns_drv_data sdhci_elba_drv_data = { +	.init = elba_drv_init, +	.pltfm_data = { +		.ops = &sdhci_elba_ops, +	}, +}; + +static const struct sdhci_cdns_drv_data sdhci_cdns_drv_data = { +	.pltfm_data = { +		.ops = &sdhci_cdns_ops, +	},  };  static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host *mmc, @@ -347,10 +459,26 @@ static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host *mmc,  					 SDHCI_CDNS_HRS06_MODE_MMC_HS400);  } +static void sdhci_cdns_mmc_hw_reset(struct mmc_host *mmc) +{ +	struct sdhci_host *host = mmc_priv(mmc); +	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + +	dev_dbg(mmc_dev(host->mmc), "emmc hardware reset\n"); + +	reset_control_assert(priv->rst_hw); +	/* For eMMC, minimum is 1us but give it 3us for good measure */ +	udelay(3); + +	reset_control_deassert(priv->rst_hw); +	/* For eMMC, minimum is 200us but give it 300us for good measure */ +	usleep_range(300, 1000); +} +  static int sdhci_cdns_probe(struct platform_device *pdev)  {  	struct sdhci_host *host; -	const struct sdhci_pltfm_data *data; +	const struct sdhci_cdns_drv_data *data;  	struct sdhci_pltfm_host *pltfm_host;  	struct sdhci_cdns_priv *priv;  	struct clk *clk; @@ -369,10 +497,10 @@ static int sdhci_cdns_probe(struct platform_device *pdev)  	data = of_device_get_match_data(dev);  	if (!data) -		data = &sdhci_cdns_pltfm_data; +		data = &sdhci_cdns_drv_data;  	nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node); -	host = sdhci_pltfm_init(pdev, data, +	host = sdhci_pltfm_init(pdev, &data->pltfm_data,  				struct_size(priv, phy_params, nr_phy_params));  	if (IS_ERR(host)) {  		ret = PTR_ERR(host); @@ -386,9 +514,15 @@ static int sdhci_cdns_probe(struct platform_device *pdev)  	priv->nr_phy_params = nr_phy_params;  	priv->hrs_addr = host->ioaddr;  	priv->enhanced_strobe = false; +	priv->priv_writel = cdns_writel;  	host->ioaddr += SDHCI_CDNS_SRS_BASE;  	host->mmc_host_ops.hs400_enhanced_strobe =  				sdhci_cdns_hs400_enhanced_strobe; +	if (data->init) { +		ret = data->init(pdev); +		if (ret) +			goto free; +	}  	sdhci_enable_v4_mode(host);  	__sdhci_read_caps(host, &version, NULL, NULL); @@ -404,6 +538,15 @@ static int sdhci_cdns_probe(struct platform_device *pdev)  	if (ret)  		goto free; +	if (host->mmc->caps & MMC_CAP_HW_RESET) { +		priv->rst_hw = devm_reset_control_get_optional_exclusive(dev, NULL); +		if (IS_ERR(priv->rst_hw)) +			return dev_err_probe(mmc_dev(host->mmc), PTR_ERR(priv->rst_hw), +					     "reset controller error\n"); +		if (priv->rst_hw) +			host->mmc_host_ops.card_hw_reset = sdhci_cdns_mmc_hw_reset; +	} +  	ret = sdhci_add_host(host);  	if (ret)  		goto free; @@ -453,7 +596,11 @@ static const struct dev_pm_ops sdhci_cdns_pm_ops = {  static const struct of_device_id sdhci_cdns_match[] = {  	{  		.compatible = "socionext,uniphier-sd4hc", -		.data = &sdhci_cdns_uniphier_pltfm_data, +		.data = &sdhci_cdns_uniphier_drv_data, +	}, +	{ +		.compatible = "amd,pensando-elba-sd4hc", +		.data = &sdhci_elba_drv_data,  	},  	{ .compatible = "cdns,sd4hc" },  	{ /* sentinel */ } diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 58f042fdd4f4..d7c0c0b9e26c 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -1597,7 +1597,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,  	struct esdhc_platform_data *boarddata = &imx_data->boarddata;  	int ret; -	if (of_get_property(np, "fsl,wp-controller", NULL)) +	if (of_property_read_bool(np, "fsl,wp-controller"))  		boarddata->wp_type = ESDHC_WP_CONTROLLER;  	/* @@ -1614,7 +1614,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,  	of_property_read_u32(np, "fsl,strobe-dll-delay-target",  				&boarddata->strobe_dll_delay_target); -	if (of_find_property(np, "no-1-8-v", NULL)) +	if (of_property_read_bool(np, "no-1-8-v"))  		host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;  	if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line)) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 89c431a34c43..294dd605fd2b 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -41,11 +41,41 @@  #define VENDOR_ENHANCED_STROBE		BIT(0)  #define PHY_CLK_TOO_SLOW_HZ		400000 +#define MIN_PHY_CLK_HZ			50000000  #define SDHCI_ITAPDLY_CHGWIN		0x200  #define SDHCI_ITAPDLY_ENABLE		0x100  #define SDHCI_OTAPDLY_ENABLE		0x40 +#define PHY_CTRL_REG1			0x270 +#define PHY_CTRL_ITAPDLY_ENA_MASK	BIT(0) +#define PHY_CTRL_ITAPDLY_SEL_MASK	GENMASK(5, 1) +#define PHY_CTRL_ITAPDLY_SEL_SHIFT	1 +#define PHY_CTRL_ITAP_CHG_WIN_MASK	BIT(6) +#define PHY_CTRL_OTAPDLY_ENA_MASK	BIT(8) +#define PHY_CTRL_OTAPDLY_SEL_MASK	GENMASK(15, 12) +#define PHY_CTRL_OTAPDLY_SEL_SHIFT	12 +#define PHY_CTRL_STRB_SEL_MASK		GENMASK(23, 16) +#define PHY_CTRL_STRB_SEL_SHIFT		16 +#define PHY_CTRL_TEST_CTRL_MASK		GENMASK(31, 24) + +#define PHY_CTRL_REG2			0x274 +#define PHY_CTRL_EN_DLL_MASK		BIT(0) +#define PHY_CTRL_DLL_RDY_MASK		BIT(1) +#define PHY_CTRL_FREQ_SEL_MASK		GENMASK(6, 4) +#define PHY_CTRL_FREQ_SEL_SHIFT		4 +#define PHY_CTRL_SEL_DLY_TX_MASK	BIT(16) +#define PHY_CTRL_SEL_DLY_RX_MASK	BIT(17) +#define FREQSEL_200M_170M		0x0 +#define FREQSEL_170M_140M	        0x1 +#define FREQSEL_140M_110M	        0x2 +#define FREQSEL_110M_80M	        0x3 +#define FREQSEL_80M_50M			0x4 +#define FREQSEL_275M_250M		0x5 +#define FREQSEL_250M_225M		0x6 +#define FREQSEL_225M_200M		0x7 +#define PHY_DLL_TIMEOUT_MS		100 +  /* Default settings for ZynqMP Clock Phases */  #define ZYNQMP_ICLK_PHASE {0, 63, 63, 0, 63,  0,   0, 183, 54,  0, 0}  #define ZYNQMP_OCLK_PHASE {0, 72, 60, 0, 60, 72, 135, 48, 72, 135, 0} @@ -53,6 +83,11 @@  #define VERSAL_ICLK_PHASE {0, 132, 132, 0, 132, 0, 0, 162, 90, 0, 0}  #define VERSAL_OCLK_PHASE {0,  60, 48, 0, 48, 72, 90, 36, 60, 90, 0} +#define VERSAL_NET_EMMC_ICLK_PHASE {0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0} +#define VERSAL_NET_EMMC_OCLK_PHASE {0, 113, 0, 0, 0, 0, 0, 0, 113, 79, 45} + +#define VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL		0X77 +  /*   * On some SoCs the syscon area has a feature where the upper 16-bits of   * each 32-bit register act as a write mask for the lower 16-bits.  This allows @@ -135,6 +170,7 @@ struct sdhci_arasan_clk_data {   * @clk_ahb:		Pointer to the AHB clock   * @phy:		Pointer to the generic phy   * @is_phy_on:		True if the PHY is on; false if not. + * @internal_phy_reg:	True if the PHY is within the Host controller.   * @has_cqe:		True if controller has command queuing engine.   * @clk_data:		Struct for the Arasan Controller Clock Data.   * @clk_ops:		Struct for the Arasan Controller Clock Operations. @@ -147,6 +183,7 @@ struct sdhci_arasan_data {  	struct clk	*clk_ahb;  	struct phy	*phy;  	bool		is_phy_on; +	bool		internal_phy_reg;  	bool		has_cqe;  	struct sdhci_arasan_clk_data clk_data; @@ -193,13 +230,6 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = {  	.hiword_update = false,  }; -static const struct sdhci_arasan_soc_ctl_map thunderbay_soc_ctl_map = { -	.baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 }, -	.clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 }, -	.support64b = { .reg = 0x4, .width = 1, .shift = 24 }, -	.hiword_update = false, -}; -  static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = {  	.baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },  	.clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 }, @@ -207,6 +237,61 @@ static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = {  	.hiword_update = false,  }; +static void sdhci_arasan_phy_set_delaychain(struct sdhci_host *host, bool enable) +{ +	u32 reg; + +	reg = readl(host->ioaddr + PHY_CTRL_REG2); +	if (enable) +		reg |= (PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK); +	else +		reg &= ~(PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK); + +	writel(reg, host->ioaddr + PHY_CTRL_REG2); +} + +static int sdhci_arasan_phy_set_dll(struct sdhci_host *host, bool enable) +{ +	u32 reg; + +	reg = readl(host->ioaddr + PHY_CTRL_REG2); +	if (enable) +		reg |= PHY_CTRL_EN_DLL_MASK; +	else +		reg &= ~PHY_CTRL_EN_DLL_MASK; + +	writel(reg, host->ioaddr + PHY_CTRL_REG2); + +	if (!enable) +		return 0; + +	return readl_relaxed_poll_timeout(host->ioaddr + PHY_CTRL_REG2, reg, +					  (reg & PHY_CTRL_DLL_RDY_MASK), 10, +					  1000 * PHY_DLL_TIMEOUT_MS); +} + +static void sdhci_arasan_phy_dll_set_freq(struct sdhci_host *host, int clock) +{ +	u32 reg, freq_sel, freq; + +	freq = DIV_ROUND_CLOSEST(clock, 1000000); +	if (freq <= 200 && freq > 170) +		freq_sel = FREQSEL_200M_170M; +	else if (freq <= 170 && freq > 140) +		freq_sel = FREQSEL_170M_140M; +	else if (freq <= 140 && freq > 110) +		freq_sel = FREQSEL_140M_110M; +	else if (freq <= 110 && freq > 80) +		freq_sel = FREQSEL_110M_80M; +	else +		freq_sel = FREQSEL_80M_50M; + +	reg = readl(host->ioaddr + PHY_CTRL_REG2); +	reg &= ~PHY_CTRL_FREQ_SEL_MASK; +	reg |= (freq_sel << PHY_CTRL_FREQ_SEL_SHIFT); +	writel(reg, host->ioaddr + PHY_CTRL_REG2); +} +  /**   * sdhci_arasan_syscon_write - Write to a field in soc_ctl registers   * @@ -321,11 +406,24 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock)  	}  	/* Set the Input and Output Clock Phase Delays */ -	if (clk_data->set_clk_delays) +	if (clk_data->set_clk_delays && clock > PHY_CLK_TOO_SLOW_HZ)  		clk_data->set_clk_delays(host); +	if (sdhci_arasan->internal_phy_reg && clock >= MIN_PHY_CLK_HZ) { +		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); +		sdhci_arasan_phy_set_dll(host, 0); +		sdhci_arasan_phy_set_delaychain(host, 0); +		sdhci_arasan_phy_dll_set_freq(host, clock); +	} else if (sdhci_arasan->internal_phy_reg) { +		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); +		sdhci_arasan_phy_set_delaychain(host, 1); +	} +  	sdhci_set_clock(host, clock); +	if (sdhci_arasan->internal_phy_reg && clock >= MIN_PHY_CLK_HZ) +		sdhci_arasan_phy_set_dll(host, 1); +  	if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE)  		/*  		 * Some controllers immediately report SDHCI_CLOCK_INT_STABLE @@ -465,15 +563,6 @@ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = {  			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,  }; -static const struct sdhci_pltfm_data sdhci_arasan_thunderbay_pdata = { -	.ops = &sdhci_arasan_cqe_ops, -	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, -	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | -		SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | -		SDHCI_QUIRK2_STOP_WITH_TC | -		SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400, -}; -  #ifdef CONFIG_PM_SLEEP  /**   * sdhci_arasan_suspend - Suspend method for the driver @@ -897,6 +986,101 @@ static const struct clk_ops versal_sampleclk_ops = {  	.set_phase = sdhci_versal_sampleclk_set_phase,  }; +static int sdhci_versal_net_emmc_sdcardclk_set_phase(struct clk_hw *hw, int degrees) +{ +	struct sdhci_arasan_clk_data *clk_data = +		container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw); +	struct sdhci_arasan_data *sdhci_arasan = +		container_of(clk_data, struct sdhci_arasan_data, clk_data); +	struct sdhci_host *host = sdhci_arasan->host; +	u8 tap_delay, tap_max = 0; + +	switch (host->timing) { +	case MMC_TIMING_MMC_HS: +	case MMC_TIMING_MMC_DDR52: +		tap_max = 16; +		break; +	case MMC_TIMING_MMC_HS200: +	case MMC_TIMING_MMC_HS400: +		 /* For 200MHz clock, 32 Taps are available */ +		tap_max = 32; +		break; +	default: +		break; +	} + +	tap_delay = (degrees * tap_max) / 360; + +	/* Set the Clock Phase */ +	if (tap_delay) { +		u32 regval; + +		regval = sdhci_readl(host, PHY_CTRL_REG1); +		regval |= PHY_CTRL_OTAPDLY_ENA_MASK; +		sdhci_writel(host, regval, PHY_CTRL_REG1); +		regval &= ~PHY_CTRL_OTAPDLY_SEL_MASK; +		regval |= tap_delay << PHY_CTRL_OTAPDLY_SEL_SHIFT; +		sdhci_writel(host, regval, PHY_CTRL_REG1); +	} + +	return 0; +} + +static const struct clk_ops versal_net_sdcardclk_ops = { +	.recalc_rate = sdhci_arasan_sdcardclk_recalc_rate, +	.set_phase = sdhci_versal_net_emmc_sdcardclk_set_phase, +}; + +static int sdhci_versal_net_emmc_sampleclk_set_phase(struct clk_hw *hw, int degrees) +{ +	struct sdhci_arasan_clk_data *clk_data = +		container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw); +	struct sdhci_arasan_data *sdhci_arasan = +		container_of(clk_data, struct sdhci_arasan_data, clk_data); +	struct sdhci_host *host = sdhci_arasan->host; +	u8 tap_delay, tap_max = 0; +	u32 regval; + +	switch (host->timing) { +	case MMC_TIMING_MMC_HS: +	case MMC_TIMING_MMC_DDR52: +		tap_max = 32; +		break; +	case MMC_TIMING_MMC_HS400: +		/* Strobe select tap point for strb90 and strb180 */ +		regval = sdhci_readl(host, PHY_CTRL_REG1); +		regval &= ~PHY_CTRL_STRB_SEL_MASK; +		regval |= VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL << PHY_CTRL_STRB_SEL_SHIFT; +		sdhci_writel(host, regval, PHY_CTRL_REG1); +		break; +	default: +		break; +	} + +	tap_delay = (degrees * tap_max) / 360; + +	/* Set the Clock Phase */ +	if (tap_delay) { +		regval = sdhci_readl(host, PHY_CTRL_REG1); +		regval |= PHY_CTRL_ITAP_CHG_WIN_MASK; +		sdhci_writel(host, regval, PHY_CTRL_REG1); +		regval |= PHY_CTRL_ITAPDLY_ENA_MASK; +		sdhci_writel(host, regval, PHY_CTRL_REG1); +		regval &= ~PHY_CTRL_ITAPDLY_SEL_MASK; +		regval |= tap_delay << PHY_CTRL_ITAPDLY_SEL_SHIFT; +		sdhci_writel(host, regval, PHY_CTRL_REG1); +		regval &= ~PHY_CTRL_ITAP_CHG_WIN_MASK; +		sdhci_writel(host, regval, PHY_CTRL_REG1); +	} + +	return 0; +} + +static const struct clk_ops versal_net_sampleclk_ops = { +	.recalc_rate = sdhci_arasan_sampleclk_recalc_rate, +	.set_phase = sdhci_versal_net_emmc_sampleclk_set_phase, +}; +  static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u32 deviceid)  {  	u16 clk; @@ -1107,7 +1291,17 @@ static void arasan_dt_parse_clk_phases(struct device *dev,  			clk_data->clk_phase_out[i] = versal_oclk_phase[i];  		}  	} +	if (of_device_is_compatible(dev->of_node, "xlnx,versal-net-emmc")) { +		u32 versal_net_iclk_phase[MMC_TIMING_MMC_HS400 + 1] = +			VERSAL_NET_EMMC_ICLK_PHASE; +		u32 versal_net_oclk_phase[MMC_TIMING_MMC_HS400 + 1] = +			VERSAL_NET_EMMC_OCLK_PHASE; +		for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) { +			clk_data->clk_phase_in[i] = versal_net_iclk_phase[i]; +			clk_data->clk_phase_out[i] = versal_net_oclk_phase[i]; +		} +	}  	arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_LEGACY,  				 "clk-phase-legacy");  	arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_MMC_HS, @@ -1150,12 +1344,6 @@ static struct sdhci_arasan_of_data sdhci_arasan_generic_data = {  	.clk_ops = &arasan_clk_ops,  }; -static const struct sdhci_arasan_of_data sdhci_arasan_thunderbay_data = { -	.soc_ctl_map = &thunderbay_soc_ctl_map, -	.pdata = &sdhci_arasan_thunderbay_pdata, -	.clk_ops = &arasan_clk_ops, -}; -  static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = {  	.ops = &sdhci_arasan_cqe_ops,  	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | @@ -1225,6 +1413,14 @@ static const struct sdhci_pltfm_data sdhci_arasan_zynqmp_pdata = {  			SDHCI_QUIRK2_STOP_WITH_TC,  }; +static const struct sdhci_pltfm_data sdhci_arasan_versal_net_pdata = { +	.ops = &sdhci_arasan_ops, +	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | +			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | +			SDHCI_QUIRK2_STOP_WITH_TC | +			SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400, +}; +  static const struct sdhci_arasan_clk_ops zynqmp_clk_ops = {  	.sdcardclk_ops = &zynqmp_sdcardclk_ops,  	.sampleclk_ops = &zynqmp_sampleclk_ops, @@ -1245,6 +1441,16 @@ static struct sdhci_arasan_of_data sdhci_arasan_versal_data = {  	.clk_ops = &versal_clk_ops,  }; +static const struct sdhci_arasan_clk_ops versal_net_clk_ops = { +	.sdcardclk_ops = &versal_net_sdcardclk_ops, +	.sampleclk_ops = &versal_net_sampleclk_ops, +}; + +static struct sdhci_arasan_of_data sdhci_arasan_versal_net_data = { +	.pdata = &sdhci_arasan_versal_net_pdata, +	.clk_ops = &versal_net_clk_ops, +}; +  static struct sdhci_arasan_of_data intel_keembay_emmc_data = {  	.soc_ctl_map = &intel_keembay_soc_ctl_map,  	.pdata = &sdhci_keembay_emmc_pdata, @@ -1289,10 +1495,6 @@ static const struct of_device_id sdhci_arasan_of_match[] = {  		.compatible = "intel,keembay-sdhci-5.1-sdio",  		.data = &intel_keembay_sdio_data,  	}, -	{ -		.compatible = "intel,thunderbay-sdhci-5.1", -		.data = &sdhci_arasan_thunderbay_data, -	},  	/* Generic compatible below here */  	{  		.compatible = "arasan,sdhci-8.9a", @@ -1314,6 +1516,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = {  		.compatible = "xlnx,versal-8.9a",  		.data = &sdhci_arasan_versal_data,  	}, +	{ +		.compatible = "xlnx,versal-net-emmc", +		.data = &sdhci_arasan_versal_net_data, +	},  	{ /* sentinel */ }  };  MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match); @@ -1434,7 +1640,7 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev)  {  	struct device_node *np = dev->of_node; -	if (!of_find_property(np, "#clock-cells", NULL)) +	if (!of_property_present(np, "#clock-cells"))  		return;  	of_clk_del_provider(dev->of_node); @@ -1630,6 +1836,7 @@ static int sdhci_arasan_probe(struct platform_device *pdev)  	int ret;  	struct device_node *node;  	struct clk *clk_xin; +	struct clk *clk_dll;  	struct sdhci_host *host;  	struct sdhci_pltfm_host *pltfm_host;  	struct device *dev = &pdev->dev; @@ -1703,6 +1910,12 @@ static int sdhci_arasan_probe(struct platform_device *pdev)  		goto clk_dis_ahb;  	} +	clk_dll = devm_clk_get_optional_enabled(dev, "gate"); +	if (IS_ERR(clk_dll)) { +		ret = dev_err_probe(dev, PTR_ERR(clk_dll), "failed to get dll clk\n"); +		goto clk_disable_all; +	} +  	if (of_property_read_bool(np, "xlnx,fails-without-test-cd"))  		sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_FORCE_CDTEST; @@ -1716,8 +1929,7 @@ static int sdhci_arasan_probe(struct platform_device *pdev)  	if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||  	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") || -	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio") || -	    of_device_is_compatible(np, "intel,thunderbay-sdhci-5.1")) { +	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {  		sdhci_arasan_update_clockmultiplier(host, 0x0);  		sdhci_arasan_update_support64b(host, 0x0); @@ -1781,6 +1993,9 @@ static int sdhci_arasan_probe(struct platform_device *pdev)  			host->mmc->caps2 |= MMC_CAP2_CQE_DCMD;  	} +	if (of_device_is_compatible(np, "xlnx,versal-net-emmc")) +		sdhci_arasan->internal_phy_reg = true; +  	ret = sdhci_arasan_add_host(sdhci_arasan);  	if (ret)  		goto err_add_host; diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c index ba6677bf7372..25b4073f698b 100644 --- a/drivers/mmc/host/sdhci-of-aspeed.c +++ b/drivers/mmc/host/sdhci-of-aspeed.c @@ -547,8 +547,7 @@ static int aspeed_sdc_probe(struct platform_device *pdev)  		return ret;  	} -	sdc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	sdc->regs = devm_ioremap_resource(&pdev->dev, sdc->res); +	sdc->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &sdc->res);  	if (IS_ERR(sdc->regs)) {  		ret = PTR_ERR(sdc->regs);  		goto err_clk; diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index d1490469184b..e68cd87998c8 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -126,6 +126,13 @@ static unsigned int dwcmshc_get_max_clock(struct sdhci_host *host)  		return pltfm_host->clock;  } +static unsigned int rk35xx_get_max_clock(struct sdhci_host *host) +{ +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + +	return clk_round_rate(pltfm_host->clk, ULONG_MAX); +} +  static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc,  				     struct mmc_request *mrq)  { @@ -343,7 +350,7 @@ static const struct sdhci_ops sdhci_dwcmshc_rk35xx_ops = {  	.set_clock		= dwcmshc_rk3568_set_clock,  	.set_bus_width		= sdhci_set_bus_width,  	.set_uhs_signaling	= dwcmshc_set_uhs_signaling, -	.get_max_clock		= sdhci_pltfm_clk_get_max_clock, +	.get_max_clock		= rk35xx_get_max_clock,  	.reset			= rk35xx_sdhci_reset,  	.adma_write_desc	= dwcmshc_adma_write_desc,  }; diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 4712adac7f7c..48ca1cf15b19 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -133,6 +133,7 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,  			return ret;  		}  	} +  	/*  	 * The DAT[3:0] line signal levels and the CMD line signal level are  	 * not compatible with standard SDHC register. The line signal levels @@ -144,6 +145,16 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,  		ret = value & 0x000fffff;  		ret |= (value >> 4) & SDHCI_DATA_LVL_MASK;  		ret |= (value << 1) & SDHCI_CMD_LVL; + +		/* +		 * Some controllers have unreliable Data Line Active +		 * bit for commands with busy signal. This affects +		 * Command Inhibit (data) bit. Just ignore it since +		 * MMC core driver has already polled card status +		 * with CMD13 after any command with busy siganl. +		 */ +		if (esdhc->quirk_ignore_data_inhibit) +			ret &= ~SDHCI_DATA_INHIBIT;  		return ret;  	} @@ -158,19 +169,6 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,  		return ret;  	} -	/* -	 * Some controllers have unreliable Data Line Active -	 * bit for commands with busy signal. This affects -	 * Command Inhibit (data) bit. Just ignore it since -	 * MMC core driver has already polled card status -	 * with CMD13 after any command with busy siganl. -	 */ -	if ((spec_reg == SDHCI_PRESENT_STATE) && -	(esdhc->quirk_ignore_data_inhibit == true)) { -		ret = value & ~SDHCI_DATA_INHIBIT; -		return ret; -	} -  	ret = value;  	return ret;  } diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c index 98cadff47b2b..620f52ad9667 100644 --- a/drivers/mmc/host/sdhci-pci-o2micro.c +++ b/drivers/mmc/host/sdhci-pci-o2micro.c @@ -339,22 +339,24 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)  	reg_val &= ~SDHCI_CLOCK_CARD_EN;  	sdhci_writew(host, reg_val, SDHCI_CLOCK_CONTROL); -	/* UnLock WP */ -	pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); -	scratch_8 &= 0x7f; -	pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); - -	/* Set pcr 0x354[16] to choose dll clock, and set the default phase */ -	pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, ®_val); -	reg_val &= ~(O2_SD_SEL_DLL | O2_SD_PHASE_MASK); -	reg_val |= (O2_SD_SEL_DLL | O2_SD_FIX_PHASE); -	pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, reg_val); +	if ((host->timing == MMC_TIMING_MMC_HS200) || +		(host->timing == MMC_TIMING_UHS_SDR104)) { +		/* UnLock WP */ +		pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); +		scratch_8 &= 0x7f; +		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); -	/* Lock WP */ -	pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); -	scratch_8 |= 0x80; -	pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); +		/* Set pcr 0x354[16] to choose dll clock, and set the default phase */ +		pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, ®_val); +		reg_val &= ~(O2_SD_SEL_DLL | O2_SD_PHASE_MASK); +		reg_val |= (O2_SD_SEL_DLL | O2_SD_FIX_PHASE); +		pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, reg_val); +		/* Lock WP */ +		pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); +		scratch_8 |= 0x80; +		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); +	}  	/* Start clk */  	reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL);  	reg_val |= SDHCI_CLOCK_CARD_EN; diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 328b132bbe57..673e750a8490 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -54,7 +54,6 @@ static bool sdhci_wp_inverted(struct device *dev)  #endif /* CONFIG_PPC */  } -#ifdef CONFIG_OF  static void sdhci_get_compatibility(struct platform_device *pdev)  {  	struct sdhci_host *host = platform_get_drvdata(pdev); @@ -72,9 +71,6 @@ static void sdhci_get_compatibility(struct platform_device *pdev)  	    of_device_is_compatible(np, "fsl,mpc8536-esdhc"))  		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;  } -#else -void sdhci_get_compatibility(struct platform_device *pdev) {} -#endif /* CONFIG_OF */  void sdhci_get_property(struct platform_device *pdev)  { diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index fc306eb1f845..91aca8f8d6ef 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c @@ -228,7 +228,7 @@ static struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev)  	if (!pdata)  		return NULL; -	if (of_find_property(np, "non-removable", NULL)) +	if (of_property_read_bool(np, "non-removable"))  		pdata->flags |= PXA_FLAG_CARD_PERMANENT;  	of_property_read_u32(np, "bus-width", &bus_width); diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 9085f3932443..504015e84308 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -437,12 +437,12 @@ static int sdhci_s3c_parse_dt(struct device *dev,  	pdata->max_width = max_width;  	/* get the card detection method */ -	if (of_get_property(node, "broken-cd", NULL)) { +	if (of_property_read_bool(node, "broken-cd")) {  		pdata->cd_type = S3C_SDHCI_CD_NONE;  		return 0;  	} -	if (of_get_property(node, "non-removable", NULL)) { +	if (of_property_read_bool(node, "non-removable")) {  		pdata->cd_type = S3C_SDHCI_CD_PERMANENT;  		return 0;  	} diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index 7ef828942df3..7cdf0f54e3a5 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -85,6 +85,7 @@  #define DRIVER_STRENGTH_40_OHM	0x4  #define CLOCK_TOO_SLOW_HZ	50000000 +#define SDHCI_AM654_AUTOSUSPEND_DELAY	-1  /* Command Queue Host Controller Interface Base address */  #define SDHCI_AM654_CQE_BASE_ADDR 0x200 @@ -351,8 +352,6 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)  		 */  		case MMC_TIMING_SD_HS:  		case MMC_TIMING_MMC_HS: -		case MMC_TIMING_UHS_SDR12: -		case MMC_TIMING_UHS_SDR25:  			val &= ~SDHCI_CTRL_HISPD;  		}  	} @@ -369,7 +368,7 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)  					MAX_POWER_ON_TIMEOUT, false, host, val,  					reg);  		if (ret) -			dev_warn(mmc_dev(host->mmc), "Power on failed\n"); +			dev_info(mmc_dev(host->mmc), "Power on failed\n");  	}  } @@ -810,16 +809,10 @@ static int sdhci_am654_probe(struct platform_device *pdev)  	pltfm_host->clk = clk_xin; -	/* Clocks are enabled using pm_runtime */ -	pm_runtime_enable(dev); -	ret = pm_runtime_resume_and_get(dev); -	if (ret) -		goto pm_runtime_disable; -  	base = devm_platform_ioremap_resource(pdev, 1);  	if (IS_ERR(base)) {  		ret = PTR_ERR(base); -		goto pm_runtime_put; +		goto err_pltfm_free;  	}  	sdhci_am654->base = devm_regmap_init_mmio(dev, base, @@ -827,31 +820,47 @@ static int sdhci_am654_probe(struct platform_device *pdev)  	if (IS_ERR(sdhci_am654->base)) {  		dev_err(dev, "Failed to initialize regmap\n");  		ret = PTR_ERR(sdhci_am654->base); -		goto pm_runtime_put; +		goto err_pltfm_free;  	}  	ret = sdhci_am654_get_of_property(pdev, sdhci_am654);  	if (ret) -		goto pm_runtime_put; +		goto err_pltfm_free;  	ret = mmc_of_parse(host->mmc);  	if (ret) {  		dev_err_probe(dev, ret, "parsing dt failed\n"); -		goto pm_runtime_put; +		goto err_pltfm_free;  	}  	host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning; +	pm_runtime_get_noresume(dev); +	ret = pm_runtime_set_active(dev); +	if (ret) +		goto pm_put; +	pm_runtime_enable(dev); +	ret = clk_prepare_enable(pltfm_host->clk); +	if (ret) +		goto pm_disable; +  	ret = sdhci_am654_init(host);  	if (ret) -		goto pm_runtime_put; +		goto clk_disable; +	/* Setting up autosuspend */ +	pm_runtime_set_autosuspend_delay(dev, SDHCI_AM654_AUTOSUSPEND_DELAY); +	pm_runtime_use_autosuspend(dev); +	pm_runtime_mark_last_busy(dev); +	pm_runtime_put_autosuspend(dev);  	return 0; -pm_runtime_put: -	pm_runtime_put_sync(dev); -pm_runtime_disable: +clk_disable: +	clk_disable_unprepare(pltfm_host->clk); +pm_disable:  	pm_runtime_disable(dev); +pm_put: +	pm_runtime_put_noidle(dev);  err_pltfm_free:  	sdhci_pltfm_free(pdev);  	return ret; @@ -860,23 +869,127 @@ err_pltfm_free:  static int sdhci_am654_remove(struct platform_device *pdev)  {  	struct sdhci_host *host = platform_get_drvdata(pdev); +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);  	int ret; -	sdhci_remove_host(host, true); -	ret = pm_runtime_put_sync(&pdev->dev); +	ret = pm_runtime_resume_and_get(&pdev->dev);  	if (ret < 0)  		return ret; +	sdhci_remove_host(host, true); +	clk_disable_unprepare(pltfm_host->clk);  	pm_runtime_disable(&pdev->dev); +	pm_runtime_put_noidle(&pdev->dev);  	sdhci_pltfm_free(pdev); +	return 0; +} + +#ifdef CONFIG_PM +static int sdhci_am654_restore(struct sdhci_host *host) +{ +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); +	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); +	u32 ctl_cfg_2 = 0; +	u32 val; +	int ret; + +	if (sdhci_am654->flags & DLL_CALIB) { +		regmap_read(sdhci_am654->base, PHY_STAT1, &val); +		if (~val & CALDONE_MASK) { +			/* Calibrate IO lines */ +			regmap_update_bits(sdhci_am654->base, PHY_CTRL1, +					   PDB_MASK, PDB_MASK); +			ret = regmap_read_poll_timeout(sdhci_am654->base, +						       PHY_STAT1, val, +						       val & CALDONE_MASK, +						       1, 20); +			if (ret) +				return ret; +		} +	} + +	/* Enable pins by setting IO mux to 0 */ +	if (sdhci_am654->flags & IOMUX_PRESENT) +		regmap_update_bits(sdhci_am654->base, PHY_CTRL1, +				   IOMUX_ENABLE_MASK, 0); +	/* Set slot type based on SD or eMMC */ +	if (host->mmc->caps & MMC_CAP_NONREMOVABLE) +		ctl_cfg_2 = SLOTTYPE_EMBEDDED; + +	regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK, +			   ctl_cfg_2); + +	regmap_read(sdhci_am654->base, CTL_CFG_3, &val); +	if (~val & TUNINGFORSDR50_MASK) +		/* Enable tuning for SDR50 */ +		regmap_update_bits(sdhci_am654->base, CTL_CFG_3, TUNINGFORSDR50_MASK, +				   TUNINGFORSDR50_MASK); + +	return 0; +} + +static int sdhci_am654_runtime_suspend(struct device *dev) +{ +	struct sdhci_host *host = dev_get_drvdata(dev); +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); +	int ret; + +	if (host->tuning_mode != SDHCI_TUNING_MODE_3) +		mmc_retune_needed(host->mmc); + +	ret = cqhci_suspend(host->mmc); +	if (ret) +		return ret; + +	ret = sdhci_runtime_suspend_host(host); +	if (ret) +		return ret; + +	/* disable the clock */ +	clk_disable_unprepare(pltfm_host->clk);  	return 0;  } +static int sdhci_am654_runtime_resume(struct device *dev) +{ +	struct sdhci_host *host = dev_get_drvdata(dev); +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); +	int ret; + +	/* Enable the clock */ +	ret = clk_prepare_enable(pltfm_host->clk); +	if (ret) +		return ret; + +	ret = sdhci_am654_restore(host); +	if (ret) +		return ret; + +	ret = sdhci_runtime_resume_host(host, 0); +	if (ret) +		return ret; + +	ret = cqhci_resume(host->mmc); +	if (ret) +		return ret; + +	return 0; +} +#endif + +static const struct dev_pm_ops sdhci_am654_dev_pm_ops = { +	SET_RUNTIME_PM_OPS(sdhci_am654_runtime_suspend, +			   sdhci_am654_runtime_resume, NULL) +	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, +				pm_runtime_force_resume) +}; +  static struct platform_driver sdhci_am654_driver = {  	.driver = {  		.name = "sdhci-am654",  		.probe_type = PROBE_PREFER_ASYNCHRONOUS, +		.pm = &sdhci_am654_dev_pm_ops,  		.of_match_table = sdhci_am654_of_match,  	},  	.probe = sdhci_am654_probe, diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index 76a8cd3a186f..57b8c1a96756 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -101,14 +101,6 @@ static inline void sdricoh_writel(struct sdricoh_host *host, unsigned int reg,  } -static inline unsigned int sdricoh_readw(struct sdricoh_host *host, -					 unsigned int reg) -{ -	unsigned int value = readw(host->iobase + reg); -	dev_vdbg(host->dev, "rb %x 0x%x\n", reg, value); -	return value; -} -  static inline void sdricoh_writew(struct sdricoh_host *host, unsigned int reg,  					 unsigned short value)  { diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index e24c3d284515..be7f18fd4836 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c @@ -1084,7 +1084,7 @@ static void tmio_mmc_of_parse(struct platform_device *pdev,  	 * For new platforms, please use "disable-wp" instead of  	 * "toshiba,mmc-wrprotect-disable"  	 */ -	if (of_get_property(np, "toshiba,mmc-wrprotect-disable", NULL)) +	if (of_property_read_bool(np, "toshiba,mmc-wrprotect-disable"))  		mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;  } diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c index 99515be6e5e5..2f59917b105e 100644 --- a/drivers/mmc/host/usdhi6rol0.c +++ b/drivers/mmc/host/usdhi6rol0.c @@ -1790,8 +1790,7 @@ static int usdhi6_probe(struct platform_device *pdev)  	host->pins_uhs = pinctrl_lookup_state(host->pinctrl, "state_uhs"); -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	host->base = devm_ioremap_resource(dev, res); +	host->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);  	if (IS_ERR(host->base)) {  		ret = PTR_ERR(host->base);  		goto e_free_mmc; diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index 72f65f32abbc..e4c4bfac3763 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c @@ -1341,8 +1341,6 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,  		return;  	} -	return; -  copy_error_message:  	strncpy(vub300->vub_name, "SDIO pseudocode download failed",  		sizeof(vub300->vub_name)); diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c index 9aa3027ca25e..68525d900046 100644 --- a/drivers/mmc/host/wmt-sdmmc.c +++ b/drivers/mmc/host/wmt-sdmmc.c @@ -802,10 +802,8 @@ static int wmt_mci_probe(struct platform_device *pdev)  	priv->power_inverted = 0;  	priv->cd_inverted = 0; -	if (of_get_property(np, "sdon-inverted", NULL)) -		priv->power_inverted = 1; -	if (of_get_property(np, "cd-inverted", NULL)) -		priv->cd_inverted = 1; +	priv->power_inverted = of_property_read_bool(np, "sdon-inverted"); +	priv->cd_inverted = of_property_read_bool(np, "cd-inverted");  	priv->sdmmc_base = of_iomap(np, 0);  	if (!priv->sdmmc_base) {  |