diff options
author | David Brown <davidb@codeaurora.org> | 2011-01-24 18:42:46 -0500 |
---|---|---|
committer | David Brown <davidb@codeaurora.org> | 2011-01-24 18:42:46 -0500 |
commit | 14847fdf3598109384e590a4154010f2ece6bb96 (patch) | |
tree | 613391138f0ec4c798befa7f7ea7f0479b71ec23 /drivers | |
parent | 75b0d32d5c0acd9b28f447aeddde5e94e5d64e5d (diff) | |
parent | 8b4d95fc76b85696c508f316810a6fbc15a7b8c5 (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.c | 92 | ||||
-rw-r--r-- | drivers/mmc/host/msm_sdcc.h | 1 |
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 | ||
945 | static 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 | |||
972 | free_gpios: | ||
973 | for (; i >= 0; i--) | ||
974 | gpio_free(curr->gpio[i].no); | ||
975 | } | ||
976 | |||
949 | static void | 977 | static void |
950 | msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 978 | msmsdcc_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 | ||
1011 | static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable) | 1044 | static 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; |