diff options
author | Philip Rakity <prakity@marvell.com> | 2011-01-21 14:26:40 -0500 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2011-05-24 21:02:33 -0400 |
commit | 393c1a34dd852dbf0c409ec94dd48057100480ea (patch) | |
tree | e24e7ceda2f730cfe53f4c5744f979a45f0478d6 | |
parent | 4b01681c77642c62a833187066c35e71e59caaf5 (diff) |
mmc: sdhci: Add pre and post reset processing for chip specific reset
Marvell pxa controllers have private registers that may need to be
modified before and after a reset is done.
For example, the SD reset operation, RESET_ALL, will reset the private
registers to their default state. This will cause the clock adjustment
registers that may have been programmed to have incorrect values.
RESET_DATA sometimes needs to be delayed before the reset is done
(depending on SoC) to enable any transactions being handled by the
SDIO card to be completed. Needed in pre SD 3.0 silicon to handle
clock gating.
Implement hooks to allow this to happen.
Signed-off-by: Philip Rakity <prakity@marvell.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | drivers/mmc/host/sdhci.c | 6 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 2 |
2 files changed, 8 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 4b97d5265526..a70a3d1ef35a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -156,6 +156,9 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) | |||
156 | if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) | 156 | if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) |
157 | ier = sdhci_readl(host, SDHCI_INT_ENABLE); | 157 | ier = sdhci_readl(host, SDHCI_INT_ENABLE); |
158 | 158 | ||
159 | if (host->ops->platform_reset_enter) | ||
160 | host->ops->platform_reset_enter(host, mask); | ||
161 | |||
159 | sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); | 162 | sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); |
160 | 163 | ||
161 | if (mask & SDHCI_RESET_ALL) | 164 | if (mask & SDHCI_RESET_ALL) |
@@ -176,6 +179,9 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) | |||
176 | mdelay(1); | 179 | mdelay(1); |
177 | } | 180 | } |
178 | 181 | ||
182 | if (host->ops->platform_reset_exit) | ||
183 | host->ops->platform_reset_exit(host, mask); | ||
184 | |||
179 | if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) | 185 | if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) |
180 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); | 186 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); |
181 | } | 187 | } |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 85750a94c612..c6e25a76d269 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -229,6 +229,8 @@ struct sdhci_ops { | |||
229 | void (*platform_send_init_74_clocks)(struct sdhci_host *host, | 229 | void (*platform_send_init_74_clocks)(struct sdhci_host *host, |
230 | u8 power_mode); | 230 | u8 power_mode); |
231 | unsigned int (*get_ro)(struct sdhci_host *host); | 231 | unsigned int (*get_ro)(struct sdhci_host *host); |
232 | void (*platform_reset_enter)(struct sdhci_host *host, u8 mask); | ||
233 | void (*platform_reset_exit)(struct sdhci_host *host, u8 mask); | ||
232 | }; | 234 | }; |
233 | 235 | ||
234 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS | 236 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS |