mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +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;
|
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 {
|
struct msm_mmc_platform_data {
|
||||||
unsigned int ocr_mask; /* available voltages */
|
unsigned int ocr_mask; /* available voltages */
|
||||||
u32 (*translate_vdd)(struct device *, unsigned int);
|
u32 (*translate_vdd)(struct device *, unsigned int);
|
||||||
unsigned int (*status)(struct device *);
|
unsigned int (*status)(struct device *);
|
||||||
struct embedded_sdio_data *embedded_sdio;
|
struct embedded_sdio_data *embedded_sdio;
|
||||||
int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
|
int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
|
||||||
|
struct msm_mmc_gpio_data *gpio_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/memory.h>
|
#include <linux/memory.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/div64.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);
|
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
|
static void
|
||||||
msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
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);
|
msmsdcc_enable_clocks(host);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&host->lock, flags);
|
||||||
|
|
||||||
if (ios->clock) {
|
if (ios->clock) {
|
||||||
if (ios->clock != host->clk_rate) {
|
if (ios->clock != host->clk_rate) {
|
||||||
rc = clk_set_rate(host->clk, ios->clock);
|
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) {
|
switch (ios->power_mode) {
|
||||||
case MMC_POWER_OFF:
|
case MMC_POWER_OFF:
|
||||||
|
msmsdcc_setup_gpio(host, false);
|
||||||
break;
|
break;
|
||||||
case MMC_POWER_UP:
|
case MMC_POWER_UP:
|
||||||
pwr |= MCI_PWR_UP;
|
pwr |= MCI_PWR_UP;
|
||||||
|
msmsdcc_setup_gpio(host, true);
|
||||||
break;
|
break;
|
||||||
case MMC_POWER_ON:
|
case MMC_POWER_ON:
|
||||||
pwr |= MCI_PWR_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);
|
msmsdcc_writel(host, pwr, MMCIPOWER);
|
||||||
}
|
}
|
||||||
#if BUSCLK_PWRSAVE
|
#if BUSCLK_PWRSAVE
|
||||||
|
spin_lock_irqsave(&host->lock, flags);
|
||||||
msmsdcc_disable_clocks(host, 1);
|
msmsdcc_disable_clocks(host, 1);
|
||||||
#endif
|
|
||||||
spin_unlock_irqrestore(&host->lock, flags);
|
spin_unlock_irqrestore(&host->lock, flags);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
|
static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
|
||||||
|
|
|
@ -243,6 +243,7 @@ struct msmsdcc_host {
|
||||||
unsigned int cmd_datactrl;
|
unsigned int cmd_datactrl;
|
||||||
struct mmc_command *cmd_cmd;
|
struct mmc_command *cmd_cmd;
|
||||||
u32 cmd_c;
|
u32 cmd_c;
|
||||||
|
bool gpio_config_status;
|
||||||
|
|
||||||
bool prog_scan;
|
bool prog_scan;
|
||||||
bool prog_enable;
|
bool prog_enable;
|
||||||
|
|
Loading…
Reference in a new issue