Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a89248a authored by Sahitya Tummala's avatar Sahitya Tummala Committed by David Brown
Browse files

mmc: msm_sdcc: Add gpio handling function to driver



Configure SDCC GPIOs when the host is powered up or powered off.

Signed-off-by: default avatarSahitya Tummala <stummala@codeaurora.org>
parent 727a99a5
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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
+39 −1
Original line number Diff line number Diff line
@@ -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)
+1 −0
Original line number Diff line number Diff line
@@ -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;