Commit 1ae7efb3 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - Fix a couple of quite severe issues for the CQE request path

  MMC host:
   - alcor: Fix a resource leak in the error path for ->probe()
   - sdhci-acpi: Fix the DMA support for the AMD eMMC v5.0 variant
   - sdhci-pci-gli: Fix system resume support for GL975x
   - sdhci-pci-gli: Fix reboot error for GL9750"

* tag 'mmc-v5.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci-acpi: Add SDHCI_QUIRK2_BROKEN_64_BIT_DMA for AMDI0040
  mmc: block: Fix request completion in the CQE timeout path
  mmc: core: Fix recursive locking issue in CQE recovery path
  mmc: core: Check request type before completing the request
  mmc: sdhci-pci-gli: Fix can not access GL9750 after reboot from Windows 10
  mmc: alcor: Fix a resource leak in the error path for ->probe()
  mmc: sdhci-pci-gli: Fix no irq handler from suspend
parents decd6167 45a3fe3b
...@@ -1370,6 +1370,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req) ...@@ -1370,6 +1370,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req)
struct mmc_request *mrq = &mqrq->brq.mrq; struct mmc_request *mrq = &mqrq->brq.mrq;
struct request_queue *q = req->q; struct request_queue *q = req->q;
struct mmc_host *host = mq->card->host; struct mmc_host *host = mq->card->host;
enum mmc_issue_type issue_type = mmc_issue_type(mq, req);
unsigned long flags; unsigned long flags;
bool put_card; bool put_card;
int err; int err;
...@@ -1399,7 +1400,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req) ...@@ -1399,7 +1400,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req)
spin_lock_irqsave(&mq->lock, flags); spin_lock_irqsave(&mq->lock, flags);
mq->in_flight[mmc_issue_type(mq, req)] -= 1; mq->in_flight[issue_type] -= 1;
put_card = (mmc_tot_in_flight(mq) == 0); put_card = (mmc_tot_in_flight(mq) == 0);
......
...@@ -107,11 +107,10 @@ static enum blk_eh_timer_return mmc_cqe_timed_out(struct request *req) ...@@ -107,11 +107,10 @@ static enum blk_eh_timer_return mmc_cqe_timed_out(struct request *req)
case MMC_ISSUE_DCMD: case MMC_ISSUE_DCMD:
if (host->cqe_ops->cqe_timeout(host, mrq, &recovery_needed)) { if (host->cqe_ops->cqe_timeout(host, mrq, &recovery_needed)) {
if (recovery_needed) if (recovery_needed)
__mmc_cqe_recovery_notifier(mq); mmc_cqe_recovery_notifier(mrq);
return BLK_EH_RESET_TIMER; return BLK_EH_RESET_TIMER;
} }
/* No timeout (XXX: huh? comment doesn't make much sense) */ /* The request has gone already */
blk_mq_complete_request(req);
return BLK_EH_DONE; return BLK_EH_DONE;
default: default:
/* Timeout is handled by mmc core */ /* Timeout is handled by mmc core */
...@@ -127,18 +126,13 @@ static enum blk_eh_timer_return mmc_mq_timed_out(struct request *req, ...@@ -127,18 +126,13 @@ static enum blk_eh_timer_return mmc_mq_timed_out(struct request *req,
struct mmc_card *card = mq->card; struct mmc_card *card = mq->card;
struct mmc_host *host = card->host; struct mmc_host *host = card->host;
unsigned long flags; unsigned long flags;
int ret; bool ignore_tout;
spin_lock_irqsave(&mq->lock, flags); spin_lock_irqsave(&mq->lock, flags);
ignore_tout = mq->recovery_needed || !mq->use_cqe || host->hsq_enabled;
if (mq->recovery_needed || !mq->use_cqe || host->hsq_enabled)
ret = BLK_EH_RESET_TIMER;
else
ret = mmc_cqe_timed_out(req);
spin_unlock_irqrestore(&mq->lock, flags); spin_unlock_irqrestore(&mq->lock, flags);
return ret; return ignore_tout ? BLK_EH_RESET_TIMER : mmc_cqe_timed_out(req);
} }
static void mmc_mq_recovery_handler(struct work_struct *work) static void mmc_mq_recovery_handler(struct work_struct *work)
......
...@@ -1104,7 +1104,7 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) ...@@ -1104,7 +1104,7 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev)
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to get irq for data line\n"); dev_err(&pdev->dev, "Failed to get irq for data line\n");
return ret; goto free_host;
} }
mutex_init(&host->cmd_mutex); mutex_init(&host->cmd_mutex);
...@@ -1116,6 +1116,10 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) ...@@ -1116,6 +1116,10 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, host); dev_set_drvdata(&pdev->dev, host);
mmc_add_host(mmc); mmc_add_host(mmc);
return 0; return 0;
free_host:
mmc_free_host(mmc);
return ret;
} }
static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev) static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev)
......
...@@ -605,10 +605,12 @@ static int sdhci_acpi_emmc_amd_probe_slot(struct platform_device *pdev, ...@@ -605,10 +605,12 @@ static int sdhci_acpi_emmc_amd_probe_slot(struct platform_device *pdev,
} }
static const struct sdhci_acpi_slot sdhci_acpi_slot_amd_emmc = { static const struct sdhci_acpi_slot sdhci_acpi_slot_amd_emmc = {
.chip = &sdhci_acpi_chip_amd, .chip = &sdhci_acpi_chip_amd,
.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
.quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
SDHCI_QUIRK_32BIT_ADMA_SIZE, SDHCI_QUIRK_32BIT_DMA_SIZE |
SDHCI_QUIRK_32BIT_ADMA_SIZE,
.quirks2 = SDHCI_QUIRK2_BROKEN_64_BIT_DMA,
.probe_slot = sdhci_acpi_emmc_amd_probe_slot, .probe_slot = sdhci_acpi_emmc_amd_probe_slot,
}; };
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
#define SDHCI_GLI_9750_DRIVING_2 GENMASK(27, 26) #define SDHCI_GLI_9750_DRIVING_2 GENMASK(27, 26)
#define GLI_9750_DRIVING_1_VALUE 0xFFF #define GLI_9750_DRIVING_1_VALUE 0xFFF
#define GLI_9750_DRIVING_2_VALUE 0x3 #define GLI_9750_DRIVING_2_VALUE 0x3
#define SDHCI_GLI_9750_SEL_1 BIT(29)
#define SDHCI_GLI_9750_SEL_2 BIT(31)
#define SDHCI_GLI_9750_ALL_RST (BIT(24)|BIT(25)|BIT(28)|BIT(30))
#define SDHCI_GLI_9750_PLL 0x864 #define SDHCI_GLI_9750_PLL 0x864
#define SDHCI_GLI_9750_PLL_TX2_INV BIT(23) #define SDHCI_GLI_9750_PLL_TX2_INV BIT(23)
...@@ -122,6 +125,8 @@ static void gli_set_9750(struct sdhci_host *host) ...@@ -122,6 +125,8 @@ static void gli_set_9750(struct sdhci_host *host)
GLI_9750_DRIVING_1_VALUE); GLI_9750_DRIVING_1_VALUE);
driving_value |= FIELD_PREP(SDHCI_GLI_9750_DRIVING_2, driving_value |= FIELD_PREP(SDHCI_GLI_9750_DRIVING_2,
GLI_9750_DRIVING_2_VALUE); GLI_9750_DRIVING_2_VALUE);
driving_value &= ~(SDHCI_GLI_9750_SEL_1|SDHCI_GLI_9750_SEL_2|SDHCI_GLI_9750_ALL_RST);
driving_value |= SDHCI_GLI_9750_SEL_2;
sdhci_writel(host, driving_value, SDHCI_GLI_9750_DRIVING); sdhci_writel(host, driving_value, SDHCI_GLI_9750_DRIVING);
sw_ctrl_value &= ~SDHCI_GLI_9750_SW_CTRL_4; sw_ctrl_value &= ~SDHCI_GLI_9750_SW_CTRL_4;
...@@ -334,6 +339,18 @@ static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg) ...@@ -334,6 +339,18 @@ static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg)
return value; return value;
} }
#ifdef CONFIG_PM_SLEEP
static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot = chip->slots[0];
pci_free_irq_vectors(slot->chip->pdev);
gli_pcie_enable_msi(slot);
return sdhci_pci_resume_host(chip);
}
#endif
static const struct sdhci_ops sdhci_gl9755_ops = { static const struct sdhci_ops sdhci_gl9755_ops = {
.set_clock = sdhci_set_clock, .set_clock = sdhci_set_clock,
.enable_dma = sdhci_pci_enable_dma, .enable_dma = sdhci_pci_enable_dma,
...@@ -348,6 +365,9 @@ const struct sdhci_pci_fixes sdhci_gl9755 = { ...@@ -348,6 +365,9 @@ const struct sdhci_pci_fixes sdhci_gl9755 = {
.quirks2 = SDHCI_QUIRK2_BROKEN_DDR50, .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50,
.probe_slot = gli_probe_slot_gl9755, .probe_slot = gli_probe_slot_gl9755,
.ops = &sdhci_gl9755_ops, .ops = &sdhci_gl9755_ops,
#ifdef CONFIG_PM_SLEEP
.resume = sdhci_pci_gli_resume,
#endif
}; };
static const struct sdhci_ops sdhci_gl9750_ops = { static const struct sdhci_ops sdhci_gl9750_ops = {
...@@ -366,4 +386,7 @@ const struct sdhci_pci_fixes sdhci_gl9750 = { ...@@ -366,4 +386,7 @@ const struct sdhci_pci_fixes sdhci_gl9750 = {
.quirks2 = SDHCI_QUIRK2_BROKEN_DDR50, .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50,
.probe_slot = gli_probe_slot_gl9750, .probe_slot = gli_probe_slot_gl9750,
.ops = &sdhci_gl9750_ops, .ops = &sdhci_gl9750_ops,
#ifdef CONFIG_PM_SLEEP
.resume = sdhci_pci_gli_resume,
#endif
}; };
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