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>
This commit is contained in:
parent
52c6182a47
commit
69d1fe18e9
1 changed files with 19 additions and 6 deletions
|
@ -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)
|
static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
|
||||||
{
|
{
|
||||||
struct tmio_mmc_data *pdata = host->pdata;
|
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
|
* 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)
|
||||||
*/
|
*/
|
||||||
if (pdata->flags & TMIO_MMC_SDIO_IRQ)
|
if (pdata->flags & TMIO_MMC_SDIO_IRQ)
|
||||||
disable_irq(host->irq);
|
disable_irq(host->irq);
|
||||||
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
|
/* implicit BUG_ON(!res) */
|
||||||
msleep(10);
|
if (resource_size(res) > 0x100) {
|
||||||
|
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
|
||||||
|
msleep(10);
|
||||||
|
}
|
||||||
if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
|
if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
|
||||||
tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
|
tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
|
||||||
enable_irq(host->irq);
|
enable_irq(host->irq);
|
||||||
|
@ -232,6 +236,7 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
|
||||||
static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
|
static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
|
||||||
{
|
{
|
||||||
struct tmio_mmc_data *pdata = host->pdata;
|
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_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
|
||||||
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
|
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
|
||||||
|
@ -239,8 +244,11 @@ static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
|
||||||
/* see comment in tmio_mmc_clk_stop above */
|
/* see comment in tmio_mmc_clk_stop above */
|
||||||
if (pdata->flags & TMIO_MMC_SDIO_IRQ)
|
if (pdata->flags & TMIO_MMC_SDIO_IRQ)
|
||||||
disable_irq(host->irq);
|
disable_irq(host->irq);
|
||||||
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
|
/* implicit BUG_ON(!res) */
|
||||||
msleep(10);
|
if (resource_size(res) > 0x100) {
|
||||||
|
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
|
||||||
|
msleep(10);
|
||||||
|
}
|
||||||
if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
|
if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
|
||||||
tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
|
tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
|
||||||
enable_irq(host->irq);
|
enable_irq(host->irq);
|
||||||
|
@ -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)
|
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 */
|
/* FIXME - should we set stop clock reg here */
|
||||||
sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
|
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);
|
msleep(10);
|
||||||
sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
|
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);
|
msleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue