diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2014-06-13 07:21:38 -0400 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-08-11 04:24:23 -0400 |
commit | 7878289b269d41c8e611aa6d4519feae706e49f3 (patch) | |
tree | fa9ea335a8123968a123551d7cb92fc1d5bf651a /drivers/mmc | |
parent | ad82bfea44835da9633548e2031a1af4a9965c14 (diff) |
mmc: mmci: Reverse IRQ handling for the arm_variant
Commit "mmc: mmci: Handle CMD irq before DATA irq", caused an issue
when using the ARM model of the PL181 and running QEMU.
The bug was reported for the following QEMU version:
$ qemu-system-arm -version
QEMU emulator version 2.0.0 (Debian 2.0.0+dfsg-2ubuntu1.1), Copyright
(c) 2003-2008 Fabrice Bellard
To resolve the problem, let's restore the old behavior were the DATA
irq is handled prior the CMD irq, but only for the arm_variant, which
the problem was reported for.
Reported-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Russell King <linux@arm.linux.org.uk>
Tested-by: Kees Cook <keescook@chromium.org>
Tested-by: John Stultz <john.stultz@linaro.org>
Cc: <stable@vger.kernel.org> # v3.15+
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/mmci.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 5d20bfba3e49..e4d470704150 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -74,6 +74,7 @@ static unsigned int fmax = 515633; | |||
74 | * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply | 74 | * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply |
75 | * @explicit_mclk_control: enable explicit mclk control in driver. | 75 | * @explicit_mclk_control: enable explicit mclk control in driver. |
76 | * @qcom_fifo: enables qcom specific fifo pio read logic. | 76 | * @qcom_fifo: enables qcom specific fifo pio read logic. |
77 | * @reversed_irq_handling: handle data irq before cmd irq. | ||
77 | */ | 78 | */ |
78 | struct variant_data { | 79 | struct variant_data { |
79 | unsigned int clkreg; | 80 | unsigned int clkreg; |
@@ -97,6 +98,7 @@ struct variant_data { | |||
97 | bool pwrreg_nopower; | 98 | bool pwrreg_nopower; |
98 | bool explicit_mclk_control; | 99 | bool explicit_mclk_control; |
99 | bool qcom_fifo; | 100 | bool qcom_fifo; |
101 | bool reversed_irq_handling; | ||
100 | }; | 102 | }; |
101 | 103 | ||
102 | static struct variant_data variant_arm = { | 104 | static struct variant_data variant_arm = { |
@@ -105,6 +107,7 @@ static struct variant_data variant_arm = { | |||
105 | .datalength_bits = 16, | 107 | .datalength_bits = 16, |
106 | .pwrreg_powerup = MCI_PWR_UP, | 108 | .pwrreg_powerup = MCI_PWR_UP, |
107 | .f_max = 100000000, | 109 | .f_max = 100000000, |
110 | .reversed_irq_handling = true, | ||
108 | }; | 111 | }; |
109 | 112 | ||
110 | static struct variant_data variant_arm_extended_fifo = { | 113 | static struct variant_data variant_arm_extended_fifo = { |
@@ -1236,8 +1239,13 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) | |||
1236 | 1239 | ||
1237 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); | 1240 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); |
1238 | 1241 | ||
1239 | mmci_cmd_irq(host, host->cmd, status); | 1242 | if (host->variant->reversed_irq_handling) { |
1240 | mmci_data_irq(host, host->data, status); | 1243 | mmci_data_irq(host, host->data, status); |
1244 | mmci_cmd_irq(host, host->cmd, status); | ||
1245 | } else { | ||
1246 | mmci_cmd_irq(host, host->cmd, status); | ||
1247 | mmci_data_irq(host, host->data, status); | ||
1248 | } | ||
1241 | 1249 | ||
1242 | /* Don't poll for busy completion in irq context. */ | 1250 | /* Don't poll for busy completion in irq context. */ |
1243 | if (host->busy_status) | 1251 | if (host->busy_status) |