aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-02-15 11:45:28 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-02-15 11:45:28 -0500
commitdfeae3379836fd0609488e73f4df260af4af2672 (patch)
tree882ea698abf901ab0353a704a3ea44e7ab7320a1
parent545aabcbdcec6c88faa3dfde506ad1931d119f52 (diff)
parent83e418a805d880a8b18add07f94d19b2a5a80307 (diff)
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
-rw-r--r--drivers/mmc/core/block.c10
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c3
-rw-r--r--drivers/mmc/host/sunxi-mmc.c26
-rw-r--r--include/linux/mmc/card.h1
4 files changed, 37 insertions, 3 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index aef1185f383d..14f3fdb8c6bb 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -2112,7 +2112,7 @@ static void mmc_blk_mq_req_done(struct mmc_request *mrq)
2112 if (waiting) 2112 if (waiting)
2113 wake_up(&mq->wait); 2113 wake_up(&mq->wait);
2114 else 2114 else
2115 kblockd_schedule_work(&mq->complete_work); 2115 queue_work(mq->card->complete_wq, &mq->complete_work);
2116 2116
2117 return; 2117 return;
2118 } 2118 }
@@ -2924,6 +2924,13 @@ static int mmc_blk_probe(struct mmc_card *card)
2924 2924
2925 mmc_fixup_device(card, mmc_blk_fixups); 2925 mmc_fixup_device(card, mmc_blk_fixups);
2926 2926
2927 card->complete_wq = alloc_workqueue("mmc_complete",
2928 WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
2929 if (unlikely(!card->complete_wq)) {
2930 pr_err("Failed to create mmc completion workqueue");
2931 return -ENOMEM;
2932 }
2933
2927 md = mmc_blk_alloc(card); 2934 md = mmc_blk_alloc(card);
2928 if (IS_ERR(md)) 2935 if (IS_ERR(md))
2929 return PTR_ERR(md); 2936 return PTR_ERR(md);
@@ -2987,6 +2994,7 @@ static void mmc_blk_remove(struct mmc_card *card)
2987 pm_runtime_put_noidle(&card->dev); 2994 pm_runtime_put_noidle(&card->dev);
2988 mmc_blk_remove_req(md); 2995 mmc_blk_remove_req(md);
2989 dev_set_drvdata(&card->dev, NULL); 2996 dev_set_drvdata(&card->dev, NULL);
2997 destroy_workqueue(card->complete_wq);
2990} 2998}
2991 2999
2992static int _mmc_blk_suspend(struct mmc_card *card) 3000static int _mmc_blk_suspend(struct mmc_card *card)
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index f19ec60bcbdc..2eba507790e4 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -1338,7 +1338,8 @@ static int meson_mmc_probe(struct platform_device *pdev)
1338 host->regs + SD_EMMC_IRQ_EN); 1338 host->regs + SD_EMMC_IRQ_EN);
1339 1339
1340 ret = request_threaded_irq(host->irq, meson_mmc_irq, 1340 ret = request_threaded_irq(host->irq, meson_mmc_irq,
1341 meson_mmc_irq_thread, IRQF_SHARED, NULL, host); 1341 meson_mmc_irq_thread, IRQF_SHARED,
1342 dev_name(&pdev->dev), host);
1342 if (ret) 1343 if (ret)
1343 goto err_init_clk; 1344 goto err_init_clk;
1344 1345
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 279e326e397e..70fadc976795 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -1399,13 +1399,37 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
1399 mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | 1399 mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
1400 MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; 1400 MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
1401 1401
1402 if (host->cfg->clk_delays || host->use_new_timings) 1402 /*
1403 * Some H5 devices do not have signal traces precise enough to
1404 * use HS DDR mode for their eMMC chips.
1405 *
1406 * We still enable HS DDR modes for all the other controller
1407 * variants that support them.
1408 */
1409 if ((host->cfg->clk_delays || host->use_new_timings) &&
1410 !of_device_is_compatible(pdev->dev.of_node,
1411 "allwinner,sun50i-h5-emmc"))
1403 mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; 1412 mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR;
1404 1413
1405 ret = mmc_of_parse(mmc); 1414 ret = mmc_of_parse(mmc);
1406 if (ret) 1415 if (ret)
1407 goto error_free_dma; 1416 goto error_free_dma;
1408 1417
1418 /*
1419 * If we don't support delay chains in the SoC, we can't use any
1420 * of the higher speed modes. Mask them out in case the device
1421 * tree specifies the properties for them, which gets added to
1422 * the caps by mmc_of_parse() above.
1423 */
1424 if (!(host->cfg->clk_delays || host->use_new_timings)) {
1425 mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR |
1426 MMC_CAP_1_2V_DDR | MMC_CAP_UHS);
1427 mmc->caps2 &= ~MMC_CAP2_HS200;
1428 }
1429
1430 /* TODO: This driver doesn't support HS400 mode yet */
1431 mmc->caps2 &= ~MMC_CAP2_HS400;
1432
1409 ret = sunxi_mmc_init_host(host); 1433 ret = sunxi_mmc_init_host(host);
1410 if (ret) 1434 if (ret)
1411 goto error_free_dma; 1435 goto error_free_dma;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index de7377815b6b..8ef330027b13 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -308,6 +308,7 @@ struct mmc_card {
308 unsigned int nr_parts; 308 unsigned int nr_parts;
309 309
310 unsigned int bouncesz; /* Bounce buffer size */ 310 unsigned int bouncesz; /* Bounce buffer size */
311 struct workqueue_struct *complete_wq; /* Private workqueue */
311}; 312};
312 313
313static inline bool mmc_large_sector(struct mmc_card *card) 314static inline bool mmc_large_sector(struct mmc_card *card)