diff options
Diffstat (limited to 'drivers/mmc/host/sh_mobile_sdhi.c')
-rw-r--r-- | drivers/mmc/host/sh_mobile_sdhi.c | 23 |
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 | |||
36 | struct sh_mobile_sdhi_of_data { | 38 | struct 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 | ||
73 | static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host) | 75 | static 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 | */ |