Re: [PATCH 1/3 ] mmc: add support for h/w clock gating of sd controller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 3 Dec 2010, Philip Rakity wrote:

> This code extends software clock gating in the mmc layer
> by adding the ability to indicate that controller support
> hardware clock gating.
> 
> hardware clock gating is enabled by setting the mmc quirk
> MMC_CAP_CLOCK_GATING_HW
> in the sd driver.
> eg: host->mmc->caps |= MMC_CAP_CLOCK_GATING_HW
> 
> The approach follows the suggestion of Nico Pitre.
> 
> sd/mmc/eMMC cards use dynmamic clocks
> sdio uses continuous clocks
> 
> The code has been test using marvell linux for mmp2.  The marvell
> controller support h/w clock gating.
> 
> Signed-off-by: Philip Rakity <prakity@xxxxxxxxxxx>

Comments below.

> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 6286898..c8bba7d 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -131,7 +131,10 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
>  		if (mrq->done)
>  			mrq->done(mrq);
>  
> -		mmc_host_clk_gate(host);
> +#ifdef CONFIG_MMC_CLKGATE
> +		if ((host->caps & MMC_CAP_CLOCK_GATING_HW) == 0)
> +			mmc_host_clk_gate(host);
> +#endif

This is a needless proliferation of #ifdef's, since you could just test 
for MMC_CAP_CLOCK_GATING_HW inside mmc_host_clk_gate() instead, and 
return early if set.

>  }
>  
> @@ -192,7 +195,10 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
>  			mrq->stop->mrq = mrq;
>  		}
>  	}
> -	mmc_host_clk_ungate(host);
> +#ifdef CONFIG_MMC_CLKGATE
> +	if ((host->caps & MMC_CAP_CLOCK_GATING_HW) == 0)
> +		mmc_host_clk_ungate(host);
> +#endif

Same thing here.

>  	host->ops->request(host, mrq);
>  }
>  
> @@ -1547,8 +1553,14 @@ void mmc_rescan(struct work_struct *work)
>  		pr_info("%s: %s: trying to init card at %u Hz\n",
>  			mmc_hostname(host), __func__, host->f_init);
>  #endif
> -		mmc_power_up(host);
> +
> +#ifdef CONFIG_MMC_CLKGATE
> +		if (host->caps & MMC_CAP_CLOCK_GATING_HW)
> +			mmc_hwungate_clock(host);
> +#endif

Here you should do just like what is done for mmc_host_clk_gate() in 
host.h: provide an empty inline version when CONFIG_MMC_CLKGATE is not 
defined and get rid of the #ifdef here.

>  		sdio_reset(host);
> +		mmc_power_up(host);

Why did you move down this mmc_power_up()?

>  		mmc_go_idle(host);
>  
>  		mmc_send_if_cond(host, host->ocr_avail);
[...]
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index 92e3370..ace748e 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -282,7 +282,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
>  	host->class_dev.class = &mmc_host_class;
>  	device_initialize(&host->class_dev);
>  
> -	mmc_host_clk_init(host);
> +#ifdef CONFIG_MMC_CLKGATE
> +	if ((host->caps & MMC_CAP_CLOCK_GATING_HW) == 0)
> +		mmc_host_clk_init(host);
> +#endif

Same comment as above: why don't you check for MMC_CAP_CLOCK_GATING_HW 
inside mmc_host_clk_init()?

Granted, here mmc_host_clk_init() appears to be misnomed (maybe 
mmc_host_clk_gating_init() would have been clearer).

>  	spin_lock_init(&host->lock);
>  	init_waitqueue_head(&host->wq);
> @@ -366,7 +369,10 @@ void mmc_remove_host(struct mmc_host *host)
>  
>  	led_trigger_unregister_simple(host->led);
>  
> -	mmc_host_clk_exit(host);
> +#ifdef CONFIG_MMC_CLKGATE
> +	if ((host->caps & MMC_CAP_CLOCK_GATING_HW) == 0)
> +		mmc_host_clk_exit(host);
> +#endif

Ditto here.

>  }
>  
>  EXPORT_SYMBOL(mmc_remove_host);
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 0eccd96..195e557 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -517,6 +517,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>  
>  	mmc_set_clock(host, max_dtr);
>  
> +#ifdef CONFIG_MMC_CLKGATE
> +	if (host->caps & MMC_CAP_CLOCK_GATING_HW)
> +		mmc_hwgate_clock(host);
> +#endif

And here I seriously begin to dislike this patch.  The sw gating code is 
centralized while the hw one is spread across all card type drivers.  
Why not calling mmc_hwgate_clock() at the appropriate location within 
mmc_rescan() (that would be where it is determined that only anew card 
might be present) and call mmc_hwgate_clock() at the end of mmc_rescan() 
and only if mmc_host_may_gate_card() is true?


Nicolas
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux