forked from mirrors/linux
		
	mmc: sdhci: add get_cd() implementation
1. mmc_rescan will call get_cd to know whether the card is present before mmc_rescan_try_freq to avoid useless trials during card removal or start host is called when card is not present. 2. get_cd needs to be checked to resolve slow card removal issue. Signed-off-by: Kevin Liu <kliu5@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
		
							parent
							
								
									1450734ec6
								
							
						
					
					
						commit
						94144a465d
					
				
					 1 changed files with 32 additions and 0 deletions
				
			
		| 
						 | 
					@ -1581,6 +1581,37 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 | 
				
			||||||
	sdhci_runtime_pm_put(host);
 | 
						sdhci_runtime_pm_put(host);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sdhci_do_get_cd(struct sdhci_host *host)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int gpio_cd = mmc_gpio_get_cd(host->mmc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (host->flags & SDHCI_DEVICE_DEAD)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If polling/nonremovable, assume that the card is always present. */
 | 
				
			||||||
 | 
						if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
 | 
				
			||||||
 | 
						    (host->mmc->caps & MMC_CAP_NONREMOVABLE))
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Try slot gpio detect */
 | 
				
			||||||
 | 
						if (!IS_ERR_VALUE(gpio_cd))
 | 
				
			||||||
 | 
							return !!gpio_cd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Host native card detect */
 | 
				
			||||||
 | 
						return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sdhci_get_cd(struct mmc_host *mmc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sdhci_host *host = mmc_priv(mmc);
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sdhci_runtime_pm_get(host);
 | 
				
			||||||
 | 
						ret = sdhci_do_get_cd(host);
 | 
				
			||||||
 | 
						sdhci_runtime_pm_put(host);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sdhci_check_ro(struct sdhci_host *host)
 | 
					static int sdhci_check_ro(struct sdhci_host *host)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
| 
						 | 
					@ -2038,6 +2069,7 @@ static void sdhci_card_event(struct mmc_host *mmc)
 | 
				
			||||||
static const struct mmc_host_ops sdhci_ops = {
 | 
					static const struct mmc_host_ops sdhci_ops = {
 | 
				
			||||||
	.request	= sdhci_request,
 | 
						.request	= sdhci_request,
 | 
				
			||||||
	.set_ios	= sdhci_set_ios,
 | 
						.set_ios	= sdhci_set_ios,
 | 
				
			||||||
 | 
						.get_cd		= sdhci_get_cd,
 | 
				
			||||||
	.get_ro		= sdhci_get_ro,
 | 
						.get_ro		= sdhci_get_ro,
 | 
				
			||||||
	.hw_reset	= sdhci_hw_reset,
 | 
						.hw_reset	= sdhci_hw_reset,
 | 
				
			||||||
	.enable_sdio_irq = sdhci_enable_sdio_irq,
 | 
						.enable_sdio_irq = sdhci_enable_sdio_irq,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue