aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/omap_hsmmc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-13 23:41:15 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-13 23:41:15 -0500
commit4b8be38cf782f8ebebc089083fa0572ade79d7ca (patch)
tree2f88a0a5c1c0be9121c31b5a2775ae2f979cfa66 /drivers/mmc/host/omap_hsmmc.c
parent5df1b274cd2f0304339c7f5586fa16cce0fdfce2 (diff)
parent0db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022 (diff)
Merge tag 'mmc-merge-for-3.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
MMC highlights for 3.3: Core: * Support for the HS200 high-speed eMMC mode. * Support SDIO 3.0 Ultra High Speed cards. * Kill pending block requests immediately if card is removed. * Enable the eMMC feature for locking boot partitions read-only until next power on, exposed via sysfs. Drivers: * Runtime PM support for Intel Medfield SDIO. * Suspend/resume support for sdhci-spear. * sh-mmcif now processes requests asynchronously. * tag 'mmc-merge-for-3.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (58 commits) mmc: fix a deadlock between system suspend and MMC block IO mmc: sdhci: restore the enabled dma when do reset all mmc: dw_mmc: miscaculated the fifo-depth with wrong bit operation mmc: host: Adds support for eMMC 4.5 HS200 mode mmc: core: HS200 mode support for eMMC 4.5 mmc: dw_mmc: fixed wrong bit operation for SDMMC_GET_FCNT() mmc: core: Separate the timeout value for cache-ctrl mmc: sdhci-spear: Fix compilation error mmc: sdhci: Deal with failure case in sdhci_suspend_host mmc: dw_mmc: Clear the DDR mode for non-DDR mmc: sd: Fix SDR12 timing regression mmc: sdhci: Fix tuning timer incorrect setting when suspending host mmc: core: Add option to prevent eMMC sleep command mmc: omap_hsmmc: use threaded irq handler for card-detect. mmc: sdhci-pci: enable runtime PM for Medfield SDIO mmc: sdhci: Always pass clock request value zero to set_clock host op mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION mmc: sdhci-pci: get gpio numbers from platform data mmc: sdhci-pci: add platform data mmc: sdhci: prevent card detection activity for non-removable cards ...
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c43
1 files changed, 12 insertions, 31 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d1fb561e089d..fd0c661bbad3 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>
@@ -120,7 +119,6 @@
120 119
121#define MMC_AUTOSUSPEND_DELAY 100 120#define MMC_AUTOSUSPEND_DELAY 100
122#define MMC_TIMEOUT_MS 20 121#define MMC_TIMEOUT_MS 20
123#define OMAP_MMC_MASTER_CLOCK 96000000
124#define OMAP_MMC_MIN_CLOCK 400000 122#define OMAP_MMC_MIN_CLOCK 400000
125#define OMAP_MMC_MAX_CLOCK 52000000 123#define OMAP_MMC_MAX_CLOCK 52000000
126#define DRIVER_NAME "omap_hsmmc" 124#define DRIVER_NAME "omap_hsmmc"
@@ -163,7 +161,6 @@ struct omap_hsmmc_host {
163 */ 161 */
164 struct regulator *vcc; 162 struct regulator *vcc;
165 struct regulator *vcc_aux; 163 struct regulator *vcc_aux;
166 struct work_struct mmc_carddetect_work;
167 void __iomem *base; 164 void __iomem *base;
168 resource_size_t mapbase; 165 resource_size_t mapbase;
169 spinlock_t irq_lock; /* Prevent races with irq handler */ 166 spinlock_t irq_lock; /* Prevent races with irq handler */
@@ -598,12 +595,12 @@ static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host)
598} 595}
599 596
600/* Calculate divisor for the given clock frequency */ 597/* Calculate divisor for the given clock frequency */
601static u16 calc_divisor(struct mmc_ios *ios) 598static u16 calc_divisor(struct omap_hsmmc_host *host, struct mmc_ios *ios)
602{ 599{
603 u16 dsor = 0; 600 u16 dsor = 0;
604 601
605 if (ios->clock) { 602 if (ios->clock) {
606 dsor = DIV_ROUND_UP(OMAP_MMC_MASTER_CLOCK, ios->clock); 603 dsor = DIV_ROUND_UP(clk_get_rate(host->fclk), ios->clock);
607 if (dsor > 250) 604 if (dsor > 250)
608 dsor = 250; 605 dsor = 250;
609 } 606 }
@@ -623,7 +620,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
623 620
624 regval = OMAP_HSMMC_READ(host->base, SYSCTL); 621 regval = OMAP_HSMMC_READ(host->base, SYSCTL);
625 regval = regval & ~(CLKD_MASK | DTO_MASK); 622 regval = regval & ~(CLKD_MASK | DTO_MASK);
626 regval = regval | (calc_divisor(ios) << 6) | (DTO << 16); 623 regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16);
627 OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); 624 OMAP_HSMMC_WRITE(host->base, SYSCTL, regval);
628 OMAP_HSMMC_WRITE(host->base, SYSCTL, 625 OMAP_HSMMC_WRITE(host->base, SYSCTL,
629 OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); 626 OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
@@ -1280,17 +1277,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
1280} 1277}
1281 1278
1282/* 1279/*
1283 * Work Item to notify the core about card insertion/removal 1280 * irq handler to notify the core about card insertion/removal
1284 */ 1281 */
1285static void omap_hsmmc_detect(struct work_struct *work) 1282static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
1286{ 1283{
1287 struct omap_hsmmc_host *host = 1284 struct omap_hsmmc_host *host = dev_id;
1288 container_of(work, struct omap_hsmmc_host, mmc_carddetect_work);
1289 struct omap_mmc_slot_data *slot = &mmc_slot(host); 1285 struct omap_mmc_slot_data *slot = &mmc_slot(host);
1290 int carddetect; 1286 int carddetect;
1291 1287
1292 if (host->suspended) 1288 if (host->suspended)
1293 return; 1289 return IRQ_HANDLED;
1294 1290
1295 sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); 1291 sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
1296 1292
@@ -1305,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work)
1305 mmc_detect_change(host->mmc, (HZ * 200) / 1000); 1301 mmc_detect_change(host->mmc, (HZ * 200) / 1000);
1306 else 1302 else
1307 mmc_detect_change(host->mmc, (HZ * 50) / 1000); 1303 mmc_detect_change(host->mmc, (HZ * 50) / 1000);
1308}
1309
1310/*
1311 * ISR for handling card insertion and removal
1312 */
1313static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id)
1314{
1315 struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id;
1316
1317 if (host->suspended)
1318 return IRQ_HANDLED;
1319 schedule_work(&host->mmc_carddetect_work);
1320
1321 return IRQ_HANDLED; 1304 return IRQ_HANDLED;
1322} 1305}
1323 1306
@@ -1919,7 +1902,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
1919 host->next_data.cookie = 1; 1902 host->next_data.cookie = 1;
1920 1903
1921 platform_set_drvdata(pdev, host); 1904 platform_set_drvdata(pdev, host);
1922 INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
1923 1905
1924 mmc->ops = &omap_hsmmc_ops; 1906 mmc->ops = &omap_hsmmc_ops;
1925 1907
@@ -2049,10 +2031,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
2049 2031
2050 /* Request IRQ for card detect */ 2032 /* Request IRQ for card detect */
2051 if ((mmc_slot(host).card_detect_irq)) { 2033 if ((mmc_slot(host).card_detect_irq)) {
2052 ret = request_irq(mmc_slot(host).card_detect_irq, 2034 ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
2053 omap_hsmmc_cd_handler, 2035 NULL,
2054 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 2036 omap_hsmmc_detect,
2055 mmc_hostname(mmc), host); 2037 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
2038 mmc_hostname(mmc), host);
2056 if (ret) { 2039 if (ret) {
2057 dev_dbg(mmc_dev(host->mmc), 2040 dev_dbg(mmc_dev(host->mmc),
2058 "Unable to grab MMC CD IRQ\n"); 2041 "Unable to grab MMC CD IRQ\n");
@@ -2131,7 +2114,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
2131 free_irq(host->irq, host); 2114 free_irq(host->irq, host);
2132 if (mmc_slot(host).card_detect_irq) 2115 if (mmc_slot(host).card_detect_irq)
2133 free_irq(mmc_slot(host).card_detect_irq, host); 2116 free_irq(mmc_slot(host).card_detect_irq, host);
2134 flush_work_sync(&host->mmc_carddetect_work);
2135 2117
2136 pm_runtime_put_sync(host->dev); 2118 pm_runtime_put_sync(host->dev);
2137 pm_runtime_disable(host->dev); 2119 pm_runtime_disable(host->dev);
@@ -2178,7 +2160,6 @@ static int omap_hsmmc_suspend(struct device *dev)
2178 return ret; 2160 return ret;
2179 } 2161 }
2180 } 2162 }
2181 cancel_work_sync(&host->mmc_carddetect_work);
2182 ret = mmc_suspend_host(host->mmc); 2163 ret = mmc_suspend_host(host->mmc);
2183 2164
2184 if (ret) { 2165 if (ret) {