From 6de707f200f73af7a58b58b3a5b956cff7b6e228 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 12 Jun 2012 23:29:35 +0200 Subject: mmc: tmio: Don't access hardware registers after stopping clocks The tmio_mmc_set_ios() function configures the MMC power, clock and bus width. When the mmc core requests the driver to power off the card, we inform runtime PM, that the controller can be suspended. This can lead to the MSTP clock being turned off. Writing to any 16-bit hardware registers with the MSTP clock off leads to timeouts and errors being printed to the kernel log. This can occur both when stopping the MMC clock and when configuring the bus width. To fix this, stop the MMC clock before calling put_runtime_pm(), and skip bus width configuration when power is off. Signed-off-by: Laurent Pinchart Tested-by: Kuninori Morimoto Tested-by: Simon Horman Acked-by: Guennadi Liakhovetski Signed-off-by: Chris Ball --- drivers/mmc/host/tmio_mmc_pio.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 7ffc489bed3..4f26edf0720 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -811,19 +811,21 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) host->set_pwr(host->pdev, 0); if (host->power) { + tmio_mmc_clk_stop(host); host->power = false; pm_runtime_put(dev); } - tmio_mmc_clk_stop(host); } - switch (ios->bus_width) { - case MMC_BUS_WIDTH_1: - sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0); - break; - case MMC_BUS_WIDTH_4: - sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); - break; + if (host->power) { + switch (ios->bus_width) { + case MMC_BUS_WIDTH_1: + sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0); + break; + case MMC_BUS_WIDTH_4: + sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); + break; + } } /* Let things settle. delay taken from winCE driver */ -- cgit v1.2.3