diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 23:41:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 23:41:15 -0500 |
commit | 4b8be38cf782f8ebebc089083fa0572ade79d7ca (patch) | |
tree | 2f88a0a5c1c0be9121c31b5a2775ae2f979cfa66 /drivers/mmc/host/omap_hsmmc.c | |
parent | 5df1b274cd2f0304339c7f5586fa16cce0fdfce2 (diff) | |
parent | 0db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022 (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.c | 43 |
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 */ |
601 | static u16 calc_divisor(struct mmc_ios *ios) | 598 | static 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 | */ |
1285 | static void omap_hsmmc_detect(struct work_struct *work) | 1282 | static 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 | */ | ||
1313 | static 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) { |