mmc: sdhci: convert sdhci_set_clock() into a library function
authorRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 25 Apr 2014 11:58:55 +0000 (12:58 +0100)
committerChris Ball <chris@printf.net>
Thu, 22 May 2014 11:26:32 +0000 (07:26 -0400)
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>
19 files changed:
drivers/mmc/host/sdhci-acpi.c
drivers/mmc/host/sdhci-bcm-kona.c
drivers/mmc/host/sdhci-bcm2835.c
drivers/mmc/host/sdhci-cns3xxx.c
drivers/mmc/host/sdhci-dove.c
drivers/mmc/host/sdhci-esdhc.h
drivers/mmc/host/sdhci-of-arasan.c
drivers/mmc/host/sdhci-of-hlwd.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci-pltfm.c
drivers/mmc/host/sdhci-pxav2.c
drivers/mmc/host/sdhci-pxav3.c
drivers/mmc/host/sdhci-s3c.c
drivers/mmc/host/sdhci-sirf.c
drivers/mmc/host/sdhci-spear.c
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
include/linux/mmc/sdhci.h

index aca84a6825519d094f0efa2dbc8ad6c4f406742d..323e2a688563bc7b7bd50936207a795d0eab2e94 100644 (file)
@@ -102,12 +102,14 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
+       .set_clock = sdhci_set_clock,
        .enable_dma = sdhci_acpi_enable_dma,
        .set_bus_width = sdhci_set_bus_width,
        .reset = sdhci_reset,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
+       .set_clock = sdhci_set_clock,
        .enable_dma = sdhci_acpi_enable_dma,
        .set_bus_width = sdhci_set_bus_width,
        .reset = sdhci_reset,
index 7b97bfab910d3196f66c2264f7454344985a10a2..e610811c09b0c38b9e8022c0369690ea34ce3634 100644 (file)
@@ -206,6 +206,7 @@ static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
 }
 
 static struct sdhci_ops sdhci_bcm_kona_ops = {
+       .set_clock = sdhci_set_clock,
        .get_max_clock = sdhci_bcm_kona_get_max_clk,
        .get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
        .platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
index 289b1c80d5fc43a2814e5e30c283e65df039db0f..74906d6008e121aee081746448ab00dc1e5b7bf6 100644 (file)
@@ -131,6 +131,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
        .read_l = bcm2835_sdhci_readl,
        .read_w = bcm2835_sdhci_readw,
        .read_b = bcm2835_sdhci_readb,
+       .set_clock = sdhci_set_clock,
        .get_max_clock = sdhci_pltfm_clk_get_max_clock,
        .get_min_clock = bcm2835_sdhci_get_min_clock,
        .set_bus_width = sdhci_set_bus_width,
index 416f4a4c2e3551822fd54e7785fda1347d837311..587d73ef33ff0f08a034aa3106454593e8f35143 100644 (file)
@@ -89,8 +89,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
                  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
                  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
                  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
-                 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
-                 SDHCI_QUIRK_NONSTANDARD_CLOCK,
+                 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
 };
 
 static int sdhci_cns3xxx_probe(struct platform_device *pdev)
index 1408cc11d8812307034a258d4d9ab6c19fafc790..8ef4ab52f8e014f547f612575476bd00b691f94e 100644 (file)
@@ -86,6 +86,7 @@ static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
 static const struct sdhci_ops sdhci_dove_ops = {
        .read_w = sdhci_dove_readw,
        .read_l = sdhci_dove_readl,
+       .set_clock = sdhci_set_clock,
        .set_bus_width = sdhci_set_bus_width,
        .reset = sdhci_reset,
 };
index de69bddc3afc551a70d5deb576d47d3ce9c1242b..3497cfaf683c539edbd062199e03f5692e43bb26 100644 (file)
@@ -20,7 +20,6 @@
 
 #define ESDHC_DEFAULT_QUIRKS   (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
                                SDHCI_QUIRK_NO_BUSY_IRQ | \
-                               SDHCI_QUIRK_NONSTANDARD_CLOCK | \
                                SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
                                SDHCI_QUIRK_PIO_NEEDS_DELAY)
 
