summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-06-12 23:29:35 +0200
committerChris Ball <cjb@laptop.org>2012-07-21 00:02:07 -0400
commit6de707f200f73af7a58b58b3a5b956cff7b6e228 (patch)
tree6b4c98cbf5720e2acd5e2cd0958043434aa000ea
parent7541ca98477862e2e9988c6c2ceadbdccefa9d77 (diff)
downloadlinux-3.10-6de707f200f73af7a58b58b3a5b956cff7b6e228.tar.gz
linux-3.10-6de707f200f73af7a58b58b3a5b956cff7b6e228.tar.bz2
linux-3.10-6de707f200f73af7a58b58b3a5b956cff7b6e228.zip
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 <laurent.pinchart@ideasonboard.com> Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Tested-by: Simon Horman <horms@verge.net.au> Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/tmio_mmc_pio.c18
1 files 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 */