sdhci: Add get_{max,timeout}_clock callbacks
authorBen Dooks <ben-linux@fluff.org>
Mon, 16 Mar 2009 21:13:57 +0000 (00:13 +0300)
committerPierre Ossman <drzeus@drzeus.cx>
Tue, 24 Mar 2009 20:30:09 +0000 (21:30 +0100)
Some controllers do not provide clock information in their capabilities
(in the Samsung case, it is because there are multiple clock sources
available to the controller). Add hooks to allow the system to supply
clock information.

p.s.
In the original Ben's patch there was a bug that makes sdhci_add_host()
return -ENODEV even if callbacks were specified. This is fixed now.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h

index c814220..34ab77b 100644 (file)
@@ -1674,19 +1674,27 @@ int sdhci_add_host(struct sdhci_host *host)
 
        host->max_clk =
                (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+       host->max_clk *= 1000000;
        if (host->max_clk == 0) {
-               printk(KERN_ERR "%s: Hardware doesn't specify base clock "
-                       "frequency.\n", mmc_hostname(mmc));
-               return -ENODEV;
+               if (!host->ops->get_max_clock) {
+                       printk(KERN_ERR
+                              "%s: Hardware doesn't specify base clock "
+                              "frequency.\n", mmc_hostname(mmc));
+                       return -ENODEV;
+               }
+               host->max_clk = host->ops->get_max_clock(host);
        }
-       host->max_clk *= 1000000;
 
        host->timeout_clk =
                (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
        if (host->timeout_clk == 0) {
-               printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
-                       "frequency.\n", mmc_hostname(mmc));
-               return -ENODEV;
+               if (!host->ops->get_timeout_clock) {
+                       printk(KERN_ERR
+                              "%s: Hardware doesn't specify timeout clock "
+                              "frequency.\n", mmc_hostname(mmc));
+                       return -ENODEV;
+               }
+               host->timeout_clk = host->ops->get_timeout_clock(host);
        }
        if (caps & SDHCI_TIMEOUT_CLK_UNIT)
                host->timeout_clk *= 1000;
index 6980f27..aab0652 100644 (file)
@@ -285,6 +285,8 @@ struct sdhci_ops {
 #endif
 
        int             (*enable_dma)(struct sdhci_host *host);
+       unsigned int    (*get_max_clock)(struct sdhci_host *host);
+       unsigned int    (*get_timeout_clock)(struct sdhci_host *host);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS