aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/msm_sdcc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/msm_sdcc.c')
-rw-r--r--drivers/mmc/host/msm_sdcc.c267
1 files changed, 148 insertions, 119 deletions
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 84b284e3a28..52485859790 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
@@ -47,6 +48,7 @@
47 48
48#define DRIVER_NAME "msm-sdcc" 49#define DRIVER_NAME "msm-sdcc"
49 50
51#define BUSCLK_TIMEOUT (HZ * 5)
50static unsigned int msmsdcc_fmin = 144000; 52static unsigned int msmsdcc_fmin = 144000;
51static unsigned int msmsdcc_fmax = 50000000; 53static unsigned int msmsdcc_fmax = 50000000;
52static unsigned int msmsdcc_4bit = 1; 54static unsigned int msmsdcc_4bit = 1;
@@ -106,8 +108,6 @@ msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd,
106static void 108static void
107msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) 109msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
108{ 110{
109 msmsdcc_writel(host, 0, MMCICOMMAND);
110
111 BUG_ON(host->curr.data); 111 BUG_ON(host->curr.data);
112 112
113 host->curr.mrq = NULL; 113 host->curr.mrq = NULL;
@@ -119,7 +119,7 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
119 mdelay(5); 119 mdelay(5);
120 120
121 if (host->use_bustimer) 121 if (host->use_bustimer)
122 mod_timer(&host->busclk_timer, jiffies + HZ); 122 mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT);
123 /* 123 /*
124 * Need to drop the host lock here; mmc_request_done may call 124 * Need to drop the host lock here; mmc_request_done may call
125 * back into the driver... 125 * back into the driver...
@@ -132,7 +132,6 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
132static void 132static void
133msmsdcc_stop_data(struct msmsdcc_host *host) 133msmsdcc_stop_data(struct msmsdcc_host *host)
134{ 134{
135 msmsdcc_writel(host, 0, MMCIDATACTRL);
136 host->curr.data = NULL; 135 host->curr.data = NULL;
137 host->curr.got_dataend = host->curr.got_datablkend = 0; 136 host->curr.got_dataend = host->curr.got_datablkend = 0;
138} 137}
@@ -153,6 +152,29 @@ uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host)
153 return 0; 152 return 0;
154} 153}
155 154
155static inline void
156msmsdcc_start_command_exec(struct msmsdcc_host *host, u32 arg, u32 c) {
157 msmsdcc_writel(host, arg, MMCIARGUMENT);
158 msmsdcc_writel(host, c, MMCICOMMAND);
159}
160
161static void
162msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd)
163{
164 struct msmsdcc_host *host = (struct msmsdcc_host *)cmd->data;
165
166 writel(host->cmd_timeout, host->base + MMCIDATATIMER);
167 writel((unsigned int)host->curr.xfer_size, host->base + MMCIDATALENGTH);
168 writel(host->cmd_pio_irqmask, host->base + MMCIMASK1);
169 writel(host->cmd_datactrl, host->base + MMCIDATACTRL);
170
171 if (host->cmd_cmd) {
172 msmsdcc_start_command_exec(host,
173 (u32)host->cmd_cmd->arg, (u32)host->cmd_c);
174 }
175 host->dma.active = 1;
176}
177
156static void 178static void
157msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, 179msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
158 unsigned int result, 180 unsigned int result,
@@ -165,6 +187,8 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
165 struct mmc_request *mrq; 187 struct mmc_request *mrq;
166 188
167 spin_lock_irqsave(&host->lock, flags); 189 spin_lock_irqsave(&host->lock, flags);
190 host->dma.active = 0;
191
168 mrq = host->curr.mrq; 192 mrq = host->curr.mrq;
169 BUG_ON(!mrq); 193 BUG_ON(!mrq);
170 194
@@ -190,7 +214,6 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
190 if (!mrq->data->error) 214 if (!mrq->data->error)
191 mrq->data->error = -EIO; 215 mrq->data->error = -EIO;
192 } 216 }
193 host->dma.busy = 0;
194 dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents, 217 dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents,
195 host->dma.dir); 218 host->dma.dir);
196 219
@@ -203,6 +226,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
203 } 226 }
204 227
205 host->dma.sg = NULL; 228 host->dma.sg = NULL;
229 host->dma.busy = 0;
206 230
207 if ((host->curr.got_dataend && host->curr.got_datablkend) 231 if ((host->curr.got_dataend && host->curr.got_datablkend)
208 || mrq->data->error) { 232 || mrq->data->error) {
@@ -262,6 +286,8 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
262 host->dma.sg = data->sg; 286 host->dma.sg = data->sg;
263 host->dma.num_ents = data->sg_len; 287 host->dma.num_ents = data->sg_len;
264 288
289 BUG_ON(host->dma.num_ents > NR_SG); /* Prevent memory corruption */
290
265 nc = host->dma.nc; 291 nc = host->dma.nc;
266 292
267 switch (host->pdev_id) { 293 switch (host->pdev_id) {
@@ -290,22 +316,15 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
290 316
291 host->curr.user_pages = 0; 317 host->curr.user_pages = 0;
292 318
293 n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
294 host->dma.num_ents, host->dma.dir);
295
296 if (n != host->dma.num_ents) {
297 pr_err("%s: Unable to map in all sg elements\n",
298 mmc_hostname(host->mmc));
299 host->dma.sg = NULL;
300 host->dma.num_ents = 0;
301 return -ENOMEM;
302 }
303
304 box = &nc->cmd[0]; 319 box = &nc->cmd[0];
305 for (i = 0; i < host->dma.num_ents; i++) { 320 for (i = 0; i < host->dma.num_ents; i++) {
306 box->cmd = CMD_MODE_BOX; 321 box->cmd = CMD_MODE_BOX;
307 322
308 if (i == (host->dma.num_ents - 1)) 323 /* Initialize sg dma address */
324 sg->dma_address = page_to_dma(mmc_dev(host->mmc), sg_page(sg))
325 + sg->offset;
326
327 if (i == (host->dma.num_ents - 1))
309 box->cmd |= CMD_LC; 328 box->cmd |= CMD_LC;
310 rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ? 329 rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ?
311 (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 : 330 (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 :
@@ -343,13 +362,68 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
343 host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST | 362 host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST |
344 DMOV_CMD_ADDR(host->dma.cmdptr_busaddr); 363 DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
345 host->dma.hdr.complete_func = msmsdcc_dma_complete_func; 364 host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
346 host->dma.hdr.execute_func = NULL;
347 365
366 n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
367 host->dma.num_ents, host->dma.dir);
368/* dsb inside dma_map_sg will write nc out to mem as well */
369
370 if (n != host->dma.num_ents) {
371 printk(KERN_ERR "%s: Unable to map in all sg elements\n",
372 mmc_hostname(host->mmc));
373 host->dma.sg = NULL;
374 host->dma.num_ents = 0;
375 return -ENOMEM;
376 }
377
378 return 0;
379}
380
381static int
382snoop_cccr_abort(struct mmc_command *cmd)
383{
384 if ((cmd->opcode == 52) &&
385 (cmd->arg & 0x80000000) &&
386 (((cmd->arg >> 9) & 0x1ffff) == SDIO_CCCR_ABORT))
387 return 1;
348 return 0; 388 return 0;
349} 389}
350 390
351static void 391static void
352msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) 392msmsdcc_start_command_deferred(struct msmsdcc_host *host,
393 struct mmc_command *cmd, u32 *c)
394{
395 *c |= (cmd->opcode | MCI_CPSM_ENABLE);
396
397 if (cmd->flags & MMC_RSP_PRESENT) {
398 if (cmd->flags & MMC_RSP_136)
399 *c |= MCI_CPSM_LONGRSP;
400 *c |= MCI_CPSM_RESPONSE;
401 }
402
403 if (/*interrupt*/0)
404 *c |= MCI_CPSM_INTERRUPT;
405
406 if ((((cmd->opcode == 17) || (cmd->opcode == 18)) ||
407 ((cmd->opcode == 24) || (cmd->opcode == 25))) ||
408 (cmd->opcode == 53))
409 *c |= MCI_CSPM_DATCMD;
410
411 if (cmd == cmd->mrq->stop)
412 *c |= MCI_CSPM_MCIABORT;
413
414 if (snoop_cccr_abort(cmd))
415 *c |= MCI_CSPM_MCIABORT;
416
417 if (host->curr.cmd != NULL) {
418 printk(KERN_ERR "%s: Overlapping command requests\n",
419 mmc_hostname(host->mmc));
420 }
421 host->curr.cmd = cmd;
422}
423
424static void
425msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
426 struct mmc_command *cmd, u32 c)
353{ 427{
354 unsigned int datactrl, timeout; 428 unsigned int datactrl, timeout;
355 unsigned long long clks; 429 unsigned long long clks;
@@ -364,13 +438,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data)
364 438
365 memset(&host->pio, 0, sizeof(host->pio)); 439 memset(&host->pio, 0, sizeof(host->pio));
366 440
367 clks = (unsigned long long)data->timeout_ns * host->clk_rate;
368 do_div(clks, NSEC_PER_SEC);
369 timeout = data->timeout_clks + (unsigned int)clks;
370 msmsdcc_writel(host, timeout, MMCIDATATIMER);
371
372 msmsdcc_writel(host, host->curr.xfer_size, MMCIDATALENGTH);
373
374 datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); 441 datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
375 442
376 if (!msmsdcc_config_dma(host, data)) 443 if (!msmsdcc_config_dma(host, data))
@@ -391,56 +458,51 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data)
391 if (data->flags & MMC_DATA_READ) 458 if (data->flags & MMC_DATA_READ)
392 datactrl |= MCI_DPSM_DIRECTION; 459 datactrl |= MCI_DPSM_DIRECTION;
393 460
394 msmsdcc_writel(host, pio_irqmask, MMCIMASK1); 461 clks = (unsigned long long)data->timeout_ns * host->clk_rate;
395 msmsdcc_writel(host, datactrl, MMCIDATACTRL); 462 do_div(clks, NSEC_PER_SEC);
463 timeout = data->timeout_clks + (unsigned int)clks*2 ;
396 464
397 if (datactrl & MCI_DPSM_DMAENABLE) { 465 if (datactrl & MCI_DPSM_DMAENABLE) {
466 /* Save parameters for the exec function */
467 host->cmd_timeout = timeout;
468 host->cmd_pio_irqmask = pio_irqmask;
469 host->cmd_datactrl = datactrl;
470 host->cmd_cmd = cmd;
471
472 host->dma.hdr.execute_func = msmsdcc_dma_exec_func;
473 host->dma.hdr.data = (void *)host;
398 host->dma.busy = 1; 474 host->dma.busy = 1;
475
476 if (cmd) {
477 msmsdcc_start_command_deferred(host, cmd, &c);
478 host->cmd_c = c;
479 }
399 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); 480 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr);
400 } 481 } else {
401} 482 msmsdcc_writel(host, timeout, MMCIDATATIMER);
402 483
403static int 484 msmsdcc_writel(host, host->curr.xfer_size, MMCIDATALENGTH);
404snoop_cccr_abort(struct mmc_command *cmd) 485
405{ 486 msmsdcc_writel(host, pio_irqmask, MMCIMASK1);
406 if ((cmd->opcode == 52) && 487 msmsdcc_writel(host, datactrl, MMCIDATACTRL);
407 (cmd->arg & 0x80000000) && 488
408 (((cmd->arg >> 9) & 0x1ffff) == SDIO_CCCR_ABORT)) 489 if (cmd) {
409 return 1; 490 /* Daisy-chain the command if requested */
410 return 0; 491 msmsdcc_start_command(host, cmd, c);
492 }
493 }
411} 494}
412 495
413static void 496static void
414msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) 497msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c)
415{ 498{
416 if (msmsdcc_readl(host, MMCICOMMAND) & MCI_CPSM_ENABLE)
417 msmsdcc_writel(host, 0, MMCICOMMAND);
418
419 c |= cmd->opcode | MCI_CPSM_ENABLE;
420
421 if (cmd->flags & MMC_RSP_PRESENT) {
422 if (cmd->flags & MMC_RSP_136)
423 c |= MCI_CPSM_LONGRSP;
424 c |= MCI_CPSM_RESPONSE;
425 }
426
427 if (cmd->opcode == 17 || cmd->opcode == 18 ||
428 cmd->opcode == 24 || cmd->opcode == 25 ||
429 cmd->opcode == 53)
430 c |= MCI_CSPM_DATCMD;
431
432 if (cmd == cmd->mrq->stop) 499 if (cmd == cmd->mrq->stop)
433 c |= MCI_CSPM_MCIABORT; 500 c |= MCI_CSPM_MCIABORT;
434 501
435 if (snoop_cccr_abort(cmd))
436 c |= MCI_CSPM_MCIABORT;
437
438 host->curr.cmd = cmd;
439
440 host->stats.cmds++; 502 host->stats.cmds++;
441 503
442 msmsdcc_writel(host, cmd->arg, MMCIARGUMENT); 504 msmsdcc_start_command_deferred(host, cmd, &c);
443 msmsdcc_writel(host, c, MMCICOMMAND); 505 msmsdcc_start_command_exec(host, cmd->arg, c);
444} 506}
445 507
446static void 508static void
@@ -611,7 +673,6 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
611 cmd->resp[2] = msmsdcc_readl(host, MMCIRESPONSE2); 673 cmd->resp[2] = msmsdcc_readl(host, MMCIRESPONSE2);
612 cmd->resp[3] = msmsdcc_readl(host, MMCIRESPONSE3); 674 cmd->resp[3] = msmsdcc_readl(host, MMCIRESPONSE3);
613 675
614 del_timer(&host->command_timer);
615 if (status & MCI_CMDTIMEOUT) { 676 if (status & MCI_CMDTIMEOUT) {
616 cmd->error = -ETIMEDOUT; 677 cmd->error = -ETIMEDOUT;
617 } else if (status & MCI_CMDCRCFAIL && 678 } else if (status & MCI_CMDCRCFAIL &&
@@ -629,16 +690,24 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
629 msmsdcc_request_end(host, cmd->mrq); 690 msmsdcc_request_end(host, cmd->mrq);
630 } else /* host->data == NULL */ 691 } else /* host->data == NULL */
631 msmsdcc_request_end(host, cmd->mrq); 692 msmsdcc_request_end(host, cmd->mrq);
632 } else if (!(cmd->data->flags & MMC_DATA_READ)) 693 } else if (cmd->data)
633 msmsdcc_start_data(host, cmd->data); 694 if (!(cmd->data->flags & MMC_DATA_READ))
695 msmsdcc_start_data(host, cmd->data,
696 NULL, 0);
634} 697}
635 698
636static void 699static void
637msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status, 700msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
638 void __iomem *base) 701 void __iomem *base)
639{ 702{
640 struct mmc_data *data = host->curr.data; 703 struct mmc_data *data;
641 704
705 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
706 MCI_CMDTIMEOUT) && host->curr.cmd) {
707 msmsdcc_do_cmdirq(host, status);
708 }
709
710 data = host->curr.data;
642 if (!data) 711 if (!data)
643 return; 712 return;
644 713
@@ -720,11 +789,6 @@ msmsdcc_irq(int irq, void *dev_id)
720 789
721 msmsdcc_handle_irq_data(host, status, base); 790 msmsdcc_handle_irq_data(host, status, base);
722 791
723 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
724 MCI_CMDTIMEOUT) && host->curr.cmd) {
725 msmsdcc_do_cmdirq(host, status);
726 }
727
728 if (status & MCI_SDIOINTOPER) { 792 if (status & MCI_SDIOINTOPER) {
729 cardint = 1; 793 cardint = 1;
730 status &= ~MCI_SDIOINTOPER; 794 status &= ~MCI_SDIOINTOPER;
@@ -775,9 +839,10 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
775 msmsdcc_enable_clocks(host, 1); 839 msmsdcc_enable_clocks(host, 1);
776 840
777 if (mrq->data && mrq->data->flags & MMC_DATA_READ) 841 if (mrq->data && mrq->data->flags & MMC_DATA_READ)
778 msmsdcc_start_data(host, mrq->data); 842 /* Queue/read data, daisy-chain command when data starts */
779 843 msmsdcc_start_data(host, mrq->data, mrq->cmd, 0);
780 msmsdcc_start_command(host, mrq->cmd, 0); 844 else
845 msmsdcc_start_command(host, mrq->cmd, 0);
781 846
782 if (host->cmdpoll && !msmsdcc_spin_on_status(host, 847 if (host->cmdpoll && !msmsdcc_spin_on_status(host,
783 MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT, 848 MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT,
@@ -790,7 +855,6 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
790 host->stats.cmdpoll_hits++; 855 host->stats.cmdpoll_hits++;
791 } else { 856 } else {
792 host->stats.cmdpoll_misses++; 857 host->stats.cmdpoll_misses++;
793 mod_timer(&host->command_timer, jiffies + HZ);
794 } 858 }
795 spin_unlock_irqrestore(&host->lock, flags); 859 spin_unlock_irqrestore(&host->lock, flags);
796} 860}
@@ -943,42 +1007,6 @@ msmsdcc_busclk_expired(unsigned long _data)
943 spin_unlock_irqrestore(&host->lock, flags); 1007 spin_unlock_irqrestore(&host->lock, flags);
944} 1008}
945 1009
946/*
947 * called when a command expires.
948 * Dump some debugging, and then error
949 * out the transaction.
950 */
951static void
952msmsdcc_command_expired(unsigned long _data)
953{
954 struct msmsdcc_host *host = (struct msmsdcc_host *) _data;
955 struct mmc_request *mrq;
956 unsigned long flags;
957
958 spin_lock_irqsave(&host->lock, flags);
959 mrq = host->curr.mrq;
960
961 if (!mrq) {
962 spin_unlock_irqrestore(&host->lock, flags);
963 return;
964 }
965
966 pr_err("%s: Controller lockup detected\n",
967 mmc_hostname(host->mmc));
968 mrq->cmd->error = -ETIMEDOUT;
969 msmsdcc_stop_data(host);
970
971 msmsdcc_writel(host, 0, MMCICOMMAND);
972
973 host->curr.mrq = NULL;
974 host->curr.cmd = NULL;
975
976 if (host->clks_on)
977 msmsdcc_enable_clocks(host, 0);
978 spin_unlock_irqrestore(&host->lock, flags);
979 mmc_request_done(host->mmc, mrq);
980}
981
982static int 1010static int
983msmsdcc_init_dma(struct msmsdcc_host *host) 1011msmsdcc_init_dma(struct msmsdcc_host *host)
984{ 1012{
@@ -1078,6 +1106,7 @@ msmsdcc_probe(struct platform_device *pdev)
1078 host->pdev_id = pdev->id; 1106 host->pdev_id = pdev->id;
1079 host->plat = plat; 1107 host->plat = plat;
1080 host->mmc = mmc; 1108 host->mmc = mmc;
1109 host->curr.cmd = NULL;
1081 1110
1082 host->cmdpoll = 1; 1111 host->cmdpoll = 1;
1083 1112
@@ -1194,14 +1223,6 @@ msmsdcc_probe(struct platform_device *pdev)
1194 host->eject = !host->oldstat; 1223 host->eject = !host->oldstat;
1195 } 1224 }
1196 1225
1197 /*
1198 * Setup a command timer. We currently need this due to
1199 * some 'strange' timeout / error handling situations.
1200 */
1201 init_timer(&host->command_timer);
1202 host->command_timer.data = (unsigned long) host;
1203 host->command_timer.function = msmsdcc_command_expired;
1204
1205 init_timer(&host->busclk_timer); 1226 init_timer(&host->busclk_timer);
1206 host->busclk_timer.data = (unsigned long) host; 1227 host->busclk_timer.data = (unsigned long) host;
1207 host->busclk_timer.function = msmsdcc_busclk_expired; 1228 host->busclk_timer.function = msmsdcc_busclk_expired;
@@ -1243,7 +1264,7 @@ msmsdcc_probe(struct platform_device *pdev)
1243 pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc)); 1264 pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc));
1244 1265
1245 if (host->use_bustimer) 1266 if (host->use_bustimer)
1246 mod_timer(&host->busclk_timer, jiffies + HZ); 1267 mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT);
1247 return 0; 1268 return 0;
1248 cmd_irq_free: 1269 cmd_irq_free:
1249 free_irq(cmd_irqres->start, host); 1270 free_irq(cmd_irqres->start, host);
@@ -1267,10 +1288,14 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state)
1267{ 1288{
1268 struct mmc_host *mmc = mmc_get_drvdata(dev); 1289 struct mmc_host *mmc = mmc_get_drvdata(dev);
1269 int rc = 0; 1290 int rc = 0;
1291 unsigned long flags;
1270 1292
1271 if (mmc) { 1293 if (mmc) {
1272 struct msmsdcc_host *host = mmc_priv(mmc); 1294 struct msmsdcc_host *host = mmc_priv(mmc);
1273 1295
1296 if (host->use_bustimer)
1297 del_timer_sync(&host->busclk_timer);
1298 spin_lock_irqsave(&host->lock, flags);
1274 if (host->stat_irq) 1299 if (host->stat_irq)
1275 disable_irq(host->stat_irq); 1300 disable_irq(host->stat_irq);
1276 1301
@@ -1282,6 +1307,7 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state)
1282 if (host->clks_on) 1307 if (host->clks_on)
1283 msmsdcc_enable_clocks(host, 0); 1308 msmsdcc_enable_clocks(host, 0);
1284 } 1309 }
1310 spin_unlock_irqrestore(&host->lock, flags);
1285 } 1311 }
1286 return rc; 1312 return rc;
1287} 1313}
@@ -1300,6 +1326,9 @@ msmsdcc_resume(struct platform_device *dev)
1300 if (!host->clks_on) 1326 if (!host->clks_on)
1301 msmsdcc_enable_clocks(host, 1); 1327 msmsdcc_enable_clocks(host, 1);
1302 1328
1329 if (host->use_bustimer)
1330 mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT);
1331
1303 msmsdcc_writel(host, host->saved_irq0mask, MMCIMASK0); 1332 msmsdcc_writel(host, host->saved_irq0mask, MMCIMASK0);
1304 1333
1305 spin_unlock_irqrestore(&host->lock, flags); 1334 spin_unlock_irqrestore(&host->lock, flags);