aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2011-03-09 11:28:55 -0500
committerChris Ball <cjb@laptop.org>2011-03-25 10:39:49 -0400
commit69d1fe18e92afb4687605a1ab2ec73fbc3bae344 (patch)
treef9cf934890b958d1d593405c8399d5ba973c11e7
parent52c6182a47fa66ad5f2647a831efa99c05b0a54e (diff)
mmc: tmio: only access registers above 0xff, if available
Not all tmio implementations have registers above oxff. Accessing them on thise platforms is dangerous. In some cases it leads to address wrapping to addresses below 0x100, which corrupts random unrelated registers. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/tmio_mmc_pio.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index a7406e3701c9..28e14c7a2540 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -209,6 +209,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
209static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) 209static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
210{ 210{
211 struct tmio_mmc_data *pdata = host->pdata; 211 struct tmio_mmc_data *pdata = host->pdata;
212 struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
212 213
213 /* 214 /*
214 * Testing on sh-mobile showed that SDIO IRQs are unmasked when 215 * Testing on sh-mobile showed that SDIO IRQs are unmasked when
@@ -218,8 +219,11 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
218 */ 219 */
219 if (pdata->flags & TMIO_MMC_SDIO_IRQ) 220 if (pdata->flags & TMIO_MMC_SDIO_IRQ)
220 disable_irq(host->irq); 221 disable_irq(host->irq);
221 sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); 222 /* implicit BUG_ON(!res) */
222 msleep(10); 223 if (resource_size(res) > 0x100) {
224 sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
225 msleep(10);
226 }
223 if (pdata->flags & TMIO_MMC_SDIO_IRQ) { 227 if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
224 tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled); 228 tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
225 enable_irq(host->irq); 229 enable_irq(host->irq);
@@ -232,6 +236,7 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
232static void tmio_mmc_clk_start(struct tmio_mmc_host *host) 236static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
233{ 237{
234 struct tmio_mmc_data *pdata = host->pdata; 238 struct tmio_mmc_data *pdata = host->pdata;
239 struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
235 240
236 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 | 241 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
237 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); 242 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
@@ -239,8 +244,11 @@ static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
239 /* see comment in tmio_mmc_clk_stop above */ 244 /* see comment in tmio_mmc_clk_stop above */
240 if (pdata->flags & TMIO_MMC_SDIO_IRQ) 245 if (pdata->flags & TMIO_MMC_SDIO_IRQ)
241 disable_irq(host->irq); 246 disable_irq(host->irq);
242 sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); 247 /* implicit BUG_ON(!res) */
243 msleep(10); 248 if (resource_size(res) > 0x100) {
249 sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
250 msleep(10);
251 }
244 if (pdata->flags & TMIO_MMC_SDIO_IRQ) { 252 if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
245 tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled); 253 tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
246 enable_irq(host->irq); 254 enable_irq(host->irq);
@@ -249,12 +257,17 @@ static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
249 257
250static void tmio_mmc_reset(struct tmio_mmc_host *host) 258static void tmio_mmc_reset(struct tmio_mmc_host *host)
251{ 259{
260 struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
261
252 /* FIXME - should we set stop clock reg here */ 262 /* FIXME - should we set stop clock reg here */
253 sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); 263 sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
254 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); 264 /* implicit BUG_ON(!res) */
265 if (resource_size(res) > 0x100)
266 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
255 msleep(10); 267 msleep(10);
256 sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); 268 sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
257 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); 269 if (resource_size(res) > 0x100)
270 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
258 msleep(10); 271 msleep(10);
259} 272}
260 273