sdhci: Add set_clock callback and a quirk for nonstandard clocks
authorAnton Vorontsov <avorontsov@ru.mvista.com>
Mon, 16 Mar 2009 21:13:59 +0000 (00:13 +0300)
committerPierre Ossman <drzeus@drzeus.cx>
Tue, 24 Mar 2009 20:30:09 +0000 (21:30 +0100)
FSL eSDHC hosts have incompatible register map to manage the SDCLK.
This patch adds set_clock callback so that drivers could overwrite
set_clock behaviour.

Similar patch[1] was posted by Ben Dooks, though in Ben's version the
callback is named change_clock, plus the patch has some unrelated bits
that makes the patch difficult to reuse.

[1] http://lkml.org/lkml/2008/12/2/160

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 34ab77b..75d0ecb 100644 (file)
@@ -949,6 +949,12 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
        if (clock == host->clock)
                return;
 
+       if (host->ops->set_clock) {
+               host->ops->set_clock(host, clock);
+               if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
+                       return;
+       }
+
        sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
        if (clock == 0)
index aab0652..b9bc622 100644 (file)
@@ -218,6 +218,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK_BROKEN_CARD_DETECTION              (1<<15)
 /* Controller reports inverted write-protect state */
 #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT             (1<<16)
+/* Controller has nonstandard clock management */
+#define SDHCI_QUIRK_NONSTANDARD_CLOCK                  (1<<17)
 
        int                     irq;            /* Device IRQ */
        void __iomem *          ioaddr;         /* Mapped address */
@@ -284,6 +286,8 @@ struct sdhci_ops {
        void            (*writeb)(struct sdhci_host *host, u8 val, int reg);
 #endif
 
+       void    (*set_clock)(struct sdhci_host *host, unsigned int clock);
+
        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);