diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 22:13:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 22:13:18 -0400 |
commit | 6899608533410557e6698cb9d4ff6df553916e98 (patch) | |
tree | b392548a6757d08ec7b1395925499e032c174411 /drivers/mmc | |
parent | 411f5c7a502769ccc0377c5ba36cb0b283847ba8 (diff) | |
parent | 92c260f755c42337c550d8ac1f8ccd1b32bffb20 (diff) |
Merge branch 'for-linus' of git://codeaurora.org/quic/kernel/davidb/linux-msm
* 'for-linus' of git://codeaurora.org/quic/kernel/davidb/linux-msm: (46 commits)
msm: scm: Check for interruption immediately
msm: scm: Fix improper register assignment
msm: scm: Mark inline asm as volatile
msm: iommu: Enable HTW L2 redirection on MSM8960
msm: iommu: Don't read from write-only registers
msm: iommu: Remove dependency on IDR
msm: iommu: Use ASID tagging instead of VMID tagging
msm: iommu: Rework clock logic and add IOMMU bus clock control
msm: iommu: Clock control for the IOMMU driver
msm: mdp: Set the correct pack pattern for XRGB/ARGB
msm_fb: Fix framebuffer console
msm: mdp: Add support for RGBX 8888 image format.
video: msmfb: Put the partial update magic value into the fix_screen struct.
msm: clock: Migrate to clkdev
msm: clock: Remove references to clk_ops_pcom
msm: headsmp.S: Fix section mismatch
msm: Use explicit GPLv2 licenses
msm: iommu: Enable IOMMU support for MSM8960
msm: iommu: Generalize platform data for multiple targets
msm: iommu: Create a Kconfig item for the IOMMU driver
...
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/msm_sdcc.c | 40 | ||||
-rw-r--r-- | drivers/mmc/host/msm_sdcc.h | 1 |
2 files changed, 40 insertions, 1 deletions
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 153ab977a013..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> |
@@ -941,6 +942,38 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
941 | spin_unlock_irqrestore(&host->lock, flags); | 942 | spin_unlock_irqrestore(&host->lock, flags); |
942 | } | 943 | } |
943 | 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 | |||
944 | static void | 977 | static void |
945 | msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 978 | msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
946 | { | 979 | { |
@@ -953,6 +986,8 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
953 | 986 | ||
954 | msmsdcc_enable_clocks(host); | 987 | msmsdcc_enable_clocks(host); |
955 | 988 | ||
989 | spin_unlock_irqrestore(&host->lock, flags); | ||
990 | |||
956 | if (ios->clock) { | 991 | if (ios->clock) { |
957 | if (ios->clock != host->clk_rate) { | 992 | if (ios->clock != host->clk_rate) { |
958 | rc = clk_set_rate(host->clk, ios->clock); | 993 | rc = clk_set_rate(host->clk, ios->clock); |
@@ -979,9 +1014,11 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
979 | 1014 | ||
980 | switch (ios->power_mode) { | 1015 | switch (ios->power_mode) { |
981 | case MMC_POWER_OFF: | 1016 | case MMC_POWER_OFF: |
1017 | msmsdcc_setup_gpio(host, false); | ||
982 | break; | 1018 | break; |
983 | case MMC_POWER_UP: | 1019 | case MMC_POWER_UP: |
984 | pwr |= MCI_PWR_UP; | 1020 | pwr |= MCI_PWR_UP; |
1021 | msmsdcc_setup_gpio(host, true); | ||
985 | break; | 1022 | break; |
986 | case MMC_POWER_ON: | 1023 | case MMC_POWER_ON: |
987 | pwr |= MCI_PWR_ON; | 1024 | pwr |= MCI_PWR_ON; |
@@ -998,9 +1035,10 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
998 | msmsdcc_writel(host, pwr, MMCIPOWER); | 1035 | msmsdcc_writel(host, pwr, MMCIPOWER); |
999 | } | 1036 | } |
1000 | #if BUSCLK_PWRSAVE | 1037 | #if BUSCLK_PWRSAVE |
1038 | spin_lock_irqsave(&host->lock, flags); | ||
1001 | msmsdcc_disable_clocks(host, 1); | 1039 | msmsdcc_disable_clocks(host, 1); |
1002 | #endif | ||
1003 | spin_unlock_irqrestore(&host->lock, flags); | 1040 | spin_unlock_irqrestore(&host->lock, flags); |
1041 | #endif | ||
1004 | } | 1042 | } |
1005 | 1043 | ||
1006 | 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) |
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; |