On 2 October 2015 at 10:56, Ulf Hansson <[email protected]> wrote:
> 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: Ulf Hansson <[email protected]>
I have queued this up for next to get some testing in linux-next and
kernelci. Still, it's not too late to provide input to the patch.
Kind regards
Uffe
> ---
> Documentation/mmc/mmc-dev-attrs.txt | 10 --
> drivers/mmc/core/Kconfig | 10 --
> drivers/mmc/core/core.c | 139 +++-----------------
> drivers/mmc/core/core.h | 3 -
> drivers/mmc/core/debugfs.c | 5 -
> drivers/mmc/core/host.c | 245
> ------------------------------------
> drivers/mmc/core/mmc.c | 6 +-
> drivers/mmc/core/quirks.c | 18 ---
> drivers/mmc/core/sd.c | 2 -
> drivers/mmc/core/sdio.c | 7 +-
> drivers/mmc/core/sdio_irq.c | 14 +--
> include/linux/mmc/card.h | 1 -
> include/linux/mmc/host.h | 32 -----
> 13 files changed, 20 insertions(+), 472 deletions(-)
>
> diff --git a/Documentation/mmc/mmc-dev-attrs.txt
> b/Documentation/mmc/mmc-dev-attrs.txt
> index 189bab0..caa5557 100644
> --- a/Documentation/mmc/mmc-dev-attrs.txt
> +++ b/Documentation/mmc/mmc-dev-attrs.txt
> @@ -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
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index 9ebee72..4c33d76 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -1,13 +1,3 @@
> #
> # 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.
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 21cda23..1a36b02 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -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 @@ power_cycle:
> mmc_power_cycle(host, ocr);
> }
>
> -err_command:
> - mmc_host_clk_release(host);
> -
> return err;
> }
>
> @@ -1643,10 +1553,8 @@ err_command:
> */
> 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,
> - host_drv_type,
> - card_drv_type,
> - drv_type);
> - mmc_host_clk_release(host);
> -
> - return drive_strength;
> + return host->ops->select_drive_strength(card, max_dtr,
> + host_drv_type,
> + card_drv_type,
> + drv_type);
> }
>
> /*
> @@ -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)
> diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
> index 1a22a82..09241e5 100644
> --- a/drivers/mmc/core/core.h
> +++ b/drivers/mmc/core/core.h
> @@ -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);
> diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
> index f4db93e..154aced 100644
> --- a/drivers/mmc/core/debugfs.c
> +++ b/drivers/mmc/core/debugfs.c
> @@ -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);
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index 5466f25..970e690 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -61,246 +61,6 @@ void mmc_unregister_host_class(void)
> class_unregister(&mmc_host_class);
> }
>
> -#ifdef CONFIG_MMC_CLKGATE
> -static ssize_t clkgate_delay_show(struct device *dev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct mmc_host *host = cls_dev_to_mmc_host(dev);
> - return snprintf(buf, PAGE_SIZE, "%lu\n", host->clkgate_delay);
> -}
> -
> -static ssize_t clkgate_delay_store(struct device *dev,
> - struct device_attribute *attr, const char *buf, size_t count)
> -{
> - struct mmc_host *host = cls_dev_to_mmc_host(dev);
> - unsigned long flags, value;
> -
> - if (kstrtoul(buf, 0, &value))
> - return -EINVAL;
> -
> - spin_lock_irqsave(&host->clk_lock, flags);
> - host->clkgate_delay = value;
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> - return count;
> -}
> -
> -/*
> - * Enabling clock gating will make the core call out to the host
> - * once up and once down when it performs a request or card operation
> - * intermingled in any fashion. The driver will see this through
> - * set_ios() operations with ios.clock field set to 0 to gate (disable)
> - * the block clock, and to the old frequency to enable it again.
> - */
> -static void mmc_host_clk_gate_delayed(struct mmc_host *host)
> -{
> - unsigned long tick_ns;
> - unsigned long freq = host->ios.clock;
> - unsigned long flags;
> -
> - if (!freq) {
> - pr_debug("%s: frequency set to 0 in disable function, "
> - "this means the clock is already disabled.\n",
> - mmc_hostname(host));
> - return;
> - }
> - /*
> - * New requests may have appeared while we were scheduling,
> - * then there is no reason to delay the check before
> - * clk_disable().
> - */
> - spin_lock_irqsave(&host->clk_lock, flags);
> -
> - /*
> - * Delay n bus cycles (at least 8 from MMC spec) before attempting
> - * to disable the MCI block clock. The reference count may have
> - * gone up again after this delay due to rescheduling!
> - */
> - if (!host->clk_requests) {
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> - tick_ns = DIV_ROUND_UP(1000000000, freq);
> - ndelay(host->clk_delay * tick_ns);
> - } else {
> - /* New users appeared while waiting for this work */
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> - return;
> - }
> - mutex_lock(&host->clk_gate_mutex);
> - spin_lock_irqsave(&host->clk_lock, flags);
> - if (!host->clk_requests) {
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> - /* This will set host->ios.clock to 0 */
> - mmc_gate_clock(host);
> - spin_lock_irqsave(&host->clk_lock, flags);
> - pr_debug("%s: gated MCI clock\n", mmc_hostname(host));
> - }
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> - mutex_unlock(&host->clk_gate_mutex);
> -}
> -
> -/*
> - * Internal work. Work to disable the clock at some later point.
> - */
> -static void mmc_host_clk_gate_work(struct work_struct *work)
> -{
> - struct mmc_host *host = container_of(work, struct mmc_host,
> - clk_gate_work.work);
> -
> - mmc_host_clk_gate_delayed(host);
> -}
> -
> -/**
> - * mmc_host_clk_hold - ungate hardware MCI clocks
> - * @host: host to ungate.
> - *
> - * Makes sure the host ios.clock is restored to a non-zero value
> - * past this call. Increase clock reference count and ungate clock
> - * if we're the first user.
> - */
> -void mmc_host_clk_hold(struct mmc_host *host)
> -{
> - unsigned long flags;
> -
> - /* cancel any clock gating work scheduled by mmc_host_clk_release() */
> - cancel_delayed_work_sync(&host->clk_gate_work);
> - mutex_lock(&host->clk_gate_mutex);
> - spin_lock_irqsave(&host->clk_lock, flags);
> - if (host->clk_gated) {
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> - mmc_ungate_clock(host);
> - spin_lock_irqsave(&host->clk_lock, flags);
> - pr_debug("%s: ungated MCI clock\n", mmc_hostname(host));
> - }
> - host->clk_requests++;
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> - mutex_unlock(&host->clk_gate_mutex);
> -}
> -
> -/**
> - * mmc_host_may_gate_card - check if this card may be gated
> - * @card: card to check.
> - */
> -static bool mmc_host_may_gate_card(struct mmc_card *card)
> -{
> - /* If there is no card we may gate it */
> - if (!card)
> - return true;
> - /*
> - * Don't gate SDIO cards! These need to be clocked at all times
> - * since they may be independent systems generating interrupts
> - * and other events. The clock requests counter from the core will
> - * go down to zero since the core does not need it, but we will not
> - * gate the clock, because there is somebody out there that may still
> - * be using it.
> - */
> - return !(card->quirks & MMC_QUIRK_BROKEN_CLK_GATING);
> -}
> -
> -/**
> - * mmc_host_clk_release - gate off hardware MCI clocks
> - * @host: host to gate.
> - *
> - * Calls the host driver with ios.clock set to zero as often as possible
> - * in order to gate off hardware MCI clocks. Decrease clock reference
> - * count and schedule disabling of clock.
> - */
> -void mmc_host_clk_release(struct mmc_host *host)
> -{
> - unsigned long flags;
> -
> - spin_lock_irqsave(&host->clk_lock, flags);
> - host->clk_requests--;
> - if (mmc_host_may_gate_card(host->card) &&
> - !host->clk_requests)
> - schedule_delayed_work(&host->clk_gate_work,
> - msecs_to_jiffies(host->clkgate_delay));
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> -}
> -
> -/**
> - * mmc_host_clk_rate - get current clock frequency setting
> - * @host: host to get the clock frequency for.
> - *
> - * Returns current clock frequency regardless of gating.
> - */
> -unsigned int mmc_host_clk_rate(struct mmc_host *host)
> -{
> - unsigned long freq;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&host->clk_lock, flags);
> - if (host->clk_gated)
> - freq = host->clk_old;
> - else
> - freq = host->ios.clock;
> - spin_unlock_irqrestore(&host->clk_lock, flags);
> - return freq;
> -}
> -
> -/**
> - * mmc_host_clk_init - set up clock gating code
> - * @host: host with potential clock to control
> - */
> -static inline void mmc_host_clk_init(struct mmc_host *host)
> -{
> - host->clk_requests = 0;
> - /* Hold MCI clock for 8 cycles by default */
> - host->clk_delay = 8;
> - /*
> - * Default clock gating delay is 0ms to avoid wasting power.
> - * This value can be tuned by writing into sysfs entry.
> - */
> - host->clkgate_delay = 0;
> - host->clk_gated = false;
> - INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work);
> - spin_lock_init(&host->clk_lock);
> - mutex_init(&host->clk_gate_mutex);
> -}
> -
> -/**
> - * mmc_host_clk_exit - shut down clock gating code
> - * @host: host with potential clock to control
> - */
> -static inline void mmc_host_clk_exit(struct mmc_host *host)
> -{
> - /*
> - * Wait for any outstanding gate and then make sure we're
> - * ungated before exiting.
> - */
> - if (cancel_delayed_work_sync(&host->clk_gate_work))
> - mmc_host_clk_gate_delayed(host);
> - if (host->clk_gated)
> - mmc_host_clk_hold(host);
> - /* There should be only one user now */
> - WARN_ON(host->clk_requests > 1);
> -}
> -
> -static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
> -{
> - host->clkgate_delay_attr.show = clkgate_delay_show;
> - host->clkgate_delay_attr.store = clkgate_delay_store;
> - sysfs_attr_init(&host->clkgate_delay_attr.attr);
> - host->clkgate_delay_attr.attr.name = "clkgate_delay";
> - host->clkgate_delay_attr.attr.mode = S_IRUGO | S_IWUSR;
> - if (device_create_file(&host->class_dev, &host->clkgate_delay_attr))
> - pr_err("%s: Failed to create clkgate_delay sysfs entry\n",
> - mmc_hostname(host));
> -}
> -#else
> -
> -static inline void mmc_host_clk_init(struct mmc_host *host)
> -{
> -}
> -
> -static inline void mmc_host_clk_exit(struct mmc_host *host)
> -{
> -}
> -
> -static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
> -{
> -}
> -
> -#endif
> -
> void mmc_retune_enable(struct mmc_host *host)
> {
> host->can_retune = 1;
> @@ -583,8 +343,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device
> *dev)
> return NULL;
> }
>
> - mmc_host_clk_init(host);
> -
> spin_lock_init(&host->lock);
> init_waitqueue_head(&host->wq);
> INIT_DELAYED_WORK(&host->detect, mmc_rescan);
> @@ -633,7 +391,6 @@ int mmc_add_host(struct mmc_host *host)
> #ifdef CONFIG_DEBUG_FS
> mmc_add_host_debugfs(host);
> #endif
> - mmc_host_clk_sysfs_init(host);
>
> mmc_start_host(host);
> register_pm_notifier(&host->pm_notify);
> @@ -663,8 +420,6 @@ void mmc_remove_host(struct mmc_host *host)
> device_del(&host->class_dev);
>
> led_trigger_unregister_simple(host->led);
> -
> - mmc_host_clk_exit(host);
> }
>
> EXPORT_SYMBOL(mmc_remove_host);
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index e726903..1b8907f 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -1932,20 +1932,16 @@ static int mmc_reset(struct mmc_host *host)
> if (!mmc_can_reset(card))
> return -EOPNOTSUPP;
>
> - mmc_host_clk_hold(host);
> mmc_set_clock(host, host->f_init);
>
> host->ops->hw_reset(host);
>
> /* If the reset has happened, then a status command will fail */
> - if (!mmc_send_status(card, &status)) {
> - mmc_host_clk_release(host);
> + if (!mmc_send_status(card, &status))
> return -ENOSYS;
> - }
>
> /* Set initial state and call mmc_set_ios */
> mmc_set_initial_state(host);
> - mmc_host_clk_release(host);
>
> return mmc_init_card(host, card->ocr, card);
> }
> diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c
> index dd1d1e0..fad660b 100644
> --- a/drivers/mmc/core/quirks.c
> +++ b/drivers/mmc/core/quirks.c
> @@ -35,25 +35,7 @@
> #define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128
> #endif
>
> -/*
> - * This hook just adds a quirk for all sdio devices
> - */
> -static void add_quirk_for_sdio_devices(struct mmc_card *card, int data)
> -{
> - if (mmc_card_sdio(card))
> - card->quirks |= data;
> -}
> -
> static const struct mmc_fixup mmc_fixup_methods[] = {
> - /* by default sdio devices are considered CLK_GATING broken */
> - /* good cards will be whitelisted as they are tested */
> - SDIO_FIXUP(SDIO_ANY_ID, SDIO_ANY_ID,
> - add_quirk_for_sdio_devices,
> - MMC_QUIRK_BROKEN_CLK_GATING),
> -
> - SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
> - remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING),
> -
> SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
> add_quirk, MMC_QUIRK_NONSTD_FUNC_IF),
>
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index e28ebf3..60a18ab 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -784,9 +784,7 @@ static int mmc_sd_get_ro(struct mmc_host *host)
> if (!host->ops->get_ro)
> return -1;
>
> - mmc_host_clk_hold(host);
> ro = host->ops->get_ro(host);
> - mmc_host_clk_release(host);
>
> return ro;
> }
> diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
> index 95bc101..16d838e 100644
> --- a/drivers/mmc/core/sdio.c
> +++ b/drivers/mmc/core/sdio.c
> @@ -956,13 +956,10 @@ static int mmc_sdio_resume(struct mmc_host *host)
> }
>
> if (!err && host->sdio_irqs) {
> - if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) {
> + if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD))
> wake_up_process(host->sdio_irq_thread);
> - } else if (host->caps & MMC_CAP_SDIO_IRQ) {
> - mmc_host_clk_hold(host);
> + else if (host->caps & MMC_CAP_SDIO_IRQ)
> host->ops->enable_sdio_irq(host, 1);
> - mmc_host_clk_release(host);
> - }
> }
>
> mmc_release_host(host);
> diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
> index 09cc67d..91bbbfb 100644
> --- a/drivers/mmc/core/sdio_irq.c
> +++ b/drivers/mmc/core/sdio_irq.c
> @@ -168,21 +168,15 @@ static int sdio_irq_thread(void *_host)
> }
>
> set_current_state(TASK_INTERRUPTIBLE);
> - if (host->caps & MMC_CAP_SDIO_IRQ) {
> - mmc_host_clk_hold(host);
> + if (host->caps & MMC_CAP_SDIO_IRQ)
> host->ops->enable_sdio_irq(host, 1);
> - mmc_host_clk_release(host);
> - }
> if (!kthread_should_stop())
> schedule_timeout(period);
> set_current_state(TASK_RUNNING);
> } while (!kthread_should_stop());
>
> - if (host->caps & MMC_CAP_SDIO_IRQ) {
> - mmc_host_clk_hold(host);
> + if (host->caps & MMC_CAP_SDIO_IRQ)
> host->ops->enable_sdio_irq(host, 0);
> - mmc_host_clk_release(host);
> - }
>
> pr_debug("%s: IRQ thread exiting with code %d\n",
> mmc_hostname(host), ret);
> @@ -208,9 +202,7 @@ static int sdio_card_irq_get(struct mmc_card *card)
> return err;
> }
> } else if (host->caps & MMC_CAP_SDIO_IRQ) {
> - mmc_host_clk_hold(host);
> host->ops->enable_sdio_irq(host, 1);
> - mmc_host_clk_release(host);
> }
> }
>
> @@ -229,9 +221,7 @@ static int sdio_card_irq_put(struct mmc_card *card)
> atomic_set(&host->sdio_irq_thread_abort, 1);
> kthread_stop(host->sdio_irq_thread);
> } else if (host->caps & MMC_CAP_SDIO_IRQ) {
> - mmc_host_clk_hold(host);
> host->ops->enable_sdio_irq(host, 0);
> - mmc_host_clk_release(host);
> }
> }
>
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index fdd0779..eb0151b 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -269,7 +269,6 @@ struct mmc_card {
> /* for byte mode */
> #define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card
> attached */
> /* (missing CIA registers) */
> -#define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus
> will make card fail */
> #define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has
> nonstd function interfaces */
> #define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3]
> resistor */
> #define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken
> CMD38 */
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 83b81fd..cfb3c99 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -292,18 +292,6 @@ struct mmc_host {
>
> mmc_pm_flag_t pm_caps; /* supported pm features */
>
> -#ifdef CONFIG_MMC_CLKGATE
> - int clk_requests; /* internal reference counter
> */
> - unsigned int clk_delay; /* number of MCI clk hold
> cycles */
> - bool clk_gated; /* clock gated */
> - struct delayed_work clk_gate_work; /* delayed clock gate */
> - unsigned int clk_old; /* old clock value cache */
> - spinlock_t clk_lock; /* lock for clk fields */
> - struct mutex clk_gate_mutex; /* mutex for clock gating */
> - struct device_attribute clkgate_delay_attr;
> - unsigned long clkgate_delay;
> -#endif
> -
> /* host specific block data */
> unsigned int max_seg_size; /* see
> blk_queue_max_segment_size */
> unsigned short max_segs; /* see blk_queue_max_segments
> */
> @@ -479,26 +467,6 @@ static inline int mmc_host_packed_wr(struct mmc_host
> *host)
> return host->caps2 & MMC_CAP2_PACKED_WR;
> }
>
> -#ifdef CONFIG_MMC_CLKGATE
> -void mmc_host_clk_hold(struct mmc_host *host);
> -void mmc_host_clk_release(struct mmc_host *host);
> -unsigned int mmc_host_clk_rate(struct mmc_host *host);
> -
> -#else
> -static inline void mmc_host_clk_hold(struct mmc_host *host)
> -{
> -}
> -
> -static inline void mmc_host_clk_release(struct mmc_host *host)
> -{
> -}
> -
> -static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
> -{
> - return host->ios.clock;
> -}
> -#endif
> -
> static inline int mmc_card_hs(struct mmc_card *card)
> {
> return card->host->ios.timing == MMC_TIMING_SD_HS ||
> --
> 1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html