aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/hvc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-07-23 17:33:13 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-05 01:19:34 -0400
commit92057a493af4bb56928a762ad0423200b835d995 (patch)
treef1c7377ff78695e493372eeec5e7071fc84b63e3 /drivers/tty/hvc
parentbaa436b3676ac0eea48dfbeaf7babf53a2305bba (diff)
hvc_console: Better kernel console support
hvc_console has two methods to instanciate the consoles. hvc_instanciate is meant to be called at early boot, while hvc_alloc is called for more dynamically probed objects. Currently, it only deals with adding kernel consoles in the former case, which means for example that if a console only uses dynamic probing, it will never be usable as a kernel console even when specifying console=hvc0 explicitly, which could be considered annoying... More specifically, on pseries, we only do the early instanciate for the console currently used by the firmware, so if you have your firmware configured to go to a video card, for example, you cannot get your kernel console, oops messages, etc... on your serial port or hypervisor console, which would be handy to deal with oopses. This fixes it by checking if hvc_console.flags & CON_ENABLED is set when registering a new dynamic console, and if not, redo the index check and re-register the console if the index matches, allowing console=hvcN to work. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r--drivers/tty/hvc/hvc_console.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 2d691eb7c40a..f1d4d96a4a07 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -245,6 +245,20 @@ static void hvc_port_destruct(struct tty_port *port)
245 kfree(hp); 245 kfree(hp);
246} 246}
247 247
248static void hvc_check_console(int index)
249{
250 /* Already enabled, bail out */
251 if (hvc_console.flags & CON_ENABLED)
252 return;
253
254 /* If this index is what the user requested, then register
255 * now (setup won't fail at this point). It's ok to just
256 * call register again if previously .setup failed.
257 */
258 if (index == hvc_console.index)
259 register_console(&hvc_console);
260}
261
248/* 262/*
249 * hvc_instantiate() is an early console discovery method which locates 263 * hvc_instantiate() is an early console discovery method which locates
250 * consoles * prior to the vio subsystem discovering them. Hotplugged 264 * consoles * prior to the vio subsystem discovering them. Hotplugged
@@ -275,12 +289,8 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
275 if (last_hvc < index) 289 if (last_hvc < index)
276 last_hvc = index; 290 last_hvc = index;
277 291
278 /* if this index is what the user requested, then register 292 /* check if we need to re-register the kernel console */
279 * now (setup won't fail at this point). It's ok to just 293 hvc_check_console(index);
280 * call register again if previously .setup failed.
281 */
282 if (index == hvc_console.index)
283 register_console(&hvc_console);
284 294
285 return 0; 295 return 0;
286} 296}
@@ -858,10 +868,15 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
858 i = ++last_hvc; 868 i = ++last_hvc;
859 869
860 hp->index = i; 870 hp->index = i;
871 cons_ops[i] = ops;
872 vtermnos[i] = vtermno;
861 873
862 list_add_tail(&(hp->next), &hvc_structs); 874 list_add_tail(&(hp->next), &hvc_structs);
863 spin_unlock(&hvc_structs_lock); 875 spin_unlock(&hvc_structs_lock);
864 876
877 /* check if we need to re-register the kernel console */
878 hvc_check_console(i);
879
865 return hp; 880 return hp;
866} 881}
867EXPORT_SYMBOL_GPL(hvc_alloc); 882EXPORT_SYMBOL_GPL(hvc_alloc);
@@ -874,8 +889,12 @@ int hvc_remove(struct hvc_struct *hp)
874 tty = tty_port_tty_get(&hp->port); 889 tty = tty_port_tty_get(&hp->port);
875 890
876 spin_lock_irqsave(&hp->lock, flags); 891 spin_lock_irqsave(&hp->lock, flags);
877 if (hp->index < MAX_NR_HVC_CONSOLES) 892 if (hp->index < MAX_NR_HVC_CONSOLES) {
893 console_lock();
878 vtermnos[hp->index] = -1; 894 vtermnos[hp->index] = -1;
895 cons_ops[hp->index] = NULL;
896 console_unlock();
897 }
879 898
880 /* Don't whack hp->irq because tty_hangup() will need to free the irq. */ 899 /* Don't whack hp->irq because tty_hangup() will need to free the irq. */
881 900