index faef21740584658b8586e815f340146b500a98f0..f0ee594f25d1ba79deddf19bbdab1088d4c1bb49 100644 (file)
@@ -52,6 +52,7 @@ static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 }
 
 static struct sdhci_ops sdhci_arasan_ops = {
+       .set_clock = sdhci_set_clock,
        .get_max_clock = sdhci_pltfm_clk_get_max_clock,
        .get_timeout_clock = sdhci_arasan_get_timeout_clock,
        .set_bus_width = sdhci_set_bus_width,
index fb01958cb18e6127ef7e82c8f2ea60bfa6eb30a7..a4a1f0f2c0a08487b4a7cc099da0caf0aea59e0f 100644 (file)
@@ -58,6 +58,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
        .write_l = sdhci_hlwd_writel,
        .write_w = sdhci_hlwd_writew,
        .write_b = sdhci_hlwd_writeb,
+       .set_clock = sdhci_set_clock,
        .set_bus_width = sdhci_set_bus_width,
        .reset = sdhci_reset,
 };
index 87f9dd91f68c0727d5db7c096d9248b4089aab76..b3a28f6b170e53ce5fe51307fc50d316fa556771 100644 (file)
@@ -1078,6 +1078,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_pci_ops = {
+       .set_clock      = sdhci_set_clock,
        .enable_dma     = sdhci_pci_enable_dma,
        .set_bus_width  = sdhci_pci_set_bus_width,
        .reset          = sdhci_reset,
index bfbf467b61c7d719475b36d3ab496216c757636b..1fb89f44bd5846179c7a1f3cea5796cbf8bb53b6 100644 (file)
@@ -45,6 +45,7 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
+       .set_clock = sdhci_set_clock,
        .set_bus_width = sdhci_set_bus_width,
        .reset = sdhci_reset,
 };
index 2eee0c8b88ebcfe2061d9d1fae38d3e267174a03..db5257bf032e3d78dde7831b429ce6d0f8c33fc8 100644 (file)
@@ -112,6 +112,7 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 }
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
+       .set_clock     = sdhci_set_clock,
        .get_max_clock = sdhci_pltfm_clk_get_max_clock,
        .set_bus_width = pxav2_mmc_set_bus_width,
        .reset         = pxav2_reset,
index 86564233ae9372b4b9c644159d478ba0842a81bd..8a40e079a57ed05a2e4461ffac4b59af9e86a0ea 100644 (file)
@@ -225,6 +225,7 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
+       .set_clock = sdhci_set_clock,
        .set_uhs_signaling = pxav3_set_uhs_signaling,
        .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
        .get_max_clock = sdhci_pltfm_clk_get_max_clock,
index 9d710b748b9c6310e5d019e467aa314c5b15c010..9e6f1c52982cbdababd2adad0e1447766553b574 100644 (file)
@@ -55,6 +55,8 @@ struct sdhci_s3c {
        struct clk              *clk_io;
        struct clk              *clk_bus[MAX_BUS_CLK];
        unsigned long           clk_rates[MAX_BUS_CLK];
+
+       bool                    no_divider;
 };
 
 /**
@@ -67,6 +69,7 @@ struct sdhci_s3c {
  */
 struct sdhci_s3c_drv_data {
        unsigned int    sdhci_quirks;
+       bool            no_divider;
 };
 
 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
@@ -116,7 +119,7 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
         * If controller uses a non-standard clock division, find the best clock
         * speed possible with selected clock source and skip the division.
         */
-       if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
+       if (ourhost->no_divider) {
                rate = clk_round_rate(clksrc, wanted);
                return wanted - rate;
        }
@@ -161,8 +164,10 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
        host->mmc->actual_clock = 0;
 
        /* don't bother if the clock is going off. */
-       if (clock == 0)
+       if (clock == 0) {
+               sdhci_set_clock(host, clock);
                return;
+       }
 
        for (src = 0; src < MAX_BUS_CLK; src++) {
                delta = sdhci_s3c_consider_clock(ourhost, src, clock);
@@ -214,6 +219,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
        if (clock < 25 * 1000000)
                ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
        writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
+
+       sdhci_set_clock(host, clock);
 }
 
 /**
@@ -603,8 +610,10 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
        /* Setup quirks for the controller */
        host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
        host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
-       if (drv_data)
+       if (drv_data) {
                host->quirks |= drv_data->sdhci_quirks;
+               sc->no_divider = drv_data->no_divider;
+       }
 
 #ifndef CONFIG_MMC_SDHCI_S3C_DMA
 
