Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: sdhci-esdhc: move common esdhc_set_clock to platform driver

We need a lot of imx6 specific things into common esdhc_set_clock
for support SD3.0 and eMMC DDR mode which is not needed for power pc
platforms, so esdhc_set_clock seems not so common anymore.

Instead of keeping add platform specfics things into this common API,
we choose to move that code into platform driver itself to handle.
This can also exclude the dependency between imx and power pc on this
headfile and is easy for maintain in the future.

Signed-off-by: Dong Aisheng <b29396@freescale.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>

authored by

Dong Aisheng and committed by
Chris Ball
d31fc00a c0e55129

+65 -40
+32 -1
drivers/mmc/host/sdhci-esdhc-imx.c
··· 409 409 unsigned int clock) 410 410 { 411 411 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 412 + unsigned int host_clock = clk_get_rate(pltfm_host->clk); 413 + int pre_div = 2; 414 + int div = 1; 415 + u32 temp; 412 416 413 - esdhc_set_clock(host, clock, clk_get_rate(pltfm_host->clk)); 417 + if (clock == 0) 418 + goto out; 419 + 420 + temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 421 + temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN 422 + | ESDHC_CLOCK_MASK); 423 + sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 424 + 425 + while (host_clock / pre_div / 16 > clock && pre_div < 256) 426 + pre_div *= 2; 427 + 428 + while (host_clock / pre_div / div > clock && div < 16) 429 + div++; 430 + 431 + dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", 432 + clock, host_clock / pre_div / div); 433 + 434 + pre_div >>= 1; 435 + div--; 436 + 437 + temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 438 + temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN 439 + | (div << ESDHC_DIVIDER_SHIFT) 440 + | (pre_div << ESDHC_PREDIV_SHIFT)); 441 + sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 442 + mdelay(1); 443 + out: 444 + host->clock = clock; 414 445 } 415 446 416 447 static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
-37
drivers/mmc/host/sdhci-esdhc.h
··· 49 49 50 50 #define ESDHC_HOST_CONTROL_RES 0x05 51 51 52 - static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock, 53 - unsigned int host_clock) 54 - { 55 - int pre_div = 2; 56 - int div = 1; 57 - u32 temp; 58 - 59 - if (clock == 0) 60 - goto out; 61 - 62 - temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 63 - temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN 64 - | ESDHC_CLOCK_MASK); 65 - sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 66 - 67 - while (host_clock / pre_div / 16 > clock && pre_div < 256) 68 - pre_div *= 2; 69 - 70 - while (host_clock / pre_div / div > clock && div < 16) 71 - div++; 72 - 73 - dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", 74 - clock, host_clock / pre_div / div); 75 - 76 - pre_div >>= 1; 77 - div--; 78 - 79 - temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 80 - temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN 81 - | (div << ESDHC_DIVIDER_SHIFT) 82 - | (pre_div << ESDHC_PREDIV_SHIFT)); 83 - sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 84 - mdelay(1); 85 - out: 86 - host->clock = clock; 87 - } 88 - 89 52 #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
+33 -2
drivers/mmc/host/sdhci-of-esdhc.c
··· 199 199 200 200 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) 201 201 { 202 + 203 + int pre_div = 2; 204 + int div = 1; 205 + u32 temp; 206 + 207 + if (clock == 0) 208 + goto out; 209 + 202 210 /* Workaround to reduce the clock frequency for p1010 esdhc */ 203 211 if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) { 204 212 if (clock > 20000000) ··· 215 207 clock -= 5000000; 216 208 } 217 209 218 - /* Set the clock */ 219 - esdhc_set_clock(host, clock, host->max_clk); 210 + temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 211 + temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN 212 + | ESDHC_CLOCK_MASK); 213 + sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 214 + 215 + while (host->max_clk / pre_div / 16 > clock && pre_div < 256) 216 + pre_div *= 2; 217 + 218 + while (host->max_clk / pre_div / div > clock && div < 16) 219 + div++; 220 + 221 + dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", 222 + clock, host_clock / pre_div / div); 223 + 224 + pre_div >>= 1; 225 + div--; 226 + 227 + temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 228 + temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN 229 + | (div << ESDHC_DIVIDER_SHIFT) 230 + | (pre_div << ESDHC_PREDIV_SHIFT)); 231 + sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 232 + mdelay(1); 233 + out: 234 + host->clock = clock; 220 235 } 221 236 222 237 #ifdef CONFIG_PM