aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2005-06-22 19:43:28 -0400
committerPaul Mackerras <paulus@samba.org>2005-06-22 19:43:28 -0400
commit6566c6f1f18d42affe73ccdd403e290b64d10473 (patch)
tree9c9cdea21d05e52a60044abf339e9750c6760f0a
parentc5a3c2e52af1bcb118022ffac9a0fd1d42d43bd3 (diff)
[PATCH] ppc64: pSeries_progress -> rtas_progress
The pSeries_progress function is called from some places in the rtas code, which may also be used by non-pSeries platforms. Though pSeries is currently the only platform type that implements display-character, the code is actually generic enough to be part of the rtas subsystem. I hit a bug here because the generic rtas code tried calling ppc_md.progress, which points to an __init function on most platforms. We could also clear the ppc_md.progress pointer when freeing the init memory to make it more explicit that ppc_md.progress must not be called after bootup. Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/ppc64/kernel/pSeries_setup.c103
-rw-r--r--arch/ppc64/kernel/rtas-proc.c4
-rw-r--r--arch/ppc64/kernel/rtas.c106
-rw-r--r--include/asm-ppc64/rtas.h1
4 files changed, 108 insertions, 106 deletions
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
index c5f3ccac7cd1..41e6de2c9158 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/ppc64/kernel/pSeries_setup.c
@@ -375,107 +375,6 @@ static void __init pSeries_init_early(void)
375} 375}
376 376
377 377
378static void pSeries_progress(char *s, unsigned short hex)
379{
380 struct device_node *root;
381 int width, *p;
382 char *os;
383 static int display_character, set_indicator;
384 static int max_width;
385 static DEFINE_SPINLOCK(progress_lock);
386 static int pending_newline = 0; /* did last write end with unprinted newline? */
387
388 if (!rtas.base)
389 return;
390
391 if (max_width == 0) {
392 if ((root = find_path_device("/rtas")) &&
393 (p = (unsigned int *)get_property(root,
394 "ibm,display-line-length",
395 NULL)))
396 max_width = *p;
397 else
398 max_width = 0x10;
399 display_character = rtas_token("display-character");
400 set_indicator = rtas_token("set-indicator");
401 }
402
403 if (display_character == RTAS_UNKNOWN_SERVICE) {
404 /* use hex display if available */
405 if (set_indicator != RTAS_UNKNOWN_SERVICE)
406 rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
407 return;
408 }
409
410 spin_lock(&progress_lock);
411
412 /*
413 * Last write ended with newline, but we didn't print it since
414 * it would just clear the bottom line of output. Print it now
415 * instead.
416 *
417 * If no newline is pending, print a CR to start output at the
418 * beginning of the line.
419 */
420 if (pending_newline) {
421 rtas_call(display_character, 1, 1, NULL, '\r');
422 rtas_call(display_character, 1, 1, NULL, '\n');
423 pending_newline = 0;
424 } else {
425 rtas_call(display_character, 1, 1, NULL, '\r');
426 }
427
428 width = max_width;
429 os = s;
430 while (*os) {
431 if (*os == '\n' || *os == '\r') {
432 /* Blank to end of line. */
433 while (width-- > 0)
434 rtas_call(display_character, 1, 1, NULL, ' ');
435
436 /* If newline is the last character, save it
437 * until next call to avoid bumping up the
438 * display output.
439 */
440 if (*os == '\n' && !os[1]) {
441 pending_newline = 1;
442 spin_unlock(&progress_lock);
443 return;
444 }
445
446 /* RTAS wants CR-LF, not just LF */
447
448 if (*os == '\n') {
449 rtas_call(display_character, 1, 1, NULL, '\r');
450 rtas_call(display_character, 1, 1, NULL, '\n');
451 } else {
452 /* CR might be used to re-draw a line, so we'll
453 * leave it alone and not add LF.
454 */
455 rtas_call(display_character, 1, 1, NULL, *os);
456 }
457
458 width = max_width;
459 } else {
460 width--;
461 rtas_call(display_character, 1, 1, NULL, *os);
462 }
463
464 os++;
465
466 /* if we overwrite the screen length */
467 if (width <= 0)
468 while ((*os != 0) && (*os != '\n') && (*os != '\r'))
469 os++;
470 }
471
472 /* Blank to end of line. */
473 while (width-- > 0)
474 rtas_call(display_character, 1, 1, NULL, ' ');
475
476 spin_unlock(&progress_lock);
477}
478
479static int pSeries_check_legacy_ioport(unsigned int baseport) 378static int pSeries_check_legacy_ioport(unsigned int baseport)
480{ 379{
481 struct device_node *np; 380 struct device_node *np;
@@ -535,7 +434,7 @@ struct machdep_calls __initdata pSeries_md = {
535 .get_rtc_time = rtas_get_rtc_time, 434 .get_rtc_time = rtas_get_rtc_time,
536 .set_rtc_time = rtas_set_rtc_time, 435 .set_rtc_time = rtas_set_rtc_time,
537 .calibrate_decr = generic_calibrate_decr, 436 .calibrate_decr = generic_calibrate_decr,
538 .progress = pSeries_progress, 437 .progress = rtas_progress,
539 .check_legacy_ioport = pSeries_check_legacy_ioport, 438 .check_legacy_ioport = pSeries_check_legacy_ioport,
540 .system_reset_exception = pSeries_system_reset_exception, 439 .system_reset_exception = pSeries_system_reset_exception,
541 .machine_check_exception = pSeries_machine_check_exception, 440 .machine_check_exception = pSeries_machine_check_exception,
diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
index 28b1f1521f21..1f3ff860fdf0 100644
--- a/arch/ppc64/kernel/rtas-proc.c
+++ b/arch/ppc64/kernel/rtas-proc.c
@@ -371,11 +371,11 @@ static ssize_t ppc_rtas_progress_write(struct file *file,
371 /* Lets see if the user passed hexdigits */ 371 /* Lets see if the user passed hexdigits */
372 hex = simple_strtoul(progress_led, NULL, 10); 372 hex = simple_strtoul(progress_led, NULL, 10);
373 373
374 ppc_md.progress ((char *)progress_led, hex); 374 rtas_progress ((char *)progress_led, hex);
375 return count; 375 return count;
376 376
377 /* clear the line */ 377 /* clear the line */
378 /* ppc_md.progress(" ", 0xffff);*/ 378 /* rtas_progress(" ", 0xffff);*/
379} 379}
380/* ****************************************************************** */ 380/* ****************************************************************** */
381static int ppc_rtas_progress_show(struct seq_file *m, void *v) 381static int ppc_rtas_progress_show(struct seq_file *m, void *v)
diff --git a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
index 5575603def27..43e1518653d5 100644
--- a/arch/ppc64/kernel/rtas.c
+++ b/arch/ppc64/kernel/rtas.c
@@ -91,6 +91,108 @@ 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 max_width;
102 static DEFINE_SPINLOCK(progress_lock);
103 static int pending_newline = 0; /* did last write end with unprinted newline? */
104
105 if (!rtas.base)
106 return;
107
108 if (max_width == 0) {
109 if ((root = find_path_device("/rtas")) &&
110 (p = (unsigned int *)get_property(root,
111 "ibm,display-line-length",
112 NULL)))
113 max_width = *p;
114 else
115 max_width = 0x10;
116 display_character = rtas_token("display-character");
117 set_indicator = rtas_token("set-indicator");
118 }
119
120 if (display_character == RTAS_UNKNOWN_SERVICE) {
121 /* use hex display if available */
122 if (set_indicator != RTAS_UNKNOWN_SERVICE)
123 rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
124 return;
125 }
126
127 spin_lock(&progress_lock);
128
129 /*
130 * Last write ended with newline, but we didn't print it since
131 * it would just clear the bottom line of output. Print it now
132 * instead.
133 *
134 * If no newline is pending, print a CR to start output at the
135 * beginning of the line.
136 */
137 if (pending_newline) {
138 rtas_call(display_character, 1, 1, NULL, '\r');
139 rtas_call(display_character, 1, 1, NULL, '\n');
140 pending_newline = 0;
141 } else {
142 rtas_call(display_character, 1, 1, NULL, '\r');
143 }
144
145 width = max_width;
146 os = s;
147 while (*os) {
148 if (*os == '\n' || *os == '\r') {
149 /* Blank to end of line. */
150 while (width-- > 0)
151 rtas_call(display_character, 1, 1, NULL, ' ');
152
153 /* If newline is the last character, save it
154 * until next call to avoid bumping up the
155 * display output.
156 */
157 if (*os == '\n' && !os[1]) {
158 pending_newline = 1;
159 spin_unlock(&progress_lock);
160 return;
161 }
162
163 /* RTAS wants CR-LF, not just LF */
164
165 if (*os == '\n') {
166 rtas_call(display_character, 1, 1, NULL, '\r');
167 rtas_call(display_character, 1, 1, NULL, '\n');
168 } else {
169 /* CR might be used to re-draw a line, so we'll
170 * leave it alone and not add LF.
171 */
172 rtas_call(display_character, 1, 1, NULL, *os);
173 }
174
175 width = max_width;
176 } else {
177 width--;
178 rtas_call(display_character, 1, 1, NULL, *os);
179 }
180
181 os++;
182
183 /* if we overwrite the screen length */
184 if (width <= 0)
185 while ((*os != 0) && (*os != '\n') && (*os != '\r'))
186 os++;
187 }
188
189 /* Blank to end of line. */
190 while (width-- > 0)
191 rtas_call(display_character, 1, 1, NULL, ' ');
192
193 spin_unlock(&progress_lock);
194}
195
94int 196int
95rtas_token(const char *service) 197rtas_token(const char *service)
96{ 198{
@@ -425,8 +527,8 @@ rtas_flash_firmware(void)
425 527
426 printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size); 528 printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
427 printk(KERN_ALERT "FLASH: performing flash and reboot\n"); 529 printk(KERN_ALERT "FLASH: performing flash and reboot\n");
428 ppc_md.progress("Flashing \n", 0x0); 530 rtas_progress("Flashing \n", 0x0);
429 ppc_md.progress("Please Wait... ", 0x0); 531 rtas_progress("Please Wait... ", 0x0);
430 printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n"); 532 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); 533 status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
432 switch (status) { /* should only get "bad" status */ 534 switch (status) { /* should only get "bad" status */
diff --git a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
index c46ceb2ffc12..e7d1b5222802 100644
--- a/include/asm-ppc64/rtas.h
+++ b/include/asm-ppc64/rtas.h
@@ -186,6 +186,7 @@ extern int rtas_get_sensor(int sensor, int index, int *state);
186extern int rtas_get_power_level(int powerdomain, int *level); 186extern int rtas_get_power_level(int powerdomain, int *level);
187extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); 187extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
188extern int rtas_set_indicator(int indicator, int index, int new_value); 188extern int rtas_set_indicator(int indicator, int index, int new_value);
189extern void rtas_progress(char *s, unsigned short hex);
189extern void rtas_initialize(void); 190extern void rtas_initialize(void);
190 191
191struct rtc_time; 192struct rtc_time;