All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] MMCI Break out clock divider setup
@ 2009-09-09 20:55 ` Linus Walleij
  0 siblings, 0 replies; 4+ messages in thread
From: Linus Walleij @ 2009-09-09 20:55 UTC (permalink / raw)
  To: linux-mmc, linux-arm-kernel; +Cc: Catalin Marinas, Linus Walleij

This breaks out the clock divider set-up code from the
mmci_set_ios() code and surrounds the two register
writes with a host lock so we don't get collisions if
(in future code) two code paths want to change the
clock divider at the same time as can be the case if
we get something like pre/post- clock frequency change
notifications soonish.

Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
---
 drivers/mmc/host/mmci.c |   49 +++++++++++++++++++++++++++++++---------------
 1 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a923ee2..083f9b8 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -38,6 +38,33 @@
 
 static unsigned int fmax = 515633;
 
+/*
+ * This must be called with host->lock held
+ */
+static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
+{
+	u32 clk = 0;
+
+	if (desired) {
+		if (desired >= host->mclk) {
+			clk = MCI_CLK_BYPASS;
+			host->cclk = host->mclk;
+		} else {
+			clk = host->mclk / (2 * desired) - 1;
+			if (clk >= 256)
+				clk = 255;
+			host->cclk = host->mclk / (2 * (clk + 1));
+		}
+		if (host->hw_designer == 0x80)
+			clk |= MCI_FCEN; /* Bug fix in ST IP block */
+		clk |= MCI_CLK_ENABLE;
+		/* This hasn't proven to be worthwhile */
+		/* clk |= MCI_CLK_PWRSAVE; */
+	}
+
+	writel(clk, host->base + MMCICLOCK);
+}
+
 static void
 mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
@@ -420,21 +447,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct mmci_host *host = mmc_priv(mmc);
 	u32 clk = 0, pwr = 0;
-
-	if (ios->clock) {
-		if (ios->clock >= host->mclk) {
-			clk = MCI_CLK_BYPASS;
-			host->cclk = host->mclk;
-		} else {
-			clk = host->mclk / (2 * ios->clock) - 1;
-			if (clk >= 256)
-				clk = 255;
-			host->cclk = host->mclk / (2 * (clk + 1));
-		}
-		if (host->hw_designer == 0x80)
-			clk |= MCI_FCEN; /* Bug fix in ST IP block */
-		clk |= MCI_CLK_ENABLE;
-	}
+	unsigned long flags;
 
 	if (host->plat->translate_vdd)
 		pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
@@ -465,12 +478,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		}
 	}
 
-	writel(clk, host->base + MMCICLOCK);
+	spin_lock_irqsave(&host->lock, flags);
+
+	mmci_set_clkreg(host, ios->clock);
 
 	if (host->pwr != pwr) {
 		host->pwr = pwr;
 		writel(pwr, host->base + MMCIPOWER);
 	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static int mmci_get_ro(struct mmc_host *mmc)
-- 
1.6.2.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 1/3] MMCI Break out clock divider setup
@ 2009-09-09 20:55 ` Linus Walleij
  0 siblings, 0 replies; 4+ messages in thread
From: Linus Walleij @ 2009-09-09 20:55 UTC (permalink / raw)
  To: linux-arm-kernel

This breaks out the clock divider set-up code from the
mmci_set_ios() code and surrounds the two register
writes with a host lock so we don't get collisions if
(in future code) two code paths want to change the
clock divider at the same time as can be the case if
we get something like pre/post- clock frequency change
notifications soonish.

Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
---
 drivers/mmc/host/mmci.c |   49 +++++++++++++++++++++++++++++++---------------
 1 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a923ee2..083f9b8 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -38,6 +38,33 @@
 
 static unsigned int fmax = 515633;
 
+/*
+ * This must be called with host->lock held
+ */
+static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
+{
+	u32 clk = 0;
+
+	if (desired) {
+		if (desired >= host->mclk) {
+			clk = MCI_CLK_BYPASS;
+			host->cclk = host->mclk;
+		} else {
+			clk = host->mclk / (2 * desired) - 1;
+			if (clk >= 256)
+				clk = 255;
+			host->cclk = host->mclk / (2 * (clk + 1));
+		}
+		if (host->hw_designer == 0x80)
+			clk |= MCI_FCEN; /* Bug fix in ST IP block */
+		clk |= MCI_CLK_ENABLE;
+		/* This hasn't proven to be worthwhile */
+		/* clk |= MCI_CLK_PWRSAVE; */
+	}
+
+	writel(clk, host->base + MMCICLOCK);
+}
+
 static void
 mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
