aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/rtas.h2
-rw-r--r--arch/powerpc/kernel/rtas.c44
2 files changed, 35 insertions, 11 deletions
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index b77ef369c0f0..6db1d6977a0d 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -338,6 +338,8 @@ extern void enter_rtas(unsigned long);
338extern int rtas_token(const char *service); 338extern int rtas_token(const char *service);
339extern int rtas_service_present(const char *service); 339extern int rtas_service_present(const char *service);
340extern int rtas_call(int token, int, int, int *, ...); 340extern int rtas_call(int token, int, int, int *, ...);
341void rtas_call_unlocked(struct rtas_args *args, int token, int nargs,
342 int nret, ...);
341extern void rtas_restart(char *cmd); 343extern void rtas_restart(char *cmd);
342extern void rtas_power_off(void); 344extern void rtas_power_off(void);
343extern void rtas_halt(void); 345extern void rtas_halt(void);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 5a753fae8265..fcf2d653a6fe 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -418,6 +418,36 @@ static char *__fetch_rtas_last_error(char *altbuf)
418#define get_errorlog_buffer() NULL 418#define get_errorlog_buffer() NULL
419#endif 419#endif
420 420
421
422static void
423va_rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret,
424 va_list list)
425{
426 int i;
427
428 args->token = cpu_to_be32(token);
429 args->nargs = cpu_to_be32(nargs);
430 args->nret = cpu_to_be32(nret);
431 args->rets = &(args->args[nargs]);
432
433 for (i = 0; i < nargs; ++i)
434 args->args[i] = cpu_to_be32(va_arg(list, __u32));
435
436 for (i = 0; i < nret; ++i)
437 args->rets[i] = 0;
438
439 enter_rtas(__pa(args));
440}
441
442void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, ...)
443{
444 va_list list;
445
446 va_start(list, nret);
447 va_rtas_call_unlocked(args, token, nargs, nret, list);
448 va_end(list);
449}
450
421int rtas_call(int token, int nargs, int nret, int *outputs, ...) 451int rtas_call(int token, int nargs, int nret, int *outputs, ...)
422{ 452{
423 va_list list; 453 va_list list;
@@ -431,22 +461,14 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
431 return -1; 461 return -1;
432 462
433 s = lock_rtas(); 463 s = lock_rtas();
464
465 /* We use the global rtas args buffer */
434 rtas_args = &rtas.args; 466 rtas_args = &rtas.args;
435 467
436 rtas_args->token = cpu_to_be32(token);
437 rtas_args->nargs = cpu_to_be32(nargs);
438 rtas_args->nret = cpu_to_be32(nret);
439 rtas_args->rets = &(rtas_args->args[nargs]);
440 va_start(list, outputs); 468 va_start(list, outputs);
441 for (i = 0; i < nargs; ++i) 469 va_rtas_call_unlocked(rtas_args, token, nargs, nret, list);
442 rtas_args->args[i] = cpu_to_be32(va_arg(list, __u32));
443 va_end(list); 470 va_end(list);
444 471
445 for (i = 0; i < nret; ++i)
446 rtas_args->rets[i] = 0;
447
448 enter_rtas(__pa(rtas_args));
449
450 /* A -1 return code indicates that the last command couldn't 472 /* A -1 return code indicates that the last command couldn't
451 be completed due to a hardware error. */ 473 be completed due to a hardware error. */
452 if (be32_to_cpu(rtas_args->rets[0]) == -1) 474 if (be32_to_cpu(rtas_args->rets[0]) == -1)