Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sahitya Tummala and committed by
David Brown
7a89248a 727a99a5

+51 -1
+11
arch/arm/mach-msm/include/mach/mmc.h
··· 15 15 int num_funcs; 16 16 }; 17 17 18 + struct msm_mmc_gpio { 19 + unsigned no; 20 + const char *name; 21 + }; 22 + 23 + struct msm_mmc_gpio_data { 24 + struct msm_mmc_gpio *gpio; 25 + u8 size; 26 + }; 27 + 18 28 struct msm_mmc_platform_data { 19 29 unsigned int ocr_mask; /* available voltages */ 20 30 u32 (*translate_vdd)(struct device *, unsigned int); 21 31 unsigned int (*status)(struct device *); 22 32 struct embedded_sdio_data *embedded_sdio; 23 33 int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id); 34 + struct msm_mmc_gpio_data *gpio_data; 24 35 }; 25 36 26 37 #endif
+39 -1
drivers/mmc/host/msm_sdcc.c
··· 36 36 #include <linux/io.h> 37 37 #include <linux/memory.h> 38 38 #include <linux/gfp.h> 39 + #include <linux/gpio.h> 39 40 40 41 #include <asm/cacheflush.h> 41 42 #include <asm/div64.h> ··· 942 941 spin_unlock_irqrestore(&host->lock, flags); 943 942 } 944 943 944 + static void msmsdcc_setup_gpio(struct msmsdcc_host *host, bool enable) 945 + { 946 + struct msm_mmc_gpio_data *curr; 947 + int i, rc = 0; 948 + 949 + if (!host->plat->gpio_data && host->gpio_config_status == enable) 950 + return; 951 + 952 + curr = host->plat->gpio_data; 953 + for (i = 0; i < curr->size; i++) { 954 + if (enable) { 955 + rc = gpio_request(curr->gpio[i].no, 956 + curr->gpio[i].name); 957 + if (rc) { 958 + pr_err("%s: gpio_request(%d, %s) failed %d\n", 959 + mmc_hostname(host->mmc), 960 + curr->gpio[i].no, 961 + curr->gpio[i].name, rc); 962 + goto free_gpios; 963 + } 964 + } else { 965 + gpio_free(curr->gpio[i].no); 966 + } 967 + } 968 + host->gpio_config_status = enable; 969 + return; 970 + 971 + free_gpios: 972 + for (; i >= 0; i--) 973 + gpio_free(curr->gpio[i].no); 974 + } 975 + 945 976 static void 946 977 msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 947 978 { ··· 985 952 spin_lock_irqsave(&host->lock, flags); 986 953 987 954 msmsdcc_enable_clocks(host); 955 + 956 + spin_unlock_irqrestore(&host->lock, flags); 988 957 989 958 if (ios->clock) { 990 959 if (ios->clock != host->clk_rate) { ··· 1014 979 1015 980 switch (ios->power_mode) { 1016 981 case MMC_POWER_OFF: 982 + msmsdcc_setup_gpio(host, false); 1017 983 break; 1018 984 case MMC_POWER_UP: 1019 985 pwr |= MCI_PWR_UP; 986 + msmsdcc_setup_gpio(host, true); 1020 987 break; 1021 988 case MMC_POWER_ON: 1022 989 pwr |= MCI_PWR_ON; ··· 1035 998 msmsdcc_writel(host, pwr, MMCIPOWER); 1036 999 } 1037 1000 #if BUSCLK_PWRSAVE 1001 + spin_lock_irqsave(&host->lock, flags); 1038 1002 msmsdcc_disable_clocks(host, 1); 1039 - #endif 1040 1003 spin_unlock_irqrestore(&host->lock, flags); 1004 + #endif 1041 1005 } 1042 1006 1043 1007 static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+1
drivers/mmc/host/msm_sdcc.h
··· 243 243 unsigned int cmd_datactrl; 244 244 struct mmc_command *cmd_cmd; 245 245 u32 cmd_c; 246 + bool gpio_config_status; 246 247 247 248 bool prog_scan; 248 249 bool prog_enable;