@@ -420,21 +447,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct mmci_host *host = mmc_priv(mmc);
 	u32 clk = 0, pwr = 0;
-
-	if (ios->clock) {
-		if (ios->clock >= host->mclk) {
-			clk = MCI_CLK_BYPASS;
-			host->cclk = host->mclk;
-		} else {
-			clk = host->mclk / (2 * ios->clock) - 1;
-			if (clk >= 256)
-				clk = 255;
-			host->cclk = host->mclk / (2 * (clk + 1));
-		}
-		if (host->hw_designer == 0x80)
-			clk |= MCI_FCEN; /* Bug fix in ST IP block */
-		clk |= MCI_CLK_ENABLE;
-	}
+	unsigned long flags;
 
 	if (host->plat->translate_vdd)
 		pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
@@ -465,12 +478,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		}
 	}
 
-	writel(clk, host->base + MMCICLOCK);
+	spin_lock_irqsave(&host->lock, flags);
+
+	mmci_set_clkreg(host, ios->clock);
 
 	if (host->pwr != pwr) {
 		host->pwr = pwr;
 		writel(pwr, host->base + MMCIPOWER);
 	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static int mmci_get_ro(struct mmc_host *mmc)
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/3] MMCI Break out clock divider setup
  2009-09-09 20:55 ` Linus Walleij
@ 2009-09-12 11:05   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 4+ messages in thread
From: Russell King - ARM Linux @ 2009-09-12 11:05 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-mmc, linux-arm-kernel, Catalin Marinas

Unfortunately, these patches can not be applied in their current form
because they don't take account of the conflicting changes already in
my tree.

On Wed, Sep 09, 2009 at 10:55:00PM +0200, Linus Walleij wrote:
> This breaks out the clock divider set-up code from the
> mmci_set_ios() code and surrounds the two register
> writes with a host lock so we don't get collisions if
> (in future code) two code paths want to change the
> clock divider at the same time as can be the case if
> we get something like pre/post- clock frequency change
> notifications soonish.
> 
> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
> ---
>  drivers/mmc/host/mmci.c |   49 +++++++++++++++++++++++++++++++---------------
>  1 files changed, 33 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index a923ee2..083f9b8 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -38,6 +38,33 @@
>  
>  static unsigned int fmax = 515633;
>  
> +/*
> + * This must be called with host->lock held
> + */
> +static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
> +{
> +	u32 clk = 0;
> +
> +	if (desired) {
> +		if (desired >= host->mclk) {
> +			clk = MCI_CLK_BYPASS;
> +			host->cclk = host->mclk;
> +		} else {
> +			clk = host->mclk / (2 * desired) - 1;
> +			if (clk >= 256)
> +				clk = 255;
> +			host->cclk = host->mclk / (2 * (clk + 1));
> +		}
> +		if (host->hw_designer == 0x80)
> +			clk |= MCI_FCEN; /* Bug fix in ST IP block */
> +		clk |= MCI_CLK_ENABLE;
> +		/* This hasn't proven to be worthwhile */
> +		/* clk |= MCI_CLK_PWRSAVE; */
> +	}
> +
> +	writel(clk, host->base + MMCICLOCK);
> +}
> +
>  static void
>  mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
>  {
> @@ -420,21 +447,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  {
>  	struct mmci_host *host = mmc_priv(mmc);
>  	u32 clk = 0, pwr = 0;
> -
> -	if (ios->clock) {
> -		if (ios->clock >= host->mclk) {
> -			clk = MCI_CLK_BYPASS;
> -			host->cclk = host->mclk;
> -		} else {
> -			clk = host->mclk / (2 * ios->clock) - 1;
> -			if (clk >= 256)
> -				clk = 255;
> -			host->cclk = host->mclk / (2 * (clk + 1));
> -		}
> -		if (host->hw_designer == 0x80)
> -			clk |= MCI_FCEN; /* Bug fix in ST IP block */
> -		clk |= MCI_CLK_ENABLE;
> -	}
> +	unsigned long flags;
>  
>  	if (host->plat->translate_vdd)
>  		pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
> @@ -465,12 +478,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  		}
>  	}
>  
> -	writel(clk, host->base + MMCICLOCK);
> +	spin_lock_irqsave(&host->lock, flags);
> +
> +	mmci_set_clkreg(host, ios->clock);
>  
>  	if (host->pwr != pwr) {
>  		host->pwr = pwr;
>  		writel(pwr, host->base + MMCIPOWER);
>  	}
> +
> +	spin_unlock_irqrestore(&host->lock, flags);
>  }
>  
>  static int mmci_get_ro(struct mmc_host *mmc)
> -- 
> 1.6.2.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] MMCI Break out clock divider setup
@ 2009-09-12 11:05   ` Russell King - ARM Linux
  0 siblings, 0 replies; 4+ messages in thread
