summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 56e9a4168264..50b5f9926f64 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -29,6 +29,7 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/amba/mmci.h>
+#include <linux/pm_runtime.h>
#include <asm/div64.h>
#include <asm/io.h>
@@ -170,6 +171,7 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
* back into the driver...
*/
spin_unlock(&host->lock);
+ pm_runtime_put(mmc_dev(host->mmc));
mmc_request_done(host->mmc, mrq);
spin_lock(&host->lock);
}
@@ -464,7 +466,7 @@ static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
struct mmci_host_next *next = &host->next_data;
if (data->host_cookie && data->host_cookie != next->cookie) {
- printk(KERN_WARNING "[%s] invalid cookie: data->host_cookie %d"
+ pr_warning("[%s] invalid cookie: data->host_cookie %d"
" host->next_data.cookie %d\n",
__func__, data->host_cookie, host->next_data.cookie);
data->host_cookie = 0;
@@ -529,7 +531,7 @@ static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq,
if (chan) {
if (err)
dmaengine_terminate_all(chan);
- if (err || data->host_cookie)
+ if (data->host_cookie)
dma_unmap_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, dir);
mrq->data->host_cookie = 0;
@@ -984,6 +986,8 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
return;
}
+ pm_runtime_get_sync(mmc_dev(mmc));
+
spin_lock_irqsave(&host->lock, flags);
host->mrq = mrq;
@@ -1156,10 +1160,14 @@ static int __devinit mmci_probe(struct amba_device *dev,
goto host_free;
}
- ret = clk_enable(host->clk);
+ ret = clk_prepare(host->clk);
if (ret)
goto clk_free;
+ ret = clk_enable(host->clk);
+ if (ret)
+ goto clk_unprep;
+
host->plat = plat;
host->variant = variant;
host->mclk = clk_get_rate(host->clk);
@@ -1327,6 +1335,8 @@ static int __devinit mmci_probe(struct amba_device *dev,
mmci_dma_setup(host);
+ pm_runtime_put(&dev->dev);
+
mmc_add_host(mmc);
return 0;
@@ -1345,6 +1355,8 @@ static int __devinit mmci_probe(struct amba_device *dev,
iounmap(host->base);
clk_disable:
clk_disable(host->clk);
+ clk_unprep:
+ clk_unprepare(host->clk);
clk_free:
clk_put(host->clk);
host_free:
@@ -1364,6 +1376,12 @@ static int __devexit mmci_remove(struct amba_device *dev)
if (mmc) {
struct mmci_host *host = mmc_priv(mmc);
+ /*
+ * Undo pm_runtime_put() in probe. We use the _sync
+ * version here so that we can access the primecell.
+ */
+ pm_runtime_get_sync(&dev->dev);
+
mmc_remove_host(mmc);
writel(0, host->base + MMCIMASK0);
@@ -1386,6 +1404,7 @@ static int __devexit mmci_remove(struct amba_device *dev)
iounmap(host->base);
clk_disable(host->clk);
+ clk_unprepare(host->clk);
clk_put(host->clk);
if (host->vcc)