diff options
Diffstat (limited to 'drivers/mmc/host/mmci.c')
| -rw-r--r-- | drivers/mmc/host/mmci.c | 76 | 
1 files changed, 50 insertions, 26 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index edc3e9baf0e..150772395cc 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -33,6 +33,7 @@  #include <linux/amba/mmci.h>  #include <linux/pm_runtime.h>  #include <linux/types.h> +#include <linux/pinctrl/consumer.h>  #include <asm/div64.h>  #include <asm/io.h> @@ -261,7 +262,7 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)   * no custom DMA interfaces are supported.   */  #ifdef CONFIG_DMA_ENGINE -static void __devinit mmci_dma_setup(struct mmci_host *host) +static void mmci_dma_setup(struct mmci_host *host)  {  	struct mmci_platform_data *plat = host->plat;  	const char *rxname, *txname; @@ -337,7 +338,7 @@ static void __devinit mmci_dma_setup(struct mmci_host *host)  }  /* - * This is used in __devinit or __devexit so inline it + * This is used in or so inline it   * so it can be discarded.   */  static inline void mmci_dma_release(struct mmci_host *host) @@ -654,9 +655,31 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)  	/* The ST Micro variants has a special bit to enable SDIO */  	if (variant->sdio && host->mmc->card) -		if (mmc_card_sdio(host->mmc->card)) +		if (mmc_card_sdio(host->mmc->card)) { +			/* +			 * The ST Micro variants has a special bit +			 * to enable SDIO. +			 */ +			u32 clk; +  			datactrl |= MCI_ST_DPSM_SDIOEN; +			/* +			 * The ST Micro variant for SDIO small write transfers +			 * needs to have clock H/W flow control disabled, +			 * otherwise the transfer will not start. The threshold +			 * depends on the rate of MCLK. +			 */ +			if (data->flags & MMC_DATA_WRITE && +			    (host->size < 8 || +			     (host->size <= 8 && host->mclk > 50000000))) +				clk = host->clk_reg & ~variant->clkreg_enable; +			else +				clk = host->clk_reg | variant->clkreg_enable; + +			mmci_write_clkreg(host, clk); +		} +  	/*  	 * Attempt to use DMA operation mode, if this  	 * should fail, fall back to PIO mode @@ -840,14 +863,14 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema  		if (unlikely(count & 0x3)) {  			if (count < 4) {  				unsigned char buf[4]; -				readsl(base + MMCIFIFO, buf, 1); +				ioread32_rep(base + MMCIFIFO, buf, 1);  				memcpy(ptr, buf, count);  			} else { -				readsl(base + MMCIFIFO, ptr, count >> 2); +				ioread32_rep(base + MMCIFIFO, ptr, count >> 2);  				count &= ~0x3;  			}  		} else { -			readsl(base + MMCIFIFO, ptr, count >> 2); +			ioread32_rep(base + MMCIFIFO, ptr, count >> 2);  		}  		ptr += count; @@ -877,22 +900,6 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem  		count = min(remain, maxcnt);  		/* -		 * The ST Micro variant for SDIO transfer sizes -		 * less then 8 bytes should have clock H/W flow -		 * control disabled. -		 */ -		if (variant->sdio && -		    mmc_card_sdio(host->mmc->card)) { -			u32 clk; -			if (count < 8) -				clk = host->clk_reg & ~variant->clkreg_enable; -			else -				clk = host->clk_reg | variant->clkreg_enable; - -			mmci_write_clkreg(host, clk); -		} - -		/*  		 * SDIO especially may want to send something that is  		 * not divisible by 4 (as opposed to card sectors  		 * etc), and the FIFO only accept full 32-bit writes. @@ -900,7 +907,7 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem  		 * byte become a 32bit write, 7 bytes will be two  		 * 32bit writes etc.  		 */ -		writesl(base + MMCIFIFO, ptr, (count + 3) >> 2); +		iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2);  		ptr += count;  		remain -= count; @@ -1255,7 +1262,7 @@ static void mmci_dt_populate_generic_pdata(struct device_node *np,  }  #endif -static int __devinit mmci_probe(struct amba_device *dev, +static int mmci_probe(struct amba_device *dev,  	const struct amba_id *id)  {  	struct mmci_platform_data *plat = dev->dev.platform_data; @@ -1360,6 +1367,23 @@ static int __devinit mmci_probe(struct amba_device *dev,  		mmc->f_max = min(host->mclk, fmax);  	dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); +	host->pinctrl = devm_pinctrl_get(&dev->dev); +	if (IS_ERR(host->pinctrl)) { +		ret = PTR_ERR(host->pinctrl); +		goto clk_disable; +	} + +	host->pins_default = pinctrl_lookup_state(host->pinctrl, +			PINCTRL_STATE_DEFAULT); + +	/* enable pins to be muxed in and configured */ +	if (!IS_ERR(host->pins_default)) { +		ret = pinctrl_select_state(host->pinctrl, host->pins_default); +		if (ret) +			dev_warn(&dev->dev, "could not set default pins\n"); +	} else +		dev_warn(&dev->dev, "could not get default pinstate\n"); +  #ifdef CONFIG_REGULATOR  	/* If we're using the regulator framework, try to fetch a regulator */  	host->vcc = regulator_get(&dev->dev, "vmmc"); @@ -1522,7 +1546,7 @@ static int __devinit mmci_probe(struct amba_device *dev,  	return ret;  } -static int __devexit mmci_remove(struct amba_device *dev) +static int mmci_remove(struct amba_device *dev)  {  	struct mmc_host *mmc = amba_get_drvdata(dev); @@ -1669,7 +1693,7 @@ static struct amba_driver mmci_driver = {  		.pm	= &mmci_dev_pm_ops,  	},  	.probe		= mmci_probe, -	.remove		= __devexit_p(mmci_remove), +	.remove		= mmci_remove,  	.id_table	= mmci_ids,  };  |