[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>
This commit is contained in:
parent
c5a3c2e52a
commit
6566c6f1f1
4 changed files with 108 additions and 106 deletions
|
@ -375,107 +375,6 @@ static void __init pSeries_init_early(void)
|
|||
}
|
||||
|
||||
|
||||
static void pSeries_progress(char *s, unsigned short hex)
|
||||
{
|
||||
struct device_node *root;
|
||||
int width, *p;
|
||||
char *os;
|
||||
static int display_character, set_indicator;
|
||||
static int max_width;
|
||||
static DEFINE_SPINLOCK(progress_lock);
|
||||
static int pending_newline = 0; /* did last write end with unprinted newline? */
|
||||
|
||||
if (!rtas.base)
|
||||
return;
|
||||
|
||||
if (max_width == 0) {
|
||||
if ((root = find_path_device("/rtas")) &&
|
||||
(p = (unsigned int *)get_property(root,
|
||||
"ibm,display-line-length",
|
||||
NULL)))
|
||||
max_width = *p;
|
||||
else
|
||||
max_width = 0x10;
|
||||
display_character = rtas_token("display-character");
|
||||
set_indicator = rtas_token("set-indicator");
|
||||
}
|
||||
|
||||
if (display_character == RTAS_UNKNOWN_SERVICE) {
|
||||
/* use hex display if available */
|
||||
if (set_indicator != RTAS_UNKNOWN_SERVICE)
|
||||
rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock(&progress_lock);
|
||||
|
||||
/*
|
||||
* Last write ended with newline, but we didn't print it since
|
||||
* it would just clear the bottom line of output. Print it now
|
||||
* instead.
|
||||
*
|
||||
* If no newline is pending, print a CR to start output at the
|
||||
* beginning of the line.
|
||||
*/
|
||||
if (pending_newline) {
|
||||
rtas_call(display_character, 1, 1, NULL, '\r');
|
||||
rtas_call(display_character, 1, 1, NULL, '\n');
|
||||
pending_newline = 0;
|
||||
} else {
|
||||
rtas_call(display_character, 1, 1, NULL, '\r');
|
||||
}
|
||||
|
||||
width = max_width;
|
||||
os = s;
|
||||
while (*os) {
|
||||
if (*os == '\n' || *os == '\r') {
|
||||
/* Blank to end of line. */
|
||||
while (width-- > 0)
|
||||
rtas_call(display_character, 1, 1, NULL, ' ');
|
||||
|
||||
/* If newline is the last character, save it
|
||||
* until next call to avoid bumping up the
|
||||
* display output.
|
||||
*/
|
||||
if (*os == '\n' && !os[1]) {
|
||||
pending_newline = 1;
|
||||
spin_unlock(&progress_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* RTAS wants CR-LF, not just LF */
|
||||
|
||||
if (*os == '\n') {
|
||||
rtas_call(display_character, 1, 1, NULL, '\r');
|
||||
rtas_call(display_character, 1, 1, NULL, '\n');
|
||||
} else {
|
||||
/* CR might be used to re-draw a line, so we'll
|
||||
* leave it alone and not add LF.
|
||||
*/
|
||||
rtas_call(display_character, 1, 1, NULL, *os);
|
||||
}
|
||||
|
||||
width = max_width;
|
||||
} else {
|
||||
width--;
|
||||
rtas_call(display_character, 1, 1, NULL, *os);
|
||||
}
|
||||
|
||||
os++;
|
||||
|
||||
/* if we overwrite the screen length */
|
||||
if (width <= 0)
|
||||
while ((*os != 0) && (*os != '\n') && (*os != '\r'))
|
||||
os++;
|
||||
}
|
||||
|
||||
/* Blank to end of line. */
|
||||
while (width-- > 0)
|
||||
rtas_call(display_character, 1, 1, NULL, ' ');
|
||||
|
||||
spin_unlock(&progress_lock);
|
||||
}
|
||||
|
||||
static int pSeries_check_legacy_ioport(unsigned int baseport)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
@ -535,7 +434,7 @@ struct machdep_calls __initdata pSeries_md = {
|
|||
.get_rtc_time = rtas_get_rtc_time,
|
||||
.set_rtc_time = rtas_set_rtc_time,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = pSeries_progress,
|
||||
.progress = rtas_progress,
|
||||
.check_legacy_ioport = pSeries_check_legacy_ioport,
|
||||
.system_reset_exception = pSeries_system_reset_exception,
|
||||
.machine_check_exception = pSeries_machine_check_exception,
|
||||
|
|
|
@ -371,11 +371,11 @@ static ssize_t ppc_rtas_progress_write(struct file *file,
|
|||
/* Lets see if the user passed hexdigits */
|
||||
hex = simple_strtoul(progress_led, NULL, 10);
|
||||
|
||||
ppc_md.progress ((char *)progress_led, hex);
|
||||
rtas_progress ((char *)progress_led, hex);
|
||||
return count;
|
||||
|
||||
/* clear the line */
|
||||
/* ppc_md.progress(" ", 0xffff);*/
|
||||
/* rtas_progress(" ", 0xffff);*/
|
||||
}
|
||||
/* ****************************************************************** */
|
||||
static int ppc_rtas_progress_show(struct seq_file *m, void *v)
|
||||
|
|
|
@ -91,6 +91,108 @@ call_rtas_display_status_delay(unsigned char c)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
rtas_progress(char *s, unsigned short hex)
|
||||
{
|
||||
struct device_node *root;
|
||||
int width, *p;
|
||||
char *os;
|
||||
static int display_character, set_indicator;
|
||||
static int max_width;
|
||||
static DEFINE_SPINLOCK(progress_lock);
|
||||
static int pending_newline = 0; /* did last write end with unprinted newline? */
|
||||
|
||||
if (!rtas.base)
|
||||
return;
|
||||
|
||||
if (max_width == 0) {
|
||||
if ((root = find_path_device("/rtas")) &&
|
||||
(p = (unsigned int *)get_property(root,
|
||||
"ibm,display-line-length",
|
||||
NULL)))
|
||||
max_width = *p;
|
||||
else
|
||||
max_width = 0x10;
|
||||
display_character = rtas_token("display-character");
|
||||
set_indicator = rtas_token("set-indicator");
|
||||
}
|
||||
|
||||
if (display_character == RTAS_UNKNOWN_SERVICE) {
|
||||
/* use hex display if available */
|
||||
if (set_indicator != RTAS_UNKNOWN_SERVICE)
|
||||
rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock(&progress_lock);
|
||||
|
||||
/*
|
||||
* Last write ended with newline, but we didn't print it since
|
||||
* it would just clear the bottom line of output. Print it now
|
||||
* instead.
|
||||
*
|
||||
* If no newline is pending, print a CR to start output at the
|
||||
* beginning of the line.
|
||||
*/
|
||||
if (pending_newline) {
|
||||
rtas_call(display_character, 1, 1, NULL, '\r');
|
||||
rtas_call(display_character, 1, 1, NULL, '\n');
|
||||
pending_newline = 0;
|
||||
} else {
|
||||
rtas_call(display_character, 1, 1, NULL, '\r');
|
||||
}
|
||||
|
||||
width = max_width;
|
||||
os = s;
|
||||
while (*os) {
|
||||
if (*os == '\n' || *os == '\r') {
|
||||
/* Blank to end of line. */
|
||||
while (width-- > 0)
|
||||
rtas_call(display_character, 1, 1, NULL, ' ');
|
||||
|
||||
/* If newline is the last character, save it
|
||||
* until next call to avoid bumping up the
|
||||
* display output.
|
||||
*/
|
||||
if (*os == '\n' && !os[1]) {
|
||||
pending_newline = 1;
|
||||
spin_unlock(&progress_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* RTAS wants CR-LF, not just LF */
|
||||
|
||||
if (*os == '\n') {
|
||||
rtas_call(display_character, 1, 1, NULL, '\r');
|
||||
rtas_call(display_character, 1, 1, NULL, '\n');
|
||||
} else {
|
||||
/* CR might be used to re-draw a line, so we'll
|
||||
* leave it alone and not add LF.
|
||||
*/
|
||||
rtas_call(display_character, 1, 1, NULL, *os);
|
||||
}
|
||||
|
||||
width = max_width;
|
||||
} else {
|
||||
width--;
|
||||
rtas_call(display_character, 1, 1, NULL, *os);
|
||||
}
|
||||
|
||||
os++;
|
||||
|
||||
/* if we overwrite the screen length */
|
||||
if (width <= 0)
|
||||
while ((*os != 0) && (*os != '\n') && (*os != '\r'))
|
||||
os++;
|
||||
}
|
||||
|
||||
/* Blank to end of line. */
|
||||
while (width-- > 0)
|
||||
rtas_call(display_character, 1, 1, NULL, ' ');
|
||||
|
||||
spin_unlock(&progress_lock);
|
||||
}
|
||||
|
||||
int
|
||||
rtas_token(const char *service)
|
||||
{
|
||||
|
@ -425,8 +527,8 @@ rtas_flash_firmware(void)
|
|||
|
||||
printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
|
||||
printk(KERN_ALERT "FLASH: performing flash and reboot\n");
|
||||
ppc_md.progress("Flashing \n", 0x0);
|
||||
ppc_md.progress("Please Wait... ", 0x0);
|
||||
rtas_progress("Flashing \n", 0x0);
|
||||
rtas_progress("Please Wait... ", 0x0);
|
||||
printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
|
||||
status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
|
||||
switch (status) { /* should only get "bad" status */
|
||||
|
|
|
@ -186,6 +186,7 @@ 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_power_level(int powerdomain, int level, int *setlevel);
|
||||
extern int rtas_set_indicator(int indicator, int index, int new_value);
|
||||
extern void rtas_progress(char *s, unsigned short hex);
|
||||
extern void rtas_initialize(void);
|
||||
|
||||
struct rtc_time;
|
||||
|
|
Loading…
Reference in a new issue