aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/rtas.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/rtas.c')
-rw-r--r--arch/ppc64/kernel/rtas.c121
1 files changed, 119 insertions, 2 deletions
diff --git a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
index 5575603def27..5e8eb33b8e54 100644
--- a/arch/ppc64/kernel/rtas.c
+++ b/arch/ppc64/kernel/rtas.c
@@ -91,6 +91,123 @@ call_rtas_display_status_delay(unsigned char c)
91 } 91 }
92} 92}
93 93
94void
95rtas_progress(char *s, unsigned short hex)
96{
97 struct device_node *root;
98 int width, *p;
99 char *os;
100 static int display_character, set_indicator;
101 static int display_width, display_lines, *row_width, form_feed;
102 static DEFINE_SPINLOCK(progress_lock);
103 static int current_line;
104 static int pending_newline = 0; /* did last write end with unprinted newline? */
105
106 if (!rtas.base)
107 return;
108
109 if (display_width == 0) {
110 display_width = 0x10;
111 if ((root = find_path_device("/rtas"))) {
112 if ((p = (unsigned int *)get_property(root,
113 "ibm,display-line-length", NULL)))
114 display_width = *p;
115 if ((p = (unsigned int *)get_property(root,
116 "ibm,form-feed", NULL)))
117 form_feed = *p;
118 if ((p = (unsigned int *)get_property(root,
119 "ibm,display-number-of-lines", NULL)))
120 display_lines = *p;
121 row_width = (unsigned int *)get_property(root,
122 "ibm,display-truncation-length", NULL);
123 }
124 display_character = rtas_token("display-character");
125 set_indicator = rtas_token("set-indicator");
126 }
127
128 if (display_character == RTAS_UNKNOWN_SERVICE) {
129 /* use hex display if available */
130 if (set_indicator != RTAS_UNKNOWN_SERVICE)
131 rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
132 return;
133 }
134
135 spin_lock(&progress_lock);
136
137 /*
138 * Last write ended with newline, but we didn't print it since
139 * it would just clear the bottom line of output. Print it now
140 * instead.
141 *
142 * If no newline is pending and form feed is supported, clear the
143 * display with a form feed; otherwise, print a CR to start output
144 * at the beginning of the line.
145 */
146 if (pending_newline) {
147 rtas_call(display_character, 1, 1, NULL, '\r');
148 rtas_call(display_character, 1, 1, NULL, '\n');
149 pending_newline = 0;
150 } else {
151 current_line = 0;
152 if (form_feed)
153 rtas_call(display_character, 1, 1, NULL,
154 (char)form_feed);
155 else
156 rtas_call(display_character, 1, 1, NULL, '\r');
157 }
158
159 if (row_width)
160 width = row_width[current_line];
161 else
162 width = display_width;
163 os = s;
164 while (*os) {
165 if (*os == '\n' || *os == '\r') {
166 /* If newline is the last character, save it
167 * until next call to avoid bumping up the
168 * display output.
169 */
170 if (*os == '\n' && !os[1]) {
171 pending_newline = 1;
172 current_line++;
173 if (current_line > display_lines-1)
174 current_line = display_lines-1;
175 spin_unlock(&progress_lock);
176 return;
177 }
178
179 /* RTAS wants CR-LF, not just LF */
180
181 if (*os == '\n') {
182 rtas_call(display_character, 1, 1, NULL, '\r');
183 rtas_call(display_character, 1, 1, NULL, '\n');
184 } else {
185 /* CR might be used to re-draw a line, so we'll
186 * leave it alone and not add LF.
187 */
188 rtas_call(display_character, 1, 1, NULL, *os);
189 }
190
191 if (row_width)
192 width = row_width[current_line];
193 else
194 width = display_width;
195 } else {
196 width--;
197 rtas_call(display_character, 1, 1, NULL, *os);
198 }
199
200 os++;
201
202 /* if we overwrite the screen length */
203 if (width <= 0)
204 while ((*os != 0) && (*os != '\n') && (*os != '\r'))
205 os++;
206 }
207
208 spin_unlock(&progress_lock);
209}
210
94int 211int
95rtas_token(const char *service) 212rtas_token(const char *service)
96{ 213{
@@ -425,8 +542,8 @@ rtas_flash_firmware(void)
425 542
426 printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size); 543 printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
427 printk(KERN_ALERT "FLASH: performing flash and reboot\n"); 544 printk(KERN_ALERT "FLASH: performing flash and reboot\n");
428 ppc_md.progress("Flashing \n", 0x0); 545 rtas_progress("Flashing \n", 0x0);
429 ppc_md.progress("Please Wait... ", 0x0); 546 rtas_progress("Please Wait... ", 0x0);
430 printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n"); 547 printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
431 status = rtas_call(update_token, 1, 1, NULL, rtas_block_list); 548 status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
432 switch (status) { /* should only get "bad" status */ 549 switch (status) { /* should only get "bad" status */