diff options
author | Manuel Lauss <mano@roarinelk.homelinux.net> | 2008-07-17 07:07:28 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-07-23 08:18:06 -0400 |
commit | dd8572af68229a65b6716b286395ad7f5e2ecc48 (patch) | |
tree | 205d20a1d2bcfacb213f049a195c4b5f02858ef7 /drivers/mmc | |
parent | d2f2761bb75ee365077b52c7e73a6e5164d3efa0 (diff) |
au1xmmc: suspend/resume implementation
Basic suspend/resume support: disable peripheral on suspend and
reinit on resume.
Tested on Au1200.
Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 3f15eb20489..99b20917cc0 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -1043,7 +1043,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) | |||
1043 | goto out6; | 1043 | goto out6; |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | platform_set_drvdata(pdev, mmc); | 1046 | platform_set_drvdata(pdev, host); |
1047 | 1047 | ||
1048 | printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X" | 1048 | printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X" |
1049 | " (mode=%s)\n", pdev->id, host->iobase, | 1049 | " (mode=%s)\n", pdev->id, host->iobase, |
@@ -1087,13 +1087,10 @@ out0: | |||
1087 | 1087 | ||
1088 | static int __devexit au1xmmc_remove(struct platform_device *pdev) | 1088 | static int __devexit au1xmmc_remove(struct platform_device *pdev) |
1089 | { | 1089 | { |
1090 | struct mmc_host *mmc = platform_get_drvdata(pdev); | 1090 | struct au1xmmc_host *host = platform_get_drvdata(pdev); |
1091 | struct au1xmmc_host *host; | ||
1092 | |||
1093 | if (mmc) { | ||
1094 | host = mmc_priv(mmc); | ||
1095 | 1091 | ||
1096 | mmc_remove_host(mmc); | 1092 | if (host) { |
1093 | mmc_remove_host(host->mmc); | ||
1097 | 1094 | ||
1098 | #ifdef CONFIG_LEDS_CLASS | 1095 | #ifdef CONFIG_LEDS_CLASS |
1099 | if (host->platdata && host->platdata->led) | 1096 | if (host->platdata && host->platdata->led) |
@@ -1101,8 +1098,8 @@ static int __devexit au1xmmc_remove(struct platform_device *pdev) | |||
1101 | #endif | 1098 | #endif |
1102 | 1099 | ||
1103 | if (host->platdata && host->platdata->cd_setup && | 1100 | if (host->platdata && host->platdata->cd_setup && |
1104 | !(mmc->caps & MMC_CAP_NEEDS_POLL)) | 1101 | !(host->mmc->caps & MMC_CAP_NEEDS_POLL)) |
1105 | host->platdata->cd_setup(mmc, 0); | 1102 | host->platdata->cd_setup(host->mmc, 0); |
1106 | 1103 | ||
1107 | au_writel(0, HOST_ENABLE(host)); | 1104 | au_writel(0, HOST_ENABLE(host)); |
1108 | au_writel(0, HOST_CONFIG(host)); | 1105 | au_writel(0, HOST_CONFIG(host)); |
@@ -1122,16 +1119,49 @@ static int __devexit au1xmmc_remove(struct platform_device *pdev) | |||
1122 | release_resource(host->ioarea); | 1119 | release_resource(host->ioarea); |
1123 | kfree(host->ioarea); | 1120 | kfree(host->ioarea); |
1124 | 1121 | ||
1125 | mmc_free_host(mmc); | 1122 | mmc_free_host(host->mmc); |
1123 | platform_set_drvdata(pdev, NULL); | ||
1126 | } | 1124 | } |
1127 | return 0; | 1125 | return 0; |
1128 | } | 1126 | } |
1129 | 1127 | ||
1128 | #ifdef CONFIG_PM | ||
1129 | static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state) | ||
1130 | { | ||
1131 | struct au1xmmc_host *host = platform_get_drvdata(pdev); | ||
1132 | int ret; | ||
1133 | |||
1134 | ret = mmc_suspend_host(host->mmc, state); | ||
1135 | if (ret) | ||
1136 | return ret; | ||
1137 | |||
1138 | au_writel(0, HOST_CONFIG2(host)); | ||
1139 | au_writel(0, HOST_CONFIG(host)); | ||
1140 | au_writel(0xffffffff, HOST_STATUS(host)); | ||
1141 | au_writel(0, HOST_ENABLE(host)); | ||
1142 | au_sync(); | ||
1143 | |||
1144 | return 0; | ||
1145 | } | ||
1146 | |||
1147 | static int au1xmmc_resume(struct platform_device *pdev) | ||
1148 | { | ||
1149 | struct au1xmmc_host *host = platform_get_drvdata(pdev); | ||
1150 | |||
1151 | au1xmmc_reset_controller(host); | ||
1152 | |||
1153 | return mmc_resume_host(host->mmc); | ||
1154 | } | ||
1155 | #else | ||
1156 | #define au1xmmc_suspend NULL | ||
1157 | #define au1xmmc_resume NULL | ||
1158 | #endif | ||
1159 | |||
1130 | static struct platform_driver au1xmmc_driver = { | 1160 | static struct platform_driver au1xmmc_driver = { |
1131 | .probe = au1xmmc_probe, | 1161 | .probe = au1xmmc_probe, |
1132 | .remove = au1xmmc_remove, | 1162 | .remove = au1xmmc_remove, |
1133 | .suspend = NULL, | 1163 | .suspend = au1xmmc_suspend, |
1134 | .resume = NULL, | 1164 | .resume = au1xmmc_resume, |
1135 | .driver = { | 1165 | .driver = { |
1136 | .name = DRIVER_NAME, | 1166 | .name = DRIVER_NAME, |
1137 | .owner = THIS_MODULE, | 1167 | .owner = THIS_MODULE, |