diff options
author | Simon Kagstrom <simon.kagstrom@netinsight.net> | 2014-10-28 07:19:00 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2014-11-09 17:59:30 -0500 |
commit | 4b4b13d5fec8a82ed2780c487e49cfc4321a8c14 (patch) | |
tree | d021c3f9a715abfbc2b51100c7f32e5e61783d60 | |
parent | 90029640fd5963343fb862d419db161bc0424120 (diff) |
powerpc/boot: Parse chosen/cmdline-timeout parameter
On some platforms a 5 second timeout during boot might be quite long, so
make it configurable. Run the loop at least once to let the user stop
the boot by holding a key pressed. If the timeout is set to 0, don't
wait for input, which can be used as a workaround if the boot hangs on
random data coming in on the serial port.
Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net>
[mpe: Changelog wording & whitespace]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/boot/main.c | 15 | ||||
-rw-r--r-- | arch/powerpc/boot/ops.h | 2 | ||||
-rw-r--r-- | arch/powerpc/boot/serial.c | 6 |
3 files changed, 17 insertions, 6 deletions
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index d367a0aece2a..d80161b633f4 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c | |||
@@ -144,13 +144,24 @@ static char cmdline[BOOT_COMMAND_LINE_SIZE] | |||
144 | 144 | ||
145 | static void prep_cmdline(void *chosen) | 145 | static void prep_cmdline(void *chosen) |
146 | { | 146 | { |
147 | unsigned int getline_timeout = 5000; | ||
148 | int v; | ||
149 | int n; | ||
150 | |||
151 | /* Wait-for-input time */ | ||
152 | n = getprop(chosen, "linux,cmdline-timeout", &v, sizeof(v)); | ||
153 | if (n == sizeof(v)) | ||
154 | getline_timeout = v; | ||
155 | |||
147 | if (cmdline[0] == '\0') | 156 | if (cmdline[0] == '\0') |
148 | getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); | 157 | getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); |
149 | 158 | ||
150 | printf("\n\rLinux/PowerPC load: %s", cmdline); | 159 | printf("\n\rLinux/PowerPC load: %s", cmdline); |
160 | |||
151 | /* If possible, edit the command line */ | 161 | /* If possible, edit the command line */ |
152 | if (console_ops.edit_cmdline) | 162 | if (console_ops.edit_cmdline && getline_timeout) |
153 | console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE); | 163 | console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE, getline_timeout); |
164 | |||
154 | printf("\n\r"); | 165 | printf("\n\r"); |
155 | 166 | ||
156 | /* Put the command line back into the devtree for the kernel */ | 167 | /* Put the command line back into the devtree for the kernel */ |
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 8aad3c55aeda..5e75e1c5518e 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h | |||
@@ -58,7 +58,7 @@ extern struct dt_ops dt_ops; | |||
58 | struct console_ops { | 58 | struct console_ops { |
59 | int (*open)(void); | 59 | int (*open)(void); |
60 | void (*write)(const char *buf, int len); | 60 | void (*write)(const char *buf, int len); |
61 | void (*edit_cmdline)(char *buf, int len); | 61 | void (*edit_cmdline)(char *buf, int len, unsigned int getline_timeout); |
62 | void (*close)(void); | 62 | void (*close)(void); |
63 | void *data; | 63 | void *data; |
64 | }; | 64 | }; |
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c index f2156f07571f..167ee9433de6 100644 --- a/arch/powerpc/boot/serial.c +++ b/arch/powerpc/boot/serial.c | |||
@@ -33,7 +33,7 @@ static void serial_write(const char *buf, int len) | |||
33 | scdp->putc(*buf++); | 33 | scdp->putc(*buf++); |
34 | } | 34 | } |
35 | 35 | ||
36 | static void serial_edit_cmdline(char *buf, int len) | 36 | static void serial_edit_cmdline(char *buf, int len, unsigned int timeout) |
37 | { | 37 | { |
38 | int timer = 0, count; | 38 | int timer = 0, count; |
39 | char ch, *cp; | 39 | char ch, *cp; |
@@ -44,7 +44,7 @@ static void serial_edit_cmdline(char *buf, int len) | |||
44 | cp = &buf[count]; | 44 | cp = &buf[count]; |
45 | count++; | 45 | count++; |
46 | 46 | ||
47 | while (timer++ < 5*1000) { | 47 | do { |
48 | if (scdp->tstc()) { | 48 | if (scdp->tstc()) { |
49 | while (((ch = scdp->getc()) != '\n') && (ch != '\r')) { | 49 | while (((ch = scdp->getc()) != '\n') && (ch != '\r')) { |
50 | /* Test for backspace/delete */ | 50 | /* Test for backspace/delete */ |
@@ -70,7 +70,7 @@ static void serial_edit_cmdline(char *buf, int len) | |||
70 | break; /* Exit 'timer' loop */ | 70 | break; /* Exit 'timer' loop */ |
71 | } | 71 | } |
72 | udelay(1000); /* 1 msec */ | 72 | udelay(1000); /* 1 msec */ |
73 | } | 73 | } while (timer++ < timeout); |
74 | *cp = 0; | 74 | *cp = 0; |
75 | } | 75 | } |
76 | 76 | ||