From: Russell King - ARM Linux @ 2009-09-12 11:05 UTC (permalink / raw)
  To: linux-arm-kernel

Unfortunately, these patches can not be applied in their current form
because they don't take account of the conflicting changes already in
my tree.

On Wed, Sep 09, 2009 at 10:55:00PM +0200, Linus Walleij wrote:
> This breaks out the clock divider set-up code from the
> mmci_set_ios() code and surrounds the two register
> writes with a host lock so we don't get collisions if
> (in future code) two code paths want to change the
> clock divider at the same time as can be the case if
> we get something like pre/post- clock frequency change
> notifications soonish.
> 
> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
> ---
>  drivers/mmc/host/mmci.c |   49 +++++++++++++++++++++++++++++++---------------
>  1 files changed, 33 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index a923ee2..083f9b8 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -38,6 +38,33 @@
>  
>  static unsigned int fmax = 515633;
>  
> +/*
> + * This must be called with host->lock held
> + */
> +static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
> +{
> +	u32 clk = 0;
> +
> +	if (desired) {
> +		if (desired >= host->mclk) {
> +			clk = MCI_CLK_BYPASS;
> +			host->cclk = host->mclk;
> +		} else {
> +			clk = host->mclk / (2 * desired) - 1;
> +			if (clk >= 256)
> +				clk = 255;
> +			host->cclk = host->mclk / (2 * (clk + 1));
> +		}
> +		if (host->hw_designer == 0x80)
> +			clk |= MCI_FCEN; /* Bug fix in ST IP block */
> +		clk |= MCI_CLK_ENABLE;
> +		/* This hasn't proven to be worthwhile */
> +		/* clk |= MCI_CLK_PWRSAVE; */
> +	}
> +
> +	writel(clk, host->base + MMCICLOCK);
> +}
> +
>  static void
>  mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
>  {
> @@ -420,21 +447,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  {
>  	struct mmci_host *host = mmc_priv(mmc);
>  	u32 clk = 0, pwr = 0;
> -
> -	if (ios->clock) {
> -		if (ios->clock >= host->mclk) {
> -			clk = MCI_CLK_BYPASS;
> -			host->cclk = host->mclk;
> -		} else {
> -			clk = host->mclk / (2 * ios->clock) - 1;
> -			if (clk >= 256)
> -				clk = 255;
> -			host->cclk = host->mclk / (2 * (clk + 1));
> -		}
> -		if (host->hw_designer == 0x80)
> -			clk |= MCI_FCEN; /* Bug fix in ST IP block */
> -		clk |= MCI_CLK_ENABLE;
> -	}
> +	unsigned long flags;
>  
>  	if (host->plat->translate_vdd)
>  		pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
> @@ -465,12 +478,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  		}
>  	}
>  
> -	writel(clk, host->base + MMCICLOCK);
> +	spin_lock_irqsave(&host->lock, flags);
> +
> +	mmci_set_clkreg(host, ios->clock);
>  
>  	if (host->pwr != pwr) {
>  		host->pwr = pwr;
>  		writel(pwr, host->base + MMCIPOWER);
>  	}
> +
> +	spin_unlock_irqrestore(&host->lock, flags);
>  }
>  
>  static int mmci_get_ro(struct mmc_host *mmc)
> -- 
> 1.6.2.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-09-12 11:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-09 20:55 [PATCH 1/3] MMCI Break out clock divider setup Linus Walleij
2009-09-09 20:55 ` Linus Walleij
2009-09-12 11:05 ` Russell King - ARM Linux
2009-09-12 11:05   ` Russell King - ARM Linux

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.