diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-12-11 19:24:34 -0500 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2009-03-08 09:19:54 -0400 |
commit | aa8aba6944203a17a7e941b42d8415153c649660 (patch) | |
tree | 83b96dda96383f02c2c7be746e3e71e183e9271d /arch | |
parent | 663a83048c602d5176c23489b4e29598d753e42b (diff) |
[ARM] S3C: Do not kmalloc/kfree during inner suspend code.
The PM CRC checking code kmallocs an area to save a set of
CRC values during suspend. This triggers a warning due to the
call of a function that might sleep whilst the system is not
in a valid state to do so.
Move the allocation and free to points in the suspend and resume
process where they can call a function that might-sleep.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/plat-s3c/include/plat/pm.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-s3c/pm-check.c | 20 | ||||
-rw-r--r-- | arch/arm/plat-s3c/pm.c | 19 |
3 files changed, 33 insertions, 8 deletions
diff --git a/arch/arm/plat-s3c/include/plat/pm.h b/arch/arm/plat-s3c/include/plat/pm.h index c27b8cf5d891..5ee26da27028 100644 --- a/arch/arm/plat-s3c/include/plat/pm.h +++ b/arch/arm/plat-s3c/include/plat/pm.h | |||
@@ -129,10 +129,12 @@ extern void s3c_pm_dbg(const char *msg, ...); | |||
129 | #ifdef CONFIG_S3C2410_PM_CHECK | 129 | #ifdef CONFIG_S3C2410_PM_CHECK |
130 | extern void s3c_pm_check_prepare(void); | 130 | extern void s3c_pm_check_prepare(void); |
131 | extern void s3c_pm_check_restore(void); | 131 | extern void s3c_pm_check_restore(void); |
132 | extern void s3c_pm_check_cleanup(void); | ||
132 | extern void s3c_pm_check_store(void); | 133 | extern void s3c_pm_check_store(void); |
133 | #else | 134 | #else |
134 | #define s3c_pm_check_prepare() do { } while(0) | 135 | #define s3c_pm_check_prepare() do { } while(0) |
135 | #define s3c_pm_check_restore() do { } while(0) | 136 | #define s3c_pm_check_restore() do { } while(0) |
137 | #define s3c_pm_check_cleanup() do { } while(0) | ||
136 | #define s3c_pm_check_store() do { } while(0) | 138 | #define s3c_pm_check_store() do { } while(0) |
137 | #endif | 139 | #endif |
138 | 140 | ||
diff --git a/arch/arm/plat-s3c/pm-check.c b/arch/arm/plat-s3c/pm-check.c index 183f1304bf58..39f2555564da 100644 --- a/arch/arm/plat-s3c/pm-check.c +++ b/arch/arm/plat-s3c/pm-check.c | |||
@@ -222,9 +222,21 @@ static u32 *s3c_pm_runcheck(struct resource *res, u32 *val) | |||
222 | */ | 222 | */ |
223 | void s3c_pm_check_restore(void) | 223 | void s3c_pm_check_restore(void) |
224 | { | 224 | { |
225 | if (crcs != NULL) { | 225 | if (crcs != NULL) |
226 | s3c_pm_run_sysram(s3c_pm_runcheck, crcs); | 226 | s3c_pm_run_sysram(s3c_pm_runcheck, crcs); |
227 | kfree(crcs); | ||
228 | crcs = NULL; | ||
229 | } | ||
230 | } | 227 | } |
228 | |||
229 | /** | ||
230 | * s3c_pm_check_cleanup() - free memory resources | ||
231 | * | ||
232 | * Free the resources that where allocated by the suspend | ||
233 | * memory check code. We do this separately from the | ||
234 | * s3c_pm_check_restore() function as we cannot call any | ||
235 | * functions that might sleep during that resume. | ||
236 | */ | ||
237 | void s3c_pm_check_cleanup(void) | ||
238 | { | ||
239 | kfree(crcs); | ||
240 | crcs = NULL; | ||
241 | } | ||
242 | |||
diff --git a/arch/arm/plat-s3c/pm.c b/arch/arm/plat-s3c/pm.c index 78bf50a14027..a0ca18a75b0e 100644 --- a/arch/arm/plat-s3c/pm.c +++ b/arch/arm/plat-s3c/pm.c | |||
@@ -254,10 +254,6 @@ static int s3c_pm_enter(suspend_state_t state) | |||
254 | return -EINVAL; | 254 | return -EINVAL; |
255 | } | 255 | } |
256 | 256 | ||
257 | /* prepare check area if configured */ | ||
258 | |||
259 | s3c_pm_check_prepare(); | ||
260 | |||
261 | /* store the physical address of the register recovery block */ | 257 | /* store the physical address of the register recovery block */ |
262 | 258 | ||
263 | s3c_sleep_save_phys = virt_to_phys(regs_save); | 259 | s3c_sleep_save_phys = virt_to_phys(regs_save); |
@@ -329,8 +325,23 @@ static int s3c_pm_enter(suspend_state_t state) | |||
329 | return 0; | 325 | return 0; |
330 | } | 326 | } |
331 | 327 | ||
328 | static int s3c_pm_prepare(void) | ||
329 | { | ||
330 | /* prepare check area if configured */ | ||
331 | |||
332 | s3c_pm_check_prepare(); | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static void s3c_pm_finish(void) | ||
337 | { | ||
338 | s3c_pm_check_cleanup(); | ||
339 | } | ||
340 | |||
332 | static struct platform_suspend_ops s3c_pm_ops = { | 341 | static struct platform_suspend_ops s3c_pm_ops = { |
333 | .enter = s3c_pm_enter, | 342 | .enter = s3c_pm_enter, |
343 | .prepare = s3c_pm_prepare, | ||
344 | .finish = s3c_pm_finish, | ||
334 | .valid = suspend_valid_only_mem, | 345 | .valid = suspend_valid_only_mem, |
335 | }; | 346 | }; |
336 | 347 | ||