mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
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>
This commit is contained in:
parent
727a99a576
commit
7a89248a47
3 changed files with 51 additions and 1 deletions
|
@ -15,12 +15,23 @@ struct embedded_sdio_data {
|
|||
int num_funcs;
|
||||
};
|
||||
|
||||
struct msm_mmc_gpio {
|
||||
unsigned no;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct msm_mmc_gpio_data {
|
||||
struct msm_mmc_gpio *gpio;
|
||||
u8 size;
|
||||
};
|
||||
|
||||
struct msm_mmc_platform_data {
|
||||
unsigned int ocr_mask; /* available voltages */
|
||||
u32 (*translate_vdd)(struct device *, unsigned int);
|
||||
unsigned int (*status)(struct device *);
|
||||
struct embedded_sdio_data *embedded_sdio;
|
||||
int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
|
||||
struct msm_mmc_gpio_data *gpio_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/div64.h>
|
||||
|
@ -941,6 +942,38 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
static void msmsdcc_setup_gpio(struct msmsdcc_host *host, bool enable)
|
||||
{
|
||||
struct msm_mmc_gpio_data *curr;
|
||||
int i, rc = 0;
|
||||
|
||||
if (!host->plat->gpio_data && host->gpio_config_status == enable)
|
||||
return;
|
||||
|
||||
curr = host->plat->gpio_data;
|
||||
for (i = 0; i < curr->size; i++) {
|
||||
if (enable) {
|
||||
rc = gpio_request(curr->gpio[i].no,
|
||||
curr->gpio[i].name);
|
||||
if (rc) {
|
||||
pr_err("%s: gpio_request(%d, %s) failed %d\n",
|
||||
mmc_hostname(host->mmc),
|
||||
curr->gpio[i].no,
|
||||
curr->gpio[i].name, rc);
|
||||
goto free_gpios;
|
||||
}
|
||||
} else {
|
||||
gpio_free(curr->gpio[i].no);
|
||||
}
|
||||
}
|
||||
host->gpio_config_status = enable;
|
||||
return;
|
||||
|
||||
free_gpios:
|
||||
for (; i >= 0; i--)
|
||||
gpio_free(curr->gpio[i].no);
|
||||
}
|
||||
|
||||
static void
|
||||
msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
{
|
||||
|
@ -953,6 +986,8 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|||
|
||||
msmsdcc_enable_clocks(host);
|
||||
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
if (ios->clock) {
|
||||
if (ios->clock != host->clk_rate) {
|
||||
rc = clk_set_rate(host->clk, ios->clock);
|
||||
|
@ -979,9 +1014,11 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|||
|
||||
switch (ios->power_mode) {
|
||||
case MMC_POWER_OFF:
|
||||
msmsdcc_setup_gpio(host, false);
|
||||
break;
|
||||
case MMC_POWER_UP:
|
||||
pwr |= MCI_PWR_UP;
|
||||
msmsdcc_setup_gpio(host, true);
|
||||
break;
|
||||
case MMC_POWER_ON:
|
||||
pwr |= MCI_PWR_ON;
|
||||
|
@ -998,9 +1035,10 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|||
msmsdcc_writel(host, pwr, MMCIPOWER);
|
||||
}
|
||||
#if BUSCLK_PWRSAVE
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
msmsdcc_disable_clocks(host, 1);
|
||||
#endif
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
|
||||
|
|
|
@ -243,6 +243,7 @@ struct msmsdcc_host {
|
|||
unsigned int cmd_datactrl;
|
||||
struct mmc_command *cmd_cmd;
|
||||
u32 cmd_c;
|
||||
bool gpio_config_status;
|
||||
|
||||
bool prog_scan;
|
||||
bool prog_enable;
|
||||
|
|
Loading…
Reference in a new issue