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

Commit 8c102a96 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Chris Ball
Browse files

mmc: tmio: add callbacks to enable-update and disable the interface clock



Every time the clock is enabled after possibly being disabled, we have
to re-read its frequency and update our configuration.

Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent e0337cc8
Loading
Loading
Loading
Loading
+32 −3
Original line number Diff line number Diff line
@@ -752,6 +752,22 @@ static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
	mmc_request_done(mmc, mrq);
}

static int tmio_mmc_clk_update(struct mmc_host *mmc)
{
	struct tmio_mmc_host *host = mmc_priv(mmc);
	struct tmio_mmc_data *pdata = host->pdata;
	int ret;

	if (!pdata->clk_enable)
		return -ENOTSUPP;

	ret = pdata->clk_enable(host->pdev, &mmc->f_max);
	if (!ret)
		mmc->f_min = mmc->f_max / 512;

	return ret;
}

/* Set MMC clock / power.
 * Note: This controller uses a simple divider scheme therefore it cannot
 * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
@@ -798,6 +814,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
	 */
	if (ios->power_mode == MMC_POWER_ON && ios->clock) {
		if (!host->power) {
			tmio_mmc_clk_update(mmc);
			pm_runtime_get_sync(dev);
			host->power = true;
		}
@@ -811,9 +828,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
		if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
			host->set_pwr(host->pdev, 0);
		if (host->power) {
			struct tmio_mmc_data *pdata = host->pdata;
			tmio_mmc_clk_stop(host);
			host->power = false;
			pm_runtime_put(dev);
			if (pdata->clk_disable)
				pdata->clk_disable(host->pdev);
		}
	}

@@ -907,8 +927,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,

	mmc->ops = &tmio_mmc_ops;
	mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
	mmc->f_max = pdata->hclk;
	mmc->f_min = mmc->f_max / 512;
	mmc->max_segs = 32;
	mmc->max_blk_size = 512;
	mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
@@ -930,6 +948,11 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
	if (ret < 0)
		goto pm_disable;

	if (tmio_mmc_clk_update(mmc) < 0) {
		mmc->f_max = pdata->hclk;
		mmc->f_min = mmc->f_max / 512;
	}

	/*
	 * There are 4 different scenarios for the card detection:
	 *  1) an external gpio irq handles the cd (best for power savings)
@@ -975,7 +998,13 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
	/* See if we also get DMA */
	tmio_mmc_request_dma(_host, pdata);

	mmc_add_host(mmc);
	ret = mmc_add_host(mmc);
	if (pdata->clk_disable)
		pdata->clk_disable(pdev);
	if (ret < 0) {
		tmio_mmc_host_remove(_host);
		return ret;
	}

	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);

+3 −0
Original line number Diff line number Diff line
@@ -110,6 +110,9 @@ struct tmio_mmc_data {
	void (*set_clk_div)(struct platform_device *host, int state);
	int (*get_cd)(struct platform_device *host);
	int (*write16_hook)(struct tmio_mmc_host *host, int addr);
	/* clock management callbacks */
	int (*clk_enable)(struct platform_device *pdev, unsigned int *f);
	void (*clk_disable)(struct platform_device *pdev);
};

/*