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

Commit 9eadcc05 authored by Ulf Hansson's avatar Ulf Hansson
Browse files

mmc: core: Remove MMC_CLKGATE



MMC_CLKGATE was once invented to save power by gating the bus clock at
request inactivity. At that time it served its purpose. The modern way to
deal with power saving for these scenarios, is by using runtime PM.

Nowadays, several host drivers have deployed runtime PM, but for those
that haven't and which still cares power saving at request inactivity,
it's certainly time to deploy runtime PM as it has been around for several
years now.

To simplify code to mmc core and thus decrease maintenance efforts, this
patch removes all code related to MMC_CLKGATE.

Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent a22950c8
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -72,13 +72,3 @@ Note on raw_rpmb_size_mult:
	"raw_rpmb_size_mult" is a mutliple of 128kB block.
	RPMB size in byte is calculated by using the following equation:
	RPMB partition size = 128kB x raw_rpmb_size_mult

SD/MMC/SDIO Clock Gating Attribute
==================================

Read and write access is provided to following attribute.
This attribute appears only if CONFIG_MMC_CLKGATE is enabled.

	clkgate_delay	Tune the clock gating delay with desired value in milliseconds.

echo <desired delay> > /sys/class/mmc_host/mmcX/clkgate_delay
+0 −10
Original line number Diff line number Diff line
#
# MMC core configuration
#

config MMC_CLKGATE
	bool "MMC host clock gating"
	help
	  This will attempt to aggressively gate the clock to the MMC card.
	  This is done to save power due to gating off the logic and bus
	  noise when the MMC card is not in use. Your host driver has to
	  support handling this in order for it to be of any use.

	  If unsure, say N.
+15 −124
Original line number Diff line number Diff line
@@ -187,8 +187,6 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)

		if (mrq->done)
			mrq->done(mrq);

		mmc_host_clk_release(host);
	}
}

@@ -292,7 +290,6 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
			mrq->stop->mrq = mrq;
		}
	}
	mmc_host_clk_hold(host);
	led_trigger_event(host->led, LED_FULL);
	__mmc_start_request(host, mrq);

@@ -542,11 +539,8 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
		 bool is_first_req)
{
	if (host->ops->pre_req) {
		mmc_host_clk_hold(host);
	if (host->ops->pre_req)
		host->ops->pre_req(host, mrq, is_first_req);
		mmc_host_clk_release(host);
	}
}

/**
@@ -561,11 +555,8 @@ static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
			 int err)
{
	if (host->ops->post_req) {
		mmc_host_clk_hold(host);
	if (host->ops->post_req)
		host->ops->post_req(host, mrq, err);
		mmc_host_clk_release(host);
	}
}

/**
@@ -850,9 +841,9 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
		unsigned int timeout_us, limit_us;

		timeout_us = data->timeout_ns / 1000;
		if (mmc_host_clk_rate(card->host))
		if (card->host->ios.clock)
			timeout_us += data->timeout_clks * 1000 /
				(mmc_host_clk_rate(card->host) / 1000);
				(card->host->ios.clock / 1000);

		if (data->flags & MMC_DATA_WRITE)
			/*
@@ -1050,8 +1041,6 @@ static inline void mmc_set_ios(struct mmc_host *host)
		 ios->power_mode, ios->chip_select, ios->vdd,
		 ios->bus_width, ios->timing);

	if (ios->clock > 0)
		mmc_set_ungated(host);
	host->ops->set_ios(host, ios);
}

@@ -1060,17 +1049,15 @@ static inline void mmc_set_ios(struct mmc_host *host)
 */
void mmc_set_chip_select(struct mmc_host *host, int mode)
{
	mmc_host_clk_hold(host);
	host->ios.chip_select = mode;
	mmc_set_ios(host);
	mmc_host_clk_release(host);
}

/*
 * Sets the host clock to the highest possible frequency that
 * is below "hz".
 */
static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)
void mmc_set_clock(struct mmc_host *host, unsigned int hz)
{
	WARN_ON(hz && hz < host->f_min);

@@ -1081,68 +1068,6 @@ static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)
	mmc_set_ios(host);
}

