aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-msm
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2011-02-24 13:44:44 -0500
committerDavid Brown <davidb@codeaurora.org>2011-03-10 15:01:37 -0500
commit8e76a80960bf06c245160a484d5a363ca6b520bb (patch)
treef98916f0969c25a4bae63a97b5a2051424e958a7 /arch/arm/mach-msm
parent98d4ded60bda17a9ffecd902b03deac52922b788 (diff)
msm: scm: Check for interruption immediately
When we're interrupted on the secure side, we should just issue another smc instruction again instead of replaying the arguments to smc. Fix it. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: David Brown <davidb@codeaurora.org>
Diffstat (limited to 'arch/arm/mach-msm')
-rw-r--r--arch/arm/mach-msm/scm.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
index 5eddf549717a..cfa808dd4897 100644
--- a/arch/arm/mach-msm/scm.c
+++ b/arch/arm/mach-msm/scm.c
@@ -174,15 +174,18 @@ static u32 smc(u32 cmd_addr)
174 register u32 r0 asm("r0") = 1; 174 register u32 r0 asm("r0") = 1;
175 register u32 r1 asm("r1") = (u32)&context_id; 175 register u32 r1 asm("r1") = (u32)&context_id;
176 register u32 r2 asm("r2") = cmd_addr; 176 register u32 r2 asm("r2") = cmd_addr;
177 asm volatile( 177 do {
178 __asmeq("%0", "r0") 178 asm volatile(
179 __asmeq("%1", "r0") 179 __asmeq("%0", "r0")
180 __asmeq("%2", "r1") 180 __asmeq("%1", "r0")
181 __asmeq("%3", "r2") 181 __asmeq("%2", "r1")
182 "smc #0 @ switch to secure world\n" 182 __asmeq("%3", "r2")
183 : "=r" (r0) 183 "smc #0 @ switch to secure world\n"
184 : "r" (r0), "r" (r1), "r" (r2) 184 : "=r" (r0)
185 : "r3"); 185 : "r" (r0), "r" (r1), "r" (r2)
186 : "r3");
187 } while (r0 == SCM_INTERRUPTED);
188
186 return r0; 189 return r0;
187} 190}
188 191
@@ -197,13 +200,9 @@ static int __scm_call(const struct scm_command *cmd)
197 * side in the buffer. 200 * side in the buffer.
198 */ 201 */
199 flush_cache_all(); 202 flush_cache_all();
200 do { 203 ret = smc(cmd_addr);
201 ret = smc(cmd_addr); 204 if (ret < 0)
202 if (ret < 0) { 205 ret = scm_remap_error(ret);
203 ret = scm_remap_error(ret);
204 break;
205 }
206 } while (ret == SCM_INTERRUPTED);
207 206
208 return ret; 207 return ret;
209} 208}
@@ -274,14 +273,18 @@ u32 scm_get_version(void)
274 273
275 r0 = 0x1 << 8; 274 r0 = 0x1 << 8;
276 r1 = (u32)&context_id; 275 r1 = (u32)&context_id;
277 asm volatile( 276 do {
278 __asmeq("%0", "r1") 277 asm volatile(
279 __asmeq("%1", "r0") 278 __asmeq("%0", "r0")
280 __asmeq("%2", "r1") 279 __asmeq("%1", "r1")
281 "smc #0 @ switch to secure world\n" 280 __asmeq("%2", "r0")
282 : "=r" (r1) 281 __asmeq("%3", "r1")
283 : "r" (r0), "r" (r1) 282 "smc #0 @ switch to secure world\n"
284 : "r2", "r3"); 283 : "=r" (r0), "=r" (r1)
284 : "r" (r0), "r" (r1)
285 : "r2", "r3");
286 } while (r0 == SCM_INTERRUPTED);
287
285 version = r1; 288 version = r1;
286 mutex_unlock(&scm_lock); 289 mutex_unlock(&scm_lock);
287 290