diff mbox series

[3/7] mmc: sdhci: fix SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN

Message ID eb105eedaa387ced14bb687e38d3aa33d4fcf70a.1585827904.git.mirq-linux@rere.qmqm.pl (mailing list archive)
State New, archived
Headers show
Series SDHCI clock handling fixes and cleanups | expand

Commit Message

Michał Mirosław April 2, 2020, 11:54 a.m. UTC
Fix returned clock rate for SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN case.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Cc: stable@kernel.vger.org
Fixes: d1955c3a9a1d ("mmc: sdhci: add quirk SDHCI_QUIRK_CLOCK_DIV_ZERO_BROKEN")
---
 drivers/mmc/host/sdhci.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Adrian Hunter April 15, 2020, 1:06 p.m. UTC | #1
On 2/04/20 2:54 pm, Michał Mirosław wrote:
> Fix returned clock rate for SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN case.

Does this change anything, because it looks the same to me?

> 
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Cc: stable@kernel.vger.org
> Fixes: d1955c3a9a1d ("mmc: sdhci: add quirk SDHCI_QUIRK_CLOCK_DIV_ZERO_BROKEN")
> ---
>  drivers/mmc/host/sdhci.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index b2dc4f1cfa5c..a043bf5e3565 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1807,9 +1807,12 @@ u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
>  
>  		if (!host->clk_mul || switch_base_clk) {
>  			/* Version 3.00 divisors must be a multiple of 2. */
> -			if (host->max_clk <= clock)
> +			if (host->max_clk <= clock) {
>  				div = 1;
> -			else {
> +				if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
> +					&& host->max_clk <= 25000000)
> +					div = 2;
> +			} else {
>  				for (div = 2; div < SDHCI_MAX_DIV_SPEC_300;
>  				     div += 2) {
>  					if ((host->max_clk / div) <= clock)
> @@ -1818,9 +1821,6 @@ u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
>  			}
>  			real_div = div;
>  			div >>= 1;
> -			if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
> -				&& !div && host->max_clk <= 25000000)
> -				div = 1;
>  		}
>  	} else {
>  		/* Version 2.00 divisors must be a power of 2. */
>
Michał Mirosław April 15, 2020, 4:03 p.m. UTC | #2
On Wed, Apr 15, 2020 at 04:06:02PM +0300, Adrian Hunter wrote:
> On 2/04/20 2:54 pm, Michał Mirosław wrote:
> > Fix returned clock rate for SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN case.
> 
> Does this change anything, because it looks the same to me?

The value of real_div is fixed this way. With previous code after
applying the quirk you would have real_div = 1 instead of real_div = 2.

Best Regards,
Michał Mirosław

> 
> > 
> > Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> > Cc: stable@kernel.vger.org
> > Fixes: d1955c3a9a1d ("mmc: sdhci: add quirk SDHCI_QUIRK_CLOCK_DIV_ZERO_BROKEN")
> > ---
> >  drivers/mmc/host/sdhci.c | 10 +++++-----
> >  1 file changed, 5 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> > index b2dc4f1cfa5c..a043bf5e3565 100644
> > --- a/drivers/mmc/host/sdhci.c
> > +++ b/drivers/mmc/host/sdhci.c
> > @@ -1807,9 +1807,12 @@ u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
> >  
> >  		if (!host->clk_mul || switch_base_clk) {
> >  			/* Version 3.00 divisors must be a multiple of 2. */
> > -			if (host->max_clk <= clock)
> > +			if (host->max_clk <= clock) {
> >  				div = 1;
> > -			else {
> > +				if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
> > +					&& host->max_clk <= 25000000)
> > +					div = 2;
> > +			} else {
> >  				for (div = 2; div < SDHCI_MAX_DIV_SPEC_300;
> >  				     div += 2) {
> >  					if ((host->max_clk / div) <= clock)
> > @@ -1818,9 +1821,6 @@ u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
> >  			}
> >  			real_div = div;
> >  			div >>= 1;
> > -			if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
> > -				&& !div && host->max_clk <= 25000000)
> > -				div = 1;
> >  		}
> >  	} else {
> >  		/* Version 2.00 divisors must be a power of 2. */
> > 
>
Adrian Hunter April 16, 2020, 7:40 a.m. UTC | #3
On 15/04/20 7:03 pm, Michał Mirosław wrote:
> On Wed, Apr 15, 2020 at 04:06:02PM +0300, Adrian Hunter wrote:
>> On 2/04/20 2:54 pm, Michał Mirosław wrote:
>>> Fix returned clock rate for SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN case.
>>
>> Does this change anything, because it looks the same to me?
> 
> The value of real_div is fixed this way. With previous code after
> applying the quirk you would have real_div = 1 instead of real_div = 2.

That kind of thing should be in the commit message.  Please also explain
what effect this has (the actual clock value will be too high, but also what
problems does that manifest) and what hardware is affected.

> 
> Best Regards,
> Michał Mirosław
> 
>>
>>>
>>> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>>> Cc: stable@kernel.vger.org
>>> Fixes: d1955c3a9a1d ("mmc: sdhci: add quirk SDHCI_QUIRK_CLOCK_DIV_ZERO_BROKEN")
>>> ---
>>>  drivers/mmc/host/sdhci.c | 10 +++++-----
>>>  1 file changed, 5 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>> index b2dc4f1cfa5c..a043bf5e3565 100644
>>> --- a/drivers/mmc/host/sdhci.c
>>> +++ b/drivers/mmc/host/sdhci.c
>>> @@ -1807,9 +1807,12 @@ u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
>>>  
>>>  		if (!host->clk_mul || switch_base_clk) {
>>>  			/* Version 3.00 divisors must be a multiple of 2. */
>>> -			if (host->max_clk <= clock)
>>> +			if (host->max_clk <= clock) {
>>>  				div = 1;
>>> -			else {
>>> +				if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
>>> +					&& host->max_clk <= 25000000)
>>> +					div = 2;
>>> +			} else {
>>>  				for (div = 2; div < SDHCI_MAX_DIV_SPEC_300;
>>>  				     div += 2) {
>>>  					if ((host->max_clk / div) <= clock)
>>> @@ -1818,9 +1821,6 @@ u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
>>>  			}
>>>  			real_div = div;
>>>  			div >>= 1;
>>> -			if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
>>> -				&& !div && host->max_clk <= 25000000)
>>> -				div = 1;
>>>  		}
>>>  	} else {
>>>  		/* Version 2.00 divisors must be a power of 2. */
>>>
>>
diff mbox series

Patch

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b2dc4f1cfa5c..a043bf5e3565 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1807,9 +1807,12 @@  u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
 
 		if (!host->clk_mul || switch_base_clk) {
 			/* Version 3.00 divisors must be a multiple of 2. */
-			if (host->max_clk <= clock)
+			if (host->max_clk <= clock) {
 				div = 1;
-			else {
+				if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
+					&& host->max_clk <= 25000000)
+					div = 2;
+			} else {
 				for (div = 2; div < SDHCI_MAX_DIV_SPEC_300;
 				     div += 2) {
 					if ((host->max_clk / div) <= clock)
@@ -1818,9 +1821,6 @@  u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
 			}
 			real_div = div;
 			div >>= 1;
-			if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN)
-				&& !div && host->max_clk <= 25000000)
-				div = 1;
 		}
 	} else {
 		/* Version 2.00 divisors must be a power of 2. */