]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ppc64: Add some rtas calls, from John Rose
authorAndrew Morton <akpm@osdl.org>
Mon, 19 Jan 2004 02:15:16 +0000 (18:15 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 19 Jan 2004 02:15:16 +0000 (18:15 -0800)
From: Anton Blanchard <anton@samba.org>

Added functions for 3 RTAS calls
get-power-level
get-sensor-state
set-indicator

arch/ppc64/kernel/rtas.c
include/asm-ppc64/rtas.h

index ddab82877c9111c646468d660e35d4f46da3af9a..ed2196cb47093a95d1109f79dc4453a07f80c471 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/system.h>
 #include <asm/abs_addr.h>
 #include <asm/udbg.h>
+#include <asm/delay.h>
 
 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);
index adc212dcb420470eac8c700f1dcba31f1060a254..621a352310daa9882c277006c444d5726f413eb6 100644 (file)
@@ -165,6 +165,9 @@ extern void call_rtas_display_status(char);
 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(int status)
  * 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];