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