aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-12-29 20:35:13 -0500
committerChris Ball <cjb@laptop.org>2012-01-11 23:58:48 -0500
commit7efab4f35740c63502e438886cf1e4aa3f3b800f (patch)
treed95950c98e3f363167c340d6862e3328ec4f4cdc
parent93933508ce3753b9ef1fefb75531b5b1622de03f (diff)
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>
-rw-r--r--drivers/mmc/host/omap_hsmmc.c36
1 files changed, 9 insertions, 27 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5b35c7e5a26..09fc4f8967a 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -24,7 +24,6 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/workqueue.h>
28#include <linux/timer.h> 27#include <linux/timer.h>
29#include <linux/clk.h> 28#include <linux/clk.h>
30#include <linux/mmc/host.h> 29#include <linux/mmc/host.h>
@@ -162,7 +161,6 @@ struct omap_hsmmc_host {
162 */ 161 */
163 struct regulator *vcc; 162 struct regulator *vcc;
164 struct regulator *vcc_aux; 163 struct regulator *vcc_aux;
165 struct work_struct mmc_carddetect_work;
166 void __iomem *base; 164 void __iomem *base;
167 resource_size_t mapbase; 165 resource_size_t mapbase;
168 spinlock_t irq_lock; /* Prevent races with irq handler */ 166 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} 1277}
1280 1278
1281/* 1279/*
1282 * Work Item to notify the core about card insertion/removal 1280 * irq handler to notify the core about card insertion/removal
1283 */ 1281 */
1284static void omap_hsmmc_detect(struct work_struct *work) 1282static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
1285{ 1283{
1286 struct omap_hsmmc_host *host = 1284 struct omap_hsmmc_host *host = dev_id;
1287 container_of(work, struct omap_hsmmc_host, mmc_carddetect_work);
1288 struct omap_mmc_slot_data *slot = &mmc_slot(host); 1285 struct omap_mmc_slot_data *slot = &mmc_slot(host);
1289 int carddetect; 1286 int carddetect;
1290 1287
1291 if (host->suspended) 1288 if (host->suspended)
1292 return; 1289 return IRQ_HANDLED;
1293 1290
1294 sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); 1291 sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
1295 1292
@@ -1304,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work)
1304 mmc_detect_change(host->mmc, (HZ * 200) / 1000); 1301 mmc_detect_change(host->mmc, (HZ * 200) / 1000);
1305 else 1302 else
1306 mmc_detect_change(host->mmc, (HZ * 50) / 1000); 1303 mmc_detect_change(host->mmc, (HZ * 50) / 1000);
1307}
1308
1309/*
1310 * ISR for handling card insertion and removal
1311 */
1312static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id)
1313{
1314 struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id;
1315
1316 if (host->suspended)
1317 return IRQ_HANDLED;
1318 schedule_work(&host->mmc_carddetect_work);
1319
1320 return IRQ_HANDLED; 1304 return IRQ_HANDLED;
1321} 1305}
1322 1306
@@ -1918,7 +1902,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
1918 host->next_data.cookie = 1; 1902 host->next_data.cookie = 1;
1919 1903
1920 platform_set_drvdata(pdev, host); 1904 platform_set_drvdata(pdev, host);
1921 INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
1922 1905
1923 mmc->ops = &omap_hsmmc_ops; 1906 mmc->ops = &omap_hsmmc_ops;
1924 1907
@@ -2046,10 +2029,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
2046 2029
2047 /* Request IRQ for card detect */ 2030 /* Request IRQ for card detect */
2048 if ((mmc_slot(host).card_detect_irq)) { 2031 if ((mmc_slot(host).card_detect_irq)) {
2049 ret = request_irq(mmc_slot(host).card_detect_irq, 2032 ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
2050 omap_hsmmc_cd_handler, 2033 NULL,
2051 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 2034 omap_hsmmc_detect,
2052 mmc_hostname(mmc), host); 2035 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
2036 mmc_hostname(mmc), host);
2053 if (ret) { 2037 if (ret) {
2054 dev_dbg(mmc_dev(host->mmc), 2038 dev_dbg(mmc_dev(host->mmc),
2055 "Unable to grab MMC CD IRQ\n"); 2039 "Unable to grab MMC CD IRQ\n");
@@ -2128,7 +2112,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
2128 free_irq(host->irq, host); 2112 free_irq(host->irq, host);
2129 if (mmc_slot(host).card_detect_irq) 2113 if (mmc_slot(host).card_detect_irq)
2130 free_irq(mmc_slot(host).card_detect_irq, host); 2114 free_irq(mmc_slot(host).card_detect_irq, host);
2131 flush_work_sync(&host->mmc_carddetect_work);
2132 2115
2133 pm_runtime_put_sync(host->dev); 2116 pm_runtime_put_sync(host->dev);
2134 pm_runtime_disable(host->dev); 2117 pm_runtime_disable(host->dev);
@@ -2175,7 +2158,6 @@ static int omap_hsmmc_suspend(struct device *dev)
2175 return ret; 2158 return ret;
2176 } 2159 }
2177 } 2160 }
2178 cancel_work_sync(&host->mmc_carddetect_work);
2179 ret = mmc_suspend_host(host->mmc); 2161 ret = mmc_suspend_host(host->mmc);
2180 2162
2181 if (ret == 0) { 2163 if (ret == 0) {