mmc: omap_hsmmc: use threaded irq handler for card-detect.

As the card-detect irq handler just schedules work to be done by a
thread, we can use request_threaded_irq to do much of the work for
us.  This means that interrupts which arrive by handle_nested_irq
actually work.

Reviewed-by: Felipe Balbi <balbi@ti.com>
Tested-by: Grazvydas Ignotas <notasas@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Acked-by: Kishore Kadiyala <kishorek.kadiyala@gmail.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
NeilBrown 2011-12-30 12:35:13 +11:00 committed by Chris Ball
parent 93933508ce
commit 7efab4f357

View File

@ -24,7 +24,6 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
#include <linux/clk.h>
#include <linux/mmc/host.h>
@ -162,7 +161,6 @@ struct omap_hsmmc_host {
*/
struct regulator *vcc;
struct regulator *vcc_aux;
struct work_struct mmc_carddetect_work;
void __iomem *base;
resource_size_t mapbase;
spinlock_t irq_lock; /* Prevent races with irq handler */
@ -1279,17 +1277,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
}
/*
* Work Item to notify the core about card insertion/removal
* irq handler to notify the core about card insertion/removal
*/
static void omap_hsmmc_detect(struct work_struct *work)
static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
{
struct omap_hsmmc_host *host =
container_of(work, struct omap_hsmmc_host, mmc_carddetect_work);
struct omap_hsmmc_host *host = dev_id;
struct omap_mmc_slot_data *slot = &mmc_slot(host);
int carddetect;
if (host->suspended)
return;
return IRQ_HANDLED;
sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
@ -1304,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work)
mmc_detect_change(host->mmc, (HZ * 200) / 1000);
else
mmc_detect_change(host->mmc, (HZ * 50) / 1000);
}
/*
* ISR for handling card insertion and removal
*/
static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id)
{
struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id;
if (host->suspended)
return IRQ_HANDLED;
schedule_work(&host->mmc_carddetect_work);
return IRQ_HANDLED;
}
@ -1918,7 +1902,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
host->next_data.cookie = 1;
platform_set_drvdata(pdev, host);
INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
mmc->ops = &omap_hsmmc_ops;
@ -2046,10 +2029,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
/* Request IRQ for card detect */
if ((mmc_slot(host).card_detect_irq)) {
ret = request_irq(mmc_slot(host).card_detect_irq,
omap_hsmmc_cd_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
mmc_hostname(mmc), host);
ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
NULL,
omap_hsmmc_detect,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
mmc_hostname(mmc), host);
if (ret) {
dev_dbg(mmc_dev(host->mmc),
"Unable to grab MMC CD IRQ\n");
@ -2128,7 +2112,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
free_irq(host->irq, host);
if (mmc_slot(host).card_detect_irq)
free_irq(mmc_slot(host).card_detect_irq, host);
flush_work_sync(&host->mmc_carddetect_work);
pm_runtime_put_sync(host->dev);
pm_runtime_disable(host->dev);
@ -2175,7 +2158,6 @@ static int omap_hsmmc_suspend(struct device *dev)
return ret;
}
}
cancel_work_sync(&host->mmc_carddetect_work);
ret = mmc_suspend_host(host->mmc);
if (ret == 0) {