diff options
author | NeilBrown <neilb@suse.de> | 2011-12-29 20:35:13 -0500 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-01-11 23:58:48 -0500 |
commit | 7efab4f35740c63502e438886cf1e4aa3f3b800f (patch) | |
tree | d95950c98e3f363167c340d6862e3328ec4f4cdc /drivers/mmc/host | |
parent | 93933508ce3753b9ef1fefb75531b5b1622de03f (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>
Diffstat (limited to 'drivers/mmc/host')
-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 5b35c7e5a26d..09fc4f8967ad 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 | */ |
1284 | static void omap_hsmmc_detect(struct work_struct *work) | 1282 | static 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 | */ | ||
1312 | static 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) { |