aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-05-22 02:36:56 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-05-22 02:36:56 -0400
commitcf9b59e9d3e008591d1f54830f570982bb307a0d (patch)
tree113478ce8fd8c832ba726ffdf59b82cb46356476 /drivers/mmc
parent44504b2bebf8b5823c59484e73096a7d6574471d (diff)
parentf4b87dee923342505e1ddba8d34ce9de33e75050 (diff)
Merge remote branch 'origin' into secretlab/next-devicetree
Merging in current state of Linus' tree to deal with merge conflicts and build failures in vio.c after merge. Conflicts: drivers/i2c/busses/i2c-cpm.c drivers/i2c/busses/i2c-mpc.c drivers/net/gianfar.c Also fixed up one line in arch/powerpc/kernel/vio.c to use the correct node pointer. Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/at91_mci.c2
-rw-r--r--drivers/mmc/host/atmel-mci.c20
-rw-r--r--drivers/mmc/host/mmci.c19
-rw-r--r--drivers/mmc/host/mmci.h6
-rw-r--r--drivers/mmc/host/msm_sdcc.c472
-rw-r--r--drivers/mmc/host/msm_sdcc.h15
-rw-r--r--drivers/mmc/host/pxamci.c2
7 files changed, 334 insertions, 202 deletions
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index a6dd7da37357..336d9f553f3e 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -314,8 +314,8 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
314 dmabuf = (unsigned *)tmpv; 314 dmabuf = (unsigned *)tmpv;
315 } 315 }
316 316
317 flush_kernel_dcache_page(sg_page(sg));
317 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); 318 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
318 dmac_flush_range((void *)sgbuffer, ((void *)sgbuffer) + amount);
319 data->bytes_xfered += amount; 319 data->bytes_xfered += amount;
320 if (size == 0) 320 if (size == 0)
321 break; 321 break;
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 88be37d9e9a5..df0e8a88d85f 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -266,7 +266,7 @@ static int atmci_req_show(struct seq_file *s, void *v)
266 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", 266 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
267 cmd->opcode, cmd->arg, cmd->flags, 267 cmd->opcode, cmd->arg, cmd->flags,
268 cmd->resp[0], cmd->resp[1], cmd->resp[2], 268 cmd->resp[0], cmd->resp[1], cmd->resp[2],
269 cmd->resp[2], cmd->error); 269 cmd->resp[3], cmd->error);
270 if (data) 270 if (data)
271 seq_printf(s, "DATA %u / %u * %u flg %x err %d\n", 271 seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
272 data->bytes_xfered, data->blocks, 272 data->bytes_xfered, data->blocks,
@@ -276,7 +276,7 @@ static int atmci_req_show(struct seq_file *s, void *v)
276 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", 276 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
277 stop->opcode, stop->arg, stop->flags, 277 stop->opcode, stop->arg, stop->flags,
278 stop->resp[0], stop->resp[1], stop->resp[2], 278 stop->resp[0], stop->resp[1], stop->resp[2],
279 stop->resp[2], stop->error); 279 stop->resp[3], stop->error);
280 } 280 }
281 281
282 spin_unlock_bh(&slot->host->lock); 282 spin_unlock_bh(&slot->host->lock);
@@ -569,9 +569,10 @@ static void atmci_dma_cleanup(struct atmel_mci *host)
569{ 569{
570 struct mmc_data *data = host->data; 570 struct mmc_data *data = host->data;
571 571
572 dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, 572 if (data)
573 ((data->flags & MMC_DATA_WRITE) 573 dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
574 ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); 574 ((data->flags & MMC_DATA_WRITE)
575 ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
575} 576}
576 577
577static void atmci_stop_dma(struct atmel_mci *host) 578static void atmci_stop_dma(struct atmel_mci *host)
@@ -579,7 +580,7 @@ static void atmci_stop_dma(struct atmel_mci *host)
579 struct dma_chan *chan = host->data_chan; 580 struct dma_chan *chan = host->data_chan;
580 581
581 if (chan) { 582 if (chan) {
582 chan->device->device_terminate_all(chan); 583 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
583 atmci_dma_cleanup(host); 584 atmci_dma_cleanup(host);
584 } else { 585 } else {
585 /* Data transfer was stopped by the interrupt handler */ 586 /* Data transfer was stopped by the interrupt handler */
@@ -1099,8 +1100,8 @@ static void atmci_command_complete(struct atmel_mci *host,
1099 "command error: status=0x%08x\n", status); 1100 "command error: status=0x%08x\n", status);
1100 1101
1101 if (cmd->data) { 1102 if (cmd->data) {
1102 host->data = NULL;
1103 atmci_stop_dma(host); 1103 atmci_stop_dma(host);
1104 host->data = NULL;
1104 mci_writel(host, IDR, MCI_NOTBUSY 1105 mci_writel(host, IDR, MCI_NOTBUSY
1105 | MCI_TXRDY | MCI_RXRDY 1106 | MCI_TXRDY | MCI_RXRDY
1106 | ATMCI_DATA_ERROR_FLAGS); 1107 | ATMCI_DATA_ERROR_FLAGS);
@@ -1293,6 +1294,7 @@ static void atmci_tasklet_func(unsigned long priv)
1293 } else { 1294 } else {
1294 data->bytes_xfered = data->blocks * data->blksz; 1295 data->bytes_xfered = data->blocks * data->blksz;
1295 data->error = 0; 1296 data->error = 0;
1297 mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS);
1296 } 1298 }
1297 1299
1298 if (!data->stop) { 1300 if (!data->stop) {
@@ -1751,13 +1753,13 @@ static int __init atmci_probe(struct platform_device *pdev)
1751 ret = -ENODEV; 1753 ret = -ENODEV;
1752 if (pdata->slot[0].bus_width) { 1754 if (pdata->slot[0].bus_width) {
1753 ret = atmci_init_slot(host, &pdata->slot[0], 1755 ret = atmci_init_slot(host, &pdata->slot[0],
1754 MCI_SDCSEL_SLOT_A, 0); 1756 0, MCI_SDCSEL_SLOT_A);
1755 if (!ret) 1757 if (!ret)
1756 nr_slots++; 1758 nr_slots++;
1757 } 1759 }
1758 if (pdata->slot[1].bus_width) { 1760 if (pdata->slot[1].bus_width) {
1759 ret = atmci_init_slot(host, &pdata->slot[1], 1761 ret = atmci_init_slot(host, &pdata->slot[1],
1760 MCI_SDCSEL_SLOT_B, 1); 1762 1, MCI_SDCSEL_SLOT_B);
1761 if (!ret) 1763 if (!ret)
1762 nr_slots++; 1764 nr_slots++;
1763 } 1765 }
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 84c103a7ee13..ff115d920888 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -55,14 +55,16 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
55 host->cclk = host->mclk / (2 * (clk + 1)); 55 host->cclk = host->mclk / (2 * (clk + 1));
56 } 56 }
57 if (host->hw_designer == AMBA_VENDOR_ST) 57 if (host->hw_designer == AMBA_VENDOR_ST)
58 clk |= MCI_FCEN; /* Bug fix in ST IP block */ 58 clk |= MCI_ST_FCEN; /* Bug fix in ST IP block */
59 clk |= MCI_CLK_ENABLE; 59 clk |= MCI_CLK_ENABLE;
60 /* This hasn't proven to be worthwhile */ 60 /* This hasn't proven to be worthwhile */
61 /* clk |= MCI_CLK_PWRSAVE; */ 61 /* clk |= MCI_CLK_PWRSAVE; */
62 } 62 }
63 63
64 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) 64 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
65 clk |= MCI_WIDE_BUS; 65 clk |= MCI_4BIT_BUS;
66 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
67 clk |= MCI_ST_8BIT_BUS;
66 68
67 writel(clk, host->base + MMCICLOCK); 69 writel(clk, host->base + MMCICLOCK);
68} 70}
@@ -629,7 +631,18 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
629 631
630 mmc->ops = &mmci_ops; 632 mmc->ops = &mmci_ops;
631 mmc->f_min = (host->mclk + 511) / 512; 633 mmc->f_min = (host->mclk + 511) / 512;
632 mmc->f_max = min(host->mclk, fmax); 634 /*
635 * If the platform data supplies a maximum operating
636 * frequency, this takes precedence. Else, we fall back
637 * to using the module parameter, which has a (low)
638 * default value in case it is not specified. Either
639 * value must not exceed the clock rate into the block,
640 * of course.
641 */
642 if (plat->f_max)
643 mmc->f_max = min(host->mclk, plat->f_max);
644 else
645 mmc->f_max = min(host->mclk, fmax);
633 dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); 646 dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
634 647
635#ifdef CONFIG_REGULATOR 648#ifdef CONFIG_REGULATOR
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 1ceb9a90f59b..d77062e5e3af 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -25,9 +25,11 @@
25#define MCI_CLK_ENABLE (1 << 8) 25#define MCI_CLK_ENABLE (1 << 8)
26#define MCI_CLK_PWRSAVE (1 << 9) 26#define MCI_CLK_PWRSAVE (1 << 9)
27#define MCI_CLK_BYPASS (1 << 10) 27#define MCI_CLK_BYPASS (1 << 10)
28#define MCI_WIDE_BUS (1 << 11) 28#define MCI_4BIT_BUS (1 << 11)
29/* 8bit wide buses supported in ST Micro versions */
30#define MCI_ST_8BIT_BUS (1 << 12)
29/* HW flow control on the ST Micro version */ 31/* HW flow control on the ST Micro version */
30#define MCI_FCEN (1 << 13) 32#define MCI_ST_FCEN (1 << 13)
31 33
32#define MMCIARGUMENT 0x008 34#define MMCIARGUMENT 0x008
33#define MMCICOMMAND 0x00c 35#define MMCICOMMAND 0x00c
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 04ae884383f6..61f1d27fed3f 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2007 Google Inc, 4 * Copyright (C) 2007 Google Inc,
5 * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. 5 * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
6 * Copyright (C) 2009, Code Aurora Forum. All Rights Reserved.
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -26,6 +27,7 @@
26#include <linux/log2.h> 27#include <linux/log2.h>
27#include <linux/mmc/host.h> 28#include <linux/mmc/host.h>
28#include <linux/mmc/card.h> 29#include <linux/mmc/card.h>
30#include <linux/mmc/sdio.h>
29#include <linux/clk.h> 31#include <linux/clk.h>
30#include <linux/scatterlist.h> 32#include <linux/scatterlist.h>
31#include <linux/platform_device.h> 33#include <linux/platform_device.h>
@@ -47,6 +49,8 @@
47 49
48#define DRIVER_NAME "msm-sdcc" 50#define DRIVER_NAME "msm-sdcc"
49 51
52#define BUSCLK_PWRSAVE 1
53#define BUSCLK_TIMEOUT (HZ)
50static unsigned int msmsdcc_fmin = 144000; 54static unsigned int msmsdcc_fmin = 144000;
51static unsigned int msmsdcc_fmax = 50000000; 55static unsigned int msmsdcc_fmax = 50000000;
52static unsigned int msmsdcc_4bit = 1; 56static unsigned int msmsdcc_4bit = 1;
@@ -57,6 +61,67 @@ static unsigned int msmsdcc_sdioirq;
57#define PIO_SPINMAX 30 61#define PIO_SPINMAX 30
58#define CMD_SPINMAX 20 62#define CMD_SPINMAX 20
59 63
64
65static inline void
66msmsdcc_disable_clocks(struct msmsdcc_host *host, int deferr)
67{
68 WARN_ON(!host->clks_on);
69
70 BUG_ON(host->curr.mrq);
71
72 if (deferr) {
73 mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT);
74 } else {
75 del_timer_sync(&host->busclk_timer);
76 /* Need to check clks_on again in case the busclk
77 * timer fired
78 */
79 if (host->clks_on) {
80 clk_disable(host->clk);
81 clk_disable(host->pclk);
82 host->clks_on = 0;
83 }
84 }
85}
86
87static inline int
88msmsdcc_enable_clocks(struct msmsdcc_host *host)
89{
90 int rc;
91
92 del_timer_sync(&host->busclk_timer);
93
94 if (!host->clks_on) {
95 rc = clk_enable(host->pclk);
96 if (rc)
97 return rc;
98 rc = clk_enable(host->clk);
99 if (rc) {
100 clk_disable(host->pclk);
101 return rc;
102 }
103 udelay(1 + ((3 * USEC_PER_SEC) /
104 (host->clk_rate ? host->clk_rate : msmsdcc_fmin)));
105 host->clks_on = 1;
106 }
107 return 0;
108}
109
110static inline unsigned int
111msmsdcc_readl(struct msmsdcc_host *host, unsigned int reg)
112{
113 return readl(host->base + reg);
114}
115
116static inline void
117msmsdcc_writel(struct msmsdcc_host *host, u32 data, unsigned int reg)
118{
119 writel(data, host->base + reg);
120 /* 3 clk delay required! */
121 udelay(1 + ((3 * USEC_PER_SEC) /
122 (host->clk_rate ? host->clk_rate : msmsdcc_fmin)));
123}
124
60static void 125static void
61msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, 126msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd,
62 u32 c); 127 u32 c);
@@ -64,8 +129,6 @@ msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd,
64static void 129static void
65msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) 130msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
66{ 131{
67 writel(0, host->base + MMCICOMMAND);
68
69 BUG_ON(host->curr.data); 132 BUG_ON(host->curr.data);
70 133
71 host->curr.mrq = NULL; 134 host->curr.mrq = NULL;
@@ -76,6 +139,9 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
76 if (mrq->cmd->error == -ETIMEDOUT) 139 if (mrq->cmd->error == -ETIMEDOUT)
77 mdelay(5); 140 mdelay(5);
78 141
142#if BUSCLK_PWRSAVE
143 msmsdcc_disable_clocks(host, 1);
144#endif
79 /* 145 /*
80 * Need to drop the host lock here; mmc_request_done may call 146 * Need to drop the host lock here; mmc_request_done may call
81 * back into the driver... 147 * back into the driver...
@@ -88,7 +154,6 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
88static void 154static void
89msmsdcc_stop_data(struct msmsdcc_host *host) 155msmsdcc_stop_data(struct msmsdcc_host *host)
90{ 156{
91 writel(0, host->base + MMCIDATACTRL);
92 host->curr.data = NULL; 157 host->curr.data = NULL;
93 host->curr.got_dataend = host->curr.got_datablkend = 0; 158 host->curr.got_dataend = host->curr.got_datablkend = 0;
94} 159}
@@ -109,6 +174,31 @@ uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host)
109 return 0; 174 return 0;
110} 175}
111 176
177static inline void
178msmsdcc_start_command_exec(struct msmsdcc_host *host, u32 arg, u32 c) {
179 msmsdcc_writel(host, arg, MMCIARGUMENT);
180 msmsdcc_writel(host, c, MMCICOMMAND);
181}
182
183static void
184msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd)
185{
186 struct msmsdcc_host *host = (struct msmsdcc_host *)cmd->data;
187
188 msmsdcc_writel(host, host->cmd_timeout, MMCIDATATIMER);
189 msmsdcc_writel(host, (unsigned int)host->curr.xfer_size,
190 MMCIDATALENGTH);
191 msmsdcc_writel(host, host->cmd_pio_irqmask, MMCIMASK1);
192 msmsdcc_writel(host, host->cmd_datactrl, MMCIDATACTRL);
193
194 if (host->cmd_cmd) {
195 msmsdcc_start_command_exec(host,
196 (u32) host->cmd_cmd->arg,
197 (u32) host->cmd_c);
198 }
199 host->dma.active = 1;
200}
201
112static void 202static void
113msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, 203msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
114 unsigned int result, 204 unsigned int result,
@@ -121,8 +211,11 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
121 struct mmc_request *mrq; 211 struct mmc_request *mrq;
122 212
123 spin_lock_irqsave(&host->lock, flags); 213 spin_lock_irqsave(&host->lock, flags);
214 host->dma.active = 0;
215
124 mrq = host->curr.mrq; 216 mrq = host->curr.mrq;
125 BUG_ON(!mrq); 217 BUG_ON(!mrq);
218 WARN_ON(!mrq->data);
126 219
127 if (!(result & DMOV_RSLT_VALID)) { 220 if (!(result & DMOV_RSLT_VALID)) {
128 pr_err("msmsdcc: Invalid DataMover result\n"); 221 pr_err("msmsdcc: Invalid DataMover result\n");
@@ -146,7 +239,6 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
146 if (!mrq->data->error) 239 if (!mrq->data->error)
147 mrq->data->error = -EIO; 240 mrq->data->error = -EIO;
148 } 241 }
149 host->dma.busy = 0;
150 dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents, 242 dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents,
151 host->dma.dir); 243 host->dma.dir);
152 244
@@ -159,6 +251,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
159 } 251 }
160 252
161 host->dma.sg = NULL; 253 host->dma.sg = NULL;
254 host->dma.busy = 0;
162 255
163 if ((host->curr.got_dataend && host->curr.got_datablkend) 256 if ((host->curr.got_dataend && host->curr.got_datablkend)
164 || mrq->data->error) { 257 || mrq->data->error) {
@@ -172,12 +265,14 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
172 if (!mrq->data->error) 265 if (!mrq->data->error)
173 host->curr.data_xfered = host->curr.xfer_size; 266 host->curr.data_xfered = host->curr.xfer_size;
174 if (!mrq->data->stop || mrq->cmd->error) { 267 if (!mrq->data->stop || mrq->cmd->error) {
175 writel(0, host->base + MMCICOMMAND);
176 host->curr.mrq = NULL; 268 host->curr.mrq = NULL;
177 host->curr.cmd = NULL; 269 host->curr.cmd = NULL;
178 mrq->data->bytes_xfered = host->curr.data_xfered; 270 mrq->data->bytes_xfered = host->curr.data_xfered;
179 271
180 spin_unlock_irqrestore(&host->lock, flags); 272 spin_unlock_irqrestore(&host->lock, flags);
273#if BUSCLK_PWRSAVE
274 msmsdcc_disable_clocks(host, 1);
275#endif
181 mmc_request_done(host->mmc, mrq); 276 mmc_request_done(host->mmc, mrq);
182 return; 277 return;
183 } else 278 } else
@@ -218,6 +313,8 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
218 host->dma.sg = data->sg; 313 host->dma.sg = data->sg;
219 host->dma.num_ents = data->sg_len; 314 host->dma.num_ents = data->sg_len;
220 315
316 BUG_ON(host->dma.num_ents > NR_SG); /* Prevent memory corruption */
317
221 nc = host->dma.nc; 318 nc = host->dma.nc;
222 319
223 switch (host->pdev_id) { 320 switch (host->pdev_id) {
@@ -246,22 +343,15 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
246 343
247 host->curr.user_pages = 0; 344 host->curr.user_pages = 0;
248 345
249 n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
250 host->dma.num_ents, host->dma.dir);
251
252 if (n != host->dma.num_ents) {
253 pr_err("%s: Unable to map in all sg elements\n",
254 mmc_hostname(host->mmc));
255 host->dma.sg = NULL;
256 host->dma.num_ents = 0;
257 return -ENOMEM;
258 }
259
260 box = &nc->cmd[0]; 346 box = &nc->cmd[0];
261 for (i = 0; i < host->dma.num_ents; i++) { 347 for (i = 0; i < host->dma.num_ents; i++) {
262 box->cmd = CMD_MODE_BOX; 348 box->cmd = CMD_MODE_BOX;
263 349
264 if (i == (host->dma.num_ents - 1)) 350 /* Initialize sg dma address */
351 sg->dma_address = page_to_dma(mmc_dev(host->mmc), sg_page(sg))
352 + sg->offset;
353
354 if (i == (host->dma.num_ents - 1))
265 box->cmd |= CMD_LC; 355 box->cmd |= CMD_LC;
266 rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ? 356 rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ?
267 (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 : 357 (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 :
@@ -300,15 +390,70 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
300 DMOV_CMD_ADDR(host->dma.cmdptr_busaddr); 390 DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
301 host->dma.hdr.complete_func = msmsdcc_dma_complete_func; 391 host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
302 392
393 n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
394 host->dma.num_ents, host->dma.dir);
395/* dsb inside dma_map_sg will write nc out to mem as well */
396
397 if (n != host->dma.num_ents) {
398 printk(KERN_ERR "%s: Unable to map in all sg elements\n",
399 mmc_hostname(host->mmc));
400 host->dma.sg = NULL;
401 host->dma.num_ents = 0;
402 return -ENOMEM;
403 }
404
405 return 0;
406}
407
408static int
409snoop_cccr_abort(struct mmc_command *cmd)
410{
411 if ((cmd->opcode == 52) &&
412 (cmd->arg & 0x80000000) &&
413 (((cmd->arg >> 9) & 0x1ffff) == SDIO_CCCR_ABORT))
414 return 1;
303 return 0; 415 return 0;
304} 416}
305 417
306static void 418static void
307msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) 419msmsdcc_start_command_deferred(struct msmsdcc_host *host,
420 struct mmc_command *cmd, u32 *c)
421{
422 *c |= (cmd->opcode | MCI_CPSM_ENABLE);
423
424 if (cmd->flags & MMC_RSP_PRESENT) {
425 if (cmd->flags & MMC_RSP_136)
426 *c |= MCI_CPSM_LONGRSP;
427 *c |= MCI_CPSM_RESPONSE;
428 }
429
430 if (/*interrupt*/0)
431 *c |= MCI_CPSM_INTERRUPT;
432
433 if ((((cmd->opcode == 17) || (cmd->opcode == 18)) ||
434 ((cmd->opcode == 24) || (cmd->opcode == 25))) ||
435 (cmd->opcode == 53))
436 *c |= MCI_CSPM_DATCMD;
437
438 if (cmd == cmd->mrq->stop)
439 *c |= MCI_CSPM_MCIABORT;
440
441 if (snoop_cccr_abort(cmd))
442 *c |= MCI_CSPM_MCIABORT;
443
444 if (host->curr.cmd != NULL) {
445 printk(KERN_ERR "%s: Overlapping command requests\n",
446 mmc_hostname(host->mmc));
447 }
448 host->curr.cmd = cmd;
449}
450
451static void
452msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
453 struct mmc_command *cmd, u32 c)
308{ 454{
309 unsigned int datactrl, timeout; 455 unsigned int datactrl, timeout;
310 unsigned long long clks; 456 unsigned long long clks;
311 void __iomem *base = host->base;
312 unsigned int pio_irqmask = 0; 457 unsigned int pio_irqmask = 0;
313 458
314 host->curr.data = data; 459 host->curr.data = data;
@@ -320,13 +465,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data)
320 465
321 memset(&host->pio, 0, sizeof(host->pio)); 466 memset(&host->pio, 0, sizeof(host->pio));
322 467
323 clks = (unsigned long long)data->timeout_ns * host->clk_rate;
324 do_div(clks, NSEC_PER_SEC);
325 timeout = data->timeout_clks + (unsigned int)clks;
326 writel(timeout, base + MMCIDATATIMER);
327
328 writel(host->curr.xfer_size, base + MMCIDATALENGTH);
329
330 datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); 468 datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
331 469
332 if (!msmsdcc_config_dma(host, data)) 470 if (!msmsdcc_config_dma(host, data))
@@ -347,47 +485,51 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data)
347 if (data->flags & MMC_DATA_READ) 485 if (data->flags & MMC_DATA_READ)
348 datactrl |= MCI_DPSM_DIRECTION; 486 datactrl |= MCI_DPSM_DIRECTION;
349 487
350 writel(pio_irqmask, base + MMCIMASK1); 488 clks = (unsigned long long)data->timeout_ns * host->clk_rate;
351 writel(datactrl, base + MMCIDATACTRL); 489 do_div(clks, NSEC_PER_SEC);
490 timeout = data->timeout_clks + (unsigned int)clks*2 ;
352 491
353 if (datactrl & MCI_DPSM_DMAENABLE) { 492 if (datactrl & MCI_DPSM_DMAENABLE) {
493 /* Save parameters for the exec function */
494 host->cmd_timeout = timeout;
495 host->cmd_pio_irqmask = pio_irqmask;
496 host->cmd_datactrl = datactrl;
497 host->cmd_cmd = cmd;
498
499 host->dma.hdr.execute_func = msmsdcc_dma_exec_func;
500 host->dma.hdr.data = (void *)host;
354 host->dma.busy = 1; 501 host->dma.busy = 1;
502
503 if (cmd) {
504 msmsdcc_start_command_deferred(host, cmd, &c);
505 host->cmd_c = c;
506 }
355 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); 507 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr);
508 } else {
509 msmsdcc_writel(host, timeout, MMCIDATATIMER);
510
511 msmsdcc_writel(host, host->curr.xfer_size, MMCIDATALENGTH);
512
513 msmsdcc_writel(host, pio_irqmask, MMCIMASK1);
514 msmsdcc_writel(host, datactrl, MMCIDATACTRL);
515
516 if (cmd) {
517 /* Daisy-chain the command if requested */
518 msmsdcc_start_command(host, cmd, c);
519 }
356 } 520 }
357} 521}
358 522
359static void 523static void
360msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) 524msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c)
361{ 525{
362 void __iomem *base = host->base;
363
364 if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
365 writel(0, base + MMCICOMMAND);
366 udelay(2 + ((5 * 1000000) / host->clk_rate));
367 }
368
369 c |= cmd->opcode | MCI_CPSM_ENABLE;
370
371 if (cmd->flags & MMC_RSP_PRESENT) {
372 if (cmd->flags & MMC_RSP_136)
373 c |= MCI_CPSM_LONGRSP;
374 c |= MCI_CPSM_RESPONSE;
375 }
376
377 if (cmd->opcode == 17 || cmd->opcode == 18 ||
378 cmd->opcode == 24 || cmd->opcode == 25 ||
379 cmd->opcode == 53)
380 c |= MCI_CSPM_DATCMD;
381
382 if (cmd == cmd->mrq->stop) 526 if (cmd == cmd->mrq->stop)
383 c |= MCI_CSPM_MCIABORT; 527 c |= MCI_CSPM_MCIABORT;
384 528
385 host->curr.cmd = cmd;
386
387 host->stats.cmds++; 529 host->stats.cmds++;
388 530
389 writel(cmd->arg, base + MMCIARGUMENT); 531 msmsdcc_start_command_deferred(host, cmd, &c);
390 writel(c, base + MMCICOMMAND); 532 msmsdcc_start_command_exec(host, cmd->arg, c);
391} 533}
392 534
393static void 535static void
@@ -421,13 +563,11 @@ msmsdcc_data_err(struct msmsdcc_host *host, struct mmc_data *data,
421static int 563static int
422msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain) 564msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain)
423{ 565{
424 void __iomem *base = host->base;
425 uint32_t *ptr = (uint32_t *) buffer; 566 uint32_t *ptr = (uint32_t *) buffer;
426 int count = 0; 567 int count = 0;
427 568
428 while (readl(base + MMCISTATUS) & MCI_RXDATAAVLBL) { 569 while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) {
429 570 *ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE));
430 *ptr = readl(base + MMCIFIFO + (count % MCI_FIFOSIZE));
431 ptr++; 571 ptr++;
432 count += sizeof(uint32_t); 572 count += sizeof(uint32_t);
433 573
@@ -459,7 +599,7 @@ msmsdcc_pio_write(struct msmsdcc_host *host, char *buffer,
459 if (remain == 0) 599 if (remain == 0)
460 break; 600 break;
461 601
462 status = readl(base + MMCISTATUS); 602 status = msmsdcc_readl(host, MMCISTATUS);
463 } while (status & MCI_TXFIFOHALFEMPTY); 603 } while (status & MCI_TXFIFOHALFEMPTY);
464 604
465 return ptr - buffer; 605 return ptr - buffer;
@@ -469,7 +609,7 @@ static int
469msmsdcc_spin_on_status(struct msmsdcc_host *host, uint32_t mask, int maxspin) 609msmsdcc_spin_on_status(struct msmsdcc_host *host, uint32_t mask, int maxspin)
470{ 610{
471 while (maxspin) { 611 while (maxspin) {
472 if ((readl(host->base + MMCISTATUS) & mask)) 612 if ((msmsdcc_readl(host, MMCISTATUS) & mask))
473 return 0; 613 return 0;
474 udelay(1); 614 udelay(1);
475 --maxspin; 615 --maxspin;
@@ -477,14 +617,13 @@ msmsdcc_spin_on_status(struct msmsdcc_host *host, uint32_t mask, int maxspin)
477 return -ETIMEDOUT; 617 return -ETIMEDOUT;
478} 618}
479 619
480static int 620static irqreturn_t
481msmsdcc_pio_irq(int irq, void *dev_id) 621msmsdcc_pio_irq(int irq, void *dev_id)
482{ 622{
483 struct msmsdcc_host *host = dev_id; 623 struct msmsdcc_host *host = dev_id;
484 void __iomem *base = host->base;
485 uint32_t status; 624 uint32_t status;
486 625
487 status = readl(base + MMCISTATUS); 626 status = msmsdcc_readl(host, MMCISTATUS);
488 627
489 do { 628 do {
490 unsigned long flags; 629 unsigned long flags;
@@ -539,14 +678,14 @@ msmsdcc_pio_irq(int irq, void *dev_id)
539 host->pio.sg_off = 0; 678 host->pio.sg_off = 0;
540 } 679 }
541 680
542 status = readl(base + MMCISTATUS); 681 status = msmsdcc_readl(host, MMCISTATUS);
543 } while (1); 682 } while (1);
544 683
545 if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) 684 if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE)
546 writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1); 685 msmsdcc_writel(host, MCI_RXDATAAVLBLMASK, MMCIMASK1);
547 686
548 if (!host->curr.xfer_remain) 687 if (!host->curr.xfer_remain)
549 writel(0, base + MMCIMASK1); 688 msmsdcc_writel(host, 0, MMCIMASK1);
550 689
551 return IRQ_HANDLED; 690 return IRQ_HANDLED;
552} 691}
@@ -554,15 +693,13 @@ msmsdcc_pio_irq(int irq, void *dev_id)
554static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status) 693static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
555{ 694{
556 struct mmc_command *cmd = host->curr.cmd; 695 struct mmc_command *cmd = host->curr.cmd;
557 void __iomem *base = host->base;
558 696
559 host->curr.cmd = NULL; 697 host->curr.cmd = NULL;
560 cmd->resp[0] = readl(base + MMCIRESPONSE0); 698 cmd->resp[0] = msmsdcc_readl(host, MMCIRESPONSE0);
561 cmd->resp[1] = readl(base + MMCIRESPONSE1); 699 cmd->resp[1] = msmsdcc_readl(host, MMCIRESPONSE1);
562 cmd->resp[2] = readl(base + MMCIRESPONSE2); 700 cmd->resp[2] = msmsdcc_readl(host, MMCIRESPONSE2);
563 cmd->resp[3] = readl(base + MMCIRESPONSE3); 701 cmd->resp[3] = msmsdcc_readl(host, MMCIRESPONSE3);
564 702
565 del_timer(&host->command_timer);
566 if (status & MCI_CMDTIMEOUT) { 703 if (status & MCI_CMDTIMEOUT) {
567 cmd->error = -ETIMEDOUT; 704 cmd->error = -ETIMEDOUT;
568 } else if (status & MCI_CMDCRCFAIL && 705 } else if (status & MCI_CMDCRCFAIL &&
@@ -580,8 +717,10 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
580 msmsdcc_request_end(host, cmd->mrq); 717 msmsdcc_request_end(host, cmd->mrq);
581 } else /* host->data == NULL */ 718 } else /* host->data == NULL */
582 msmsdcc_request_end(host, cmd->mrq); 719 msmsdcc_request_end(host, cmd->mrq);
583 } else if (!(cmd->data->flags & MMC_DATA_READ)) 720 } else if (cmd->data)
584 msmsdcc_start_data(host, cmd->data); 721 if (!(cmd->data->flags & MMC_DATA_READ))
722 msmsdcc_start_data(host, cmd->data,
723 NULL, 0);
585} 724}
586 725
587static void 726static void
@@ -590,6 +729,11 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
590{ 729{
591 struct mmc_data *data = host->curr.data; 730 struct mmc_data *data = host->curr.data;
592 731
732 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
733 MCI_CMDTIMEOUT) && host->curr.cmd) {
734 msmsdcc_do_cmdirq(host, status);
735 }
736
593 if (!data) 737 if (!data)
594 return; 738 return;
595 739
@@ -602,7 +746,8 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
602 msm_dmov_stop_cmd(host->dma.channel, 746 msm_dmov_stop_cmd(host->dma.channel,
603 &host->dma.hdr, 0); 747 &host->dma.hdr, 0);
604 else { 748 else {
605 msmsdcc_stop_data(host); 749 if (host->curr.data)
750 msmsdcc_stop_data(host);
606 if (!data->stop) 751 if (!data->stop)
607 msmsdcc_request_end(host, data->mrq); 752 msmsdcc_request_end(host, data->mrq);
608 else 753 else
@@ -657,17 +802,18 @@ msmsdcc_irq(int irq, void *dev_id)
657 spin_lock(&host->lock); 802 spin_lock(&host->lock);
658 803
659 do { 804 do {
660 status = readl(base + MMCISTATUS); 805 status = msmsdcc_readl(host, MMCISTATUS);
806 status &= (msmsdcc_readl(host, MMCIMASK0) |
807 MCI_DATABLOCKENDMASK);
808 msmsdcc_writel(host, status, MMCICLEAR);
661 809
662 status &= (readl(base + MMCIMASK0) | MCI_DATABLOCKENDMASK); 810 if (status & MCI_SDIOINTR)
663 writel(status, base + MMCICLEAR); 811 status &= ~MCI_SDIOINTR;
664 812
665 msmsdcc_handle_irq_data(host, status, base); 813 if (!status)
814 break;
666 815
667 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | 816 msmsdcc_handle_irq_data(host, status, base);
668 MCI_CMDTIMEOUT) && host->curr.cmd) {
669 msmsdcc_do_cmdirq(host, status);
670 }
671 817
672 if (status & MCI_SDIOINTOPER) { 818 if (status & MCI_SDIOINTOPER) {
673 cardint = 1; 819 cardint = 1;
@@ -714,24 +860,27 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
714 return; 860 return;
715 } 861 }
716 862
863 msmsdcc_enable_clocks(host);
864
717 host->curr.mrq = mrq; 865 host->curr.mrq = mrq;
718 866
719 if (mrq->data && mrq->data->flags & MMC_DATA_READ) 867 if (mrq->data && mrq->data->flags & MMC_DATA_READ)
720 msmsdcc_start_data(host, mrq->data); 868 /* Queue/read data, daisy-chain command when data starts */
721 869 msmsdcc_start_data(host, mrq->data, mrq->cmd, 0);
722 msmsdcc_start_command(host, mrq->cmd, 0); 870 else
871 msmsdcc_start_command(host, mrq->cmd, 0);
723 872
724 if (host->cmdpoll && !msmsdcc_spin_on_status(host, 873 if (host->cmdpoll && !msmsdcc_spin_on_status(host,
725 MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT, 874 MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT,
726 CMD_SPINMAX)) { 875 CMD_SPINMAX)) {
727 uint32_t status = readl(host->base + MMCISTATUS); 876 uint32_t status = msmsdcc_readl(host, MMCISTATUS);
728 msmsdcc_do_cmdirq(host, status); 877 msmsdcc_do_cmdirq(host, status);
729 writel(MCI_CMDRESPEND | MCI_CMDCRCFAIL | MCI_CMDTIMEOUT, 878 msmsdcc_writel(host,
730 host->base + MMCICLEAR); 879 MCI_CMDRESPEND | MCI_CMDCRCFAIL | MCI_CMDTIMEOUT,
880 MMCICLEAR);
731 host->stats.cmdpoll_hits++; 881 host->stats.cmdpoll_hits++;
732 } else { 882 } else {
733 host->stats.cmdpoll_misses++; 883 host->stats.cmdpoll_misses++;
734 mod_timer(&host->command_timer, jiffies + HZ);
735 } 884 }
736 spin_unlock_irqrestore(&host->lock, flags); 885 spin_unlock_irqrestore(&host->lock, flags);
737} 886}
@@ -742,14 +891,13 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
742 struct msmsdcc_host *host = mmc_priv(mmc); 891 struct msmsdcc_host *host = mmc_priv(mmc);
743 u32 clk = 0, pwr = 0; 892 u32 clk = 0, pwr = 0;
744 int rc; 893 int rc;
894 unsigned long flags;
745 895
746 if (ios->clock) { 896 spin_lock_irqsave(&host->lock, flags);
747 897
748 if (!host->clks_on) { 898 msmsdcc_enable_clocks(host);
749 clk_enable(host->pclk); 899
750 clk_enable(host->clk); 900 if (ios->clock) {
751 host->clks_on = 1;
752 }
753 if (ios->clock != host->clk_rate) { 901 if (ios->clock != host->clk_rate) {
754 rc = clk_set_rate(host->clk, ios->clock); 902 rc = clk_set_rate(host->clk, ios->clock);
755 if (rc < 0) 903 if (rc < 0)
@@ -787,18 +935,16 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
787 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 935 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
788 pwr |= MCI_OD; 936 pwr |= MCI_OD;
789 937
790 writel(clk, host->base + MMCICLOCK); 938 msmsdcc_writel(host, clk, MMCICLOCK);
791 939
792 if (host->pwr != pwr) { 940 if (host->pwr != pwr) {
793 host->pwr = pwr; 941 host->pwr = pwr;
794 writel(pwr, host->base + MMCIPOWER); 942 msmsdcc_writel(host, pwr, MMCIPOWER);
795 }
796
797 if (!(clk & MCI_CLK_ENABLE) && host->clks_on) {
798 clk_disable(host->clk);
799 clk_disable(host->pclk);
800 host->clks_on = 0;
801 } 943 }
944#if BUSCLK_PWRSAVE
945 msmsdcc_disable_clocks(host, 1);
946#endif
947 spin_unlock_irqrestore(&host->lock, flags);
802} 948}
803 949
804static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable) 950static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
@@ -809,13 +955,13 @@ static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
809 955
810 spin_lock_irqsave(&host->lock, flags); 956 spin_lock_irqsave(&host->lock, flags);
811 if (msmsdcc_sdioirq == 1) { 957 if (msmsdcc_sdioirq == 1) {
812 status = readl(host->base + MMCIMASK0); 958 status = msmsdcc_readl(host, MMCIMASK0);
813 if (enable) 959 if (enable)
814 status |= MCI_SDIOINTOPERMASK; 960 status |= MCI_SDIOINTOPERMASK;
815 else 961 else
816 status &= ~MCI_SDIOINTOPERMASK; 962 status &= ~MCI_SDIOINTOPERMASK;
817 host->saved_irq0mask = status; 963 host->saved_irq0mask = status;
818 writel(status, host->base + MMCIMASK0); 964 msmsdcc_writel(host, status, MMCIMASK0);
819 } 965 }
820 spin_unlock_irqrestore(&host->lock, flags); 966 spin_unlock_irqrestore(&host->lock, flags);
821} 967}
@@ -875,42 +1021,13 @@ msmsdcc_status_notify_cb(int card_present, void *dev_id)
875 msmsdcc_check_status((unsigned long) host); 1021 msmsdcc_check_status((unsigned long) host);
876} 1022}
877 1023
878/*
879 * called when a command expires.
880 * Dump some debugging, and then error
881 * out the transaction.
882 */
883static void 1024static void
884msmsdcc_command_expired(unsigned long _data) 1025msmsdcc_busclk_expired(unsigned long _data)
885{ 1026{
886 struct msmsdcc_host *host = (struct msmsdcc_host *) _data; 1027 struct msmsdcc_host *host = (struct msmsdcc_host *) _data;
887 struct mmc_request *mrq;
888 unsigned long flags;
889
890 spin_lock_irqsave(&host->lock, flags);
891 mrq = host->curr.mrq;
892
893 if (!mrq) {
894 pr_info("%s: Command expiry misfire\n",
895 mmc_hostname(host->mmc));
896 spin_unlock_irqrestore(&host->lock, flags);
897 return;
898 }
899
900 pr_err("%s: Command timeout (%p %p %p %p)\n",
901 mmc_hostname(host->mmc), mrq, mrq->cmd,
902 mrq->data, host->dma.sg);
903
904 mrq->cmd->error = -ETIMEDOUT;
905 msmsdcc_stop_data(host);
906 1028
907 writel(0, host->base + MMCICOMMAND); 1029 if (host->clks_on)
908 1030 msmsdcc_disable_clocks(host, 0);
909 host->curr.mrq = NULL;
910 host->curr.cmd = NULL;
911
912 spin_unlock_irqrestore(&host->lock, flags);
913 mmc_request_done(host->mmc, mrq);
914} 1031}
915 1032
916static int 1033static int
@@ -1012,6 +1129,7 @@ msmsdcc_probe(struct platform_device *pdev)
1012 host->pdev_id = pdev->id; 1129 host->pdev_id = pdev->id;
1013 host->plat = plat; 1130 host->plat = plat;
1014 host->mmc = mmc; 1131 host->mmc = mmc;
1132 host->curr.cmd = NULL;
1015 1133
1016 host->cmdpoll = 1; 1134 host->cmdpoll = 1;
1017 1135
@@ -1027,36 +1145,35 @@ msmsdcc_probe(struct platform_device *pdev)
1027 host->dmares = dmares; 1145 host->dmares = dmares;
1028 spin_lock_init(&host->lock); 1146 spin_lock_init(&host->lock);
1029 1147
1148#ifdef CONFIG_MMC_EMBEDDED_SDIO
1149 if (plat->embedded_sdio)
1150 mmc_set_embedded_sdio_data(mmc,
1151 &plat->embedded_sdio->cis,
1152 &plat->embedded_sdio->cccr,
1153 plat->embedded_sdio->funcs,
1154 plat->embedded_sdio->num_funcs);
1155#endif
1156
1030 /* 1157 /*
1031 * Setup DMA 1158 * Setup DMA
1032 */ 1159 */
1033 msmsdcc_init_dma(host); 1160 msmsdcc_init_dma(host);
1034 1161
1035 /* 1162 /* Get our clocks */
1036 * Setup main peripheral bus clock
1037 */
1038 host->pclk = clk_get(&pdev->dev, "sdc_pclk"); 1163 host->pclk = clk_get(&pdev->dev, "sdc_pclk");
1039 if (IS_ERR(host->pclk)) { 1164 if (IS_ERR(host->pclk)) {
1040 ret = PTR_ERR(host->pclk); 1165 ret = PTR_ERR(host->pclk);
1041 goto host_free; 1166 goto host_free;
1042 } 1167 }
1043 1168
1044 ret = clk_enable(host->pclk);
1045 if (ret)
1046 goto pclk_put;
1047
1048 host->pclk_rate = clk_get_rate(host->pclk);
1049
1050 /*
1051 * Setup SDC MMC clock
1052 */
1053 host->clk = clk_get(&pdev->dev, "sdc_clk"); 1169 host->clk = clk_get(&pdev->dev, "sdc_clk");
1054 if (IS_ERR(host->clk)) { 1170 if (IS_ERR(host->clk)) {
1055 ret = PTR_ERR(host->clk); 1171 ret = PTR_ERR(host->clk);
1056 goto pclk_disable; 1172 goto pclk_put;
1057 } 1173 }
1058 1174
1059 ret = clk_enable(host->clk); 1175 /* Enable clocks */
1176 ret = msmsdcc_enable_clocks(host);
1060 if (ret) 1177 if (ret)
1061 goto clk_put; 1178 goto clk_put;
1062 1179
@@ -1066,10 +1183,9 @@ msmsdcc_probe(struct platform_device *pdev)
1066 goto clk_disable; 1183 goto clk_disable;
1067 } 1184 }
1068 1185
1186 host->pclk_rate = clk_get_rate(host->pclk);
1069 host->clk_rate = clk_get_rate(host->clk); 1187 host->clk_rate = clk_get_rate(host->clk);
1070 1188
1071 host->clks_on = 1;
1072
1073 /* 1189 /*
1074 * Setup MMC host structure 1190 * Setup MMC host structure
1075 */ 1191 */
@@ -1092,10 +1208,10 @@ msmsdcc_probe(struct platform_device *pdev)
1092 mmc->max_req_size = 33554432; /* MCI_DATA_LENGTH is 25 bits */ 1208 mmc->max_req_size = 33554432; /* MCI_DATA_LENGTH is 25 bits */
1093 mmc->max_seg_size = mmc->max_req_size; 1209 mmc->max_seg_size = mmc->max_req_size;
1094 1210
1095 writel(0, host->base + MMCIMASK0); 1211 msmsdcc_writel(host, 0, MMCIMASK0);
1096 writel(0x5e007ff, host->base + MMCICLEAR); /* Add: 1 << 25 */ 1212 msmsdcc_writel(host, 0x5e007ff, MMCICLEAR);
1097 1213
1098 writel(MCI_IRQENABLE, host->base + MMCIMASK0); 1214 msmsdcc_writel(host, MCI_IRQENABLE, MMCIMASK0);
1099 host->saved_irq0mask = MCI_IRQENABLE; 1215 host->saved_irq0mask = MCI_IRQENABLE;
1100 1216
1101 /* 1217 /*
@@ -1137,13 +1253,9 @@ msmsdcc_probe(struct platform_device *pdev)
1137 host->eject = !host->oldstat; 1253 host->eject = !host->oldstat;
1138 } 1254 }
1139 1255
1140 /* 1256 init_timer(&host->busclk_timer);
1141 * Setup a command timer. We currently need this due to 1257 host->busclk_timer.data = (unsigned long) host;
1142 * some 'strange' timeout / error handling situations. 1258 host->busclk_timer.function = msmsdcc_busclk_expired;
1143 */
1144 init_timer(&host->command_timer);
1145 host->command_timer.data = (unsigned long) host;
1146 host->command_timer.function = msmsdcc_command_expired;
1147 1259
1148 ret = request_irq(cmd_irqres->start, msmsdcc_irq, IRQF_SHARED, 1260 ret = request_irq(cmd_irqres->start, msmsdcc_irq, IRQF_SHARED,
1149 DRIVER_NAME " (cmd)", host); 1261 DRIVER_NAME " (cmd)", host);
@@ -1181,6 +1293,9 @@ msmsdcc_probe(struct platform_device *pdev)
1181 if (host->timer.function) 1293 if (host->timer.function)
1182 pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc)); 1294 pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc));
1183 1295
1296#if BUSCLK_PWRSAVE
1297 msmsdcc_disable_clocks(host, 1);
1298#endif
1184 return 0; 1299 return 0;
1185 cmd_irq_free: 1300 cmd_irq_free:
1186 free_irq(cmd_irqres->start, host); 1301 free_irq(cmd_irqres->start, host);
@@ -1188,11 +1303,9 @@ msmsdcc_probe(struct platform_device *pdev)
1188 if (host->stat_irq) 1303 if (host->stat_irq)
1189 free_irq(host->stat_irq, host); 1304 free_irq(host->stat_irq, host);
1190 clk_disable: 1305 clk_disable:
1191 clk_disable(host->clk); 1306 msmsdcc_disable_clocks(host, 0);
1192 clk_put: 1307 clk_put:
1193 clk_put(host->clk); 1308 clk_put(host->clk);
1194 pclk_disable:
1195 clk_disable(host->pclk);
1196 pclk_put: 1309 pclk_put:
1197 clk_put(host->pclk); 1310 clk_put(host->pclk);
1198 host_free: 1311 host_free:
@@ -1215,15 +1328,10 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state)
1215 1328
1216 if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) 1329 if (mmc->card && mmc->card->type != MMC_TYPE_SDIO)
1217 rc = mmc_suspend_host(mmc, state); 1330 rc = mmc_suspend_host(mmc, state);
1218 if (!rc) { 1331 if (!rc)
1219 writel(0, host->base + MMCIMASK0); 1332 msmsdcc_writel(host, 0, MMCIMASK0);
1220 1333 if (host->clks_on)
1221 if (host->clks_on) { 1334 msmsdcc_disable_clocks(host, 0);
1222 clk_disable(host->clk);
1223 clk_disable(host->pclk);
1224 host->clks_on = 0;
1225 }
1226 }
1227 } 1335 }
1228 return rc; 1336 return rc;
1229} 1337}
@@ -1232,27 +1340,21 @@ static int
1232msmsdcc_resume(struct platform_device *dev) 1340msmsdcc_resume(struct platform_device *dev)
1233{ 1341{
1234 struct mmc_host *mmc = mmc_get_drvdata(dev); 1342 struct mmc_host *mmc = mmc_get_drvdata(dev);
1235 unsigned long flags;
1236 1343
1237 if (mmc) { 1344 if (mmc) {
1238 struct msmsdcc_host *host = mmc_priv(mmc); 1345 struct msmsdcc_host *host = mmc_priv(mmc);
1239 1346
1240 spin_lock_irqsave(&host->lock, flags); 1347 msmsdcc_enable_clocks(host);
1241 1348
1242 if (!host->clks_on) { 1349 msmsdcc_writel(host, host->saved_irq0mask, MMCIMASK0);
1243 clk_enable(host->pclk);
1244 clk_enable(host->clk);
1245 host->clks_on = 1;
1246 }
1247
1248 writel(host->saved_irq0mask, host->base + MMCIMASK0);
1249
1250 spin_unlock_irqrestore(&host->lock, flags);
1251 1350
1252 if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) 1351 if (mmc->card && mmc->card->type != MMC_TYPE_SDIO)
1253 mmc_resume_host(mmc); 1352 mmc_resume_host(mmc);
1254 if (host->stat_irq) 1353 if (host->stat_irq)
1255 enable_irq(host->stat_irq); 1354 enable_irq(host->stat_irq);
1355#if BUSCLK_PWRSAVE
1356 msmsdcc_disable_clocks(host, 1);
1357#endif
1256 } 1358 }
1257 return 0; 1359 return 0;
1258} 1360}
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 8c8448469811..da0039c9285e 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -171,6 +171,7 @@ struct msmsdcc_dma_data {
171 int channel; 171 int channel;
172 struct msmsdcc_host *host; 172 struct msmsdcc_host *host;
173 int busy; /* Set if DM is busy */ 173 int busy; /* Set if DM is busy */
174 int active;
174}; 175};
175 176
176struct msmsdcc_pio_data { 177struct msmsdcc_pio_data {
@@ -213,7 +214,7 @@ struct msmsdcc_host {
213 struct clk *clk; /* main MMC bus clock */ 214 struct clk *clk; /* main MMC bus clock */
214 struct clk *pclk; /* SDCC peripheral bus clock */ 215 struct clk *pclk; /* SDCC peripheral bus clock */
215 unsigned int clks_on; /* set if clocks are enabled */ 216 unsigned int clks_on; /* set if clocks are enabled */
216 struct timer_list command_timer; 217 struct timer_list busclk_timer;
217 218
218 unsigned int eject; /* eject state */ 219 unsigned int eject; /* eject state */
219 220
@@ -233,6 +234,18 @@ struct msmsdcc_host {
233 struct msmsdcc_pio_data pio; 234 struct msmsdcc_pio_data pio;
234 int cmdpoll; 235 int cmdpoll;
235 struct msmsdcc_stats stats; 236 struct msmsdcc_stats stats;
237
238#ifdef CONFIG_MMC_MSM7X00A_RESUME_IN_WQ
239 struct work_struct resume_task;
240#endif
241
242 /* Command parameters */
243 unsigned int cmd_timeout;
244 unsigned int cmd_pio_irqmask;
245 unsigned int cmd_datactrl;
246 struct mmc_command *cmd_cmd;
247 u32 cmd_c;
248
236}; 249};
237 250
238#endif 251#endif
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 0ed48959b590..e4f00e70a749 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -544,7 +544,7 @@ static irqreturn_t pxamci_detect_irq(int irq, void *devid)
544{ 544{
545 struct pxamci_host *host = mmc_priv(devid); 545 struct pxamci_host *host = mmc_priv(devid);
546 546
547 mmc_detect_change(devid, host->pdata->detect_delay); 547 mmc_detect_change(devid, msecs_to_jiffies(host->pdata->detect_delay_ms));
548 return IRQ_HANDLED; 548 return IRQ_HANDLED;
549} 549}
550 550