Commit dfeae337 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v5.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "A couple of MMC fixes intended for v5.0-rc7.

  MMC core:
   - Fix deadlock bug for block I/O requests

  MMC host:
   - sunxi: Disable broken HS-DDR mode for H5 by default
   - sunxi: Avoid unsupported speed modes declared via DT
   - meson-gx: Restore interrupt name"

* tag 'mmc-v5.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: meson-gx: fix interrupt name
  mmc: block: handle complete_work on separate workqueue
  mmc: sunxi: Filter out unsupported modes declared in the device tree
  mmc: sunxi: Disable HS-DDR mode for H5 eMMC controller by default
parents 545aabcb 83e418a8
...@@ -2112,7 +2112,7 @@ static void mmc_blk_mq_req_done(struct mmc_request *mrq) ...@@ -2112,7 +2112,7 @@ static void mmc_blk_mq_req_done(struct mmc_request *mrq)
if (waiting) if (waiting)
wake_up(&mq->wait); wake_up(&mq->wait);
else else
kblockd_schedule_work(&mq->complete_work); queue_work(mq->card->complete_wq, &mq->complete_work);
return; return;
} }
...@@ -2924,6 +2924,13 @@ static int mmc_blk_probe(struct mmc_card *card) ...@@ -2924,6 +2924,13 @@ static int mmc_blk_probe(struct mmc_card *card)
mmc_fixup_device(card, mmc_blk_fixups); mmc_fixup_device(card, mmc_blk_fixups);
card->complete_wq = alloc_workqueue("mmc_complete",
WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
if (unlikely(!card->complete_wq)) {
pr_err("Failed to create mmc completion workqueue");
return -ENOMEM;
}
md = mmc_blk_alloc(card); md = mmc_blk_alloc(card);
if (IS_ERR(md)) if (IS_ERR(md))
return PTR_ERR(md); return PTR_ERR(md);
...@@ -2987,6 +2994,7 @@ static void mmc_blk_remove(struct mmc_card *card) ...@@ -2987,6 +2994,7 @@ static void mmc_blk_remove(struct mmc_card *card)
pm_runtime_put_noidle(&card->dev); pm_runtime_put_noidle(&card->dev);
mmc_blk_remove_req(md); mmc_blk_remove_req(md);
dev_set_drvdata(&card->dev, NULL); dev_set_drvdata(&card->dev, NULL);
destroy_workqueue(card->complete_wq);
} }
static int _mmc_blk_suspend(struct mmc_card *card) static int _mmc_blk_suspend(struct mmc_card *card)
......
...@@ -1338,7 +1338,8 @@ static int meson_mmc_probe(struct platform_device *pdev) ...@@ -1338,7 +1338,8 @@ static int meson_mmc_probe(struct platform_device *pdev)
host->regs + SD_EMMC_IRQ_EN); host->regs + SD_EMMC_IRQ_EN);
ret = request_threaded_irq(host->irq, meson_mmc_irq, ret = request_threaded_irq(host->irq, meson_mmc_irq,
meson_mmc_irq_thread, IRQF_SHARED, NULL, host); meson_mmc_irq_thread, IRQF_SHARED,
dev_name(&pdev->dev), host);
if (ret) if (ret)
goto err_init_clk; goto err_init_clk;
......
...@@ -1399,13 +1399,37 @@ static int sunxi_mmc_probe(struct platform_device *pdev) ...@@ -1399,13 +1399,37 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
if (host->cfg->clk_delays || host->use_new_timings) /*
* Some H5 devices do not have signal traces precise enough to
* use HS DDR mode for their eMMC chips.
*
* We still enable HS DDR modes for all the other controller
* variants that support them.
*/
if ((host->cfg->clk_delays || host->use_new_timings) &&
!of_device_is_compatible(pdev->dev.of_node,
"allwinner,sun50i-h5-emmc"))
mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR;
ret = mmc_of_parse(mmc); ret = mmc_of_parse(mmc);
if (ret) if (ret)
goto error_free_dma; goto error_free_dma;
/*
* If we don't support delay chains in the SoC, we can't use any
* of the higher speed modes. Mask them out in case the device
* tree specifies the properties for them, which gets added to
* the caps by mmc_of_parse() above.
*/
if (!(host->cfg->clk_delays || host->use_new_timings)) {
mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR |
MMC_CAP_1_2V_DDR | MMC_CAP_UHS);
mmc->caps2 &= ~MMC_CAP2_HS200;
}
/* TODO: This driver doesn't support HS400 mode yet */
mmc->caps2 &= ~MMC_CAP2_HS400;
ret = sunxi_mmc_init_host(host); ret = sunxi_mmc_init_host(host);
if (ret) if (ret)
goto error_free_dma; goto error_free_dma;
......
...@@ -308,6 +308,7 @@ struct mmc_card { ...@@ -308,6 +308,7 @@ struct mmc_card {
unsigned int nr_parts; unsigned int nr_parts;
unsigned int bouncesz; /* Bounce buffer size */ unsigned int bouncesz; /* Bounce buffer size */
struct workqueue_struct *complete_wq; /* Private workqueue */
}; };
static inline bool mmc_large_sector(struct mmc_card *card) static inline bool mmc_large_sector(struct mmc_card *card)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment