aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Brown <davidb@codeaurora.org>2011-01-24 18:42:46 -0500
committerDavid Brown <davidb@codeaurora.org>2011-01-24 18:42:46 -0500
commit14847fdf3598109384e590a4154010f2ece6bb96 (patch)
tree613391138f0ec4c798befa7f7ea7f0479b71ec23 /drivers
parent75b0d32d5c0acd9b28f447aeddde5e94e5d64e5d (diff)
parent8b4d95fc76b85696c508f316810a6fbc15a7b8c5 (diff)
Merge branch 'msm-sdcc' into for-next
* msm-sdcc: msm: 8x50: Add initial support for SDCC mmc: msm_sdcc: Add gpio handling function to driver drivers: mmc: msm: remove clock disable in probe mmc: msm: fix dma usage not to use internal APIs
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/msm_sdcc.c92
-rw-r--r--drivers/mmc/host/msm_sdcc.h1
2 files changed, 62 insertions, 31 deletions
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 5decfd0bd61d..97c9b3638d57 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -36,6 +36,7 @@
36#include <linux/io.h> 36#include <linux/io.h>
37#include <linux/memory.h> 37#include <linux/memory.h>
38#include <linux/gfp.h> 38#include <linux/gfp.h>
39#include <linux/gpio.h>
39 40
40#include <asm/cacheflush.h> 41#include <asm/cacheflush.h>
41#include <asm/div64.h> 42#include <asm/div64.h>
@@ -383,14 +384,30 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
383 host->curr.user_pages = 0; 384 host->curr.user_pages = 0;
384 385
385 box = &nc->cmd[0]; 386 box = &nc->cmd[0];
386 for (i = 0; i < host->dma.num_ents; i++) {
387 box->cmd = CMD_MODE_BOX;
388 387
389 /* Initialize sg dma address */ 388 /* location of command block must be 64 bit aligned */
390 sg->dma_address = page_to_dma(mmc_dev(host->mmc), sg_page(sg)) 389 BUG_ON(host->dma.cmd_busaddr & 0x07);
391 + sg->offset; 390
391 nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP;
392 host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST |
393 DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
394 host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
392 395
393 if (i == (host->dma.num_ents - 1)) 396 n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
397 host->dma.num_ents, host->dma.dir);
398 if (n == 0) {
399 printk(KERN_ERR "%s: Unable to map in all sg elements\n",
400 mmc_hostname(host->mmc));
401 host->dma.sg = NULL;
402 host->dma.num_ents = 0;
403 return -ENOMEM;
404 }
405
406 for_each_sg(host->dma.sg, sg, n, i) {
407
408 box->cmd = CMD_MODE_BOX;
409
410 if (i == n - 1)
394 box->cmd |= CMD_LC; 411 box->cmd |= CMD_LC;
395 rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ? 412 rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ?
396 (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 : 413 (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 :
@@ -418,27 +435,6 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
418 box->cmd |= CMD_DST_CRCI(crci); 435 box->cmd |= CMD_DST_CRCI(crci);
419 } 436 }
420 box++; 437 box++;
421 sg++;
422 }
423
424 /* location of command block must be 64 bit aligned */
425 BUG_ON(host->dma.cmd_busaddr & 0x07);
426
427 nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP;
428 host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST |
429 DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
430 host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
431
432 n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
433 host->dma.num_ents, host->dma.dir);
434/* dsb inside dma_map_sg will write nc out to mem as well */
435
436 if (n != host->dma.num_ents) {
437 printk(KERN_ERR "%s: Unable to map in all sg elements\n",
438 mmc_hostname(host->mmc));
439 host->dma.sg = NULL;
440 host->dma.num_ents = 0;
441 return -ENOMEM;
442 } 438 }
443 439
444 return 0; 440 return 0;
@@ -946,6 +942,38 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
946 spin_unlock_irqrestore(&host->lock, flags); 942 spin_unlock_irqrestore(&host->lock, flags);
947} 943}
948 944
945static void msmsdcc_setup_gpio(struct msmsdcc_host *host, bool enable)
946{
947 struct msm_mmc_gpio_data *curr;
948 int i, rc = 0;
949
950 if (!host->plat->gpio_data && host->gpio_config_status == enable)
951 return;
952
953 curr = host->plat->gpio_data;
954 for (i = 0; i < curr->size; i++) {
955 if (enable) {
956 rc = gpio_request(curr->gpio[i].no,
957 curr->gpio[i].name);
958 if (rc) {
959 pr_err("%s: gpio_request(%d, %s) failed %d\n",
960 mmc_hostname(host->mmc),
961 curr->gpio[i].no,
962 curr->gpio[i].name, rc);
963 goto free_gpios;
964 }
965 } else {
966 gpio_free(curr->gpio[i].no);
967 }
968 }
969 host->gpio_config_status = enable;
970 return;
971
972free_gpios:
973 for (; i >= 0; i--)
974 gpio_free(curr->gpio[i].no);
975}
976
949static void 977static void
950msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 978msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
951{ 979{
@@ -958,6 +986,8 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
958 986
959 msmsdcc_enable_clocks(host); 987 msmsdcc_enable_clocks(host);
960 988
989 spin_unlock_irqrestore(&host->lock, flags);
990
961 if (ios->clock) { 991 if (ios->clock) {
962 if (ios->clock != host->clk_rate) { 992 if (ios->clock != host->clk_rate) {
963 rc = clk_set_rate(host->clk, ios->clock); 993 rc = clk_set_rate(host->clk, ios->clock);
@@ -984,9 +1014,11 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
984 1014
985 switch (ios->power_mode) { 1015 switch (ios->power_mode) {
986 case MMC_POWER_OFF: 1016 case MMC_POWER_OFF:
1017 msmsdcc_setup_gpio(host, false);
987 break; 1018 break;
988 case MMC_POWER_UP: 1019 case MMC_POWER_UP:
989 pwr |= MCI_PWR_UP; 1020 pwr |= MCI_PWR_UP;
1021 msmsdcc_setup_gpio(host, true);
990 break; 1022 break;
991 case MMC_POWER_ON: 1023 case MMC_POWER_ON:
992 pwr |= MCI_PWR_ON; 1024 pwr |= MCI_PWR_ON;
@@ -1003,9 +1035,10 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1003 msmsdcc_writel(host, pwr, MMCIPOWER); 1035 msmsdcc_writel(host, pwr, MMCIPOWER);
1004 } 1036 }
1005#if BUSCLK_PWRSAVE 1037#if BUSCLK_PWRSAVE
1038 spin_lock_irqsave(&host->lock, flags);
1006 msmsdcc_disable_clocks(host, 1); 1039 msmsdcc_disable_clocks(host, 1);
1007#endif
1008 spin_unlock_irqrestore(&host->lock, flags); 1040 spin_unlock_irqrestore(&host->lock, flags);
1041#endif
1009} 1042}
1010 1043
1011static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable) 1044static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
@@ -1331,9 +1364,6 @@ msmsdcc_probe(struct platform_device *pdev)
1331 if (host->timer.function) 1364 if (host->timer.function)
1332 pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc)); 1365 pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc));
1333 1366
1334#if BUSCLK_PWRSAVE
1335 msmsdcc_disable_clocks(host, 1);
1336#endif
1337 return 0; 1367 return 0;
1338 cmd_irq_free: 1368 cmd_irq_free:
1339 free_irq(cmd_irqres->start, host); 1369 free_irq(cmd_irqres->start, host);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 939557af266d..42d7bbc977c5 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -243,6 +243,7 @@ struct msmsdcc_host {
243 unsigned int cmd_datactrl; 243 unsigned int cmd_datactrl;
244 struct mmc_command *cmd_cmd; 244 struct mmc_command *cmd_cmd;
245 u32 cmd_c; 245 u32 cmd_c;
246 bool gpio_config_status;
246 247
247 bool prog_scan; 248 bool prog_scan;
248 bool prog_enable; 249 bool prog_enable;