提交 8d86cf88 编写于 作者: L Linus Torvalds

Merge tag 'mmc-v4.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - further fix thread wake-up for requests
   - use a bounce buffer to fix DMA issue for SSR register read

  MMC host:
   - sdhci: Fix a regression for runtime PM
   - sdhci-cadence: Add a proper SoC specific DT compatible"

* tag 'mmc-v4.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sd: Meet alignment requirements for raw_ssr DMA
  mmc: core: Further fix thread wake-up
  mmc: sdhci: Fix to handle MMC_POWER_UNDEFINED
  mmc: sdhci-cadence: add Socionext UniPhier specific compatible string
* Cadence SD/SDIO/eMMC Host Controller
Required properties:
- compatible: should be "cdns,sd4hc".
- compatible: should be one of the following:
"cdns,sd4hc" - default of the IP
"socionext,uniphier-sd4hc" - for Socionext UniPhier SoCs
- reg: offset and length of the register set for the device.
- interrupts: a single interrupt specifier.
- clocks: phandle to the input clock.
......@@ -19,7 +21,7 @@ if supported. See mmc.txt for details.
Example:
emmc: sdhci@5a000000 {
compatible = "cdns,sd4hc";
compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc";
reg = <0x5a000000 0x400>;
interrupts = <0 78 4>;
clocks = <&clk 4>;
......
......@@ -496,8 +496,7 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
* Returns enum mmc_blk_status after checking errors.
*/
static enum mmc_blk_status mmc_wait_for_data_req_done(struct mmc_host *host,
struct mmc_request *mrq,
struct mmc_async_req *next_req)
struct mmc_request *mrq)
{
struct mmc_command *cmd;
struct mmc_context_info *context_info = &host->context_info;
......@@ -507,7 +506,7 @@ static enum mmc_blk_status mmc_wait_for_data_req_done(struct mmc_host *host,
wait_event_interruptible(context_info->wait,
(context_info->is_done_rcv ||
context_info->is_new_req));
context_info->is_waiting_last_req = false;
if (context_info->is_done_rcv) {
context_info->is_done_rcv = false;
cmd = mrq->cmd;
......@@ -527,10 +526,9 @@ static enum mmc_blk_status mmc_wait_for_data_req_done(struct mmc_host *host,
__mmc_start_request(host, mrq);
continue; /* wait for done/new event again */
}
} else if (context_info->is_new_req) {
if (!next_req)
return MMC_BLK_NEW_REQUEST;
}
return MMC_BLK_NEW_REQUEST;
}
mmc_retune_release(host);
return status;
......@@ -660,7 +658,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
mmc_pre_req(host, areq->mrq);
if (host->areq) {
status = mmc_wait_for_data_req_done(host, host->areq->mrq, areq);
status = mmc_wait_for_data_req_done(host, host->areq->mrq);
if (status == MMC_BLK_NEW_REQUEST) {
if (ret_stat)
*ret_stat = status;
......
......@@ -223,6 +223,7 @@ static int mmc_decode_scr(struct mmc_card *card)
static int mmc_read_ssr(struct mmc_card *card)
{
unsigned int au, es, et, eo;
u32 *raw_ssr;
int i;
if (!(card->csd.cmdclass & CCC_APP_SPEC)) {
......@@ -231,14 +232,21 @@ static int mmc_read_ssr(struct mmc_card *card)
return 0;
}
if (mmc_app_sd_status(card, card->raw_ssr)) {
raw_ssr = kmalloc(sizeof(card->raw_ssr), GFP_KERNEL);
if (!raw_ssr)
return -ENOMEM;
if (mmc_app_sd_status(card, raw_ssr)) {
pr_warn("%s: problem reading SD Status register\n",
mmc_hostname(card->host));
kfree(raw_ssr);
return 0;
}
for (i = 0; i < 16; i++)
card->raw_ssr[i] = be32_to_cpu(card->raw_ssr[i]);
card->raw_ssr[i] = be32_to_cpu(raw_ssr[i]);
kfree(raw_ssr);
/*
* UNSTUFF_BITS only works with four u32s so we have to offset the
......
......@@ -262,6 +262,7 @@ static int sdhci_cdns_probe(struct platform_device *pdev)
}
static const struct of_device_id sdhci_cdns_match[] = {
{ .compatible = "socionext,uniphier-sd4hc" },
{ .compatible = "cdns,sd4hc" },
{ /* sentinel */ }
};
......
......@@ -1576,6 +1576,9 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
unsigned long flags;
u8 ctrl;
if (ios->power_mode == MMC_POWER_UNDEFINED)
return;
spin_lock_irqsave(&host->lock, flags);
if (host->flags & SDHCI_DEVICE_DEAD) {
......@@ -2938,22 +2941,24 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
sdhci_init(host, 0);
/* Force clock and power re-program */
host->pwr = 0;
host->clock = 0;
mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios);
mmc->ops->set_ios(mmc, &mmc->ios);
if (mmc->ios.power_mode != MMC_POWER_UNDEFINED) {
/* Force clock and power re-program */
host->pwr = 0;
host->clock = 0;
mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios);
mmc->ops->set_ios(mmc, &mmc->ios);
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);
}
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);
}
if ((mmc->caps2 & MMC_CAP2_HS400_ES) &&
mmc->ops->hs400_enhanced_strobe)
mmc->ops->hs400_enhanced_strobe(mmc, &mmc->ios);
if ((mmc->caps2 & MMC_CAP2_HS400_ES) &&
mmc->ops->hs400_enhanced_strobe)
mmc->ops->hs400_enhanced_strobe(mmc, &mmc->ios);
}
spin_lock_irqsave(&host->lock, flags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册