diff options
Diffstat (limited to 'arch/powerpc/kernel/rtas.c')
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 5a753fa..fcf2d65 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) #define get_errorlog_buffer() NULL #endif + +static void +va_rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, + va_list list) +{ + int i; + + args->token = cpu_to_be32(token); + args->nargs = cpu_to_be32(nargs); + args->nret = cpu_to_be32(nret); + args->rets = &(args->args[nargs]); + + for (i = 0; i < nargs; ++i) + args->args[i] = cpu_to_be32(va_arg(list, __u32)); + + for (i = 0; i < nret; ++i) + args->rets[i] = 0; + + enter_rtas(__pa(args)); +} + +void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, ...) +{ + va_list list; + + va_start(list, nret); + va_rtas_call_unlocked(args, token, nargs, nret, list); + va_end(list); +} + int rtas_call(int token, int nargs, int nret, int *outputs, ...) { va_list list; @@ -431,22 +461,14 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) return -1; s = lock_rtas(); + + /* We use the global rtas args buffer */ rtas_args = &rtas.args; - rtas_args->token = cpu_to_be32(token); - rtas_args->nargs = cpu_to_be32(nargs); - rtas_args->nret = cpu_to_be32(nret); - rtas_args->rets = &(rtas_args->args[nargs]); va_start(list, outputs); - for (i = 0; i < nargs; ++i) - rtas_args->args[i] = cpu_to_be32(va_arg(list, __u32)); + va_rtas_call_unlocked(rtas_args, token, nargs, nret, list); va_end(list); - for (i = 0; i < nret; ++i) - rtas_args->rets[i] = 0; - - enter_rtas(__pa(rtas_args)); - /* A -1 return code indicates that the last command couldn't be completed due to a hardware error. */ if (be32_to_cpu(rtas_args->rets[0]) == -1) |