| From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Date: Thu, 26 Feb 2015 12:13:36 +0100 |
| Subject: 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. |
| |
| |
| Reported-By: Michal Šmucr <msmucr@gmail.com> |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| drivers/mmc/host/sdhci.c | 32 +++++++++++++++++++++++++++----- |
| 1 file changed, 27 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/mmc/host/sdhci.c |
| +++ b/drivers/mmc/host/sdhci.c |
| @@ -2691,6 +2691,31 @@ static irqreturn_t sdhci_thread_irq(int |
| 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 * |
| @@ -2758,9 +2783,7 @@ int sdhci_resume_host(struct sdhci_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 { |
| @@ -3417,8 +3440,7 @@ int sdhci_add_host(struct sdhci_host *ho |
| |
| 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); |