diff options
author | Nicolin Chen <Guangyu.Chen@freescale.com> | 2014-05-15 06:51:56 -0400 |
---|---|---|
committer | Nicolin Chen <Guangyu.Chen@freescale.com> | 2014-06-19 05:07:58 -0400 |
commit | 34c50abd9df28580b367070bc20b8bca6cd7655c (patch) | |
tree | 1b750d6cdb21d164974be53132dce0ae1346438a /sound/soc/fsl | |
parent | fd7d2c1a137c1b9d7adb58aaf06b90938172b964 (diff) |
ENGR00318773-9 ASoC: fsl_ssi: Add driver suspend and resume to support MEGA Fast
For i.MX6 SoloX, there is a mode of the SoC to shutdown all power source of
modules during system suspend and resume procedure. Thus, SSI needs to save
all the values of registers before the system suspend and restore them after
the system resume.
Acked-by: Wang Shengjiu <b02247@freescale.com>
Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index a66dd375047b..331c1465a818 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -53,9 +53,9 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) | |||
53 | } | 53 | } |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | #ifdef DEBUG | ||
57 | #define NUM_OF_SSI_REG (sizeof(struct ccsr_ssi) / sizeof(__be32)) | 56 | #define NUM_OF_SSI_REG (sizeof(struct ccsr_ssi) / sizeof(__be32)) |
58 | 57 | ||
58 | #ifdef DEBUG | ||
59 | void dump_reg(struct ccsr_ssi __iomem *ssi) | 59 | void dump_reg(struct ccsr_ssi __iomem *ssi) |
60 | { | 60 | { |
61 | u32 val, i; | 61 | u32 val, i; |
@@ -169,9 +169,25 @@ struct fsl_ssi_private { | |||
169 | unsigned int tfe0; | 169 | unsigned int tfe0; |
170 | } stats; | 170 | } stats; |
171 | 171 | ||
172 | u32 regcache[NUM_OF_SSI_REG]; | ||
172 | char name[1]; | 173 | char name[1]; |
173 | }; | 174 | }; |
174 | 175 | ||
176 | static bool fsl_ssi_volatile_reg(unsigned int reg) | ||
177 | { | ||
178 | switch (reg) { | ||
179 | case 0x0: /* stx0 */ | ||
180 | case 0x4: /* stx1 */ | ||
181 | case 0x8: /* srx0 */ | ||
182 | case 0xc: /* srx1 */ | ||
183 | case 0x14: /* sisr */ | ||
184 | case 0x50: /* saccst */ | ||
185 | return true; | ||
186 | default: | ||
187 | return false; | ||
188 | } | ||
189 | } | ||
190 | |||
175 | /** | 191 | /** |
176 | * fsl_ssi_isr: SSI interrupt handler | 192 | * fsl_ssi_isr: SSI interrupt handler |
177 | * | 193 | * |
@@ -1163,10 +1179,51 @@ static int fsl_ssi_runtime_suspend(struct device *dev) | |||
1163 | } | 1179 | } |
1164 | #endif | 1180 | #endif |
1165 | 1181 | ||
1182 | #ifdef CONFIG_PM_SLEEP | ||
1183 | static int fsl_ssi_suspend(struct device *dev) | ||
1184 | { | ||
1185 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); | ||
1186 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
1187 | int i; | ||
1188 | |||
1189 | clk_prepare_enable(ssi_private->coreclk); | ||
1190 | |||
1191 | for (i = 0; i < NUM_OF_SSI_REG; i++) { | ||
1192 | if (&ssi->stx0 + i == NULL || fsl_ssi_volatile_reg(i * 0x4)) | ||
1193 | continue; | ||
1194 | ssi_private->regcache[i] = read_ssi(&ssi->stx0 + i); | ||
1195 | } | ||
1196 | |||
1197 | clk_disable_unprepare(ssi_private->coreclk); | ||
1198 | |||
1199 | return 0; | ||
1200 | } | ||
1201 | |||
1202 | static int fsl_ssi_resume(struct device *dev) | ||
1203 | { | ||
1204 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); | ||
1205 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
1206 | int i; | ||
1207 | |||
1208 | clk_prepare_enable(ssi_private->coreclk); | ||
1209 | |||
1210 | for (i = 0; i < NUM_OF_SSI_REG; i++) { | ||
1211 | if (&ssi->stx0 + i == NULL || fsl_ssi_volatile_reg(i * 0x4)) | ||
1212 | continue; | ||
1213 | write_ssi(ssi_private->regcache[i], &ssi->stx0 + i); | ||
1214 | } | ||
1215 | |||
1216 | clk_disable_unprepare(ssi_private->coreclk); | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | #endif /* CONFIG_PM_SLEEP */ | ||
1221 | |||
1166 | static const struct dev_pm_ops fsl_ssi_pm = { | 1222 | static const struct dev_pm_ops fsl_ssi_pm = { |
1167 | SET_RUNTIME_PM_OPS(fsl_ssi_runtime_suspend, | 1223 | SET_RUNTIME_PM_OPS(fsl_ssi_runtime_suspend, |
1168 | fsl_ssi_runtime_resume, | 1224 | fsl_ssi_runtime_resume, |
1169 | NULL) | 1225 | NULL) |
1226 | SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume) | ||
1170 | }; | 1227 | }; |
1171 | 1228 | ||
1172 | static const struct of_device_id fsl_ssi_ids[] = { | 1229 | static const struct of_device_id fsl_ssi_ids[] = { |