aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-s3c.c78
1 files changed, 17 insertions, 61 deletions
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 7e14db07eb30..bad0e00a3e8f 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -51,7 +51,7 @@ struct sdhci_s3c {
51 struct platform_device *pdev; 51 struct platform_device *pdev;
52 struct resource *ioarea; 52 struct resource *ioarea;
53 struct s3c_sdhci_platdata *pdata; 53 struct s3c_sdhci_platdata *pdata;
54 unsigned int cur_clk; 54 int cur_clk;
55 int ext_cd_irq; 55 int ext_cd_irq;
56 int ext_cd_gpio; 56 int ext_cd_gpio;
57 57
@@ -78,32 +78,6 @@ static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
78} 78}
79 79
80/** 80/**
81 * get_curclk - convert ctrl2 register to clock source number
82 * @ctrl2: Control2 register value.
83 */
84static u32 get_curclk(u32 ctrl2)
85{
86 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
87 ctrl2 >>= S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
88
89 return ctrl2;
90}
91
92static void sdhci_s3c_check_sclk(struct sdhci_host *host)
93{
94 struct sdhci_s3c *ourhost = to_s3c(host);
95 u32 tmp = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
96
97 if (get_curclk(tmp) != ourhost->cur_clk) {
98 dev_dbg(&ourhost->pdev->dev, "restored ctrl2 clock setting\n");
99
100 tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
101 tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
102 writel(tmp, host->ioaddr + S3C_SDHCI_CONTROL2);
103 }
104}
105
106/**
107 * sdhci_s3c_get_max_clk - callback to get maximum clock frequency. 81 * sdhci_s3c_get_max_clk - callback to get maximum clock frequency.
108 * @host: The SDHCI host instance. 82 * @host: The SDHCI host instance.
109 * 83 *
@@ -115,11 +89,6 @@ static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host)
115 unsigned long rate, max = 0; 89 unsigned long rate, max = 0;
116 int src; 90 int src;
117 91
118 /* note, a reset will reset the clock source */
119
120 sdhci_s3c_check_sclk(host);
121
122
123 for (src = 0; src < MAX_BUS_CLK; src++) { 92 for (src = 0; src < MAX_BUS_CLK; src++) {
124 rate = ourhost->clk_rates[src]; 93 rate = ourhost->clk_rates[src];
125 if (rate > max) 94 if (rate > max)
@@ -206,20 +175,22 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
206 struct clk *clk = ourhost->clk_bus[best_src]; 175 struct clk *clk = ourhost->clk_bus[best_src];
207 176
208 clk_prepare_enable(clk); 177 clk_prepare_enable(clk);
209 clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); 178 if (ourhost->cur_clk >= 0)
210 179 clk_disable_unprepare(
211 /* turn clock off to card before changing clock source */ 180 ourhost->clk_bus[ourhost->cur_clk]);
212 writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
213 181
214 ourhost->cur_clk = best_src; 182 ourhost->cur_clk = best_src;
215 host->max_clk = ourhost->clk_rates[best_src]; 183 host->max_clk = ourhost->clk_rates[best_src];
216
217 ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
218 ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
219 ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
220 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2);
221 } 184 }
222 185
186 /* turn clock off to card before changing clock source */
187 writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
188
189 ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
190 ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
191 ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
192 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2);
193
223 /* reprogram default hardware configuration */ 194 /* reprogram default hardware configuration */
224 writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, 195 writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA,
225 host->ioaddr + S3C64XX_SDHCI_CONTROL4); 196 host->ioaddr + S3C64XX_SDHCI_CONTROL4);
@@ -573,6 +544,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
573 sc->host = host; 544 sc->host = host;
574 sc->pdev = pdev; 545 sc->pdev = pdev;
575 sc->pdata = pdata; 546 sc->pdata = pdata;
547 sc->cur_clk = -1;
576 548
577 platform_set_drvdata(pdev, host); 549 platform_set_drvdata(pdev, host);
578 550
@@ -595,13 +567,6 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
595 continue; 567 continue;
596 568
597 clks++; 569 clks++;
598
599 /*
600 * save current clock index to know which clock bus
601 * is used later in overriding functions.
602 */
603 sc->cur_clk = ptr;
604
605 sc->clk_rates[ptr] = clk_get_rate(sc->clk_bus[ptr]); 570 sc->clk_rates[ptr] = clk_get_rate(sc->clk_bus[ptr]);
606 571
607 dev_info(dev, "clock source %d: %s (%ld Hz)\n", 572 dev_info(dev, "clock source %d: %s (%ld Hz)\n",
@@ -614,10 +579,6 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
614 goto err_no_busclks; 579 goto err_no_busclks;
615 } 580 }
616 581
617#ifndef CONFIG_PM_RUNTIME
618 clk_prepare_enable(sc->clk_bus[sc->cur_clk]);
619#endif
620
621 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 582 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
622 host->ioaddr = devm_ioremap_resource(&pdev->dev, res); 583 host->ioaddr = devm_ioremap_resource(&pdev->dev, res);
623 if (IS_ERR(host->ioaddr)) { 584 if (IS_ERR(host->ioaddr)) {
@@ -730,10 +691,6 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
730 return 0; 691 return 0;
731 692
732 err_req_regs: 693 err_req_regs:
733#ifndef CONFIG_PM_RUNTIME
734 clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
735#endif
736
737 err_no_busclks: 694 err_no_busclks:
738 clk_disable_unprepare(sc->clk_io); 695 clk_disable_unprepare(sc->clk_io);
739 696
@@ -764,9 +721,6 @@ static int sdhci_s3c_remove(struct platform_device *pdev)
764 pm_runtime_dont_use_autosuspend(&pdev->dev); 721 pm_runtime_dont_use_autosuspend(&pdev->dev);
765 pm_runtime_disable(&pdev->dev); 722 pm_runtime_disable(&pdev->dev);
766 723
767#ifndef CONFIG_PM_RUNTIME
768 clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
769#endif
770 clk_disable_unprepare(sc->clk_io); 724 clk_disable_unprepare(sc->clk_io);
771 725
772 sdhci_free_host(host); 726 sdhci_free_host(host);
@@ -800,7 +754,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev)
800 754
801 ret = sdhci_runtime_suspend_host(host); 755 ret = sdhci_runtime_suspend_host(host);
802 756
803 clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); 757 if (ourhost->cur_clk >= 0)
758 clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
804 clk_disable_unprepare(busclk); 759 clk_disable_unprepare(busclk);
805 return ret; 760 return ret;
806} 761}
@@ -813,7 +768,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev)
813 int ret; 768 int ret;
814 769
815 clk_prepare_enable(busclk); 770 clk_prepare_enable(busclk);
816 clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); 771 if (ourhost->cur_clk >= 0)
772 clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
817 ret = sdhci_runtime_resume_host(host); 773 ret = sdhci_runtime_resume_host(host);
818 return ret; 774 return ret;
819} 775}