aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/hvc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r--drivers/tty/hvc/hvc_console.c33
-rw-r--r--drivers/tty/hvc/hvc_vio.c123
2 files changed, 96 insertions, 60 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 4a652999380f..a5dec1ca1b82 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}
@@ -877,10 +887,15 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
877 i = ++last_hvc; 887 i = ++last_hvc;
878 888
879 hp->index = i; 889 hp->index = i;
890 cons_ops[i] = ops;
891 vtermnos[i] = vtermno;
880 892
881 list_add_tail(&(hp->next), &hvc_structs); 893 list_add_tail(&(hp->next), &hvc_structs);
882 spin_unlock(&hvc_structs_lock); 894 spin_unlock(&hvc_structs_lock);
883 895
896 /* check if we need to re-register the kernel console */
897 hvc_check_console(i);
898
884 return hp; 899 return hp;
885} 900}
886EXPORT_SYMBOL_GPL(hvc_alloc); 901EXPORT_SYMBOL_GPL(hvc_alloc);
@@ -893,8 +908,12 @@ int hvc_remove(struct hvc_struct *hp)
893 tty = tty_port_tty_get(&hp->port); 908 tty = tty_port_tty_get(&hp->port);
894 909
895 spin_lock_irqsave(&hp->lock, flags); 910 spin_lock_irqsave(&hp->lock, flags);
896 if (hp->index < MAX_NR_HVC_CONSOLES) 911 if (hp->index < MAX_NR_HVC_CONSOLES) {
912 console_lock();
897 vtermnos[hp->index] = -1; 913 vtermnos[hp->index] = -1;
914 cons_ops[hp->index] = NULL;
915 console_unlock();
916 }
898 917
899 /* Don't whack hp->irq because tty_hangup() will need to free the irq. */ 918 /* Don't whack hp->irq because tty_hangup() will need to free the irq. */
900 919
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
index ee307799271a..070c0ee68642 100644
--- a/drivers/tty/hvc/hvc_vio.c
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -230,6 +230,69 @@ static const struct hv_ops hvterm_hvsi_ops = {
230 .tiocmset = hvterm_hvsi_tiocmset, 230 .tiocmset = hvterm_hvsi_tiocmset,
231}; 231};
232 232
233static void udbg_hvc_putc(char c)
234{
235 int count = -1;
236
237 if (!hvterm_privs[0])
238 return;
239
240 if (c == '\n')
241 udbg_hvc_putc('\r');
242
243 do {
244 switch(hvterm_privs[0]->proto) {
245 case HV_PROTOCOL_RAW:
246 count = hvterm_raw_put_chars(0, &c, 1);
247 break;
248 case HV_PROTOCOL_HVSI:
249 count = hvterm_hvsi_put_chars(0, &c, 1);
250 break;
251 }
252 } while(count == 0);
253}
254
255static int udbg_hvc_getc_poll(void)
256{
257 int rc = 0;
258 char c;
259
260 if (!hvterm_privs[0])
261 return -1;
262
263 switch(hvterm_privs[0]->proto) {
264 case HV_PROTOCOL_RAW:
265 rc = hvterm_raw_get_chars(0, &c, 1);
266 break;
267 case HV_PROTOCOL_HVSI:
268 rc = hvterm_hvsi_get_chars(0, &c, 1);
269 break;
270 }
271 if (!rc)
272 return -1;
273 return c;
274}
275
276static int udbg_hvc_getc(void)
277{
278 int ch;
279
280 if (!hvterm_privs[0])
281 return -1;
282
283 for (;;) {
284 ch = udbg_hvc_getc_poll();
285 if (ch == -1) {
286 /* This shouldn't be needed...but... */
287 volatile unsigned long delay;
288 for (delay=0; delay < 2000000; delay++)
289 ;
290 } else {
291 return ch;
292 }
293 }
294}
295
233static int __devinit hvc_vio_probe(struct vio_dev *vdev, 296static int __devinit hvc_vio_probe(struct vio_dev *vdev,
234 const struct vio_device_id *id) 297 const struct vio_device_id *id)
235{ 298{
@@ -289,6 +352,13 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev,
289 return PTR_ERR(hp); 352 return PTR_ERR(hp);
290 dev_set_drvdata(&vdev->dev, hp); 353 dev_set_drvdata(&vdev->dev, hp);
291 354
355 /* register udbg if it's not there already for console 0 */
356 if (hp->index == 0 && !udbg_putc) {
357 udbg_putc = udbg_hvc_putc;
358 udbg_getc = udbg_hvc_getc;
359 udbg_getc_poll = udbg_hvc_getc_poll;
360 }
361
292 return 0; 362 return 0;
293} 363}
294 364
@@ -331,59 +401,6 @@ static void __exit hvc_vio_exit(void)
331} 401}
332module_exit(hvc_vio_exit); 402module_exit(hvc_vio_exit);
333 403
334static void udbg_hvc_putc(char c)
335{
336 int count = -1;
337
338 if (c == '\n')
339 udbg_hvc_putc('\r');
340
341 do {
342 switch(hvterm_priv0.proto) {
343 case HV_PROTOCOL_RAW:
344 count = hvterm_raw_put_chars(0, &c, 1);
345 break;
346 case HV_PROTOCOL_HVSI:
347 count = hvterm_hvsi_put_chars(0, &c, 1);
348 break;
349 }
350 } while(count == 0);
351}
352
353static int udbg_hvc_getc_poll(void)
354{
355 int rc = 0;
356 char c;
357
358 switch(hvterm_priv0.proto) {
359 case HV_PROTOCOL_RAW:
360 rc = hvterm_raw_get_chars(0, &c, 1);
361 break;
362 case HV_PROTOCOL_HVSI:
363 rc = hvterm_hvsi_get_chars(0, &c, 1);
364 break;
365 }
366 if (!rc)
367 return -1;
368 return c;
369}
370
371static int udbg_hvc_getc(void)
372{
373 int ch;
374 for (;;) {
375 ch = udbg_hvc_getc_poll();
376 if (ch == -1) {
377 /* This shouldn't be needed...but... */
378 volatile unsigned long delay;
379 for (delay=0; delay < 2000000; delay++)
380 ;
381 } else {
382 return ch;
383 }
384 }
385}
386
387void __init hvc_vio_init_early(void) 404void __init hvc_vio_init_early(void)
388{ 405{
389 struct device_node *stdout_node; 406 struct device_node *stdout_node;