void mmc_set_clock(struct mmc_host *host, unsigned int hz)
{
	mmc_host_clk_hold(host);
	__mmc_set_clock(host, hz);
	mmc_host_clk_release(host);
}

#ifdef CONFIG_MMC_CLKGATE
/*
 * This gates the clock by setting it to 0 Hz.
 */
void mmc_gate_clock(struct mmc_host *host)
{
	unsigned long flags;

	spin_lock_irqsave(&host->clk_lock, flags);
	host->clk_old = host->ios.clock;
	host->ios.clock = 0;
	host->clk_gated = true;
	spin_unlock_irqrestore(&host->clk_lock, flags);
	mmc_set_ios(host);
}

/*
 * This restores the clock from gating by using the cached
 * clock value.
 */
void mmc_ungate_clock(struct mmc_host *host)
{
	/*
	 * We should previously have gated the clock, so the clock shall
	 * be 0 here! The clock may however be 0 during initialization,
	 * when some request operations are performed before setting
	 * the frequency. When ungate is requested in that situation
	 * we just ignore the call.
	 */
	if (host->clk_old) {
		BUG_ON(host->ios.clock);
		/* This call will also set host->clk_gated to false */
		__mmc_set_clock(host, host->clk_old);
	}
}

void mmc_set_ungated(struct mmc_host *host)
{
	unsigned long flags;

	/*
	 * We've been given a new frequency while the clock is gated,
	 * so make sure we regard this as ungating it.
	 */
	spin_lock_irqsave(&host->clk_lock, flags);
	host->clk_gated = false;
	spin_unlock_irqrestore(&host->clk_lock, flags);
}

#else
void mmc_set_ungated(struct mmc_host *host)
{
}
#endif

