aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sh_mobile_sdhi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sh_mobile_sdhi.c')
-rw-r--r--drivers/mmc/host/sh_mobile_sdhi.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index f344659dceac..2d6ce257a273 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -33,6 +33,8 @@
33 33
34#include "tmio_mmc.h" 34#include "tmio_mmc.h"
35 35
36#define EXT_ACC 0xe4
37
36struct sh_mobile_sdhi_of_data { 38struct sh_mobile_sdhi_of_data {
37 unsigned long tmio_flags; 39 unsigned long tmio_flags;
38}; 40};
@@ -54,7 +56,7 @@ static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int
54 struct mmc_host *mmc = platform_get_drvdata(pdev); 56 struct mmc_host *mmc = platform_get_drvdata(pdev);
55 struct tmio_mmc_host *host = mmc_priv(mmc); 57 struct tmio_mmc_host *host = mmc_priv(mmc);
56 struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data); 58 struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
57 int ret = clk_enable(priv->clk); 59 int ret = clk_prepare_enable(priv->clk);
58 if (ret < 0) 60 if (ret < 0)
59 return ret; 61 return ret;
60 62
@@ -67,7 +69,7 @@ static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev)
67 struct mmc_host *mmc = platform_get_drvdata(pdev); 69 struct mmc_host *mmc = platform_get_drvdata(pdev);
68 struct tmio_mmc_host *host = mmc_priv(mmc); 70 struct tmio_mmc_host *host = mmc_priv(mmc);
69 struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data); 71 struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
70 clk_disable(priv->clk); 72 clk_disable_unprepare(priv->clk);
71} 73}
72 74
73static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host) 75static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
@@ -133,9 +135,15 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
133 struct tmio_mmc_data *mmc_data; 135 struct tmio_mmc_data *mmc_data;
134 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; 136 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
135 struct tmio_mmc_host *host; 137 struct tmio_mmc_host *host;
138 struct resource *res;
136 int irq, ret, i = 0; 139 int irq, ret, i = 0;
137 bool multiplexed_isr = true; 140 bool multiplexed_isr = true;
138 struct tmio_mmc_dma *dma_priv; 141 struct tmio_mmc_dma *dma_priv;
142 u16 ver;
143
144 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
145 if (!res)
146 return -EINVAL;
139 147
140 priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_mobile_sdhi), GFP_KERNEL); 148 priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
141 if (priv == NULL) { 149 if (priv == NULL) {
@@ -206,11 +214,22 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
206 mmc_data->flags |= of_data->tmio_flags; 214 mmc_data->flags |= of_data->tmio_flags;
207 } 215 }
208 216
217 /* SD control register space size is 0x100, 0x200 for bus_shift=1 */
218 mmc_data->bus_shift = resource_size(res) >> 9;
219
209 ret = tmio_mmc_host_probe(&host, pdev, mmc_data); 220 ret = tmio_mmc_host_probe(&host, pdev, mmc_data);
210 if (ret < 0) 221 if (ret < 0)
211 goto eprobe; 222 goto eprobe;
212 223
213 /* 224 /*
225 * FIXME:
226 * this Workaround can be more clever method
227 */
228 ver = sd_ctrl_read16(host, CTL_VERSION);
229 if (ver == 0xCB0D)
230 sd_ctrl_write16(host, EXT_ACC, 1);
231
232 /*
214 * Allow one or more specific (named) ISRs or 233 * Allow one or more specific (named) ISRs or
215 * one or more multiplexed (un-named) ISRs. 234 * one or more multiplexed (un-named) ISRs.
216 */ 235 */