diff options
author | Sahitya Tummala <stummala@codeaurora.org> | 2011-01-18 00:52:49 -0500 |
---|---|---|
committer | David Brown <davidb@codeaurora.org> | 2011-01-21 19:58:00 -0500 |
commit | 7a89248a47d201e6ade2daddd79b0fd902cad400 (patch) | |
tree | 4c430c1e5a3ffc65022ce2c7ae39c42495166900 /drivers/mmc/host | |
parent | 727a99a576ba562e5074d54cfcc57a1ce101c240 (diff) |
mmc: msm_sdcc: Add gpio handling function to driver
Configure SDCC GPIOs when the host is powered up or powered off.
Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
Diffstat (limited to 'drivers/mmc/host')
-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 153ab977a01..97c9b3638d5 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 939557af266..42d7bbc977c 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; |