Skip to content

Commit

Permalink
mmc: tmio: only access registers above 0xff, if available
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Guennadi Liakhovetski authored and Chris Ball committed Mar 25, 2011
1 parent 52c6182 commit 69d1fe1
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions drivers/mmc/host/tmio_mmc_pio.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
{
struct tmio_mmc_data *pdata = host->pdata;
struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);

/*
* Testing on sh-mobile showed that SDIO IRQs are unmasked when
Expand All @@ -218,8 +219,11 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
*/
if (pdata->flags & TMIO_MMC_SDIO_IRQ)
disable_irq(host->irq);
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
msleep(10);
/* implicit BUG_ON(!res) */
if (resource_size(res) > 0x100) {
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
msleep(10);
}
if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
enable_irq(host->irq);
Expand All @@ -232,15 +236,19 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
{
struct tmio_mmc_data *pdata = host->pdata;
struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);

sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
msleep(10);
/* see comment in tmio_mmc_clk_stop above */
if (pdata->flags & TMIO_MMC_SDIO_IRQ)
disable_irq(host->irq);
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
msleep(10);
/* implicit BUG_ON(!res) */
if (resource_size(res) > 0x100) {
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
msleep(10);
}
if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
enable_irq(host->irq);
Expand All @@ -249,12 +257,17 @@ static void tmio_mmc_clk_start(struct tmio_mmc_host *host)

static void tmio_mmc_reset(struct tmio_mmc_host *host)
{
struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);

/* FIXME - should we set stop clock reg here */
sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
/* implicit BUG_ON(!res) */
if (resource_size(res) > 0x100)
sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
msleep(10);
sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
if (resource_size(res) > 0x100)
sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
msleep(10);
}

Expand Down

0 comments on commit 69d1fe1

Please sign in to comment.