int mmc_execute_tuning(struct mmc_card *card)
{
	struct mmc_host *host = card->host;
@@ -1157,9 +1082,7 @@ int mmc_execute_tuning(struct mmc_card *card)
	else
		opcode = MMC_SEND_TUNING_BLOCK;

	mmc_host_clk_hold(host);
	err = host->ops->execute_tuning(host, opcode);
	mmc_host_clk_release(host);

	if (err)
		pr_err("%s: tuning execution failed\n", mmc_hostname(host));
@@ -1174,10 +1097,8 @@ int mmc_execute_tuning(struct mmc_card *card)
 */
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
{
	mmc_host_clk_hold(host);
	host->ios.bus_mode = mode;
	mmc_set_ios(host);
	mmc_host_clk_release(host);
}

/*
@@ -1185,10 +1106,8 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
 */
void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
{
	mmc_host_clk_hold(host);
	host->ios.bus_width = width;
	mmc_set_ios(host);
	mmc_host_clk_release(host);
}

/*
@@ -1532,11 +1451,8 @@ int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
	int old_signal_voltage = host->ios.signal_voltage;

	host->ios.signal_voltage = signal_voltage;
	if (host->ops->start_signal_voltage_switch) {
		mmc_host_clk_hold(host);
	if (host->ops->start_signal_voltage_switch)
		err = host->ops->start_signal_voltage_switch(host, &host->ios);
		mmc_host_clk_release(host);
	}

	if (err)
		host->ios.signal_voltage = old_signal_voltage;
@@ -1570,20 +1486,17 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr)
		pr_warn("%s: cannot verify signal voltage switch\n",
			mmc_hostname(host));

	mmc_host_clk_hold(host);

	cmd.opcode = SD_SWITCH_VOLTAGE;
	cmd.arg = 0;
	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;

	err = mmc_wait_for_cmd(host, &cmd, 0);
	if (err)
		goto err_command;
		return err;

	if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
		return -EIO;

	if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) {
		err = -EIO;
		goto err_command;
	}
	/*
	 * The card should drive cmd and dat[0:3] low immediately
	 * after the response of cmd11, but wait 1 ms to be sure
@@ -1632,9 +1545,6 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr)
		mmc_power_cycle(host, ocr);
	}

err_command:
	mmc_host_clk_release(host);

	return err;
}

@@ -1643,10 +1553,8 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr)
 */
void mmc_set_timing(struct mmc_host *host, unsigned int timing)
{
	mmc_host_clk_hold(host);
	host->ios.timing = timing;
	mmc_set_ios(host);
	mmc_host_clk_release(host);
}

/*
@@ -1654,10 +1562,8 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
 */
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
{
	mmc_host_clk_hold(host);
	host->ios.drv_type = drv_type;
	mmc_set_ios(host);
	mmc_host_clk_release(host);
}

int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
@@ -1665,7 +1571,6 @@ int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
{
	struct mmc_host *host = card->host;
	int host_drv_type = SD_DRIVER_TYPE_B;
	int drive_strength;

	*drv_type = 0;

@@ -1688,14 +1593,10 @@ int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
	 * information and let the hardware specific code
	 * return what is possible given the options
	 */
	mmc_host_clk_hold(host);
	drive_strength = host->ops->select_drive_strength(card, max_dtr,
	return host->ops->select_drive_strength(card, max_dtr,
						host_drv_type,
						card_drv_type,
						drv_type);
	mmc_host_clk_release(host);

	return drive_strength;
}

/*
@@ -1714,8 +1615,6 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
	if (host->ios.power_mode == MMC_POWER_ON)
		return;

	mmc_host_clk_hold(host);

	mmc_pwrseq_pre_power_on(host);

	host->ios.vdd = fls(ocr) - 1;
@@ -1749,8 +1648,6 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
	 * time required to reach a stable voltage.
	 */
	mmc_delay(10);

	mmc_host_clk_release(host);
}

void mmc_power_off(struct mmc_host *host)
@@ -1758,8 +1655,6 @@ void mmc_power_off(struct mmc_host *host)
	if (host->ios.power_mode == MMC_POWER_OFF)
		return;

	mmc_host_clk_hold(host);

	mmc_pwrseq_power_off(host);

	host->ios.clock = 0;
@@ -1775,8 +1670,6 @@ void mmc_power_off(struct mmc_host *host)
	 * can be successfully turned on again.
	 */
	mmc_delay(1);

	mmc_host_clk_release(host);
}

void mmc_power_cycle(struct mmc_host *host, u32 ocr)
@@ -1992,7 +1885,7 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
		 */
		timeout_clks <<= 1;
		timeout_us += (timeout_clks * 1000) /
			      (mmc_host_clk_rate(card->host) / 1000);
			      (card->host->ios.clock / 1000);

		erase_timeout = timeout_us / 1000;

@@ -2440,9 +2333,7 @@ static void mmc_hw_reset_for_init(struct mmc_host *host)
{
	if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
		return;
	mmc_host_clk_hold(host);
	host->ops->hw_reset(host);
	mmc_host_clk_release(host);
}

int mmc_hw_reset(struct mmc_host *host)
+0 −3
Original line number Diff line number Diff line
@@ -40,9 +40,6 @@ void mmc_init_erase(struct mmc_card *card);

void mmc_set_chip_select(struct mmc_host *host, int mode);
void mmc_set_clock(struct mmc_host *host, unsigned int hz);
void mmc_gate_clock(struct mmc_host *host);
void mmc_ungate_clock(struct mmc_host *host);
void mmc_set_ungated(struct mmc_host *host);
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
+0 −5
Original line number Diff line number Diff line
@@ -255,11 +255,6 @@ void mmc_add_host_debugfs(struct mmc_host *host)
			&mmc_clock_fops))
		goto err_node;

#ifdef CONFIG_MMC_CLKGATE
	if (!debugfs_create_u32("clk_delay", (S_IRUSR | S_IWUSR),
				root, &host->clk_delay))
		goto err_node;
#endif
#ifdef CONFIG_FAIL_MMC_REQUEST
	if (fail_request)
		setup_fault_attr(&fail_default_attr, fail_request);
Loading