[ARM] 5024/1: Fix some minor clk issues in the MMCI PL18x driver
authorLinus Walleij <triad@df.lth.se>
Tue, 29 Apr 2008 08:34:07 +0000 (09:34 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 4 May 2008 10:06:05 +0000 (11:06 +0100)
This fixes some two minor clk issues.

The first is a comparison where a byte will probably wrap around to 0 instead of being saturated to 255, shouldn't be triggered very often but need fixing.

The second is an attempt by the driver to adjust MCLK down to the maximum frequency according to the spec, so we don't accidentally overclock the PL18x block. None of the mach-{versatile|integrator|lh7a40x} that use it in-tree seem to have a problem with this (all are well below 100MHz, typically 33MHz), but some day there will be a problem.

This is not applied on top of the earlier mmci patch for race condition but rather a clean 2.6.25, but I guess it applies without major protests anyway.

Signed-off-by: Linus Walleij <triad@df.lth.se>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/mmc/host/mmci.c

index 626ac083f4e09c294c4d465dd3c85e886082867d..da5fecad74d9a79152076730981a36d35cfe3bed 100644 (file)
@@ -425,7 +425,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                        host->cclk = host->mclk;
                } else {
                        clk = host->mclk / (2 * ios->clock) - 1;
-                       if (clk > 256)
+                       if (clk >= 256)
                                clk = 255;
                        host->cclk = host->mclk / (2 * (clk + 1));
                }
@@ -512,6 +512,18 @@ static int mmci_probe(struct amba_device *dev, void *id)
 
        host->plat = plat;
        host->mclk = clk_get_rate(host->clk);
+       /*
+        * According to the spec, mclk is max 100 MHz,
+        * so we try to adjust the clock down to this,
+        * (if possible).
+        */
+       if (host->mclk > 100000000) {
+               ret = clk_set_rate(host->clk, 100000000);
+               if (ret < 0)
+                       goto clk_disable;
+               host->mclk = clk_get_rate(host->clk);
+               DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
+       }
        host->mmc = mmc;
        host->base = ioremap(dev->res.start, SZ_4K);
        if (!host->base) {