aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-03-07 03:31:14 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2012-04-25 11:03:38 -0400
commit529aa29e033f3bcd3346de1532e4bd5ff969fd0d (patch)
tree1742f3a452f86de0aef7791d6cbc4d0da8dae13f /drivers/mmc
parentf4d40de39a23f0c39cca55ac63e1175c69c3d2f7 (diff)
mmc mxcmmc: do not depend on grouped clocks
the current i.MX clock support groups together unrelated clocks to a single clock which is then used by the driver. This can't be accomplished with the generic clock framework so we instead request the individual clocks in the driver. For i.MX there are generally three different clocks: ipg: bus clock (needed to access registers) ahb: dma relevant clock, sometimes referred to as hclk in the datasheet per: bit clock, pixel clock This patch changes the driver to request the individual clocks. Currently all clk_get will get the same clock until the SoCs are converted to the generic clock framework Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mxcmmc.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index b2058b432320..28ed52d58f7f 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -136,7 +136,8 @@ struct mxcmci_host {
136 u16 rev_no; 136 u16 rev_no;
137 unsigned int cmdat; 137 unsigned int cmdat;
138 138
139 struct clk *clk; 139 struct clk *clk_ipg;
140 struct clk *clk_per;
140 141
141 int clock; 142 int clock;
142 143
@@ -672,7 +673,7 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
672{ 673{
673 unsigned int divider; 674 unsigned int divider;
674 int prescaler = 0; 675 int prescaler = 0;
675 unsigned int clk_in = clk_get_rate(host->clk); 676 unsigned int clk_in = clk_get_rate(host->clk_per);
676 677
677 while (prescaler <= 0x800) { 678 while (prescaler <= 0x800) {
678 for (divider = 1; divider <= 0xF; divider++) { 679 for (divider = 1; divider <= 0xF; divider++) {
@@ -900,12 +901,20 @@ static int mxcmci_probe(struct platform_device *pdev)
900 host->res = r; 901 host->res = r;
901 host->irq = irq; 902 host->irq = irq;
902 903
903 host->clk = clk_get(&pdev->dev, NULL); 904 host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
904 if (IS_ERR(host->clk)) { 905 if (IS_ERR(host->clk_ipg)) {
905 ret = PTR_ERR(host->clk); 906 ret = PTR_ERR(host->clk_ipg);
906 goto out_iounmap; 907 goto out_iounmap;
907 } 908 }
908 clk_enable(host->clk); 909
910 host->clk_per = devm_clk_get(&pdev->dev, "per");
911 if (IS_ERR(host->clk_per)) {
912 ret = PTR_ERR(host->clk_per);
913 goto out_iounmap;
914 }
915
916 clk_prepare_enable(host->clk_per);
917 clk_prepare_enable(host->clk_ipg);
909 918
910 mxcmci_softreset(host); 919 mxcmci_softreset(host);
911 920
@@ -917,8 +926,8 @@ static int mxcmci_probe(struct platform_device *pdev)
917 goto out_clk_put; 926 goto out_clk_put;
918 } 927 }
919 928
920 mmc->f_min = clk_get_rate(host->clk) >> 16; 929 mmc->f_min = clk_get_rate(host->clk_per) >> 16;
921 mmc->f_max = clk_get_rate(host->clk) >> 1; 930 mmc->f_max = clk_get_rate(host->clk_per) >> 1;
922 931
923 /* recommended in data sheet */ 932 /* recommended in data sheet */
924 writew(0x2db4, host->base + MMC_REG_READ_TO); 933 writew(0x2db4, host->base + MMC_REG_READ_TO);
@@ -967,8 +976,8 @@ out_free_dma:
967 if (host->dma) 976 if (host->dma)
968 dma_release_channel(host->dma); 977 dma_release_channel(host->dma);
969out_clk_put: 978out_clk_put:
970 clk_disable(host->clk); 979 clk_disable_unprepare(host->clk_per);
971 clk_put(host->clk); 980 clk_disable_unprepare(host->clk_ipg);
972out_iounmap: 981out_iounmap:
973 iounmap(host->base); 982 iounmap(host->base);
974out_free: 983out_free:
@@ -999,8 +1008,8 @@ static int mxcmci_remove(struct platform_device *pdev)
999 if (host->dma) 1008 if (host->dma)
1000 dma_release_channel(host->dma); 1009 dma_release_channel(host->dma);
1001 1010
1002 clk_disable(host->clk); 1011 clk_disable_unprepare(host->clk_per);
1003 clk_put(host->clk); 1012 clk_disable_unprepare(host->clk_ipg);
1004 1013
1005 release_mem_region(host->res->start, resource_size(host->res)); 1014 release_mem_region(host->res->start, resource_size(host->res));
1006 1015
@@ -1018,7 +1027,8 @@ static int mxcmci_suspend(struct device *dev)
1018 1027
1019 if (mmc) 1028 if (mmc)
1020 ret = mmc_suspend_host(mmc); 1029 ret = mmc_suspend_host(mmc);
1021 clk_disable(host->clk); 1030 clk_disable_unprepare(host->clk_per);
1031 clk_disable_unprepare(host->clk_ipg);
1022 1032
1023 return ret; 1033 return ret;
1024} 1034}
@@ -1029,7 +1039,8 @@ static int mxcmci_resume(struct device *dev)
1029 struct mxcmci_host *host = mmc_priv(mmc); 1039 struct mxcmci_host *host = mmc_priv(mmc);
1030 int ret = 0; 1040 int ret = 0;
1031 1041
1032 clk_enable(host->clk); 1042 clk_prepare_enable(host->clk_per);
1043 clk_prepare_enable(host->clk_ipg);
1033 if (mmc) 1044 if (mmc)
1034 ret = mmc_resume_host(mmc); 1045 ret = mmc_resume_host(mmc);
1035 1046