diff options
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
| -rw-r--r-- | drivers/mmc/host/sdhci.c | 448 | 
1 files changed, 247 insertions, 201 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 6f0bfc0c8c9..51bbba486f3 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -53,6 +53,7 @@ static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);  static void sdhci_finish_command(struct sdhci_host *);  static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);  static void sdhci_tuning_timer(unsigned long data); +static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);  #ifdef CONFIG_PM_RUNTIME  static int sdhci_runtime_pm_get(struct sdhci_host *host); @@ -1082,6 +1083,37 @@ static void sdhci_finish_command(struct sdhci_host *host)  	}  } +static u16 sdhci_get_preset_value(struct sdhci_host *host) +{ +	u16 ctrl, preset = 0; + +	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + +	switch (ctrl & SDHCI_CTRL_UHS_MASK) { +	case SDHCI_CTRL_UHS_SDR12: +		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12); +		break; +	case SDHCI_CTRL_UHS_SDR25: +		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25); +		break; +	case SDHCI_CTRL_UHS_SDR50: +		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50); +		break; +	case SDHCI_CTRL_UHS_SDR104: +		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104); +		break; +	case SDHCI_CTRL_UHS_DDR50: +		preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50); +		break; +	default: +		pr_warn("%s: Invalid UHS-I mode selected\n", +			mmc_hostname(host->mmc)); +		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12); +		break; +	} +	return preset; +} +  static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)  {  	int div = 0; /* Initialized for compiler warning */ @@ -1106,35 +1138,43 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)  		goto out;  	if (host->version >= SDHCI_SPEC_300) { +		if (sdhci_readw(host, SDHCI_HOST_CONTROL2) & +			SDHCI_CTRL_PRESET_VAL_ENABLE) { +			u16 pre_val; + +			clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); +			pre_val = sdhci_get_preset_value(host); +			div = (pre_val & SDHCI_PRESET_SDCLK_FREQ_MASK) +				>> SDHCI_PRESET_SDCLK_FREQ_SHIFT; +			if (host->clk_mul && +				(pre_val & SDHCI_PRESET_CLKGEN_SEL_MASK)) { +				clk = SDHCI_PROG_CLOCK_MODE; +				real_div = div + 1; +				clk_mul = host->clk_mul; +			} else { +				real_div = max_t(int, 1, div << 1); +			} +			goto clock_set; +		} +  		/*  		 * Check if the Host Controller supports Programmable Clock  		 * Mode.  		 */  		if (host->clk_mul) { -			u16 ctrl; - +			for (div = 1; div <= 1024; div++) { +				if ((host->max_clk * host->clk_mul / div) +					<= clock) +					break; +			}  			/* -			 * We need to figure out whether the Host Driver needs -			 * to select Programmable Clock Mode, or the value can -			 * be set automatically by the Host Controller based on -			 * the Preset Value registers. +			 * Set Programmable Clock Mode in the Clock +			 * Control register.  			 */ -			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); -			if (!(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { -				for (div = 1; div <= 1024; div++) { -					if (((host->max_clk * host->clk_mul) / -					      div) <= clock) -						break; -				} -				/* -				 * Set Programmable Clock Mode in the Clock -				 * Control register. -				 */ -				clk = SDHCI_PROG_CLOCK_MODE; -				real_div = div; -				clk_mul = host->clk_mul; -				div--; -			} +			clk = SDHCI_PROG_CLOCK_MODE; +			real_div = div; +			clk_mul = host->clk_mul; +			div--;  		} else {  			/* Version 3.00 divisors must be a multiple of 2. */  			if (host->max_clk <= clock) @@ -1159,6 +1199,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)  		div >>= 1;  	} +clock_set:  	if (real_div)  		host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; @@ -1189,6 +1230,15 @@ out:  	host->clock = clock;  } +static inline void sdhci_update_clock(struct sdhci_host *host) +{ +	unsigned int clock; + +	clock = host->clock; +	host->clock = 0; +	sdhci_set_clock(host, clock); +} +  static int sdhci_set_power(struct sdhci_host *host, unsigned short power)  {  	u8 pwr = 0; @@ -1258,7 +1308,7 @@ static int sdhci_set_power(struct sdhci_host *host, unsigned short power)  static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)  {  	struct sdhci_host *host; -	bool present; +	int present;  	unsigned long flags;  	u32 tuning_opcode; @@ -1287,18 +1337,21 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)  	host->mrq = mrq; -	/* If polling, assume that the card is always present. */ -	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) -		present = true; -	else -		present = sdhci_readl(host, SDHCI_PRESENT_STATE) & -				SDHCI_CARD_PRESENT; - -	/* If we're using a cd-gpio, testing the presence bit might fail. */ -	if (!present) { -		int ret = mmc_gpio_get_cd(host->mmc); -		if (ret > 0) -			present = true; +	/* +	 * Firstly check card presence from cd-gpio.  The return could +	 * be one of the following possibilities: +	 *     negative: cd-gpio is not available +	 *     zero: cd-gpio is used, and card is removed +	 *     one: cd-gpio is used, and card is present +	 */ +	present = mmc_gpio_get_cd(host->mmc); +	if (present < 0) { +		/* If polling, assume that the card is always present. */ +		if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) +			present = 1; +		else +			present = sdhci_readl(host, SDHCI_PRESENT_STATE) & +					SDHCI_CARD_PRESENT;  	}  	if (!present || host->flags & SDHCI_DEVICE_DEAD) { @@ -1364,6 +1417,10 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)  		sdhci_reinit(host);  	} +	if (host->version >= SDHCI_SPEC_300 && +		(ios->power_mode == MMC_POWER_UP)) +		sdhci_enable_preset_value(host, false); +  	sdhci_set_clock(host, ios->clock);  	if (ios->power_mode == MMC_POWER_OFF) @@ -1383,11 +1440,11 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)  	/*  	 * If your platform has 8-bit width support but is not a v3 controller,  	 * or if it requires special setup code, you should implement that in -	 * platform_8bit_width(). +	 * platform_bus_width().  	 */ -	if (host->ops->platform_8bit_width) -		host->ops->platform_8bit_width(host, ios->bus_width); -	else { +	if (host->ops->platform_bus_width) { +		host->ops->platform_bus_width(host, ios->bus_width); +	} else {  		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);  		if (ios->bus_width == MMC_BUS_WIDTH_8) {  			ctrl &= ~SDHCI_CTRL_4BITBUS; @@ -1415,7 +1472,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)  	if (host->version >= SDHCI_SPEC_300) {  		u16 clk, ctrl_2; -		unsigned int clock;  		/* In case of UHS-I modes, set High Speed Enable */  		if ((ios->timing == MMC_TIMING_MMC_HS200) || @@ -1455,9 +1511,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)  			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);  			/* Re-enable SD Clock */ -			clock = host->clock; -			host->clock = 0; -			sdhci_set_clock(host, clock); +			sdhci_update_clock(host);  		} @@ -1487,10 +1541,22 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)  			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);  		} +		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && +				((ios->timing == MMC_TIMING_UHS_SDR12) || +				 (ios->timing == MMC_TIMING_UHS_SDR25) || +				 (ios->timing == MMC_TIMING_UHS_SDR50) || +				 (ios->timing == MMC_TIMING_UHS_SDR104) || +				 (ios->timing == MMC_TIMING_UHS_DDR50))) { +			u16 preset; + +			sdhci_enable_preset_value(host, true); +			preset = sdhci_get_preset_value(host); +			ios->drv_type = (preset & SDHCI_PRESET_DRV_MASK) +				>> SDHCI_PRESET_DRV_SHIFT; +		} +  		/* Re-enable SD Clock */ -		clock = host->clock; -		host->clock = 0; -		sdhci_set_clock(host, clock); +		sdhci_update_clock(host);  	} else  		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); @@ -1608,141 +1674,91 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)  	spin_unlock_irqrestore(&host->lock, flags);  } -static int sdhci_do_3_3v_signal_voltage_switch(struct sdhci_host *host, -						u16 ctrl) +static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host, +						struct mmc_ios *ios)  { +	u16 ctrl;  	int ret; -	/* Set 1.8V Signal Enable in the Host Control2 register to 0 */ -	ctrl &= ~SDHCI_CTRL_VDD_180; -	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); - -	if (host->vqmmc) { -		ret = regulator_set_voltage(host->vqmmc, 2700000, 3600000); -		if (ret) { -			pr_warning("%s: Switching to 3.3V signalling voltage " -				   " failed\n", mmc_hostname(host->mmc)); -			return -EIO; -		} -	} -	/* Wait for 5ms */ -	usleep_range(5000, 5500); +	/* +	 * Signal Voltage Switching is only applicable for Host Controllers +	 * v3.00 and above. +	 */ +	if (host->version < SDHCI_SPEC_300) +		return 0; -	/* 3.3V regulator output should be stable within 5 ms */  	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); -	if (!(ctrl & SDHCI_CTRL_VDD_180)) -		return 0; -	pr_warning("%s: 3.3V regulator output did not became stable\n", -		   mmc_hostname(host->mmc)); +	switch (ios->signal_voltage) { +	case MMC_SIGNAL_VOLTAGE_330: +		/* Set 1.8V Signal Enable in the Host Control2 register to 0 */ +		ctrl &= ~SDHCI_CTRL_VDD_180; +		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); -	return -EIO; -} +		if (host->vqmmc) { +			ret = regulator_set_voltage(host->vqmmc, 2700000, 3600000); +			if (ret) { +				pr_warning("%s: Switching to 3.3V signalling voltage " +						" failed\n", mmc_hostname(host->mmc)); +				return -EIO; +			} +		} +		/* Wait for 5ms */ +		usleep_range(5000, 5500); -static int sdhci_do_1_8v_signal_voltage_switch(struct sdhci_host *host, -						u16 ctrl) -{ -	u8 pwr; -	u16 clk; -	u32 present_state; -	int ret; +		/* 3.3V regulator output should be stable within 5 ms */ +		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); +		if (!(ctrl & SDHCI_CTRL_VDD_180)) +			return 0; -	/* Stop SDCLK */ -	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -	clk &= ~SDHCI_CLOCK_CARD_EN; -	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); +		pr_warning("%s: 3.3V regulator output did not became stable\n", +				mmc_hostname(host->mmc)); + +		return -EAGAIN; +	case MMC_SIGNAL_VOLTAGE_180: +		if (host->vqmmc) { +			ret = regulator_set_voltage(host->vqmmc, +					1700000, 1950000); +			if (ret) { +				pr_warning("%s: Switching to 1.8V signalling voltage " +						" failed\n", mmc_hostname(host->mmc)); +				return -EIO; +			} +		} -	/* Check whether DAT[3:0] is 0000 */ -	present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); -	if (!((present_state & SDHCI_DATA_LVL_MASK) >> -	       SDHCI_DATA_LVL_SHIFT)) {  		/*  		 * Enable 1.8V Signal Enable in the Host Control2  		 * register  		 */ -		if (host->vqmmc) -			ret = regulator_set_voltage(host->vqmmc, -				1700000, 1950000); -		else -			ret = 0; +		ctrl |= SDHCI_CTRL_VDD_180; +		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); -		if (!ret) { -			ctrl |= SDHCI_CTRL_VDD_180; -			sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); +		/* Wait for 5ms */ +		usleep_range(5000, 5500); -			/* Wait for 5ms */ -			usleep_range(5000, 5500); +		/* 1.8V regulator output should be stable within 5 ms */ +		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); +		if (ctrl & SDHCI_CTRL_VDD_180) +			return 0; -			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); -			if (ctrl & SDHCI_CTRL_VDD_180) { -				/* Provide SDCLK again and wait for 1ms */ -				clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -				clk |= SDHCI_CLOCK_CARD_EN; -				sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -				usleep_range(1000, 1500); +		pr_warning("%s: 1.8V regulator output did not became stable\n", +				mmc_hostname(host->mmc)); -				/* -				 * If DAT[3:0] level is 1111b, then the card -				 * was successfully switched to 1.8V signaling. -				 */ -				present_state = sdhci_readl(host, -							SDHCI_PRESENT_STATE); -				if ((present_state & SDHCI_DATA_LVL_MASK) == -				     SDHCI_DATA_LVL_MASK) -					return 0; +		return -EAGAIN; +	case MMC_SIGNAL_VOLTAGE_120: +		if (host->vqmmc) { +			ret = regulator_set_voltage(host->vqmmc, 1100000, 1300000); +			if (ret) { +				pr_warning("%s: Switching to 1.2V signalling voltage " +						" failed\n", mmc_hostname(host->mmc)); +				return -EIO;  			}  		} -	} - -	/* -	 * If we are here, that means the switch to 1.8V signaling -	 * failed. We power cycle the card, and retry initialization -	 * sequence by setting S18R to 0. -	 */ -	pwr = sdhci_readb(host, SDHCI_POWER_CONTROL); -	pwr &= ~SDHCI_POWER_ON; -	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); -	if (host->vmmc) -		regulator_disable(host->vmmc); - -	/* Wait for 1ms as per the spec */ -	usleep_range(1000, 1500); -	pwr |= SDHCI_POWER_ON; -	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); -	if (host->vmmc) -		regulator_enable(host->vmmc); - -	pr_warning("%s: Switching to 1.8V signalling voltage failed, " -		   "retrying with S18R set to 0\n", mmc_hostname(host->mmc)); - -	return -EAGAIN; -} - -static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host, -						struct mmc_ios *ios) -{ -	u16 ctrl; - -	/* -	 * Signal Voltage Switching is only applicable for Host Controllers -	 * v3.00 and above. -	 */ -	if (host->version < SDHCI_SPEC_300)  		return 0; - -	/* -	 * We first check whether the request is to set signalling voltage -	 * to 3.3V. If so, we change the voltage to 3.3V and return quickly. -	 */ -	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); -	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) -		return sdhci_do_3_3v_signal_voltage_switch(host, ctrl); -	else if (!(ctrl & SDHCI_CTRL_VDD_180) && -			(ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) -		return sdhci_do_1_8v_signal_voltage_switch(host, ctrl); -	else +	default:  		/* No signal voltage switch required */  		return 0; +	}  }  static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, @@ -1759,6 +1775,19 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,  	return err;  } +static int sdhci_card_busy(struct mmc_host *mmc) +{ +	struct sdhci_host *host = mmc_priv(mmc); +	u32 present_state; + +	sdhci_runtime_pm_get(host); +	/* Check whether DAT[3:0] is 0000 */ +	present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); +	sdhci_runtime_pm_put(host); + +	return !(present_state & SDHCI_DATA_LVL_MASK); +} +  static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)  {  	struct sdhci_host *host; @@ -1955,17 +1984,15 @@ out:  	return err;  } -static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable) + +static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)  {  	u16 ctrl; -	unsigned long flags;  	/* Host Controller v3.00 defines preset value registers */  	if (host->version < SDHCI_SPEC_300)  		return; -	spin_lock_irqsave(&host->lock, flags); -  	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);  	/* @@ -1981,17 +2008,6 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable)  		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);  		host->flags &= ~SDHCI_PV_ENABLED;  	} - -	spin_unlock_irqrestore(&host->lock, flags); -} - -static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable) -{ -	struct sdhci_host *host = mmc_priv(mmc); - -	sdhci_runtime_pm_get(host); -	sdhci_do_enable_preset_value(host, enable); -	sdhci_runtime_pm_put(host);  }  static void sdhci_card_event(struct mmc_host *mmc) @@ -2027,8 +2043,8 @@ static const struct mmc_host_ops sdhci_ops = {  	.enable_sdio_irq = sdhci_enable_sdio_irq,  	.start_signal_voltage_switch	= sdhci_start_signal_voltage_switch,  	.execute_tuning			= sdhci_execute_tuning, -	.enable_preset_value		= sdhci_enable_preset_value,  	.card_event			= sdhci_card_event, +	.card_busy	= sdhci_card_busy,  };  /*****************************************************************************\ @@ -2080,14 +2096,9 @@ static void sdhci_tasklet_finish(unsigned long param)  		   (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {  		/* Some controllers need this kick or reset won't work here */ -		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { -			unsigned int clock; - +		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)  			/* This is to force an update */ -			clock = host->clock; -			host->clock = 0; -			sdhci_set_clock(host, clock); -		} +			sdhci_update_clock(host);  		/* Spec says we should do both at the same time, but Ricoh  		   controllers do not like that. */ @@ -2455,6 +2466,32 @@ out:  \*****************************************************************************/  #ifdef CONFIG_PM +void sdhci_enable_irq_wakeups(struct sdhci_host *host) +{ +	u8 val; +	u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE +			| SDHCI_WAKE_ON_INT; + +	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); +	val |= mask ; +	/* Avoid fake wake up */ +	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) +		val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE); +	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); +} +EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); + +void sdhci_disable_irq_wakeups(struct sdhci_host *host) +{ +	u8 val; +	u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE +			| SDHCI_WAKE_ON_INT; + +	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); +	val &= ~mask; +	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); +} +EXPORT_SYMBOL_GPL(sdhci_disable_irq_wakeups);  int sdhci_suspend_host(struct sdhci_host *host)  { @@ -2484,8 +2521,13 @@ int sdhci_suspend_host(struct sdhci_host *host)  		return ret;  	} -	free_irq(host->irq, host); - +	if (!device_may_wakeup(mmc_dev(host->mmc))) { +		sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK); +		free_irq(host->irq, host); +	} else { +		sdhci_enable_irq_wakeups(host); +		enable_irq_wake(host->irq); +	}  	return ret;  } @@ -2500,10 +2542,15 @@ int sdhci_resume_host(struct sdhci_host *host)  			host->ops->enable_dma(host);  	} -	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, -			  mmc_hostname(host->mmc), host); -	if (ret) -		return ret; +	if (!device_may_wakeup(mmc_dev(host->mmc))) { +		ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, +				  mmc_hostname(host->mmc), host); +		if (ret) +			return ret; +	} else { +		sdhci_disable_irq_wakeups(host); +		disable_irq_wake(host->irq); +	}  	if ((host->mmc->pm_flags & MMC_PM_KEEP_POWER) &&  	    (host->quirks2 & SDHCI_QUIRK2_HOST_OFF_CARD_ON)) { @@ -2531,17 +2578,6 @@ int sdhci_resume_host(struct sdhci_host *host)  }  EXPORT_SYMBOL_GPL(sdhci_resume_host); - -void sdhci_enable_irq_wakeups(struct sdhci_host *host) -{ -	u8 val; -	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); -	val |= SDHCI_WAKE_ON_INT; -	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); -} - -EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); -  #endif /* CONFIG_PM */  #ifdef CONFIG_PM_RUNTIME @@ -2600,8 +2636,12 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)  	sdhci_do_set_ios(host, &host->mmc->ios);  	sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios); -	if (host_flags & SDHCI_PV_ENABLED) -		sdhci_do_enable_preset_value(host, true); +	if ((host_flags & SDHCI_PV_ENABLED) && +		!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) { +		spin_lock_irqsave(&host->lock, flags); +		sdhci_enable_preset_value(host, true); +		spin_unlock_irqrestore(&host->lock, flags); +	}  	/* Set the re-tuning expiration flag */  	if (host->flags & SDHCI_USING_RETUNING_TIMER) @@ -2936,7 +2976,11 @@ int sdhci_add_host(struct sdhci_host *host)  	}  #ifdef CONFIG_REGULATOR -	if (host->vmmc) { +	/* +	 * Voltage range check makes sense only if regulator reports +	 * any voltage value. +	 */ +	if (host->vmmc && regulator_get_voltage(host->vmmc) > 0) {  		ret = regulator_is_supported_voltage(host->vmmc, 2700000,  			3600000);  		if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_330))) @@ -3139,6 +3183,7 @@ int sdhci_add_host(struct sdhci_host *host)  #ifdef SDHCI_USE_LEDS_CLASS  reset:  	sdhci_reset(host, SDHCI_RESET_ALL); +	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);  	free_irq(host->irq, host);  #endif  untasklet: @@ -3181,6 +3226,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)  	if (!dead)  		sdhci_reset(host, SDHCI_RESET_ALL); +	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);  	free_irq(host->irq, host);  	del_timer_sync(&host->timer);  |