diff options
Diffstat (limited to 'drivers/mmc/host/mxcmmc.c')
| -rw-r--r-- | drivers/mmc/host/mxcmmc.c | 152 | 
1 files changed, 51 insertions, 101 deletions
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index c174c6a0d22..ed1cb93c378 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -124,9 +124,8 @@ enum mxcmci_type {  struct mxcmci_host {  	struct mmc_host		*mmc; -	struct resource		*res;  	void __iomem		*base; -	int			irq; +	dma_addr_t		phys_base;  	int			detect_irq;  	struct dma_chan		*dma;  	struct dma_async_tx_descriptor *desc; @@ -154,8 +153,6 @@ struct mxcmci_host {  	struct work_struct	datawork;  	spinlock_t		lock; -	struct regulator	*vcc; -  	int			burstlen;  	int			dmareq;  	struct dma_slave_config dma_slave_config; @@ -241,37 +238,15 @@ static inline void mxcmci_writew(struct mxcmci_host *host, u16 val, int reg)  static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); -static inline void mxcmci_init_ocr(struct mxcmci_host *host) -{ -	host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); - -	if (IS_ERR(host->vcc)) { -		host->vcc = NULL; -	} else { -		host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); -		if (host->pdata && host->pdata->ocr_avail) -			dev_warn(mmc_dev(host->mmc), -				"pdata->ocr_avail will not be used\n"); -	} - -	if (host->vcc == NULL) { -		/* fall-back to platform data */ -		if (host->pdata && host->pdata->ocr_avail) -			host->mmc->ocr_avail = host->pdata->ocr_avail; -		else -			host->mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; -	} -} - -static inline void mxcmci_set_power(struct mxcmci_host *host, -				    unsigned char power_mode, -				    unsigned int vdd) +static void mxcmci_set_power(struct mxcmci_host *host, unsigned int vdd)  { -	if (host->vcc) { -		if (power_mode == MMC_POWER_UP) -			mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); -		else if (power_mode == MMC_POWER_OFF) -			mmc_regulator_set_ocr(host->mmc, host->vcc, 0); +	if (!IS_ERR(host->mmc->supply.vmmc)) { +		if (host->power_mode == MMC_POWER_UP) +			mmc_regulator_set_ocr(host->mmc, +					      host->mmc->supply.vmmc, vdd); +		else if (host->power_mode == MMC_POWER_OFF) +			mmc_regulator_set_ocr(host->mmc, +					      host->mmc->supply.vmmc, 0);  	}  	if (host->pdata && host->pdata->setpower) @@ -299,7 +274,6 @@ static void mxcmci_softreset(struct mxcmci_host *host)  	mxcmci_writew(host, 0xff, MMC_REG_RES_TO);  } -static int mxcmci_setup_dma(struct mmc_host *mmc);  #if IS_ENABLED(CONFIG_PPC_MPC512x)  static inline void buffer_swap32(u32 *buf, int len) @@ -868,8 +842,8 @@ static int mxcmci_setup_dma(struct mmc_host *mmc)  	struct mxcmci_host *host = mmc_priv(mmc);  	struct dma_slave_config *config = &host->dma_slave_config; -	config->dst_addr = host->res->start + MMC_REG_BUFFER_ACCESS; -	config->src_addr = host->res->start + MMC_REG_BUFFER_ACCESS; +	config->dst_addr = host->phys_base + MMC_REG_BUFFER_ACCESS; +	config->src_addr = host->phys_base + MMC_REG_BUFFER_ACCESS;  	config->dst_addr_width = 4;  	config->src_addr_width = 4;  	config->dst_maxburst = host->burstlen; @@ -911,8 +885,8 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  		host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;  	if (host->power_mode != ios->power_mode) { -		mxcmci_set_power(host, ios->power_mode, ios->vdd);  		host->power_mode = ios->power_mode; +		mxcmci_set_power(host, ios->vdd);  		if (ios->power_mode == MMC_POWER_ON)  			host->cmdat |= CMD_DAT_CONT_INIT; @@ -1040,8 +1014,8 @@ static const struct mmc_host_ops mxcmci_ops = {  static int mxcmci_probe(struct platform_device *pdev)  {  	struct mmc_host *mmc; -	struct mxcmci_host *host = NULL; -	struct resource *iores, *r; +	struct mxcmci_host *host; +	struct resource *res;  	int ret = 0, irq;  	bool dat3_card_detect = false;  	dma_cap_mask_t mask; @@ -1052,21 +1026,25 @@ static int mxcmci_probe(struct platform_device *pdev)  	of_id = of_match_device(mxcmci_of_match, &pdev->dev); -	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	irq = platform_get_irq(pdev, 0); -	if (!iores || irq < 0) +	if (irq < 0)  		return -EINVAL; -	r = request_mem_region(iores->start, resource_size(iores), pdev->name); -	if (!r) -		return -EBUSY; +	mmc = mmc_alloc_host(sizeof(*host), &pdev->dev); +	if (!mmc) +		return -ENOMEM; -	mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev); -	if (!mmc) { -		ret = -ENOMEM; -		goto out_release_mem; +	host = mmc_priv(mmc); + +	host->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(host->base)) { +		ret = PTR_ERR(host->base); +		goto out_free;  	} +	host->phys_base = res->start; +  	ret = mmc_of_parse(mmc);  	if (ret)  		goto out_free; @@ -1084,13 +1062,6 @@ static int mxcmci_probe(struct platform_device *pdev)  	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;  	mmc->max_seg_size = mmc->max_req_size; -	host = mmc_priv(mmc); -	host->base = ioremap(r->start, resource_size(r)); -	if (!host->base) { -		ret = -ENOMEM; -		goto out_free; -	} -  	if (of_id) {  		const struct platform_device_id *id_entry = of_id->data;  		host->devtype = id_entry->driver_data; @@ -1112,7 +1083,14 @@ static int mxcmci_probe(struct platform_device *pdev)  			&& !of_property_read_bool(pdev->dev.of_node, "cd-gpios"))  		dat3_card_detect = true; -	mxcmci_init_ocr(host); +	ret = mmc_regulator_get_supply(mmc); +	if (ret) { +		if (pdata && ret != -EPROBE_DEFER) +			mmc->ocr_avail = pdata->ocr_avail ? : +				MMC_VDD_32_33 | MMC_VDD_33_34; +		else +			goto out_free; +	}  	if (dat3_card_detect)  		host->default_irq_mask = @@ -1120,19 +1098,16 @@ static int mxcmci_probe(struct platform_device *pdev)  	else  		host->default_irq_mask = 0; -	host->res = r; -	host->irq = irq; -  	host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");  	if (IS_ERR(host->clk_ipg)) {  		ret = PTR_ERR(host->clk_ipg); -		goto out_iounmap; +		goto out_free;  	}  	host->clk_per = devm_clk_get(&pdev->dev, "per");  	if (IS_ERR(host->clk_per)) {  		ret = PTR_ERR(host->clk_per); -		goto out_iounmap; +		goto out_free;  	}  	clk_prepare_enable(host->clk_per); @@ -1159,9 +1134,9 @@ static int mxcmci_probe(struct platform_device *pdev)  	if (!host->pdata) {  		host->dma = dma_request_slave_channel(&pdev->dev, "rx-tx");  	} else { -		r = platform_get_resource(pdev, IORESOURCE_DMA, 0); -		if (r) { -			host->dmareq = r->start; +		res = platform_get_resource(pdev, IORESOURCE_DMA, 0); +		if (res) { +			host->dmareq = res->start;  			host->dma_data.peripheral_type = IMX_DMATYPE_SDHC;  			host->dma_data.priority = DMA_PRIO_LOW;  			host->dma_data.dma_request = host->dmareq; @@ -1178,7 +1153,8 @@ static int mxcmci_probe(struct platform_device *pdev)  	INIT_WORK(&host->datawork, mxcmci_datawork); -	ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host); +	ret = devm_request_irq(&pdev->dev, irq, mxcmci_irq, 0, +			       dev_name(&pdev->dev), host);  	if (ret)  		goto out_free_dma; @@ -1188,7 +1164,7 @@ static int mxcmci_probe(struct platform_device *pdev)  		ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq,  				host->mmc);  		if (ret) -			goto out_free_irq; +			goto out_free_dma;  	}  	init_timer(&host->watchdog); @@ -1199,20 +1175,17 @@ static int mxcmci_probe(struct platform_device *pdev)  	return 0; -out_free_irq: -	free_irq(host->irq, host);  out_free_dma:  	if (host->dma)  		dma_release_channel(host->dma); +  out_clk_put:  	clk_disable_unprepare(host->clk_per);  	clk_disable_unprepare(host->clk_ipg); -out_iounmap: -	iounmap(host->base); +  out_free:  	mmc_free_host(mmc); -out_release_mem: -	release_mem_region(iores->start, resource_size(iores)); +  	return ret;  } @@ -1223,62 +1196,41 @@ static int mxcmci_remove(struct platform_device *pdev)  	mmc_remove_host(mmc); -	if (host->vcc) -		regulator_put(host->vcc); -  	if (host->pdata && host->pdata->exit)  		host->pdata->exit(&pdev->dev, mmc); -	free_irq(host->irq, host); -	iounmap(host->base); -  	if (host->dma)  		dma_release_channel(host->dma);  	clk_disable_unprepare(host->clk_per);  	clk_disable_unprepare(host->clk_ipg); -	release_mem_region(host->res->start, resource_size(host->res)); -  	mmc_free_host(mmc);  	return 0;  } -#ifdef CONFIG_PM -static int mxcmci_suspend(struct device *dev) +static int __maybe_unused mxcmci_suspend(struct device *dev)  {  	struct mmc_host *mmc = dev_get_drvdata(dev);  	struct mxcmci_host *host = mmc_priv(mmc); -	int ret = 0; -	if (mmc) -		ret = mmc_suspend_host(mmc);  	clk_disable_unprepare(host->clk_per);  	clk_disable_unprepare(host->clk_ipg); - -	return ret; +	return 0;  } -static int mxcmci_resume(struct device *dev) +static int __maybe_unused mxcmci_resume(struct device *dev)  {  	struct mmc_host *mmc = dev_get_drvdata(dev);  	struct mxcmci_host *host = mmc_priv(mmc); -	int ret = 0;  	clk_prepare_enable(host->clk_per);  	clk_prepare_enable(host->clk_ipg); -	if (mmc) -		ret = mmc_resume_host(mmc); - -	return ret; +	return 0;  } -static const struct dev_pm_ops mxcmci_pm_ops = { -	.suspend	= mxcmci_suspend, -	.resume		= mxcmci_resume, -}; -#endif +static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume);  static struct platform_driver mxcmci_driver = {  	.probe		= mxcmci_probe, @@ -1287,9 +1239,7 @@ static struct platform_driver mxcmci_driver = {  	.driver		= {  		.name		= DRIVER_NAME,  		.owner		= THIS_MODULE, -#ifdef CONFIG_PM  		.pm	= &mxcmci_pm_ops, -#endif  		.of_match_table	= mxcmci_of_match,  	}  };  | 
