Hi Johan, On 25 September 2012 09:03, Johan Rudholm <johan.rudholm@xxxxxxxxxxxxxx> wrote: > When switching SD and SDIO cards from 3.3V to 1.8V signal levels, the > clock should be gated for 5 ms during the step. Failure by the card to > switch is indicated by dat0 being pulled low. The host should check for > this condition and power-cycle the card if failure is indicated. > > Signed-off-by: Johan Rudholm <johan.rudholm@xxxxxxxxxxxxxx> > --- > Changelog v2: > - Keep calls to mmc_host_clk_hold / mmc_host_clk_release > --- > drivers/mmc/core/core.c | 22 ++++++++++++++++++++++ > include/linux/mmc/host.h | 3 +++ > 2 files changed, 25 insertions(+) > > diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c > index 6612163..dae6744 100644 > --- a/drivers/mmc/core/core.c > +++ b/drivers/mmc/core/core.c > @@ -1220,6 +1220,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 > { > struct mmc_command cmd = {0}; > int err = 0; > + unsigned char old_voltage = host->ios.signal_voltage; > > BUG_ON(!host); > > @@ -1243,8 +1244,29 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 > host->ios.signal_voltage = signal_voltage; > > if (host->ops->start_signal_voltage_switch) { > + u32 clock = host->ios.clock; > + > mmc_host_clk_hold(host); > + host->ios.clock = 0; > + mmc_set_ios(host); > err = host->ops->start_signal_voltage_switch(host, &host->ios); > + > + /* Hold clock for at least 5 ms according to spec */ This also potentially affects eMMC. Is that really what you want? According to commit msg you will only fixup something for SD and SDIO. By the way, it seems like some fixes for drivers/mmc/core/sdio.c should be included in this patch as well? Or do you intend to send those changes as a separate patch? > + mmc_delay(5); > + host->ios.clock = clock; > + mmc_set_ios(host); > + > + /* Wait for at least 1 ms until we check if card is ready */ > + mmc_delay(1); > + > + /* Check busy */ > + if (cmd11 && host->ops->card_busy && > + host->ops->card_busy(host)) { > + host->ios.signal_voltage = old_voltage; Why bother about restoring signal voltage state? Could that not be handled from upper layer? > + host->ops->start_signal_voltage_switch(host, > + &host->ios); > + err = -EAGAIN; > + } > mmc_host_clk_release(host); > } > > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h > index d5d9bd4..b58641a 100644 > --- a/include/linux/mmc/host.h > +++ b/include/linux/mmc/host.h > @@ -131,6 +131,9 @@ struct mmc_host_ops { > > int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); > > + /* Check if the card is pulling dat0 low */ > + int (*card_busy)(struct mmc_host *host); > + > /* The tuning command opcode value is different for SD and eMMC cards */ > int (*execute_tuning)(struct mmc_host *host, u32 opcode); > void (*enable_preset_value)(struct mmc_host *host, bool enable); > -- > 1.7.10 > Kind regards Ulf Hansson -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html