MMC host:
- mmci: Fix hang while waiting for busy-end interrupt -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYndE6AAoJEP4mhCVzWIwp/aIQALUz+j+UGDajC33Od+hHXtM6 EduVtUHlnzwn3xu8vCOSfPrmWI+1NGs3ZBdlz/1bY1VKNm86RYoFIICNZyecm/Uz lkpJy8mY7McucE02xMk5DhwlUudopqMRK0iQTQWKn6RdijM4wrkiuqJD4O9ZSju8 iq4QjGgJupDafT38SSC7DHT1us1Cz87CknO8gRFgqMoSbRF8c8pn1r3zyIx/qViM CZihu7McUPC+0YulftxiMDqwsdqSQhnluBzWldvRR+WaebKk7YrQMLOdfLTjiUK2 /DlQLzN0aae5gwO4GkPz/IeiC7K1AGOYnrD7pgIzX0A0xRoUuyRaxnMsF36L7LW6 zwDS98co3Nuya9PqDsKHiLsqzEFCWZReME2xM6m2a3WRibCDmXTpzlUo+L4IVTSB 1W9OvFUR7V8zGImtZl8JUJDCbC5dBE7qO3CJGhC0ESRkcPVhFlHoYimoJPhn7mdg qoMg7ZcAHK/8Y2hBpcwmq2ey4ARFIRrCAOxbGQ2Fkcv8DfRFi3FwA3o1zGyXi5K3 xJe4JhYm2pol6zyvwoMY00876I0lCAVqA43AEoy0D2n5PbBOFs5kqiwm5xP7ScOB C/fGGNALMlMmFuqjITfyrVtnOdhCrJE+rXfmMWWQFiNyxVnkfjDH3PvygUH7Rb0p Db031/RS40qLz9j+gRdC =vxob -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
fc6f41ba8b
|
@ -1023,7 +1023,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
|
|||
if (!host->busy_status && busy_resp &&
|
||||
!(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) &&
|
||||
(readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) {
|
||||
/* Unmask the busy IRQ */
|
||||
|
||||
/* Clear the busy start IRQ */
|
||||
writel(host->variant->busy_detect_mask,
|
||||
host->base + MMCICLEAR);
|
||||
|
||||
/* Unmask the busy end IRQ */
|
||||
writel(readl(base + MMCIMASK0) |
|
||||
host->variant->busy_detect_mask,
|
||||
base + MMCIMASK0);
|
||||
|
@ -1038,10 +1043,14 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
|
|||
|
||||
/*
|
||||
* At this point we are not busy with a command, we have
|
||||
* not received a new busy request, mask the busy IRQ and
|
||||
* fall through to process the IRQ.
|
||||
* not received a new busy request, clear and mask the busy
|
||||
* end IRQ and fall through to process the IRQ.
|
||||
*/
|
||||
if (host->busy_status) {
|
||||
|
||||
writel(host->variant->busy_detect_mask,
|
||||
host->base + MMCICLEAR);
|
||||
|
||||
writel(readl(base + MMCIMASK0) &
|
||||
~host->variant->busy_detect_mask,
|
||||
base + MMCIMASK0);
|
||||
|
@ -1283,12 +1292,21 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
/*
|
||||
* We intentionally clear the MCI_ST_CARDBUSY IRQ here (if it's
|
||||
* enabled) since the HW seems to be triggering the IRQ on both
|
||||
* edges while monitoring DAT0 for busy completion.
|
||||
* We intentionally clear the MCI_ST_CARDBUSY IRQ (if it's
|
||||
* enabled) in mmci_cmd_irq() function where ST Micro busy
|
||||
* detection variant is handled. Considering the HW seems to be
|
||||
* triggering the IRQ on both edges while monitoring DAT0 for
|
||||
* busy completion and that same status bit is used to monitor
|
||||
* start and end of busy detection, special care must be taken
|
||||
* to make sure that both start and end interrupts are always
|
||||
* cleared one after the other.
|
||||
*/
|
||||
status &= readl(host->base + MMCIMASK0);
|
||||
writel(status, host->base + MMCICLEAR);
|
||||
if (host->variant->busy_detect)
|
||||
writel(status & ~host->variant->busy_detect_mask,
|
||||
host->base + MMCICLEAR);
|
||||
else
|
||||
writel(status, host->base + MMCICLEAR);
|
||||
|
||||
dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
|
||||
|
||||
|
|
Loading…
Reference in New Issue