@@ -653,7 +662,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
         * If controller does not have internal clock divider,
         * we can use overriding functions instead of default.
         */
-       if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
+       if (sc->no_divider) {
                sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
                sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
                sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
@@ -794,7 +803,7 @@ static const struct dev_pm_ops sdhci_s3c_pmops = {
 
 #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
 static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
-       .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
+       .no_divider = true,
 };
 #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
 #else
index 5d79e10e1ba2c7cf7139c467559ddad4b3090ce3..3b775348b4702fbe9df2b1357f4067a213881cfd 100644 (file)
@@ -28,6 +28,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 }
 
 static struct sdhci_ops sdhci_sirf_ops = {
+       .set_clock = sdhci_set_clock,
        .get_max_clock  = sdhci_sirf_get_max_clk,
        .set_bus_width = sdhci_set_bus_width,
        .reset = sdhci_reset,
index c2a2bedc8813d275362914b37d6e1072566278ce..8bf64ab36720c04ae3520c7e42f195f127976dd6 100644 (file)
@@ -38,6 +38,7 @@ struct spear_sdhci {
 
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
+       .set_clock = sdhci_set_clock,
        .set_bus_width = sdhci_set_bus_width,
        .reset = sdhci_reset,
 };
index 7754c0319fdaf35d75fe9ea7905ef4685c649d98..a0a8b5cc3b0cdaa5886ff8b1504bb8dd9990261d 100644 (file)
@@ -153,6 +153,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
        .read_l     = tegra_sdhci_readl,
        .read_w     = tegra_sdhci_readw,
        .write_l    = tegra_sdhci_writel,
+       .set_clock  = sdhci_set_clock,
        .set_bus_width = tegra_sdhci_set_bus_width,
        .reset      = tegra_sdhci_reset,
 };
index d9b91fc17bb0be415bb52407bc41b2d941c073fb..69e58d071b331cd5187cd2f0019106b020471bea 100644 (file)
@@ -1112,19 +1112,13 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
        return preset;
 }
 
-static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
+void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
        int div = 0; /* Initialized for compiler warning */
        int real_div = div, clk_mul = 1;
        u16 clk = 0;
        unsigned long timeout;
 
-       if (host->ops->set_clock) {
-               host->ops->set_clock(host, clock);
-               if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
-                       return;
-       }
-
        host->mmc->actual_clock = 0;
 
        sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
@@ -1221,6 +1215,7 @@ clock_set:
        clk |= SDHCI_CLOCK_CARD_EN;
        sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 }
+EXPORT_SYMBOL_GPL(sdhci_set_clock);
 
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
 {
@@ -1439,7 +1434,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
                sdhci_enable_preset_value(host, false);
 
        if (!ios->clock || ios->clock != host->clock) {
-               sdhci_set_clock(host, ios->clock);
+               host->ops->set_clock(host, ios->clock);
                host->clock = ios->clock;
        }
 
@@ -1510,7 +1505,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
                        sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
                        /* Re-enable SD Clock */
-                       sdhci_set_clock(host, host->clock);
+                       host->ops->set_clock(host, host->clock);
                }
 
 
@@ -1555,7 +1550,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
                }
 
                /* Re-enable SD Clock */
-               sdhci_set_clock(host, host->clock);
+               host->ops->set_clock(host, host->clock);
        } else
                sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -2129,7 +2124,7 @@ static void sdhci_tasklet_finish(unsigned long param)
                /* Some controllers need this kick or reset won't work here */
                if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
                        /* This is to force an update */
-                       sdhci_set_clock(host, host->clock);
+                       host->ops->set_clock(host, host->clock);
 
                /* Spec says we should do both at the same time, but Ricoh
                   controllers do not like that. */
index 7d84cb3b0e004ea2f389166f5772b53c28f4570a..ac20195f667b2facd54e0d57fbf78edb022242d6 100644 (file)
@@ -400,6 +400,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
        return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
 }
 
+void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
 
index 02919ef99419fbdb6e50ca1e0494851127fe5fa9..72a90baf111f1bfbc2fca7e5fc6e6ace8fe4b6ec 100644 (file)
@@ -57,8 +57,6 @@ 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)
 /* Controller does not like fast PIO transfers */
 #define SDHCI_QUIRK_PIO_NEEDS_DELAY                    (1<<18)
 /* Controller has to be forced to use block size of 2048 bytes */