diff options
author | NeilBrown <neilb@suse.de> | 2011-12-30 12:35:13 +1100 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-01-11 23:58:48 -0500 |
commit | 7efab4f35740c63502e438886cf1e4aa3f3b800f (patch) | |
tree | d95950c98e3f363167c340d6862e3328ec4f4cdc /drivers/mmc | |
parent | 93933508ce3753b9ef1fefb75531b5b1622de03f (diff) | |
download | op-kernel-dev-7efab4f35740c63502e438886cf1e4aa3f3b800f.zip op-kernel-dev-7efab4f35740c63502e438886cf1e4aa3f3b800f.tar.gz |
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>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 36 |
1 files changed, 9 insertions, 27 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 5b35c7e..09fc4f8 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -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) { |