aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/omap_hsmmc.c
diff options
context:
space:
mode:
authorKim Kyuwon <chammoru@gmail.com>2009-02-20 07:10:08 -0500
committerPierre Ossman <drzeus@drzeus.cx>2009-03-24 16:29:59 -0400
commit1b331e69a2313f6e857890c7c2c40e3e2a74367a (patch)
treeb45fb12a701c4a4710ea72aeff3c5ff6b4c0790d /drivers/mmc/host/omap_hsmmc.c
parent9e57d60829f5c00ebf44df65a4b709359e285c20 (diff)
omap_hsmmc: Initialize hsmmc controller registers when resuming
Most registers lose its state when the processor wakes up from sleep state. Thus registers should be initialized, when the processor wakes up. However the current hsmmc 'resume' function doesn't consider this issue and finally makes deadlock. So this patch fixes this problem. Signed-off-by: Kim Kyuwon <chammoru@gmail.com> Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 303a7970806d..576bfa7216b3 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -56,6 +56,7 @@
56#define SDVS18 (0x5 << 9) 56#define SDVS18 (0x5 << 9)
57#define SDVS30 (0x6 << 9) 57#define SDVS30 (0x6 << 9)
58#define SDVS33 (0x7 << 9) 58#define SDVS33 (0x7 << 9)
59#define SDVS_MASK 0x00000E00
59#define SDVSCLR 0xFFFFF1FF 60#define SDVSCLR 0xFFFFF1FF
60#define SDVSDET 0x00000400 61#define SDVSDET 0x00000400
61#define AUTOIDLE 0x1 62#define AUTOIDLE 0x1
@@ -874,6 +875,34 @@ static int omap_hsmmc_get_ro(struct mmc_host *mmc)
874 return pdata->slots[0].get_ro(host->dev, 0); 875 return pdata->slots[0].get_ro(host->dev, 0);
875} 876}
876 877
878static void omap_hsmmc_init(struct mmc_omap_host *host)
879{
880 u32 hctl, capa, value;
881
882 /* Only MMC1 supports 3.0V */
883 if (host->id == OMAP_MMC1_DEVID) {
884 hctl = SDVS30;
885 capa = VS30 | VS18;
886 } else {
887 hctl = SDVS18;
888 capa = VS18;
889 }
890
891 value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
892 OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
893
894 value = OMAP_HSMMC_READ(host->base, CAPA);
895 OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
896
897 /* Set the controller to AUTO IDLE mode */
898 value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
899 OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
900
901 /* Set SD bus power bit */
902 value = OMAP_HSMMC_READ(host->base, HCTL);
903 OMAP_HSMMC_WRITE(host->base, HCTL, value | SDBP);
904}
905
877static struct mmc_host_ops mmc_omap_ops = { 906static struct mmc_host_ops mmc_omap_ops = {
878 .request = omap_mmc_request, 907 .request = omap_mmc_request,
879 .set_ios = omap_mmc_set_ios, 908 .set_ios = omap_mmc_set_ios,
@@ -889,7 +918,6 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
889 struct mmc_omap_host *host = NULL; 918 struct mmc_omap_host *host = NULL;
890 struct resource *res; 919 struct resource *res;
891 int ret = 0, irq; 920 int ret = 0, irq;
892 u32 hctl, capa;
893 921
894 if (pdata == NULL) { 922 if (pdata == NULL) {
895 dev_err(&pdev->dev, "Platform Data is missing\n"); 923 dev_err(&pdev->dev, "Platform Data is missing\n");
@@ -994,28 +1022,7 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
994 if (pdata->slots[host->slot_id].wires >= 4) 1022 if (pdata->slots[host->slot_id].wires >= 4)
995 mmc->caps |= MMC_CAP_4_BIT_DATA; 1023 mmc->caps |= MMC_CAP_4_BIT_DATA;
996 1024
997 /* Only MMC1 supports 3.0V */ 1025 omap_hsmmc_init(host);
998 if (host->id == OMAP_MMC1_DEVID) {
999 hctl = SDVS30;
1000 capa = VS30 | VS18;
1001 } else {
1002 hctl = SDVS18;
1003 capa = VS18;
1004 }
1005
1006 OMAP_HSMMC_WRITE(host->base, HCTL,
1007 OMAP_HSMMC_READ(host->base, HCTL) | hctl);
1008
1009 OMAP_HSMMC_WRITE(host->base, CAPA,
1010 OMAP_HSMMC_READ(host->base, CAPA) | capa);
1011
1012 /* Set the controller to AUTO IDLE mode */
1013 OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
1014 OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
1015
1016 /* Set SD bus power bit */
1017 OMAP_HSMMC_WRITE(host->base, HCTL,
1018 OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
1019 1026
1020 /* Request IRQ for MMC operations */ 1027 /* Request IRQ for MMC operations */
1021 ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED, 1028 ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED,
@@ -1205,6 +1212,8 @@ static int omap_mmc_resume(struct platform_device *pdev)
1205 dev_dbg(mmc_dev(host->mmc), 1212 dev_dbg(mmc_dev(host->mmc),
1206 "Enabling debounce clk failed\n"); 1213 "Enabling debounce clk failed\n");
1207 1214
1215 omap_hsmmc_init(host);
1216
1208 if (host->pdata->resume) { 1217 if (host->pdata->resume) {
1209 ret = host->pdata->resume(&pdev->dev, host->slot_id); 1218 ret = host->pdata->resume(&pdev->dev, host->slot_id);
1210 if (ret) 1219 if (ret)