Skip to content

Commit fc6f41b

Browse files
committed
Merge tag 'mmc-v4.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC host fix from Ulf Hansson: "mmci: Fix hang while waiting for busy-end interrupt" * tag 'mmc-v4.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: mmci: avoid clearing ST Micro busy end interrupt mistakenly
2 parents 1f369d1 + 5cad24d commit fc6f41b

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

drivers/mmc/host/mmci.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
10231023
if (!host->busy_status && busy_resp &&
10241024
!(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) &&
10251025
(readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) {
1026-
/* Unmask the busy IRQ */
1026+
1027+
/* Clear the busy start IRQ */
1028+
writel(host->variant->busy_detect_mask,
1029+
host->base + MMCICLEAR);
1030+
1031+
/* Unmask the busy end IRQ */
10271032
writel(readl(base + MMCIMASK0) |
10281033
host->variant->busy_detect_mask,
10291034
base + MMCIMASK0);
@@ -1038,10 +1043,14 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
10381043

10391044
/*
10401045
* At this point we are not busy with a command, we have
1041-
* not received a new busy request, mask the busy IRQ and
1042-
* fall through to process the IRQ.
1046+
* not received a new busy request, clear and mask the busy
1047+
* end IRQ and fall through to process the IRQ.
10431048
*/
10441049
if (host->busy_status) {
1050+
1051+
writel(host->variant->busy_detect_mask,
1052+
host->base + MMCICLEAR);
1053+
10451054
writel(readl(base + MMCIMASK0) &
10461055
~host->variant->busy_detect_mask,
10471056
base + MMCIMASK0);
@@ -1283,12 +1292,21 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
12831292
}
12841293

12851294
/*
1286-
* We intentionally clear the MCI_ST_CARDBUSY IRQ here (if it's
1287-
* enabled) since the HW seems to be triggering the IRQ on both
1288-
* edges while monitoring DAT0 for busy completion.
1295+
* We intentionally clear the MCI_ST_CARDBUSY IRQ (if it's
1296+
* enabled) in mmci_cmd_irq() function where ST Micro busy
1297+
* detection variant is handled. Considering the HW seems to be
1298+
* triggering the IRQ on both edges while monitoring DAT0 for
1299+
* busy completion and that same status bit is used to monitor
1300+
* start and end of busy detection, special care must be taken
1301+
* to make sure that both start and end interrupts are always
1302+
* cleared one after the other.
12891303
*/
12901304
status &= readl(host->base + MMCIMASK0);
1291-
writel(status, host->base + MMCICLEAR);
1305+
if (host->variant->busy_detect)
1306+
writel(status & ~host->variant->busy_detect_mask,
1307+
host->base + MMCICLEAR);
1308+
else
1309+
writel(status, host->base + MMCICLEAR);
12921310

12931311
dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
12941312

0 commit comments

Comments
 (0)