[ppc64] Add some rtas calls, from John Rose Added functions for 3 RTAS calls get-power-level get-sensor-state set-indicator --- arch/ppc64/kernel/rtas.c | 86 ++++++++++++++++++++++++++++++++++++++++++++--- include/asm-ppc64/rtas.h | 7 +++ 2 files changed, 89 insertions(+), 4 deletions(-) diff -puN arch/ppc64/kernel/rtas.c~ppc64-rtas_functions arch/ppc64/kernel/rtas.c --- 25/arch/ppc64/kernel/rtas.c~ppc64-rtas_functions 2004-01-13 23:22:38.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/rtas.c 2004-01-13 23:22:38.000000000 -0800 @@ -28,6 +28,7 @@ #include #include #include +#include struct flash_block_list_header rtas_firmware_flash_list = {0, 0}; @@ -180,18 +181,18 @@ rtas_call(int token, int nargs, int nret } /* Given an RTAS status code of 990n compute the hinted delay of 10^n - * (last digit) milliseconds. For now we bound at n=3 (1 sec). + * (last digit) milliseconds. For now we bound at n=5 (100 sec). */ unsigned int rtas_extended_busy_delay_time(int status) { int order = status - 9900; - unsigned int ms; + unsigned long ms; if (order < 0) order = 0; /* RTC depends on this for -2 clock busy */ - else if (order > 3) - order = 3; /* bound */ + else if (order > 5) + order = 5; /* bound */ /* Use microseconds for reasonable accuracy */ for (ms = 1000; order > 0; order--) @@ -199,6 +200,80 @@ rtas_extended_busy_delay_time(int status return ms / (1000000/HZ); /* round down is fine */ } +int +rtas_get_power_level(int powerdomain, int *level) +{ + int token = rtas_token("get-power-level"); + long powerlevel; + int rc; + + if (token == RTAS_UNKNOWN_SERVICE) + return RTAS_UNKNOWN_OP; + + while(1) { + rc = (int) rtas_call(token, 1, 2, &powerlevel, powerdomain); + if (rc == RTAS_BUSY) + udelay(1); + else + break; + } + *level = (int) powerlevel; + return rc; +} + +int +rtas_get_sensor(int sensor, int index, int *state) +{ + int token = rtas_token("get-sensor-state"); + unsigned int wait_time; + long returned_state; + int rc; + + if (token == RTAS_UNKNOWN_SERVICE) + return RTAS_UNKNOWN_OP; + + while (1) { + rc = (int) rtas_call(token, 2, 2, &returned_state, sensor, + index); + if (rc == RTAS_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } + else + break; + } + *state = (int) returned_state; + return rc; +} + +int +rtas_set_indicator(int indicator, int index, int new_value) +{ + int token = rtas_token("set-indicator"); + unsigned int wait_time; + int rc; + + if (token == RTAS_UNKNOWN_SERVICE) + return RTAS_UNKNOWN_OP; + + while (1) { + rc = (int) rtas_call(token, 3, 1, NULL, indicator, index, + new_value); + if (rc == RTAS_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } + else + break; + } + + return rc; +} + #define FLASH_BLOCK_LIST_VERSION (1UL) static void rtas_flash_firmware(void) @@ -315,3 +390,6 @@ EXPORT_SYMBOL(rtas_call); EXPORT_SYMBOL(rtas_data_buf); EXPORT_SYMBOL(rtas_data_buf_lock); EXPORT_SYMBOL(rtas_extended_busy_delay_time); +EXPORT_SYMBOL(rtas_get_sensor); +EXPORT_SYMBOL(rtas_get_power_level); +EXPORT_SYMBOL(rtas_set_indicator); diff -puN include/asm-ppc64/rtas.h~ppc64-rtas_functions include/asm-ppc64/rtas.h --- 25/include/asm-ppc64/rtas.h~ppc64-rtas_functions 2004-01-13 23:22:38.000000000 -0800 +++ 25-akpm/include/asm-ppc64/rtas.h 2004-01-13 23:22:38.000000000 -0800 @@ -165,6 +165,9 @@ extern void call_rtas_display_status(cha extern void rtas_restart(char *cmd); extern void rtas_power_off(void); extern void rtas_halt(void); +extern int rtas_get_sensor(int sensor, int index, int *state); +extern int rtas_get_power_level(int powerdomain, int *level); +extern int rtas_set_indicator(int indicator, int index, int new_value); /* Given an RTAS status code of 9900..9905 compute the hinted delay */ unsigned int rtas_extended_busy_delay_time(int status); @@ -179,6 +182,10 @@ static inline int rtas_is_extended_busy( * of holding the buffer for long. */ #define RTAS_DATA_BUF_SIZE 1024 + +#define RTAS_UNKNOWN_OP -1099 /* Return Status - Unknown RTAS Token */ +#define RTAS_BUSY -2 /* RTAS Return Status - Busy */ + extern spinlock_t rtas_data_buf_lock; extern char rtas_data_buf[RTAS_DATA_BUF_SIZE]; _