Commit 7efab4f3 authored by NeilBrown's avatar NeilBrown Committed by Chris Ball

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: default avatarFelipe Balbi <balbi@ti.com>
Tested-by: default avatarGrazvydas Ignotas <notasas@gmail.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Acked-by: default avatarKishore Kadiyala <kishorek.kadiyala@gmail.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 93933508
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
...@@ -162,7 +161,6 @@ struct omap_hsmmc_host { ...@@ -162,7 +161,6 @@ struct omap_hsmmc_host {
*/ */
struct regulator *vcc; struct regulator *vcc;
struct regulator *vcc_aux; struct regulator *vcc_aux;
struct work_struct mmc_carddetect_work;
void __iomem *base; void __iomem *base;
resource_size_t mapbase; resource_size_t mapbase;
spinlock_t irq_lock; /* Prevent races with irq handler */ spinlock_t irq_lock; /* Prevent races with irq handler */
...@@ -1279,17 +1277,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) ...@@ -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 = struct omap_hsmmc_host *host = dev_id;
container_of(work, struct omap_hsmmc_host, mmc_carddetect_work);
struct omap_mmc_slot_data *slot = &mmc_slot(host); struct omap_mmc_slot_data *slot = &mmc_slot(host);
int carddetect; int carddetect;
if (host->suspended) if (host->suspended)
return; return IRQ_HANDLED;
sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
...@@ -1304,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work) ...@@ -1304,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work)
mmc_detect_change(host->mmc, (HZ * 200) / 1000); mmc_detect_change(host->mmc, (HZ * 200) / 1000);
else else
mmc_detect_change(host->mmc, (HZ * 50) / 1000); 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; return IRQ_HANDLED;
} }
...@@ -1918,7 +1902,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) ...@@ -1918,7 +1902,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
host->next_data.cookie = 1; host->next_data.cookie = 1;
platform_set_drvdata(pdev, host); platform_set_drvdata(pdev, host);
INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
mmc->ops = &omap_hsmmc_ops; mmc->ops = &omap_hsmmc_ops;
...@@ -2046,10 +2029,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) ...@@ -2046,10 +2029,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
/* Request IRQ for card detect */ /* Request IRQ for card detect */
if ((mmc_slot(host).card_detect_irq)) { if ((mmc_slot(host).card_detect_irq)) {
ret = request_irq(mmc_slot(host).card_detect_irq, ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
omap_hsmmc_cd_handler, NULL,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, omap_hsmmc_detect,
mmc_hostname(mmc), host); IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
mmc_hostname(mmc), host);
if (ret) { if (ret) {
dev_dbg(mmc_dev(host->mmc), dev_dbg(mmc_dev(host->mmc),
"Unable to grab MMC CD IRQ\n"); "Unable to grab MMC CD IRQ\n");
...@@ -2128,7 +2112,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev) ...@@ -2128,7 +2112,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
free_irq(host->irq, host); free_irq(host->irq, host);
if (mmc_slot(host).card_detect_irq) if (mmc_slot(host).card_detect_irq)
free_irq(mmc_slot(host).card_detect_irq, host); free_irq(mmc_slot(host).card_detect_irq, host);
flush_work_sync(&host->mmc_carddetect_work);
pm_runtime_put_sync(host->dev); pm_runtime_put_sync(host->dev);
pm_runtime_disable(host->dev); pm_runtime_disable(host->dev);
...@@ -2175,7 +2158,6 @@ static int omap_hsmmc_suspend(struct device *dev) ...@@ -2175,7 +2158,6 @@ static int omap_hsmmc_suspend(struct device *dev)
return ret; return ret;
} }
} }
cancel_work_sync(&host->mmc_carddetect_work);
ret = mmc_suspend_host(host->mmc); ret = mmc_suspend_host(host->mmc);
if (ret == 0) { if (ret == 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment