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>

authored by Guennadi Liakhovetski and committed by Chris Ball 69d1fe18 52c6182a

+19 -6
+19 -6
drivers/mmc/host/tmio_mmc_pio.c
··· 209 209 static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) 210 210 { 211 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 215 * Testing on sh-mobile showed that SDIO IRQs are unmasked when ··· 219 218 */ 220 219 if (pdata->flags & TMIO_MMC_SDIO_IRQ) 221 220 disable_irq(host->irq); 222 - sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); 223 - msleep(10); 221 + /* implicit BUG_ON(!res) */ 222 + if (resource_size(res) > 0x100) { 223 + sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); 224 + msleep(10); 225 + } 224 226 if (pdata->flags & TMIO_MMC_SDIO_IRQ) { 225 227 tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled); 226 228 enable_irq(host->irq); ··· 236 232 static void tmio_mmc_clk_start(struct tmio_mmc_host *host) 237 233 { 238 234 struct tmio_mmc_data *pdata = host->pdata; 235 + struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0); 239 236 240 237 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 | 241 238 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); ··· 244 239 /* see comment in tmio_mmc_clk_stop above */ 245 240 if (pdata->flags & TMIO_MMC_SDIO_IRQ) 246 241 disable_irq(host->irq); 247 - sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); 248 - msleep(10); 242 + /* implicit BUG_ON(!res) */ 243 + if (resource_size(res) > 0x100) { 244 + sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); 245 + msleep(10); 246 + } 249 247 if (pdata->flags & TMIO_MMC_SDIO_IRQ) { 250 248 tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled); 251 249 enable_irq(host->irq); ··· 257 249 258 250 static void tmio_mmc_reset(struct tmio_mmc_host *host) 259 251 { 252 + struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0); 253 + 260 254 /* FIXME - should we set stop clock reg here */ 261 255 sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); 262 - sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); 256 + /* implicit BUG_ON(!res) */ 257 + if (resource_size(res) > 0x100) 258 + sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); 263 259 msleep(10); 264 260 sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); 265 - sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); 261 + if (resource_size(res) > 0x100) 262 + sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); 266 263 msleep(10); 267 264 } 268 265