aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2015-02-26 12:13:36 +0100
committerAnders Roxell <anders.roxell@linaro.org>2015-06-24 21:13:10 +0200
commit6a95b625e97833e0c994fbb73dc8554232bf2b4e (patch)
treee83e19acfcf73fba1870f9a31fc8019bded53138
parent476b538d72ead64c70845619895bcc28aec219af (diff)
mmc: sdhci: don't provide hard irq handler
the sdhci code provides both irq handlers: the primary and the thread handler. Initially it was meant for the primary handler to be very short. The result is not that on -RT we have the primrary handler grabing locks and this isn't really working. As a hack for now I just push both handler into the threaded mode. Cc: stable-rt@vger.kernel.org Reported-By: Michal Å mucr <msmucr@gmail.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--drivers/mmc/host/sdhci.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 023c2010cd75..bcde53774bc9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2565,6 +2565,31 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
return isr ? IRQ_HANDLED : IRQ_NONE;
}
+#ifdef CONFIG_PREEMPT_RT_BASE
+static irqreturn_t sdhci_rt_irq(int irq, void *dev_id)
+{
+ irqreturn_t ret;
+
+ local_bh_disable();
+ ret = sdhci_irq(irq, dev_id);
+ local_bh_enable();
+ if (ret == IRQ_WAKE_THREAD)
+ ret = sdhci_thread_irq(irq, dev_id);
+ return ret;
+}
+#endif
+
+static int sdhci_req_irq(struct sdhci_host *host)
+{
+#ifdef CONFIG_PREEMPT_RT_BASE
+ return request_threaded_irq(host->irq, NULL, sdhci_rt_irq,
+ IRQF_SHARED, mmc_hostname(host->mmc), host);
+#else
+ return request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
+ IRQF_SHARED, mmc_hostname(host->mmc), host);
+#endif
+}
+
/*****************************************************************************\
* *
* Suspend/resume *
@@ -2632,9 +2657,7 @@ int sdhci_resume_host(struct sdhci_host *host)
}
if (!device_may_wakeup(mmc_dev(host->mmc))) {
- ret = request_threaded_irq(host->irq, sdhci_irq,
- sdhci_thread_irq, IRQF_SHARED,
- mmc_hostname(host->mmc), host);
+ ret = sdhci_req_irq(host);
if (ret)
return ret;
} else {
@@ -3253,8 +3276,7 @@ int sdhci_add_host(struct sdhci_host *host)
sdhci_init(host, 0);
- ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
- IRQF_SHARED, mmc_hostname(mmc), host);
+ ret = sdhci_req_irq(host);
if (ret) {
pr_err("%s: Failed to request IRQ %d: %d\n",
mmc_hostname(mmc), host->irq, ret);