aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-04-25 07:58:55 -0400
committerChris Ball <chris@printf.net>2014-05-22 07:26:32 -0400
commit1771059cf5f9c09e37ef6315df8acf120f2642fc (patch)
tree5d0a909b2834d01fd251697b25a5fb3a24ca222b /drivers/mmc
parent1650d0c71a209c7d6bdddda8a7e187c537ceb71a (diff)
mmc: sdhci: convert sdhci_set_clock() into a library function
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>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-acpi.c2
-rw-r--r--drivers/mmc/host/sdhci-bcm-kona.c1
-rw-r--r--drivers/mmc/host/sdhci-bcm2835.c1
-rw-r--r--drivers/mmc/host/sdhci-cns3xxx.c3
-rw-r--r--drivers/mmc/host/sdhci-dove.c1
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h1
-rw-r--r--drivers/mmc/host/sdhci-of-arasan.c1
-rw-r--r--drivers/mmc/host/sdhci-of-hlwd.c1
-rw-r--r--drivers/mmc/host/sdhci-pci.c1
-rw-r--r--drivers/mmc/host/sdhci-pltfm.c1
-rw-r--r--drivers/mmc/host/sdhci-pxav2.c1
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c1
-rw-r--r--drivers/mmc/host/sdhci-s3c.c19
-rw-r--r--drivers/mmc/host/sdhci-sirf.c1
-rw-r--r--drivers/mmc/host/sdhci-spear.c1
-rw-r--r--drivers/mmc/host/sdhci-tegra.c1
-rw-r--r--drivers/mmc/host/sdhci.c17
-rw-r--r--drivers/mmc/host/sdhci.h1
18 files changed, 36 insertions, 19 deletions
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index aca84a682551..323e2a688563 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -102,12 +102,14 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
102} 102}
103 103
104static const struct sdhci_ops sdhci_acpi_ops_dflt = { 104static const struct sdhci_ops sdhci_acpi_ops_dflt = {
105 .set_clock = sdhci_set_clock,
105 .enable_dma = sdhci_acpi_enable_dma, 106 .enable_dma = sdhci_acpi_enable_dma,
106 .set_bus_width = sdhci_set_bus_width, 107 .set_bus_width = sdhci_set_bus_width,
107 .reset = sdhci_reset, 108 .reset = sdhci_reset,
108}; 109};
109 110
110static const struct sdhci_ops sdhci_acpi_ops_int = { 111static const struct sdhci_ops sdhci_acpi_ops_int = {
112 .set_clock = sdhci_set_clock,
111 .enable_dma = sdhci_acpi_enable_dma, 113 .enable_dma = sdhci_acpi_enable_dma,
112 .set_bus_width = sdhci_set_bus_width, 114 .set_bus_width = sdhci_set_bus_width,
113 .reset = sdhci_reset, 115 .reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 7b97bfab910d..e610811c09b0 100644
--- a/drivers/mmc/host/sdhci-bcm-kona.c
+++ b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -206,6 +206,7 @@ static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
206} 206}
207 207
208static struct sdhci_ops sdhci_bcm_kona_ops = { 208static struct sdhci_ops sdhci_bcm_kona_ops = {
209 .set_clock = sdhci_set_clock,
209 .get_max_clock = sdhci_bcm_kona_get_max_clk, 210 .get_max_clock = sdhci_bcm_kona_get_max_clk,
210 .get_timeout_clock = sdhci_bcm_kona_get_timeout_clock, 211 .get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
211 .platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks, 212 .platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 289b1c80d5fc..74906d6008e1 100644
--- a/drivers/mmc/host/sdhci-bcm2835.c
+++ b/drivers/mmc/host/sdhci-bcm2835.c
@@ -131,6 +131,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
131 .read_l = bcm2835_sdhci_readl, 131 .read_l = bcm2835_sdhci_readl,
132 .read_w = bcm2835_sdhci_readw, 132 .read_w = bcm2835_sdhci_readw,
133 .read_b = bcm2835_sdhci_readb, 133 .read_b = bcm2835_sdhci_readb,
134 .set_clock = sdhci_set_clock,
134 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 135 .get_max_clock = sdhci_pltfm_clk_get_max_clock,
135 .get_min_clock = bcm2835_sdhci_get_min_clock, 136 .get_min_clock = bcm2835_sdhci_get_min_clock,
136 .set_bus_width = sdhci_set_bus_width, 137 .set_bus_width = sdhci_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 416f4a4c2e35..587d73ef33ff 100644
--- a/drivers/mmc/host/sdhci-cns3xxx.c
+++ b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -89,8 +89,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
89 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | 89 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
90 SDHCI_QUIRK_INVERTED_WRITE_PROTECT | 90 SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
91 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | 91 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
92 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | 92 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
93 SDHCI_QUIRK_NONSTANDARD_CLOCK,
94}; 93};
95 94
96static int sdhci_cns3xxx_probe(struct platform_device *pdev) 95static int sdhci_cns3xxx_probe(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 1408cc11d881..8ef4ab52f8e0 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -86,6 +86,7 @@ static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
86static const struct sdhci_ops sdhci_dove_ops = { 86static const struct sdhci_ops sdhci_dove_ops = {
87 .read_w = sdhci_dove_readw, 87 .read_w = sdhci_dove_readw,
88 .read_l = sdhci_dove_readl, 88 .read_l = sdhci_dove_readl,
89 .set_clock = sdhci_set_clock,
89 .set_bus_width = sdhci_set_bus_width, 90 .set_bus_width = sdhci_set_bus_width,
90 .reset = sdhci_reset, 91 .reset = sdhci_reset,
91}; 92};
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index de69bddc3afc..3497cfaf683c 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -20,7 +20,6 @@
20 20
21#define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \ 21#define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
22 SDHCI_QUIRK_NO_BUSY_IRQ | \ 22 SDHCI_QUIRK_NO_BUSY_IRQ | \
23 SDHCI_QUIRK_NONSTANDARD_CLOCK | \
24 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \ 23 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
25 SDHCI_QUIRK_PIO_NEEDS_DELAY) 24 SDHCI_QUIRK_PIO_NEEDS_DELAY)
26 25
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index faef21740584..f0ee594f25d1 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -52,6 +52,7 @@ static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
52} 52}
53 53
54static struct sdhci_ops sdhci_arasan_ops = { 54static struct sdhci_ops sdhci_arasan_ops = {
55 .set_clock = sdhci_set_clock,
55 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 56 .get_max_clock = sdhci_pltfm_clk_get_max_clock,
56 .get_timeout_clock = sdhci_arasan_get_timeout_clock, 57 .get_timeout_clock = sdhci_arasan_get_timeout_clock,
57 .set_bus_width = sdhci_set_bus_width, 58 .set_bus_width = sdhci_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index fb01958cb18e..a4a1f0f2c0a0 100644
--- a/drivers/mmc/host/sdhci-of-hlwd.c
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -58,6 +58,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
58 .write_l = sdhci_hlwd_writel, 58 .write_l = sdhci_hlwd_writel,
59 .write_w = sdhci_hlwd_writew, 59 .write_w = sdhci_hlwd_writew,
60 .write_b = sdhci_hlwd_writeb, 60 .write_b = sdhci_hlwd_writeb,
61 .set_clock = sdhci_set_clock,
61 .set_bus_width = sdhci_set_bus_width, 62 .set_bus_width = sdhci_set_bus_width,
62 .reset = sdhci_reset, 63 .reset = sdhci_reset,
63}; 64};
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 87f9dd91f68c..b3a28f6b170e 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -1078,6 +1078,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
1078} 1078}
1079 1079
1080static const struct sdhci_ops sdhci_pci_ops = { 1080static const struct sdhci_ops sdhci_pci_ops = {
1081 .set_clock = sdhci_set_clock,
1081 .enable_dma = sdhci_pci_enable_dma, 1082 .enable_dma = sdhci_pci_enable_dma,
1082 .set_bus_width = sdhci_pci_set_bus_width, 1083 .set_bus_width = sdhci_pci_set_bus_width,
1083 .reset = sdhci_reset, 1084 .reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index bfbf467b61c7..1fb89f44bd58 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -45,6 +45,7 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
45EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock); 45EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
46 46
47static const struct sdhci_ops sdhci_pltfm_ops = { 47static const struct sdhci_ops sdhci_pltfm_ops = {
48 .set_clock = sdhci_set_clock,
48 .set_bus_width = sdhci_set_bus_width, 49 .set_bus_width = sdhci_set_bus_width,
49 .reset = sdhci_reset, 50 .reset = sdhci_reset,
50}; 51};
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 2eee0c8b88eb..db5257bf032e 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -112,6 +112,7 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
112} 112}
113 113
114static const struct sdhci_ops pxav2_sdhci_ops = { 114static const struct sdhci_ops pxav2_sdhci_ops = {
115 .set_clock = sdhci_set_clock,
115 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 116 .get_max_clock = sdhci_pltfm_clk_get_max_clock,
116 .set_bus_width = pxav2_mmc_set_bus_width, 117 .set_bus_width = pxav2_mmc_set_bus_width,
117 .reset = pxav2_reset, 118 .reset = pxav2_reset,
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 86564233ae93..8a40e079a57e 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -225,6 +225,7 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
225} 225}
226 226
227static const struct sdhci_ops pxav3_sdhci_ops = { 227static const struct sdhci_ops pxav3_sdhci_ops = {
228 .set_clock = sdhci_set_clock,
228 .set_uhs_signaling = pxav3_set_uhs_signaling, 229 .set_uhs_signaling = pxav3_set_uhs_signaling,
229 .platform_send_init_74_clocks = pxav3_gen_init_74_clocks, 230 .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
230 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 231 .get_max_clock = sdhci_pltfm_clk_get_max_clock,
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 9d710b748b9c..9e6f1c52982c 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -55,6 +55,8 @@ struct sdhci_s3c {
55 struct clk *clk_io; 55 struct clk *clk_io;
56 struct clk *clk_bus[MAX_BUS_CLK]; 56 struct clk *clk_bus[MAX_BUS_CLK];
57 unsigned long clk_rates[MAX_BUS_CLK]; 57 unsigned long clk_rates[MAX_BUS_CLK];
58
59 bool no_divider;
58}; 60};
59 61
60/** 62/**
@@ -67,6 +69,7 @@ struct sdhci_s3c {
67 */ 69 */
68struct sdhci_s3c_drv_data { 70struct sdhci_s3c_drv_data {
69 unsigned int sdhci_quirks; 71 unsigned int sdhci_quirks;
72 bool no_divider;
70}; 73};
71 74
72static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host) 75static 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,
116 * If controller uses a non-standard clock division, find the best clock 119 * If controller uses a non-standard clock division, find the best clock
117 * speed possible with selected clock source and skip the division. 120 * speed possible with selected clock source and skip the division.
118 */ 121 */
119 if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) { 122 if (ourhost->no_divider) {
120 rate = clk_round_rate(clksrc, wanted); 123 rate = clk_round_rate(clksrc, wanted);
121 return wanted - rate; 124 return wanted - rate;
122 } 125 }
@@ -161,8 +164,10 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
161 host->mmc->actual_clock = 0; 164 host->mmc->actual_clock = 0;
162 165
163 /* don't bother if the clock is going off. */ 166 /* don't bother if the clock is going off. */
164 if (clock == 0) 167 if (clock == 0) {
168 sdhci_set_clock(host, clock);
165 return; 169 return;
170 }
166 171
167 for (src = 0; src < MAX_BUS_CLK; src++) { 172 for (src = 0; src < MAX_BUS_CLK; src++) {
168 delta = sdhci_s3c_consider_clock(ourhost, src, clock); 173 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)
214 if (clock < 25 * 1000000) 219 if (clock < 25 * 1000000)
215 ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2); 220 ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
216 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3); 221 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
222
223 sdhci_set_clock(host, clock);
217} 224}
218 225
219/** 226/**
@@ -603,8 +610,10 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
603 /* Setup quirks for the controller */ 610 /* Setup quirks for the controller */
604 host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; 611 host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
605 host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; 612 host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
606 if (drv_data) 613 if (drv_data) {
607 host->quirks |= drv_data->sdhci_quirks; 614 host->quirks |= drv_data->sdhci_quirks;
615 sc->no_divider = drv_data->no_divider;
616 }
608 617
609#ifndef CONFIG_MMC_SDHCI_S3C_DMA 618#ifndef CONFIG_MMC_SDHCI_S3C_DMA
610 619
@@ -653,7 +662,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
653 * If controller does not have internal clock divider, 662 * If controller does not have internal clock divider,
654 * we can use overriding functions instead of default. 663 * we can use overriding functions instead of default.
655 */ 664 */
656 if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) { 665 if (sc->no_divider) {
657 sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock; 666 sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
658 sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; 667 sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
659 sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; 668 sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
@@ -794,7 +803,7 @@ static const struct dev_pm_ops sdhci_s3c_pmops = {
794 803
795#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) 804#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
796static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = { 805static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
797 .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK, 806 .no_divider = true,
798}; 807};
799#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data) 808#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
800#else 809#else
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 5d79e10e1ba2..3b775348b470 100644
--- a/drivers/mmc/host/sdhci-sirf.c
+++ b/drivers/mmc/host/sdhci-sirf.c
@@ -28,6 +28,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
28} 28}
29 29
30static struct sdhci_ops sdhci_sirf_ops = { 30static struct sdhci_ops sdhci_sirf_ops = {
31 .set_clock = sdhci_set_clock,
31 .get_max_clock = sdhci_sirf_get_max_clk, 32 .get_max_clock = sdhci_sirf_get_max_clk,
32 .set_bus_width = sdhci_set_bus_width, 33 .set_bus_width = sdhci_set_bus_width,
33 .reset = sdhci_reset, 34 .reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index c2a2bedc8813..8bf64ab36720 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -38,6 +38,7 @@ struct spear_sdhci {
38 38
39/* sdhci ops */ 39/* sdhci ops */
40static const struct sdhci_ops sdhci_pltfm_ops = { 40static const struct sdhci_ops sdhci_pltfm_ops = {
41 .set_clock = sdhci_set_clock,
41 .set_bus_width = sdhci_set_bus_width, 42 .set_bus_width = sdhci_set_bus_width,
42 .reset = sdhci_reset, 43 .reset = sdhci_reset,
43}; 44};
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 7754c0319fda..a0a8b5cc3b0c 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -153,6 +153,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
153 .read_l = tegra_sdhci_readl, 153 .read_l = tegra_sdhci_readl,
154 .read_w = tegra_sdhci_readw, 154 .read_w = tegra_sdhci_readw,
155 .write_l = tegra_sdhci_writel, 155 .write_l = tegra_sdhci_writel,
156 .set_clock = sdhci_set_clock,
156 .set_bus_width = tegra_sdhci_set_bus_width, 157 .set_bus_width = tegra_sdhci_set_bus_width,
157 .reset = tegra_sdhci_reset, 158 .reset = tegra_sdhci_reset,
158}; 159};
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d9b91fc17bb0..69e58d071b33 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1112,19 +1112,13 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
1112 return preset; 1112 return preset;
1113} 1113}
1114 1114
1115static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) 1115void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
1116{ 1116{
1117 int div = 0; /* Initialized for compiler warning */ 1117 int div = 0; /* Initialized for compiler warning */
1118 int real_div = div, clk_mul = 1; 1118 int real_div = div, clk_mul = 1;
1119 u16 clk = 0; 1119 u16 clk = 0;
1120 unsigned long timeout; 1120 unsigned long timeout;
1121 1121
1122 if (host->ops->set_clock) {
1123 host->ops->set_clock(host, clock);
1124 if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
1125 return;
1126 }
1127
1128 host->mmc->actual_clock = 0; 1122 host->mmc->actual_clock = 0;
1129 1123
1130 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); 1124 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
@@ -1221,6 +1215,7 @@ clock_set:
1221 clk |= SDHCI_CLOCK_CARD_EN; 1215 clk |= SDHCI_CLOCK_CARD_EN;
1222 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 1216 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
1223} 1217}
1218EXPORT_SYMBOL_GPL(sdhci_set_clock);
1224 1219
1225static int sdhci_set_power(struct sdhci_host *host, unsigned short power) 1220static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
1226{ 1221{
@@ -1439,7 +1434,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
1439 sdhci_enable_preset_value(host, false); 1434 sdhci_enable_preset_value(host, false);
1440 1435
1441 if (!ios->clock || ios->clock != host->clock) { 1436 if (!ios->clock || ios->clock != host->clock) {
1442 sdhci_set_clock(host, ios->clock); 1437 host->ops->set_clock(host, ios->clock);
1443 host->clock = ios->clock; 1438 host->clock = ios->clock;
1444 } 1439 }
1445 1440
@@ -1510,7 +1505,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
1510 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1505 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1511 1506
1512 /* Re-enable SD Clock */ 1507 /* Re-enable SD Clock */
1513 sdhci_set_clock(host, host->clock); 1508 host->ops->set_clock(host, host->clock);
1514 } 1509 }
1515 1510
1516 1511
@@ -1555,7 +1550,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
1555 } 1550 }
1556 1551
1557 /* Re-enable SD Clock */ 1552 /* Re-enable SD Clock */
1558 sdhci_set_clock(host, host->clock); 1553 host->ops->set_clock(host, host->clock);
1559 } else 1554 } else
1560 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1555 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1561 1556
@@ -2129,7 +2124,7 @@ static void sdhci_tasklet_finish(unsigned long param)
2129 /* Some controllers need this kick or reset won't work here */ 2124 /* Some controllers need this kick or reset won't work here */
2130 if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) 2125 if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
2131 /* This is to force an update */ 2126 /* This is to force an update */
2132 sdhci_set_clock(host, host->clock); 2127 host->ops->set_clock(host, host->clock);
2133 2128
2134 /* Spec says we should do both at the same time, but Ricoh 2129 /* Spec says we should do both at the same time, but Ricoh
2135 controllers do not like that. */ 2130 controllers do not like that. */
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7d84cb3b0e00..ac20195f667b 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -400,6 +400,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
400 return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED); 400 return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
401} 401}
402 402
403void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
403void sdhci_set_bus_width(struct sdhci_host *host, int width); 404void sdhci_set_bus_width(struct sdhci_host *host, int width);
404void sdhci_reset(struct sdhci_host *host, u8 mask); 405void sdhci_reset(struct sdhci_host *host, u8 mask);
405 406