diff options
author | Adrian Hunter <adrian.hunter@nokia.com> | 2009-09-22 19:45:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 10:39:36 -0400 |
commit | 2bec08937e3cdf6828d29421c7f870dca84f3b02 (patch) | |
tree | 1c6dc84d86515e347fc70c3f4d664d341f2ffc59 /drivers/mmc | |
parent | b62f622812c5aaacad217fd8f4445562b917df6d (diff) |
omap_hsmmc: ensure all clock enables and disables are paired
[madhu.cr@ti.com: fix for the db clock failure message]
Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Acked-by: Matt Fleming <matt@console-pimps.org>
Cc: Ian Molton <ian@mnementh.co.uk>
Cc: "Roberto A. Foglietta" <roberto.foglietta@gmail.com>
Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com>
Cc: Denis Karpov <ext-denis.2.karpov@nokia.com>
Cc: Pierre Ossman <pierre@ossman.eu>
Cc: Philip Langdale <philipl@overt.org>
Cc: "Madhusudhan" <madhu.cr@ti.com>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: Madhusudhan Chikkature <madhu.cr@ti.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 60 |
1 files changed, 33 insertions, 27 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index a20fafecfc60..14c58caac990 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -162,7 +162,7 @@ struct omap_hsmmc_host { | |||
162 | int use_dma, dma_ch; | 162 | int use_dma, dma_ch; |
163 | int dma_line_tx, dma_line_rx; | 163 | int dma_line_tx, dma_line_rx; |
164 | int slot_id; | 164 | int slot_id; |
165 | int dbclk_enabled; | 165 | int got_dbclk; |
166 | int response_busy; | 166 | int response_busy; |
167 | int context_loss; | 167 | int context_loss; |
168 | int dpm_state; | 168 | int dpm_state; |
@@ -742,22 +742,24 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) | |||
742 | /* Disable the clocks */ | 742 | /* Disable the clocks */ |
743 | clk_disable(host->fclk); | 743 | clk_disable(host->fclk); |
744 | clk_disable(host->iclk); | 744 | clk_disable(host->iclk); |
745 | clk_disable(host->dbclk); | 745 | if (host->got_dbclk) |
746 | clk_disable(host->dbclk); | ||
746 | 747 | ||
747 | /* Turn the power off */ | 748 | /* Turn the power off */ |
748 | ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); | 749 | ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); |
749 | if (ret != 0) | ||
750 | goto err; | ||
751 | 750 | ||
752 | /* Turn the power ON with given VDD 1.8 or 3.0v */ | 751 | /* Turn the power ON with given VDD 1.8 or 3.0v */ |
753 | ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, vdd); | 752 | if (!ret) |
753 | ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, | ||
754 | vdd); | ||
755 | clk_enable(host->iclk); | ||
756 | clk_enable(host->fclk); | ||
757 | if (host->got_dbclk) | ||
758 | clk_enable(host->dbclk); | ||
759 | |||
754 | if (ret != 0) | 760 | if (ret != 0) |
755 | goto err; | 761 | goto err; |
756 | 762 | ||
757 | clk_enable(host->fclk); | ||
758 | clk_enable(host->iclk); | ||
759 | clk_enable(host->dbclk); | ||
760 | |||
761 | OMAP_HSMMC_WRITE(host->base, HCTL, | 763 | OMAP_HSMMC_WRITE(host->base, HCTL, |
762 | OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); | 764 | OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); |
763 | reg_val = OMAP_HSMMC_READ(host->base, HCTL); | 765 | reg_val = OMAP_HSMMC_READ(host->base, HCTL); |
@@ -1695,18 +1697,22 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1695 | goto err1; | 1697 | goto err1; |
1696 | } | 1698 | } |
1697 | 1699 | ||
1698 | host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); | 1700 | if (cpu_is_omap2430()) { |
1699 | /* | 1701 | host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); |
1700 | * MMC can still work without debounce clock. | 1702 | /* |
1701 | */ | 1703 | * MMC can still work without debounce clock. |
1702 | if (IS_ERR(host->dbclk)) | 1704 | */ |
1703 | dev_warn(mmc_dev(host->mmc), "Failed to get debounce clock\n"); | 1705 | if (IS_ERR(host->dbclk)) |
1704 | else | 1706 | dev_warn(mmc_dev(host->mmc), |
1705 | if (clk_enable(host->dbclk) != 0) | 1707 | "Failed to get debounce clock\n"); |
1706 | dev_dbg(mmc_dev(host->mmc), "Enabling debounce" | ||
1707 | " clk failed\n"); | ||
1708 | else | 1708 | else |
1709 | host->dbclk_enabled = 1; | 1709 | host->got_dbclk = 1; |
1710 | |||
1711 | if (host->got_dbclk) | ||
1712 | if (clk_enable(host->dbclk) != 0) | ||
1713 | dev_dbg(mmc_dev(host->mmc), "Enabling debounce" | ||
1714 | " clk failed\n"); | ||
1715 | } | ||
1710 | 1716 | ||
1711 | /* Since we do only SG emulation, we can have as many segs | 1717 | /* Since we do only SG emulation, we can have as many segs |
1712 | * as we want. */ | 1718 | * as we want. */ |
@@ -1820,7 +1826,7 @@ err_irq: | |||
1820 | clk_disable(host->iclk); | 1826 | clk_disable(host->iclk); |
1821 | clk_put(host->fclk); | 1827 | clk_put(host->fclk); |
1822 | clk_put(host->iclk); | 1828 | clk_put(host->iclk); |
1823 | if (host->dbclk_enabled) { | 1829 | if (host->got_dbclk) { |
1824 | clk_disable(host->dbclk); | 1830 | clk_disable(host->dbclk); |
1825 | clk_put(host->dbclk); | 1831 | clk_put(host->dbclk); |
1826 | } | 1832 | } |
@@ -1854,7 +1860,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
1854 | clk_disable(host->iclk); | 1860 | clk_disable(host->iclk); |
1855 | clk_put(host->fclk); | 1861 | clk_put(host->fclk); |
1856 | clk_put(host->iclk); | 1862 | clk_put(host->iclk); |
1857 | if (host->dbclk_enabled) { | 1863 | if (host->got_dbclk) { |
1858 | clk_disable(host->dbclk); | 1864 | clk_disable(host->dbclk); |
1859 | clk_put(host->dbclk); | 1865 | clk_put(host->dbclk); |
1860 | } | 1866 | } |
@@ -1905,7 +1911,8 @@ static int omap_hsmmc_suspend(struct platform_device *pdev, pm_message_t state) | |||
1905 | OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); | 1911 | OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); |
1906 | mmc_host_disable(host->mmc); | 1912 | mmc_host_disable(host->mmc); |
1907 | clk_disable(host->iclk); | 1913 | clk_disable(host->iclk); |
1908 | clk_disable(host->dbclk); | 1914 | if (host->got_dbclk) |
1915 | clk_disable(host->dbclk); | ||
1909 | } else { | 1916 | } else { |
1910 | host->suspended = 0; | 1917 | host->suspended = 0; |
1911 | if (host->pdata->resume) { | 1918 | if (host->pdata->resume) { |
@@ -1936,15 +1943,14 @@ static int omap_hsmmc_resume(struct platform_device *pdev) | |||
1936 | if (ret) | 1943 | if (ret) |
1937 | goto clk_en_err; | 1944 | goto clk_en_err; |
1938 | 1945 | ||
1939 | if (clk_enable(host->dbclk) != 0) | ||
1940 | dev_dbg(mmc_dev(host->mmc), | ||
1941 | "Enabling debounce clk failed\n"); | ||
1942 | |||
1943 | if (mmc_host_enable(host->mmc) != 0) { | 1946 | if (mmc_host_enable(host->mmc) != 0) { |
1944 | clk_disable(host->iclk); | 1947 | clk_disable(host->iclk); |
1945 | goto clk_en_err; | 1948 | goto clk_en_err; |
1946 | } | 1949 | } |
1947 | 1950 | ||
1951 | if (host->got_dbclk) | ||
1952 | clk_enable(host->dbclk); | ||
1953 | |||
1948 | omap_hsmmc_conf_bus_power(host); | 1954 | omap_hsmmc_conf_bus_power(host); |
1949 | 1955 | ||
1950 | if (host->pdata->resume) { | 1956 | if (host->pdata->resume) { |